elements don't support innerText even when does.
+ contentKey = 'textContent' in document.documentElement ? 'textContent' : 'innerText';
+ }
+ return contentKey;
+}
+
+module.exports = getTextContentAccessor;
+
+/***/ }),
+/* 187 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {/**
+ * Copyright 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ */
+
+
+
+var _prodInvariant = __webpack_require__(3),
+ _assign = __webpack_require__(5);
+
+var ReactCompositeComponent = __webpack_require__(379);
+var ReactEmptyComponent = __webpack_require__(175);
+var ReactHostComponent = __webpack_require__(177);
+
+var getNextDebugID = __webpack_require__(447);
+var invariant = __webpack_require__(1);
+var warning = __webpack_require__(2);
+
+// To avoid a cyclic dependency, we create the final class in this module
+var ReactCompositeComponentWrapper = function (element) {
+ this.construct(element);
+};
+
+function getDeclarationErrorAddendum(owner) {
+ if (owner) {
+ var name = owner.getName();
+ if (name) {
+ return ' Check the render method of `' + name + '`.';
+ }
+ }
+ return '';
+}
+
+/**
+ * Check if the type reference is a known internal type. I.e. not a user
+ * provided composite type.
+ *
+ * @param {function} type
+ * @return {boolean} Returns true if this is a valid internal type.
+ */
+function isInternalComponentType(type) {
+ return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function';
+}
+
+/**
+ * Given a ReactNode, create an instance that will actually be mounted.
+ *
+ * @param {ReactNode} node
+ * @param {boolean} shouldHaveDebugID
+ * @return {object} A new instance of the element's constructor.
+ * @protected
+ */
+function instantiateReactComponent(node, shouldHaveDebugID) {
+ var instance;
+
+ if (node === null || node === false) {
+ instance = ReactEmptyComponent.create(instantiateReactComponent);
+ } else if (typeof node === 'object') {
+ var element = node;
+ var type = element.type;
+ if (typeof type !== 'function' && typeof type !== 'string') {
+ var info = '';
+ if (process.env.NODE_ENV !== 'production') {
+ if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
+ info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.';
+ }
+ }
+ info += getDeclarationErrorAddendum(element._owner);
+ true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info) : _prodInvariant('130', type == null ? type : typeof type, info) : void 0;
+ }
+
+ // Special case string values
+ if (typeof element.type === 'string') {
+ instance = ReactHostComponent.createInternalComponent(element);
+ } else if (isInternalComponentType(element.type)) {
+ // This is temporarily available for custom components that are not string
+ // representations. I.e. ART. Once those are updated to use the string
+ // representation, we can drop this code path.
+ instance = new element.type(element);
+
+ // We renamed this. Allow the old name for compat. :(
+ if (!instance.getHostNode) {
+ instance.getHostNode = instance.getNativeNode;
+ }
+ } else {
+ instance = new ReactCompositeComponentWrapper(element);
+ }
+ } else if (typeof node === 'string' || typeof node === 'number') {
+ instance = ReactHostComponent.createInstanceForText(node);
+ } else {
+ true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : _prodInvariant('131', typeof node) : void 0;
+ }
+
+ if (process.env.NODE_ENV !== 'production') {
+ process.env.NODE_ENV !== 'production' ? warning(typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.getHostNode === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : void 0;
+ }
+
+ // These two fields are used by the DOM and ART diffing algorithms
+ // respectively. Instead of using expandos on components, we should be
+ // storing the state needed by the diffing algorithms elsewhere.
+ instance._mountIndex = 0;
+ instance._mountImage = null;
+
+ if (process.env.NODE_ENV !== 'production') {
+ instance._debugID = shouldHaveDebugID ? getNextDebugID() : 0;
+ }
+
+ // Internal instances should fully constructed at this point, so they should
+ // not get any new fields added to them at this point.
+ if (process.env.NODE_ENV !== 'production') {
+ if (Object.preventExtensions) {
+ Object.preventExtensions(instance);
+ }
+ }
+
+ return instance;
+}
+
+_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, {
+ _instantiateReactComponent: instantiateReactComponent
+});
+
+module.exports = instantiateReactComponent;
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
+
+/***/ }),
+/* 188 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+ * Copyright 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ *
+ */
+
+
+
+/**
+ * @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;
+}
+
+module.exports = isTextInputElement;
+
+/***/ }),
+/* 189 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+ * Copyright 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ */
+
+
+
+var ExecutionEnvironment = __webpack_require__(8);
+var escapeTextContentForBrowser = __webpack_require__(68);
+var setInnerHTML = __webpack_require__(69);
+
+/**
+ * Set the textContent property of a node, ensuring that whitespace is preserved
+ * even in IE8. innerText is a poor substitute for textContent and, among many
+ * issues, inserts
instead of the literal newline chars. innerHTML behaves
+ * as it should.
+ *
+ * @param {DOMElement} node
+ * @param {string} text
+ * @internal
+ */
+var setTextContent = function (node, text) {
+ if (text) {
+ var firstChild = node.firstChild;
+
+ if (firstChild && firstChild === node.lastChild && firstChild.nodeType === 3) {
+ firstChild.nodeValue = text;
+ return;
+ }
+ }
+ node.textContent = text;
+};
+
+if (ExecutionEnvironment.canUseDOM) {
+ if (!('textContent' in document.documentElement)) {
+ setTextContent = function (node, text) {
+ if (node.nodeType === 3) {
+ node.nodeValue = text;
+ return;
+ }
+ setInnerHTML(node, escapeTextContentForBrowser(text));
+ };
+ }
+}
+
+module.exports = setTextContent;
+
+/***/ }),
+/* 190 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {/**
+ * Copyright 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ */
+
+
+
+var _prodInvariant = __webpack_require__(3);
+
+var ReactCurrentOwner = __webpack_require__(20);
+var REACT_ELEMENT_TYPE = __webpack_require__(397);
+
+var getIteratorFn = __webpack_require__(432);
+var invariant = __webpack_require__(1);
+var KeyEscapeUtils = __webpack_require__(100);
+var warning = __webpack_require__(2);
+
+var SEPARATOR = '.';
+var SUBSEPARATOR = ':';
+
+/**
+ * This is inlined from ReactElement since this file is shared between
+ * isomorphic and renderers. We could extract this to a
+ *
+ */
+
+/**
+ * TODO: Test that a single child and an array with one item have the same key
+ * pattern.
+ */
+
+var didWarnAboutMaps = false;
+
+/**
+ * Generate a key string that identifies a component within a set.
+ *
+ * @param {*} component A component that could contain a manual key.
+ * @param {number} index Index that is used if a manual key is not provided.
+ * @return {string}
+ */
+function getComponentKey(component, index) {
+ // Do some typechecking here since we call this blindly. We want to ensure
+ // that we don't block potential future ES APIs.
+ if (component && typeof component === 'object' && component.key != null) {
+ // Explicit key
+ return KeyEscapeUtils.escape(component.key);
+ }
+ // Implicit key determined by the index in the set
+ return index.toString(36);
+}
+
+/**
+ * @param {?*} children Children tree container.
+ * @param {!string} nameSoFar Name of the key path so far.
+ * @param {!function} callback Callback to invoke with each child found.
+ * @param {?*} traverseContext Used to pass information throughout the traversal
+ * process.
+ * @return {!number} The number of children in this subtree.
+ */
+function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {
+ var type = typeof children;
+
+ if (type === 'undefined' || type === 'boolean') {
+ // All of the above are perceived as null.
+ children = null;
+ }
+
+ if (children === null || type === 'string' || type === 'number' ||
+ // The following is inlined from ReactElement. This means we can optimize
+ // some checks. React Fiber also inlines this logic for similar purposes.
+ type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) {
+ callback(traverseContext, children,
+ // If it's the only child, treat the name as if it was wrapped in an array
+ // so that it's consistent if the number of children grows.
+ nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);
+ return 1;
+ }
+
+ var child;
+ var nextName;
+ var subtreeCount = 0; // Count of children found in the current subtree.
+ var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;
+
+ if (Array.isArray(children)) {
+ for (var i = 0; i < children.length; i++) {
+ child = children[i];
+ nextName = nextNamePrefix + getComponentKey(child, i);
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
+ }
+ } else {
+ var iteratorFn = getIteratorFn(children);
+ if (iteratorFn) {
+ var iterator = iteratorFn.call(children);
+ var step;
+ if (iteratorFn !== children.entries) {
+ var ii = 0;
+ while (!(step = iterator.next()).done) {
+ child = step.value;
+ nextName = nextNamePrefix + getComponentKey(child, ii++);
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
+ }
+ } else {
+ if (process.env.NODE_ENV !== 'production') {
+ var mapsAsChildrenAddendum = '';
+ if (ReactCurrentOwner.current) {
+ var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName();
+ if (mapsAsChildrenOwnerName) {
+ mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.';
+ }
+ }
+ process.env.NODE_ENV !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0;
+ didWarnAboutMaps = true;
+ }
+ // Iterator will provide entry [k,v] tuples rather than values.
+ while (!(step = iterator.next()).done) {
+ var entry = step.value;
+ if (entry) {
+ child = entry[1];
+ nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0);
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
+ }
+ }
+ }
+ } else if (type === 'object') {
+ var addendum = '';
+ if (process.env.NODE_ENV !== 'production') {
+ addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.';
+ if (children._isReactElement) {
+ addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.';
+ }
+ if (ReactCurrentOwner.current) {
+ var name = ReactCurrentOwner.current.getName();
+ if (name) {
+ addendum += ' Check the render method of `' + name + '`.';
+ }
+ }
+ }
+ var childrenString = String(children);
+ true ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0;
+ }
+ }
+
+ return subtreeCount;
+}
+
+/**
+ * Traverses children that are typically specified as `props.children`, but
+ * might also be specified through attributes:
+ *
+ * - `traverseAllChildren(this.props.children, ...)`
+ * - `traverseAllChildren(this.props.leftPanelChildren, ...)`
+ *
+ * The `traverseContext` is an optional argument that is passed through the
+ * entire traversal. It can be used to store accumulations or anything else that
+ * the callback might find relevant.
+ *
+ * @param {?*} children Children tree object.
+ * @param {!function} callback To invoke upon traversing each child.
+ * @param {?*} traverseContext Context for traversal.
+ * @return {!number} The number of children in this subtree.
+ */
+function traverseAllChildren(children, callback, traverseContext) {
+ if (children == null) {
+ return 0;
+ }
+
+ return traverseAllChildrenImpl(children, '', callback, traverseContext);
+}
+
+module.exports = traverseAllChildren;
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
+
+/***/ }),
+/* 191 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+ * Copyright 2014-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ *
+ */
+
+
+
+// The Symbol used to tag the ReactElement type. If there is no native Symbol
+// nor polyfill, then a plain number is used for performance.
+
+var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
+
+module.exports = REACT_ELEMENT_TYPE;
+
+/***/ }),
+/* 192 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {/**
+ * Copyright 2014-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ */
+
+/**
+ * ReactElementValidator provides a wrapper around a element factory
+ * which validates the props passed to the element. This is intended to be
+ * used only in DEV and could be replaced by a static type checker for languages
+ * that support it.
+ */
+
+
+
+var ReactCurrentOwner = __webpack_require__(20);
+var ReactComponentTreeHook = __webpack_require__(13);
+var ReactElement = __webpack_require__(31);
+
+var checkReactTypeSpec = __webpack_require__(446);
+
+var canDefineProperty = __webpack_require__(70);
+var getIteratorFn = __webpack_require__(194);
+var warning = __webpack_require__(2);
+
+function getDeclarationErrorAddendum() {
+ if (ReactCurrentOwner.current) {
+ var name = ReactCurrentOwner.current.getName();
+ if (name) {
+ return ' Check the render method of `' + name + '`.';
+ }
+ }
+ return '';
+}
+
+function getSourceInfoErrorAddendum(elementProps) {
+ if (elementProps !== null && elementProps !== undefined && elementProps.__source !== undefined) {
+ var source = elementProps.__source;
+ var fileName = source.fileName.replace(/^.*[\\\/]/, '');
+ var lineNumber = source.lineNumber;
+ return ' Check your code at ' + fileName + ':' + lineNumber + '.';
+ }
+ return '';
+}
+
+/**
+ * Warn if there's no key explicitly set on dynamic arrays of children or
+ * object keys are not valid. This allows us to keep track of children between
+ * updates.
+ */
+var ownerHasKeyUseWarning = {};
+
+function getCurrentComponentErrorInfo(parentType) {
+ var info = getDeclarationErrorAddendum();
+
+ if (!info) {
+ var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
+ if (parentName) {
+ info = ' Check the top-level render call using <' + parentName + '>.';
+ }
+ }
+ return info;
+}
+
+/**
+ * Warn if the element doesn't have an explicit key assigned to it.
+ * This element is in an array. The array could grow and shrink or be
+ * reordered. All children that haven't already been validated are required to
+ * have a "key" property assigned to it. Error statuses are cached so a warning
+ * will only be shown once.
+ *
+ * @internal
+ * @param {ReactElement} element Element that requires a key.
+ * @param {*} parentType element's parent's type.
+ */
+function validateExplicitKey(element, parentType) {
+ if (!element._store || element._store.validated || element.key != null) {
+ return;
+ }
+ element._store.validated = true;
+
+ var memoizer = ownerHasKeyUseWarning.uniqueKey || (ownerHasKeyUseWarning.uniqueKey = {});
+
+ var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
+ if (memoizer[currentComponentErrorInfo]) {
+ return;
+ }
+ memoizer[currentComponentErrorInfo] = true;
+
+ // Usually the current owner is the offender, but if it accepts children as a
+ // property, it may be the creator of the child that's responsible for
+ // assigning it a key.
+ var childOwner = '';
+ if (element && element._owner && element._owner !== ReactCurrentOwner.current) {
+ // Give the component that originally created this child.
+ childOwner = ' It was passed a child from ' + element._owner.getName() + '.';
+ }
+
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s See https://fb.me/react-warning-keys for more information.%s', currentComponentErrorInfo, childOwner, ReactComponentTreeHook.getCurrentStackAddendum(element)) : void 0;
+}
+
+/**
+ * Ensure that every element either is passed in a static location, in an
+ * array with an explicit keys property defined, or in an object literal
+ * with valid key property.
+ *
+ * @internal
+ * @param {ReactNode} node Statically passed child of any type.
+ * @param {*} parentType node's parent's type.
+ */
+function validateChildKeys(node, parentType) {
+ if (typeof node !== 'object') {
+ return;
+ }
+ if (Array.isArray(node)) {
+ for (var i = 0; i < node.length; i++) {
+ var child = node[i];
+ if (ReactElement.isValidElement(child)) {
+ validateExplicitKey(child, parentType);
+ }
+ }
+ } else if (ReactElement.isValidElement(node)) {
+ // This element was passed in a valid location.
+ if (node._store) {
+ node._store.validated = true;
+ }
+ } else if (node) {
+ var iteratorFn = getIteratorFn(node);
+ // Entry iterators provide implicit keys.
+ if (iteratorFn) {
+ if (iteratorFn !== node.entries) {
+ var iterator = iteratorFn.call(node);
+ var step;
+ while (!(step = iterator.next()).done) {
+ if (ReactElement.isValidElement(step.value)) {
+ validateExplicitKey(step.value, parentType);
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Given an element, validate that its props follow the propTypes definition,
+ * provided by the type.
+ *
+ * @param {ReactElement} element
+ */
+function validatePropTypes(element) {
+ var componentClass = element.type;
+ if (typeof componentClass !== 'function') {
+ return;
+ }
+ var name = componentClass.displayName || componentClass.name;
+ if (componentClass.propTypes) {
+ checkReactTypeSpec(componentClass.propTypes, element.props, 'prop', name, element, null);
+ }
+ if (typeof componentClass.getDefaultProps === 'function') {
+ process.env.NODE_ENV !== 'production' ? warning(componentClass.getDefaultProps.isReactClassApproved, 'getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.') : void 0;
+ }
+}
+
+var ReactElementValidator = {
+
+ createElement: function (type, props, children) {
+ var validType = typeof type === 'string' || typeof type === 'function';
+ // We warn in this case but don't throw. We expect the element creation to
+ // succeed and there will likely be errors in render.
+ if (!validType) {
+ if (typeof type !== 'function' && typeof type !== 'string') {
+ var info = '';
+ if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
+ info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.';
+ }
+
+ var sourceInfo = getSourceInfoErrorAddendum(props);
+ if (sourceInfo) {
+ info += sourceInfo;
+ } else {
+ info += getDeclarationErrorAddendum();
+ }
+
+ info += ReactComponentTreeHook.getCurrentStackAddendum();
+
+ process.env.NODE_ENV !== 'production' ? warning(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', type == null ? type : typeof type, info) : void 0;
+ }
+ }
+
+ var element = ReactElement.createElement.apply(this, arguments);
+
+ // The result can be nullish if a mock or a custom function is used.
+ // TODO: Drop this when these are no longer allowed as the type argument.
+ if (element == null) {
+ return element;
+ }
+
+ // Skip key warning if the type isn't valid since our key validation logic
+ // doesn't expect a non-string/function type and can throw confusing errors.
+ // We don't want exception behavior to differ between dev and prod.
+ // (Rendering will throw with a helpful message and as soon as the type is
+ // fixed, the key warnings will appear.)
+ if (validType) {
+ for (var i = 2; i < arguments.length; i++) {
+ validateChildKeys(arguments[i], type);
+ }
+ }
+
+ validatePropTypes(element);
+
+ return element;
+ },
+
+ createFactory: function (type) {
+ var validatedFactory = ReactElementValidator.createElement.bind(null, type);
+ // Legacy hook TODO: Warn if this is accessed
+ validatedFactory.type = type;
+
+ if (process.env.NODE_ENV !== 'production') {
+ if (canDefineProperty) {
+ Object.defineProperty(validatedFactory, 'type', {
+ enumerable: false,
+ get: function () {
+ process.env.NODE_ENV !== 'production' ? warning(false, 'Factory.type is deprecated. Access the class directly ' + 'before passing it to createFactory.') : void 0;
+ Object.defineProperty(this, 'type', {
+ value: type
+ });
+ return type;
+ }
+ });
+ }
+ }
+
+ return validatedFactory;
+ },
+
+ cloneElement: function (element, props, children) {
+ var newElement = ReactElement.cloneElement.apply(this, arguments);
+ for (var i = 2; i < arguments.length; i++) {
+ validateChildKeys(arguments[i], newElement.type);
+ }
+ validatePropTypes(newElement);
+ return newElement;
+ }
+
+};
+
+module.exports = ReactElementValidator;
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
+
+/***/ }),
+/* 193 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {/**
+ * Copyright 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ *
+ */
+
+
+
+var ReactPropTypeLocationNames = {};
+
+if (process.env.NODE_ENV !== 'production') {
+ ReactPropTypeLocationNames = {
+ prop: 'prop',
+ context: 'context',
+ childContext: 'child context'
+ };
+}
+
+module.exports = ReactPropTypeLocationNames;
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
+
+/***/ }),
+/* 194 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+ * Copyright 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ *
+ */
+
+
+
+/* global Symbol */
+
+var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
+var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
+
+/**
+ * Returns the iterator method function contained on the iterable object.
+ *
+ * Be sure to invoke the function with the iterable as context:
+ *
+ * var iteratorFn = getIteratorFn(myIterable);
+ * if (iteratorFn) {
+ * var iterator = iteratorFn.call(myIterable);
+ * ...
+ * }
+ *
+ * @param {?object} maybeIterable
+ * @return {?function}
+ */
+function getIteratorFn(maybeIterable) {
+ var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
+ if (typeof iteratorFn === 'function') {
+ return iteratorFn;
+ }
+}
+
+module.exports = getIteratorFn;
+
+/***/ }),
+/* 195 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* AppConfig.tsx
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* A simple class to store application config.
+*/
+
+var AppConfig = (function () {
+ function AppConfig() {
+ this._isDebug = false;
+ this._isDevelopment = false;
+ }
+ AppConfig.prototype.setAppConfig = function (isDebug, isDevelopment) {
+ this._isDebug = isDebug;
+ this._isDevelopment = isDevelopment;
+ };
+ AppConfig.prototype.isDebugMode = function () {
+ return this._isDebug;
+ };
+ AppConfig.prototype.isDevelopmentMode = function () {
+ return this._isDevelopment;
+ };
+ return AppConfig;
+}());
+exports.AppConfig = AppConfig;
+var instance = new AppConfig();
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = instance;
+
+
+/***/ }),
+/* 196 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* Accessibility.ts
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* Web wrapper for subscribing or querying the current state of the
+* screen reader.
+*/
+
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var Accessibility_1 = __webpack_require__(450);
+var Accessibility = (function (_super) {
+ __extends(Accessibility, _super);
+ function Accessibility() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ // Calling this API on web has no effect.
+ Accessibility.prototype.isScreenReaderEnabled = function () {
+ return false;
+ };
+ return Accessibility;
+}(Accessibility_1.Accessibility));
+exports.Accessibility = Accessibility;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = new Accessibility();
+
+
+/***/ }),
+/* 197 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* Image.tsx
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* Web-specific implementation of the cross-platform Image abstraction.
+*/
+
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var _ = __webpack_require__(9);
+var React = __webpack_require__(6);
+var ReactDOM = __webpack_require__(11);
+var SyncTasks = __webpack_require__(33);
+var restyleForInlineText = __webpack_require__(203);
+var RX = __webpack_require__(4);
+var Styles_1 = __webpack_require__(15);
+var _styles = {
+ image: {
+ position: 'absolute',
+ display: 'flex',
+ opacity: 0,
+ maxWidth: '100%',
+ maxHeight: '100%'
+ },
+ defaultContainer: Styles_1.default.createImageStyle({
+ position: 'relative',
+ flex: 0,
+ overflow: 'visible',
+ backgroundColor: 'transparent'
+ })
+};
+;
+var XhrBlobUrlCache = (function () {
+ function XhrBlobUrlCache() {
+ }
+ XhrBlobUrlCache.get = function (source) {
+ if (this._cachedXhrBlobUrls[source]) {
+ this._cachedXhrBlobUrls[source].refCount++;
+ return this._cachedXhrBlobUrls[source].xhrBlobUrl;
+ }
+ return null;
+ };
+ XhrBlobUrlCache.insert = function (source, xhrBlobUrl) {
+ XhrBlobUrlCache._cleanupIfCapacityExceeded();
+ if (this._cachedXhrBlobUrls[source]) {
+ XhrBlobUrlCache._cachedXhrBlobUrls[source].refCount++;
+ }
+ else {
+ var xhrBlobUrlCacheEntry = {
+ xhrBlobUrl: xhrBlobUrl,
+ insertionDate: Date.now(),
+ refCount: 1
+ };
+ XhrBlobUrlCache._cachedXhrBlobUrls[source] = xhrBlobUrlCacheEntry;
+ }
+ };
+ XhrBlobUrlCache.release = function (source) {
+ // Keep track of which cache entries are being used as we don't want to clean up a resource that someone is
+ // still relying on.
+ if (this._cachedXhrBlobUrls[source]) {
+ XhrBlobUrlCache._cachedXhrBlobUrls[source].refCount--;
+ }
+ };
+ XhrBlobUrlCache._cleanupIfCapacityExceeded = function () {
+ // If we've reached maximum capacity, clean up the oldest freeable cache entry if any. An entry is freeable is
+ // it's not currently in use (refCount == 0). Return whether we have room to add more entries to the cache.
+ if (Object.keys(XhrBlobUrlCache._cachedXhrBlobUrls).length + 1 > XhrBlobUrlCache._maximumItems) {
+ var oldestFreeableKey_1;
+ var oldestFreeableEntry_1;
+ Object.keys(XhrBlobUrlCache._cachedXhrBlobUrls).forEach(function (key) {
+ if ((!oldestFreeableEntry_1 || XhrBlobUrlCache._cachedXhrBlobUrls[key].insertionDate < oldestFreeableEntry_1.insertionDate) &&
+ XhrBlobUrlCache._cachedXhrBlobUrls[key].refCount === 0) {
+ oldestFreeableKey_1 = key;
+ oldestFreeableEntry_1 = XhrBlobUrlCache._cachedXhrBlobUrls[key];
+ }
+ });
+ if (oldestFreeableKey_1) {
+ URL.revokeObjectURL(oldestFreeableEntry_1.xhrBlobUrl);
+ delete XhrBlobUrlCache._cachedXhrBlobUrls[oldestFreeableKey_1];
+ }
+ }
+ };
+ return XhrBlobUrlCache;
+}());
+// Use a global cache to work around the image loading delays introduced by the xhr requests. This is especially
+// visible when scrolling a virtual list view which contains xhr images.
+XhrBlobUrlCache._maximumItems = 128;
+XhrBlobUrlCache._cachedXhrBlobUrls = {};
+var Image = (function (_super) {
+ __extends(Image, _super);
+ function Image(props) {
+ var _this = _super.call(this, props) || this;
+ _this._isMounted = false;
+ _this._onLoad = function () {
+ if (!_this._isMounted) {
+ return;
+ }
+ // Measure the natural width & height of the image.
+ _this._nativeImageWidth = undefined;
+ _this._nativeImageHeight = undefined;
+ var imageDOM = ReactDOM.findDOMNode(_this.refs['image']);
+ if (imageDOM) {
+ _this._nativeImageWidth = imageDOM.naturalWidth;
+ _this._nativeImageHeight = imageDOM.naturalHeight;
+ }
+ // We can hide the img now. We assume that if the img. URL resolved without error,
+ // then the background img. URL also did.
+ _this.setState({
+ showImgTag: false
+ });
+ if (_this.props.onLoad) {
+ _this.props.onLoad({ width: _this._nativeImageWidth, height: _this._nativeImageHeight });
+ }
+ };
+ _this._imgOnError = function () {
+ _this._onError();
+ };
+ _this._onMouseUp = function (e) {
+ if (e.button === 0) {
+ // Types.Image doesn't officially support an onClick prop, but when it's
+ // contained within a button, it may have this prop.
+ var onClick = _this.props.onClick;
+ if (onClick) {
+ onClick(e);
+ }
+ }
+ };
+ var performXhrRequest = _this._initializeAndSetState(props);
+ if (performXhrRequest) {
+ _this._startXhrImageFetch(props);
+ }
+ return _this;
+ }
+ Image.prototype.getChildContext = function () {
+ // Let descendant RX components know that their nearest RX ancestor is not an RX.Text.
+ // Because they're in an RX.Image, they should use their normal styling rather than their
+ // special styling for appearing inline with text.
+ return { isRxParentAText: false };
+ };
+ Image.prefetch = function (url) {
+ var defer = SyncTasks.Defer();
+ var img = new window.Image();
+ img.src = url;
+ img.onload = (function (event) {
+ defer.resolve(true);
+ });
+ img.onerror = (function (event) {
+ defer.reject('Failed to prefetch url ' + url);
+ });
+ img.onabort = (function (event) {
+ defer.reject('Prefetch cancelled for url ' + url);
+ });
+ return defer.promise();
+ };
+ Image.prototype.componentWillReceiveProps = function (nextProps) {
+ var sourceOrHeaderChanged = (nextProps.source !== this.props.source ||
+ !_.isEqual(nextProps.headers || {}, this.props.headers || {}));
+ if (!nextProps.onLoad !== !this.props.onLoad || !nextProps.onError !== !this.props.onError || sourceOrHeaderChanged) {
+ var performXhrRequest = this._initializeAndSetState(nextProps);
+ if (sourceOrHeaderChanged && performXhrRequest) {
+ this._startXhrImageFetch(nextProps);
+ }
+ }
+ };
+ Image.prototype.componentDidMount = function () {
+ this._isMounted = true;
+ };
+ Image.prototype.componentWillUnmount = function () {
+ this._isMounted = false;
+ if (this.state.displayUrl && this.state.xhrRequest) {
+ XhrBlobUrlCache.release(this.props.source);
+ }
+ };
+ Image.prototype._initializeAndSetState = function (props) {
+ // Retrieve the xhr blob url from the cache if it exists. This is a performance optimization as we've seen xhr
+ // requests take some time and cause flicker during rendering. Even when we're hitting the browser cache, we've
+ // seen it stall and take some time.
+ var cachedXhrBlobUrl = props.headers ? XhrBlobUrlCache.get(props.source) : null;
+ var displayUrl = !!cachedXhrBlobUrl ? cachedXhrBlobUrl :
+ !!props.headers ? '' : props.source;
+ // Only make the xhr request if headers are specified and there was no cache hit.
+ var performXhrRequest = !!props.headers && !cachedXhrBlobUrl;
+ // We normally don't show an img tag because we use background images. However, if the caller has supplied an
+ // onLoad or onError callback, we'll use the img tag until we receive an onLoad or onError.
+ this.state = {
+ showImgTag: (!performXhrRequest || !!cachedXhrBlobUrl) && (!!props.onLoad || !!props.onError),
+ xhrRequest: !!props.headers,
+ displayUrl: displayUrl
+ };
+ return performXhrRequest;
+ };
+ Image.prototype._handleXhrBlob = function (blob) {
+ if (!this._isMounted) {
+ return;
+ }
+ this.setState({
+ displayUrl: URL.createObjectURL(blob)
+ });
+ // Save the newly fetched xhr blob url in the cache.
+ XhrBlobUrlCache.insert(this.props.source, this.state.displayUrl);
+ this._onLoad();
+ };
+ Image.prototype._startXhrImageFetch = function (props) {
+ // Test hook to simulate a slower hxr request.
+ // window.setTimeout(() => this._actuallyStartXhrImageFetch(props), 2500);
+ this._actuallyStartXhrImageFetch(props);
+ };
+ Image.prototype._actuallyStartXhrImageFetch = function (props) {
+ var _this = this;
+ // Fetch Implementation
+ if (window.fetch) {
+ var headers = new Headers();
+ Object.keys(props.headers).forEach(function (key) {
+ headers.append(key, props.headers[key]);
+ });
+ var xhr = new Request(props.source, {
+ method: 'GET',
+ headers: headers,
+ mode: 'cors'
+ });
+ fetch(xhr)
+ .then(function (response) {
+ if (!response.ok) {
+ _this._onError(new Error(response.statusText));
+ }
+ response.blob().then(function (blob) {
+ _this._handleXhrBlob(blob);
+ });
+ }, function (err) {
+ _this._onError(err);
+ });
+ }
+ else {
+ var req = new XMLHttpRequest();
+ req.open('GET', props.source, true);
+ req.responseType = 'blob';
+ Object.keys(props.headers).forEach(function (key) {
+ req.setRequestHeader(key, props.headers[key]);
+ });
+ req.onload = function () {
+ if (req.status >= 400 || req.status < 600) {
+ _this._onError(new Error(req.statusText));
+ }
+ else {
+ _this._handleXhrBlob(req.response);
+ }
+ };
+ req.onerror = function () {
+ _this._onError(new Error('Network issue downloading the image.'));
+ };
+ req.send();
+ }
+ };
+ Image.prototype.render = function () {
+ // Prepare image source (necessary as iOS implementation also allows objects)
+ if (typeof this.props.source !== 'string' && typeof this.props.source !== 'undefined') {
+ var errorText = 'Types/web/Image only accepts string sources! You passed: '
+ + this.props.source + ' of type ' + (typeof this.props.source);
+ throw new Error(errorText);
+ }
+ var optionalImg = null;
+ if (this.state.showImgTag) {
+ optionalImg = (React.createElement("img", { style: _styles.image, src: this.state.displayUrl, alt: this.props.accessibilityLabel, onLoad: this._onLoad, onError: this._imgOnError, key: 'image', ref: 'image' }));
+ }
+ var reactElement = (React.createElement("div", { style: this._getStyles(), onMouseUp: this._onMouseUp, title: this.props.title },
+ optionalImg,
+ this.props.children));
+ return this.context.isRxParentAText ?
+ restyleForInlineText(reactElement) :
+ reactElement;
+ };
+ Image.prototype._getStyles = function () {
+ var combinedStyles = Styles_1.default.combine(_styles.defaultContainer, this.props.style);
+ combinedStyles['display'] = 'flex';
+ // It is necessary to wrap the url in quotes as in url("a.jpg?q=(a and b)").
+ // If the url is unquoted and contains paranthesis, e.g. a.jpg?q=(a and b), it will become url(a.jpg?q=(a and b))
+ // which will not render on the screen.
+ combinedStyles['backgroundImage'] = 'url("' + this.state.displayUrl + '")';
+ // Types doesn't support border styles other than "solid" for images.
+ if (combinedStyles.borderWidth) {
+ combinedStyles['borderStyle'] = 'solid';
+ }
+ var resizeMode = 'contain';
+ switch (this.props.resizeMode) {
+ case 'cover':
+ resizeMode = 'cover';
+ break;
+ case 'stretch':
+ resizeMode = '100% 100%';
+ break;
+ case 'repeat':
+ resizeMode = 'auto';
+ break;
+ }
+ combinedStyles['backgroundPosition'] = 'center center';
+ combinedStyles['backgroundSize'] = resizeMode;
+ combinedStyles['backgroundRepeat'] = this.props.resizeMode === 'repeat' ? 'repeat' : 'no-repeat';
+ return combinedStyles;
+ };
+ Image.prototype._onError = function (err) {
+ if (!this._isMounted) {
+ return;
+ }
+ // We can hide the img now. We assume that if the img. URL failed to resolve,
+ // then the background img. URL also did.
+ this.setState({
+ showImgTag: false
+ });
+ if (this.props.onError) {
+ this.props.onError(err);
+ }
+ };
+ ;
+ // Note: This works only if you have an onLoaded handler and wait for the image to load.
+ Image.prototype.getNativeWidth = function () {
+ return this._nativeImageWidth;
+ };
+ Image.prototype.getNativeHeight = function () {
+ return this._nativeImageHeight;
+ };
+ return Image;
+}(RX.Image));
+Image.contextTypes = {
+ isRxParentAText: React.PropTypes.bool
+};
+Image.childContextTypes = {
+ isRxParentAText: React.PropTypes.bool.isRequired
+};
+exports.Image = Image;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = Image;
+
+
+/***/ }),
+/* 198 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* Input.ts
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* Web implementation of Input interface.
+*/
+
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var RX = __webpack_require__(4);
+var Input = (function (_super) {
+ __extends(Input, _super);
+ function Input() {
+ return _super.call(this) || this;
+ }
+ Input.prototype.dispatchKeyDown = function (e) {
+ this.keyDownEvent.fire(e);
+ };
+ Input.prototype.dispatchKeyUp = function (e) {
+ if (this.keyUpEvent.fire(e)) {
+ e.stopPropagation();
+ }
+ };
+ return Input;
+}(RX.Input));
+exports.Input = Input;
+;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = new Input();
+
+
+/***/ }),
+/* 199 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* ScrollViewConfig.ts
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* Web-specific scroll view configuration, required to avoid circular
+* dependency between application and ScrollView.
+*/
+
+var ScrollViewConfig = (function () {
+ function ScrollViewConfig() {
+ this._useCustomScrollbars = false;
+ }
+ // Enable native scrollbars for all instances.
+ ScrollViewConfig.prototype.setUseCustomScrollbars = function (value) {
+ this._useCustomScrollbars = value;
+ };
+ ScrollViewConfig.prototype.useCustomScrollbars = function () {
+ return this._useCustomScrollbars;
+ };
+ return ScrollViewConfig;
+}());
+exports.ScrollViewConfig = ScrollViewConfig;
+;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = new ScrollViewConfig();
+
+
+/***/ }),
+/* 200 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* Text.tsx
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* Web-specific implementation of the cross-platform Text abstraction.
+*/
+
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var React = __webpack_require__(6);
+var ReactDOM = __webpack_require__(11);
+var AccessibilityUtil_1 = __webpack_require__(71);
+var RX = __webpack_require__(4);
+var Styles_1 = __webpack_require__(15);
+var _styles = {
+ defaultStyle: {
+ position: 'relative',
+ display: 'inline',
+ flex: '0 0 auto',
+ overflow: 'hidden',
+ whiteSpace: 'pre-wrap',
+ overflowWrap: 'break-word',
+ msHyphens: 'auto'
+ },
+ ellipsis: {
+ position: 'relative',
+ display: 'inline',
+ flex: '0 0 auto',
+ overflow: 'hidden',
+ whiteSpace: 'pre',
+ textOverflow: 'ellipsis'
+ }
+};
+var Text = (function (_super) {
+ __extends(Text, _super);
+ function Text() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ Text.prototype.getChildContext = function () {
+ // Let descendant Types components know that their nearest Types ancestor is an Types.Text.
+ // Because they're in an Types.Text, they should style themselves specially for appearing
+ // inline with text.
+ return { isRxParentAText: true };
+ };
+ Text.prototype.render = function () {
+ // Handle special case
+ if (typeof this.props.children === 'string' && this.props.children === '\n') {
+ return React.createElement("br", null);
+ }
+ var isAriaHidden = AccessibilityUtil_1.default.isHidden(this.props.importantForAccessibility);
+ return (React.createElement("div", { style: this._getStyles(), "aria-hidden": isAriaHidden, onClick: this.props.onPress }, this.props.children));
+ };
+ Text.prototype._getStyles = function () {
+ // There's no way in HTML to properly handle numberOfLines > 1,
+ // but we can correctly handle the common case where numberOfLines is 1.
+ var combinedStyles = Styles_1.default.combine(this.props.numberOfLines === 1 ?
+ _styles.ellipsis : _styles.defaultStyle, this.props.style);
+ // Handle cursor styles
+ if (this.props.selectable) {
+ combinedStyles['cursor'] = 'text';
+ combinedStyles['userSelect'] = 'text';
+ combinedStyles['WebkitUserSelect'] = 'text';
+ combinedStyles['MozUserSelect'] = 'text';
+ combinedStyles['msUserSelect'] = 'text';
+ }
+ else {
+ combinedStyles['cursor'] = 'inherit';
+ }
+ if (this.props.onPress) {
+ combinedStyles['cursor'] = 'pointer';
+ }
+ return combinedStyles;
+ };
+ Text.prototype.blur = function () {
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ el.blur();
+ }
+ };
+ Text.prototype.focus = function () {
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ el.focus();
+ }
+ };
+ return Text;
+}(RX.Text));
+Text.childContextTypes = {
+ isRxParentAText: React.PropTypes.bool.isRequired
+};
+exports.Text = Text;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = Text;
+
+
+/***/ }),
+/* 201 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* TextInput.tsx
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* Web-specific implementation of the cross-platform TextInput abstraction.
+*/
+
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var _ = __webpack_require__(9);
+var React = __webpack_require__(6);
+var ReactDOM = __webpack_require__(11);
+var RX = __webpack_require__(4);
+var Styles_1 = __webpack_require__(15);
+var _styles = {
+ defaultStyle: {
+ position: 'relative',
+ display: 'flex',
+ flexDirection: 'row',
+ flexBasis: 'auto',
+ flex: '0 0 auto',
+ overflowX: 'hidden',
+ overflowY: 'auto',
+ alignItems: 'stretch'
+ }
+};
+var TextInput = (function (_super) {
+ __extends(TextInput, _super);
+ function TextInput(props) {
+ var _this = _super.call(this, props) || this;
+ _this._selectionStart = 0;
+ _this._selectionEnd = 0;
+ _this._onPaste = function (e) {
+ if (_this.props.onPaste) {
+ _this.props.onPaste(e);
+ }
+ _this._checkSelectionChanged();
+ };
+ _this._onInput = function (e) {
+ if (!e.defaultPrevented) {
+ var el = ReactDOM.findDOMNode(_this);
+ if (el) {
+ // Has the input value changed?
+ var value = el.value || '';
+ if (_this.state.inputValue !== value) {
+ // If the parent component didn't specify a value, we'll keep
+ // track of the modified value.
+ if (_this.props.value === undefined) {
+ _this.setState({
+ inputValue: value
+ });
+ }
+ if (_this.props.onChangeText) {
+ _this.props.onChangeText(value);
+ }
+ }
+ _this._checkSelectionChanged();
+ }
+ }
+ };
+ _this._checkSelectionChanged = function () {
+ var el = ReactDOM.findDOMNode(_this);
+ if (el) {
+ if (_this._selectionStart !== el.selectionStart || _this._selectionEnd !== el.selectionEnd) {
+ _this._selectionStart = el.selectionStart;
+ _this._selectionEnd = el.selectionEnd;
+ if (_this.props.onSelectionChange) {
+ _this.props.onSelectionChange(_this._selectionStart, _this._selectionEnd);
+ }
+ }
+ }
+ };
+ _this._onKeyDown = function (e) {
+ // Generate a "submit editing" event if the user
+ // pressed enter or return.
+ if (e.keyCode === 13 && (!_this.props.multiline || _this.props.blurOnSubmit)) {
+ if (_this.props.onSubmitEditing) {
+ _this.props.onSubmitEditing();
+ }
+ if (_this.props.blurOnSubmit) {
+ _this.blur();
+ }
+ }
+ if (_this.props.onKeyPress) {
+ _this.props.onKeyPress(e);
+ }
+ _this._checkSelectionChanged();
+ };
+ _this._onScroll = function (e) {
+ if (_this.props.onScroll) {
+ var _a = e.target, scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;
+ _this.props.onScroll(scrollLeft, scrollTop);
+ }
+ };
+ _this.state = {
+ inputValue: props.value || props.defaultValue || ''
+ };
+ return _this;
+ }
+ TextInput.prototype.componentWillReceiveProps = function (nextProps) {
+ if (nextProps.value !== undefined && nextProps.value !== this.state.inputValue) {
+ this.setState({
+ inputValue: nextProps.value || ''
+ });
+ }
+ };
+ TextInput.prototype.componentDidMount = function () {
+ if (this.props.autoFocus) {
+ this.focus();
+ }
+ };
+ TextInput.prototype.render = function () {
+ var combinedStyles = Styles_1.default.combine(_styles.defaultStyle, this.props.style);
+ // Always hide the outline and border.
+ combinedStyles = _.extend({
+ outline: 'none',
+ border: 'none',
+ resize: 'none'
+ }, combinedStyles);
+ // By default, the control is editable.
+ var editable = (this.props.editable !== undefined ? this.props.editable : true);
+ var spellCheck = (this.props.spellCheck !== undefined ? this.props.spellCheck : this.props.autoCorrect);
+ // Use a textarea for multi-line and a regular input for single-line.
+ if (this.props.multiline) {
+ return (React.createElement("textarea", { style: combinedStyles, value: this.state.inputValue, autoCorrect: this.props.autoCorrect, spellCheck: spellCheck, disabled: !editable, maxLength: this.props.maxLength, placeholder: this.props.placeholder, onInput: this._onInput, onKeyDown: this._onKeyDown, onKeyUp: this._checkSelectionChanged, onFocus: this.props.onFocus, onBlur: this.props.onBlur, onMouseDown: this._checkSelectionChanged, onMouseUp: this._checkSelectionChanged, onPaste: this._onPaste, onScroll: this._onScroll, "aria-label": this.props.accessibilityLabel }));
+ }
+ else {
+ return (React.createElement("input", { style: combinedStyles, value: this.state.inputValue, autoCorrect: this.props.autoCorrect, spellCheck: spellCheck, disabled: !editable, maxLength: this.props.maxLength, placeholder: this.props.placeholder, onInput: this._onInput, onKeyDown: this._onKeyDown, onKeyUp: this._checkSelectionChanged, onFocus: this.props.onFocus, onBlur: this.props.onBlur, onMouseDown: this._checkSelectionChanged, onMouseUp: this._checkSelectionChanged, onPaste: this._onPaste, "aria-label": this.props.accessibilityLabel }));
+ }
+ };
+ TextInput.prototype.blur = function () {
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ el.blur();
+ }
+ };
+ TextInput.prototype.focus = function () {
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ el.focus();
+ }
+ };
+ TextInput.prototype.isFocused = function () {
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ return document.activeElement === el;
+ }
+ return false;
+ };
+ TextInput.prototype.selectAll = function () {
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ el.select();
+ }
+ };
+ TextInput.prototype.selectRange = function (start, end) {
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ el.setSelectionRange(start, end);
+ }
+ };
+ TextInput.prototype.getSelectionRange = function () {
+ var range = {
+ start: 0,
+ end: 0
+ };
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ range.start = el.selectionStart;
+ range.end = el.selectionEnd;
+ }
+ return range;
+ };
+ TextInput.prototype.setValue = function (value) {
+ var inputValue = value || '';
+ if (this.state.inputValue !== inputValue) {
+ // It's important to set the actual value in the DOM immediately. This allows us to call other related methods
+ // like selectRange synchronously afterward.
+ var el = ReactDOM.findDOMNode(this);
+ if (el) {
+ el.value = inputValue;
+ }
+ this.setState({
+ inputValue: inputValue
+ });
+ if (this.props.onChangeText) {
+ this.props.onChangeText(value);
+ }
+ }
+ };
+ return TextInput;
+}(RX.TextInput));
+exports.TextInput = TextInput;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = TextInput;
+
+
+/***/ }),
+/* 202 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* executeTransition.tsx
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* Provides a convenient API for applying a CSS transition to a DOM element and
+* notifying when the transition is complete.
+*/
+
+var _ = __webpack_require__(9);
+// Convenient API for applying a CSS transition to a DOM element. Calls `done` when the transition is completed.
+function executeTransition(element, transitions, done) {
+ var longestDurationPlusDelay = 0;
+ var longestDurationProperty = '';
+ var cssTransitions = [];
+ _.each(transitions, function (transition) {
+ var property = transition.property;
+ var duration = transition.duration;
+ var timing = transition.timing === undefined ? 'linear' : transition.timing;
+ var delay = transition.delay === undefined ? 0 : transition.delay;
+ var from = transition.from;
+ if (duration + delay > longestDurationPlusDelay) {
+ longestDurationPlusDelay = duration + delay;
+ longestDurationProperty = property;
+ }
+ // Initial state
+ element.style[property] = from;
+ // Resolve styles. This is a trick to force the browser to refresh the
+ // computed styles. Without this, it won't pick up the new "from" value
+ // that we just set above.
+ getComputedStyle(element).opacity;
+ // TODO: Cross-browser equivalent of 'transition' style (e.g. vendor prefixed).
+ cssTransitions.push(duration + 'ms ' + property + ' ' + timing + ' ' + delay + 'ms');
+ });
+ element.style.transition = cssTransitions.join(', ');
+ var finish;
+ var onTransitionEnd = function (ev) {
+ if (ev.target === element && ev.propertyName === longestDurationProperty) {
+ finish();
+ }
+ };
+ // TODO: Cross-browser equivalent of 'transitionEnd' event (e.g. vendor prefixed).
+ element.addEventListener('webkitTransitionEnd', onTransitionEnd);
+ element.addEventListener('transitionEnd', onTransitionEnd);
+ var timeoutId = 0;
+ var didFinish = false;
+ finish = function () {
+ if (!didFinish) {
+ clearTimeout(timeoutId);
+ // TODO: Cross-browser equivalent of 'transitionEnd' event (e.g. vendor prefixed).
+ element.removeEventListener('webkitTransitionEnd', onTransitionEnd);
+ element.removeEventListener('transitionEnd', onTransitionEnd);
+ // Only clean the transition if we are ending the same transition it was initially set.
+ // There are cases where transitions may be overriden before the transition before ends.
+ if (element.dataset['transitionId'] === timeoutId.toString()) {
+ delete element.dataset['transitionId'];
+ element.style.transition = 'none';
+ }
+ didFinish = true;
+ done();
+ }
+ };
+ // Watchdog timeout for cases where transitionEnd event doesn't fire.
+ timeoutId = window.setTimeout(finish, longestDurationPlusDelay + 10);
+ element.dataset['transitionId'] = timeoutId.toString();
+ // On webkit browsers, we need to defer the setting of the actual properties
+ // for some reason.
+ _.defer(function () {
+ // Set the "to" values.
+ _.each(transitions, function (transition) {
+ var property = transition.property;
+ var to = transition.to;
+ element.style[property] = to;
+ });
+ });
+}
+exports.executeTransition = executeTransition;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = executeTransition;
+
+
+/***/ }),
+/* 203 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+* restyleForInlineText.tsx
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+* Licensed under the MIT license.
+*
+* When a ReactXP component appears as a child of an RX.Text, it needs to be styled
+* specially so that it appears inline with the text rather than introducing line
+* breaks.
+*
+* This utility restyles the component that is passed to it as inline so it flows
+* with the text. When a ReactXP component is a child of a text, pass the return value
+* of its render method to this utility. See RX.View for an example.
+*/
+
+var _ = __webpack_require__(9);
+var assert = __webpack_require__(120);
+var React = __webpack_require__(6);
+function restyleForInlineText(reactElement) {
+ var style = reactElement.props['style'];
+ assert(style &&
+ style['width'] !== undefined &&
+ style['height'] !== undefined, 'Children of an must have a defined height and width');
+ /*
+ We'll use display: inline-block for inline element because
+ inline-flex will introduce new lines into the text that is
+ copied to the clipboard. In most our use-cases inline-block
+ is fine and should behave same as inline-flex.
+
+ Example:
+
+ // InlineView
+
+ // set by this function - will introduce new line when copied
+
+
+
+
+
+ result into selection: "[text node][transparent text][new line][text node]"
+ with inline-block this will properly resolve as "[text node][transparent text][text node]"
+ */
+ return React.cloneElement(reactElement, {
+ style: _.assign({}, style, {
+ display: 'inline-block',
+ // Reset the line height so the value from outside
+ // the inlined item doesn't cascade into this element.
+ lineHeight: 'normal'
+ })
+ });
+}
+module.exports = restyleForInlineText;
+
+
+/***/ }),
+/* 204 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var apply = Function.prototype.apply;
+
+// DOM APIs, for completeness
+
+exports.setTimeout = function() {
+ return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
+};
+exports.setInterval = function() {
+ return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
+};
+exports.clearTimeout =
+exports.clearInterval = function(timeout) {
+ if (timeout) {
+ timeout.close();
+ }
+};
+
+function Timeout(id, clearFn) {
+ this._id = id;
+ this._clearFn = clearFn;
+}
+Timeout.prototype.unref = Timeout.prototype.ref = function() {};
+Timeout.prototype.close = function() {
+ this._clearFn.call(window, this._id);
+};
+
+// Does not start the time, just sets up the members needed.
+exports.enroll = function(item, msecs) {
+ clearTimeout(item._idleTimeoutId);
+ item._idleTimeout = msecs;
+};
+
+exports.unenroll = function(item) {
+ clearTimeout(item._idleTimeoutId);
+ item._idleTimeout = -1;
+};
+
+exports._unrefActive = exports.active = function(item) {
+ clearTimeout(item._idleTimeoutId);
+
+ var msecs = item._idleTimeout;
+ if (msecs >= 0) {
+ item._idleTimeoutId = setTimeout(function onTimeout() {
+ if (item._onTimeout)
+ item._onTimeout();
+ }, msecs);
+ }
+};
+
+// setimmediate attaches itself to the global object
+__webpack_require__(488);
+exports.setImmediate = setImmediate;
+exports.clearImmediate = clearImmediate;
+
+
+/***/ }),
+/* 205 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/*
+* This file demonstrates a basic ReactXP app.
+*/
+
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var RX = __webpack_require__(119);
+var styles = {
+ container: RX.Styles.createViewStyle({
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ backgroundColor: '#f5fcff'
+ }),
+ helloWorld: RX.Styles.createTextStyle({
+ fontSize: 48,
+ fontWeight: 'bold',
+ marginBottom: 28
+ }),
+ welcome: RX.Styles.createTextStyle({
+ fontSize: 32,
+ marginBottom: 12
+ }),
+ instructions: RX.Styles.createTextStyle({
+ fontSize: 16,
+ color: '#aaa',
+ marginBottom: 40
+ }),
+ docLink: RX.Styles.createLinkStyle({
+ fontSize: 16,
+ color: 'blue'
+ })
+};
+var App = (function (_super) {
+ __extends(App, _super);
+ function App() {
+ var _this = _super.call(this) || this;
+ _this._translationValue = new RX.Animated.Value(-100);
+ _this._animatedStyle = RX.Styles.createAnimatedTextStyle({
+ transform: [
+ {
+ translateY: _this._translationValue
+ }
+ ]
+ });
+ return _this;
+ }
+ App.prototype.componentDidMount = function () {
+ var animation = RX.Animated.timing(this._translationValue, {
+ toValue: 0,
+ easing: RX.Animated.Easing.OutBack(),
+ duration: 500
+ });
+ animation.start();
+ };
+ App.prototype.render = function () {
+ return (RX.createElement(RX.View, { style: styles.container },
+ RX.createElement(RX.Animated.Text, { style: [styles.helloWorld, this._animatedStyle] }, "Hello World"),
+ RX.createElement(RX.Text, { style: styles.welcome }, "Welcome to ReactXP"),
+ RX.createElement(RX.Text, { style: styles.instructions }, "Edit App.tsx to get started"),
+ RX.createElement(RX.Link, { style: styles.docLink, url: 'https://microsoft.github.io/reactxp/docs' }, "View ReactXP documentation")));
+ };
+ return App;
+}(RX.Component));
+module.exports = App;
+
+
+/***/ }),
+/* 206 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @typechecks
+ */
+
+var _hyphenPattern = /-(.)/g;
+
+/**
+ * Camelcases a hyphenated string, for example:
+ *
+ * > camelize('background-color')
+ * < "backgroundColor"
+ *
+ * @param {string} string
+ * @return {string}
+ */
+function camelize(string) {
+ return string.replace(_hyphenPattern, function (_, character) {
+ return character.toUpperCase();
+ });
+}
+
+module.exports = camelize;
+
+/***/ }),
+/* 207 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @typechecks
+ */
+
+
+
+var camelize = __webpack_require__(206);
+
+var msPattern = /^-ms-/;
+
+/**
+ * Camelcases a hyphenated CSS property name, for example:
+ *
+ * > camelizeStyleName('background-color')
+ * < "backgroundColor"
+ * > camelizeStyleName('-moz-transition')
+ * < "MozTransition"
+ * > camelizeStyleName('-ms-transition')
+ * < "msTransition"
+ *
+ * As Andi Smith suggests
+ * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
+ * is converted to lowercase `ms`.
+ *
+ * @param {string} string
+ * @return {string}
+ */
+function camelizeStyleName(string) {
+ return camelize(string.replace(msPattern, 'ms-'));
+}
+
+module.exports = camelizeStyleName;
+
+/***/ }),
+/* 208 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ *
+ */
+
+var isTextNode = __webpack_require__(216);
+
+/*eslint-disable no-bitwise */
+
+/**
+ * Checks if a given DOM node contains or is another DOM 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;
+ }
+}
+
+module.exports = containsNode;
+
+/***/ }),
+/* 209 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @typechecks
+ */
+
+var invariant = __webpack_require__(1);
+
+/**
+ * Convert array-like objects to arrays.
+ *
+ * This API assumes the caller knows the contents of the data type. For less
+ * well defined inputs use createArrayFromMixed.
+ *
+ * @param {object|function|filelist} obj
+ * @return {array}
+ */
+function toArray(obj) {
+ var length = obj.length;
+
+ // Some browsers builtin objects can report typeof 'function' (e.g. NodeList
+ // in old versions of Safari).
+ !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : void 0;
+
+ !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : void 0;
+
+ !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : void 0;
+
+ !(typeof obj.callee !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : invariant(false) : void 0;
+
+ // Old IE doesn't give collections access to hasOwnProperty. Assume inputs
+ // without method will throw during the slice call and skip straight to the
+ // fallback.
+ if (obj.hasOwnProperty) {
+ try {
+ return Array.prototype.slice.call(obj);
+ } catch (e) {
+ // IE < 9 does not support Array#slice on collections objects
+ }
+ }
+
+ // Fall back to copying key by key. This assumes all keys have a value,
+ // so will not preserve sparsely populated inputs.
+ var ret = Array(length);
+ for (var ii = 0; ii < length; ii++) {
+ ret[ii] = obj[ii];
+ }
+ return ret;
+}
+
+/**
+ * Perform a heuristic test to determine if an object is "array-like".
+ *
+ * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
+ * Joshu replied: "Mu."
+ *
+ * This function determines if its argument has "array nature": it returns
+ * true if the argument is an actual array, an `arguments' object, or an
+ * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
+ *
+ * It will return false for other array-like objects like Filelist.
+ *
+ * @param {*} obj
+ * @return {boolean}
+ */
+function hasArrayNature(obj) {
+ return (
+ // not null/false
+ !!obj && (
+ // arrays are objects, NodeLists are functions in Safari
+ typeof obj == 'object' || typeof obj == 'function') &&
+ // quacks like an array
+ 'length' in obj &&
+ // not window
+ !('setInterval' in obj) &&
+ // no DOM node should be considered an array-like
+ // a 'select' element has 'length' and 'item' properties on IE8
+ typeof obj.nodeType != 'number' && (
+ // a real array
+ Array.isArray(obj) ||
+ // arguments
+ 'callee' in obj ||
+ // HTMLCollection/NodeList
+ 'item' in obj)
+ );
+}
+
+/**
+ * Ensure that the argument is an array by wrapping it in an array if it is not.
+ * Creates a copy of the argument if it is already an array.
+ *
+ * This is mostly useful idiomatically:
+ *
+ * var createArrayFromMixed = require('createArrayFromMixed');
+ *
+ * function takesOneOrMoreThings(things) {
+ * things = createArrayFromMixed(things);
+ * ...
+ * }
+ *
+ * This allows you to treat `things' as an array, but accept scalars in the API.
+ *
+ * If you need to convert an array-like object, like `arguments`, into an array
+ * use toArray instead.
+ *
+ * @param {*} obj
+ * @return {array}
+ */
+function createArrayFromMixed(obj) {
+ if (!hasArrayNature(obj)) {
+ return [obj];
+ } else if (Array.isArray(obj)) {
+ return obj.slice();
+ } else {
+ return toArray(obj);
+ }
+}
+
+module.exports = createArrayFromMixed;
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
+
+/***/ }),
+/* 210 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function(process) {
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @typechecks
+ */
+
+/*eslint-disable fb-www/unsafe-html*/
+
+var ExecutionEnvironment = __webpack_require__(8);
+
+var createArrayFromMixed = __webpack_require__(209);
+var getMarkupWrap = __webpack_require__(211);
+var invariant = __webpack_require__(1);
+
+/**
+ * Dummy container used to render all markup.
+ */
+var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
+
+/**
+ * Pattern used by `getNodeName`.
+ */
+var nodeNamePattern = /^\s*<(\w+)/;
+
+/**
+ * Extracts the `nodeName` of the first element in a string of markup.
+ *
+ * @param {string} markup String of markup.
+ * @return {?string} Node name of the supplied markup.
+ */
+function getNodeName(markup) {
+ var nodeNameMatch = markup.match(nodeNamePattern);
+ return nodeNameMatch && nodeNameMatch[1].toLowerCase();
+}
+
+/**
+ * Creates an array containing the nodes rendered from the supplied markup. The
+ * optionally supplied `handleScript` function will be invoked once for each
+ *
+//
+//
+// Here's how it works.
+//
+// ```
+// // Get a reference to the logo element.
+// var el = document.getElementById('logo');
+//
+// // create a SpringSystem and a Spring with a bouncy config.
+// var springSystem = new rebound.SpringSystem();
+// var spring = springSystem.createSpring(50, 3);
+//
+// // Add a listener to the spring. Every time the physics
+// // solver updates the Spring's value onSpringUpdate will
+// // be called.
+// spring.addListener({
+// onSpringUpdate: function(spring) {
+// var val = spring.getCurrentValue();
+// val = rebound.MathUtil
+// .mapValueInRange(val, 0, 1, 1, 0.5);
+// scale(el, val);
+// }
+// });
+//
+// // Listen for mouse down/up/out and toggle the
+// //springs endValue from 0 to 1.
+// el.addEventListener('mousedown', function() {
+// spring.setEndValue(1);
+// });
+//
+// el.addEventListener('mouseout', function() {
+// spring.setEndValue(0);
+// });
+//
+// el.addEventListener('mouseup', function() {
+// spring.setEndValue(0);
+// });
+//
+// // Helper for scaling an element with css transforms.
+// function scale(el, val) {
+// el.style.mozTransform =
+// el.style.msTransform =
+// el.style.webkitTransform =
+// el.style.transform = 'scale3d(' +
+// val + ', ' + val + ', 1)';
+// }
+// ```
+
+(function() {
+ var rebound = {};
+ var util = rebound.util = {};
+ var concat = Array.prototype.concat;
+ var slice = Array.prototype.slice;
+
+ // Bind a function to a context object.
+ util.bind = function bind(func, context) {
+ var args = slice.call(arguments, 2);
+ return function() {
+ func.apply(context, concat.call(args, slice.call(arguments)));
+ };
+ };
+
+ // Add all the properties in the source to the target.
+ util.extend = function extend(target, source) {
+ for (var key in source) {
+ if (source.hasOwnProperty(key)) {
+ target[key] = source[key];
+ }
+ }
+ };
+
+ // SpringSystem
+ // ------------
+ // **SpringSystem** is a set of Springs that all run on the same physics
+ // timing loop. To get started with a Rebound animation you first
+ // create a new SpringSystem and then add springs to it.
+ var SpringSystem = rebound.SpringSystem = function SpringSystem(looper) {
+ this._springRegistry = {};
+ this._activeSprings = [];
+ this.listeners = [];
+ this._idleSpringIndices = [];
+ this.looper = looper || new AnimationLooper();
+ this.looper.springSystem = this;
+ };
+
+ util.extend(SpringSystem.prototype, {
+
+ _springRegistry: null,
+
+ _isIdle: true,
+
+ _lastTimeMillis: -1,
+
+ _activeSprings: null,
+
+ listeners: null,
+
+ _idleSpringIndices: null,
+
+ // A SpringSystem is iterated by a looper. The looper is responsible
+ // for executing each frame as the SpringSystem is resolved to idle.
+ // There are three types of Loopers described below AnimationLooper,
+ // SimulationLooper, and SteppingSimulationLooper. AnimationLooper is
+ // the default as it is the most useful for common UI animations.
+ setLooper: function(looper) {
+ this.looper = looper;
+ looper.springSystem = this;
+ },
+
+ // Add a new spring to this SpringSystem. This Spring will now be solved for
+ // during the physics iteration loop. By default the spring will use the
+ // default Origami spring config with 40 tension and 7 friction, but you can
+ // also provide your own values here.
+ createSpring: function(tension, friction) {
+ var springConfig;
+ if (tension === undefined || friction === undefined) {
+ springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG;
+ } else {
+ springConfig =
+ SpringConfig.fromOrigamiTensionAndFriction(tension, friction);
+ }
+ return this.createSpringWithConfig(springConfig);
+ },
+
+ // Add a spring with a specified bounciness and speed. To replicate Origami
+ // compositions based on PopAnimation patches, use this factory method to
+ // create matching springs.
+ createSpringWithBouncinessAndSpeed: function(bounciness, speed) {
+ var springConfig;
+ if (bounciness === undefined || speed === undefined) {
+ springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG;
+ } else {
+ springConfig =
+ SpringConfig.fromBouncinessAndSpeed(bounciness, speed);
+ }
+ return this.createSpringWithConfig(springConfig);
+ },
+
+ // Add a spring with the provided SpringConfig.
+ createSpringWithConfig: function(springConfig) {
+ var spring = new Spring(this);
+ this.registerSpring(spring);
+ spring.setSpringConfig(springConfig);
+ return spring;
+ },
+
+ // You can check if a SpringSystem is idle or active by calling
+ // getIsIdle. If all of the Springs in the SpringSystem are at rest,
+ // i.e. the physics forces have reached equilibrium, then this
+ // method will return true.
+ getIsIdle: function() {
+ return this._isIdle;
+ },
+
+ // Retrieve a specific Spring from the SpringSystem by id. This
+ // can be useful for inspecting the state of a spring before
+ // or after an integration loop in the SpringSystem executes.
+ getSpringById: function (id) {
+ return this._springRegistry[id];
+ },
+
+ // Get a listing of all the springs registered with this
+ // SpringSystem.
+ getAllSprings: function() {
+ var vals = [];
+ for (var id in this._springRegistry) {
+ if (this._springRegistry.hasOwnProperty(id)) {
+ vals.push(this._springRegistry[id]);
+ }
+ }
+ return vals;
+ },
+
+ // registerSpring is called automatically as soon as you create
+ // a Spring with SpringSystem#createSpring. This method sets the
+ // spring up in the registry so that it can be solved in the
+ // solver loop.
+ registerSpring: function(spring) {
+ this._springRegistry[spring.getId()] = spring;
+ },
+
+ // Deregister a spring with this SpringSystem. The SpringSystem will
+ // no longer consider this Spring during its integration loop once
+ // this is called. This is normally done automatically for you when
+ // you call Spring#destroy.
+ deregisterSpring: function(spring) {
+ removeFirst(this._activeSprings, spring);
+ delete this._springRegistry[spring.getId()];
+ },
+
+ advance: function(time, deltaTime) {
+ while(this._idleSpringIndices.length > 0) this._idleSpringIndices.pop();
+ for (var i = 0, len = this._activeSprings.length; i < len; i++) {
+ var spring = this._activeSprings[i];
+ if (spring.systemShouldAdvance()) {
+ spring.advance(time / 1000.0, deltaTime / 1000.0);
+ } else {
+ this._idleSpringIndices.push(this._activeSprings.indexOf(spring));
+ }
+ }
+ while(this._idleSpringIndices.length > 0) {
+ var idx = this._idleSpringIndices.pop();
+ idx >= 0 && this._activeSprings.splice(idx, 1);
+ }
+ },
+
+ // This is our main solver loop called to move the simulation
+ // forward through time. Before each pass in the solver loop
+ // onBeforeIntegrate is called on an any listeners that have
+ // registered themeselves with the SpringSystem. This gives you
+ // an opportunity to apply any constraints or adjustments to
+ // the springs that should be enforced before each iteration
+ // loop. Next the advance method is called to move each Spring in
+ // the systemShouldAdvance forward to the current time. After the
+ // integration step runs in advance, onAfterIntegrate is called
+ // on any listeners that have registered themselves with the
+ // SpringSystem. This gives you an opportunity to run any post
+ // integration constraints or adjustments on the Springs in the
+ // SpringSystem.
+ loop: function(currentTimeMillis) {
+ var listener;
+ if (this._lastTimeMillis === -1) {
+ this._lastTimeMillis = currentTimeMillis -1;
+ }
+ var ellapsedMillis = currentTimeMillis - this._lastTimeMillis;
+ this._lastTimeMillis = currentTimeMillis;
+
+ var i = 0, len = this.listeners.length;
+ for (i = 0; i < len; i++) {
+ listener = this.listeners[i];
+ listener.onBeforeIntegrate && listener.onBeforeIntegrate(this);
+ }
+
+ this.advance(currentTimeMillis, ellapsedMillis);
+ if (this._activeSprings.length === 0) {
+ this._isIdle = true;
+ this._lastTimeMillis = -1;
+ }
+
+ for (i = 0; i < len; i++) {
+ listener = this.listeners[i];
+ listener.onAfterIntegrate && listener.onAfterIntegrate(this);
+ }
+
+ if (!this._isIdle) {
+ this.looper.run();
+ }
+ },
+
+ // activateSpring is used to notify the SpringSystem that a Spring
+ // has become displaced. The system responds by starting its solver
+ // loop up if it is currently idle.
+ activateSpring: function(springId) {
+ var spring = this._springRegistry[springId];
+ if (this._activeSprings.indexOf(spring) == -1) {
+ this._activeSprings.push(spring);
+ }
+ if (this.getIsIdle()) {
+ this._isIdle = false;
+ this.looper.run();
+ }
+ },
+
+ // Add a listener to the SpringSystem so that you can receive
+ // before/after integration notifications allowing Springs to be
+ // constrained or adjusted.
+ addListener: function(listener) {
+ this.listeners.push(listener);
+ },
+
+ // Remove a previously added listener on the SpringSystem.
+ removeListener: function(listener) {
+ removeFirst(this.listeners, listener);
+ },
+
+ // Remove all previously added listeners on the SpringSystem.
+ removeAllListeners: function() {
+ this.listeners = [];
+ }
+
+ });
+
+ // Spring
+ // ------
+ // **Spring** provides a model of a classical spring acting to
+ // resolve a body to equilibrium. Springs have configurable
+ // tension which is a force multipler on the displacement of the
+ // spring from its rest point or `endValue` as defined by [Hooke's
+ // law](http://en.wikipedia.org/wiki/Hooke's_law). Springs also have
+ // configurable friction, which ensures that they do not oscillate
+ // infinitely. When a Spring is displaced by updating it's resting
+ // or `currentValue`, the SpringSystems that contain that Spring
+ // will automatically start looping to solve for equilibrium. As each
+ // timestep passes, `SpringListener` objects attached to the Spring
+ // will be notified of the updates providing a way to drive an
+ // animation off of the spring's resolution curve.
+ var Spring = rebound.Spring = function Spring(springSystem) {
+ this._id = 's' + Spring._ID++;
+ this._springSystem = springSystem;
+ this.listeners = [];
+ this._currentState = new PhysicsState();
+ this._previousState = new PhysicsState();
+ this._tempState = new PhysicsState();
+ };
+
+ util.extend(Spring, {
+ _ID: 0,
+
+ MAX_DELTA_TIME_SEC: 0.064,
+
+ SOLVER_TIMESTEP_SEC: 0.001
+
+ });
+
+ util.extend(Spring.prototype, {
+
+ _id: 0,
+
+ _springConfig: null,
+
+ _overshootClampingEnabled: false,
+
+ _currentState: null,
+
+ _previousState: null,
+
+ _tempState: null,
+
+ _startValue: 0,
+
+ _endValue: 0,
+
+ _wasAtRest: true,
+
+ _restSpeedThreshold: 0.001,
+
+ _displacementFromRestThreshold: 0.001,
+
+ listeners: null,
+
+ _timeAccumulator: 0,
+
+ _springSystem: null,
+
+ // Remove a Spring from simulation and clear its listeners.
+ destroy: function() {
+ this.listeners = [];
+ this.frames = [];
+ this._springSystem.deregisterSpring(this);
+ },
+
+ // Get the id of the spring, which can be used to retrieve it from
+ // the SpringSystems it participates in later.
+ getId: function() {
+ return this._id;
+ },
+
+ // Set the configuration values for this Spring. A SpringConfig
+ // contains the tension and friction values used to solve for the
+ // equilibrium of the Spring in the physics loop.
+ setSpringConfig: function(springConfig) {
+ this._springConfig = springConfig;
+ return this;
+ },
+
+ // Retrieve the SpringConfig used by this Spring.
+ getSpringConfig: function() {
+ return this._springConfig;
+ },
+
+ // Set the current position of this Spring. Listeners will be updated
+ // with this value immediately. If the rest or `endValue` is not
+ // updated to match this value, then the spring will be dispalced and
+ // the SpringSystem will start to loop to restore the spring to the
+ // `endValue`.
+ //
+ // A common pattern is to move a Spring around without animation by
+ // calling.
+ //
+ // ```
+ // spring.setCurrentValue(n).setAtRest();
+ // ```
+ //
+ // This moves the Spring to a new position `n`, sets the endValue
+ // to `n`, and removes any velocity from the `Spring`. By doing
+ // this you can allow the `SpringListener` to manage the position
+ // of UI elements attached to the spring even when moving without
+ // animation. For example, when dragging an element you can
+ // update the position of an attached view through a spring
+ // by calling `spring.setCurrentValue(x)`. When
+ // the gesture ends you can update the Springs
+ // velocity and endValue
+ // `spring.setVelocity(gestureEndVelocity).setEndValue(flingTarget)`
+ // to cause it to naturally animate the UI element to the resting
+ // position taking into account existing velocity. The codepaths for
+ // synchronous movement and spring driven animation can
+ // be unified using this technique.
+ setCurrentValue: function(currentValue, skipSetAtRest) {
+ this._startValue = currentValue;
+ this._currentState.position = currentValue;
+ if (!skipSetAtRest) {
+ this.setAtRest();
+ }
+ this.notifyPositionUpdated(false, false);
+ return this;
+ },
+
+ // Get the position that the most recent animation started at. This
+ // can be useful for determining the number off oscillations that
+ // have occurred.
+ getStartValue: function() {
+ return this._startValue;
+ },
+
+ // Retrieve the current value of the Spring.
+ getCurrentValue: function() {
+ return this._currentState.position;
+ },
+
+ // Get the absolute distance of the Spring from it's resting endValue
+ // position.
+ getCurrentDisplacementDistance: function() {
+ return this.getDisplacementDistanceForState(this._currentState);
+ },
+
+ getDisplacementDistanceForState: function(state) {
+ return Math.abs(this._endValue - state.position);
+ },
+
+ // Set the endValue or resting position of the spring. If this
+ // value is different than the current value, the SpringSystem will
+ // be notified and will begin running its solver loop to resolve
+ // the Spring to equilibrium. Any listeners that are registered
+ // for onSpringEndStateChange will also be notified of this update
+ // immediately.
+ setEndValue: function(endValue) {
+ if (this._endValue == endValue && this.isAtRest()) {
+ return this;
+ }
+ this._startValue = this.getCurrentValue();
+ this._endValue = endValue;
+ this._springSystem.activateSpring(this.getId());
+ for (var i = 0, len = this.listeners.length; i < len; i++) {
+ var listener = this.listeners[i];
+ var onChange = listener.onSpringEndStateChange;
+ onChange && onChange(this);
+ }
+ return this;
+ },
+
+ // Retrieve the endValue or resting position of this spring.
+ getEndValue: function() {
+ return this._endValue;
+ },
+
+ // Set the current velocity of the Spring. As previously mentioned,
+ // this can be useful when you are performing a direct manipulation
+ // gesture. When a UI element is released you may call setVelocity
+ // on its animation Spring so that the Spring continues with the
+ // same velocity as the gesture ended with. The friction, tension,
+ // and displacement of the Spring will then govern its motion to
+ // return to rest on a natural feeling curve.
+ setVelocity: function(velocity) {
+ if (velocity === this._currentState.velocity) {
+ return this;
+ }
+ this._currentState.velocity = velocity;
+ this._springSystem.activateSpring(this.getId());
+ return this;
+ },
+
+ // Get the current velocity of the Spring.
+ getVelocity: function() {
+ return this._currentState.velocity;
+ },
+
+ // Set a threshold value for the movement speed of the Spring below
+ // which it will be considered to be not moving or resting.
+ setRestSpeedThreshold: function(restSpeedThreshold) {
+ this._restSpeedThreshold = restSpeedThreshold;
+ return this;
+ },
+
+ // Retrieve the rest speed threshold for this Spring.
+ getRestSpeedThreshold: function() {
+ return this._restSpeedThreshold;
+ },
+
+ // Set a threshold value for displacement below which the Spring
+ // will be considered to be not displaced i.e. at its resting
+ // `endValue`.
+ setRestDisplacementThreshold: function(displacementFromRestThreshold) {
+ this._displacementFromRestThreshold = displacementFromRestThreshold;
+ },
+
+ // Retrieve the rest displacement threshold for this spring.
+ getRestDisplacementThreshold: function() {
+ return this._displacementFromRestThreshold;
+ },
+
+ // Enable overshoot clamping. This means that the Spring will stop
+ // immediately when it reaches its resting position regardless of
+ // any existing momentum it may have. This can be useful for certain
+ // types of animations that should not oscillate such as a scale
+ // down to 0 or alpha fade.
+ setOvershootClampingEnabled: function(enabled) {
+ this._overshootClampingEnabled = enabled;
+ return this;
+ },
+
+ // Check if overshoot clamping is enabled for this spring.
+ isOvershootClampingEnabled: function() {
+ return this._overshootClampingEnabled;
+ },
+
+ // Check if the Spring has gone past its end point by comparing
+ // the direction it was moving in when it started to the current
+ // position and end value.
+ isOvershooting: function() {
+ var start = this._startValue;
+ var end = this._endValue;
+ return this._springConfig.tension > 0 &&
+ ((start < end && this.getCurrentValue() > end) ||
+ (start > end && this.getCurrentValue() < end));
+ },
+
+ // Spring.advance is the main solver method for the Spring. It takes
+ // the current time and delta since the last time step and performs
+ // an RK4 integration to get the new position and velocity state
+ // for the Spring based on the tension, friction, velocity, and
+ // displacement of the Spring.
+ advance: function(time, realDeltaTime) {
+ var isAtRest = this.isAtRest();
+
+ if (isAtRest && this._wasAtRest) {
+ return;
+ }
+
+ var adjustedDeltaTime = realDeltaTime;
+ if (realDeltaTime > Spring.MAX_DELTA_TIME_SEC) {
+ adjustedDeltaTime = Spring.MAX_DELTA_TIME_SEC;
+ }
+
+ this._timeAccumulator += adjustedDeltaTime;
+
+ var tension = this._springConfig.tension,
+ friction = this._springConfig.friction,
+
+ position = this._currentState.position,
+ velocity = this._currentState.velocity,
+ tempPosition = this._tempState.position,
+ tempVelocity = this._tempState.velocity,
+
+ aVelocity, aAcceleration,
+ bVelocity, bAcceleration,
+ cVelocity, cAcceleration,
+ dVelocity, dAcceleration,
+
+ dxdt, dvdt;
+
+ while(this._timeAccumulator >= Spring.SOLVER_TIMESTEP_SEC) {
+
+ this._timeAccumulator -= Spring.SOLVER_TIMESTEP_SEC;
+
+ if (this._timeAccumulator < Spring.SOLVER_TIMESTEP_SEC) {
+ this._previousState.position = position;
+ this._previousState.velocity = velocity;
+ }
+
+ aVelocity = velocity;
+ aAcceleration =
+ (tension * (this._endValue - tempPosition)) - friction * velocity;
+
+ tempPosition = position + aVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5;
+ tempVelocity =
+ velocity + aAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5;
+ bVelocity = tempVelocity;
+ bAcceleration =
+ (tension * (this._endValue - tempPosition)) - friction * tempVelocity;
+
+ tempPosition = position + bVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5;
+ tempVelocity =
+ velocity + bAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5;
+ cVelocity = tempVelocity;
+ cAcceleration =
+ (tension * (this._endValue - tempPosition)) - friction * tempVelocity;
+
+ tempPosition = position + cVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5;
+ tempVelocity =
+ velocity + cAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5;
+ dVelocity = tempVelocity;
+ dAcceleration =
+ (tension * (this._endValue - tempPosition)) - friction * tempVelocity;
+
+ dxdt =
+ 1.0/6.0 * (aVelocity + 2.0 * (bVelocity + cVelocity) + dVelocity);
+ dvdt = 1.0/6.0 * (
+ aAcceleration + 2.0 * (bAcceleration + cAcceleration) + dAcceleration
+ );
+
+ position += dxdt * Spring.SOLVER_TIMESTEP_SEC;
+ velocity += dvdt * Spring.SOLVER_TIMESTEP_SEC;
+ }
+
+ this._tempState.position = tempPosition;
+ this._tempState.velocity = tempVelocity;
+
+ this._currentState.position = position;
+ this._currentState.velocity = velocity;
+
+ if (this._timeAccumulator > 0) {
+ this._interpolate(this._timeAccumulator / Spring.SOLVER_TIMESTEP_SEC);
+ }
+
+ if (this.isAtRest() ||
+ this._overshootClampingEnabled && this.isOvershooting()) {
+
+ if (this._springConfig.tension > 0) {
+ this._startValue = this._endValue;
+ this._currentState.position = this._endValue;
+ } else {
+ this._endValue = this._currentState.position;
+ this._startValue = this._endValue;
+ }
+ this.setVelocity(0);
+ isAtRest = true;
+ }
+
+ var notifyActivate = false;
+ if (this._wasAtRest) {
+ this._wasAtRest = false;
+ notifyActivate = true;
+ }
+
+ var notifyAtRest = false;
+ if (isAtRest) {
+ this._wasAtRest = true;
+ notifyAtRest = true;
+ }
+
+ this.notifyPositionUpdated(notifyActivate, notifyAtRest);
+ },
+
+ notifyPositionUpdated: function(notifyActivate, notifyAtRest) {
+ for (var i = 0, len = this.listeners.length; i < len; i++) {
+ var listener = this.listeners[i];
+ if (notifyActivate && listener.onSpringActivate) {
+ listener.onSpringActivate(this);
+ }
+
+ if (listener.onSpringUpdate) {
+ listener.onSpringUpdate(this);
+ }
+
+ if (notifyAtRest && listener.onSpringAtRest) {
+ listener.onSpringAtRest(this);
+ }
+ }
+ },
+
+
+ // Check if the SpringSystem should advance. Springs are advanced
+ // a final frame after they reach equilibrium to ensure that the
+ // currentValue is exactly the requested endValue regardless of the
+ // displacement threshold.
+ systemShouldAdvance: function() {
+ return !this.isAtRest() || !this.wasAtRest();
+ },
+
+ wasAtRest: function() {
+ return this._wasAtRest;
+ },
+
+ // Check if the Spring is atRest meaning that it's currentValue and
+ // endValue are the same and that it has no velocity. The previously
+ // described thresholds for speed and displacement define the bounds
+ // of this equivalence check. If the Spring has 0 tension, then it will
+ // be considered at rest whenever its absolute velocity drops below the
+ // restSpeedThreshold.
+ isAtRest: function() {
+ return Math.abs(this._currentState.velocity) < this._restSpeedThreshold &&
+ (this.getDisplacementDistanceForState(this._currentState) <=
+ this._displacementFromRestThreshold ||
+ this._springConfig.tension === 0);
+ },
+
+ // Force the spring to be at rest at its current position. As
+ // described in the documentation for setCurrentValue, this method
+ // makes it easy to do synchronous non-animated updates to ui
+ // elements that are attached to springs via SpringListeners.
+ setAtRest: function() {
+ this._endValue = this._currentState.position;
+ this._tempState.position = this._currentState.position;
+ this._currentState.velocity = 0;
+ return this;
+ },
+
+ _interpolate: function(alpha) {
+ this._currentState.position = this._currentState.position *
+ alpha + this._previousState.position * (1 - alpha);
+ this._currentState.velocity = this._currentState.velocity *
+ alpha + this._previousState.velocity * (1 - alpha);
+ },
+
+ getListeners: function() {
+ return this.listeners;
+ },
+
+ addListener: function(newListener) {
+ this.listeners.push(newListener);
+ return this;
+ },
+
+ removeListener: function(listenerToRemove) {
+ removeFirst(this.listeners, listenerToRemove);
+ return this;
+ },
+
+ removeAllListeners: function() {
+ this.listeners = [];
+ return this;
+ },
+
+ currentValueIsApproximately: function(value) {
+ return Math.abs(this.getCurrentValue() - value) <=
+ this.getRestDisplacementThreshold();
+ }
+
+ });
+
+ // PhysicsState
+ // ------------
+ // **PhysicsState** consists of a position and velocity. A Spring uses
+ // this internally to keep track of its current and prior position and
+ // velocity values.
+ var PhysicsState = function PhysicsState() {};
+
+ util.extend(PhysicsState.prototype, {
+ position: 0,
+ velocity: 0
+ });
+
+ // SpringConfig
+ // ------------
+ // **SpringConfig** maintains a set of tension and friction constants
+ // for a Spring. You can use fromOrigamiTensionAndFriction to convert
+ // values from the [Origami](http://facebook.github.io/origami/)
+ // design tool directly to Rebound spring constants.
+ var SpringConfig = rebound.SpringConfig =
+ function SpringConfig(tension, friction) {
+ this.tension = tension;
+ this.friction = friction;
+ };
+
+ // Loopers
+ // -------
+ // **AnimationLooper** plays each frame of the SpringSystem on animation
+ // timing loop. This is the default type of looper for a new spring system
+ // as it is the most common when developing UI.
+ var AnimationLooper = rebound.AnimationLooper = function AnimationLooper() {
+ this.springSystem = null;
+ var _this = this;
+ var _run = function() {
+ _this.springSystem.loop(Date.now());
+ };
+
+ this.run = function() {
+ util.onFrame(_run);
+ };
+ };
+
+ // **SimulationLooper** resolves the SpringSystem to a resting state in a
+ // tight and blocking loop. This is useful for synchronously generating
+ // pre-recorded animations that can then be played on a timing loop later.
+ // Sometimes this lead to better performance to pre-record a single spring
+ // curve and use it to drive many animations; however, it can make dynamic
+ // response to user input a bit trickier to implement.
+ rebound.SimulationLooper = function SimulationLooper(timestep) {
+ this.springSystem = null;
+ var time = 0;
+ var running = false;
+ timestep=timestep || 16.667;
+
+ this.run = function() {
+ if (running) {
+ return;
+ }
+ running = true;
+ while(!this.springSystem.getIsIdle()) {
+ this.springSystem.loop(time+=timestep);
+ }
+ running = false;
+ };
+ };
+
+ // **SteppingSimulationLooper** resolves the SpringSystem one step at a
+ // time controlled by an outside loop. This is useful for testing and
+ // verifying the behavior of a SpringSystem or if you want to control your own
+ // timing loop for some reason e.g. slowing down or speeding up the
+ // simulation.
+ rebound.SteppingSimulationLooper = function(timestep) {
+ this.springSystem = null;
+ var time = 0;
+
+ // this.run is NOOP'd here to allow control from the outside using
+ // this.step.
+ this.run = function(){};
+
+ // Perform one step toward resolving the SpringSystem.
+ this.step = function(timestep) {
+ this.springSystem.loop(time+=timestep);
+ };
+ };
+
+ // Math for converting from
+ // [Origami](http://facebook.github.io/origami/) to
+ // [Rebound](http://facebook.github.io/rebound).
+ // You mostly don't need to worry about this, just use
+ // SpringConfig.fromOrigamiTensionAndFriction(v, v);
+ var OrigamiValueConverter = rebound.OrigamiValueConverter = {
+ tensionFromOrigamiValue: function(oValue) {
+ return (oValue - 30.0) * 3.62 + 194.0;
+ },
+
+ origamiValueFromTension: function(tension) {
+ return (tension - 194.0) / 3.62 + 30.0;
+ },
+
+ frictionFromOrigamiValue: function(oValue) {
+ return (oValue - 8.0) * 3.0 + 25.0;
+ },
+
+ origamiFromFriction: function(friction) {
+ return (friction - 25.0) / 3.0 + 8.0;
+ }
+ };
+
+ // BouncyConversion provides math for converting from Origami PopAnimation
+ // config values to regular Origami tension and friction values. If you are
+ // trying to replicate prototypes made with PopAnimation patches in Origami,
+ // then you should create your springs with
+ // SpringSystem.createSpringWithBouncinessAndSpeed, which uses this Math
+ // internally to create a spring to match the provided PopAnimation
+ // configuration from Origami.
+ var BouncyConversion = rebound.BouncyConversion = function(bounciness, speed){
+ this.bounciness = bounciness;
+ this.speed = speed;
+ var b = this.normalize(bounciness / 1.7, 0, 20.0);
+ b = this.projectNormal(b, 0.0, 0.8);
+ var s = this.normalize(speed / 1.7, 0, 20.0);
+ this.bouncyTension = this.projectNormal(s, 0.5, 200)
+ this.bouncyFriction = this.quadraticOutInterpolation(
+ b,
+ this.b3Nobounce(this.bouncyTension),
+ 0.01);
+ }
+
+ util.extend(BouncyConversion.prototype, {
+
+ normalize: function(value, startValue, endValue) {
+ return (value - startValue) / (endValue - startValue);
+ },
+
+ projectNormal: function(n, start, end) {
+ return start + (n * (end - start));
+ },
+
+ linearInterpolation: function(t, start, end) {
+ return t * end + (1.0 - t) * start;
+ },
+
+ quadraticOutInterpolation: function(t, start, end) {
+ return this.linearInterpolation(2*t - t*t, start, end);
+ },
+
+ b3Friction1: function(x) {
+ return (0.0007 * Math.pow(x, 3)) -
+ (0.031 * Math.pow(x, 2)) + 0.64 * x + 1.28;
+ },
+
+ b3Friction2: function(x) {
+ return (0.000044 * Math.pow(x, 3)) -
+ (0.006 * Math.pow(x, 2)) + 0.36 * x + 2.;
+ },
+
+ b3Friction3: function(x) {
+ return (0.00000045 * Math.pow(x, 3)) -
+ (0.000332 * Math.pow(x, 2)) + 0.1078 * x + 5.84;
+ },
+
+ b3Nobounce: function(tension) {
+ var friction = 0;
+ if (tension <= 18) {
+ friction = this.b3Friction1(tension);
+ } else if (tension > 18 && tension <= 44) {
+ friction = this.b3Friction2(tension);
+ } else {
+ friction = this.b3Friction3(tension);
+ }
+ return friction;
+ }
+ });
+
+ util.extend(SpringConfig, {
+ // Convert an origami Spring tension and friction to Rebound spring
+ // constants. If you are prototyping a design with Origami, this
+ // makes it easy to make your springs behave exactly the same in
+ // Rebound.
+ fromOrigamiTensionAndFriction: function(tension, friction) {
+ return new SpringConfig(
+ OrigamiValueConverter.tensionFromOrigamiValue(tension),
+ OrigamiValueConverter.frictionFromOrigamiValue(friction));
+ },
+
+ // Convert an origami PopAnimation Spring bounciness and speed to Rebound
+ // spring constants. If you are using PopAnimation patches in Origami, this
+ // utility will provide springs that match your prototype.
+ fromBouncinessAndSpeed: function(bounciness, speed) {
+ var bouncyConversion = new rebound.BouncyConversion(bounciness, speed);
+ return this.fromOrigamiTensionAndFriction(
+ bouncyConversion.bouncyTension,
+ bouncyConversion.bouncyFriction);
+ },
+
+ // Create a SpringConfig with no tension or a coasting spring with some
+ // amount of Friction so that it does not coast infininitely.
+ coastingConfigWithOrigamiFriction: function(friction) {
+ return new SpringConfig(
+ 0,
+ OrigamiValueConverter.frictionFromOrigamiValue(friction)
+ );
+ }
+ });
+
+ SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG =
+ SpringConfig.fromOrigamiTensionAndFriction(40, 7);
+
+ util.extend(SpringConfig.prototype, {friction: 0, tension: 0});
+
+ // Here are a couple of function to convert colors between hex codes and RGB
+ // component values. These are handy when performing color
+ // tweening animations.
+ var colorCache = {};
+ util.hexToRGB = function(color) {
+ if (colorCache[color]) {
+ return colorCache[color];
+ }
+ color = color.replace('#', '');
+ if (color.length === 3) {
+ color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];
+ }
+ var parts = color.match(/.{2}/g);
+
+ var ret = {
+ r: parseInt(parts[0], 16),
+ g: parseInt(parts[1], 16),
+ b: parseInt(parts[2], 16)
+ };
+
+ colorCache[color] = ret;
+ return ret;
+ };
+
+ util.rgbToHex = function(r, g, b) {
+ r = r.toString(16);
+ g = g.toString(16);
+ b = b.toString(16);
+ r = r.length < 2 ? '0' + r : r;
+ g = g.length < 2 ? '0' + g : g;
+ b = b.length < 2 ? '0' + b : b;
+ return '#' + r + g + b;
+ };
+
+ var MathUtil = rebound.MathUtil = {
+ // This helper function does a linear interpolation of a value from
+ // one range to another. This can be very useful for converting the
+ // motion of a Spring to a range of UI property values. For example a
+ // spring moving from position 0 to 1 could be interpolated to move a
+ // view from pixel 300 to 350 and scale it from 0.5 to 1. The current
+ // position of the `Spring` just needs to be run through this method
+ // taking its input range in the _from_ parameters with the property
+ // animation range in the _to_ parameters.
+ mapValueInRange: function(value, fromLow, fromHigh, toLow, toHigh) {
+ var fromRangeSize = fromHigh - fromLow;
+ var toRangeSize = toHigh - toLow;
+ var valueScale = (value - fromLow) / fromRangeSize;
+ return toLow + (valueScale * toRangeSize);
+ },
+
+ // Interpolate two hex colors in a 0 - 1 range or optionally provide a
+ // custom range with fromLow,fromHight. The output will be in hex by default
+ // unless asRGB is true in which case it will be returned as an rgb string.
+ interpolateColor:
+ function(val, startColor, endColor, fromLow, fromHigh, asRGB) {
+ fromLow = fromLow === undefined ? 0 : fromLow;
+ fromHigh = fromHigh === undefined ? 1 : fromHigh;
+ startColor = util.hexToRGB(startColor);
+ endColor = util.hexToRGB(endColor);
+ var r = Math.floor(
+ util.mapValueInRange(val, fromLow, fromHigh, startColor.r, endColor.r)
+ );
+ var g = Math.floor(
+ util.mapValueInRange(val, fromLow, fromHigh, startColor.g, endColor.g)
+ );
+ var b = Math.floor(
+ util.mapValueInRange(val, fromLow, fromHigh, startColor.b, endColor.b)
+ );
+ if (asRGB) {
+ return 'rgb(' + r + ',' + g + ',' + b + ')';
+ } else {
+ return util.rgbToHex(r, g, b);
+ }
+ },
+
+ degreesToRadians: function(deg) {
+ return (deg * Math.PI) / 180;
+ },
+
+ radiansToDegrees: function(rad) {
+ return (rad * 180) / Math.PI;
+ }
+
+ }
+
+ util.extend(util, MathUtil);
+
+
+ // Utilities
+ // ---------
+ // Here are a few useful JavaScript utilities.
+
+ // Lop off the first occurence of the reference in the Array.
+ function removeFirst(array, item) {
+ var idx = array.indexOf(item);
+ idx != -1 && array.splice(idx, 1);
+ }
+
+ var _onFrame;
+ if (typeof window !== 'undefined') {
+ _onFrame = window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ function(callback) {
+ window.setTimeout(callback, 1000 / 60);
+ };
+ }
+ if (!_onFrame && typeof process !== 'undefined' && process.title === 'node') {
+ _onFrame = setImmediate;
+ }
+
+ // Cross browser/node timer functions.
+ util.onFrame = function onFrame(func) {
+ return _onFrame(func);
+ };
+
+ // Export the public api using exports for common js or the window for
+ // normal browser inclusion.
+ if (true) {
+ util.extend(exports, rebound);
+ } else if (typeof window != 'undefined') {
+ window.rebound = rebound;
+ }
+})();
+
+
+// Legal Stuff
+// -----------
+/**
+ * Copyright (c) 2013, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0), __webpack_require__(204).setImmediate))
+
+/***/ }),
+/* 488 */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {
+ "use strict";
+
+ if (global.setImmediate) {
+ return;
+ }
+
+ var nextHandle = 1; // Spec says greater than zero
+ var tasksByHandle = {};
+ var currentlyRunningATask = false;
+ var doc = global.document;
+ var registerImmediate;
+
+ function setImmediate(callback) {
+ // Callback can either be a function or a string
+ if (typeof callback !== "function") {
+ callback = new Function("" + callback);
+ }
+ // Copy function arguments
+ var args = new Array(arguments.length - 1);
+ for (var i = 0; i < args.length; i++) {
+ args[i] = arguments[i + 1];
+ }
+ // Store and register the task
+ var task = { callback: callback, args: args };
+ tasksByHandle[nextHandle] = task;
+ registerImmediate(nextHandle);
+ return nextHandle++;
+ }
+
+ function clearImmediate(handle) {
+ delete tasksByHandle[handle];
+ }
+
+ function run(task) {
+ var callback = task.callback;
+ var args = task.args;
+ switch (args.length) {
+ case 0:
+ callback();
+ break;
+ case 1:
+ callback(args[0]);
+ break;
+ case 2:
+ callback(args[0], args[1]);
+ break;
+ case 3:
+ callback(args[0], args[1], args[2]);
+ break;
+ default:
+ callback.apply(undefined, args);
+ break;
+ }
+ }
+
+ function runIfPresent(handle) {
+ // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
+ // So if we're currently running a task, we'll need to delay this invocation.
+ if (currentlyRunningATask) {
+ // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
+ // "too much recursion" error.
+ setTimeout(runIfPresent, 0, handle);
+ } else {
+ var task = tasksByHandle[handle];
+ if (task) {
+ currentlyRunningATask = true;
+ try {
+ run(task);
+ } finally {
+ clearImmediate(handle);
+ currentlyRunningATask = false;
+ }
+ }
+ }
+ }
+
+ function installNextTickImplementation() {
+ registerImmediate = function(handle) {
+ process.nextTick(function () { runIfPresent(handle); });
+ };
+ }
+
+ function canUsePostMessage() {
+ // The test against `importScripts` prevents this implementation from being installed inside a web worker,
+ // where `global.postMessage` means something completely different and can't be used for this purpose.
+ if (global.postMessage && !global.importScripts) {
+ var postMessageIsAsynchronous = true;
+ var oldOnMessage = global.onmessage;
+ global.onmessage = function() {
+ postMessageIsAsynchronous = false;
+ };
+ global.postMessage("", "*");
+ global.onmessage = oldOnMessage;
+ return postMessageIsAsynchronous;
+ }
+ }
+
+ function installPostMessageImplementation() {
+ // Installs an event handler on `global` for the `message` event: see
+ // * https://developer.mozilla.org/en/DOM/window.postMessage
+ // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
+
+ var messagePrefix = "setImmediate$" + Math.random() + "$";
+ var onGlobalMessage = function(event) {
+ if (event.source === global &&
+ typeof event.data === "string" &&
+ event.data.indexOf(messagePrefix) === 0) {
+ runIfPresent(+event.data.slice(messagePrefix.length));
+ }
+ };
+
+ if (global.addEventListener) {
+ global.addEventListener("message", onGlobalMessage, false);
+ } else {
+ global.attachEvent("onmessage", onGlobalMessage);
+ }
+
+ registerImmediate = function(handle) {
+ global.postMessage(messagePrefix + handle, "*");
+ };
+ }
+
+ function installMessageChannelImplementation() {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(event) {
+ var handle = event.data;
+ runIfPresent(handle);
+ };
+
+ registerImmediate = function(handle) {
+ channel.port2.postMessage(handle);
+ };
+ }
+
+ function installReadyStateChangeImplementation() {
+ var html = doc.documentElement;
+ registerImmediate = function(handle) {
+ // Create a \n// \n//\n// Here's how it works.\n//\n// ```\n// // Get a reference to the logo element.\n// var el = document.getElementById('logo');\n//\n// // create a SpringSystem and a Spring with a bouncy config.\n// var springSystem = new rebound.SpringSystem();\n// var spring = springSystem.createSpring(50, 3);\n//\n// // Add a listener to the spring. Every time the physics\n// // solver updates the Spring's value onSpringUpdate will\n// // be called.\n// spring.addListener({\n// onSpringUpdate: function(spring) {\n// var val = spring.getCurrentValue();\n// val = rebound.MathUtil\n// .mapValueInRange(val, 0, 1, 1, 0.5);\n// scale(el, val);\n// }\n// });\n//\n// // Listen for mouse down/up/out and toggle the\n// //springs endValue from 0 to 1.\n// el.addEventListener('mousedown', function() {\n// spring.setEndValue(1);\n// });\n//\n// el.addEventListener('mouseout', function() {\n// spring.setEndValue(0);\n// });\n//\n// el.addEventListener('mouseup', function() {\n// spring.setEndValue(0);\n// });\n//\n// // Helper for scaling an element with css transforms.\n// function scale(el, val) {\n// el.style.mozTransform =\n// el.style.msTransform =\n// el.style.webkitTransform =\n// el.style.transform = 'scale3d(' +\n// val + ', ' + val + ', 1)';\n// }\n// ```\n\n(function() {\n var rebound = {};\n var util = rebound.util = {};\n var concat = Array.prototype.concat;\n var slice = Array.prototype.slice;\n\n // Bind a function to a context object.\n util.bind = function bind(func, context) {\n var args = slice.call(arguments, 2);\n return function() {\n func.apply(context, concat.call(args, slice.call(arguments)));\n };\n };\n\n // Add all the properties in the source to the target.\n util.extend = function extend(target, source) {\n for (var key in source) {\n if (source.hasOwnProperty(key)) {\n target[key] = source[key];\n }\n }\n };\n\n // SpringSystem\n // ------------\n // **SpringSystem** is a set of Springs that all run on the same physics\n // timing loop. To get started with a Rebound animation you first\n // create a new SpringSystem and then add springs to it.\n var SpringSystem = rebound.SpringSystem = function SpringSystem(looper) {\n this._springRegistry = {};\n this._activeSprings = [];\n this.listeners = [];\n this._idleSpringIndices = [];\n this.looper = looper || new AnimationLooper();\n this.looper.springSystem = this;\n };\n\n util.extend(SpringSystem.prototype, {\n\n _springRegistry: null,\n\n _isIdle: true,\n\n _lastTimeMillis: -1,\n\n _activeSprings: null,\n\n listeners: null,\n\n _idleSpringIndices: null,\n\n // A SpringSystem is iterated by a looper. The looper is responsible\n // for executing each frame as the SpringSystem is resolved to idle.\n // There are three types of Loopers described below AnimationLooper,\n // SimulationLooper, and SteppingSimulationLooper. AnimationLooper is\n // the default as it is the most useful for common UI animations.\n setLooper: function(looper) {\n this.looper = looper;\n looper.springSystem = this;\n },\n\n // Add a new spring to this SpringSystem. This Spring will now be solved for\n // during the physics iteration loop. By default the spring will use the\n // default Origami spring config with 40 tension and 7 friction, but you can\n // also provide your own values here.\n createSpring: function(tension, friction) {\n var springConfig;\n if (tension === undefined || friction === undefined) {\n springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG;\n } else {\n springConfig =\n SpringConfig.fromOrigamiTensionAndFriction(tension, friction);\n }\n return this.createSpringWithConfig(springConfig);\n },\n\n // Add a spring with a specified bounciness and speed. To replicate Origami\n // compositions based on PopAnimation patches, use this factory method to\n // create matching springs.\n createSpringWithBouncinessAndSpeed: function(bounciness, speed) {\n var springConfig;\n if (bounciness === undefined || speed === undefined) {\n springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG;\n } else {\n springConfig =\n SpringConfig.fromBouncinessAndSpeed(bounciness, speed);\n }\n return this.createSpringWithConfig(springConfig);\n },\n\n // Add a spring with the provided SpringConfig.\n createSpringWithConfig: function(springConfig) {\n var spring = new Spring(this);\n this.registerSpring(spring);\n spring.setSpringConfig(springConfig);\n return spring;\n },\n\n // You can check if a SpringSystem is idle or active by calling\n // getIsIdle. If all of the Springs in the SpringSystem are at rest,\n // i.e. the physics forces have reached equilibrium, then this\n // method will return true.\n getIsIdle: function() {\n return this._isIdle;\n },\n\n // Retrieve a specific Spring from the SpringSystem by id. This\n // can be useful for inspecting the state of a spring before\n // or after an integration loop in the SpringSystem executes.\n getSpringById: function (id) {\n return this._springRegistry[id];\n },\n\n // Get a listing of all the springs registered with this\n // SpringSystem.\n getAllSprings: function() {\n var vals = [];\n for (var id in this._springRegistry) {\n if (this._springRegistry.hasOwnProperty(id)) {\n vals.push(this._springRegistry[id]);\n }\n }\n return vals;\n },\n\n // registerSpring is called automatically as soon as you create\n // a Spring with SpringSystem#createSpring. This method sets the\n // spring up in the registry so that it can be solved in the\n // solver loop.\n registerSpring: function(spring) {\n this._springRegistry[spring.getId()] = spring;\n },\n\n // Deregister a spring with this SpringSystem. The SpringSystem will\n // no longer consider this Spring during its integration loop once\n // this is called. This is normally done automatically for you when\n // you call Spring#destroy.\n deregisterSpring: function(spring) {\n removeFirst(this._activeSprings, spring);\n delete this._springRegistry[spring.getId()];\n },\n\n advance: function(time, deltaTime) {\n while(this._idleSpringIndices.length > 0) this._idleSpringIndices.pop();\n for (var i = 0, len = this._activeSprings.length; i < len; i++) {\n var spring = this._activeSprings[i];\n if (spring.systemShouldAdvance()) {\n spring.advance(time / 1000.0, deltaTime / 1000.0);\n } else {\n this._idleSpringIndices.push(this._activeSprings.indexOf(spring));\n }\n }\n while(this._idleSpringIndices.length > 0) {\n var idx = this._idleSpringIndices.pop();\n idx >= 0 && this._activeSprings.splice(idx, 1);\n }\n },\n\n // This is our main solver loop called to move the simulation\n // forward through time. Before each pass in the solver loop\n // onBeforeIntegrate is called on an any listeners that have\n // registered themeselves with the SpringSystem. This gives you\n // an opportunity to apply any constraints or adjustments to\n // the springs that should be enforced before each iteration\n // loop. Next the advance method is called to move each Spring in\n // the systemShouldAdvance forward to the current time. After the\n // integration step runs in advance, onAfterIntegrate is called\n // on any listeners that have registered themselves with the\n // SpringSystem. This gives you an opportunity to run any post\n // integration constraints or adjustments on the Springs in the\n // SpringSystem.\n loop: function(currentTimeMillis) {\n var listener;\n if (this._lastTimeMillis === -1) {\n this._lastTimeMillis = currentTimeMillis -1;\n }\n var ellapsedMillis = currentTimeMillis - this._lastTimeMillis;\n this._lastTimeMillis = currentTimeMillis;\n\n var i = 0, len = this.listeners.length;\n for (i = 0; i < len; i++) {\n listener = this.listeners[i];\n listener.onBeforeIntegrate && listener.onBeforeIntegrate(this);\n }\n\n this.advance(currentTimeMillis, ellapsedMillis);\n if (this._activeSprings.length === 0) {\n this._isIdle = true;\n this._lastTimeMillis = -1;\n }\n\n for (i = 0; i < len; i++) {\n listener = this.listeners[i];\n listener.onAfterIntegrate && listener.onAfterIntegrate(this);\n }\n\n if (!this._isIdle) {\n this.looper.run();\n }\n },\n\n // activateSpring is used to notify the SpringSystem that a Spring\n // has become displaced. The system responds by starting its solver\n // loop up if it is currently idle.\n activateSpring: function(springId) {\n var spring = this._springRegistry[springId];\n if (this._activeSprings.indexOf(spring) == -1) {\n this._activeSprings.push(spring);\n }\n if (this.getIsIdle()) {\n this._isIdle = false;\n this.looper.run();\n }\n },\n\n // Add a listener to the SpringSystem so that you can receive\n // before/after integration notifications allowing Springs to be\n // constrained or adjusted.\n addListener: function(listener) {\n this.listeners.push(listener);\n },\n\n // Remove a previously added listener on the SpringSystem.\n removeListener: function(listener) {\n removeFirst(this.listeners, listener);\n },\n\n // Remove all previously added listeners on the SpringSystem.\n removeAllListeners: function() {\n this.listeners = [];\n }\n\n });\n\n // Spring\n // ------\n // **Spring** provides a model of a classical spring acting to\n // resolve a body to equilibrium. Springs have configurable\n // tension which is a force multipler on the displacement of the\n // spring from its rest point or `endValue` as defined by [Hooke's\n // law](http://en.wikipedia.org/wiki/Hooke's_law). Springs also have\n // configurable friction, which ensures that they do not oscillate\n // infinitely. When a Spring is displaced by updating it's resting\n // or `currentValue`, the SpringSystems that contain that Spring\n // will automatically start looping to solve for equilibrium. As each\n // timestep passes, `SpringListener` objects attached to the Spring\n // will be notified of the updates providing a way to drive an\n // animation off of the spring's resolution curve.\n var Spring = rebound.Spring = function Spring(springSystem) {\n this._id = 's' + Spring._ID++;\n this._springSystem = springSystem;\n this.listeners = [];\n this._currentState = new PhysicsState();\n this._previousState = new PhysicsState();\n this._tempState = new PhysicsState();\n };\n\n util.extend(Spring, {\n _ID: 0,\n\n MAX_DELTA_TIME_SEC: 0.064,\n\n SOLVER_TIMESTEP_SEC: 0.001\n\n });\n\n util.extend(Spring.prototype, {\n\n _id: 0,\n\n _springConfig: null,\n\n _overshootClampingEnabled: false,\n\n _currentState: null,\n\n _previousState: null,\n\n _tempState: null,\n\n _startValue: 0,\n\n _endValue: 0,\n\n _wasAtRest: true,\n\n _restSpeedThreshold: 0.001,\n\n _displacementFromRestThreshold: 0.001,\n\n listeners: null,\n\n _timeAccumulator: 0,\n\n _springSystem: null,\n\n // Remove a Spring from simulation and clear its listeners.\n destroy: function() {\n this.listeners = [];\n this.frames = [];\n this._springSystem.deregisterSpring(this);\n },\n\n // Get the id of the spring, which can be used to retrieve it from\n // the SpringSystems it participates in later.\n getId: function() {\n return this._id;\n },\n\n // Set the configuration values for this Spring. A SpringConfig\n // contains the tension and friction values used to solve for the\n // equilibrium of the Spring in the physics loop.\n setSpringConfig: function(springConfig) {\n this._springConfig = springConfig;\n return this;\n },\n\n // Retrieve the SpringConfig used by this Spring.\n getSpringConfig: function() {\n return this._springConfig;\n },\n\n // Set the current position of this Spring. Listeners will be updated\n // with this value immediately. If the rest or `endValue` is not\n // updated to match this value, then the spring will be dispalced and\n // the SpringSystem will start to loop to restore the spring to the\n // `endValue`.\n //\n // A common pattern is to move a Spring around without animation by\n // calling.\n //\n // ```\n // spring.setCurrentValue(n).setAtRest();\n // ```\n //\n // This moves the Spring to a new position `n`, sets the endValue\n // to `n`, and removes any velocity from the `Spring`. By doing\n // this you can allow the `SpringListener` to manage the position\n // of UI elements attached to the spring even when moving without\n // animation. For example, when dragging an element you can\n // update the position of an attached view through a spring\n // by calling `spring.setCurrentValue(x)`. When\n // the gesture ends you can update the Springs\n // velocity and endValue\n // `spring.setVelocity(gestureEndVelocity).setEndValue(flingTarget)`\n // to cause it to naturally animate the UI element to the resting\n // position taking into account existing velocity. The codepaths for\n // synchronous movement and spring driven animation can\n // be unified using this technique.\n setCurrentValue: function(currentValue, skipSetAtRest) {\n this._startValue = currentValue;\n this._currentState.position = currentValue;\n if (!skipSetAtRest) {\n this.setAtRest();\n }\n this.notifyPositionUpdated(false, false);\n return this;\n },\n\n // Get the position that the most recent animation started at. This\n // can be useful for determining the number off oscillations that\n // have occurred.\n getStartValue: function() {\n return this._startValue;\n },\n\n // Retrieve the current value of the Spring.\n getCurrentValue: function() {\n return this._currentState.position;\n },\n\n // Get the absolute distance of the Spring from it's resting endValue\n // position.\n getCurrentDisplacementDistance: function() {\n return this.getDisplacementDistanceForState(this._currentState);\n },\n\n getDisplacementDistanceForState: function(state) {\n return Math.abs(this._endValue - state.position);\n },\n\n // Set the endValue or resting position of the spring. If this\n // value is different than the current value, the SpringSystem will\n // be notified and will begin running its solver loop to resolve\n // the Spring to equilibrium. Any listeners that are registered\n // for onSpringEndStateChange will also be notified of this update\n // immediately.\n setEndValue: function(endValue) {\n if (this._endValue == endValue && this.isAtRest()) {\n return this;\n }\n this._startValue = this.getCurrentValue();\n this._endValue = endValue;\n this._springSystem.activateSpring(this.getId());\n for (var i = 0, len = this.listeners.length; i < len; i++) {\n var listener = this.listeners[i];\n var onChange = listener.onSpringEndStateChange;\n onChange && onChange(this);\n }\n return this;\n },\n\n // Retrieve the endValue or resting position of this spring.\n getEndValue: function() {\n return this._endValue;\n },\n\n // Set the current velocity of the Spring. As previously mentioned,\n // this can be useful when you are performing a direct manipulation\n // gesture. When a UI element is released you may call setVelocity\n // on its animation Spring so that the Spring continues with the\n // same velocity as the gesture ended with. The friction, tension,\n // and displacement of the Spring will then govern its motion to\n // return to rest on a natural feeling curve.\n setVelocity: function(velocity) {\n if (velocity === this._currentState.velocity) {\n return this;\n }\n this._currentState.velocity = velocity;\n this._springSystem.activateSpring(this.getId());\n return this;\n },\n\n // Get the current velocity of the Spring.\n getVelocity: function() {\n return this._currentState.velocity;\n },\n\n // Set a threshold value for the movement speed of the Spring below\n // which it will be considered to be not moving or resting.\n setRestSpeedThreshold: function(restSpeedThreshold) {\n this._restSpeedThreshold = restSpeedThreshold;\n return this;\n },\n\n // Retrieve the rest speed threshold for this Spring.\n getRestSpeedThreshold: function() {\n return this._restSpeedThreshold;\n },\n\n // Set a threshold value for displacement below which the Spring\n // will be considered to be not displaced i.e. at its resting\n // `endValue`.\n setRestDisplacementThreshold: function(displacementFromRestThreshold) {\n this._displacementFromRestThreshold = displacementFromRestThreshold;\n },\n\n // Retrieve the rest displacement threshold for this spring.\n getRestDisplacementThreshold: function() {\n return this._displacementFromRestThreshold;\n },\n\n // Enable overshoot clamping. This means that the Spring will stop\n // immediately when it reaches its resting position regardless of\n // any existing momentum it may have. This can be useful for certain\n // types of animations that should not oscillate such as a scale\n // down to 0 or alpha fade.\n setOvershootClampingEnabled: function(enabled) {\n this._overshootClampingEnabled = enabled;\n return this;\n },\n\n // Check if overshoot clamping is enabled for this spring.\n isOvershootClampingEnabled: function() {\n return this._overshootClampingEnabled;\n },\n\n // Check if the Spring has gone past its end point by comparing\n // the direction it was moving in when it started to the current\n // position and end value.\n isOvershooting: function() {\n var start = this._startValue;\n var end = this._endValue;\n return this._springConfig.tension > 0 &&\n ((start < end && this.getCurrentValue() > end) ||\n (start > end && this.getCurrentValue() < end));\n },\n\n // Spring.advance is the main solver method for the Spring. It takes\n // the current time and delta since the last time step and performs\n // an RK4 integration to get the new position and velocity state\n // for the Spring based on the tension, friction, velocity, and\n // displacement of the Spring.\n advance: function(time, realDeltaTime) {\n var isAtRest = this.isAtRest();\n\n if (isAtRest && this._wasAtRest) {\n return;\n }\n\n var adjustedDeltaTime = realDeltaTime;\n if (realDeltaTime > Spring.MAX_DELTA_TIME_SEC) {\n adjustedDeltaTime = Spring.MAX_DELTA_TIME_SEC;\n }\n\n this._timeAccumulator += adjustedDeltaTime;\n\n var tension = this._springConfig.tension,\n friction = this._springConfig.friction,\n\n position = this._currentState.position,\n velocity = this._currentState.velocity,\n tempPosition = this._tempState.position,\n tempVelocity = this._tempState.velocity,\n\n aVelocity, aAcceleration,\n bVelocity, bAcceleration,\n cVelocity, cAcceleration,\n dVelocity, dAcceleration,\n\n dxdt, dvdt;\n\n while(this._timeAccumulator >= Spring.SOLVER_TIMESTEP_SEC) {\n\n this._timeAccumulator -= Spring.SOLVER_TIMESTEP_SEC;\n\n if (this._timeAccumulator < Spring.SOLVER_TIMESTEP_SEC) {\n this._previousState.position = position;\n this._previousState.velocity = velocity;\n }\n\n aVelocity = velocity;\n aAcceleration =\n (tension * (this._endValue - tempPosition)) - friction * velocity;\n\n tempPosition = position + aVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5;\n tempVelocity =\n velocity + aAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5;\n bVelocity = tempVelocity;\n bAcceleration =\n (tension * (this._endValue - tempPosition)) - friction * tempVelocity;\n\n tempPosition = position + bVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5;\n tempVelocity =\n velocity + bAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5;\n cVelocity = tempVelocity;\n cAcceleration =\n (tension * (this._endValue - tempPosition)) - friction * tempVelocity;\n\n tempPosition = position + cVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5;\n tempVelocity =\n velocity + cAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5;\n dVelocity = tempVelocity;\n dAcceleration =\n (tension * (this._endValue - tempPosition)) - friction * tempVelocity;\n\n dxdt =\n 1.0/6.0 * (aVelocity + 2.0 * (bVelocity + cVelocity) + dVelocity);\n dvdt = 1.0/6.0 * (\n aAcceleration + 2.0 * (bAcceleration + cAcceleration) + dAcceleration\n );\n\n position += dxdt * Spring.SOLVER_TIMESTEP_SEC;\n velocity += dvdt * Spring.SOLVER_TIMESTEP_SEC;\n }\n\n this._tempState.position = tempPosition;\n this._tempState.velocity = tempVelocity;\n\n this._currentState.position = position;\n this._currentState.velocity = velocity;\n\n if (this._timeAccumulator > 0) {\n this._interpolate(this._timeAccumulator / Spring.SOLVER_TIMESTEP_SEC);\n }\n\n if (this.isAtRest() ||\n this._overshootClampingEnabled && this.isOvershooting()) {\n\n if (this._springConfig.tension > 0) {\n this._startValue = this._endValue;\n this._currentState.position = this._endValue;\n } else {\n this._endValue = this._currentState.position;\n this._startValue = this._endValue;\n }\n this.setVelocity(0);\n isAtRest = true;\n }\n\n var notifyActivate = false;\n if (this._wasAtRest) {\n this._wasAtRest = false;\n notifyActivate = true;\n }\n\n var notifyAtRest = false;\n if (isAtRest) {\n this._wasAtRest = true;\n notifyAtRest = true;\n }\n\n this.notifyPositionUpdated(notifyActivate, notifyAtRest);\n },\n\n notifyPositionUpdated: function(notifyActivate, notifyAtRest) {\n for (var i = 0, len = this.listeners.length; i < len; i++) {\n var listener = this.listeners[i];\n if (notifyActivate && listener.onSpringActivate) {\n listener.onSpringActivate(this);\n }\n\n if (listener.onSpringUpdate) {\n listener.onSpringUpdate(this);\n }\n\n if (notifyAtRest && listener.onSpringAtRest) {\n listener.onSpringAtRest(this);\n }\n }\n },\n\n\n // Check if the SpringSystem should advance. Springs are advanced\n // a final frame after they reach equilibrium to ensure that the\n // currentValue is exactly the requested endValue regardless of the\n // displacement threshold.\n systemShouldAdvance: function() {\n return !this.isAtRest() || !this.wasAtRest();\n },\n\n wasAtRest: function() {\n return this._wasAtRest;\n },\n\n // Check if the Spring is atRest meaning that it's currentValue and\n // endValue are the same and that it has no velocity. The previously\n // described thresholds for speed and displacement define the bounds\n // of this equivalence check. If the Spring has 0 tension, then it will\n // be considered at rest whenever its absolute velocity drops below the\n // restSpeedThreshold.\n isAtRest: function() {\n return Math.abs(this._currentState.velocity) < this._restSpeedThreshold &&\n (this.getDisplacementDistanceForState(this._currentState) <=\n this._displacementFromRestThreshold ||\n this._springConfig.tension === 0);\n },\n\n // Force the spring to be at rest at its current position. As\n // described in the documentation for setCurrentValue, this method\n // makes it easy to do synchronous non-animated updates to ui\n // elements that are attached to springs via SpringListeners.\n setAtRest: function() {\n this._endValue = this._currentState.position;\n this._tempState.position = this._currentState.position;\n this._currentState.velocity = 0;\n return this;\n },\n\n _interpolate: function(alpha) {\n this._currentState.position = this._currentState.position *\n alpha + this._previousState.position * (1 - alpha);\n this._currentState.velocity = this._currentState.velocity *\n alpha + this._previousState.velocity * (1 - alpha);\n },\n\n getListeners: function() {\n return this.listeners;\n },\n\n addListener: function(newListener) {\n this.listeners.push(newListener);\n return this;\n },\n\n removeListener: function(listenerToRemove) {\n removeFirst(this.listeners, listenerToRemove);\n return this;\n },\n\n removeAllListeners: function() {\n this.listeners = [];\n return this;\n },\n\n currentValueIsApproximately: function(value) {\n return Math.abs(this.getCurrentValue() - value) <=\n this.getRestDisplacementThreshold();\n }\n\n });\n\n // PhysicsState\n // ------------\n // **PhysicsState** consists of a position and velocity. A Spring uses\n // this internally to keep track of its current and prior position and\n // velocity values.\n var PhysicsState = function PhysicsState() {};\n\n util.extend(PhysicsState.prototype, {\n position: 0,\n velocity: 0\n });\n\n // SpringConfig\n // ------------\n // **SpringConfig** maintains a set of tension and friction constants\n // for a Spring. You can use fromOrigamiTensionAndFriction to convert\n // values from the [Origami](http://facebook.github.io/origami/)\n // design tool directly to Rebound spring constants.\n var SpringConfig = rebound.SpringConfig =\n function SpringConfig(tension, friction) {\n this.tension = tension;\n this.friction = friction;\n };\n\n // Loopers\n // -------\n // **AnimationLooper** plays each frame of the SpringSystem on animation\n // timing loop. This is the default type of looper for a new spring system\n // as it is the most common when developing UI.\n var AnimationLooper = rebound.AnimationLooper = function AnimationLooper() {\n this.springSystem = null;\n var _this = this;\n var _run = function() {\n _this.springSystem.loop(Date.now());\n };\n\n this.run = function() {\n util.onFrame(_run);\n };\n };\n\n // **SimulationLooper** resolves the SpringSystem to a resting state in a\n // tight and blocking loop. This is useful for synchronously generating\n // pre-recorded animations that can then be played on a timing loop later.\n // Sometimes this lead to better performance to pre-record a single spring\n // curve and use it to drive many animations; however, it can make dynamic\n // response to user input a bit trickier to implement.\n rebound.SimulationLooper = function SimulationLooper(timestep) {\n this.springSystem = null;\n var time = 0;\n var running = false;\n timestep=timestep || 16.667;\n\n this.run = function() {\n if (running) {\n return;\n }\n running = true;\n while(!this.springSystem.getIsIdle()) {\n this.springSystem.loop(time+=timestep);\n }\n running = false;\n };\n };\n\n // **SteppingSimulationLooper** resolves the SpringSystem one step at a\n // time controlled by an outside loop. This is useful for testing and\n // verifying the behavior of a SpringSystem or if you want to control your own\n // timing loop for some reason e.g. slowing down or speeding up the\n // simulation.\n rebound.SteppingSimulationLooper = function(timestep) {\n this.springSystem = null;\n var time = 0;\n\n // this.run is NOOP'd here to allow control from the outside using\n // this.step.\n this.run = function(){};\n\n // Perform one step toward resolving the SpringSystem.\n this.step = function(timestep) {\n this.springSystem.loop(time+=timestep);\n };\n };\n\n // Math for converting from\n // [Origami](http://facebook.github.io/origami/) to\n // [Rebound](http://facebook.github.io/rebound).\n // You mostly don't need to worry about this, just use\n // SpringConfig.fromOrigamiTensionAndFriction(v, v);\n var OrigamiValueConverter = rebound.OrigamiValueConverter = {\n tensionFromOrigamiValue: function(oValue) {\n return (oValue - 30.0) * 3.62 + 194.0;\n },\n\n origamiValueFromTension: function(tension) {\n return (tension - 194.0) / 3.62 + 30.0;\n },\n\n frictionFromOrigamiValue: function(oValue) {\n return (oValue - 8.0) * 3.0 + 25.0;\n },\n\n origamiFromFriction: function(friction) {\n return (friction - 25.0) / 3.0 + 8.0;\n }\n };\n\n // BouncyConversion provides math for converting from Origami PopAnimation\n // config values to regular Origami tension and friction values. If you are\n // trying to replicate prototypes made with PopAnimation patches in Origami,\n // then you should create your springs with\n // SpringSystem.createSpringWithBouncinessAndSpeed, which uses this Math\n // internally to create a spring to match the provided PopAnimation\n // configuration from Origami.\n var BouncyConversion = rebound.BouncyConversion = function(bounciness, speed){\n this.bounciness = bounciness;\n this.speed = speed;\n var b = this.normalize(bounciness / 1.7, 0, 20.0);\n b = this.projectNormal(b, 0.0, 0.8);\n var s = this.normalize(speed / 1.7, 0, 20.0);\n this.bouncyTension = this.projectNormal(s, 0.5, 200)\n this.bouncyFriction = this.quadraticOutInterpolation(\n b,\n this.b3Nobounce(this.bouncyTension),\n 0.01);\n }\n\n util.extend(BouncyConversion.prototype, {\n\n normalize: function(value, startValue, endValue) {\n return (value - startValue) / (endValue - startValue);\n },\n\n projectNormal: function(n, start, end) {\n return start + (n * (end - start));\n },\n\n linearInterpolation: function(t, start, end) {\n return t * end + (1.0 - t) * start;\n },\n\n quadraticOutInterpolation: function(t, start, end) {\n return this.linearInterpolation(2*t - t*t, start, end);\n },\n\n b3Friction1: function(x) {\n return (0.0007 * Math.pow(x, 3)) -\n (0.031 * Math.pow(x, 2)) + 0.64 * x + 1.28;\n },\n\n b3Friction2: function(x) {\n return (0.000044 * Math.pow(x, 3)) -\n (0.006 * Math.pow(x, 2)) + 0.36 * x + 2.;\n },\n\n b3Friction3: function(x) {\n return (0.00000045 * Math.pow(x, 3)) -\n (0.000332 * Math.pow(x, 2)) + 0.1078 * x + 5.84;\n },\n\n b3Nobounce: function(tension) {\n var friction = 0;\n if (tension <= 18) {\n friction = this.b3Friction1(tension);\n } else if (tension > 18 && tension <= 44) {\n friction = this.b3Friction2(tension);\n } else {\n friction = this.b3Friction3(tension);\n }\n return friction;\n }\n });\n\n util.extend(SpringConfig, {\n // Convert an origami Spring tension and friction to Rebound spring\n // constants. If you are prototyping a design with Origami, this\n // makes it easy to make your springs behave exactly the same in\n // Rebound.\n fromOrigamiTensionAndFriction: function(tension, friction) {\n return new SpringConfig(\n OrigamiValueConverter.tensionFromOrigamiValue(tension),\n OrigamiValueConverter.frictionFromOrigamiValue(friction));\n },\n\n // Convert an origami PopAnimation Spring bounciness and speed to Rebound\n // spring constants. If you are using PopAnimation patches in Origami, this\n // utility will provide springs that match your prototype.\n fromBouncinessAndSpeed: function(bounciness, speed) {\n var bouncyConversion = new rebound.BouncyConversion(bounciness, speed);\n return this.fromOrigamiTensionAndFriction(\n bouncyConversion.bouncyTension,\n bouncyConversion.bouncyFriction);\n },\n\n // Create a SpringConfig with no tension or a coasting spring with some\n // amount of Friction so that it does not coast infininitely.\n coastingConfigWithOrigamiFriction: function(friction) {\n return new SpringConfig(\n 0,\n OrigamiValueConverter.frictionFromOrigamiValue(friction)\n );\n }\n });\n\n SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG =\n SpringConfig.fromOrigamiTensionAndFriction(40, 7);\n\n util.extend(SpringConfig.prototype, {friction: 0, tension: 0});\n\n // Here are a couple of function to convert colors between hex codes and RGB\n // component values. These are handy when performing color\n // tweening animations.\n var colorCache = {};\n util.hexToRGB = function(color) {\n if (colorCache[color]) {\n return colorCache[color];\n }\n color = color.replace('#', '');\n if (color.length === 3) {\n color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2];\n }\n var parts = color.match(/.{2}/g);\n\n var ret = {\n r: parseInt(parts[0], 16),\n g: parseInt(parts[1], 16),\n b: parseInt(parts[2], 16)\n };\n\n colorCache[color] = ret;\n return ret;\n };\n\n util.rgbToHex = function(r, g, b) {\n r = r.toString(16);\n g = g.toString(16);\n b = b.toString(16);\n r = r.length < 2 ? '0' + r : r;\n g = g.length < 2 ? '0' + g : g;\n b = b.length < 2 ? '0' + b : b;\n return '#' + r + g + b;\n };\n\n var MathUtil = rebound.MathUtil = {\n // This helper function does a linear interpolation of a value from\n // one range to another. This can be very useful for converting the\n // motion of a Spring to a range of UI property values. For example a\n // spring moving from position 0 to 1 could be interpolated to move a\n // view from pixel 300 to 350 and scale it from 0.5 to 1. The current\n // position of the `Spring` just needs to be run through this method\n // taking its input range in the _from_ parameters with the property\n // animation range in the _to_ parameters.\n mapValueInRange: function(value, fromLow, fromHigh, toLow, toHigh) {\n var fromRangeSize = fromHigh - fromLow;\n var toRangeSize = toHigh - toLow;\n var valueScale = (value - fromLow) / fromRangeSize;\n return toLow + (valueScale * toRangeSize);\n },\n\n // Interpolate two hex colors in a 0 - 1 range or optionally provide a\n // custom range with fromLow,fromHight. The output will be in hex by default\n // unless asRGB is true in which case it will be returned as an rgb string.\n interpolateColor:\n function(val, startColor, endColor, fromLow, fromHigh, asRGB) {\n fromLow = fromLow === undefined ? 0 : fromLow;\n fromHigh = fromHigh === undefined ? 1 : fromHigh;\n startColor = util.hexToRGB(startColor);\n endColor = util.hexToRGB(endColor);\n var r = Math.floor(\n util.mapValueInRange(val, fromLow, fromHigh, startColor.r, endColor.r)\n );\n var g = Math.floor(\n util.mapValueInRange(val, fromLow, fromHigh, startColor.g, endColor.g)\n );\n var b = Math.floor(\n util.mapValueInRange(val, fromLow, fromHigh, startColor.b, endColor.b)\n );\n if (asRGB) {\n return 'rgb(' + r + ',' + g + ',' + b + ')';\n } else {\n return util.rgbToHex(r, g, b);\n }\n },\n\n degreesToRadians: function(deg) {\n return (deg * Math.PI) / 180;\n },\n\n radiansToDegrees: function(rad) {\n return (rad * 180) / Math.PI;\n }\n\n }\n\n util.extend(util, MathUtil);\n\n\n // Utilities\n // ---------\n // Here are a few useful JavaScript utilities.\n\n // Lop off the first occurence of the reference in the Array.\n function removeFirst(array, item) {\n var idx = array.indexOf(item);\n idx != -1 && array.splice(idx, 1);\n }\n\n var _onFrame;\n if (typeof window !== 'undefined') {\n _onFrame = window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n function(callback) {\n window.setTimeout(callback, 1000 / 60);\n };\n }\n if (!_onFrame && typeof process !== 'undefined' && process.title === 'node') {\n _onFrame = setImmediate;\n }\n\n // Cross browser/node timer functions.\n util.onFrame = function onFrame(func) {\n return _onFrame(func);\n };\n\n // Export the public api using exports for common js or the window for\n // normal browser inclusion.\n if (typeof exports != 'undefined') {\n util.extend(exports, rebound);\n } else if (typeof window != 'undefined') {\n window.rebound = rebound;\n }\n})();\n\n\n// Legal Stuff\n// -----------\n/**\n * Copyright (c) 2013, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/rebound/rebound.js\n// module id = 487\n// module chunks = 0","(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a
+