docs: function(module, exports, __webpack_require__) {
  
  	/**
  	 * Copyright 2013-present, Facebook, Inc.
  	 * All rights reserved.
  	 *
  	 * This source code is licensed under the BSD-style license found in the
  	 * LICENSE file in the root directory of this source tree. An additional grant
  	 * of patent rights can be found in the PATENTS file in the same directory.
  	 *
  	 */
  	
  	'use strict';
  	
  	var _prodInvariant = __webpack_require__(33);
  	
  	var EventPluginRegistry = __webpack_require__(41);
  	var EventPluginUtils = __webpack_require__(42);
  	var ReactErrorUtils = __webpack_require__(43);
  	
  	var accumulateInto = __webpack_require__(44);
  	var forEachAccumulated = __webpack_require__(45);
  	var invariant = __webpack_require__(9);
  	
  	/**
  	 * Internal store for event listeners
  	 */
  	var listenerBank = {};
  	
  	/**
  	 * Internal queue of events that have accumulated their dispatches and are
  	 * waiting to have their dispatches executed.
  	 */
  	var eventQueue = null;
  	
  	/**
  	 * Dispatches an event and releases it back into the pool, unless persistent.
  	 *
  	 * @param {?object} event Synthetic event to be dispatched.
  	 * @param {boolean} simulated If the event is simulated (changes exn behavior)
  	 * @private
  	 */
  	var executeDispatchesAndRelease = function (event, simulated) {
  	  if (event) {
  	    EventPluginUtils.executeDispatchesInOrder(event, simulated);
  	
  	    if (!event.isPersistent()) {
  	      event.constructor.release(event);
  	    }
  	  }
  	};
  	var executeDispatchesAndReleaseSimulated = function (e) {
  	  return executeDispatchesAndRelease(e, true);
  	};
  	var executeDispatchesAndReleaseTopLevel = function (e) {
  	  return executeDispatchesAndRelease(e, false);
  	};
  	
  	var getDictionaryKey = function (inst) {
  	  // Prevents V8 performance issue:
  	  // https://github.com/facebook/react/pull/7232
  	  return '.' + inst._rootNodeID;
  	};
  	
  	function isInteractive(tag) {
  	  return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
  	}
  	
  	function shouldPreventMouseEvent(name, type, props) {
  	  switch (name) {
  	    case 'onClick':
  	    case 'onClickCapture':
  	    case 'onDoubleClick':
  	    case 'onDoubleClickCapture':
  	    case 'onMouseDown':
  	    case 'onMouseDownCapture':
  	    case 'onMouseMove':
  	    case 'onMouseMoveCapture':
  	    case 'onMouseUp':
  	    case 'onMouseUpCapture':
  	      return !!(props.disabled && isInteractive(type));
  	    default:
  	      return false;
  	  }
  	}
  	
  	/**
  	 * This is a unified interface for event plugins to be installed and configured.
  	 *
  	 * Event plugins can implement the following properties:
  	 *
  	 *   `extractEvents` {function(string, DOMEventTarget, string, object): *}
  	 *     Required. When a top-level event is fired, this method is expected to
  	 *     extract synthetic events that will in turn be queued and dispatched.
  	 *
  	 *   `eventTypes` {object}
  	 *     Optional, plugins that fire events must publish a mapping of registration
  	 *     names that are used to register listeners. Values of this mapping must
  	 *     be objects that contain `registrationName` or `phasedRegistrationNames`.
  	 *
  	 *   `executeDispatch` {function(object, function, string)}
  	 *     Optional, allows plugins to override how an event gets dispatched. By
  	 *     default, the listener is simply invoked.
  	 *
  	 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
  	 *
  	 * @public
  	 */
  	var EventPluginHub = {
  	
  	  /**
  	   * Methods for injecting dependencies.
  	   */
  	  injection: {
  	
  	    /**
  	     * @param {array} InjectedEventPluginOrder
  	     * @public
  	     */
  	    injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
  	
  	    /**
  	     * @param {object} injectedNamesToPlugins Map from names to plugin modules.
  	     */
  	    injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName
  	
  	  },
  	
  	  /**
  	   * Stores `listener` at `listenerBank[registrationName][key]`. Is idempotent.
  	   *
  	   * @param {object} inst The instance, which is the source of events.
  	   * @param {string} registrationName Name of listener (e.g. `onClick`).
  	   * @param {function} listener The callback to store.
  	   */
  	  putListener: function (inst, registrationName, listener) {
  	    !(typeof listener === 'function') ?  false ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : _prodInvariant('94', registrationName, typeof listener) : void 0;
  	
  	    var key = getDictionaryKey(inst);
  	    var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {});
  	    bankForRegistrationName[key] = listener;
  	
  	    var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
  	    if (PluginModule && PluginModule.didPutListener) {
  	      PluginModule.didPutListener(inst, registrationName, listener);
  	    }
  	  },
  	
  	  /**
  	   * @param {object} inst The instance, which is the source of events.
  	   * @param {string} registrationName Name of listener (e.g. `onClick`).
  	   * @return {?function} The stored callback.
  	   */
  	  getListener: function (inst, registrationName) {
  	    // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
  	    // live here; needs to be moved to a better place soon
  	    var bankForRegistrationName = listenerBank[registrationName];
  	    if (shouldPreventMouseEvent(registrationName, inst._currentElement.type, inst._currentElement.props)) {
  	      return null;
  	    }
  	    var key = getDictionaryKey(inst);
  	    return bankForRegistrationName && bankForRegistrationName[key];
  	  },
  	
  	  /**
  	   * Deletes a listener from the registration bank.
  	   *
  	   * @param {object} inst The instance, which is the source of events.
  	   * @param {string} registrationName Name of listener (e.g. `onClick`).
  	   */
  	  deleteListener: function (inst, registrationName) {
  	    var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
  	    if (PluginModule && PluginModule.willDeleteListener) {
  	      PluginModule.willDeleteListener(inst, registrationName);
  	    }
  	
  	    var bankForRegistrationName = listenerBank[registrationName];
  	    // TODO: This should never be null -- when is it?
  	    if (bankForRegistrationName) {
  	      var key = getDictionaryKey(inst);
  	      delete bankForRegistrationName[key];
  	    }
  	  },
  	
  	  /**
  	   * Deletes all listeners for the DOM element with the supplied ID.
  	   *
  	   * @param {object} inst The instance, which is the source of events.
  	   */
  	  deleteAllListeners: function (inst) {
  	    var key = getDictionaryKey(inst);
  	    for (var registrationName in listenerBank) {
  	      if (!listenerBank.hasOwnProperty(registrationName)) {
  	        continue;
  	      }
  	
  	      if (!listenerBank[registrationName][key]) {
  	        continue;
  	      }
  	
  	      var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];
  	      if (PluginModule && PluginModule.willDeleteListener) {
  	        PluginModule.willDeleteListener(inst, registrationName);
  	      }
  	
  	      delete listenerBank[registrationName][key];
  	    }
  	  },
  	
  	  /**
  	   * Allows registered plugins an opportunity to extract events from top-level
  	   * native browser events.
  	   *
  	   * @return {*} An accumulation of synthetic events.
  	   * @internal
  	   */
  	  extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
  	    var events;
  	    var plugins = EventPluginRegistry.plugins;
  	    for (var i = 0; i < plugins.length; i++) {
  	      // Not every plugin in the ordering may be loaded at runtime.
  	      var possiblePlugin = plugins[i];
  	      if (possiblePlugin) {
  	        var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
  	        if (extractedEvents) {
  	          events = accumulateInto(events, extractedEvents);
  	        }
  	      }
  	    }
  	    return events;
  	  },
  	
  	  /**
  	   * Enqueues a synthetic event that should be dispatched when
  	   * `processEventQueue` is invoked.
  	   *
  	   * @param {*} events An accumulation of synthetic events.
  	   * @internal
  	   */
  	  enqueueEvents: function (events) {
  	    if (events) {
  	      eventQueue = accumulateInto(eventQueue, events);
  	    }
  	  },
  	
  	  /**
  	   * Dispatches all synthetic events on the event queue.
  	   *
  	   * @internal
  	   */
  	  processEventQueue: function (simulated) {
  	    // Set `eventQueue` to null before processing it so that we can tell if more
  	    // events get enqueued while processing.
  	    var processingEventQueue = eventQueue;
  	    eventQueue = null;
  	    if (simulated) {
  	      forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);
  	    } else {
  	      forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
  	    }
  	    !!eventQueue ?  false ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : _prodInvariant('95') : void 0;
  	    // This would be a good time to rethrow if any of the event handlers threw.
  	    ReactErrorUtils.rethrowCaughtError();
  	  },
  	
  	  /**
  	   * These are needed for tests only. Do not use!
  	   */
  	  __purge: function () {
  	    listenerBank = {};
  	  },
  	
  	  __getListenerBank: function () {
  	    return listenerBank;
  	  }
  	
  	};
  	
  	module.exports = EventPluginHub;
  
  /***/ }