containing any provided children.
+ *
+ * @param {object} module the mock function object exported from a
+ * module that defines the component to be mocked
+ * @param {?string} mockTagName optional dummy root tag name to return
+ * from render method (overrides
+ * module.mockTagName if provided)
+ * @return {object} the ReactTestUtils object (for chaining)
+ */
+ mockComponent: function (module, mockTagName) {
+ if (!hasWarnedAboutDeprecatedMockComponent) {
+ hasWarnedAboutDeprecatedMockComponent = true;
+ lowPriorityWarning$1(false, 'ReactTestUtils.mockComponent() is deprecated. ' + 'Use shallow rendering or jest.mock() instead.\n\n' + 'See https://fb.me/test-utils-mock-component for more information.');
+ }
+
+ mockTagName = mockTagName || module.mockTagName || 'div';
+
+ module.prototype.render.mockImplementation(function () {
+ return React.createElement(mockTagName, null, this.props.children);
+ });
+
+ return this;
+ },
+
+ nativeTouchData: function (x, y) {
+ return {
+ touches: [{ pageX: x, pageY: y }]
+ };
+ },
+
+ Simulate: null,
+ SimulateNative: {}
+};
+
+/**
+ * Exports:
+ *
+ * - `ReactTestUtils.Simulate.click(Element)`
+ * - `ReactTestUtils.Simulate.mouseMove(Element)`
+ * - `ReactTestUtils.Simulate.change(Element)`
+ * - ... (All keys from event plugin `eventTypes` objects)
+ */
+function makeSimulator(eventType) {
+ return function (domNode, eventData) {
+ !!React.isValidElement(domNode) ? invariant(false, 'TestUtils.Simulate expected a DOM node as the first argument but received a React element. Pass the DOM node you wish to simulate the event on instead. Note that TestUtils.Simulate will not work if you are using shallow rendering.') : void 0;
+ !!ReactTestUtils.isCompositeComponent(domNode) ? invariant(false, 'TestUtils.Simulate expected a DOM node as the first argument but received a component instance. Pass the DOM node you wish to simulate the event on instead.') : void 0;
+
+ var dispatchConfig = eventNameDispatchConfigs[eventType];
+
+ var fakeNativeEvent = new Event();
+ fakeNativeEvent.target = domNode;
+ fakeNativeEvent.type = eventType.toLowerCase();
+
+ // We don't use SyntheticEvent.getPooled in order to not have to worry about
+ // properly destroying any properties assigned from `eventData` upon release
+ var targetInst = getInstanceFromNode(domNode);
+ var event = new SyntheticEvent(dispatchConfig, targetInst, fakeNativeEvent, domNode);
+
+ // Since we aren't using pooling, always persist the event. This will make
+ // sure it's marked and won't warn when setting additional properties.
+ event.persist();
+ _assign(event, eventData);
+
+ if (dispatchConfig.phasedRegistrationNames) {
+ accumulateTwoPhaseDispatches(event);
+ } else {
+ accumulateDirectDispatches(event);
+ }
+
+ ReactDOM.unstable_batchedUpdates(function () {
+ // Normally extractEvent enqueues a state restore, but we'll just always
+ // do that since we we're by-passing it here.
+ enqueueStateRestore(domNode);
+ runEventsInBatch(event);
+ });
+ restoreStateIfNeeded();
+ };
+}
+
+function buildSimulators() {
+ ReactTestUtils.Simulate = {};
+
+ var eventType = void 0;
+ for (eventType in eventNameDispatchConfigs) {
+ /**
+ * @param {!Element|ReactDOMComponent} domComponentOrNode
+ * @param {?object} eventData Fake event data to use in SyntheticEvent.
+ */
+ ReactTestUtils.Simulate[eventType] = makeSimulator(eventType);
+ }
+}
+
+buildSimulators();
+
+/**
+ * Exports:
+ *
+ * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)`
+ * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)`
+ * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)`
+ * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)`
+ * - ... (All keys from `BrowserEventConstants.topLevelTypes`)
+ *
+ * Note: Top level event types are a subset of the entire set of handler types
+ * (which include a broader set of "synthetic" events). For example, onDragDone
+ * is a synthetic event. Except when testing an event plugin or React's event
+ * handling code specifically, you probably want to use ReactTestUtils.Simulate
+ * to dispatch synthetic events.
+ */
+
+function makeNativeSimulator(eventType, topLevelType) {
+ return function (domComponentOrNode, nativeEventData) {
+ var fakeNativeEvent = new Event(eventType);
+ _assign(fakeNativeEvent, nativeEventData);
+ if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {
+ simulateNativeEventOnDOMComponent(topLevelType, domComponentOrNode, fakeNativeEvent);
+ } else if (domComponentOrNode.tagName) {
+ // Will allow on actual dom nodes.
+ simulateNativeEventOnNode(topLevelType, domComponentOrNode, fakeNativeEvent);
+ }
+ };
+}
+
+[[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_BLUR, 'blur'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CANCEL, 'cancel'], [TOP_CHANGE, 'change'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_COMPOSITION_END, 'compositionEnd'], [TOP_COMPOSITION_START, 'compositionStart'], [TOP_COMPOSITION_UPDATE, 'compositionUpdate'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DRAG_START, 'dragStart'], [TOP_DRAG, 'drag'], [TOP_DROP, 'drop'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_LOAD_START, 'loadStart'], [TOP_LOAD_START, 'loadStart'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_PLAYING, 'playing'], [TOP_PROGRESS, 'progress'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_SCROLL, 'scroll'], [TOP_SEEKED, 'seeked'], [TOP_SEEKING, 'seeking'], [TOP_SELECTION_CHANGE, 'selectionChange'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TEXT_INPUT, 'textInput'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TOUCH_START, 'touchStart'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_VOLUME_CHANGE, 'volumeChange'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']].forEach(function (_ref) {
+ var topLevelType = _ref[0],
+ eventType = _ref[1];
+
+ /**
+ * @param {!Element|ReactDOMComponent} domComponentOrNode
+ * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent.
+ */
+ ReactTestUtils.SimulateNative[eventType] = makeNativeSimulator(eventType, topLevelType);
+});
+
+
+
+var ReactTestUtils$2 = Object.freeze({
+ default: ReactTestUtils
+});
+
+var ReactTestUtils$3 = ( ReactTestUtils$2 && ReactTestUtils ) || ReactTestUtils$2;
+
+// TODO: decide on the top-level export form.
+// This is hacky but makes it work with both Rollup and Jest.
+var testUtils = ReactTestUtils$3.default || ReactTestUtils$3;
+
+module.exports = testUtils;
+ })();
+}
diff --git a/node_modules/react-dom/cjs/react-dom-test-utils.production.min.js b/node_modules/react-dom/cjs/react-dom-test-utils.production.min.js
new file mode 100644
index 0000000000..e70da77c73
--- /dev/null
+++ b/node_modules/react-dom/cjs/react-dom-test-utils.production.min.js
@@ -0,0 +1,33 @@
+/** @license React v16.6.1
+ * react-dom-test-utils.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+'use strict';var g=require("object-assign"),l=require("react"),m=require("react-dom");function n(a,b,c,e,d,k,f,h){if(!a){a=void 0;if(void 0===b)a=Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var L=[c,e,d,k,f,h],M=0;a=Error(b.replace(/%s/g,function(){return L[M++]}));a.name="Invariant Violation"}a.framesToPop=1;throw a;}}
+function p(a){for(var b=arguments.length-1,c="https://reactjs.org/docs/error-decoder.html?invariant="+a,e=0;e
this.eventPool.length&&this.eventPool.push(a)}
+function x(a){a.eventPool=[];a.getPooled=y;a.release=z}var A=!("undefined"===typeof window||!window.document||!window.document.createElement);function B(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;return c}var C={animationend:B("Animation","AnimationEnd"),animationiteration:B("Animation","AnimationIteration"),animationstart:B("Animation","AnimationStart"),transitionend:B("Transition","TransitionEnd")},D={},E={};
+A&&(E=document.createElement("div").style,"AnimationEvent"in window||(delete C.animationend.animation,delete C.animationiteration.animation,delete C.animationstart.animation),"TransitionEvent"in window||delete C.transitionend.transition);function F(a){if(D[a])return D[a];if(!C[a])return a;var b=C[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in E)return D[a]=b[c];return a}
+var G=F("animationend"),H=F("animationiteration"),I=F("animationstart"),J=F("transitionend"),K=m.findDOMNode,N=m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events,O=N[0],P=N[4],Q=N[5],R=N[6],S=N[7],aa=N[8],T=N[9],ba=N[10];function U(){}
+function ca(a,b){if(!a)return[];a=t(a);if(!a)return[];for(var c=a,e=[];;){if(5===c.tag||6===c.tag||1===c.tag||0===c.tag){var d=c.stateNode;b(d)&&e.push(d)}if(c.child)c.child.return=c,c=c.child;else{if(c===a)return e;for(;!c.sibling;){if(!c.return||c.return===a)return e;c=c.return}c.sibling.return=c.return;c=c.sibling}}}
+function V(a,b){if(a&&!a._reactInternalFiber){var c=""+a;a=Array.isArray(a)?"an array":a&&1===a.nodeType&&a.tagName?"a DOM node":"[object Object]"===c?"object with keys {"+Object.keys(a).join(", ")+"}":c;p("286",b,a)}}
+var W={renderIntoDocument:function(a){var b=document.createElement("div");return m.render(a,b)},isElement:function(a){return l.isValidElement(a)},isElementOfType:function(a,b){return l.isValidElement(a)&&a.type===b},isDOMComponent:function(a){return!(!a||1!==a.nodeType||!a.tagName)},isDOMComponentElement:function(a){return!!(a&&l.isValidElement(a)&&a.tagName)},isCompositeComponent:function(a){return W.isDOMComponent(a)?!1:null!=a&&"function"===typeof a.render&&"function"===typeof a.setState},isCompositeComponentWithType:function(a,
+b){return W.isCompositeComponent(a)?a._reactInternalFiber.type===b:!1},findAllInRenderedTree:function(a,b){V(a,"findAllInRenderedTree");return a?ca(a._reactInternalFiber,b):[]},scryRenderedDOMComponentsWithClass:function(a,b){V(a,"scryRenderedDOMComponentsWithClass");return W.findAllInRenderedTree(a,function(a){if(W.isDOMComponent(a)){var c=a.className;"string"!==typeof c&&(c=a.getAttribute("class")||"");var d=c.split(/\s+/);Array.isArray(b)||(void 0===b?p("11"):void 0,b=b.split(/\s+/));return b.every(function(a){return-1!==
+d.indexOf(a)})}return!1})},findRenderedDOMComponentWithClass:function(a,b){V(a,"findRenderedDOMComponentWithClass");a=W.scryRenderedDOMComponentsWithClass(a,b);if(1!==a.length)throw Error("Did not find exactly one match (found: "+a.length+") for class:"+b);return a[0]},scryRenderedDOMComponentsWithTag:function(a,b){V(a,"scryRenderedDOMComponentsWithTag");return W.findAllInRenderedTree(a,function(a){return W.isDOMComponent(a)&&a.tagName.toUpperCase()===b.toUpperCase()})},findRenderedDOMComponentWithTag:function(a,
+b){V(a,"findRenderedDOMComponentWithTag");a=W.scryRenderedDOMComponentsWithTag(a,b);if(1!==a.length)throw Error("Did not find exactly one match (found: "+a.length+") for tag:"+b);return a[0]},scryRenderedComponentsWithType:function(a,b){V(a,"scryRenderedComponentsWithType");return W.findAllInRenderedTree(a,function(a){return W.isCompositeComponentWithType(a,b)})},findRenderedComponentWithType:function(a,b){V(a,"findRenderedComponentWithType");a=W.scryRenderedComponentsWithType(a,b);if(1!==a.length)throw Error("Did not find exactly one match (found: "+
+a.length+") for componentType:"+b);return a[0]},mockComponent:function(a,b){b=b||a.mockTagName||"div";a.prototype.render.mockImplementation(function(){return l.createElement(b,null,this.props.children)});return this},nativeTouchData:function(a,b){return{touches:[{pageX:a,pageY:b}]}},Simulate:null,SimulateNative:{}};
+function da(a){return function(b,c){l.isValidElement(b)?p("228"):void 0;W.isCompositeComponent(b)?p("229"):void 0;var e=P[a],d=new U;d.target=b;d.type=a.toLowerCase();var k=O(b),f=new w(e,k,d,b);f.persist();g(f,c);e.phasedRegistrationNames?Q(f):R(f);m.unstable_batchedUpdates(function(){S(b);ba(f)});aa()}}W.Simulate={};var X=void 0;for(X in P)W.Simulate[X]=da(X);
+function ea(a,b){return function(c,e){var d=new U(a);g(d,e);W.isDOMComponent(c)?(c=K(c),d.target=c,T(b,d)):c.tagName&&(d.target=c,T(b,d))}}
+[["abort","abort"],[G,"animationEnd"],[H,"animationIteration"],[I,"animationStart"],["blur","blur"],["canplaythrough","canPlayThrough"],["canplay","canPlay"],["cancel","cancel"],["change","change"],["click","click"],["close","close"],["compositionend","compositionEnd"],["compositionstart","compositionStart"],["compositionupdate","compositionUpdate"],["contextmenu","contextMenu"],["copy","copy"],["cut","cut"],["dblclick","doubleClick"],["dragend","dragEnd"],["dragenter","dragEnter"],["dragexit","dragExit"],
+["dragleave","dragLeave"],["dragover","dragOver"],["dragstart","dragStart"],["drag","drag"],["drop","drop"],["durationchange","durationChange"],["emptied","emptied"],["encrypted","encrypted"],["ended","ended"],["error","error"],["focus","focus"],["input","input"],["keydown","keyDown"],["keypress","keyPress"],["keyup","keyUp"],["loadstart","loadStart"],["loadstart","loadStart"],["load","load"],["loadeddata","loadedData"],["loadedmetadata","loadedMetadata"],["mousedown","mouseDown"],["mousemove","mouseMove"],
+["mouseout","mouseOut"],["mouseover","mouseOver"],["mouseup","mouseUp"],["paste","paste"],["pause","pause"],["play","play"],["playing","playing"],["progress","progress"],["ratechange","rateChange"],["scroll","scroll"],["seeked","seeked"],["seeking","seeking"],["selectionchange","selectionChange"],["stalled","stalled"],["suspend","suspend"],["textInput","textInput"],["timeupdate","timeUpdate"],["toggle","toggle"],["touchcancel","touchCancel"],["touchend","touchEnd"],["touchmove","touchMove"],["touchstart",
+"touchStart"],[J,"transitionEnd"],["volumechange","volumeChange"],["waiting","waiting"],["wheel","wheel"]].forEach(function(a){var b=a[1];W.SimulateNative[b]=ea(b,a[0])});var Y={default:W},Z=Y&&W||Y;module.exports=Z.default||Z;
diff --git a/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js b/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js
new file mode 100644
index 0000000000..fe0458e476
--- /dev/null
+++ b/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.development.js
@@ -0,0 +1,1676 @@
+/** @license React v16.6.1
+ * react-dom-unstable-native-dependencies.development.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+'use strict';
+
+
+
+if (process.env.NODE_ENV !== "production") {
+ (function() {
+'use strict';
+
+var ReactDOM = require('react-dom');
+var _assign = require('object-assign');
+
+/**
+ * Use invariant() to assert state which your program assumes to be true.
+ *
+ * Provide sprintf-style format (only %s is supported) and arguments
+ * to provide information about what broke and what you were
+ * expecting.
+ *
+ * The invariant message will be stripped in production, but the invariant
+ * will remain to ensure logic does not differ in production.
+ */
+
+var validateFormat = function () {};
+
+{
+ validateFormat = function (format) {
+ if (format === undefined) {
+ throw new Error('invariant requires an error message argument');
+ }
+ };
+}
+
+function invariant(condition, format, a, b, c, d, e, f) {
+ validateFormat(format);
+
+ if (!condition) {
+ var error = void 0;
+ if (format === undefined) {
+ error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
+ } else {
+ var args = [a, b, c, d, e, f];
+ var argIndex = 0;
+ error = new Error(format.replace(/%s/g, function () {
+ return args[argIndex++];
+ }));
+ error.name = 'Invariant Violation';
+ }
+
+ error.framesToPop = 1; // we don't care about invariant's own frame
+ throw error;
+ }
+}
+
+// Relying on the `invariant()` implementation lets us
+// preserve the format and params in the www builds.
+
+{
+ // In DEV mode, we swap out invokeGuardedCallback for a special version
+ // that plays more nicely with the browser's DevTools. The idea is to preserve
+ // "Pause on exceptions" behavior. Because React wraps all user-provided
+ // functions in invokeGuardedCallback, and the production version of
+ // invokeGuardedCallback uses a try-catch, all user exceptions are treated
+ // like caught exceptions, and the DevTools won't pause unless the developer
+ // takes the extra step of enabling pause on caught exceptions. This is
+ // untintuitive, though, because even though React has caught the error, from
+ // the developer's perspective, the error is uncaught.
+ //
+ // To preserve the expected "Pause on exceptions" behavior, we don't use a
+ // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
+ // DOM node, and call the user-provided callback from inside an event handler
+ // for that fake event. If the callback throws, the error is "captured" using
+ // a global event handler. But because the error happens in a different
+ // event loop context, it does not interrupt the normal program flow.
+ // Effectively, this gives us try-catch behavior without actually using
+ // try-catch. Neat!
+
+ // Check that the browser supports the APIs we need to implement our special
+ // DEV version of invokeGuardedCallback
+ if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
+ var fakeNode = document.createElement('react');
+
+
+ }
+}
+
+/**
+ * Call a function while guarding against errors that happens within it.
+ * Returns an error if it throws, otherwise null.
+ *
+ * In production, this is implemented using a try-catch. The reason we don't
+ * use a try-catch directly is so that we can swap out a different
+ * implementation in DEV mode.
+ *
+ * @param {String} name of the guard to use for logging or debugging
+ * @param {Function} func The function to invoke
+ * @param {*} context The context to use when calling the function
+ * @param {...*} args Arguments for function
+ */
+
+
+/**
+ * Same as invokeGuardedCallback, but instead of returning an error, it stores
+ * it in a global so it can be rethrown by `rethrowCaughtError` later.
+ * TODO: See if caughtError and rethrowError can be unified.
+ *
+ * @param {String} name of the guard to use for logging or debugging
+ * @param {Function} func The function to invoke
+ * @param {*} context The context to use when calling the function
+ * @param {...*} args Arguments for function
+ */
+
+
+/**
+ * During execution of guarded functions we will capture the first error which
+ * we will rethrow to be handled by the top level error handler.
+ */
+
+/**
+ * Similar to invariant but only logs a warning if the condition is not met.
+ * This can be used to log issues in development environments in critical
+ * paths. Removing the logging code for production environments will keep the
+ * same logic and follow the same code paths.
+ */
+
+var warningWithoutStack = function () {};
+
+{
+ warningWithoutStack = function (condition, format) {
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
+ }
+
+ if (format === undefined) {
+ throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
+ }
+ if (args.length > 8) {
+ // Check before the condition to catch violations early.
+ throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
+ }
+ if (condition) {
+ return;
+ }
+ if (typeof console !== 'undefined') {
+ var argsWithFormat = args.map(function (item) {
+ return '' + item;
+ });
+ argsWithFormat.unshift('Warning: ' + format);
+
+ // We intentionally don't use spread (or .apply) directly because it
+ // breaks IE9: https://github.com/facebook/react/issues/13610
+ Function.prototype.apply.call(console.error, console, argsWithFormat);
+ }
+ try {
+ // --- Welcome to debugging React ---
+ // This error was thrown as a convenience so that you can use this stack
+ // to find the callsite that caused this warning to fire.
+ var argIndex = 0;
+ var message = 'Warning: ' + format.replace(/%s/g, function () {
+ return args[argIndex++];
+ });
+ throw new Error(message);
+ } catch (x) {}
+ };
+}
+
+var warningWithoutStack$1 = warningWithoutStack;
+
+var getFiberCurrentPropsFromNode$1 = null;
+var getInstanceFromNode$1 = null;
+var getNodeFromInstance$1 = null;
+
+function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
+ getFiberCurrentPropsFromNode$1 = getFiberCurrentPropsFromNodeImpl;
+ getInstanceFromNode$1 = getInstanceFromNodeImpl;
+ getNodeFromInstance$1 = getNodeFromInstanceImpl;
+ {
+ !(getNodeFromInstance$1 && getInstanceFromNode$1) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
+ }
+}
+
+var validateEventDispatches = void 0;
+{
+ validateEventDispatches = function (event) {
+ var dispatchListeners = event._dispatchListeners;
+ var dispatchInstances = event._dispatchInstances;
+
+ var listenersIsArr = Array.isArray(dispatchListeners);
+ var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
+
+ var instancesIsArr = Array.isArray(dispatchInstances);
+ var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
+
+ !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
+ };
+}
+
+/**
+ * Standard/simple iteration through an event's collected dispatches.
+ */
+
+
+/**
+ * Standard/simple iteration through an event's collected dispatches, but stops
+ * at the first dispatch execution returning true, and returns that id.
+ *
+ * @return {?string} id of the first dispatch execution who's listener returns
+ * true, or null if no listener returned true.
+ */
+function executeDispatchesInOrderStopAtTrueImpl(event) {
+ var dispatchListeners = event._dispatchListeners;
+ var dispatchInstances = event._dispatchInstances;
+ {
+ validateEventDispatches(event);
+ }
+ if (Array.isArray(dispatchListeners)) {
+ for (var i = 0; i < dispatchListeners.length; i++) {
+ if (event.isPropagationStopped()) {
+ break;
+ }
+ // Listeners and Instances are two parallel arrays that are always in sync.
+ if (dispatchListeners[i](event, dispatchInstances[i])) {
+ return dispatchInstances[i];
+ }
+ }
+ } else if (dispatchListeners) {
+ if (dispatchListeners(event, dispatchInstances)) {
+ return dispatchInstances;
+ }
+ }
+ return null;
+}
+
+/**
+ * @see executeDispatchesInOrderStopAtTrueImpl
+ */
+function executeDispatchesInOrderStopAtTrue(event) {
+ var ret = executeDispatchesInOrderStopAtTrueImpl(event);
+ event._dispatchInstances = null;
+ event._dispatchListeners = null;
+ return ret;
+}
+
+/**
+ * Execution of a "direct" dispatch - there must be at most one dispatch
+ * accumulated on the event or it is considered an error. It doesn't really make
+ * sense for an event with multiple dispatches (bubbled) to keep track of the
+ * return values at each dispatch execution, but it does tend to make sense when
+ * dealing with "direct" dispatches.
+ *
+ * @return {*} The return value of executing the single dispatch.
+ */
+function executeDirectDispatch(event) {
+ {
+ validateEventDispatches(event);
+ }
+ var dispatchListener = event._dispatchListeners;
+ var dispatchInstance = event._dispatchInstances;
+ !!Array.isArray(dispatchListener) ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : void 0;
+ event.currentTarget = dispatchListener ? getNodeFromInstance$1(dispatchInstance) : null;
+ var res = dispatchListener ? dispatchListener(event) : null;
+ event.currentTarget = null;
+ event._dispatchListeners = null;
+ event._dispatchInstances = null;
+ return res;
+}
+
+/**
+ * @param {SyntheticEvent} event
+ * @return {boolean} True iff number of dispatches accumulated is greater than 0.
+ */
+function hasDispatches(event) {
+ return !!event._dispatchListeners;
+}
+
+// Before we know whether it is function or class
+ // Root of a host tree. Could be nested inside another node.
+ // A subtree. Could be an entry point to a different renderer.
+var HostComponent = 5;
+
+function getParent(inst) {
+ do {
+ inst = inst.return;
+ // TODO: If this is a HostRoot we might want to bail out.
+ // That is depending on if we want nested subtrees (layers) to bubble
+ // events to their parent. We could also go through parentNode on the
+ // host node but that wouldn't work for React Native and doesn't let us
+ // do the portal feature.
+ } while (inst && inst.tag !== HostComponent);
+ if (inst) {
+ return inst;
+ }
+ return null;
+}
+
+/**
+ * Return the lowest common ancestor of A and B, or null if they are in
+ * different trees.
+ */
+function getLowestCommonAncestor(instA, instB) {
+ var depthA = 0;
+ for (var tempA = instA; tempA; tempA = getParent(tempA)) {
+ depthA++;
+ }
+ var depthB = 0;
+ for (var tempB = instB; tempB; tempB = getParent(tempB)) {
+ depthB++;
+ }
+
+ // If A is deeper, crawl up.
+ while (depthA - depthB > 0) {
+ instA = getParent(instA);
+ depthA--;
+ }
+
+ // If B is deeper, crawl up.
+ while (depthB - depthA > 0) {
+ instB = getParent(instB);
+ depthB--;
+ }
+
+ // Walk in lockstep until we find a match.
+ var depth = depthA;
+ while (depth--) {
+ if (instA === instB || instA === instB.alternate) {
+ return instA;
+ }
+ instA = getParent(instA);
+ instB = getParent(instB);
+ }
+ return null;
+}
+
+/**
+ * Return if A is an ancestor of B.
+ */
+function isAncestor(instA, instB) {
+ while (instB) {
+ if (instA === instB || instA === instB.alternate) {
+ return true;
+ }
+ instB = getParent(instB);
+ }
+ return false;
+}
+
+/**
+ * Return the parent instance of the passed-in instance.
+ */
+function getParentInstance(inst) {
+ return getParent(inst);
+}
+
+/**
+ * Simulates the traversal of a two-phase, capture/bubble event dispatch.
+ */
+function traverseTwoPhase(inst, fn, arg) {
+ var path = [];
+ while (inst) {
+ path.push(inst);
+ inst = getParent(inst);
+ }
+ var i = void 0;
+ for (i = path.length; i-- > 0;) {
+ fn(path[i], 'captured', arg);
+ }
+ for (i = 0; i < path.length; i++) {
+ fn(path[i], 'bubbled', arg);
+ }
+}
+
+/**
+ * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
+ * should would receive a `mouseEnter` or `mouseLeave` event.
+ *
+ * Does not invoke the callback on the nearest common ancestor because nothing
+ * "entered" or "left" that element.
+ */
+
+/**
+ * Registers plugins so that they can extract and dispatch events.
+ *
+ * @see {EventPluginHub}
+ */
+
+/**
+ * Ordered list of injected plugins.
+ */
+
+
+/**
+ * Mapping from event name to dispatch config
+ */
+
+
+/**
+ * Mapping from registration name to plugin module
+ */
+
+
+/**
+ * Mapping from registration name to event name
+ */
+
+
+/**
+ * Mapping from lowercase registration names to the properly cased version,
+ * used to warn in the case of missing event handlers. Available
+ * only in true.
+ * @type {Object}
+ */
+
+// Trust the developer to only use possibleRegistrationNames in true
+
+/**
+ * Injects an ordering of plugins (by plugin name). This allows the ordering
+ * to be decoupled from injection of the actual plugins so that ordering is
+ * always deterministic regardless of packaging, on-the-fly injection, etc.
+ *
+ * @param {array} InjectedEventPluginOrder
+ * @internal
+ * @see {EventPluginHub.injection.injectEventPluginOrder}
+ */
+
+
+/**
+ * Injects plugins to be used by `EventPluginHub`. The plugin names must be
+ * in the ordering injected by `injectEventPluginOrder`.
+ *
+ * Plugins can be injected as part of page initialization or on-the-fly.
+ *
+ * @param {object} injectedNamesToPlugins Map from names to plugin modules.
+ * @internal
+ * @see {EventPluginHub.injection.injectEventPluginsByName}
+ */
+
+/**
+ * Accumulates items that must not be null or undefined into the first one. This
+ * is used to conserve memory by avoiding array allocations, and thus sacrifices
+ * API cleanness. Since `current` can be null before being passed in and not
+ * null after this function, make sure to assign it back to `current`:
+ *
+ * `a = accumulateInto(a, b);`
+ *
+ * This API should be sparingly used. Try `accumulate` for something cleaner.
+ *
+ * @return {*|array<*>} An accumulation of items.
+ */
+
+function accumulateInto(current, next) {
+ !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
+
+ if (current == null) {
+ return next;
+ }
+
+ // Both are not empty. Warning: Never call x.concat(y) when you are not
+ // certain that x is an Array (x could be a string with concat method).
+ if (Array.isArray(current)) {
+ if (Array.isArray(next)) {
+ current.push.apply(current, next);
+ return current;
+ }
+ current.push(next);
+ return current;
+ }
+
+ if (Array.isArray(next)) {
+ // A bit too dangerous to mutate `next`.
+ return [current].concat(next);
+ }
+
+ return [current, next];
+}
+
+/**
+ * @param {array} arr an "accumulation" of items which is either an Array or
+ * a single item. Useful when paired with the `accumulate` module. This is a
+ * simple utility that allows us to reason about a collection of items, but
+ * handling the case when there is exactly one item (and we do not need to
+ * allocate an array).
+ * @param {function} cb Callback invoked with each element or a collection.
+ * @param {?} [scope] Scope used as `this` in a callback.
+ */
+function forEachAccumulated(arr, cb, scope) {
+ if (Array.isArray(arr)) {
+ arr.forEach(cb, scope);
+ } else if (arr) {
+ cb.call(scope, arr);
+ }
+}
+
+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
+ */
+
+/**
+ * Methods for injecting dependencies.
+ */
+
+
+/**
+ * @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.
+ */
+function getListener(inst, registrationName) {
+ var listener = void 0;
+
+ // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
+ // live here; needs to be moved to a better place soon
+ var stateNode = inst.stateNode;
+ if (!stateNode) {
+ // Work in progress (ex: onload events in incremental mode).
+ return null;
+ }
+ var props = getFiberCurrentPropsFromNode$1(stateNode);
+ if (!props) {
+ // Work in progress.
+ return null;
+ }
+ listener = props[registrationName];
+ if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
+ return null;
+ }
+ !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
+ return listener;
+}
+
+/**
+ * Some event types have a notion of different registration names for different
+ * "phases" of propagation. This finds listeners by a given phase.
+ */
+function listenerAtPhase(inst, event, propagationPhase) {
+ var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
+ return getListener(inst, registrationName);
+}
+
+/**
+ * A small set of propagation patterns, each of which will accept a small amount
+ * of information, and generate a set of "dispatch ready event objects" - which
+ * are sets of events that have already been annotated with a set of dispatched
+ * listener functions/ids. The API is designed this way to discourage these
+ * propagation strategies from actually executing the dispatches, since we
+ * always want to collect the entire set of dispatches before executing even a
+ * single one.
+ */
+
+/**
+ * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
+ * here, allows us to not have to bind or create functions for each event.
+ * Mutating the event's members allows us to not have to create a wrapping
+ * "dispatch" object that pairs the event with the listener.
+ */
+function accumulateDirectionalDispatches(inst, phase, event) {
+ {
+ !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
+ }
+ var listener = listenerAtPhase(inst, event, phase);
+ if (listener) {
+ event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
+ event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
+ }
+}
+
+/**
+ * Collect dispatches (must be entirely collected before dispatching - see unit
+ * tests). Lazily allocate the array to conserve memory. We must loop through
+ * each event and perform the traversal for each one. We cannot perform a
+ * single traversal for the entire collection of events because each event may
+ * have a different target.
+ */
+function accumulateTwoPhaseDispatchesSingle(event) {
+ if (event && event.dispatchConfig.phasedRegistrationNames) {
+ traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
+ }
+}
+
+/**
+ * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.
+ */
+function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
+ if (event && event.dispatchConfig.phasedRegistrationNames) {
+ var targetInst = event._targetInst;
+ var parentInst = targetInst ? getParentInstance(targetInst) : null;
+ traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);
+ }
+}
+
+/**
+ * Accumulates without regard to direction, does not look for phased
+ * registration names. Same as `accumulateDirectDispatchesSingle` but without
+ * requiring that the `dispatchMarker` be the same as the dispatched ID.
+ */
+function accumulateDispatches(inst, ignoredDirection, event) {
+ if (inst && event && event.dispatchConfig.registrationName) {
+ var registrationName = event.dispatchConfig.registrationName;
+ var listener = getListener(inst, registrationName);
+ if (listener) {
+ event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
+ event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
+ }
+ }
+}
+
+/**
+ * Accumulates dispatches on an `SyntheticEvent`, but only for the
+ * `dispatchMarker`.
+ * @param {SyntheticEvent} event
+ */
+function accumulateDirectDispatchesSingle(event) {
+ if (event && event.dispatchConfig.registrationName) {
+ accumulateDispatches(event._targetInst, null, event);
+ }
+}
+
+function accumulateTwoPhaseDispatches(events) {
+ forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
+}
+
+function accumulateTwoPhaseDispatchesSkipTarget(events) {
+ forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);
+}
+
+
+
+function accumulateDirectDispatches(events) {
+ forEachAccumulated(events, accumulateDirectDispatchesSingle);
+}
+
+/* eslint valid-typeof: 0 */
+
+var EVENT_POOL_SIZE = 10;
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var EventInterface = {
+ type: null,
+ target: null,
+ // currentTarget is set when dispatching; no use in copying it here
+ currentTarget: function () {
+ return null;
+ },
+ eventPhase: null,
+ bubbles: null,
+ cancelable: null,
+ timeStamp: function (event) {
+ return event.timeStamp || Date.now();
+ },
+ defaultPrevented: null,
+ isTrusted: null
+};
+
+function functionThatReturnsTrue() {
+ return true;
+}
+
+function functionThatReturnsFalse() {
+ return false;
+}
+
+/**
+ * Synthetic events are dispatched by event plugins, typically in response to a
+ * top-level event delegation handler.
+ *
+ * These systems should generally use pooling to reduce the frequency of garbage
+ * collection. The system should check `isPersistent` to determine whether the
+ * event should be released into the pool after being dispatched. Users that
+ * need a persisted event should invoke `persist`.
+ *
+ * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
+ * normalizing browser quirks. Subclasses do not necessarily have to implement a
+ * DOM interface; custom application-specific events can also subclass this.
+ *
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {*} targetInst Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @param {DOMEventTarget} nativeEventTarget Target node.
+ */
+function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
+ {
+ // these have a getter/setter for warnings
+ delete this.nativeEvent;
+ delete this.preventDefault;
+ delete this.stopPropagation;
+ delete this.isDefaultPrevented;
+ delete this.isPropagationStopped;
+ }
+
+ this.dispatchConfig = dispatchConfig;
+ this._targetInst = targetInst;
+ this.nativeEvent = nativeEvent;
+
+ var Interface = this.constructor.Interface;
+ for (var propName in Interface) {
+ if (!Interface.hasOwnProperty(propName)) {
+ continue;
+ }
+ {
+ delete this[propName]; // this has a getter/setter for warnings
+ }
+ var normalize = Interface[propName];
+ if (normalize) {
+ this[propName] = normalize(nativeEvent);
+ } else {
+ if (propName === 'target') {
+ this.target = nativeEventTarget;
+ } else {
+ this[propName] = nativeEvent[propName];
+ }
+ }
+ }
+
+ var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
+ if (defaultPrevented) {
+ this.isDefaultPrevented = functionThatReturnsTrue;
+ } else {
+ this.isDefaultPrevented = functionThatReturnsFalse;
+ }
+ this.isPropagationStopped = functionThatReturnsFalse;
+ return this;
+}
+
+_assign(SyntheticEvent.prototype, {
+ preventDefault: function () {
+ this.defaultPrevented = true;
+ var event = this.nativeEvent;
+ if (!event) {
+ return;
+ }
+
+ if (event.preventDefault) {
+ event.preventDefault();
+ } else if (typeof event.returnValue !== 'unknown') {
+ event.returnValue = false;
+ }
+ this.isDefaultPrevented = functionThatReturnsTrue;
+ },
+
+ stopPropagation: function () {
+ var event = this.nativeEvent;
+ if (!event) {
+ return;
+ }
+
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ } else if (typeof event.cancelBubble !== 'unknown') {
+ // The ChangeEventPlugin registers a "propertychange" event for
+ // IE. This event does not support bubbling or cancelling, and
+ // any references to cancelBubble throw "Member not found". A
+ // typeof check of "unknown" circumvents this issue (and is also
+ // IE specific).
+ event.cancelBubble = true;
+ }
+
+ this.isPropagationStopped = functionThatReturnsTrue;
+ },
+
+ /**
+ * We release all dispatched `SyntheticEvent`s after each event loop, adding
+ * them back into the pool. This allows a way to hold onto a reference that
+ * won't be added back into the pool.
+ */
+ persist: function () {
+ this.isPersistent = functionThatReturnsTrue;
+ },
+
+ /**
+ * Checks if this event should be released back into the pool.
+ *
+ * @return {boolean} True if this should not be released, false otherwise.
+ */
+ isPersistent: functionThatReturnsFalse,
+
+ /**
+ * `PooledClass` looks for `destructor` on each instance it releases.
+ */
+ destructor: function () {
+ var Interface = this.constructor.Interface;
+ for (var propName in Interface) {
+ {
+ Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
+ }
+ }
+ this.dispatchConfig = null;
+ this._targetInst = null;
+ this.nativeEvent = null;
+ this.isDefaultPrevented = functionThatReturnsFalse;
+ this.isPropagationStopped = functionThatReturnsFalse;
+ this._dispatchListeners = null;
+ this._dispatchInstances = null;
+ {
+ Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
+ Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
+ Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
+ Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
+ Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
+ }
+ }
+});
+
+SyntheticEvent.Interface = EventInterface;
+
+/**
+ * Helper to reduce boilerplate when creating subclasses.
+ */
+SyntheticEvent.extend = function (Interface) {
+ var Super = this;
+
+ var E = function () {};
+ E.prototype = Super.prototype;
+ var prototype = new E();
+
+ function Class() {
+ return Super.apply(this, arguments);
+ }
+ _assign(prototype, Class.prototype);
+ Class.prototype = prototype;
+ Class.prototype.constructor = Class;
+
+ Class.Interface = _assign({}, Super.Interface, Interface);
+ Class.extend = Super.extend;
+ addEventPoolingTo(Class);
+
+ return Class;
+};
+
+addEventPoolingTo(SyntheticEvent);
+
+/**
+ * Helper to nullify syntheticEvent instance properties when destructing
+ *
+ * @param {String} propName
+ * @param {?object} getVal
+ * @return {object} defineProperty object
+ */
+function getPooledWarningPropertyDefinition(propName, getVal) {
+ var isFunction = typeof getVal === 'function';
+ return {
+ configurable: true,
+ set: set,
+ get: get
+ };
+
+ function set(val) {
+ var action = isFunction ? 'setting the method' : 'setting the property';
+ warn(action, 'This is effectively a no-op');
+ return val;
+ }
+
+ function get() {
+ var action = isFunction ? 'accessing the method' : 'accessing the property';
+ var result = isFunction ? 'This is a no-op function' : 'This is set to null';
+ warn(action, result);
+ return getVal;
+ }
+
+ function warn(action, result) {
+ var warningCondition = false;
+ !warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
+ }
+}
+
+function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
+ var EventConstructor = this;
+ if (EventConstructor.eventPool.length) {
+ var instance = EventConstructor.eventPool.pop();
+ EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
+ return instance;
+ }
+ return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
+}
+
+function releasePooledEvent(event) {
+ var EventConstructor = this;
+ !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
+ event.destructor();
+ if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
+ EventConstructor.eventPool.push(event);
+ }
+}
+
+function addEventPoolingTo(EventConstructor) {
+ EventConstructor.eventPool = [];
+ EventConstructor.getPooled = getPooledEvent;
+ EventConstructor.release = releasePooledEvent;
+}
+
+/**
+ * `touchHistory` isn't actually on the native event, but putting it in the
+ * interface will ensure that it is cleaned up when pooled/destroyed. The
+ * `ResponderEventPlugin` will populate it appropriately.
+ */
+var ResponderSyntheticEvent = SyntheticEvent.extend({
+ touchHistory: function (nativeEvent) {
+ return null; // Actually doesn't even look at the native event.
+ }
+});
+
+// Note: ideally these would be imported from DOMTopLevelEventTypes,
+// but our build system currently doesn't let us do that from a fork.
+
+var TOP_TOUCH_START = 'touchstart';
+var TOP_TOUCH_MOVE = 'touchmove';
+var TOP_TOUCH_END = 'touchend';
+var TOP_TOUCH_CANCEL = 'touchcancel';
+var TOP_SCROLL = 'scroll';
+var TOP_SELECTION_CHANGE = 'selectionchange';
+var TOP_MOUSE_DOWN = 'mousedown';
+var TOP_MOUSE_MOVE = 'mousemove';
+var TOP_MOUSE_UP = 'mouseup';
+
+function isStartish(topLevelType) {
+ return topLevelType === TOP_TOUCH_START || topLevelType === TOP_MOUSE_DOWN;
+}
+
+function isMoveish(topLevelType) {
+ return topLevelType === TOP_TOUCH_MOVE || topLevelType === TOP_MOUSE_MOVE;
+}
+
+function isEndish(topLevelType) {
+ return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL || topLevelType === TOP_MOUSE_UP;
+}
+
+var startDependencies = [TOP_TOUCH_START, TOP_MOUSE_DOWN];
+var moveDependencies = [TOP_TOUCH_MOVE, TOP_MOUSE_MOVE];
+var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_MOUSE_UP];
+
+/**
+ * Tracks the position and time of each active touch by `touch.identifier`. We
+ * should typically only see IDs in the range of 1-20 because IDs get recycled
+ * when touches end and start again.
+ */
+
+
+var MAX_TOUCH_BANK = 20;
+var touchBank = [];
+var touchHistory = {
+ touchBank: touchBank,
+ numberActiveTouches: 0,
+ // If there is only one active touch, we remember its location. This prevents
+ // us having to loop through all of the touches all the time in the most
+ // common case.
+ indexOfSingleActiveTouch: -1,
+ mostRecentTimeStamp: 0
+};
+
+function timestampForTouch(touch) {
+ // The legacy internal implementation provides "timeStamp", which has been
+ // renamed to "timestamp". Let both work for now while we iron it out
+ // TODO (evv): rename timeStamp to timestamp in internal code
+ return touch.timeStamp || touch.timestamp;
+}
+
+/**
+ * TODO: Instead of making gestures recompute filtered velocity, we could
+ * include a built in velocity computation that can be reused globally.
+ */
+function createTouchRecord(touch) {
+ return {
+ touchActive: true,
+ startPageX: touch.pageX,
+ startPageY: touch.pageY,
+ startTimeStamp: timestampForTouch(touch),
+ currentPageX: touch.pageX,
+ currentPageY: touch.pageY,
+ currentTimeStamp: timestampForTouch(touch),
+ previousPageX: touch.pageX,
+ previousPageY: touch.pageY,
+ previousTimeStamp: timestampForTouch(touch)
+ };
+}
+
+function resetTouchRecord(touchRecord, touch) {
+ touchRecord.touchActive = true;
+ touchRecord.startPageX = touch.pageX;
+ touchRecord.startPageY = touch.pageY;
+ touchRecord.startTimeStamp = timestampForTouch(touch);
+ touchRecord.currentPageX = touch.pageX;
+ touchRecord.currentPageY = touch.pageY;
+ touchRecord.currentTimeStamp = timestampForTouch(touch);
+ touchRecord.previousPageX = touch.pageX;
+ touchRecord.previousPageY = touch.pageY;
+ touchRecord.previousTimeStamp = timestampForTouch(touch);
+}
+
+function getTouchIdentifier(_ref) {
+ var identifier = _ref.identifier;
+
+ !(identifier != null) ? invariant(false, 'Touch object is missing identifier.') : void 0;
+ {
+ !(identifier <= MAX_TOUCH_BANK) ? warningWithoutStack$1(false, 'Touch identifier %s is greater than maximum supported %s which causes ' + 'performance issues backfilling array locations for all of the indices.', identifier, MAX_TOUCH_BANK) : void 0;
+ }
+ return identifier;
+}
+
+function recordTouchStart(touch) {
+ var identifier = getTouchIdentifier(touch);
+ var touchRecord = touchBank[identifier];
+ if (touchRecord) {
+ resetTouchRecord(touchRecord, touch);
+ } else {
+ touchBank[identifier] = createTouchRecord(touch);
+ }
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
+}
+
+function recordTouchMove(touch) {
+ var touchRecord = touchBank[getTouchIdentifier(touch)];
+ if (touchRecord) {
+ touchRecord.touchActive = true;
+ touchRecord.previousPageX = touchRecord.currentPageX;
+ touchRecord.previousPageY = touchRecord.currentPageY;
+ touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
+ touchRecord.currentPageX = touch.pageX;
+ touchRecord.currentPageY = touch.pageY;
+ touchRecord.currentTimeStamp = timestampForTouch(touch);
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
+ } else {
+ console.error('Cannot record touch move without a touch start.\n' + 'Touch Move: %s\n', 'Touch Bank: %s', printTouch(touch), printTouchBank());
+ }
+}
+
+function recordTouchEnd(touch) {
+ var touchRecord = touchBank[getTouchIdentifier(touch)];
+ if (touchRecord) {
+ touchRecord.touchActive = false;
+ touchRecord.previousPageX = touchRecord.currentPageX;
+ touchRecord.previousPageY = touchRecord.currentPageY;
+ touchRecord.previousTimeStamp = touchRecord.currentTimeStamp;
+ touchRecord.currentPageX = touch.pageX;
+ touchRecord.currentPageY = touch.pageY;
+ touchRecord.currentTimeStamp = timestampForTouch(touch);
+ touchHistory.mostRecentTimeStamp = timestampForTouch(touch);
+ } else {
+ console.error('Cannot record touch end without a touch start.\n' + 'Touch End: %s\n', 'Touch Bank: %s', printTouch(touch), printTouchBank());
+ }
+}
+
+function printTouch(touch) {
+ return JSON.stringify({
+ identifier: touch.identifier,
+ pageX: touch.pageX,
+ pageY: touch.pageY,
+ timestamp: timestampForTouch(touch)
+ });
+}
+
+function printTouchBank() {
+ var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK));
+ if (touchBank.length > MAX_TOUCH_BANK) {
+ printed += ' (original size: ' + touchBank.length + ')';
+ }
+ return printed;
+}
+
+var ResponderTouchHistoryStore = {
+ recordTouchTrack: function (topLevelType, nativeEvent) {
+ if (isMoveish(topLevelType)) {
+ nativeEvent.changedTouches.forEach(recordTouchMove);
+ } else if (isStartish(topLevelType)) {
+ nativeEvent.changedTouches.forEach(recordTouchStart);
+ touchHistory.numberActiveTouches = nativeEvent.touches.length;
+ if (touchHistory.numberActiveTouches === 1) {
+ touchHistory.indexOfSingleActiveTouch = nativeEvent.touches[0].identifier;
+ }
+ } else if (isEndish(topLevelType)) {
+ nativeEvent.changedTouches.forEach(recordTouchEnd);
+ touchHistory.numberActiveTouches = nativeEvent.touches.length;
+ if (touchHistory.numberActiveTouches === 1) {
+ for (var i = 0; i < touchBank.length; i++) {
+ var touchTrackToCheck = touchBank[i];
+ if (touchTrackToCheck != null && touchTrackToCheck.touchActive) {
+ touchHistory.indexOfSingleActiveTouch = i;
+ break;
+ }
+ }
+ {
+ var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch];
+ !(activeRecord != null && activeRecord.touchActive) ? warningWithoutStack$1(false, 'Cannot find single active touch.') : void 0;
+ }
+ }
+ }
+ },
+
+
+ touchHistory: touchHistory
+};
+
+/**
+ * Accumulates items that must not be null or undefined.
+ *
+ * This is used to conserve memory by avoiding array allocations.
+ *
+ * @return {*|array<*>} An accumulation of items.
+ */
+function accumulate(current, next) {
+ !(next != null) ? invariant(false, 'accumulate(...): Accumulated items must be not be null or undefined.') : void 0;
+
+ if (current == null) {
+ return next;
+ }
+
+ // Both are not empty. Warning: Never call x.concat(y) when you are not
+ // certain that x is an Array (x could be a string with concat method).
+ if (Array.isArray(current)) {
+ return current.concat(next);
+ }
+
+ if (Array.isArray(next)) {
+ return [current].concat(next);
+ }
+
+ return [current, next];
+}
+
+/**
+ * Instance of element that should respond to touch/move types of interactions,
+ * as indicated explicitly by relevant callbacks.
+ */
+var responderInst = null;
+
+/**
+ * Count of current touches. A textInput should become responder iff the
+ * selection changes while there is a touch on the screen.
+ */
+var trackedTouchCount = 0;
+
+var changeResponder = function (nextResponderInst, blockHostResponder) {
+ var oldResponderInst = responderInst;
+ responderInst = nextResponderInst;
+ if (ResponderEventPlugin.GlobalResponderHandler !== null) {
+ ResponderEventPlugin.GlobalResponderHandler.onChange(oldResponderInst, nextResponderInst, blockHostResponder);
+ }
+};
+
+var eventTypes = {
+ /**
+ * On a `touchStart`/`mouseDown`, is it desired that this element become the
+ * responder?
+ */
+ startShouldSetResponder: {
+ phasedRegistrationNames: {
+ bubbled: 'onStartShouldSetResponder',
+ captured: 'onStartShouldSetResponderCapture'
+ },
+ dependencies: startDependencies
+ },
+
+ /**
+ * On a `scroll`, is it desired that this element become the responder? This
+ * is usually not needed, but should be used to retroactively infer that a
+ * `touchStart` had occurred during momentum scroll. During a momentum scroll,
+ * a touch start will be immediately followed by a scroll event if the view is
+ * currently scrolling.
+ *
+ * TODO: This shouldn't bubble.
+ */
+ scrollShouldSetResponder: {
+ phasedRegistrationNames: {
+ bubbled: 'onScrollShouldSetResponder',
+ captured: 'onScrollShouldSetResponderCapture'
+ },
+ dependencies: [TOP_SCROLL]
+ },
+
+ /**
+ * On text selection change, should this element become the responder? This
+ * is needed for text inputs or other views with native selection, so the
+ * JS view can claim the responder.
+ *
+ * TODO: This shouldn't bubble.
+ */
+ selectionChangeShouldSetResponder: {
+ phasedRegistrationNames: {
+ bubbled: 'onSelectionChangeShouldSetResponder',
+ captured: 'onSelectionChangeShouldSetResponderCapture'
+ },
+ dependencies: [TOP_SELECTION_CHANGE]
+ },
+
+ /**
+ * On a `touchMove`/`mouseMove`, is it desired that this element become the
+ * responder?
+ */
+ moveShouldSetResponder: {
+ phasedRegistrationNames: {
+ bubbled: 'onMoveShouldSetResponder',
+ captured: 'onMoveShouldSetResponderCapture'
+ },
+ dependencies: moveDependencies
+ },
+
+ /**
+ * Direct responder events dispatched directly to responder. Do not bubble.
+ */
+ responderStart: {
+ registrationName: 'onResponderStart',
+ dependencies: startDependencies
+ },
+ responderMove: {
+ registrationName: 'onResponderMove',
+ dependencies: moveDependencies
+ },
+ responderEnd: {
+ registrationName: 'onResponderEnd',
+ dependencies: endDependencies
+ },
+ responderRelease: {
+ registrationName: 'onResponderRelease',
+ dependencies: endDependencies
+ },
+ responderTerminationRequest: {
+ registrationName: 'onResponderTerminationRequest',
+ dependencies: []
+ },
+ responderGrant: {
+ registrationName: 'onResponderGrant',
+ dependencies: []
+ },
+ responderReject: {
+ registrationName: 'onResponderReject',
+ dependencies: []
+ },
+ responderTerminate: {
+ registrationName: 'onResponderTerminate',
+ dependencies: []
+ }
+};
+
+/**
+ *
+ * Responder System:
+ * ----------------
+ *
+ * - A global, solitary "interaction lock" on a view.
+ * - If a node becomes the responder, it should convey visual feedback
+ * immediately to indicate so, either by highlighting or moving accordingly.
+ * - To be the responder means, that touches are exclusively important to that
+ * responder view, and no other view.
+ * - While touches are still occurring, the responder lock can be transferred to
+ * a new view, but only to increasingly "higher" views (meaning ancestors of
+ * the current responder).
+ *
+ * Responder being granted:
+ * ------------------------
+ *
+ * - Touch starts, moves, and scrolls can cause an ID to become the responder.
+ * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to
+ * the "appropriate place".
+ * - If nothing is currently the responder, the "appropriate place" is the
+ * initiating event's `targetID`.
+ * - If something *is* already the responder, the "appropriate place" is the
+ * first common ancestor of the event target and the current `responderInst`.
+ * - Some negotiation happens: See the timing diagram below.
+ * - Scrolled views automatically become responder. The reasoning is that a
+ * platform scroll view that isn't built on top of the responder system has
+ * began scrolling, and the active responder must now be notified that the
+ * interaction is no longer locked to it - the system has taken over.
+ *
+ * - Responder being released:
+ * As soon as no more touches that *started* inside of descendants of the
+ * *current* responderInst, an `onResponderRelease` event is dispatched to the
+ * current responder, and the responder lock is released.
+ *
+ * TODO:
+ * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that
+ * determines if the responder lock should remain.
+ * - If a view shouldn't "remain" the responder, any active touches should by
+ * default be considered "dead" and do not influence future negotiations or
+ * bubble paths. It should be as if those touches do not exist.
+ * -- For multitouch: Usually a translate-z will choose to "remain" responder
+ * after one out of many touches ended. For translate-y, usually the view
+ * doesn't wish to "remain" responder after one of many touches end.
+ * - Consider building this on top of a `stopPropagation` model similar to
+ * `W3C` events.
+ * - Ensure that `onResponderTerminate` is called on touch cancels, whether or
+ * not `onResponderTerminationRequest` returns `true` or `false`.
+ *
+ */
+
+/* Negotiation Performed
+ +-----------------------+
+ / \
+Process low level events to + Current Responder + wantsResponderID
+determine who to perform negot-| (if any exists at all) |
+iation/transition | Otherwise just pass through|
+-------------------------------+----------------------------+------------------+
+Bubble to find first ID | |
+to return true:wantsResponderID| |
+ | |
+ +-------------+ | |
+ | onTouchStart| | |
+ +------+------+ none | |
+ | return| |
++-----------v-------------+true| +------------------------+ |
+|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+
++-----------+-------------+ | +------------------------+ | |
+ | | | +--------+-------+
+ | returned true for| false:REJECT +-------->|onResponderReject
+ | wantsResponderID | | | +----------------+
+ | (now attempt | +------------------+-----+ |
+ | handoff) | | onResponder | |
+ +------------------->| TerminationRequest| |
+ | +------------------+-----+ |
+ | | | +----------------+
+ | true:GRANT +-------->|onResponderGrant|
+ | | +--------+-------+
+ | +------------------------+ | |
+ | | onResponderTerminate |<-----------+
+ | +------------------+-----+ |
+ | | | +----------------+
+ | +-------->|onResponderStart|
+ | | +----------------+
+Bubble to find first ID | |
+to return true:wantsResponderID| |
+ | |
+ +-------------+ | |
+ | onTouchMove | | |
+ +------+------+ none | |
+ | return| |
++-----------v-------------+true| +------------------------+ |
+|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+
++-----------+-------------+ | +------------------------+ | |
+ | | | +--------+-------+
+ | returned true for| false:REJECT +-------->|onResponderRejec|
+ | wantsResponderID | | | +----------------+
+ | (now attempt | +------------------+-----+ |
+ | handoff) | | onResponder | |
+ +------------------->| TerminationRequest| |
+ | +------------------+-----+ |
+ | | | +----------------+
+ | true:GRANT +-------->|onResponderGrant|
+ | | +--------+-------+
+ | +------------------------+ | |
+ | | onResponderTerminate |<-----------+
+ | +------------------+-----+ |
+ | | | +----------------+
+ | +-------->|onResponderMove |
+ | | +----------------+
+ | |
+ | |
+ Some active touch started| |
+ inside current responder | +------------------------+ |
+ +------------------------->| onResponderEnd | |
+ | | +------------------------+ |
+ +---+---------+ | |
+ | onTouchEnd | | |
+ +---+---------+ | |
+ | | +------------------------+ |
+ +------------------------->| onResponderEnd | |
+ No active touches started| +-----------+------------+ |
+ inside current responder | | |
+ | v |
+ | +------------------------+ |
+ | | onResponderRelease | |
+ | +------------------------+ |
+ | |
+ + + */
+
+/**
+ * A note about event ordering in the `EventPluginHub`.
+ *
+ * Suppose plugins are injected in the following order:
+ *
+ * `[R, S, C]`
+ *
+ * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
+ * `onClick` etc) and `R` is `ResponderEventPlugin`.
+ *
+ * "Deferred-Dispatched Events":
+ *
+ * - The current event plugin system will traverse the list of injected plugins,
+ * in order, and extract events by collecting the plugin's return value of
+ * `extractEvents()`.
+ * - These events that are returned from `extractEvents` are "deferred
+ * dispatched events".
+ * - When returned from `extractEvents`, deferred-dispatched events contain an
+ * "accumulation" of deferred dispatches.
+ * - These deferred dispatches are accumulated/collected before they are
+ * returned, but processed at a later time by the `EventPluginHub` (hence the
+ * name deferred).
+ *
+ * In the process of returning their deferred-dispatched events, event plugins
+ * themselves can dispatch events on-demand without returning them from
+ * `extractEvents`. Plugins might want to do this, so that they can use event
+ * dispatching as a tool that helps them decide which events should be extracted
+ * in the first place.
+ *
+ * "On-Demand-Dispatched Events":
+ *
+ * - On-demand-dispatched events are not returned from `extractEvents`.
+ * - On-demand-dispatched events are dispatched during the process of returning
+ * the deferred-dispatched events.
+ * - They should not have side effects.
+ * - They should be avoided, and/or eventually be replaced with another
+ * abstraction that allows event plugins to perform multiple "rounds" of event
+ * extraction.
+ *
+ * Therefore, the sequence of event dispatches becomes:
+ *
+ * - `R`s on-demand events (if any) (dispatched by `R` on-demand)
+ * - `S`s on-demand events (if any) (dispatched by `S` on-demand)
+ * - `C`s on-demand events (if any) (dispatched by `C` on-demand)
+ * - `R`s extracted events (if any) (dispatched by `EventPluginHub`)
+ * - `S`s extracted events (if any) (dispatched by `EventPluginHub`)
+ * - `C`s extracted events (if any) (dispatched by `EventPluginHub`)
+ *
+ * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
+ * on-demand dispatch returns `true` (and some other details are satisfied) the
+ * `onResponderGrant` deferred dispatched event is returned from
+ * `extractEvents`. The sequence of dispatch executions in this case
+ * will appear as follows:
+ *
+ * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
+ * - `touchStartCapture` (`EventPluginHub` dispatches as usual)
+ * - `touchStart` (`EventPluginHub` dispatches as usual)
+ * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual)
+ */
+
+function setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) ? eventTypes.moveShouldSetResponder : topLevelType === TOP_SELECTION_CHANGE ? eventTypes.selectionChangeShouldSetResponder : eventTypes.scrollShouldSetResponder;
+
+ // TODO: stop one short of the current responder.
+ var bubbleShouldSetFrom = !responderInst ? targetInst : getLowestCommonAncestor(responderInst, targetInst);
+
+ // When capturing/bubbling the "shouldSet" event, we want to skip the target
+ // (deepest ID) if it happens to be the current responder. The reasoning:
+ // It's strange to get an `onMoveShouldSetResponder` when you're *already*
+ // the responder.
+ var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst;
+ var shouldSetEvent = ResponderSyntheticEvent.getPooled(shouldSetEventType, bubbleShouldSetFrom, nativeEvent, nativeEventTarget);
+ shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
+ if (skipOverBubbleShouldSetFrom) {
+ accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent);
+ } else {
+ accumulateTwoPhaseDispatches(shouldSetEvent);
+ }
+ var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
+ if (!shouldSetEvent.isPersistent()) {
+ shouldSetEvent.constructor.release(shouldSetEvent);
+ }
+
+ if (!wantsResponderInst || wantsResponderInst === responderInst) {
+ return null;
+ }
+ var extracted = void 0;
+ var grantEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderGrant, wantsResponderInst, nativeEvent, nativeEventTarget);
+ grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
+
+ accumulateDirectDispatches(grantEvent);
+ var blockHostResponder = executeDirectDispatch(grantEvent) === true;
+ if (responderInst) {
+ var terminationRequestEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderTerminationRequest, responderInst, nativeEvent, nativeEventTarget);
+ terminationRequestEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
+ accumulateDirectDispatches(terminationRequestEvent);
+ var shouldSwitch = !hasDispatches(terminationRequestEvent) || executeDirectDispatch(terminationRequestEvent);
+ if (!terminationRequestEvent.isPersistent()) {
+ terminationRequestEvent.constructor.release(terminationRequestEvent);
+ }
+
+ if (shouldSwitch) {
+ var terminateEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderTerminate, responderInst, nativeEvent, nativeEventTarget);
+ terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
+ accumulateDirectDispatches(terminateEvent);
+ extracted = accumulate(extracted, [grantEvent, terminateEvent]);
+ changeResponder(wantsResponderInst, blockHostResponder);
+ } else {
+ var rejectEvent = ResponderSyntheticEvent.getPooled(eventTypes.responderReject, wantsResponderInst, nativeEvent, nativeEventTarget);
+ rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
+ accumulateDirectDispatches(rejectEvent);
+ extracted = accumulate(extracted, rejectEvent);
+ }
+ } else {
+ extracted = accumulate(extracted, grantEvent);
+ changeResponder(wantsResponderInst, blockHostResponder);
+ }
+ return extracted;
+}
+
+/**
+ * A transfer is a negotiation between a currently set responder and the next
+ * element to claim responder status. Any start event could trigger a transfer
+ * of responderInst. Any move event could trigger a transfer.
+ *
+ * @param {string} topLevelType Record from `BrowserEventConstants`.
+ * @return {boolean} True if a transfer of responder could possibly occur.
+ */
+function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) {
+ return topLevelInst && (
+ // responderIgnoreScroll: We are trying to migrate away from specifically
+ // tracking native scroll events here and responderIgnoreScroll indicates we
+ // will send topTouchCancel to handle canceling touch events instead
+ topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll || trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE || isStartish(topLevelType) || isMoveish(topLevelType));
+}
+
+/**
+ * Returns whether or not this touch end event makes it such that there are no
+ * longer any touches that started inside of the current `responderInst`.
+ *
+ * @param {NativeEvent} nativeEvent Native touch end event.
+ * @return {boolean} Whether or not this touch end event ends the responder.
+ */
+function noResponderTouches(nativeEvent) {
+ var touches = nativeEvent.touches;
+ if (!touches || touches.length === 0) {
+ return true;
+ }
+ for (var i = 0; i < touches.length; i++) {
+ var activeTouch = touches[i];
+ var target = activeTouch.target;
+ if (target !== null && target !== undefined && target !== 0) {
+ // Is the original touch location inside of the current responder?
+ var targetInst = getInstanceFromNode$1(target);
+ if (isAncestor(responderInst, targetInst)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+var ResponderEventPlugin = {
+ /* For unit testing only */
+ _getResponder: function () {
+ return responderInst;
+ },
+
+ eventTypes: eventTypes,
+
+ /**
+ * We must be resilient to `targetInst` being `null` on `touchMove` or
+ * `touchEnd`. On certain platforms, this means that a native scroll has
+ * assumed control and the original touch targets are destroyed.
+ */
+ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ if (isStartish(topLevelType)) {
+ trackedTouchCount += 1;
+ } else if (isEndish(topLevelType)) {
+ if (trackedTouchCount >= 0) {
+ trackedTouchCount -= 1;
+ } else {
+ console.error('Ended a touch event which was not counted in `trackedTouchCount`.');
+ return null;
+ }
+ }
+
+ ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent);
+
+ var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent) ? setResponderAndExtractTransfer(topLevelType, targetInst, nativeEvent, nativeEventTarget) : null;
+ // Responder may or may not have transferred on a new touch start/move.
+ // Regardless, whoever is the responder after any potential transfer, we
+ // direct all touch start/move/ends to them in the form of
+ // `onResponderMove/Start/End`. These will be called for *every* additional
+ // finger that move/start/end, dispatched directly to whoever is the
+ // current responder at that moment, until the responder is "released".
+ //
+ // These multiple individual change touch events are are always bookended
+ // by `onResponderGrant`, and one of
+ // (`onResponderRelease/onResponderTerminate`).
+ var isResponderTouchStart = responderInst && isStartish(topLevelType);
+ var isResponderTouchMove = responderInst && isMoveish(topLevelType);
+ var isResponderTouchEnd = responderInst && isEndish(topLevelType);
+ var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove ? eventTypes.responderMove : isResponderTouchEnd ? eventTypes.responderEnd : null;
+
+ if (incrementalTouch) {
+ var gesture = ResponderSyntheticEvent.getPooled(incrementalTouch, responderInst, nativeEvent, nativeEventTarget);
+ gesture.touchHistory = ResponderTouchHistoryStore.touchHistory;
+ accumulateDirectDispatches(gesture);
+ extracted = accumulate(extracted, gesture);
+ }
+
+ var isResponderTerminate = responderInst && topLevelType === TOP_TOUCH_CANCEL;
+ var isResponderRelease = responderInst && !isResponderTerminate && isEndish(topLevelType) && noResponderTouches(nativeEvent);
+ var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease ? eventTypes.responderRelease : null;
+ if (finalTouch) {
+ var finalEvent = ResponderSyntheticEvent.getPooled(finalTouch, responderInst, nativeEvent, nativeEventTarget);
+ finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
+ accumulateDirectDispatches(finalEvent);
+ extracted = accumulate(extracted, finalEvent);
+ changeResponder(null);
+ }
+
+ return extracted;
+ },
+
+ GlobalResponderHandler: null,
+
+ injection: {
+ /**
+ * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler
+ * Object that handles any change in responder. Use this to inject
+ * integration with an existing touch handling system etc.
+ */
+ injectGlobalResponderHandler: function (GlobalResponderHandler) {
+ ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler;
+ }
+ }
+};
+
+// Inject react-dom's ComponentTree into this module.
+// Keep in sync with ReactDOM.js and ReactTestUtils.js:
+var _ReactDOM$__SECRET_IN = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
+var getInstanceFromNode = _ReactDOM$__SECRET_IN[0];
+var getNodeFromInstance = _ReactDOM$__SECRET_IN[1];
+var getFiberCurrentPropsFromNode = _ReactDOM$__SECRET_IN[2];
+var injectEventPluginsByName = _ReactDOM$__SECRET_IN[3];
+
+
+setComponentTree(getFiberCurrentPropsFromNode, getInstanceFromNode, getNodeFromInstance);
+
+
+
+var ReactDOMUnstableNativeDependencies = Object.freeze({
+ ResponderEventPlugin: ResponderEventPlugin,
+ ResponderTouchHistoryStore: ResponderTouchHistoryStore,
+ injectEventPluginsByName: injectEventPluginsByName
+});
+
+var unstableNativeDependencies = ReactDOMUnstableNativeDependencies;
+
+module.exports = unstableNativeDependencies;
+ })();
+}
diff --git a/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.production.min.js b/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.production.min.js
new file mode 100644
index 0000000000..8ad657393b
--- /dev/null
+++ b/node_modules/react-dom/cjs/react-dom-unstable-native-dependencies.production.min.js
@@ -0,0 +1,36 @@
+/** @license React v16.6.1
+ * react-dom-unstable-native-dependencies.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+'use strict';var k=require("react-dom"),l=require("object-assign");function aa(a,b,c,f,e,d,g,h){if(!a){a=void 0;if(void 0===b)a=Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[c,f,e,d,g,h],ba=0;a=Error(b.replace(/%s/g,function(){return u[ba++]}));a.name="Invariant Violation"}a.framesToPop=1;throw a;}}
+function m(a){for(var b=arguments.length-1,c="https://reactjs.org/docs/error-decoder.html?invariant="+a,f=0;fthis.eventPool.length&&this.eventPool.push(a)}
+function E(a){a.eventPool=[];a.getPooled=ea;a.release=fa}var F=D.extend({touchHistory:function(){return null}});function G(a){return"touchstart"===a||"mousedown"===a}function H(a){return"touchmove"===a||"mousemove"===a}function I(a){return"touchend"===a||"touchcancel"===a||"mouseup"===a}var J=["touchstart","mousedown"],K=["touchmove","mousemove"],L=["touchcancel","touchend","mouseup"],M=[],N={touchBank:M,numberActiveTouches:0,indexOfSingleActiveTouch:-1,mostRecentTimeStamp:0};
+function O(a){return a.timeStamp||a.timestamp}function P(a){a=a.identifier;null==a?m("138"):void 0;return a}
+function ha(a){var b=P(a),c=M[b];c?(c.touchActive=!0,c.startPageX=a.pageX,c.startPageY=a.pageY,c.startTimeStamp=O(a),c.currentPageX=a.pageX,c.currentPageY=a.pageY,c.currentTimeStamp=O(a),c.previousPageX=a.pageX,c.previousPageY=a.pageY,c.previousTimeStamp=O(a)):(c={touchActive:!0,startPageX:a.pageX,startPageY:a.pageY,startTimeStamp:O(a),currentPageX:a.pageX,currentPageY:a.pageY,currentTimeStamp:O(a),previousPageX:a.pageX,previousPageY:a.pageY,previousTimeStamp:O(a)},M[b]=c);N.mostRecentTimeStamp=O(a)}
+function ia(a){var b=M[P(a)];b?(b.touchActive=!0,b.previousPageX=b.currentPageX,b.previousPageY=b.currentPageY,b.previousTimeStamp=b.currentTimeStamp,b.currentPageX=a.pageX,b.currentPageY=a.pageY,b.currentTimeStamp=O(a),N.mostRecentTimeStamp=O(a)):console.error("Cannot record touch move without a touch start.\nTouch Move: %s\n","Touch Bank: %s",Q(a),R())}
+function ja(a){var b=M[P(a)];b?(b.touchActive=!1,b.previousPageX=b.currentPageX,b.previousPageY=b.currentPageY,b.previousTimeStamp=b.currentTimeStamp,b.currentPageX=a.pageX,b.currentPageY=a.pageY,b.currentTimeStamp=O(a),N.mostRecentTimeStamp=O(a)):console.error("Cannot record touch end without a touch start.\nTouch End: %s\n","Touch Bank: %s",Q(a),R())}function Q(a){return JSON.stringify({identifier:a.identifier,pageX:a.pageX,pageY:a.pageY,timestamp:O(a)})}
+function R(){var a=JSON.stringify(M.slice(0,20));20 -1) ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : void 0;
+ if (plugins[pluginIndex]) {
+ continue;
+ }
+ !pluginModule.extractEvents ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : void 0;
+ plugins[pluginIndex] = pluginModule;
+ var publishedEvents = pluginModule.eventTypes;
+ for (var eventName in publishedEvents) {
+ !publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : void 0;
+ }
+ }
+}
+
+/**
+ * Publishes an event so that it can be dispatched by the supplied plugin.
+ *
+ * @param {object} dispatchConfig Dispatch configuration for the event.
+ * @param {object} PluginModule Plugin publishing the event.
+ * @return {boolean} True if the event was successfully published.
+ * @private
+ */
+function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
+ !!eventNameDispatchConfigs.hasOwnProperty(eventName) ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : void 0;
+ eventNameDispatchConfigs[eventName] = dispatchConfig;
+
+ var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
+ if (phasedRegistrationNames) {
+ for (var phaseName in phasedRegistrationNames) {
+ if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
+ var phasedRegistrationName = phasedRegistrationNames[phaseName];
+ publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
+ }
+ }
+ return true;
+ } else if (dispatchConfig.registrationName) {
+ publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Publishes a registration name that is used to identify dispatched events.
+ *
+ * @param {string} registrationName Registration name to add.
+ * @param {object} PluginModule Plugin publishing the event.
+ * @private
+ */
+function publishRegistrationName(registrationName, pluginModule, eventName) {
+ !!registrationNameModules[registrationName] ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : void 0;
+ registrationNameModules[registrationName] = pluginModule;
+ registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
+
+ {
+ var lowerCasedName = registrationName.toLowerCase();
+ possibleRegistrationNames[lowerCasedName] = registrationName;
+
+ if (registrationName === 'onDoubleClick') {
+ possibleRegistrationNames.ondblclick = registrationName;
+ }
+ }
+}
+
+/**
+ * Registers plugins so that they can extract and dispatch events.
+ *
+ * @see {EventPluginHub}
+ */
+
+/**
+ * Ordered list of injected plugins.
+ */
+var plugins = [];
+
+/**
+ * Mapping from event name to dispatch config
+ */
+var eventNameDispatchConfigs = {};
+
+/**
+ * Mapping from registration name to plugin module
+ */
+var registrationNameModules = {};
+
+/**
+ * Mapping from registration name to event name
+ */
+var registrationNameDependencies = {};
+
+/**
+ * Mapping from lowercase registration names to the properly cased version,
+ * used to warn in the case of missing event handlers. Available
+ * only in true.
+ * @type {Object}
+ */
+var possibleRegistrationNames = {};
+// Trust the developer to only use possibleRegistrationNames in true
+
+/**
+ * Injects an ordering of plugins (by plugin name). This allows the ordering
+ * to be decoupled from injection of the actual plugins so that ordering is
+ * always deterministic regardless of packaging, on-the-fly injection, etc.
+ *
+ * @param {array} InjectedEventPluginOrder
+ * @internal
+ * @see {EventPluginHub.injection.injectEventPluginOrder}
+ */
+function injectEventPluginOrder(injectedEventPluginOrder) {
+ !!eventPluginOrder ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : void 0;
+ // Clone the ordering so it cannot be dynamically mutated.
+ eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
+ recomputePluginOrdering();
+}
+
+/**
+ * Injects plugins to be used by `EventPluginHub`. The plugin names must be
+ * in the ordering injected by `injectEventPluginOrder`.
+ *
+ * Plugins can be injected as part of page initialization or on-the-fly.
+ *
+ * @param {object} injectedNamesToPlugins Map from names to plugin modules.
+ * @internal
+ * @see {EventPluginHub.injection.injectEventPluginsByName}
+ */
+function injectEventPluginsByName(injectedNamesToPlugins) {
+ var isOrderingDirty = false;
+ for (var pluginName in injectedNamesToPlugins) {
+ if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
+ continue;
+ }
+ var pluginModule = injectedNamesToPlugins[pluginName];
+ if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
+ !!namesToPlugins[pluginName] ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : void 0;
+ namesToPlugins[pluginName] = pluginModule;
+ isOrderingDirty = true;
+ }
+ }
+ if (isOrderingDirty) {
+ recomputePluginOrdering();
+ }
+}
+
+/**
+ * Similar to invariant but only logs a warning if the condition is not met.
+ * This can be used to log issues in development environments in critical
+ * paths. Removing the logging code for production environments will keep the
+ * same logic and follow the same code paths.
+ */
+
+var warningWithoutStack = function () {};
+
+{
+ warningWithoutStack = function (condition, format) {
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
+ }
+
+ if (format === undefined) {
+ throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
+ }
+ if (args.length > 8) {
+ // Check before the condition to catch violations early.
+ throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
+ }
+ if (condition) {
+ return;
+ }
+ if (typeof console !== 'undefined') {
+ var argsWithFormat = args.map(function (item) {
+ return '' + item;
+ });
+ argsWithFormat.unshift('Warning: ' + format);
+
+ // We intentionally don't use spread (or .apply) directly because it
+ // breaks IE9: https://github.com/facebook/react/issues/13610
+ Function.prototype.apply.call(console.error, console, argsWithFormat);
+ }
+ try {
+ // --- Welcome to debugging React ---
+ // This error was thrown as a convenience so that you can use this stack
+ // to find the callsite that caused this warning to fire.
+ var argIndex = 0;
+ var message = 'Warning: ' + format.replace(/%s/g, function () {
+ return args[argIndex++];
+ });
+ throw new Error(message);
+ } catch (x) {}
+ };
+}
+
+var warningWithoutStack$1 = warningWithoutStack;
+
+var getFiberCurrentPropsFromNode = null;
+var getInstanceFromNode = null;
+var getNodeFromInstance = null;
+
+function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
+ getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
+ getInstanceFromNode = getInstanceFromNodeImpl;
+ getNodeFromInstance = getNodeFromInstanceImpl;
+ {
+ !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
+ }
+}
+
+var validateEventDispatches = void 0;
+{
+ validateEventDispatches = function (event) {
+ var dispatchListeners = event._dispatchListeners;
+ var dispatchInstances = event._dispatchInstances;
+
+ var listenersIsArr = Array.isArray(dispatchListeners);
+ var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
+
+ var instancesIsArr = Array.isArray(dispatchInstances);
+ var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
+
+ !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
+ };
+}
+
+/**
+ * Dispatch the event to the listener.
+ * @param {SyntheticEvent} event SyntheticEvent to handle
+ * @param {function} listener Application-level callback
+ * @param {*} inst Internal component instance
+ */
+function executeDispatch(event, listener, inst) {
+ var type = event.type || 'unknown-event';
+ event.currentTarget = getNodeFromInstance(inst);
+ invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
+ event.currentTarget = null;
+}
+
+/**
+ * Standard/simple iteration through an event's collected dispatches.
+ */
+function executeDispatchesInOrder(event) {
+ var dispatchListeners = event._dispatchListeners;
+ var dispatchInstances = event._dispatchInstances;
+ {
+ validateEventDispatches(event);
+ }
+ if (Array.isArray(dispatchListeners)) {
+ for (var i = 0; i < dispatchListeners.length; i++) {
+ if (event.isPropagationStopped()) {
+ break;
+ }
+ // Listeners and Instances are two parallel arrays that are always in sync.
+ executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
+ }
+ } else if (dispatchListeners) {
+ executeDispatch(event, dispatchListeners, dispatchInstances);
+ }
+ event._dispatchListeners = null;
+ event._dispatchInstances = null;
+}
+
+/**
+ * @see executeDispatchesInOrderStopAtTrueImpl
+ */
+
+
+/**
+ * Execution of a "direct" dispatch - there must be at most one dispatch
+ * accumulated on the event or it is considered an error. It doesn't really make
+ * sense for an event with multiple dispatches (bubbled) to keep track of the
+ * return values at each dispatch execution, but it does tend to make sense when
+ * dealing with "direct" dispatches.
+ *
+ * @return {*} The return value of executing the single dispatch.
+ */
+
+
+/**
+ * @param {SyntheticEvent} event
+ * @return {boolean} True iff number of dispatches accumulated is greater than 0.
+ */
+
+/**
+ * Accumulates items that must not be null or undefined into the first one. This
+ * is used to conserve memory by avoiding array allocations, and thus sacrifices
+ * API cleanness. Since `current` can be null before being passed in and not
+ * null after this function, make sure to assign it back to `current`:
+ *
+ * `a = accumulateInto(a, b);`
+ *
+ * This API should be sparingly used. Try `accumulate` for something cleaner.
+ *
+ * @return {*|array<*>} An accumulation of items.
+ */
+
+function accumulateInto(current, next) {
+ !(next != null) ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : void 0;
+
+ if (current == null) {
+ return next;
+ }
+
+ // Both are not empty. Warning: Never call x.concat(y) when you are not
+ // certain that x is an Array (x could be a string with concat method).
+ if (Array.isArray(current)) {
+ if (Array.isArray(next)) {
+ current.push.apply(current, next);
+ return current;
+ }
+ current.push(next);
+ return current;
+ }
+
+ if (Array.isArray(next)) {
+ // A bit too dangerous to mutate `next`.
+ return [current].concat(next);
+ }
+
+ return [current, next];
+}
+
+/**
+ * @param {array} arr an "accumulation" of items which is either an Array or
+ * a single item. Useful when paired with the `accumulate` module. This is a
+ * simple utility that allows us to reason about a collection of items, but
+ * handling the case when there is exactly one item (and we do not need to
+ * allocate an array).
+ * @param {function} cb Callback invoked with each element or a collection.
+ * @param {?} [scope] Scope used as `this` in a callback.
+ */
+function forEachAccumulated(arr, cb, scope) {
+ if (Array.isArray(arr)) {
+ arr.forEach(cb, scope);
+ } else if (arr) {
+ cb.call(scope, arr);
+ }
+}
+
+/**
+ * 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.
+ * @private
+ */
+var executeDispatchesAndRelease = function (event) {
+ if (event) {
+ executeDispatchesInOrder(event);
+
+ if (!event.isPersistent()) {
+ event.constructor.release(event);
+ }
+ }
+};
+var executeDispatchesAndReleaseTopLevel = function (e) {
+ return executeDispatchesAndRelease(e);
+};
+
+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
+ */
+
+/**
+ * Methods for injecting dependencies.
+ */
+var injection = {
+ /**
+ * @param {array} InjectedEventPluginOrder
+ * @public
+ */
+ injectEventPluginOrder: injectEventPluginOrder,
+
+ /**
+ * @param {object} injectedNamesToPlugins Map from names to plugin modules.
+ */
+ injectEventPluginsByName: injectEventPluginsByName
+};
+
+/**
+ * @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.
+ */
+function getListener(inst, registrationName) {
+ var listener = void 0;
+
+ // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
+ // live here; needs to be moved to a better place soon
+ var stateNode = inst.stateNode;
+ if (!stateNode) {
+ // Work in progress (ex: onload events in incremental mode).
+ return null;
+ }
+ var props = getFiberCurrentPropsFromNode(stateNode);
+ if (!props) {
+ // Work in progress.
+ return null;
+ }
+ listener = props[registrationName];
+ if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
+ return null;
+ }
+ !(!listener || typeof listener === 'function') ? invariant(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener) : void 0;
+ return listener;
+}
+
+/**
+ * Allows registered plugins an opportunity to extract events from top-level
+ * native browser events.
+ *
+ * @return {*} An accumulation of synthetic events.
+ * @internal
+ */
+function extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var events = null;
+ 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;
+}
+
+function runEventsInBatch(events) {
+ if (events !== null) {
+ eventQueue = accumulateInto(eventQueue, events);
+ }
+
+ // 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 (!processingEventQueue) {
+ return;
+ }
+
+ forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
+ !!eventQueue ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : void 0;
+ // This would be a good time to rethrow if any of the event handlers threw.
+ rethrowCaughtError();
+}
+
+function runExtractedEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var events = extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);
+ runEventsInBatch(events);
+}
+
+var FunctionComponent = 0;
+var ClassComponent = 1;
+var IndeterminateComponent = 2; // Before we know whether it is function or class
+var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
+var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
+var HostComponent = 5;
+var HostText = 6;
+var Fragment = 7;
+var Mode = 8;
+var ContextConsumer = 9;
+var ContextProvider = 10;
+var ForwardRef = 11;
+var Profiler = 12;
+var SuspenseComponent = 13;
+var MemoComponent = 14;
+var SimpleMemoComponent = 15;
+var LazyComponent = 16;
+var IncompleteClassComponent = 17;
+
+var randomKey = Math.random().toString(36).slice(2);
+var internalInstanceKey = '__reactInternalInstance$' + randomKey;
+var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
+
+function precacheFiberNode(hostInst, node) {
+ node[internalInstanceKey] = hostInst;
+}
+
+/**
+ * Given a DOM node, return the closest ReactDOMComponent or
+ * ReactDOMTextComponent instance ancestor.
+ */
+function getClosestInstanceFromNode(node) {
+ if (node[internalInstanceKey]) {
+ return node[internalInstanceKey];
+ }
+
+ while (!node[internalInstanceKey]) {
+ if (node.parentNode) {
+ node = node.parentNode;
+ } else {
+ // Top of the tree. This node must not be part of a React tree (or is
+ // unmounted, potentially).
+ return null;
+ }
+ }
+
+ var inst = node[internalInstanceKey];
+ if (inst.tag === HostComponent || inst.tag === HostText) {
+ // In Fiber, this will always be the deepest root.
+ return inst;
+ }
+
+ return null;
+}
+
+/**
+ * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
+ * instance, or null if the node was not rendered by this React.
+ */
+function getInstanceFromNode$1(node) {
+ var inst = node[internalInstanceKey];
+ if (inst) {
+ if (inst.tag === HostComponent || inst.tag === HostText) {
+ return inst;
+ } else {
+ return null;
+ }
+ }
+ return null;
+}
+
+/**
+ * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
+ * DOM node.
+ */
+function getNodeFromInstance$1(inst) {
+ if (inst.tag === HostComponent || inst.tag === HostText) {
+ // In Fiber this, is just the state node right now. We assume it will be
+ // a host component or host text.
+ return inst.stateNode;
+ }
+
+ // Without this first invariant, passing a non-DOM-component triggers the next
+ // invariant for a missing parent, which is super confusing.
+ invariant(false, 'getNodeFromInstance: Invalid argument.');
+}
+
+function getFiberCurrentPropsFromNode$1(node) {
+ return node[internalEventHandlersKey] || null;
+}
+
+function updateFiberProps(node, props) {
+ node[internalEventHandlersKey] = props;
+}
+
+function getParent(inst) {
+ do {
+ inst = inst.return;
+ // TODO: If this is a HostRoot we might want to bail out.
+ // That is depending on if we want nested subtrees (layers) to bubble
+ // events to their parent. We could also go through parentNode on the
+ // host node but that wouldn't work for React Native and doesn't let us
+ // do the portal feature.
+ } while (inst && inst.tag !== HostComponent);
+ if (inst) {
+ return inst;
+ }
+ return null;
+}
+
+/**
+ * Return the lowest common ancestor of A and B, or null if they are in
+ * different trees.
+ */
+function getLowestCommonAncestor(instA, instB) {
+ var depthA = 0;
+ for (var tempA = instA; tempA; tempA = getParent(tempA)) {
+ depthA++;
+ }
+ var depthB = 0;
+ for (var tempB = instB; tempB; tempB = getParent(tempB)) {
+ depthB++;
+ }
+
+ // If A is deeper, crawl up.
+ while (depthA - depthB > 0) {
+ instA = getParent(instA);
+ depthA--;
+ }
+
+ // If B is deeper, crawl up.
+ while (depthB - depthA > 0) {
+ instB = getParent(instB);
+ depthB--;
+ }
+
+ // Walk in lockstep until we find a match.
+ var depth = depthA;
+ while (depth--) {
+ if (instA === instB || instA === instB.alternate) {
+ return instA;
+ }
+ instA = getParent(instA);
+ instB = getParent(instB);
+ }
+ return null;
+}
+
+/**
+ * Return if A is an ancestor of B.
+ */
+
+
+/**
+ * Return the parent instance of the passed-in instance.
+ */
+
+
+/**
+ * Simulates the traversal of a two-phase, capture/bubble event dispatch.
+ */
+function traverseTwoPhase(inst, fn, arg) {
+ var path = [];
+ while (inst) {
+ path.push(inst);
+ inst = getParent(inst);
+ }
+ var i = void 0;
+ for (i = path.length; i-- > 0;) {
+ fn(path[i], 'captured', arg);
+ }
+ for (i = 0; i < path.length; i++) {
+ fn(path[i], 'bubbled', arg);
+ }
+}
+
+/**
+ * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
+ * should would receive a `mouseEnter` or `mouseLeave` event.
+ *
+ * Does not invoke the callback on the nearest common ancestor because nothing
+ * "entered" or "left" that element.
+ */
+function traverseEnterLeave(from, to, fn, argFrom, argTo) {
+ var common = from && to ? getLowestCommonAncestor(from, to) : null;
+ var pathFrom = [];
+ while (true) {
+ if (!from) {
+ break;
+ }
+ if (from === common) {
+ break;
+ }
+ var alternate = from.alternate;
+ if (alternate !== null && alternate === common) {
+ break;
+ }
+ pathFrom.push(from);
+ from = getParent(from);
+ }
+ var pathTo = [];
+ while (true) {
+ if (!to) {
+ break;
+ }
+ if (to === common) {
+ break;
+ }
+ var _alternate = to.alternate;
+ if (_alternate !== null && _alternate === common) {
+ break;
+ }
+ pathTo.push(to);
+ to = getParent(to);
+ }
+ for (var i = 0; i < pathFrom.length; i++) {
+ fn(pathFrom[i], 'bubbled', argFrom);
+ }
+ for (var _i = pathTo.length; _i-- > 0;) {
+ fn(pathTo[_i], 'captured', argTo);
+ }
+}
+
+/**
+ * Some event types have a notion of different registration names for different
+ * "phases" of propagation. This finds listeners by a given phase.
+ */
+function listenerAtPhase(inst, event, propagationPhase) {
+ var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
+ return getListener(inst, registrationName);
+}
+
+/**
+ * A small set of propagation patterns, each of which will accept a small amount
+ * of information, and generate a set of "dispatch ready event objects" - which
+ * are sets of events that have already been annotated with a set of dispatched
+ * listener functions/ids. The API is designed this way to discourage these
+ * propagation strategies from actually executing the dispatches, since we
+ * always want to collect the entire set of dispatches before executing even a
+ * single one.
+ */
+
+/**
+ * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
+ * here, allows us to not have to bind or create functions for each event.
+ * Mutating the event's members allows us to not have to create a wrapping
+ * "dispatch" object that pairs the event with the listener.
+ */
+function accumulateDirectionalDispatches(inst, phase, event) {
+ {
+ !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
+ }
+ var listener = listenerAtPhase(inst, event, phase);
+ if (listener) {
+ event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
+ event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
+ }
+}
+
+/**
+ * Collect dispatches (must be entirely collected before dispatching - see unit
+ * tests). Lazily allocate the array to conserve memory. We must loop through
+ * each event and perform the traversal for each one. We cannot perform a
+ * single traversal for the entire collection of events because each event may
+ * have a different target.
+ */
+function accumulateTwoPhaseDispatchesSingle(event) {
+ if (event && event.dispatchConfig.phasedRegistrationNames) {
+ traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
+ }
+}
+
+/**
+ * Accumulates without regard to direction, does not look for phased
+ * registration names. Same as `accumulateDirectDispatchesSingle` but without
+ * requiring that the `dispatchMarker` be the same as the dispatched ID.
+ */
+function accumulateDispatches(inst, ignoredDirection, event) {
+ if (inst && event && event.dispatchConfig.registrationName) {
+ var registrationName = event.dispatchConfig.registrationName;
+ var listener = getListener(inst, registrationName);
+ if (listener) {
+ event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
+ event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
+ }
+ }
+}
+
+/**
+ * Accumulates dispatches on an `SyntheticEvent`, but only for the
+ * `dispatchMarker`.
+ * @param {SyntheticEvent} event
+ */
+function accumulateDirectDispatchesSingle(event) {
+ if (event && event.dispatchConfig.registrationName) {
+ accumulateDispatches(event._targetInst, null, event);
+ }
+}
+
+function accumulateTwoPhaseDispatches(events) {
+ forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
+}
+
+
+
+function accumulateEnterLeaveDispatches(leave, enter, from, to) {
+ traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
+}
+
+function accumulateDirectDispatches(events) {
+ forEachAccumulated(events, accumulateDirectDispatchesSingle);
+}
+
+var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
+
+// Do not uses the below two methods directly!
+// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
+// (It is the only module that is allowed to access these methods.)
+
+function unsafeCastStringToDOMTopLevelType(topLevelType) {
+ return topLevelType;
+}
+
+function unsafeCastDOMTopLevelTypeToString(topLevelType) {
+ return topLevelType;
+}
+
+/**
+ * Generate a mapping of standard vendor prefixes using the defined style property and event name.
+ *
+ * @param {string} styleProp
+ * @param {string} eventName
+ * @returns {object}
+ */
+function makePrefixMap(styleProp, eventName) {
+ var prefixes = {};
+
+ prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
+ prefixes['Webkit' + styleProp] = 'webkit' + eventName;
+ prefixes['Moz' + styleProp] = 'moz' + eventName;
+
+ return prefixes;
+}
+
+/**
+ * A list of event names to a configurable list of vendor prefixes.
+ */
+var vendorPrefixes = {
+ animationend: makePrefixMap('Animation', 'AnimationEnd'),
+ animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
+ animationstart: makePrefixMap('Animation', 'AnimationStart'),
+ transitionend: makePrefixMap('Transition', 'TransitionEnd')
+};
+
+/**
+ * Event names that have already been detected and prefixed (if applicable).
+ */
+var prefixedEventNames = {};
+
+/**
+ * Element to check for prefixes on.
+ */
+var style = {};
+
+/**
+ * Bootstrap if a DOM exists.
+ */
+if (canUseDOM) {
+ style = document.createElement('div').style;
+
+ // On some platforms, in particular some releases of Android 4.x,
+ // the un-prefixed "animation" and "transition" properties are defined on the
+ // style object but the events that fire will still be prefixed, so we need
+ // to check if the un-prefixed events are usable, and if not remove them from the map.
+ if (!('AnimationEvent' in window)) {
+ delete vendorPrefixes.animationend.animation;
+ delete vendorPrefixes.animationiteration.animation;
+ delete vendorPrefixes.animationstart.animation;
+ }
+
+ // Same as above
+ if (!('TransitionEvent' in window)) {
+ delete vendorPrefixes.transitionend.transition;
+ }
+}
+
+/**
+ * Attempts to determine the correct vendor prefixed event name.
+ *
+ * @param {string} eventName
+ * @returns {string}
+ */
+function getVendorPrefixedEventName(eventName) {
+ if (prefixedEventNames[eventName]) {
+ return prefixedEventNames[eventName];
+ } else if (!vendorPrefixes[eventName]) {
+ return eventName;
+ }
+
+ var prefixMap = vendorPrefixes[eventName];
+
+ for (var styleProp in prefixMap) {
+ if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
+ return prefixedEventNames[eventName] = prefixMap[styleProp];
+ }
+ }
+
+ return eventName;
+}
+
+/**
+ * To identify top level events in ReactDOM, we use constants defined by this
+ * module. This is the only module that uses the unsafe* methods to express
+ * that the constants actually correspond to the browser event names. This lets
+ * us save some bundle size by avoiding a top level type -> event name map.
+ * The rest of ReactDOM code should import top level types from this file.
+ */
+var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
+var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
+var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
+var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
+var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
+var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
+var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
+var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
+var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
+var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
+var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
+var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
+var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
+var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
+var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
+var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
+var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
+var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
+var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
+var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
+var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
+var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
+var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
+var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
+var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
+var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
+var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
+var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
+var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
+var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
+var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
+var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
+var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
+var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
+var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
+var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
+var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
+var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
+var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
+var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
+var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
+var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
+var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
+var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
+var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
+var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
+var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
+var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
+var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
+var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
+var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
+var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
+var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
+var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
+var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
+
+
+var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
+var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
+var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
+var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
+var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
+var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
+var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
+var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
+var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
+var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
+var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
+var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
+var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
+var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
+var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
+var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
+var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
+var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
+var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
+var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
+var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
+var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
+var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
+var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
+var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel');
+
+// List of events that need to be individually attached to media elements.
+// Note that events in this list will *not* be listened to at the top level
+// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
+var mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING];
+
+function getRawEventName(topLevelType) {
+ return unsafeCastDOMTopLevelTypeToString(topLevelType);
+}
+
+/**
+ * These variables store information about text content of a target node,
+ * allowing comparison of content before and after a given event.
+ *
+ * Identify the node where selection currently begins, then observe
+ * both its text content and its current position in the DOM. Since the
+ * browser may natively replace the target node during composition, we can
+ * use its position to find its replacement.
+ *
+ *
+ */
+
+var root = null;
+var startText = null;
+var fallbackText = null;
+
+function initialize(nativeEventTarget) {
+ root = nativeEventTarget;
+ startText = getText();
+ return true;
+}
+
+function reset() {
+ root = null;
+ startText = null;
+ fallbackText = null;
+}
+
+function getData() {
+ if (fallbackText) {
+ return fallbackText;
+ }
+
+ var start = void 0;
+ var startValue = startText;
+ var startLength = startValue.length;
+ var end = void 0;
+ var endValue = getText();
+ var endLength = endValue.length;
+
+ for (start = 0; start < startLength; start++) {
+ if (startValue[start] !== endValue[start]) {
+ break;
+ }
+ }
+
+ var minEnd = startLength - start;
+ for (end = 1; end <= minEnd; end++) {
+ if (startValue[startLength - end] !== endValue[endLength - end]) {
+ break;
+ }
+ }
+
+ var sliceTail = end > 1 ? 1 - end : undefined;
+ fallbackText = endValue.slice(start, sliceTail);
+ return fallbackText;
+}
+
+function getText() {
+ if ('value' in root) {
+ return root.value;
+ }
+ return root.textContent;
+}
+
+/* eslint valid-typeof: 0 */
+
+var EVENT_POOL_SIZE = 10;
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var EventInterface = {
+ type: null,
+ target: null,
+ // currentTarget is set when dispatching; no use in copying it here
+ currentTarget: function () {
+ return null;
+ },
+ eventPhase: null,
+ bubbles: null,
+ cancelable: null,
+ timeStamp: function (event) {
+ return event.timeStamp || Date.now();
+ },
+ defaultPrevented: null,
+ isTrusted: null
+};
+
+function functionThatReturnsTrue() {
+ return true;
+}
+
+function functionThatReturnsFalse() {
+ return false;
+}
+
+/**
+ * Synthetic events are dispatched by event plugins, typically in response to a
+ * top-level event delegation handler.
+ *
+ * These systems should generally use pooling to reduce the frequency of garbage
+ * collection. The system should check `isPersistent` to determine whether the
+ * event should be released into the pool after being dispatched. Users that
+ * need a persisted event should invoke `persist`.
+ *
+ * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
+ * normalizing browser quirks. Subclasses do not necessarily have to implement a
+ * DOM interface; custom application-specific events can also subclass this.
+ *
+ * @param {object} dispatchConfig Configuration used to dispatch this event.
+ * @param {*} targetInst Marker identifying the event target.
+ * @param {object} nativeEvent Native browser event.
+ * @param {DOMEventTarget} nativeEventTarget Target node.
+ */
+function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
+ {
+ // these have a getter/setter for warnings
+ delete this.nativeEvent;
+ delete this.preventDefault;
+ delete this.stopPropagation;
+ delete this.isDefaultPrevented;
+ delete this.isPropagationStopped;
+ }
+
+ this.dispatchConfig = dispatchConfig;
+ this._targetInst = targetInst;
+ this.nativeEvent = nativeEvent;
+
+ var Interface = this.constructor.Interface;
+ for (var propName in Interface) {
+ if (!Interface.hasOwnProperty(propName)) {
+ continue;
+ }
+ {
+ delete this[propName]; // this has a getter/setter for warnings
+ }
+ var normalize = Interface[propName];
+ if (normalize) {
+ this[propName] = normalize(nativeEvent);
+ } else {
+ if (propName === 'target') {
+ this.target = nativeEventTarget;
+ } else {
+ this[propName] = nativeEvent[propName];
+ }
+ }
+ }
+
+ var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
+ if (defaultPrevented) {
+ this.isDefaultPrevented = functionThatReturnsTrue;
+ } else {
+ this.isDefaultPrevented = functionThatReturnsFalse;
+ }
+ this.isPropagationStopped = functionThatReturnsFalse;
+ return this;
+}
+
+_assign(SyntheticEvent.prototype, {
+ preventDefault: function () {
+ this.defaultPrevented = true;
+ var event = this.nativeEvent;
+ if (!event) {
+ return;
+ }
+
+ if (event.preventDefault) {
+ event.preventDefault();
+ } else if (typeof event.returnValue !== 'unknown') {
+ event.returnValue = false;
+ }
+ this.isDefaultPrevented = functionThatReturnsTrue;
+ },
+
+ stopPropagation: function () {
+ var event = this.nativeEvent;
+ if (!event) {
+ return;
+ }
+
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ } else if (typeof event.cancelBubble !== 'unknown') {
+ // The ChangeEventPlugin registers a "propertychange" event for
+ // IE. This event does not support bubbling or cancelling, and
+ // any references to cancelBubble throw "Member not found". A
+ // typeof check of "unknown" circumvents this issue (and is also
+ // IE specific).
+ event.cancelBubble = true;
+ }
+
+ this.isPropagationStopped = functionThatReturnsTrue;
+ },
+
+ /**
+ * We release all dispatched `SyntheticEvent`s after each event loop, adding
+ * them back into the pool. This allows a way to hold onto a reference that
+ * won't be added back into the pool.
+ */
+ persist: function () {
+ this.isPersistent = functionThatReturnsTrue;
+ },
+
+ /**
+ * Checks if this event should be released back into the pool.
+ *
+ * @return {boolean} True if this should not be released, false otherwise.
+ */
+ isPersistent: functionThatReturnsFalse,
+
+ /**
+ * `PooledClass` looks for `destructor` on each instance it releases.
+ */
+ destructor: function () {
+ var Interface = this.constructor.Interface;
+ for (var propName in Interface) {
+ {
+ Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
+ }
+ }
+ this.dispatchConfig = null;
+ this._targetInst = null;
+ this.nativeEvent = null;
+ this.isDefaultPrevented = functionThatReturnsFalse;
+ this.isPropagationStopped = functionThatReturnsFalse;
+ this._dispatchListeners = null;
+ this._dispatchInstances = null;
+ {
+ Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
+ Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
+ Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
+ Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
+ Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
+ }
+ }
+});
+
+SyntheticEvent.Interface = EventInterface;
+
+/**
+ * Helper to reduce boilerplate when creating subclasses.
+ */
+SyntheticEvent.extend = function (Interface) {
+ var Super = this;
+
+ var E = function () {};
+ E.prototype = Super.prototype;
+ var prototype = new E();
+
+ function Class() {
+ return Super.apply(this, arguments);
+ }
+ _assign(prototype, Class.prototype);
+ Class.prototype = prototype;
+ Class.prototype.constructor = Class;
+
+ Class.Interface = _assign({}, Super.Interface, Interface);
+ Class.extend = Super.extend;
+ addEventPoolingTo(Class);
+
+ return Class;
+};
+
+addEventPoolingTo(SyntheticEvent);
+
+/**
+ * Helper to nullify syntheticEvent instance properties when destructing
+ *
+ * @param {String} propName
+ * @param {?object} getVal
+ * @return {object} defineProperty object
+ */
+function getPooledWarningPropertyDefinition(propName, getVal) {
+ var isFunction = typeof getVal === 'function';
+ return {
+ configurable: true,
+ set: set,
+ get: get
+ };
+
+ function set(val) {
+ var action = isFunction ? 'setting the method' : 'setting the property';
+ warn(action, 'This is effectively a no-op');
+ return val;
+ }
+
+ function get() {
+ var action = isFunction ? 'accessing the method' : 'accessing the property';
+ var result = isFunction ? 'This is a no-op function' : 'This is set to null';
+ warn(action, result);
+ return getVal;
+ }
+
+ function warn(action, result) {
+ var warningCondition = false;
+ !warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
+ }
+}
+
+function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
+ var EventConstructor = this;
+ if (EventConstructor.eventPool.length) {
+ var instance = EventConstructor.eventPool.pop();
+ EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
+ return instance;
+ }
+ return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
+}
+
+function releasePooledEvent(event) {
+ var EventConstructor = this;
+ !(event instanceof EventConstructor) ? invariant(false, 'Trying to release an event instance into a pool of a different type.') : void 0;
+ event.destructor();
+ if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
+ EventConstructor.eventPool.push(event);
+ }
+}
+
+function addEventPoolingTo(EventConstructor) {
+ EventConstructor.eventPool = [];
+ EventConstructor.getPooled = getPooledEvent;
+ EventConstructor.release = releasePooledEvent;
+}
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
+ */
+var SyntheticCompositionEvent = SyntheticEvent.extend({
+ data: null
+});
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
+ * /#events-inputevents
+ */
+var SyntheticInputEvent = SyntheticEvent.extend({
+ data: null
+});
+
+var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
+var START_KEYCODE = 229;
+
+var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
+
+var documentMode = null;
+if (canUseDOM && 'documentMode' in document) {
+ documentMode = document.documentMode;
+}
+
+// Webkit offers a very useful `textInput` event that can be used to
+// directly represent `beforeInput`. The IE `textinput` event is not as
+// useful, so we don't use it.
+var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode;
+
+// In IE9+, we have access to composition events, but the data supplied
+// by the native compositionend event may be incorrect. Japanese ideographic
+// spaces, for instance (\u3000) are not recorded correctly.
+var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
+
+var SPACEBAR_CODE = 32;
+var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
+
+// Events and their corresponding property names.
+var eventTypes = {
+ beforeInput: {
+ phasedRegistrationNames: {
+ bubbled: 'onBeforeInput',
+ captured: 'onBeforeInputCapture'
+ },
+ dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
+ },
+ compositionEnd: {
+ phasedRegistrationNames: {
+ bubbled: 'onCompositionEnd',
+ captured: 'onCompositionEndCapture'
+ },
+ dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
+ },
+ compositionStart: {
+ phasedRegistrationNames: {
+ bubbled: 'onCompositionStart',
+ captured: 'onCompositionStartCapture'
+ },
+ dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
+ },
+ compositionUpdate: {
+ phasedRegistrationNames: {
+ bubbled: 'onCompositionUpdate',
+ captured: 'onCompositionUpdateCapture'
+ },
+ dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
+ }
+};
+
+// Track whether we've ever handled a keypress on the space key.
+var hasSpaceKeypress = false;
+
+/**
+ * Return whether a native keypress event is assumed to be a command.
+ * This is required because Firefox fires `keypress` events for key commands
+ * (cut, copy, select-all, etc.) even though no character is inserted.
+ */
+function isKeypressCommand(nativeEvent) {
+ return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) &&
+ // ctrlKey && altKey is equivalent to AltGr, and is not a command.
+ !(nativeEvent.ctrlKey && nativeEvent.altKey);
+}
+
+/**
+ * Translate native top level events into event types.
+ *
+ * @param {string} topLevelType
+ * @return {object}
+ */
+function getCompositionEventType(topLevelType) {
+ switch (topLevelType) {
+ case TOP_COMPOSITION_START:
+ return eventTypes.compositionStart;
+ case TOP_COMPOSITION_END:
+ return eventTypes.compositionEnd;
+ case TOP_COMPOSITION_UPDATE:
+ return eventTypes.compositionUpdate;
+ }
+}
+
+/**
+ * Does our fallback best-guess model think this event signifies that
+ * composition has begun?
+ *
+ * @param {string} topLevelType
+ * @param {object} nativeEvent
+ * @return {boolean}
+ */
+function isFallbackCompositionStart(topLevelType, nativeEvent) {
+ return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
+}
+
+/**
+ * Does our fallback mode think that this event is the end of composition?
+ *
+ * @param {string} topLevelType
+ * @param {object} nativeEvent
+ * @return {boolean}
+ */
+function isFallbackCompositionEnd(topLevelType, nativeEvent) {
+ switch (topLevelType) {
+ case TOP_KEY_UP:
+ // Command keys insert or clear IME input.
+ return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
+ case TOP_KEY_DOWN:
+ // Expect IME keyCode on each keydown. If we get any other
+ // code we must have exited earlier.
+ return nativeEvent.keyCode !== START_KEYCODE;
+ case TOP_KEY_PRESS:
+ case TOP_MOUSE_DOWN:
+ case TOP_BLUR:
+ // Events are not possible without cancelling IME.
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * Google Input Tools provides composition data via a CustomEvent,
+ * with the `data` property populated in the `detail` object. If this
+ * is available on the event object, use it. If not, this is a plain
+ * composition event and we have nothing special to extract.
+ *
+ * @param {object} nativeEvent
+ * @return {?string}
+ */
+function getDataFromCustomEvent(nativeEvent) {
+ var detail = nativeEvent.detail;
+ if (typeof detail === 'object' && 'data' in detail) {
+ return detail.data;
+ }
+ return null;
+}
+
+/**
+ * Check if a composition event was triggered by Korean IME.
+ * Our fallback mode does not work well with IE's Korean IME,
+ * so just use native composition events when Korean IME is used.
+ * Although CompositionEvent.locale property is deprecated,
+ * it is available in IE, where our fallback mode is enabled.
+ *
+ * @param {object} nativeEvent
+ * @return {boolean}
+ */
+function isUsingKoreanIME(nativeEvent) {
+ return nativeEvent.locale === 'ko';
+}
+
+// Track the current IME composition status, if any.
+var isComposing = false;
+
+/**
+ * @return {?object} A SyntheticCompositionEvent.
+ */
+function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var eventType = void 0;
+ var fallbackData = void 0;
+
+ if (canUseCompositionEvent) {
+ eventType = getCompositionEventType(topLevelType);
+ } else if (!isComposing) {
+ if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
+ eventType = eventTypes.compositionStart;
+ }
+ } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
+ eventType = eventTypes.compositionEnd;
+ }
+
+ if (!eventType) {
+ return null;
+ }
+
+ if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
+ // The current composition is stored statically and must not be
+ // overwritten while composition continues.
+ if (!isComposing && eventType === eventTypes.compositionStart) {
+ isComposing = initialize(nativeEventTarget);
+ } else if (eventType === eventTypes.compositionEnd) {
+ if (isComposing) {
+ fallbackData = getData();
+ }
+ }
+ }
+
+ var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
+
+ if (fallbackData) {
+ // Inject data generated from fallback path into the synthetic event.
+ // This matches the property of native CompositionEventInterface.
+ event.data = fallbackData;
+ } else {
+ var customData = getDataFromCustomEvent(nativeEvent);
+ if (customData !== null) {
+ event.data = customData;
+ }
+ }
+
+ accumulateTwoPhaseDispatches(event);
+ return event;
+}
+
+/**
+ * @param {TopLevelType} topLevelType Number from `TopLevelType`.
+ * @param {object} nativeEvent Native browser event.
+ * @return {?string} The string corresponding to this `beforeInput` event.
+ */
+function getNativeBeforeInputChars(topLevelType, nativeEvent) {
+ switch (topLevelType) {
+ case TOP_COMPOSITION_END:
+ return getDataFromCustomEvent(nativeEvent);
+ case TOP_KEY_PRESS:
+ /**
+ * If native `textInput` events are available, our goal is to make
+ * use of them. However, there is a special case: the spacebar key.
+ * In Webkit, preventing default on a spacebar `textInput` event
+ * cancels character insertion, but it *also* causes the browser
+ * to fall back to its default spacebar behavior of scrolling the
+ * page.
+ *
+ * Tracking at:
+ * https://code.google.com/p/chromium/issues/detail?id=355103
+ *
+ * To avoid this issue, use the keypress event as if no `textInput`
+ * event is available.
+ */
+ var which = nativeEvent.which;
+ if (which !== SPACEBAR_CODE) {
+ return null;
+ }
+
+ hasSpaceKeypress = true;
+ return SPACEBAR_CHAR;
+
+ case TOP_TEXT_INPUT:
+ // Record the characters to be added to the DOM.
+ var chars = nativeEvent.data;
+
+ // If it's a spacebar character, assume that we have already handled
+ // it at the keypress level and bail immediately. Android Chrome
+ // doesn't give us keycodes, so we need to ignore it.
+ if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
+ return null;
+ }
+
+ return chars;
+
+ default:
+ // For other native event types, do nothing.
+ return null;
+ }
+}
+
+/**
+ * For browsers that do not provide the `textInput` event, extract the
+ * appropriate string to use for SyntheticInputEvent.
+ *
+ * @param {number} topLevelType Number from `TopLevelEventTypes`.
+ * @param {object} nativeEvent Native browser event.
+ * @return {?string} The fallback string for this `beforeInput` event.
+ */
+function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
+ // If we are currently composing (IME) and using a fallback to do so,
+ // try to extract the composed characters from the fallback object.
+ // If composition event is available, we extract a string only at
+ // compositionevent, otherwise extract it at fallback events.
+ if (isComposing) {
+ if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
+ var chars = getData();
+ reset();
+ isComposing = false;
+ return chars;
+ }
+ return null;
+ }
+
+ switch (topLevelType) {
+ case TOP_PASTE:
+ // If a paste event occurs after a keypress, throw out the input
+ // chars. Paste events should not lead to BeforeInput events.
+ return null;
+ case TOP_KEY_PRESS:
+ /**
+ * As of v27, Firefox may fire keypress events even when no character
+ * will be inserted. A few possibilities:
+ *
+ * - `which` is `0`. Arrow keys, Esc key, etc.
+ *
+ * - `which` is the pressed key code, but no char is available.
+ * Ex: 'AltGr + d` in Polish. There is no modified character for
+ * this key combination and no character is inserted into the
+ * document, but FF fires the keypress for char code `100` anyway.
+ * No `input` event will occur.
+ *
+ * - `which` is the pressed key code, but a command combination is
+ * being used. Ex: `Cmd+C`. No character is inserted, and no
+ * `input` event will occur.
+ */
+ if (!isKeypressCommand(nativeEvent)) {
+ // IE fires the `keypress` event when a user types an emoji via
+ // Touch keyboard of Windows. In such a case, the `char` property
+ // holds an emoji character like `\uD83D\uDE0A`. Because its length
+ // is 2, the property `which` does not represent an emoji correctly.
+ // In such a case, we directly return the `char` property instead of
+ // using `which`.
+ if (nativeEvent.char && nativeEvent.char.length > 1) {
+ return nativeEvent.char;
+ } else if (nativeEvent.which) {
+ return String.fromCharCode(nativeEvent.which);
+ }
+ }
+ return null;
+ case TOP_COMPOSITION_END:
+ return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
+ default:
+ return null;
+ }
+}
+
+/**
+ * Extract a SyntheticInputEvent for `beforeInput`, based on either native
+ * `textInput` or fallback behavior.
+ *
+ * @return {?object} A SyntheticInputEvent.
+ */
+function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var chars = void 0;
+
+ if (canUseTextInputEvent) {
+ chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
+ } else {
+ chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
+ }
+
+ // If no characters are being inserted, no BeforeInput event should
+ // be fired.
+ if (!chars) {
+ return null;
+ }
+
+ var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget);
+
+ event.data = chars;
+ accumulateTwoPhaseDispatches(event);
+ return event;
+}
+
+/**
+ * Create an `onBeforeInput` event to match
+ * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
+ *
+ * This event plugin is based on the native `textInput` event
+ * available in Chrome, Safari, Opera, and IE. This event fires after
+ * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
+ *
+ * `beforeInput` is spec'd but not implemented in any browsers, and
+ * the `input` event does not provide any useful information about what has
+ * actually been added, contrary to the spec. Thus, `textInput` is the best
+ * available event to identify the characters that have actually been inserted
+ * into the target node.
+ *
+ * This plugin is also responsible for emitting `composition` events, thus
+ * allowing us to share composition fallback code for both `beforeInput` and
+ * `composition` event types.
+ */
+var BeforeInputEventPlugin = {
+ eventTypes: eventTypes,
+
+ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
+
+ var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
+
+ if (composition === null) {
+ return beforeInput;
+ }
+
+ if (beforeInput === null) {
+ return composition;
+ }
+
+ return [composition, beforeInput];
+ }
+};
+
+// Use to restore controlled state after a change event has fired.
+
+var restoreImpl = null;
+var restoreTarget = null;
+var restoreQueue = null;
+
+function restoreStateOfTarget(target) {
+ // We perform this translation at the end of the event loop so that we
+ // always receive the correct fiber here
+ var internalInstance = getInstanceFromNode(target);
+ if (!internalInstance) {
+ // Unmounted
+ return;
+ }
+ !(typeof restoreImpl === 'function') ? invariant(false, 'setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.') : void 0;
+ var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
+ restoreImpl(internalInstance.stateNode, internalInstance.type, props);
+}
+
+function setRestoreImplementation(impl) {
+ restoreImpl = impl;
+}
+
+function enqueueStateRestore(target) {
+ if (restoreTarget) {
+ if (restoreQueue) {
+ restoreQueue.push(target);
+ } else {
+ restoreQueue = [target];
+ }
+ } else {
+ restoreTarget = target;
+ }
+}
+
+function needsStateRestore() {
+ return restoreTarget !== null || restoreQueue !== null;
+}
+
+function restoreStateIfNeeded() {
+ if (!restoreTarget) {
+ return;
+ }
+ var target = restoreTarget;
+ var queuedTargets = restoreQueue;
+ restoreTarget = null;
+ restoreQueue = null;
+
+ restoreStateOfTarget(target);
+ if (queuedTargets) {
+ for (var i = 0; i < queuedTargets.length; i++) {
+ restoreStateOfTarget(queuedTargets[i]);
+ }
+ }
+}
+
+// Used as a way to call batchedUpdates when we don't have a reference to
+// the renderer. Such as when we're dispatching events or if third party
+// libraries need to call batchedUpdates. Eventually, this API will go away when
+// everything is batched by default. We'll then have a similar API to opt-out of
+// scheduled work and instead do synchronous work.
+
+// Defaults
+var _batchedUpdatesImpl = function (fn, bookkeeping) {
+ return fn(bookkeeping);
+};
+var _interactiveUpdatesImpl = function (fn, a, b) {
+ return fn(a, b);
+};
+var _flushInteractiveUpdatesImpl = function () {};
+
+var isBatching = false;
+function batchedUpdates(fn, bookkeeping) {
+ if (isBatching) {
+ // If we are currently inside another batch, we need to wait until it
+ // fully completes before restoring state.
+ return fn(bookkeeping);
+ }
+ isBatching = true;
+ try {
+ return _batchedUpdatesImpl(fn, bookkeeping);
+ } finally {
+ // Here we wait until all updates have propagated, which is important
+ // when using controlled components within layers:
+ // https://github.com/facebook/react/issues/1698
+ // Then we restore state of any controlled component.
+ isBatching = false;
+ var controlledComponentsHavePendingUpdates = needsStateRestore();
+ if (controlledComponentsHavePendingUpdates) {
+ // If a controlled event was fired, we may need to restore the state of
+ // the DOM node back to the controlled value. This is necessary when React
+ // bails out of the update without touching the DOM.
+ _flushInteractiveUpdatesImpl();
+ restoreStateIfNeeded();
+ }
+ }
+}
+
+function interactiveUpdates(fn, a, b) {
+ return _interactiveUpdatesImpl(fn, a, b);
+}
+
+
+
+function setBatchingImplementation(batchedUpdatesImpl, interactiveUpdatesImpl, flushInteractiveUpdatesImpl) {
+ _batchedUpdatesImpl = batchedUpdatesImpl;
+ _interactiveUpdatesImpl = interactiveUpdatesImpl;
+ _flushInteractiveUpdatesImpl = flushInteractiveUpdatesImpl;
+}
+
+/**
+ * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
+ */
+var supportedInputTypes = {
+ color: true,
+ date: true,
+ datetime: true,
+ 'datetime-local': true,
+ email: true,
+ month: true,
+ number: true,
+ password: true,
+ range: true,
+ search: true,
+ tel: true,
+ text: true,
+ time: true,
+ url: true,
+ week: true
+};
+
+function isTextInputElement(elem) {
+ var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
+
+ if (nodeName === 'input') {
+ return !!supportedInputTypes[elem.type];
+ }
+
+ if (nodeName === 'textarea') {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * HTML nodeType values that represent the type of the node
+ */
+
+var ELEMENT_NODE = 1;
+var TEXT_NODE = 3;
+var COMMENT_NODE = 8;
+var DOCUMENT_NODE = 9;
+var DOCUMENT_FRAGMENT_NODE = 11;
+
+/**
+ * Gets the target node from a native browser event by accounting for
+ * inconsistencies in browser DOM APIs.
+ *
+ * @param {object} nativeEvent Native browser event.
+ * @return {DOMEventTarget} Target node.
+ */
+function getEventTarget(nativeEvent) {
+ // Fallback to nativeEvent.srcElement for IE9
+ // https://github.com/facebook/react/issues/12506
+ var target = nativeEvent.target || nativeEvent.srcElement || window;
+
+ // Normalize SVG element events #4963
+ if (target.correspondingUseElement) {
+ target = target.correspondingUseElement;
+ }
+
+ // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
+ // @see http://www.quirksmode.org/js/events_properties.html
+ return target.nodeType === TEXT_NODE ? target.parentNode : target;
+}
+
+/**
+ * Checks if an event is supported in the current execution environment.
+ *
+ * NOTE: This will not work correctly for non-generic events such as `change`,
+ * `reset`, `load`, `error`, and `select`.
+ *
+ * Borrows from Modernizr.
+ *
+ * @param {string} eventNameSuffix Event name, e.g. "click".
+ * @return {boolean} True if the event is supported.
+ * @internal
+ * @license Modernizr 3.0.0pre (Custom Build) | MIT
+ */
+function isEventSupported(eventNameSuffix) {
+ if (!canUseDOM) {
+ return false;
+ }
+
+ var eventName = 'on' + eventNameSuffix;
+ var isSupported = eventName in document;
+
+ if (!isSupported) {
+ var element = document.createElement('div');
+ element.setAttribute(eventName, 'return;');
+ isSupported = typeof element[eventName] === 'function';
+ }
+
+ return isSupported;
+}
+
+function isCheckable(elem) {
+ var type = elem.type;
+ var nodeName = elem.nodeName;
+ return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
+}
+
+function getTracker(node) {
+ return node._valueTracker;
+}
+
+function detachTracker(node) {
+ node._valueTracker = null;
+}
+
+function getValueFromNode(node) {
+ var value = '';
+ if (!node) {
+ return value;
+ }
+
+ if (isCheckable(node)) {
+ value = node.checked ? 'true' : 'false';
+ } else {
+ value = node.value;
+ }
+
+ return value;
+}
+
+function trackValueOnNode(node) {
+ var valueField = isCheckable(node) ? 'checked' : 'value';
+ var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
+
+ var currentValue = '' + node[valueField];
+
+ // if someone has already defined a value or Safari, then bail
+ // and don't track value will cause over reporting of changes,
+ // but it's better then a hard failure
+ // (needed for certain tests that spyOn input values and Safari)
+ if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
+ return;
+ }
+ var get = descriptor.get,
+ set = descriptor.set;
+
+ Object.defineProperty(node, valueField, {
+ configurable: true,
+ get: function () {
+ return get.call(this);
+ },
+ set: function (value) {
+ currentValue = '' + value;
+ set.call(this, value);
+ }
+ });
+ // We could've passed this the first time
+ // but it triggers a bug in IE11 and Edge 14/15.
+ // Calling defineProperty() again should be equivalent.
+ // https://github.com/facebook/react/issues/11768
+ Object.defineProperty(node, valueField, {
+ enumerable: descriptor.enumerable
+ });
+
+ var tracker = {
+ getValue: function () {
+ return currentValue;
+ },
+ setValue: function (value) {
+ currentValue = '' + value;
+ },
+ stopTracking: function () {
+ detachTracker(node);
+ delete node[valueField];
+ }
+ };
+ return tracker;
+}
+
+function track(node) {
+ if (getTracker(node)) {
+ return;
+ }
+
+ // TODO: Once it's just Fiber we can move this to node._wrapperState
+ node._valueTracker = trackValueOnNode(node);
+}
+
+function updateValueIfChanged(node) {
+ if (!node) {
+ return false;
+ }
+
+ var tracker = getTracker(node);
+ // if there is no tracker at this point it's unlikely
+ // that trying again will succeed
+ if (!tracker) {
+ return true;
+ }
+
+ var lastValue = tracker.getValue();
+ var nextValue = getValueFromNode(node);
+ if (nextValue !== lastValue) {
+ tracker.setValue(nextValue);
+ return true;
+ }
+ return false;
+}
+
+var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
+
+var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
+
+var describeComponentFrame = function (name, source, ownerName) {
+ var sourceInfo = '';
+ if (source) {
+ var path = source.fileName;
+ var fileName = path.replace(BEFORE_SLASH_RE, '');
+ {
+ // In DEV, include code for a common special case:
+ // prefer "folder/index.js" instead of just "index.js".
+ if (/^index\./.test(fileName)) {
+ var match = path.match(BEFORE_SLASH_RE);
+ if (match) {
+ var pathBeforeSlash = match[1];
+ if (pathBeforeSlash) {
+ var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
+ fileName = folderName + '/' + fileName;
+ }
+ }
+ }
+ }
+ sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
+ } else if (ownerName) {
+ sourceInfo = ' (created by ' + ownerName + ')';
+ }
+ return '\n in ' + (name || 'Unknown') + sourceInfo;
+};
+
+// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
+// nor polyfill, then a plain number is used for performance.
+var hasSymbol = typeof Symbol === 'function' && Symbol.for;
+
+var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
+var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
+var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
+var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
+var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
+var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
+var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
+
+var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
+var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
+var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
+var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
+var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
+
+var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
+var FAUX_ITERATOR_SYMBOL = '@@iterator';
+
+function getIteratorFn(maybeIterable) {
+ if (maybeIterable === null || typeof maybeIterable !== 'object') {
+ return null;
+ }
+ var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
+ if (typeof maybeIterator === 'function') {
+ return maybeIterator;
+ }
+ return null;
+}
+
+var Pending = 0;
+var Resolved = 1;
+var Rejected = 2;
+
+function refineResolvedLazyComponent(lazyComponent) {
+ return lazyComponent._status === Resolved ? lazyComponent._result : null;
+}
+
+function getWrappedName(outerType, innerType, wrapperName) {
+ var functionName = innerType.displayName || innerType.name || '';
+ return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
+}
+
+function getComponentName(type) {
+ if (type == null) {
+ // Host root, text node or just invalid type.
+ return null;
+ }
+ {
+ if (typeof type.tag === 'number') {
+ warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
+ }
+ }
+ if (typeof type === 'function') {
+ return type.displayName || type.name || null;
+ }
+ if (typeof type === 'string') {
+ return type;
+ }
+ switch (type) {
+ case REACT_CONCURRENT_MODE_TYPE:
+ return 'ConcurrentMode';
+ case REACT_FRAGMENT_TYPE:
+ return 'Fragment';
+ case REACT_PORTAL_TYPE:
+ return 'Portal';
+ case REACT_PROFILER_TYPE:
+ return 'Profiler';
+ case REACT_STRICT_MODE_TYPE:
+ return 'StrictMode';
+ case REACT_SUSPENSE_TYPE:
+ return 'Suspense';
+ }
+ if (typeof type === 'object') {
+ switch (type.$$typeof) {
+ case REACT_CONTEXT_TYPE:
+ return 'Context.Consumer';
+ case REACT_PROVIDER_TYPE:
+ return 'Context.Provider';
+ case REACT_FORWARD_REF_TYPE:
+ return getWrappedName(type, type.render, 'ForwardRef');
+ case REACT_MEMO_TYPE:
+ return getComponentName(type.type);
+ case REACT_LAZY_TYPE:
+ {
+ var thenable = type;
+ var resolvedThenable = refineResolvedLazyComponent(thenable);
+ if (resolvedThenable) {
+ return getComponentName(resolvedThenable);
+ }
+ }
+ }
+ }
+ return null;
+}
+
+var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
+
+function describeFiber(fiber) {
+ switch (fiber.tag) {
+ case IndeterminateComponent:
+ case LazyComponent:
+ case FunctionComponent:
+ case ClassComponent:
+ case HostComponent:
+ case Mode:
+ case SuspenseComponent:
+ var owner = fiber._debugOwner;
+ var source = fiber._debugSource;
+ var name = getComponentName(fiber.type);
+ var ownerName = null;
+ if (owner) {
+ ownerName = getComponentName(owner.type);
+ }
+ return describeComponentFrame(name, source, ownerName);
+ default:
+ return '';
+ }
+}
+
+function getStackByFiberInDevAndProd(workInProgress) {
+ var info = '';
+ var node = workInProgress;
+ do {
+ info += describeFiber(node);
+ node = node.return;
+ } while (node);
+ return info;
+}
+
+var current = null;
+var phase = null;
+
+function getCurrentFiberOwnerNameInDevOrNull() {
+ {
+ if (current === null) {
+ return null;
+ }
+ var owner = current._debugOwner;
+ if (owner !== null && typeof owner !== 'undefined') {
+ return getComponentName(owner.type);
+ }
+ }
+ return null;
+}
+
+function getCurrentFiberStackInDev() {
+ {
+ if (current === null) {
+ return '';
+ }
+ // Safe because if current fiber exists, we are reconciling,
+ // and it is guaranteed to be the work-in-progress version.
+ return getStackByFiberInDevAndProd(current);
+ }
+ return '';
+}
+
+function resetCurrentFiber() {
+ {
+ ReactDebugCurrentFrame.getCurrentStack = null;
+ current = null;
+ phase = null;
+ }
+}
+
+function setCurrentFiber(fiber) {
+ {
+ ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
+ current = fiber;
+ phase = null;
+ }
+}
+
+function setCurrentPhase(lifeCyclePhase) {
+ {
+ phase = lifeCyclePhase;
+ }
+}
+
+/**
+ * Similar to invariant but only logs a warning if the condition is not met.
+ * This can be used to log issues in development environments in critical
+ * paths. Removing the logging code for production environments will keep the
+ * same logic and follow the same code paths.
+ */
+
+var warning = warningWithoutStack$1;
+
+{
+ warning = function (condition, format) {
+ if (condition) {
+ return;
+ }
+ var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
+ var stack = ReactDebugCurrentFrame.getStackAddendum();
+ // eslint-disable-next-line react-internal/warning-and-invariant-args
+
+ for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ args[_key - 2] = arguments[_key];
+ }
+
+ warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
+ };
+}
+
+var warning$1 = warning;
+
+// A reserved attribute.
+// It is handled by React separately and shouldn't be written to the DOM.
+var RESERVED = 0;
+
+// A simple string attribute.
+// Attributes that aren't in the whitelist are presumed to have this type.
+var STRING = 1;
+
+// A string attribute that accepts booleans in React. In HTML, these are called
+// "enumerated" attributes with "true" and "false" as possible values.
+// When true, it should be set to a "true" string.
+// When false, it should be set to a "false" string.
+var BOOLEANISH_STRING = 2;
+
+// A real boolean attribute.
+// When true, it should be present (set either to an empty string or its name).
+// When false, it should be omitted.
+var BOOLEAN = 3;
+
+// An attribute that can be used as a flag as well as with a value.
+// When true, it should be present (set either to an empty string or its name).
+// When false, it should be omitted.
+// For any other value, should be present with that value.
+var OVERLOADED_BOOLEAN = 4;
+
+// An attribute that must be numeric or parse as a numeric.
+// When falsy, it should be removed.
+var NUMERIC = 5;
+
+// An attribute that must be positive numeric or parse as a positive numeric.
+// When falsy, it should be removed.
+var POSITIVE_NUMERIC = 6;
+
+/* eslint-disable max-len */
+var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
+/* eslint-enable max-len */
+var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
+
+
+var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
+var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+var illegalAttributeNameCache = {};
+var validatedAttributeNameCache = {};
+
+function isAttributeNameSafe(attributeName) {
+ if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
+ return true;
+ }
+ if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
+ return false;
+ }
+ if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
+ validatedAttributeNameCache[attributeName] = true;
+ return true;
+ }
+ illegalAttributeNameCache[attributeName] = true;
+ {
+ warning$1(false, 'Invalid attribute name: `%s`', attributeName);
+ }
+ return false;
+}
+
+function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
+ if (propertyInfo !== null) {
+ return propertyInfo.type === RESERVED;
+ }
+ if (isCustomComponentTag) {
+ return false;
+ }
+ if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
+ return true;
+ }
+ return false;
+}
+
+function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
+ if (propertyInfo !== null && propertyInfo.type === RESERVED) {
+ return false;
+ }
+ switch (typeof value) {
+ case 'function':
+ // $FlowIssue symbol is perfectly valid here
+ case 'symbol':
+ // eslint-disable-line
+ return true;
+ case 'boolean':
+ {
+ if (isCustomComponentTag) {
+ return false;
+ }
+ if (propertyInfo !== null) {
+ return !propertyInfo.acceptsBooleans;
+ } else {
+ var prefix = name.toLowerCase().slice(0, 5);
+ return prefix !== 'data-' && prefix !== 'aria-';
+ }
+ }
+ default:
+ return false;
+ }
+}
+
+function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
+ if (value === null || typeof value === 'undefined') {
+ return true;
+ }
+ if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
+ return true;
+ }
+ if (isCustomComponentTag) {
+ return false;
+ }
+ if (propertyInfo !== null) {
+ switch (propertyInfo.type) {
+ case BOOLEAN:
+ return !value;
+ case OVERLOADED_BOOLEAN:
+ return value === false;
+ case NUMERIC:
+ return isNaN(value);
+ case POSITIVE_NUMERIC:
+ return isNaN(value) || value < 1;
+ }
+ }
+ return false;
+}
+
+function getPropertyInfo(name) {
+ return properties.hasOwnProperty(name) ? properties[name] : null;
+}
+
+function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) {
+ this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
+ this.attributeName = attributeName;
+ this.attributeNamespace = attributeNamespace;
+ this.mustUseProperty = mustUseProperty;
+ this.propertyName = name;
+ this.type = type;
+}
+
+// When adding attributes to this list, be sure to also add them to
+// the `possibleStandardNames` module to ensure casing and incorrect
+// name warnings.
+var properties = {};
+
+// These props are reserved by React. They shouldn't be written to the DOM.
+['children', 'dangerouslySetInnerHTML',
+// TODO: This prevents the assignment of defaultValue to regular
+// elements (not just inputs). Now that ReactDOMInput assigns to the
+// defaultValue property -- do we need this?
+'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
+ name, // attributeName
+ null);
+} // attributeNamespace
+);
+
+// A few React string attributes have a different name.
+// This is a mapping from React prop names to the attribute names.
+[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
+ var name = _ref[0],
+ attributeName = _ref[1];
+
+ properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
+ attributeName, // attributeName
+ null);
+} // attributeNamespace
+);
+
+// These are "enumerated" HTML attributes that accept "true" and "false".
+// In React, we let users pass `true` and `false` even though technically
+// these aren't boolean attributes (they are coerced to strings).
+['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
+ name.toLowerCase(), // attributeName
+ null);
+} // attributeNamespace
+);
+
+// These are "enumerated" SVG attributes that accept "true" and "false".
+// In React, we let users pass `true` and `false` even though technically
+// these aren't boolean attributes (they are coerced to strings).
+// Since these are SVG attributes, their attribute names are case-sensitive.
+['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
+ name, // attributeName
+ null);
+} // attributeNamespace
+);
+
+// These are HTML boolean attributes.
+['allowFullScreen', 'async',
+// Note: there is a special case that prevents it from being written to the DOM
+// on the client side because the browsers are inconsistent. Instead we call focus().
+'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless',
+// Microdata
+'itemScope'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
+ name.toLowerCase(), // attributeName
+ null);
+} // attributeNamespace
+);
+
+// These are the few React props that we set as DOM properties
+// rather than attributes. These are all booleans.
+['checked',
+// Note: `option.selected` is not updated if `select.multiple` is
+// disabled with `removeAttribute`. We have special logic for handling this.
+'multiple', 'muted', 'selected'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
+ name, // attributeName
+ null);
+} // attributeNamespace
+);
+
+// These are HTML attributes that are "overloaded booleans": they behave like
+// booleans, but can also accept a string value.
+['capture', 'download'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
+ name, // attributeName
+ null);
+} // attributeNamespace
+);
+
+// These are HTML attributes that must be positive numbers.
+['cols', 'rows', 'size', 'span'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
+ name, // attributeName
+ null);
+} // attributeNamespace
+);
+
+// These are HTML attributes that must be numbers.
+['rowSpan', 'start'].forEach(function (name) {
+ properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
+ name.toLowerCase(), // attributeName
+ null);
+} // attributeNamespace
+);
+
+var CAMELIZE = /[\-\:]([a-z])/g;
+var capitalize = function (token) {
+ return token[1].toUpperCase();
+};
+
+// This is a list of all SVG attributes that need special casing, namespacing,
+// or boolean value assignment. Regular attributes that just accept strings
+// and have the same names are omitted, just like in the HTML whitelist.
+// Some of these attributes can be hard to find. This list was created by
+// scrapping the MDN documentation.
+['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) {
+ var name = attributeName.replace(CAMELIZE, capitalize);
+ properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
+ attributeName, null);
+} // attributeNamespace
+);
+
+// String SVG attributes with the xlink namespace.
+['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
+ var name = attributeName.replace(CAMELIZE, capitalize);
+ properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
+ attributeName, 'http://www.w3.org/1999/xlink');
+});
+
+// String SVG attributes with the xml namespace.
+['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
+ var name = attributeName.replace(CAMELIZE, capitalize);
+ properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
+ attributeName, 'http://www.w3.org/XML/1998/namespace');
+});
+
+// Special case: this attribute exists both in HTML and SVG.
+// Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
+// its React `tabIndex` name, like we do for attributes that exist only in HTML.
+properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
+'tabindex', // attributeName
+null);
+
+/**
+ * Get the value for a property on a node. Only used in DEV for SSR validation.
+ * The "expected" argument is used as a hint of what the expected value is.
+ * Some properties have multiple equivalent values.
+ */
+function getValueForProperty(node, name, expected, propertyInfo) {
+ {
+ if (propertyInfo.mustUseProperty) {
+ var propertyName = propertyInfo.propertyName;
+
+ return node[propertyName];
+ } else {
+ var attributeName = propertyInfo.attributeName;
+
+ var stringValue = null;
+
+ if (propertyInfo.type === OVERLOADED_BOOLEAN) {
+ if (node.hasAttribute(attributeName)) {
+ var value = node.getAttribute(attributeName);
+ if (value === '') {
+ return true;
+ }
+ if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
+ return value;
+ }
+ if (value === '' + expected) {
+ return expected;
+ }
+ return value;
+ }
+ } else if (node.hasAttribute(attributeName)) {
+ if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
+ // We had an attribute but shouldn't have had one, so read it
+ // for the error message.
+ return node.getAttribute(attributeName);
+ }
+ if (propertyInfo.type === BOOLEAN) {
+ // If this was a boolean, it doesn't matter what the value is
+ // the fact that we have it is the same as the expected.
+ return expected;
+ }
+ // Even if this property uses a namespace we use getAttribute
+ // because we assume its namespaced name is the same as our config.
+ // To use getAttributeNS we need the local name which we don't have
+ // in our config atm.
+ stringValue = node.getAttribute(attributeName);
+ }
+
+ if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
+ return stringValue === null ? expected : stringValue;
+ } else if (stringValue === '' + expected) {
+ return expected;
+ } else {
+ return stringValue;
+ }
+ }
+ }
+}
+
+/**
+ * Get the value for a attribute on a node. Only used in DEV for SSR validation.
+ * The third argument is used as a hint of what the expected value is. Some
+ * attributes have multiple equivalent values.
+ */
+function getValueForAttribute(node, name, expected) {
+ {
+ if (!isAttributeNameSafe(name)) {
+ return;
+ }
+ if (!node.hasAttribute(name)) {
+ return expected === undefined ? undefined : null;
+ }
+ var value = node.getAttribute(name);
+ if (value === '' + expected) {
+ return expected;
+ }
+ return value;
+ }
+}
+
+/**
+ * Sets the value for a property on a node.
+ *
+ * @param {DOMElement} node
+ * @param {string} name
+ * @param {*} value
+ */
+function setValueForProperty(node, name, value, isCustomComponentTag) {
+ var propertyInfo = getPropertyInfo(name);
+ if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
+ return;
+ }
+ if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
+ value = null;
+ }
+ // If the prop isn't in the special list, treat it as a simple attribute.
+ if (isCustomComponentTag || propertyInfo === null) {
+ if (isAttributeNameSafe(name)) {
+ var _attributeName = name;
+ if (value === null) {
+ node.removeAttribute(_attributeName);
+ } else {
+ node.setAttribute(_attributeName, '' + value);
+ }
+ }
+ return;
+ }
+ var mustUseProperty = propertyInfo.mustUseProperty;
+
+ if (mustUseProperty) {
+ var propertyName = propertyInfo.propertyName;
+
+ if (value === null) {
+ var type = propertyInfo.type;
+
+ node[propertyName] = type === BOOLEAN ? false : '';
+ } else {
+ // Contrary to `setAttribute`, object properties are properly
+ // `toString`ed by IE8/9.
+ node[propertyName] = value;
+ }
+ return;
+ }
+ // The rest are treated as attributes with special cases.
+ var attributeName = propertyInfo.attributeName,
+ attributeNamespace = propertyInfo.attributeNamespace;
+
+ if (value === null) {
+ node.removeAttribute(attributeName);
+ } else {
+ var _type = propertyInfo.type;
+
+ var attributeValue = void 0;
+ if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
+ attributeValue = '';
+ } else {
+ // `setAttribute` with objects becomes only `[object]` in IE8/9,
+ // ('' + value) makes it output the correct toString()-value.
+ attributeValue = '' + value;
+ }
+ if (attributeNamespace) {
+ node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
+ } else {
+ node.setAttribute(attributeName, attributeValue);
+ }
+ }
+}
+
+// Flow does not allow string concatenation of most non-string types. To work
+// around this limitation, we use an opaque type that can only be obtained by
+// passing the value through getToStringValue first.
+function toString(value) {
+ return '' + value;
+}
+
+function getToStringValue(value) {
+ switch (typeof value) {
+ case 'boolean':
+ case 'number':
+ case 'object':
+ case 'string':
+ case 'undefined':
+ return value;
+ default:
+ // function, symbol are assigned as empty strings
+ return '';
+ }
+}
+
+var ReactDebugCurrentFrame$1 = null;
+
+var ReactControlledValuePropTypes = {
+ checkPropTypes: null
+};
+
+{
+ ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
+
+ var hasReadOnlyValue = {
+ button: true,
+ checkbox: true,
+ image: true,
+ hidden: true,
+ radio: true,
+ reset: true,
+ submit: true
+ };
+
+ var propTypes = {
+ value: function (props, propName, componentName) {
+ if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) {
+ return null;
+ }
+ return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
+ },
+ checked: function (props, propName, componentName) {
+ if (props.onChange || props.readOnly || props.disabled || props[propName] == null) {
+ return null;
+ }
+ return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
+ }
+ };
+
+ /**
+ * Provide a linked `value` attribute for controlled forms. You should not use
+ * this outside of the ReactDOM controlled form components.
+ */
+ ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
+ checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum);
+ };
+}
+
+var enableUserTimingAPI = true;
+
+var enableHooks = false;
+// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
+var debugRenderPhaseSideEffects = false;
+
+// In some cases, StrictMode should also double-render lifecycles.
+// This can be confusing for tests though,
+// And it can be bad for performance in production.
+// This feature flag can be used to control the behavior:
+var debugRenderPhaseSideEffectsForStrictMode = true;
+
+// To preserve the "Pause on caught exceptions" behavior of the debugger, we
+// replay the begin phase of a failed component inside invokeGuardedCallback.
+var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
+
+// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
+var warnAboutDeprecatedLifecycles = false;
+
+// Gather advanced timing metrics for Profiler subtrees.
+var enableProfilerTimer = true;
+
+// Trace which interactions trigger each commit.
+var enableSchedulerTracing = true;
+
+// Only used in www builds.
+
+
+// Only used in www builds.
+
+
+// React Fire: prevent the value and checked attributes from syncing
+// with their related DOM properties
+var disableInputAttributeSyncing = false;
+
+// These APIs will no longer be "unstable" in the upcoming 16.7 release,
+// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
+var enableStableConcurrentModeAPIs = false;
+
+// TODO: direct imports like some-package/src/* are bad. Fix me.
+var didWarnValueDefaultValue = false;
+var didWarnCheckedDefaultChecked = false;
+var didWarnControlledToUncontrolled = false;
+var didWarnUncontrolledToControlled = false;
+
+function isControlled(props) {
+ var usesChecked = props.type === 'checkbox' || props.type === 'radio';
+ return usesChecked ? props.checked != null : props.value != null;
+}
+
+/**
+ * Implements an host component that allows setting these optional
+ * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
+ *
+ * If `checked` or `value` are not supplied (or null/undefined), user actions
+ * that affect the checked state or value will trigger updates to the element.
+ *
+ * If they are supplied (and not null/undefined), the rendered element will not
+ * trigger updates to the element. Instead, the props must change in order for
+ * the rendered element to be updated.
+ *
+ * The rendered element will be initialized as unchecked (or `defaultChecked`)
+ * with an empty value (or `defaultValue`).
+ *
+ * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
+ */
+
+function getHostProps(element, props) {
+ var node = element;
+ var checked = props.checked;
+
+ var hostProps = _assign({}, props, {
+ defaultChecked: undefined,
+ defaultValue: undefined,
+ value: undefined,
+ checked: checked != null ? checked : node._wrapperState.initialChecked
+ });
+
+ return hostProps;
+}
+
+function initWrapperState(element, props) {
+ {
+ ReactControlledValuePropTypes.checkPropTypes('input', props);
+
+ if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
+ warning$1(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
+ didWarnCheckedDefaultChecked = true;
+ }
+ if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
+ warning$1(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
+ didWarnValueDefaultValue = true;
+ }
+ }
+
+ var node = element;
+ var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
+
+ node._wrapperState = {
+ initialChecked: props.checked != null ? props.checked : props.defaultChecked,
+ initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
+ controlled: isControlled(props)
+ };
+}
+
+function updateChecked(element, props) {
+ var node = element;
+ var checked = props.checked;
+ if (checked != null) {
+ setValueForProperty(node, 'checked', checked, false);
+ }
+}
+
+function updateWrapper(element, props) {
+ var node = element;
+ {
+ var _controlled = isControlled(props);
+
+ if (!node._wrapperState.controlled && _controlled && !didWarnUncontrolledToControlled) {
+ warning$1(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
+ didWarnUncontrolledToControlled = true;
+ }
+ if (node._wrapperState.controlled && !_controlled && !didWarnControlledToUncontrolled) {
+ warning$1(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
+ didWarnControlledToUncontrolled = true;
+ }
+ }
+
+ updateChecked(element, props);
+
+ var value = getToStringValue(props.value);
+ var type = props.type;
+
+ if (value != null) {
+ if (type === 'number') {
+ if (value === 0 && node.value === '' ||
+ // We explicitly want to coerce to number here if possible.
+ // eslint-disable-next-line
+ node.value != value) {
+ node.value = toString(value);
+ }
+ } else if (node.value !== toString(value)) {
+ node.value = toString(value);
+ }
+ } else if (type === 'submit' || type === 'reset') {
+ // Submit/reset inputs need the attribute removed completely to avoid
+ // blank-text buttons.
+ node.removeAttribute('value');
+ return;
+ }
+
+ if (disableInputAttributeSyncing) {
+ // When not syncing the value attribute, React only assigns a new value
+ // whenever the defaultValue React prop has changed. When not present,
+ // React does nothing
+ if (props.hasOwnProperty('defaultValue')) {
+ setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
+ }
+ } else {
+ // When syncing the value attribute, the value comes from a cascade of
+ // properties:
+ // 1. The value React property
+ // 2. The defaultValue React property
+ // 3. Otherwise there should be no change
+ if (props.hasOwnProperty('value')) {
+ setDefaultValue(node, props.type, value);
+ } else if (props.hasOwnProperty('defaultValue')) {
+ setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
+ }
+ }
+
+ if (disableInputAttributeSyncing) {
+ // When not syncing the checked attribute, the attribute is directly
+ // controllable from the defaultValue React property. It needs to be
+ // updated as new props come in.
+ if (props.defaultChecked == null) {
+ node.removeAttribute('checked');
+ } else {
+ node.defaultChecked = !!props.defaultChecked;
+ }
+ } else {
+ // When syncing the checked attribute, it only changes when it needs
+ // to be removed, such as transitioning from a checkbox into a text input
+ if (props.checked == null && props.defaultChecked != null) {
+ node.defaultChecked = !!props.defaultChecked;
+ }
+ }
+}
+
+function postMountWrapper(element, props, isHydrating) {
+ var node = element;
+
+ // Do not assign value if it is already set. This prevents user text input
+ // from being lost during SSR hydration.
+ if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
+ var type = props.type;
+ var isButton = type === 'submit' || type === 'reset';
+
+ // Avoid setting value attribute on submit/reset inputs as it overrides the
+ // default value provided by the browser. See: #12872
+ if (isButton && (props.value === undefined || props.value === null)) {
+ return;
+ }
+
+ var _initialValue = toString(node._wrapperState.initialValue);
+
+ // Do not assign value if it is already set. This prevents user text input
+ // from being lost during SSR hydration.
+ if (!isHydrating) {
+ if (disableInputAttributeSyncing) {
+ var value = getToStringValue(props.value);
+
+ // When not syncing the value attribute, the value property points
+ // directly to the React prop. Only assign it if it exists.
+ if (value != null) {
+ // Always assign on buttons so that it is possible to assign an
+ // empty string to clear button text.
+ //
+ // Otherwise, do not re-assign the value property if is empty. This
+ // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
+ // prematurely marking required inputs as invalid. Equality is compared
+ // to the current value in case the browser provided value is not an
+ // empty string.
+ if (isButton || value !== node.value) {
+ node.value = toString(value);
+ }
+ }
+ } else {
+ // When syncing the value attribute, the value property should use
+ // the wrapperState._initialValue property. This uses:
+ //
+ // 1. The value React property when present
+ // 2. The defaultValue React property when present
+ // 3. An empty string
+ if (_initialValue !== node.value) {
+ node.value = _initialValue;
+ }
+ }
+ }
+
+ if (disableInputAttributeSyncing) {
+ // When not syncing the value attribute, assign the value attribute
+ // directly from the defaultValue React property (when present)
+ var defaultValue = getToStringValue(props.defaultValue);
+ if (defaultValue != null) {
+ node.defaultValue = toString(defaultValue);
+ }
+ } else {
+ // Otherwise, the value attribute is synchronized to the property,
+ // so we assign defaultValue to the same thing as the value property
+ // assignment step above.
+ node.defaultValue = _initialValue;
+ }
+ }
+
+ // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
+ // this is needed to work around a chrome bug where setting defaultChecked
+ // will sometimes influence the value of checked (even after detachment).
+ // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
+ // We need to temporarily unset name to avoid disrupting radio button groups.
+ var name = node.name;
+ if (name !== '') {
+ node.name = '';
+ }
+
+ if (disableInputAttributeSyncing) {
+ // When not syncing the checked attribute, the checked property
+ // never gets assigned. It must be manually set. We don't want
+ // to do this when hydrating so that existing user input isn't
+ // modified
+ if (!isHydrating) {
+ updateChecked(element, props);
+ }
+
+ // Only assign the checked attribute if it is defined. This saves
+ // a DOM write when controlling the checked attribute isn't needed
+ // (text inputs, submit/reset)
+ if (props.hasOwnProperty('defaultChecked')) {
+ node.defaultChecked = !node.defaultChecked;
+ node.defaultChecked = !!props.defaultChecked;
+ }
+ } else {
+ // When syncing the checked attribute, both the checked property and
+ // attribute are assigned at the same time using defaultChecked. This uses:
+ //
+ // 1. The checked React property when present
+ // 2. The defaultChecked React property when present
+ // 3. Otherwise, false
+ node.defaultChecked = !node.defaultChecked;
+ node.defaultChecked = !!node._wrapperState.initialChecked;
+ }
+
+ if (name !== '') {
+ node.name = name;
+ }
+}
+
+function restoreControlledState(element, props) {
+ var node = element;
+ updateWrapper(node, props);
+ updateNamedCousins(node, props);
+}
+
+function updateNamedCousins(rootNode, props) {
+ var name = props.name;
+ if (props.type === 'radio' && name != null) {
+ var queryRoot = rootNode;
+
+ while (queryRoot.parentNode) {
+ queryRoot = queryRoot.parentNode;
+ }
+
+ // If `rootNode.form` was non-null, then we could try `form.elements`,
+ // but that sometimes behaves strangely in IE8. We could also try using
+ // `form.getElementsByName`, but that will only return direct children
+ // and won't include inputs that use the HTML5 `form=` attribute. Since
+ // the input might not even be in a form. It might not even be in the
+ // document. Let's just use the local `querySelectorAll` to ensure we don't
+ // miss anything.
+ var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
+
+ for (var i = 0; i < group.length; i++) {
+ var otherNode = group[i];
+ if (otherNode === rootNode || otherNode.form !== rootNode.form) {
+ continue;
+ }
+ // This will throw if radio buttons rendered by different copies of React
+ // and the same name are rendered into the same form (same as #1939).
+ // That's probably okay; we don't support it just as we don't support
+ // mixing React radio buttons with non-React ones.
+ var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
+ !otherProps ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : void 0;
+
+ // We need update the tracked value on the named cousin since the value
+ // was changed but the input saw no event or value set
+ updateValueIfChanged(otherNode);
+
+ // If this is a controlled radio button group, forcing the input that
+ // was previously checked to update will cause it to be come re-checked
+ // as appropriate.
+ updateWrapper(otherNode, otherProps);
+ }
+ }
+}
+
+// In Chrome, assigning defaultValue to certain input types triggers input validation.
+// For number inputs, the display value loses trailing decimal points. For email inputs,
+// Chrome raises "The specified value is not a valid email address".
+//
+// Here we check to see if the defaultValue has actually changed, avoiding these problems
+// when the user is inputting text
+//
+// https://github.com/facebook/react/issues/7253
+function setDefaultValue(node, type, value) {
+ if (
+ // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
+ type !== 'number' || node.ownerDocument.activeElement !== node) {
+ if (value == null) {
+ node.defaultValue = toString(node._wrapperState.initialValue);
+ } else if (node.defaultValue !== toString(value)) {
+ node.defaultValue = toString(value);
+ }
+ }
+}
+
+var eventTypes$1 = {
+ change: {
+ phasedRegistrationNames: {
+ bubbled: 'onChange',
+ captured: 'onChangeCapture'
+ },
+ dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
+ }
+};
+
+function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
+ var event = SyntheticEvent.getPooled(eventTypes$1.change, inst, nativeEvent, target);
+ event.type = 'change';
+ // Flag this event loop as needing state restore.
+ enqueueStateRestore(target);
+ accumulateTwoPhaseDispatches(event);
+ return event;
+}
+/**
+ * For IE shims
+ */
+var activeElement = null;
+var activeElementInst = null;
+
+/**
+ * SECTION: handle `change` event
+ */
+function shouldUseChangeEvent(elem) {
+ var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
+ return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
+}
+
+function manualDispatchChangeEvent(nativeEvent) {
+ var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
+
+ // If change and propertychange bubbled, we'd just bind to it like all the
+ // other events and have it go through ReactBrowserEventEmitter. Since it
+ // doesn't, we manually listen for the events and so we have to enqueue and
+ // process the abstract event manually.
+ //
+ // Batching is necessary here in order to ensure that all event handlers run
+ // before the next rerender (including event handlers attached to ancestor
+ // elements instead of directly on the input). Without this, controlled
+ // components don't work properly in conjunction with event bubbling because
+ // the component is rerendered and the value reverted before all the event
+ // handlers can run. See https://github.com/facebook/react/issues/708.
+ batchedUpdates(runEventInBatch, event);
+}
+
+function runEventInBatch(event) {
+ runEventsInBatch(event);
+}
+
+function getInstIfValueChanged(targetInst) {
+ var targetNode = getNodeFromInstance$1(targetInst);
+ if (updateValueIfChanged(targetNode)) {
+ return targetInst;
+ }
+}
+
+function getTargetInstForChangeEvent(topLevelType, targetInst) {
+ if (topLevelType === TOP_CHANGE) {
+ return targetInst;
+ }
+}
+
+/**
+ * SECTION: handle `input` event
+ */
+var isInputEventSupported = false;
+if (canUseDOM) {
+ // IE9 claims to support the input event but fails to trigger it when
+ // deleting text, so we ignore its input events.
+ isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
+}
+
+/**
+ * (For IE <=9) Starts tracking propertychange events on the passed-in element
+ * and override the value property so that we can distinguish user events from
+ * value changes in JS.
+ */
+function startWatchingForValueChange(target, targetInst) {
+ activeElement = target;
+ activeElementInst = targetInst;
+ activeElement.attachEvent('onpropertychange', handlePropertyChange);
+}
+
+/**
+ * (For IE <=9) Removes the event listeners from the currently-tracked element,
+ * if any exists.
+ */
+function stopWatchingForValueChange() {
+ if (!activeElement) {
+ return;
+ }
+ activeElement.detachEvent('onpropertychange', handlePropertyChange);
+ activeElement = null;
+ activeElementInst = null;
+}
+
+/**
+ * (For IE <=9) Handles a propertychange event, sending a `change` event if
+ * the value of the active element has changed.
+ */
+function handlePropertyChange(nativeEvent) {
+ if (nativeEvent.propertyName !== 'value') {
+ return;
+ }
+ if (getInstIfValueChanged(activeElementInst)) {
+ manualDispatchChangeEvent(nativeEvent);
+ }
+}
+
+function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
+ if (topLevelType === TOP_FOCUS) {
+ // In IE9, propertychange fires for most input events but is buggy and
+ // doesn't fire when text is deleted, but conveniently, selectionchange
+ // appears to fire in all of the remaining cases so we catch those and
+ // forward the event if the value has changed
+ // In either case, we don't want to call the event handler if the value
+ // is changed from JS so we redefine a setter for `.value` that updates
+ // our activeElementValue variable, allowing us to ignore those changes
+ //
+ // stopWatching() should be a noop here but we call it just in case we
+ // missed a blur event somehow.
+ stopWatchingForValueChange();
+ startWatchingForValueChange(target, targetInst);
+ } else if (topLevelType === TOP_BLUR) {
+ stopWatchingForValueChange();
+ }
+}
+
+// For IE8 and IE9.
+function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
+ if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
+ // On the selectionchange event, the target is just document which isn't
+ // helpful for us so just check activeElement instead.
+ //
+ // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
+ // propertychange on the first input event after setting `value` from a
+ // script and fires only keydown, keypress, keyup. Catching keyup usually
+ // gets it and catching keydown lets us fire an event for the first
+ // keystroke if user does a key repeat (it'll be a little delayed: right
+ // before the second keystroke). Other input methods (e.g., paste) seem to
+ // fire selectionchange normally.
+ return getInstIfValueChanged(activeElementInst);
+ }
+}
+
+/**
+ * SECTION: handle `click` event
+ */
+function shouldUseClickEvent(elem) {
+ // Use the `click` event to detect changes to checkbox and radio inputs.
+ // This approach works across all browsers, whereas `change` does not fire
+ // until `blur` in IE8.
+ var nodeName = elem.nodeName;
+ return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
+}
+
+function getTargetInstForClickEvent(topLevelType, targetInst) {
+ if (topLevelType === TOP_CLICK) {
+ return getInstIfValueChanged(targetInst);
+ }
+}
+
+function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
+ if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
+ return getInstIfValueChanged(targetInst);
+ }
+}
+
+function handleControlledInputBlur(node) {
+ var state = node._wrapperState;
+
+ if (!state || !state.controlled || node.type !== 'number') {
+ return;
+ }
+
+ if (!disableInputAttributeSyncing) {
+ // If controlled, assign the value attribute to the current value on blur
+ setDefaultValue(node, 'number', node.value);
+ }
+}
+
+/**
+ * This plugin creates an `onChange` event that normalizes change events
+ * across form elements. This event fires at a time when it's possible to
+ * change the element's value without seeing a flicker.
+ *
+ * Supported elements are:
+ * - input (see `isTextInputElement`)
+ * - textarea
+ * - select
+ */
+var ChangeEventPlugin = {
+ eventTypes: eventTypes$1,
+
+ _isInputEventSupported: isInputEventSupported,
+
+ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
+
+ var getTargetInstFunc = void 0,
+ handleEventFunc = void 0;
+ if (shouldUseChangeEvent(targetNode)) {
+ getTargetInstFunc = getTargetInstForChangeEvent;
+ } else if (isTextInputElement(targetNode)) {
+ if (isInputEventSupported) {
+ getTargetInstFunc = getTargetInstForInputOrChangeEvent;
+ } else {
+ getTargetInstFunc = getTargetInstForInputEventPolyfill;
+ handleEventFunc = handleEventsForInputEventPolyfill;
+ }
+ } else if (shouldUseClickEvent(targetNode)) {
+ getTargetInstFunc = getTargetInstForClickEvent;
+ }
+
+ if (getTargetInstFunc) {
+ var inst = getTargetInstFunc(topLevelType, targetInst);
+ if (inst) {
+ var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
+ return event;
+ }
+ }
+
+ if (handleEventFunc) {
+ handleEventFunc(topLevelType, targetNode, targetInst);
+ }
+
+ // When blurring, set the value attribute for number inputs
+ if (topLevelType === TOP_BLUR) {
+ handleControlledInputBlur(targetNode);
+ }
+ }
+};
+
+/**
+ * Module that is injectable into `EventPluginHub`, that specifies a
+ * deterministic ordering of `EventPlugin`s. A convenient way to reason about
+ * plugins, without having to package every one of them. This is better than
+ * having plugins be ordered in the same order that they are injected because
+ * that ordering would be influenced by the packaging order.
+ * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
+ * preventing default on events is convenient in `SimpleEventPlugin` handlers.
+ */
+var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
+
+var SyntheticUIEvent = SyntheticEvent.extend({
+ view: null,
+ detail: null
+});
+
+var modifierKeyToProp = {
+ Alt: 'altKey',
+ Control: 'ctrlKey',
+ Meta: 'metaKey',
+ Shift: 'shiftKey'
+};
+
+// Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
+// getModifierState. If getModifierState is not supported, we map it to a set of
+// modifier keys exposed by the event. In this case, Lock-keys are not supported.
+/**
+ * Translation from modifier key to the associated property in the event.
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
+ */
+
+function modifierStateGetter(keyArg) {
+ var syntheticEvent = this;
+ var nativeEvent = syntheticEvent.nativeEvent;
+ if (nativeEvent.getModifierState) {
+ return nativeEvent.getModifierState(keyArg);
+ }
+ var keyProp = modifierKeyToProp[keyArg];
+ return keyProp ? !!nativeEvent[keyProp] : false;
+}
+
+function getEventModifierState(nativeEvent) {
+ return modifierStateGetter;
+}
+
+var previousScreenX = 0;
+var previousScreenY = 0;
+// Use flags to signal movementX/Y has already been set
+var isMovementXSet = false;
+var isMovementYSet = false;
+
+/**
+ * @interface MouseEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var SyntheticMouseEvent = SyntheticUIEvent.extend({
+ screenX: null,
+ screenY: null,
+ clientX: null,
+ clientY: null,
+ pageX: null,
+ pageY: null,
+ ctrlKey: null,
+ shiftKey: null,
+ altKey: null,
+ metaKey: null,
+ getModifierState: getEventModifierState,
+ button: null,
+ buttons: null,
+ relatedTarget: function (event) {
+ return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
+ },
+ movementX: function (event) {
+ if ('movementX' in event) {
+ return event.movementX;
+ }
+
+ var screenX = previousScreenX;
+ previousScreenX = event.screenX;
+
+ if (!isMovementXSet) {
+ isMovementXSet = true;
+ return 0;
+ }
+
+ return event.type === 'mousemove' ? event.screenX - screenX : 0;
+ },
+ movementY: function (event) {
+ if ('movementY' in event) {
+ return event.movementY;
+ }
+
+ var screenY = previousScreenY;
+ previousScreenY = event.screenY;
+
+ if (!isMovementYSet) {
+ isMovementYSet = true;
+ return 0;
+ }
+
+ return event.type === 'mousemove' ? event.screenY - screenY : 0;
+ }
+});
+
+/**
+ * @interface PointerEvent
+ * @see http://www.w3.org/TR/pointerevents/
+ */
+var SyntheticPointerEvent = SyntheticMouseEvent.extend({
+ pointerId: null,
+ width: null,
+ height: null,
+ pressure: null,
+ tangentialPressure: null,
+ tiltX: null,
+ tiltY: null,
+ twist: null,
+ pointerType: null,
+ isPrimary: null
+});
+
+var eventTypes$2 = {
+ mouseEnter: {
+ registrationName: 'onMouseEnter',
+ dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
+ },
+ mouseLeave: {
+ registrationName: 'onMouseLeave',
+ dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
+ },
+ pointerEnter: {
+ registrationName: 'onPointerEnter',
+ dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
+ },
+ pointerLeave: {
+ registrationName: 'onPointerLeave',
+ dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
+ }
+};
+
+var EnterLeaveEventPlugin = {
+ eventTypes: eventTypes$2,
+
+ /**
+ * For almost every interaction we care about, there will be both a top-level
+ * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
+ * we do not extract duplicate events. However, moving the mouse into the
+ * browser from outside will not fire a `mouseout` event. In this case, we use
+ * the `mouseover` top-level event.
+ */
+ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
+ var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
+
+ if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
+ return null;
+ }
+
+ if (!isOutEvent && !isOverEvent) {
+ // Must not be a mouse or pointer in or out - ignoring.
+ return null;
+ }
+
+ var win = void 0;
+ if (nativeEventTarget.window === nativeEventTarget) {
+ // `nativeEventTarget` is probably a window object.
+ win = nativeEventTarget;
+ } else {
+ // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
+ var doc = nativeEventTarget.ownerDocument;
+ if (doc) {
+ win = doc.defaultView || doc.parentWindow;
+ } else {
+ win = window;
+ }
+ }
+
+ var from = void 0;
+ var to = void 0;
+ if (isOutEvent) {
+ from = targetInst;
+ var related = nativeEvent.relatedTarget || nativeEvent.toElement;
+ to = related ? getClosestInstanceFromNode(related) : null;
+ } else {
+ // Moving to a node from outside the window.
+ from = null;
+ to = targetInst;
+ }
+
+ if (from === to) {
+ // Nothing pertains to our managed components.
+ return null;
+ }
+
+ var eventInterface = void 0,
+ leaveEventType = void 0,
+ enterEventType = void 0,
+ eventTypePrefix = void 0;
+
+ if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
+ eventInterface = SyntheticMouseEvent;
+ leaveEventType = eventTypes$2.mouseLeave;
+ enterEventType = eventTypes$2.mouseEnter;
+ eventTypePrefix = 'mouse';
+ } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
+ eventInterface = SyntheticPointerEvent;
+ leaveEventType = eventTypes$2.pointerLeave;
+ enterEventType = eventTypes$2.pointerEnter;
+ eventTypePrefix = 'pointer';
+ }
+
+ var fromNode = from == null ? win : getNodeFromInstance$1(from);
+ var toNode = to == null ? win : getNodeFromInstance$1(to);
+
+ var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
+ leave.type = eventTypePrefix + 'leave';
+ leave.target = fromNode;
+ leave.relatedTarget = toNode;
+
+ var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
+ enter.type = eventTypePrefix + 'enter';
+ enter.target = toNode;
+ enter.relatedTarget = fromNode;
+
+ accumulateEnterLeaveDispatches(leave, enter, from, to);
+
+ return [leave, enter];
+ }
+};
+
+/*eslint-disable no-self-compare */
+
+var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
+
+/**
+ * inlined Object.is polyfill to avoid requiring consumers ship their own
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
+ */
+function is(x, y) {
+ // SameValue algorithm
+ if (x === y) {
+ // Steps 1-5, 7-10
+ // Steps 6.b-6.e: +0 != -0
+ // Added the nonzero y check to make Flow happy, but it is redundant
+ return x !== 0 || y !== 0 || 1 / x === 1 / y;
+ } else {
+ // Step 6.a: NaN == NaN
+ return x !== x && y !== y;
+ }
+}
+
+/**
+ * Performs equality by iterating through keys on an object and returning false
+ * when any key has values which are not strictly equal between the arguments.
+ * Returns true when the values of all keys are strictly equal.
+ */
+function shallowEqual(objA, objB) {
+ if (is(objA, objB)) {
+ return true;
+ }
+
+ if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
+ return false;
+ }
+
+ var keysA = Object.keys(objA);
+ var keysB = Object.keys(objB);
+
+ if (keysA.length !== keysB.length) {
+ return false;
+ }
+
+ // Test for A's keys different from B.
+ for (var i = 0; i < keysA.length; i++) {
+ if (!hasOwnProperty$1.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/**
+ * `ReactInstanceMap` maintains a mapping from a public facing stateful
+ * instance (key) and the internal representation (value). This allows public
+ * methods to accept the user facing instance as an argument and map them back
+ * to internal methods.
+ *
+ * Note that this module is currently shared and assumed to be stateless.
+ * If this becomes an actual Map, that will break.
+ */
+
+/**
+ * This API should be called `delete` but we'd have to make sure to always
+ * transform these to strings for IE support. When this transform is fully
+ * supported we can rename it.
+ */
+
+
+function get(key) {
+ return key._reactInternalFiber;
+}
+
+function has(key) {
+ return key._reactInternalFiber !== undefined;
+}
+
+function set(key, value) {
+ key._reactInternalFiber = value;
+}
+
+// Don't change these two values. They're used by React Dev Tools.
+var NoEffect = /* */0;
+var PerformedWork = /* */1;
+
+// You can change the rest (and add more).
+var Placement = /* */2;
+var Update = /* */4;
+var PlacementAndUpdate = /* */6;
+var Deletion = /* */8;
+var ContentReset = /* */16;
+var Callback = /* */32;
+var DidCapture = /* */64;
+var Ref = /* */128;
+var Snapshot = /* */256;
+var Passive = /* */512;
+
+// Passive & Update & Callback & Ref & Snapshot
+var LifecycleEffectMask = /* */932;
+
+// Union of all host effects
+var HostEffectMask = /* */1023;
+
+var Incomplete = /* */1024;
+var ShouldCapture = /* */2048;
+
+var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
+
+var MOUNTING = 1;
+var MOUNTED = 2;
+var UNMOUNTED = 3;
+
+function isFiberMountedImpl(fiber) {
+ var node = fiber;
+ if (!fiber.alternate) {
+ // If there is no alternate, this might be a new tree that isn't inserted
+ // yet. If it is, then it will have a pending insertion effect on it.
+ if ((node.effectTag & Placement) !== NoEffect) {
+ return MOUNTING;
+ }
+ while (node.return) {
+ node = node.return;
+ if ((node.effectTag & Placement) !== NoEffect) {
+ return MOUNTING;
+ }
+ }
+ } else {
+ while (node.return) {
+ node = node.return;
+ }
+ }
+ if (node.tag === HostRoot) {
+ // TODO: Check if this was a nested HostRoot when used with
+ // renderContainerIntoSubtree.
+ return MOUNTED;
+ }
+ // If we didn't hit the root, that means that we're in an disconnected tree
+ // that has been unmounted.
+ return UNMOUNTED;
+}
+
+function isFiberMounted(fiber) {
+ return isFiberMountedImpl(fiber) === MOUNTED;
+}
+
+function isMounted(component) {
+ {
+ var owner = ReactCurrentOwner$1.current;
+ if (owner !== null && owner.tag === ClassComponent) {
+ var ownerFiber = owner;
+ var instance = ownerFiber.stateNode;
+ !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
+ instance._warnedAboutRefsInRender = true;
+ }
+ }
+
+ var fiber = get(component);
+ if (!fiber) {
+ return false;
+ }
+ return isFiberMountedImpl(fiber) === MOUNTED;
+}
+
+function assertIsMounted(fiber) {
+ !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
+}
+
+function findCurrentFiberUsingSlowPath(fiber) {
+ var alternate = fiber.alternate;
+ if (!alternate) {
+ // If there is no alternate, then we only need to check if it is mounted.
+ var state = isFiberMountedImpl(fiber);
+ !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
+ if (state === MOUNTING) {
+ return null;
+ }
+ return fiber;
+ }
+ // If we have two possible branches, we'll walk backwards up to the root
+ // to see what path the root points to. On the way we may hit one of the
+ // special cases and we'll deal with them.
+ var a = fiber;
+ var b = alternate;
+ while (true) {
+ var parentA = a.return;
+ var parentB = parentA ? parentA.alternate : null;
+ if (!parentA || !parentB) {
+ // We're at the root.
+ break;
+ }
+
+ // If both copies of the parent fiber point to the same child, we can
+ // assume that the child is current. This happens when we bailout on low
+ // priority: the bailed out fiber's child reuses the current child.
+ if (parentA.child === parentB.child) {
+ var child = parentA.child;
+ while (child) {
+ if (child === a) {
+ // We've determined that A is the current branch.
+ assertIsMounted(parentA);
+ return fiber;
+ }
+ if (child === b) {
+ // We've determined that B is the current branch.
+ assertIsMounted(parentA);
+ return alternate;
+ }
+ child = child.sibling;
+ }
+ // We should never have an alternate for any mounting node. So the only
+ // way this could possibly happen is if this was unmounted, if at all.
+ invariant(false, 'Unable to find node on an unmounted component.');
+ }
+
+ if (a.return !== b.return) {
+ // The return pointer of A and the return pointer of B point to different
+ // fibers. We assume that return pointers never criss-cross, so A must
+ // belong to the child set of A.return, and B must belong to the child
+ // set of B.return.
+ a = parentA;
+ b = parentB;
+ } else {
+ // The return pointers point to the same fiber. We'll have to use the
+ // default, slow path: scan the child sets of each parent alternate to see
+ // which child belongs to which set.
+ //
+ // Search parent A's child set
+ var didFindChild = false;
+ var _child = parentA.child;
+ while (_child) {
+ if (_child === a) {
+ didFindChild = true;
+ a = parentA;
+ b = parentB;
+ break;
+ }
+ if (_child === b) {
+ didFindChild = true;
+ b = parentA;
+ a = parentB;
+ break;
+ }
+ _child = _child.sibling;
+ }
+ if (!didFindChild) {
+ // Search parent B's child set
+ _child = parentB.child;
+ while (_child) {
+ if (_child === a) {
+ didFindChild = true;
+ a = parentB;
+ b = parentA;
+ break;
+ }
+ if (_child === b) {
+ didFindChild = true;
+ b = parentB;
+ a = parentA;
+ break;
+ }
+ _child = _child.sibling;
+ }
+ !didFindChild ? invariant(false, 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.') : void 0;
+ }
+ }
+
+ !(a.alternate === b) ? invariant(false, 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.') : void 0;
+ }
+ // If the root is not a host container, we're in a disconnected tree. I.e.
+ // unmounted.
+ !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
+ if (a.stateNode.current === a) {
+ // We've determined that A is the current branch.
+ return fiber;
+ }
+ // Otherwise B has to be current branch.
+ return alternate;
+}
+
+function findCurrentHostFiber(parent) {
+ var currentParent = findCurrentFiberUsingSlowPath(parent);
+ if (!currentParent) {
+ return null;
+ }
+
+ // Next we'll drill down this component to find the first HostComponent/Text.
+ var node = currentParent;
+ while (true) {
+ if (node.tag === HostComponent || node.tag === HostText) {
+ return node;
+ } else if (node.child) {
+ node.child.return = node;
+ node = node.child;
+ continue;
+ }
+ if (node === currentParent) {
+ return null;
+ }
+ while (!node.sibling) {
+ if (!node.return || node.return === currentParent) {
+ return null;
+ }
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ }
+ // Flow needs the return null here, but ESLint complains about it.
+ // eslint-disable-next-line no-unreachable
+ return null;
+}
+
+function findCurrentHostFiberWithNoPortals(parent) {
+ var currentParent = findCurrentFiberUsingSlowPath(parent);
+ if (!currentParent) {
+ return null;
+ }
+
+ // Next we'll drill down this component to find the first HostComponent/Text.
+ var node = currentParent;
+ while (true) {
+ if (node.tag === HostComponent || node.tag === HostText) {
+ return node;
+ } else if (node.child && node.tag !== HostPortal) {
+ node.child.return = node;
+ node = node.child;
+ continue;
+ }
+ if (node === currentParent) {
+ return null;
+ }
+ while (!node.sibling) {
+ if (!node.return || node.return === currentParent) {
+ return null;
+ }
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ }
+ // Flow needs the return null here, but ESLint complains about it.
+ // eslint-disable-next-line no-unreachable
+ return null;
+}
+
+function addEventBubbleListener(element, eventType, listener) {
+ element.addEventListener(eventType, listener, false);
+}
+
+function addEventCaptureListener(element, eventType, listener) {
+ element.addEventListener(eventType, listener, true);
+}
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
+ */
+var SyntheticAnimationEvent = SyntheticEvent.extend({
+ animationName: null,
+ elapsedTime: null,
+ pseudoElement: null
+});
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/clipboard-apis/
+ */
+var SyntheticClipboardEvent = SyntheticEvent.extend({
+ clipboardData: function (event) {
+ return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
+ }
+});
+
+/**
+ * @interface FocusEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var SyntheticFocusEvent = SyntheticUIEvent.extend({
+ relatedTarget: null
+});
+
+/**
+ * `charCode` represents the actual "character code" and is safe to use with
+ * `String.fromCharCode`. As such, only keys that correspond to printable
+ * characters produce a valid `charCode`, the only exception to this is Enter.
+ * The Tab-key is considered non-printable and does not have a `charCode`,
+ * presumably because it does not produce a tab-character in browsers.
+ *
+ * @param {object} nativeEvent Native browser event.
+ * @return {number} Normalized `charCode` property.
+ */
+function getEventCharCode(nativeEvent) {
+ var charCode = void 0;
+ var keyCode = nativeEvent.keyCode;
+
+ if ('charCode' in nativeEvent) {
+ charCode = nativeEvent.charCode;
+
+ // FF does not set `charCode` for the Enter-key, check against `keyCode`.
+ if (charCode === 0 && keyCode === 13) {
+ charCode = 13;
+ }
+ } else {
+ // IE8 does not implement `charCode`, but `keyCode` has the correct value.
+ charCode = keyCode;
+ }
+
+ // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
+ // report Enter as charCode 10 when ctrl is pressed.
+ if (charCode === 10) {
+ charCode = 13;
+ }
+
+ // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
+ // Must not discard the (non-)printable Enter-key.
+ if (charCode >= 32 || charCode === 13) {
+ return charCode;
+ }
+
+ return 0;
+}
+
+/**
+ * Normalization of deprecated HTML5 `key` values
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
+ */
+var normalizeKey = {
+ Esc: 'Escape',
+ Spacebar: ' ',
+ Left: 'ArrowLeft',
+ Up: 'ArrowUp',
+ Right: 'ArrowRight',
+ Down: 'ArrowDown',
+ Del: 'Delete',
+ Win: 'OS',
+ Menu: 'ContextMenu',
+ Apps: 'ContextMenu',
+ Scroll: 'ScrollLock',
+ MozPrintableKey: 'Unidentified'
+};
+
+/**
+ * Translation from legacy `keyCode` to HTML5 `key`
+ * Only special keys supported, all others depend on keyboard layout or browser
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
+ */
+var translateToKey = {
+ '8': 'Backspace',
+ '9': 'Tab',
+ '12': 'Clear',
+ '13': 'Enter',
+ '16': 'Shift',
+ '17': 'Control',
+ '18': 'Alt',
+ '19': 'Pause',
+ '20': 'CapsLock',
+ '27': 'Escape',
+ '32': ' ',
+ '33': 'PageUp',
+ '34': 'PageDown',
+ '35': 'End',
+ '36': 'Home',
+ '37': 'ArrowLeft',
+ '38': 'ArrowUp',
+ '39': 'ArrowRight',
+ '40': 'ArrowDown',
+ '45': 'Insert',
+ '46': 'Delete',
+ '112': 'F1',
+ '113': 'F2',
+ '114': 'F3',
+ '115': 'F4',
+ '116': 'F5',
+ '117': 'F6',
+ '118': 'F7',
+ '119': 'F8',
+ '120': 'F9',
+ '121': 'F10',
+ '122': 'F11',
+ '123': 'F12',
+ '144': 'NumLock',
+ '145': 'ScrollLock',
+ '224': 'Meta'
+};
+
+/**
+ * @param {object} nativeEvent Native browser event.
+ * @return {string} Normalized `key` property.
+ */
+function getEventKey(nativeEvent) {
+ if (nativeEvent.key) {
+ // Normalize inconsistent values reported by browsers due to
+ // implementations of a working draft specification.
+
+ // FireFox implements `key` but returns `MozPrintableKey` for all
+ // printable characters (normalized to `Unidentified`), ignore it.
+ var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
+ if (key !== 'Unidentified') {
+ return key;
+ }
+ }
+
+ // Browser does not implement `key`, polyfill as much of it as we can.
+ if (nativeEvent.type === 'keypress') {
+ var charCode = getEventCharCode(nativeEvent);
+
+ // The enter-key is technically both printable and non-printable and can
+ // thus be captured by `keypress`, no other non-printable key should.
+ return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
+ }
+ if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
+ // While user keyboard layout determines the actual meaning of each
+ // `keyCode` value, almost all function keys have a universal value.
+ return translateToKey[nativeEvent.keyCode] || 'Unidentified';
+ }
+ return '';
+}
+
+/**
+ * @interface KeyboardEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
+ key: getEventKey,
+ location: null,
+ ctrlKey: null,
+ shiftKey: null,
+ altKey: null,
+ metaKey: null,
+ repeat: null,
+ locale: null,
+ getModifierState: getEventModifierState,
+ // Legacy Interface
+ charCode: function (event) {
+ // `charCode` is the result of a KeyPress event and represents the value of
+ // the actual printable character.
+
+ // KeyPress is deprecated, but its replacement is not yet final and not
+ // implemented in any major browser. Only KeyPress has charCode.
+ if (event.type === 'keypress') {
+ return getEventCharCode(event);
+ }
+ return 0;
+ },
+ keyCode: function (event) {
+ // `keyCode` is the result of a KeyDown/Up event and represents the value of
+ // physical keyboard key.
+
+ // The actual meaning of the value depends on the users' keyboard layout
+ // which cannot be detected. Assuming that it is a US keyboard layout
+ // provides a surprisingly accurate mapping for US and European users.
+ // Due to this, it is left to the user to implement at this time.
+ if (event.type === 'keydown' || event.type === 'keyup') {
+ return event.keyCode;
+ }
+ return 0;
+ },
+ which: function (event) {
+ // `which` is an alias for either `keyCode` or `charCode` depending on the
+ // type of the event.
+ if (event.type === 'keypress') {
+ return getEventCharCode(event);
+ }
+ if (event.type === 'keydown' || event.type === 'keyup') {
+ return event.keyCode;
+ }
+ return 0;
+ }
+});
+
+/**
+ * @interface DragEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var SyntheticDragEvent = SyntheticMouseEvent.extend({
+ dataTransfer: null
+});
+
+/**
+ * @interface TouchEvent
+ * @see http://www.w3.org/TR/touch-events/
+ */
+var SyntheticTouchEvent = SyntheticUIEvent.extend({
+ touches: null,
+ targetTouches: null,
+ changedTouches: null,
+ altKey: null,
+ metaKey: null,
+ ctrlKey: null,
+ shiftKey: null,
+ getModifierState: getEventModifierState
+});
+
+/**
+ * @interface Event
+ * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
+ */
+var SyntheticTransitionEvent = SyntheticEvent.extend({
+ propertyName: null,
+ elapsedTime: null,
+ pseudoElement: null
+});
+
+/**
+ * @interface WheelEvent
+ * @see http://www.w3.org/TR/DOM-Level-3-Events/
+ */
+var SyntheticWheelEvent = SyntheticMouseEvent.extend({
+ deltaX: function (event) {
+ return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
+ 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
+ },
+ deltaY: function (event) {
+ return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
+ 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
+ 'wheelDelta' in event ? -event.wheelDelta : 0;
+ },
+
+ deltaZ: null,
+
+ // Browsers without "deltaMode" is reporting in raw wheel delta where one
+ // notch on the scroll is always +/- 120, roughly equivalent to pixels.
+ // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
+ // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
+ deltaMode: null
+});
+
+/**
+ * Turns
+ * ['abort', ...]
+ * into
+ * eventTypes = {
+ * 'abort': {
+ * phasedRegistrationNames: {
+ * bubbled: 'onAbort',
+ * captured: 'onAbortCapture',
+ * },
+ * dependencies: [TOP_ABORT],
+ * },
+ * ...
+ * };
+ * topLevelEventsToDispatchConfig = new Map([
+ * [TOP_ABORT, { sameConfig }],
+ * ]);
+ */
+
+var interactiveEventTypeNames = [[TOP_BLUR, 'blur'], [TOP_CANCEL, 'cancel'], [TOP_CLICK, 'click'], [TOP_CLOSE, 'close'], [TOP_CONTEXT_MENU, 'contextMenu'], [TOP_COPY, 'copy'], [TOP_CUT, 'cut'], [TOP_AUX_CLICK, 'auxClick'], [TOP_DOUBLE_CLICK, 'doubleClick'], [TOP_DRAG_END, 'dragEnd'], [TOP_DRAG_START, 'dragStart'], [TOP_DROP, 'drop'], [TOP_FOCUS, 'focus'], [TOP_INPUT, 'input'], [TOP_INVALID, 'invalid'], [TOP_KEY_DOWN, 'keyDown'], [TOP_KEY_PRESS, 'keyPress'], [TOP_KEY_UP, 'keyUp'], [TOP_MOUSE_DOWN, 'mouseDown'], [TOP_MOUSE_UP, 'mouseUp'], [TOP_PASTE, 'paste'], [TOP_PAUSE, 'pause'], [TOP_PLAY, 'play'], [TOP_POINTER_CANCEL, 'pointerCancel'], [TOP_POINTER_DOWN, 'pointerDown'], [TOP_POINTER_UP, 'pointerUp'], [TOP_RATE_CHANGE, 'rateChange'], [TOP_RESET, 'reset'], [TOP_SEEKED, 'seeked'], [TOP_SUBMIT, 'submit'], [TOP_TOUCH_CANCEL, 'touchCancel'], [TOP_TOUCH_END, 'touchEnd'], [TOP_TOUCH_START, 'touchStart'], [TOP_VOLUME_CHANGE, 'volumeChange']];
+var nonInteractiveEventTypeNames = [[TOP_ABORT, 'abort'], [TOP_ANIMATION_END, 'animationEnd'], [TOP_ANIMATION_ITERATION, 'animationIteration'], [TOP_ANIMATION_START, 'animationStart'], [TOP_CAN_PLAY, 'canPlay'], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough'], [TOP_DRAG, 'drag'], [TOP_DRAG_ENTER, 'dragEnter'], [TOP_DRAG_EXIT, 'dragExit'], [TOP_DRAG_LEAVE, 'dragLeave'], [TOP_DRAG_OVER, 'dragOver'], [TOP_DURATION_CHANGE, 'durationChange'], [TOP_EMPTIED, 'emptied'], [TOP_ENCRYPTED, 'encrypted'], [TOP_ENDED, 'ended'], [TOP_ERROR, 'error'], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'], [TOP_LOAD, 'load'], [TOP_LOADED_DATA, 'loadedData'], [TOP_LOADED_METADATA, 'loadedMetadata'], [TOP_LOAD_START, 'loadStart'], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'], [TOP_MOUSE_MOVE, 'mouseMove'], [TOP_MOUSE_OUT, 'mouseOut'], [TOP_MOUSE_OVER, 'mouseOver'], [TOP_PLAYING, 'playing'], [TOP_POINTER_MOVE, 'pointerMove'], [TOP_POINTER_OUT, 'pointerOut'], [TOP_POINTER_OVER, 'pointerOver'], [TOP_PROGRESS, 'progress'], [TOP_SCROLL, 'scroll'], [TOP_SEEKING, 'seeking'], [TOP_STALLED, 'stalled'], [TOP_SUSPEND, 'suspend'], [TOP_TIME_UPDATE, 'timeUpdate'], [TOP_TOGGLE, 'toggle'], [TOP_TOUCH_MOVE, 'touchMove'], [TOP_TRANSITION_END, 'transitionEnd'], [TOP_WAITING, 'waiting'], [TOP_WHEEL, 'wheel']];
+
+var eventTypes$4 = {};
+var topLevelEventsToDispatchConfig = {};
+
+function addEventTypeNameToConfig(_ref, isInteractive) {
+ var topEvent = _ref[0],
+ event = _ref[1];
+
+ var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
+ var onEvent = 'on' + capitalizedEvent;
+
+ var type = {
+ phasedRegistrationNames: {
+ bubbled: onEvent,
+ captured: onEvent + 'Capture'
+ },
+ dependencies: [topEvent],
+ isInteractive: isInteractive
+ };
+ eventTypes$4[event] = type;
+ topLevelEventsToDispatchConfig[topEvent] = type;
+}
+
+interactiveEventTypeNames.forEach(function (eventTuple) {
+ addEventTypeNameToConfig(eventTuple, true);
+});
+nonInteractiveEventTypeNames.forEach(function (eventTuple) {
+ addEventTypeNameToConfig(eventTuple, false);
+});
+
+// Only used in DEV for exhaustiveness validation.
+var knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING];
+
+var SimpleEventPlugin = {
+ eventTypes: eventTypes$4,
+
+ isInteractiveTopLevelEventType: function (topLevelType) {
+ var config = topLevelEventsToDispatchConfig[topLevelType];
+ return config !== undefined && config.isInteractive === true;
+ },
+
+
+ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
+ if (!dispatchConfig) {
+ return null;
+ }
+ var EventConstructor = void 0;
+ switch (topLevelType) {
+ case TOP_KEY_PRESS:
+ // Firefox creates a keypress event for function keys too. This removes
+ // the unwanted keypress events. Enter is however both printable and
+ // non-printable. One would expect Tab to be as well (but it isn't).
+ if (getEventCharCode(nativeEvent) === 0) {
+ return null;
+ }
+ /* falls through */
+ case TOP_KEY_DOWN:
+ case TOP_KEY_UP:
+ EventConstructor = SyntheticKeyboardEvent;
+ break;
+ case TOP_BLUR:
+ case TOP_FOCUS:
+ EventConstructor = SyntheticFocusEvent;
+ break;
+ case TOP_CLICK:
+ // Firefox creates a click event on right mouse clicks. This removes the
+ // unwanted click events.
+ if (nativeEvent.button === 2) {
+ return null;
+ }
+ /* falls through */
+ case TOP_AUX_CLICK:
+ case TOP_DOUBLE_CLICK:
+ case TOP_MOUSE_DOWN:
+ case TOP_MOUSE_MOVE:
+ case TOP_MOUSE_UP:
+ // TODO: Disabled elements should not respond to mouse events
+ /* falls through */
+ case TOP_MOUSE_OUT:
+ case TOP_MOUSE_OVER:
+ case TOP_CONTEXT_MENU:
+ EventConstructor = SyntheticMouseEvent;
+ break;
+ case TOP_DRAG:
+ case TOP_DRAG_END:
+ case TOP_DRAG_ENTER:
+ case TOP_DRAG_EXIT:
+ case TOP_DRAG_LEAVE:
+ case TOP_DRAG_OVER:
+ case TOP_DRAG_START:
+ case TOP_DROP:
+ EventConstructor = SyntheticDragEvent;
+ break;
+ case TOP_TOUCH_CANCEL:
+ case TOP_TOUCH_END:
+ case TOP_TOUCH_MOVE:
+ case TOP_TOUCH_START:
+ EventConstructor = SyntheticTouchEvent;
+ break;
+ case TOP_ANIMATION_END:
+ case TOP_ANIMATION_ITERATION:
+ case TOP_ANIMATION_START:
+ EventConstructor = SyntheticAnimationEvent;
+ break;
+ case TOP_TRANSITION_END:
+ EventConstructor = SyntheticTransitionEvent;
+ break;
+ case TOP_SCROLL:
+ EventConstructor = SyntheticUIEvent;
+ break;
+ case TOP_WHEEL:
+ EventConstructor = SyntheticWheelEvent;
+ break;
+ case TOP_COPY:
+ case TOP_CUT:
+ case TOP_PASTE:
+ EventConstructor = SyntheticClipboardEvent;
+ break;
+ case TOP_GOT_POINTER_CAPTURE:
+ case TOP_LOST_POINTER_CAPTURE:
+ case TOP_POINTER_CANCEL:
+ case TOP_POINTER_DOWN:
+ case TOP_POINTER_MOVE:
+ case TOP_POINTER_OUT:
+ case TOP_POINTER_OVER:
+ case TOP_POINTER_UP:
+ EventConstructor = SyntheticPointerEvent;
+ break;
+ default:
+ {
+ if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
+ warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
+ }
+ }
+ // HTML Events
+ // @see http://www.w3.org/TR/html5/index.html#events-0
+ EventConstructor = SyntheticEvent;
+ break;
+ }
+ var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
+ accumulateTwoPhaseDispatches(event);
+ return event;
+ }
+};
+
+var isInteractiveTopLevelEventType = SimpleEventPlugin.isInteractiveTopLevelEventType;
+
+
+var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
+var callbackBookkeepingPool = [];
+
+/**
+ * Find the deepest React component completely containing the root of the
+ * passed-in instance (for use when entire React trees are nested within each
+ * other). If React trees are not nested, returns null.
+ */
+function findRootContainerNode(inst) {
+ // TODO: It may be a good idea to cache this to prevent unnecessary DOM
+ // traversal, but caching is difficult to do correctly without using a
+ // mutation observer to listen for all DOM changes.
+ while (inst.return) {
+ inst = inst.return;
+ }
+ if (inst.tag !== HostRoot) {
+ // This can happen if we're in a detached tree.
+ return null;
+ }
+ return inst.stateNode.containerInfo;
+}
+
+// Used to store ancestor hierarchy in top level callback
+function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
+ if (callbackBookkeepingPool.length) {
+ var instance = callbackBookkeepingPool.pop();
+ instance.topLevelType = topLevelType;
+ instance.nativeEvent = nativeEvent;
+ instance.targetInst = targetInst;
+ return instance;
+ }
+ return {
+ topLevelType: topLevelType,
+ nativeEvent: nativeEvent,
+ targetInst: targetInst,
+ ancestors: []
+ };
+}
+
+function releaseTopLevelCallbackBookKeeping(instance) {
+ instance.topLevelType = null;
+ instance.nativeEvent = null;
+ instance.targetInst = null;
+ instance.ancestors.length = 0;
+ if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
+ callbackBookkeepingPool.push(instance);
+ }
+}
+
+function handleTopLevel(bookKeeping) {
+ var targetInst = bookKeeping.targetInst;
+
+ // Loop through the hierarchy, in case there's any nested components.
+ // It's important that we build the array of ancestors before calling any
+ // event handlers, because event handlers can modify the DOM, leading to
+ // inconsistencies with ReactMount's node cache. See #1105.
+ var ancestor = targetInst;
+ do {
+ if (!ancestor) {
+ bookKeeping.ancestors.push(ancestor);
+ break;
+ }
+ var root = findRootContainerNode(ancestor);
+ if (!root) {
+ break;
+ }
+ bookKeeping.ancestors.push(ancestor);
+ ancestor = getClosestInstanceFromNode(root);
+ } while (ancestor);
+
+ for (var i = 0; i < bookKeeping.ancestors.length; i++) {
+ targetInst = bookKeeping.ancestors[i];
+ runExtractedEventsInBatch(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent));
+ }
+}
+
+// TODO: can we stop exporting these?
+var _enabled = true;
+
+function setEnabled(enabled) {
+ _enabled = !!enabled;
+}
+
+function isEnabled() {
+ return _enabled;
+}
+
+/**
+ * Traps top-level events by using event bubbling.
+ *
+ * @param {number} topLevelType Number from `TopLevelEventTypes`.
+ * @param {object} element Element on which to attach listener.
+ * @return {?object} An object with a remove function which will forcefully
+ * remove the listener.
+ * @internal
+ */
+function trapBubbledEvent(topLevelType, element) {
+ if (!element) {
+ return null;
+ }
+ var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
+
+ addEventBubbleListener(element, getRawEventName(topLevelType),
+ // Check if interactive and wrap in interactiveUpdates
+ dispatch.bind(null, topLevelType));
+}
+
+/**
+ * Traps a top-level event by using event capturing.
+ *
+ * @param {number} topLevelType Number from `TopLevelEventTypes`.
+ * @param {object} element Element on which to attach listener.
+ * @return {?object} An object with a remove function which will forcefully
+ * remove the listener.
+ * @internal
+ */
+function trapCapturedEvent(topLevelType, element) {
+ if (!element) {
+ return null;
+ }
+ var dispatch = isInteractiveTopLevelEventType(topLevelType) ? dispatchInteractiveEvent : dispatchEvent;
+
+ addEventCaptureListener(element, getRawEventName(topLevelType),
+ // Check if interactive and wrap in interactiveUpdates
+ dispatch.bind(null, topLevelType));
+}
+
+function dispatchInteractiveEvent(topLevelType, nativeEvent) {
+ interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
+}
+
+function dispatchEvent(topLevelType, nativeEvent) {
+ if (!_enabled) {
+ return;
+ }
+
+ var nativeEventTarget = getEventTarget(nativeEvent);
+ var targetInst = getClosestInstanceFromNode(nativeEventTarget);
+ if (targetInst !== null && typeof targetInst.tag === 'number' && !isFiberMounted(targetInst)) {
+ // If we get an event (ex: img onload) before committing that
+ // component's mount, ignore it for now (that is, treat it as if it was an
+ // event on a non-React tree). We might also consider queueing events and
+ // dispatching them after the mount.
+ targetInst = null;
+ }
+
+ var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst);
+
+ try {
+ // Event queue being processed in the same cycle allows
+ // `preventDefault`.
+ batchedUpdates(handleTopLevel, bookKeeping);
+ } finally {
+ releaseTopLevelCallbackBookKeeping(bookKeeping);
+ }
+}
+
+/**
+ * Summary of `ReactBrowserEventEmitter` event handling:
+ *
+ * - Top-level delegation is used to trap most native browser events. This
+ * may only occur in the main thread and is the responsibility of
+ * ReactDOMEventListener, which is injected and can therefore support
+ * pluggable event sources. This is the only work that occurs in the main
+ * thread.
+ *
+ * - We normalize and de-duplicate events to account for browser quirks. This
+ * may be done in the worker thread.
+ *
+ * - Forward these native events (with the associated top-level type used to
+ * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
+ * to extract any synthetic events.
+ *
+ * - The `EventPluginHub` will then process each event by annotating them with
+ * "dispatches", a sequence of listeners and IDs that care about that event.
+ *
+ * - The `EventPluginHub` then dispatches the events.
+ *
+ * Overview of React and the event system:
+ *
+ * +------------+ .
+ * | DOM | .
+ * +------------+ .
+ * | .
+ * v .
+ * +------------+ .
+ * | ReactEvent | .
+ * | Listener | .
+ * +------------+ . +-----------+
+ * | . +--------+|SimpleEvent|
+ * | . | |Plugin |
+ * +-----|------+ . v +-----------+
+ * | | | . +--------------+ +------------+
+ * | +-----------.--->|EventPluginHub| | Event |
+ * | | . | | +-----------+ | Propagators|
+ * | ReactEvent | . | | |TapEvent | |------------|
+ * | Emitter | . | |<---+|Plugin | |other plugin|
+ * | | . | | +-----------+ | utilities |
+ * | +-----------.--->| | +------------+
+ * | | | . +--------------+
+ * +-----|------+ . ^ +-----------+
+ * | . | |Enter/Leave|
+ * + . +-------+|Plugin |
+ * +-------------+ . +-----------+
+ * | application | .
+ * |-------------| .
+ * | | .
+ * | | .
+ * +-------------+ .
+ * .
+ * React Core . General Purpose Event Plugin System
+ */
+
+var alreadyListeningTo = {};
+var reactTopListenersCounter = 0;
+
+/**
+ * To ensure no conflicts with other potential React instances on the page
+ */
+var topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
+
+function getListeningForDocument(mountAt) {
+ // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
+ // directly.
+ if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
+ mountAt[topListenersIDKey] = reactTopListenersCounter++;
+ alreadyListeningTo[mountAt[topListenersIDKey]] = {};
+ }
+ return alreadyListeningTo[mountAt[topListenersIDKey]];
+}
+
+/**
+ * We listen for bubbled touch events on the document object.
+ *
+ * Firefox v8.01 (and possibly others) exhibited strange behavior when
+ * mounting `onmousemove` events at some node that was not the document
+ * element. The symptoms were that if your mouse is not moving over something
+ * contained within that mount point (for example on the background) the
+ * top-level listeners for `onmousemove` won't be called. However, if you
+ * register the `mousemove` on the document object, then it will of course
+ * catch all `mousemove`s. This along with iOS quirks, justifies restricting
+ * top-level listeners to the document object only, at least for these
+ * movement types of events and possibly all events.
+ *
+ * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
+ *
+ * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
+ * they bubble to document.
+ *
+ * @param {string} registrationName Name of listener (e.g. `onClick`).
+ * @param {object} mountAt Container where to mount the listener
+ */
+function listenTo(registrationName, mountAt) {
+ var isListening = getListeningForDocument(mountAt);
+ var dependencies = registrationNameDependencies[registrationName];
+
+ for (var i = 0; i < dependencies.length; i++) {
+ var dependency = dependencies[i];
+ if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
+ switch (dependency) {
+ case TOP_SCROLL:
+ trapCapturedEvent(TOP_SCROLL, mountAt);
+ break;
+ case TOP_FOCUS:
+ case TOP_BLUR:
+ trapCapturedEvent(TOP_FOCUS, mountAt);
+ trapCapturedEvent(TOP_BLUR, mountAt);
+ // We set the flag for a single dependency later in this function,
+ // but this ensures we mark both as attached rather than just one.
+ isListening[TOP_BLUR] = true;
+ isListening[TOP_FOCUS] = true;
+ break;
+ case TOP_CANCEL:
+ case TOP_CLOSE:
+ if (isEventSupported(getRawEventName(dependency))) {
+ trapCapturedEvent(dependency, mountAt);
+ }
+ break;
+ case TOP_INVALID:
+ case TOP_SUBMIT:
+ case TOP_RESET:
+ // We listen to them on the target DOM elements.
+ // Some of them bubble so we don't want them to fire twice.
+ break;
+ default:
+ // By default, listen on the top level to all non-media events.
+ // Media events don't bubble so adding the listener wouldn't do anything.
+ var isMediaEvent = mediaEventTypes.indexOf(dependency) !== -1;
+ if (!isMediaEvent) {
+ trapBubbledEvent(dependency, mountAt);
+ }
+ break;
+ }
+ isListening[dependency] = true;
+ }
+ }
+}
+
+function isListeningToAllDependencies(registrationName, mountAt) {
+ var isListening = getListeningForDocument(mountAt);
+ var dependencies = registrationNameDependencies[registrationName];
+ for (var i = 0; i < dependencies.length; i++) {
+ var dependency = dependencies[i];
+ if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+function getActiveElement(doc) {
+ doc = doc || (typeof document !== 'undefined' ? document : undefined);
+ if (typeof doc === 'undefined') {
+ return null;
+ }
+ try {
+ return doc.activeElement || doc.body;
+ } catch (e) {
+ return doc.body;
+ }
+}
+
+/**
+ * Given any node return the first leaf node without children.
+ *
+ * @param {DOMElement|DOMTextNode} node
+ * @return {DOMElement|DOMTextNode}
+ */
+function getLeafNode(node) {
+ while (node && node.firstChild) {
+ node = node.firstChild;
+ }
+ return node;
+}
+
+/**
+ * Get the next sibling within a container. This will walk up the
+ * DOM if a node's siblings have been exhausted.
+ *
+ * @param {DOMElement|DOMTextNode} node
+ * @return {?DOMElement|DOMTextNode}
+ */
+function getSiblingNode(node) {
+ while (node) {
+ if (node.nextSibling) {
+ return node.nextSibling;
+ }
+ node = node.parentNode;
+ }
+}
+
+/**
+ * Get object describing the nodes which contain characters at offset.
+ *
+ * @param {DOMElement|DOMTextNode} root
+ * @param {number} offset
+ * @return {?object}
+ */
+function getNodeForCharacterOffset(root, offset) {
+ var node = getLeafNode(root);
+ var nodeStart = 0;
+ var nodeEnd = 0;
+
+ while (node) {
+ if (node.nodeType === TEXT_NODE) {
+ nodeEnd = nodeStart + node.textContent.length;
+
+ if (nodeStart <= offset && nodeEnd >= offset) {
+ return {
+ node: node,
+ offset: offset - nodeStart
+ };
+ }
+
+ nodeStart = nodeEnd;
+ }
+
+ node = getLeafNode(getSiblingNode(node));
+ }
+}
+
+/**
+ * @param {DOMElement} outerNode
+ * @return {?object}
+ */
+function getOffsets(outerNode) {
+ var ownerDocument = outerNode.ownerDocument;
+
+ var win = ownerDocument && ownerDocument.defaultView || window;
+ var selection = win.getSelection && win.getSelection();
+
+ if (!selection || selection.rangeCount === 0) {
+ return null;
+ }
+
+ var anchorNode = selection.anchorNode,
+ anchorOffset = selection.anchorOffset,
+ focusNode = selection.focusNode,
+ focusOffset = selection.focusOffset;
+
+ // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
+ // up/down buttons on an . Anonymous divs do not seem to
+ // expose properties, triggering a "Permission denied error" if any of its
+ // properties are accessed. The only seemingly possible way to avoid erroring
+ // is to access a property that typically works for non-anonymous divs and
+ // catch any error that may otherwise arise. See
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+
+ try {
+ /* eslint-disable no-unused-expressions */
+ anchorNode.nodeType;
+ focusNode.nodeType;
+ /* eslint-enable no-unused-expressions */
+ } catch (e) {
+ return null;
+ }
+
+ return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
+}
+
+/**
+ * Returns {start, end} where `start` is the character/codepoint index of
+ * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
+ * `end` is the index of (focusNode, focusOffset).
+ *
+ * Returns null if you pass in garbage input but we should probably just crash.
+ *
+ * Exported only for testing.
+ */
+function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
+ var length = 0;
+ var start = -1;
+ var end = -1;
+ var indexWithinAnchor = 0;
+ var indexWithinFocus = 0;
+ var node = outerNode;
+ var parentNode = null;
+
+ outer: while (true) {
+ var next = null;
+
+ while (true) {
+ if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
+ start = length + anchorOffset;
+ }
+ if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
+ end = length + focusOffset;
+ }
+
+ if (node.nodeType === TEXT_NODE) {
+ length += node.nodeValue.length;
+ }
+
+ if ((next = node.firstChild) === null) {
+ break;
+ }
+ // Moving from `node` to its first child `next`.
+ parentNode = node;
+ node = next;
+ }
+
+ while (true) {
+ if (node === outerNode) {
+ // If `outerNode` has children, this is always the second time visiting
+ // it. If it has no children, this is still the first loop, and the only
+ // valid selection is anchorNode and focusNode both equal to this node
+ // and both offsets 0, in which case we will have handled above.
+ break outer;
+ }
+ if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
+ start = length;
+ }
+ if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
+ end = length;
+ }
+ if ((next = node.nextSibling) !== null) {
+ break;
+ }
+ node = parentNode;
+ parentNode = node.parentNode;
+ }
+
+ // Moving from `node` to its next sibling `next`.
+ node = next;
+ }
+
+ if (start === -1 || end === -1) {
+ // This should never happen. (Would happen if the anchor/focus nodes aren't
+ // actually inside the passed-in node.)
+ return null;
+ }
+
+ return {
+ start: start,
+ end: end
+ };
+}
+
+/**
+ * In modern non-IE browsers, we can support both forward and backward
+ * selections.
+ *
+ * Note: IE10+ supports the Selection object, but it does not support
+ * the `extend` method, which means that even in modern IE, it's not possible
+ * to programmatically create a backward selection. Thus, for all IE
+ * versions, we use the old IE API to create our selections.
+ *
+ * @param {DOMElement|DOMTextNode} node
+ * @param {object} offsets
+ */
+function setOffsets(node, offsets) {
+ var doc = node.ownerDocument || document;
+ var win = doc && doc.defaultView || window;
+
+ // Edge fails with "Object expected" in some scenarios.
+ // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
+ // fails when pasting 100+ items)
+ if (!win.getSelection) {
+ return;
+ }
+
+ var selection = win.getSelection();
+ var length = node.textContent.length;
+ var start = Math.min(offsets.start, length);
+ var end = offsets.end === undefined ? start : Math.min(offsets.end, length);
+
+ // IE 11 uses modern selection, but doesn't support the extend method.
+ // Flip backward selections, so we can set with a single range.
+ if (!selection.extend && start > end) {
+ var temp = end;
+ end = start;
+ start = temp;
+ }
+
+ var startMarker = getNodeForCharacterOffset(node, start);
+ var endMarker = getNodeForCharacterOffset(node, end);
+
+ if (startMarker && endMarker) {
+ if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
+ return;
+ }
+ var range = doc.createRange();
+ range.setStart(startMarker.node, startMarker.offset);
+ selection.removeAllRanges();
+
+ if (start > end) {
+ selection.addRange(range);
+ selection.extend(endMarker.node, endMarker.offset);
+ } else {
+ range.setEnd(endMarker.node, endMarker.offset);
+ selection.addRange(range);
+ }
+ }
+}
+
+function isTextNode(node) {
+ return node && node.nodeType === TEXT_NODE;
+}
+
+function containsNode(outerNode, innerNode) {
+ if (!outerNode || !innerNode) {
+ return false;
+ } else if (outerNode === innerNode) {
+ return true;
+ } else if (isTextNode(outerNode)) {
+ return false;
+ } else if (isTextNode(innerNode)) {
+ return containsNode(outerNode, innerNode.parentNode);
+ } else if ('contains' in outerNode) {
+ return outerNode.contains(innerNode);
+ } else if (outerNode.compareDocumentPosition) {
+ return !!(outerNode.compareDocumentPosition(innerNode) & 16);
+ } else {
+ return false;
+ }
+}
+
+function isInDocument(node) {
+ return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
+}
+
+function getActiveElementDeep() {
+ var win = window;
+ var element = getActiveElement();
+ while (element instanceof win.HTMLIFrameElement) {
+ // Accessing the contentDocument of a HTMLIframeElement can cause the browser
+ // to throw, e.g. if it has a cross-origin src attribute
+ try {
+ win = element.contentDocument.defaultView;
+ } catch (e) {
+ return element;
+ }
+ element = getActiveElement(win.document);
+ }
+ return element;
+}
+
+/**
+ * @ReactInputSelection: React input selection module. Based on Selection.js,
+ * but modified to be suitable for react and has a couple of bug fixes (doesn't
+ * assume buttons have range selections allowed).
+ * Input selection module for React.
+ */
+
+/**
+ * @hasSelectionCapabilities: we get the element types that support selection
+ * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
+ * and `selectionEnd` rows.
+ */
+function hasSelectionCapabilities(elem) {
+ var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
+ return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
+}
+
+function getSelectionInformation() {
+ var focusedElem = getActiveElementDeep();
+ return {
+ focusedElem: focusedElem,
+ selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection$1(focusedElem) : null
+ };
+}
+
+/**
+ * @restoreSelection: If any selection information was potentially lost,
+ * restore it. This is useful when performing operations that could remove dom
+ * nodes and place them back in, resulting in focus being lost.
+ */
+function restoreSelection(priorSelectionInformation) {
+ var curFocusedElem = getActiveElementDeep();
+ var priorFocusedElem = priorSelectionInformation.focusedElem;
+ var priorSelectionRange = priorSelectionInformation.selectionRange;
+ if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
+ if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
+ setSelection(priorFocusedElem, priorSelectionRange);
+ }
+
+ // Focusing a node can change the scroll position, which is undesirable
+ var ancestors = [];
+ var ancestor = priorFocusedElem;
+ while (ancestor = ancestor.parentNode) {
+ if (ancestor.nodeType === ELEMENT_NODE) {
+ ancestors.push({
+ element: ancestor,
+ left: ancestor.scrollLeft,
+ top: ancestor.scrollTop
+ });
+ }
+ }
+
+ if (typeof priorFocusedElem.focus === 'function') {
+ priorFocusedElem.focus();
+ }
+
+ for (var i = 0; i < ancestors.length; i++) {
+ var info = ancestors[i];
+ info.element.scrollLeft = info.left;
+ info.element.scrollTop = info.top;
+ }
+ }
+}
+
+/**
+ * @getSelection: Gets the selection bounds of a focused textarea, input or
+ * contentEditable node.
+ * -@input: Look up selection bounds of this input
+ * -@return {start: selectionStart, end: selectionEnd}
+ */
+function getSelection$1(input) {
+ var selection = void 0;
+
+ if ('selectionStart' in input) {
+ // Modern browser with input or textarea.
+ selection = {
+ start: input.selectionStart,
+ end: input.selectionEnd
+ };
+ } else {
+ // Content editable or old IE textarea.
+ selection = getOffsets(input);
+ }
+
+ return selection || { start: 0, end: 0 };
+}
+
+/**
+ * @setSelection: Sets the selection bounds of a textarea or input and focuses
+ * the input.
+ * -@input Set selection bounds of this input or textarea
+ * -@offsets Object of same form that is returned from get*
+ */
+function setSelection(input, offsets) {
+ var start = offsets.start,
+ end = offsets.end;
+
+ if (end === undefined) {
+ end = start;
+ }
+
+ if ('selectionStart' in input) {
+ input.selectionStart = start;
+ input.selectionEnd = Math.min(end, input.value.length);
+ } else {
+ setOffsets(input, offsets);
+ }
+}
+
+var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
+
+var eventTypes$3 = {
+ select: {
+ phasedRegistrationNames: {
+ bubbled: 'onSelect',
+ captured: 'onSelectCapture'
+ },
+ dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE]
+ }
+};
+
+var activeElement$1 = null;
+var activeElementInst$1 = null;
+var lastSelection = null;
+var mouseDown = false;
+
+/**
+ * Get an object which is a unique representation of the current selection.
+ *
+ * The return value will not be consistent across nodes or browsers, but
+ * two identical selections on the same node will return identical objects.
+ *
+ * @param {DOMElement} node
+ * @return {object}
+ */
+function getSelection(node) {
+ if ('selectionStart' in node && hasSelectionCapabilities(node)) {
+ return {
+ start: node.selectionStart,
+ end: node.selectionEnd
+ };
+ } else {
+ var win = node.ownerDocument && node.ownerDocument.defaultView || window;
+ var selection = win.getSelection();
+ return {
+ anchorNode: selection.anchorNode,
+ anchorOffset: selection.anchorOffset,
+ focusNode: selection.focusNode,
+ focusOffset: selection.focusOffset
+ };
+ }
+}
+
+/**
+ * Get document associated with the event target.
+ *
+ * @param {object} nativeEventTarget
+ * @return {Document}
+ */
+function getEventTargetDocument(eventTarget) {
+ return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
+}
+
+/**
+ * Poll selection to see whether it's changed.
+ *
+ * @param {object} nativeEvent
+ * @param {object} nativeEventTarget
+ * @return {?SyntheticEvent}
+ */
+function constructSelectEvent(nativeEvent, nativeEventTarget) {
+ // Ensure we have the right element, and that the user is not dragging a
+ // selection (this matches native `select` event behavior). In HTML5, select
+ // fires only on input and textarea thus if there's no focused element we
+ // won't dispatch.
+ var doc = getEventTargetDocument(nativeEventTarget);
+
+ if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
+ return null;
+ }
+
+ // Only fire when selection has actually changed.
+ var currentSelection = getSelection(activeElement$1);
+ if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
+ lastSelection = currentSelection;
+
+ var syntheticEvent = SyntheticEvent.getPooled(eventTypes$3.select, activeElementInst$1, nativeEvent, nativeEventTarget);
+
+ syntheticEvent.type = 'select';
+ syntheticEvent.target = activeElement$1;
+
+ accumulateTwoPhaseDispatches(syntheticEvent);
+
+ return syntheticEvent;
+ }
+
+ return null;
+}
+
+/**
+ * This plugin creates an `onSelect` event that normalizes select events
+ * across form elements.
+ *
+ * Supported elements are:
+ * - input (see `isTextInputElement`)
+ * - textarea
+ * - contentEditable
+ *
+ * This differs from native browser implementations in the following ways:
+ * - Fires on contentEditable fields as well as inputs.
+ * - Fires for collapsed selection.
+ * - Fires after user input.
+ */
+var SelectEventPlugin = {
+ eventTypes: eventTypes$3,
+
+ extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {
+ var doc = getEventTargetDocument(nativeEventTarget);
+ // Track whether all listeners exists for this plugin. If none exist, we do
+ // not extract events. See #3639.
+ if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
+ return null;
+ }
+
+ var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
+
+ switch (topLevelType) {
+ // Track the input node that has focus.
+ case TOP_FOCUS:
+ if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
+ activeElement$1 = targetNode;
+ activeElementInst$1 = targetInst;
+ lastSelection = null;
+ }
+ break;
+ case TOP_BLUR:
+ activeElement$1 = null;
+ activeElementInst$1 = null;
+ lastSelection = null;
+ break;
+ // Don't fire the event while the user is dragging. This matches the
+ // semantics of the native select event.
+ case TOP_MOUSE_DOWN:
+ mouseDown = true;
+ break;
+ case TOP_CONTEXT_MENU:
+ case TOP_MOUSE_UP:
+ case TOP_DRAG_END:
+ mouseDown = false;
+ return constructSelectEvent(nativeEvent, nativeEventTarget);
+ // Chrome and IE fire non-standard event when selection is changed (and
+ // sometimes when it hasn't). IE's event fires out of order with respect
+ // to key and input events on deletion, so we discard it.
+ //
+ // Firefox doesn't support selectionchange, so check selection status
+ // after each key entry. The selection changes after keydown and before
+ // keyup, but we check on keydown as well in the case of holding down a
+ // key, when multiple keydown events are fired but only one keyup is.
+ // This is also our approach for IE handling, for the reason above.
+ case TOP_SELECTION_CHANGE:
+ if (skipSelectionChangeEvent) {
+ break;
+ }
+ // falls through
+ case TOP_KEY_DOWN:
+ case TOP_KEY_UP:
+ return constructSelectEvent(nativeEvent, nativeEventTarget);
+ }
+
+ return null;
+ }
+};
+
+/**
+ * Inject modules for resolving DOM hierarchy and plugin ordering.
+ */
+injection.injectEventPluginOrder(DOMEventPluginOrder);
+setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
+
+/**
+ * Some important event plugins included by default (without having to require
+ * them).
+ */
+injection.injectEventPluginsByName({
+ SimpleEventPlugin: SimpleEventPlugin,
+ EnterLeaveEventPlugin: EnterLeaveEventPlugin,
+ ChangeEventPlugin: ChangeEventPlugin,
+ SelectEventPlugin: SelectEventPlugin,
+ BeforeInputEventPlugin: BeforeInputEventPlugin
+});
+
+var didWarnSelectedSetOnOption = false;
+var didWarnInvalidChild = false;
+
+function flattenChildren(children) {
+ var content = '';
+
+ // Flatten children. We'll warn if they are invalid
+ // during validateProps() which runs for hydration too.
+ // Note that this would throw on non-element objects.
+ // Elements are stringified (which is normally irrelevant
+ // but matters for ).
+ React.Children.forEach(children, function (child) {
+ if (child == null) {
+ return;
+ }
+ content += child;
+ // Note: we don't warn about invalid children here.
+ // Instead, this is done separately below so that
+ // it happens during the hydration codepath too.
+ });
+
+ return content;
+}
+
+/**
+ * Implements an host component that warns when `selected` is set.
+ */
+
+function validateProps(element, props) {
+ {
+ // This mirrors the codepath above, but runs for hydration too.
+ // Warn about invalid children here so that client and hydration are consistent.
+ // TODO: this seems like it could cause a DEV-only throw for hydration
+ // if children contains a non-element object. We should try to avoid that.
+ if (typeof props.children === 'object' && props.children !== null) {
+ React.Children.forEach(props.children, function (child) {
+ if (child == null) {
+ return;
+ }
+ if (typeof child === 'string' || typeof child === 'number') {
+ return;
+ }
+ if (typeof child.type !== 'string') {
+ return;
+ }
+ if (!didWarnInvalidChild) {
+ didWarnInvalidChild = true;
+ warning$1(false, 'Only strings and numbers are supported as children.');
+ }
+ });
+ }
+
+ // TODO: Remove support for `selected` in .
+ if (props.selected != null && !didWarnSelectedSetOnOption) {
+ warning$1(false, 'Use the `defaultValue` or `value` props on instead of ' + 'setting `selected` on .');
+ didWarnSelectedSetOnOption = true;
+ }
+ }
+}
+
+function postMountWrapper$1(element, props) {
+ // value="" should make a value attribute (#6219)
+ if (props.value != null) {
+ element.setAttribute('value', toString(getToStringValue(props.value)));
+ }
+}
+
+function getHostProps$1(element, props) {
+ var hostProps = _assign({ children: undefined }, props);
+ var content = flattenChildren(props.children);
+
+ if (content) {
+ hostProps.children = content;
+ }
+
+ return hostProps;
+}
+
+// TODO: direct imports like some-package/src/* are bad. Fix me.
+var didWarnValueDefaultValue$1 = void 0;
+
+{
+ didWarnValueDefaultValue$1 = false;
+}
+
+function getDeclarationErrorAddendum() {
+ var ownerName = getCurrentFiberOwnerNameInDevOrNull();
+ if (ownerName) {
+ return '\n\nCheck the render method of `' + ownerName + '`.';
+ }
+ return '';
+}
+
+var valuePropNames = ['value', 'defaultValue'];
+
+/**
+ * Validation function for `value` and `defaultValue`.
+ */
+function checkSelectPropTypes(props) {
+ ReactControlledValuePropTypes.checkPropTypes('select', props);
+
+ for (var i = 0; i < valuePropNames.length; i++) {
+ var propName = valuePropNames[i];
+ if (props[propName] == null) {
+ continue;
+ }
+ var isArray = Array.isArray(props[propName]);
+ if (props.multiple && !isArray) {
+ warning$1(false, 'The `%s` prop supplied to must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
+ } else if (!props.multiple && isArray) {
+ warning$1(false, 'The `%s` prop supplied to must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
+ }
+ }
+}
+
+function updateOptions(node, multiple, propValue, setDefaultSelected) {
+ var options = node.options;
+
+ if (multiple) {
+ var selectedValues = propValue;
+ var selectedValue = {};
+ for (var i = 0; i < selectedValues.length; i++) {
+ // Prefix to avoid chaos with special keys.
+ selectedValue['$' + selectedValues[i]] = true;
+ }
+ for (var _i = 0; _i < options.length; _i++) {
+ var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
+ if (options[_i].selected !== selected) {
+ options[_i].selected = selected;
+ }
+ if (selected && setDefaultSelected) {
+ options[_i].defaultSelected = true;
+ }
+ }
+ } else {
+ // Do not set `select.value` as exact behavior isn't consistent across all
+ // browsers for all cases.
+ var _selectedValue = toString(getToStringValue(propValue));
+ var defaultSelected = null;
+ for (var _i2 = 0; _i2 < options.length; _i2++) {
+ if (options[_i2].value === _selectedValue) {
+ options[_i2].selected = true;
+ if (setDefaultSelected) {
+ options[_i2].defaultSelected = true;
+ }
+ return;
+ }
+ if (defaultSelected === null && !options[_i2].disabled) {
+ defaultSelected = options[_i2];
+ }
+ }
+ if (defaultSelected !== null) {
+ defaultSelected.selected = true;
+ }
+ }
+}
+
+/**
+ * Implements a host component that allows optionally setting the
+ * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
+ * stringable. If `multiple` is true, the prop must be an array of stringables.
+ *
+ * If `value` is not supplied (or null/undefined), user actions that change the
+ * selected option will trigger updates to the rendered options.
+ *
+ * If it is supplied (and not null/undefined), the rendered options will not
+ * update in response to user actions. Instead, the `value` prop must change in
+ * order for the rendered options to update.
+ *
+ * If `defaultValue` is provided, any options with the supplied values will be
+ * selected.
+ */
+
+function getHostProps$2(element, props) {
+ return _assign({}, props, {
+ value: undefined
+ });
+}
+
+function initWrapperState$1(element, props) {
+ var node = element;
+ {
+ checkSelectPropTypes(props);
+ }
+
+ node._wrapperState = {
+ wasMultiple: !!props.multiple
+ };
+
+ {
+ if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
+ warning$1(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components');
+ didWarnValueDefaultValue$1 = true;
+ }
+ }
+}
+
+function postMountWrapper$2(element, props) {
+ var node = element;
+ node.multiple = !!props.multiple;
+ var value = props.value;
+ if (value != null) {
+ updateOptions(node, !!props.multiple, value, false);
+ } else if (props.defaultValue != null) {
+ updateOptions(node, !!props.multiple, props.defaultValue, true);
+ }
+}
+
+function postUpdateWrapper(element, props) {
+ var node = element;
+ var wasMultiple = node._wrapperState.wasMultiple;
+ node._wrapperState.wasMultiple = !!props.multiple;
+
+ var value = props.value;
+ if (value != null) {
+ updateOptions(node, !!props.multiple, value, false);
+ } else if (wasMultiple !== !!props.multiple) {
+ // For simplicity, reapply `defaultValue` if `multiple` is toggled.
+ if (props.defaultValue != null) {
+ updateOptions(node, !!props.multiple, props.defaultValue, true);
+ } else {
+ // Revert the select back to its default unselected state.
+ updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
+ }
+ }
+}
+
+function restoreControlledState$2(element, props) {
+ var node = element;
+ var value = props.value;
+
+ if (value != null) {
+ updateOptions(node, !!props.multiple, value, false);
+ }
+}
+
+var didWarnValDefaultVal = false;
+
+/**
+ * Implements a