!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.ReactRouter=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o component is a special kind of that * renders when its parent matches but none of its siblings do. * Only one such route may be used at any given level in the * route hierarchy. */ function DefaultRoute(props) { return Route( merge(props, { path: null, isDefault: true }) ); } module.exports = DefaultRoute; },{"./Route":6,"react/lib/merge":44}],3:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var ActiveState = _dereq_('../mixins/ActiveState'); var transitionTo = _dereq_('../actions/LocationActions').transitionTo; var withoutProperties = _dereq_('../utils/withoutProperties'); var hasOwnProperty = _dereq_('../utils/hasOwnProperty'); var makeHref = _dereq_('../utils/makeHref'); var warning = _dereq_('react/lib/warning'); function isLeftClickEvent(event) { return event.button === 0; } function isModifiedEvent(event) { return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); } /** * DEPRECATED: A map of component props that are reserved for use by the * router and/or React. All other props are used as params that are * interpolated into the link's path. */ var RESERVED_PROPS = { to: true, key: true, className: true, activeClassName: true, query: true, onClick:true, children: true // ReactChildren }; /** * components are used to create an element that links to a route. * When that route is active, the link gets an "active" class name (or the * value of its `activeClassName` prop). * * For example, assuming you have the following route: * * * * You could use the following component to link to that route: * * * * In addition to params, links may pass along query string parameters * using the `query` prop. * * */ var Link = React.createClass({ displayName: 'Link', mixins: [ ActiveState ], statics: { // TODO: Deprecate passing props as params in v1.0 getUnreservedProps: function (props) { var props = withoutProperties(props, RESERVED_PROPS); warning( Object.keys(props).length === 0, 'Passing props for params on s is deprecated, '+ 'please use the `params` property.' ); return props; }, /** * Returns a hash of URL parameters to use in this 's path. */ getParams: function (props) { return props.params || Link.getUnreservedProps(props); } }, propTypes: { to: React.PropTypes.string.isRequired, activeClassName: React.PropTypes.string.isRequired, params: React.PropTypes.object, query: React.PropTypes.object, onClick: React.PropTypes.func }, getDefaultProps: function () { return { activeClassName: 'active' }; }, getInitialState: function () { return { isActive: false }; }, /** * Returns the value of the "href" attribute to use on the DOM element. */ getHref: function () { return makeHref(this.props.to, Link.getParams(this.props), this.props.query); }, /** * Returns the value of the "class" attribute to use on the DOM element, which contains * the value of the activeClassName property when this is active. */ getClassName: function () { var className = this.props.className || ''; if (this.state.isActive) return className + ' ' + this.props.activeClassName; return className; }, componentWillReceiveProps: function (nextProps) { var params = Link.getParams(nextProps); this.setState({ isActive: Link.isActive(nextProps.to, params, nextProps.query) }); }, updateActiveState: function () { this.setState({ isActive: Link.isActive(this.props.to, Link.getParams(this.props), this.props.query) }); }, handleClick: function (event) { var allowTransition = true; var ret; if (this.props.onClick) ret = this.props.onClick(event); if (isModifiedEvent(event) || !isLeftClickEvent(event)) return; if (ret === false || event.defaultPrevented === true) allowTransition = false; event.preventDefault(); if (allowTransition) transitionTo(this.props.to, Link.getParams(this.props), this.props.query); }, render: function () { var props = { href: this.getHref(), className: this.getClassName(), onClick: this.handleClick }; // pull in props without overriding for (var propName in this.props) { if (hasOwnProperty(this.props, propName) && hasOwnProperty(props, propName) === false) props[propName] = this.props[propName]; } return React.DOM.a(props, this.props.children); } }); module.exports = Link; },{"../actions/LocationActions":1,"../mixins/ActiveState":15,"../utils/hasOwnProperty":24,"../utils/makeHref":25,"../utils/withoutProperties":29,"react/lib/warning":48}],4:[function(_dereq_,module,exports){ var merge = _dereq_('react/lib/merge'); var Route = _dereq_('./Route'); /** * A is a special kind of that * renders when the beginning of its parent's path matches * but none of its siblings do, including any . * Only one such route may be used at any given level in the * route hierarchy. */ function NotFoundRoute(props) { return Route( merge(props, { path: null, catchAll: true }) ); } module.exports = NotFoundRoute; },{"./Route":6,"react/lib/merge":44}],5:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var Route = _dereq_('./Route'); function createRedirectHandler(to) { return React.createClass({ statics: { willTransitionTo: function (transition, params, query) { transition.redirect(to, params, query); } }, render: function () { return null; } }); } /** * A component is a special kind of that always * redirects to another route when it matches. */ function Redirect(props) { return Route({ name: props.name, path: props.from || props.path || '*', handler: createRedirectHandler(props.to) }); } module.exports = Redirect; },{"./Route":6}],6:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var withoutProperties = _dereq_('../utils/withoutProperties'); /** * A map of component props that are reserved for use by the * router and/or React. All other props are considered "static" and * are passed through to the route handler. */ var RESERVED_PROPS = { handler: true, path: true, defaultRoute: true, paramNames: true, children: true // ReactChildren }; /** * components specify components that are rendered to the page when the * URL matches a given pattern. * * Routes are arranged in a nested tree structure. When a new URL is requested, * the tree is searched depth-first to find a route whose path matches the URL. * When one is found, all routes in the tree that lead to it are considered * "active" and their components are rendered into the DOM, nested in the same * order as they are in the tree. * * Unlike Ember, a nested route's path does not build upon that of its parents. * This may seem like it creates more work up front in specifying URLs, but it * has the nice benefit of decoupling nested UI from "nested" URLs. * * The preferred way to configure a router is using JSX. The XML-like syntax is * a great way to visualize how routes are laid out in an application. * * React.renderComponent(( * * * * * * ), document.body); * * If you don't use JSX, you can also assemble a Router programmatically using * the standard React component JavaScript API. * * React.renderComponent(( * Routes({ handler: App }, * Route({ name: 'login', handler: Login }), * Route({ name: 'logout', handler: Logout }), * Route({ name: 'about', handler: About }) * ) * ), document.body); * * Handlers for Route components that contain children can render their active * child route using the activeRouteHandler prop. * * var App = React.createClass({ * render: function () { * return ( *
* {this.props.activeRouteHandler()} *
* ); * } * }); */ var Route = React.createClass({ displayName: 'Route', statics: { getUnreservedProps: function (props) { return withoutProperties(props, RESERVED_PROPS); }, }, propTypes: { preserveScrollPosition: React.PropTypes.bool.isRequired, handler: React.PropTypes.any.isRequired, path: React.PropTypes.string, name: React.PropTypes.string }, getDefaultProps: function () { return { preserveScrollPosition: false }; }, render: function () { throw new Error( 'The component should not be rendered directly. You may be ' + 'missing a wrapper around your list of routes.' ); } }); module.exports = Route; },{"../utils/withoutProperties":29}],7:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var warning = _dereq_('react/lib/warning'); var copyProperties = _dereq_('react/lib/copyProperties'); var Promise = _dereq_('when/lib/Promise'); var LocationActions = _dereq_('../actions/LocationActions'); var Route = _dereq_('../components/Route'); var Path = _dereq_('../utils/Path'); var Redirect = _dereq_('../utils/Redirect'); var Transition = _dereq_('../utils/Transition'); var DefaultLocation = _dereq_('../locations/DefaultLocation'); var HashLocation = _dereq_('../locations/HashLocation'); var HistoryLocation = _dereq_('../locations/HistoryLocation'); var RefreshLocation = _dereq_('../locations/RefreshLocation'); var ActiveStore = _dereq_('../stores/ActiveStore'); var PathStore = _dereq_('../stores/PathStore'); var RouteStore = _dereq_('../stores/RouteStore'); /** * The ref name that can be used to reference the active route component. */ var REF_NAME = '__activeRoute__'; /** * A hash of { name, location } pairs of all locations. */ var NAMED_LOCATIONS = { hash: HashLocation, history: HistoryLocation, refresh: RefreshLocation }; /** * The default handler for aborted transitions. Redirects replace * the current URL and all others roll it back. */ function defaultAbortedTransitionHandler(transition) { var reason = transition.abortReason; if (reason instanceof Redirect) { LocationActions.replaceWith(reason.to, reason.params, reason.query); } else { LocationActions.goBack(); } } /** * The default handler for active state updates. */ function defaultActiveStateChangeHandler(state) { ActiveStore.updateState(state); } /** * The default handler for errors that were thrown asynchronously * while transitioning. The default behavior is to re-throw the * error so that it isn't silently swallowed. */ function defaultTransitionErrorHandler(error) { throw error; // This error probably originated in a transition hook. } function maybeUpdateScroll(routes, rootRoute) { if (!routes.props.preserveScrollPosition && !rootRoute.props.preserveScrollPosition) LocationActions.updateScroll(); } /** * The component configures the route hierarchy and renders the * route matching the current location when rendered into a document. * * See the component for more details. */ var Routes = React.createClass({ displayName: 'Routes', propTypes: { onAbortedTransition: React.PropTypes.func.isRequired, onActiveStateChange: React.PropTypes.func.isRequired, onTransitionError: React.PropTypes.func.isRequired, preserveScrollPosition: React.PropTypes.bool, location: function (props, propName, componentName) { var location = props[propName]; if (typeof location === 'string' && !(location in NAMED_LOCATIONS)) return new Error('Unknown location "' + location + '", see ' + componentName); } }, getDefaultProps: function () { return { onAbortedTransition: defaultAbortedTransitionHandler, onActiveStateChange: defaultActiveStateChangeHandler, onTransitionError: defaultTransitionErrorHandler, preserveScrollPosition: false, location: DefaultLocation }; }, getInitialState: function () { return { routes: RouteStore.registerChildren(this.props.children, this) }; }, getLocation: function () { var location = this.props.location; if (typeof location === 'string') return NAMED_LOCATIONS[location]; return location; }, componentWillMount: function () { PathStore.setup(this.getLocation()); PathStore.addChangeListener(this.handlePathChange); }, componentDidMount: function () { this.handlePathChange(); }, componentWillUnmount: function () { PathStore.removeChangeListener(this.handlePathChange); }, handlePathChange: function () { this.dispatch(PathStore.getCurrentPath()); }, /** * Performs a depth-first search for the first route in the tree that matches * on the given path. Returns an array of all routes in the tree leading to * the one that matched in the format { route, params } where params is an * object that contains the URL parameters relevant to that route. Returns * null if no route in the tree matches the path. * * React.renderComponent( * * * * * * * ).match('/posts/123'); => [ { route: , params: {} }, * { route: , params: { id: '123' } } ] */ match: function (path) { return findMatches(Path.withoutQuery(path), this.state.routes, this.props.defaultRoute, this.props.notFoundRoute); }, /** * Performs a transition to the given path and returns a promise for the * Transition object that was used. * * In order to do this, the router first determines which routes are involved * in the transition beginning with the current route, up the route tree to * the first parent route that is shared with the destination route, and back * down the tree to the destination route. The willTransitionFrom static * method is invoked on all route handlers we're transitioning away from, in * reverse nesting order. Likewise, the willTransitionTo static method * is invoked on all route handlers we're transitioning to. * * Both willTransitionFrom and willTransitionTo hooks may either abort or * redirect the transition. If they need to resolve asynchronously, they may * return a promise. * * Any error that occurs asynchronously during the transition is re-thrown in * the top-level scope unless returnRejectedPromise is true, in which case a * rejected promise is returned so the caller may handle the error. * * Note: This function does not update the URL in a browser's location bar. * If you want to keep the URL in sync with transitions, use Router.transitionTo, * Router.replaceWith, or Router.goBack instead. */ dispatch: function (path, returnRejectedPromise) { var transition = new Transition(path); var routes = this; var promise = runTransitionHooks(routes, transition).then(function (nextState) { if (transition.isAborted) { routes.props.onAbortedTransition(transition); } else if (nextState) { routes.setState(nextState); routes.props.onActiveStateChange(nextState); // TODO: add functional test var rootMatch = getRootMatch(nextState.matches); if (rootMatch) maybeUpdateScroll(routes, rootMatch.route); } return transition; }); if (!returnRejectedPromise) { promise = promise.then(undefined, function (error) { // Use setTimeout to break the promise chain. setTimeout(function () { routes.props.onTransitionError(error); }); }); } return promise; }, render: function () { if (!this.state.path) return null; var matches = this.state.matches; if (matches.length) { // matches[0] corresponds to the top-most match return matches[0].route.props.handler(computeHandlerProps(matches, this.state.activeQuery)); } else { return null; } } }); function findMatches(path, routes, defaultRoute, notFoundRoute) { var matches = null, route, params; for (var i = 0, len = routes.length; i < len; ++i) { route = routes[i]; // Check the subtree first to find the most deeply-nested match. matches = findMatches(path, route.props.children, route.props.defaultRoute, route.props.notFoundRoute); if (matches != null) { var rootParams = getRootMatch(matches).params; params = route.props.paramNames.reduce(function (params, paramName) { params[paramName] = rootParams[paramName]; return params; }, {}); matches.unshift(makeMatch(route, params)); return matches; } // No routes in the subtree matched, so check this route. params = Path.extractParams(route.props.path, path); if (params) return [ makeMatch(route, params) ]; } // No routes matched, so try the default route if there is one. if (defaultRoute && (params = Path.extractParams(defaultRoute.props.path, path))) return [ makeMatch(defaultRoute, params) ]; // Last attempt: does the "not found" route match? if (notFoundRoute && (params = Path.extractParams(notFoundRoute.props.path, path))) return [ makeMatch(notFoundRoute, params) ]; return matches; } function makeMatch(route, params) { return { route: route, params: params }; } function hasMatch(matches, match) { return matches.some(function (m) { if (m.route !== match.route) return false; for (var property in m.params) { if (m.params[property] !== match.params[property]) return false; } return true; }); } function getRootMatch(matches) { return matches[matches.length - 1]; } function updateMatchComponents(matches, refs) { var i = 0, component; while (component = refs[REF_NAME]) { matches[i++].component = component; refs = component.refs; } } /** * Runs all transition hooks that are required to get from the current state * to the state specified by the given transition and updates the current state * if they all pass successfully. Returns a promise that resolves to the new * state if it needs to be updated, or undefined if not. */ function runTransitionHooks(routes, transition) { if (routes.state.path === transition.path) return Promise.resolve(); // Nothing to do! var currentMatches = routes.state.matches; var nextMatches = routes.match(transition.path); warning( nextMatches, 'No route matches path "' + transition.path + '". Make sure you have ' + ' somewhere in your routes' ); if (!nextMatches) nextMatches = []; var fromMatches, toMatches; if (currentMatches) { updateMatchComponents(currentMatches, routes.refs); fromMatches = currentMatches.filter(function (match) { return !hasMatch(nextMatches, match); }); toMatches = nextMatches.filter(function (match) { return !hasMatch(currentMatches, match); }); } else { fromMatches = []; toMatches = nextMatches; } var query = Path.extractQuery(transition.path) || {}; return runTransitionFromHooks(fromMatches, transition).then(function () { if (transition.isAborted) return; // No need to continue. return runTransitionToHooks(toMatches, transition, query).then(function () { if (transition.isAborted) return; // No need to continue. var rootMatch = getRootMatch(nextMatches); var params = (rootMatch && rootMatch.params) || {}; return { path: transition.path, matches: nextMatches, activeParams: params, activeQuery: query, activeRoutes: nextMatches.map(function (match) { return match.route; }) }; }); }); } /** * Calls the willTransitionFrom hook of all handlers in the given matches * serially in reverse with the transition object and the current instance of * the route's handler, so that the deepest nested handlers are called first. * Returns a promise that resolves after the last handler. */ function runTransitionFromHooks(matches, transition) { var promise = Promise.resolve(); reversedArray(matches).forEach(function (match) { promise = promise.then(function () { var handler = match.route.props.handler; if (!transition.isAborted && handler.willTransitionFrom) return handler.willTransitionFrom(transition, match.component); }); }); return promise; } /** * Calls the willTransitionTo hook of all handlers in the given matches serially * with the transition object and any params that apply to that handler. Returns * a promise that resolves after the last handler. */ function runTransitionToHooks(matches, transition, query) { var promise = Promise.resolve(); matches.forEach(function (match) { promise = promise.then(function () { var handler = match.route.props.handler; if (!transition.isAborted && handler.willTransitionTo) return handler.willTransitionTo(transition, match.params, query); }); }); return promise; } /** * Given an array of matches as returned by findMatches, return a descriptor for * the handler hierarchy specified by the route. */ function computeHandlerProps(matches, query) { var props = { ref: null, key: null, params: null, query: null, activeRouteHandler: returnNull }; var childHandler; reversedArray(matches).forEach(function (match) { var route = match.route; props = Route.getUnreservedProps(route.props); props.ref = REF_NAME; props.params = match.params; props.query = query; if (route.props.addHandlerKey) props.key = Path.injectParams(route.props.path, match.params); if (childHandler) { props.activeRouteHandler = childHandler; } else { props.activeRouteHandler = returnNull; } childHandler = function (props, addedProps) { if (arguments.length > 2 && typeof arguments[2] !== 'undefined') throw new Error('Passing children to a route handler is not supported'); return route.props.handler(copyProperties(props, addedProps)); }.bind(this, props); }); return props; } function returnNull() { return null; } function reversedArray(array) { return array.slice(0).reverse(); } module.exports = Routes; },{"../actions/LocationActions":1,"../components/Route":6,"../locations/DefaultLocation":10,"../locations/HashLocation":11,"../locations/HistoryLocation":12,"../locations/RefreshLocation":14,"../stores/ActiveStore":17,"../stores/PathStore":18,"../stores/RouteStore":19,"../utils/Path":20,"../utils/Redirect":21,"../utils/Transition":22,"react/lib/copyProperties":40,"react/lib/warning":48,"when/lib/Promise":49}],8:[function(_dereq_,module,exports){ var copyProperties = _dereq_('react/lib/copyProperties'); var Dispatcher = _dereq_('flux').Dispatcher; /** * Dispatches actions that modify the URL. */ var LocationDispatcher = copyProperties(new Dispatcher, { handleViewAction: function (action) { this.dispatch({ source: 'VIEW_ACTION', action: action }); } }); module.exports = LocationDispatcher; },{"flux":31,"react/lib/copyProperties":40}],9:[function(_dereq_,module,exports){ exports.goBack = _dereq_('./actions/LocationActions').goBack; exports.replaceWith = _dereq_('./actions/LocationActions').replaceWith; exports.transitionTo = _dereq_('./actions/LocationActions').transitionTo; exports.DefaultRoute = _dereq_('./components/DefaultRoute'); exports.Link = _dereq_('./components/Link'); exports.NotFoundRoute = _dereq_('./components/NotFoundRoute'); exports.Redirect = _dereq_('./components/Redirect'); exports.Route = _dereq_('./components/Route'); exports.Routes = _dereq_('./components/Routes'); exports.ActiveState = _dereq_('./mixins/ActiveState'); exports.AsyncState = _dereq_('./mixins/AsyncState'); exports.makeHref = _dereq_('./utils/makeHref'); },{"./actions/LocationActions":1,"./components/DefaultRoute":2,"./components/Link":3,"./components/NotFoundRoute":4,"./components/Redirect":5,"./components/Route":6,"./components/Routes":7,"./mixins/ActiveState":15,"./mixins/AsyncState":16,"./utils/makeHref":25}],10:[function(_dereq_,module,exports){ module.exports = "production" === 'test' ? _dereq_('./MemoryLocation') : _dereq_('./HashLocation'); },{"./HashLocation":11,"./MemoryLocation":13}],11:[function(_dereq_,module,exports){ var invariant = _dereq_('react/lib/invariant'); var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); var getWindowPath = _dereq_('../utils/getWindowPath'); function getHashPath() { return window.location.hash.substr(1); } function ensureSlash() { var path = getHashPath(); if (path.charAt(0) === '/') return true; HashLocation.replace('/' + path); return false; } var _onChange; function handleHashChange() { if (ensureSlash()) _onChange(); } /** * A Location that uses `window.location.hash`. */ var HashLocation = { setup: function (onChange) { invariant( ExecutionEnvironment.canUseDOM, 'You cannot use HashLocation in an environment with no DOM' ); _onChange = onChange; ensureSlash(); if (window.addEventListener) { window.addEventListener('hashchange', handleHashChange, false); } else { window.attachEvent('onhashchange', handleHashChange); } }, teardown: function () { if (window.removeEventListener) { window.removeEventListener('hashchange', handleHashChange, false); } else { window.detachEvent('onhashchange', handleHashChange); } }, push: function (path) { window.location.hash = path; }, replace: function (path) { window.location.replace(getWindowPath() + '#' + path); }, pop: function () { window.history.back(); }, getCurrentPath: getHashPath, toString: function () { return ''; } }; module.exports = HashLocation; },{"../utils/getWindowPath":23,"react/lib/ExecutionEnvironment":39,"react/lib/invariant":42}],12:[function(_dereq_,module,exports){ var invariant = _dereq_('react/lib/invariant'); var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); var getWindowPath = _dereq_('../utils/getWindowPath'); var _onChange; /** * A Location that uses HTML5 history. */ var HistoryLocation = { setup: function (onChange) { invariant( ExecutionEnvironment.canUseDOM, 'You cannot use HistoryLocation in an environment with no DOM' ); _onChange = onChange; if (window.addEventListener) { window.addEventListener('popstate', _onChange, false); } else { window.attachEvent('popstate', _onChange); } }, teardown: function () { if (window.removeEventListener) { window.removeEventListener('popstate', _onChange, false); } else { window.detachEvent('popstate', _onChange); } }, push: function (path) { window.history.pushState({ path: path }, '', path); _onChange(); }, replace: function (path) { window.history.replaceState({ path: path }, '', path); _onChange(); }, pop: function () { window.history.back(); }, getCurrentPath: getWindowPath, toString: function () { return ''; } }; module.exports = HistoryLocation; },{"../utils/getWindowPath":23,"react/lib/ExecutionEnvironment":39,"react/lib/invariant":42}],13:[function(_dereq_,module,exports){ var warning = _dereq_('react/lib/warning'); var _lastPath = null; var _currentPath = null; var _onChange; /** * A Location that does not require a DOM. */ var MemoryLocation = { setup: function (onChange) { _onChange = onChange; }, push: function (path) { _lastPath = _currentPath; _currentPath = path; _onChange(); }, replace: function (path) { _currentPath = path; _onChange(); }, pop: function () { warning( _lastPath != null, 'You cannot use MemoryLocation to go back more than once' ); _currentPath = _lastPath; _lastPath = null; _onChange(); }, getCurrentPath: function () { return _currentPath || '/'; }, toString: function () { return ''; } }; module.exports = MemoryLocation; },{"react/lib/warning":48}],14:[function(_dereq_,module,exports){ var invariant = _dereq_('react/lib/invariant'); var ExecutionEnvironment = _dereq_('react/lib/ExecutionEnvironment'); var getWindowPath = _dereq_('../utils/getWindowPath'); /** * A Location that uses full page refreshes. This is used as * the fallback for HistoryLocation in browsers that do not * support the HTML5 history API. */ var RefreshLocation = { setup: function () { invariant( ExecutionEnvironment.canUseDOM, 'You cannot use RefreshLocation in an environment with no DOM' ); }, push: function (path) { window.location = path; }, replace: function (path) { window.location.replace(path); }, pop: function () { window.history.back(); }, getCurrentPath: getWindowPath, toString: function () { return ''; } }; module.exports = RefreshLocation; },{"../utils/getWindowPath":23,"react/lib/ExecutionEnvironment":39,"react/lib/invariant":42}],15:[function(_dereq_,module,exports){ var ActiveStore = _dereq_('../stores/ActiveStore'); /** * A mixin for components that need to know about the routes, params, * and query that are currently active. Components that use it get two * things: * * 1. An `isActive` static method they can use to check if a route, * params, and query are active. * 2. An `updateActiveState` instance method that is called when the * active state changes. * * Example: * * var Tab = React.createClass({ * * mixins: [ Router.ActiveState ], * * getInitialState: function () { * return { * isActive: false * }; * }, * * updateActiveState: function () { * this.setState({ * isActive: Tab.isActive(routeName, params, query) * }) * } * * }); */ var ActiveState = { statics: { /** * Returns true if the route with the given name, URL parameters, and query * are all currently active. */ isActive: ActiveStore.isActive }, componentWillMount: function () { ActiveStore.addChangeListener(this.handleActiveStateChange); }, componentDidMount: function () { if (this.updateActiveState) this.updateActiveState(); }, componentWillUnmount: function () { ActiveStore.removeChangeListener(this.handleActiveStateChange); }, handleActiveStateChange: function () { if (this.isMounted() && typeof this.updateActiveState === 'function') this.updateActiveState(); } }; module.exports = ActiveState; },{"../stores/ActiveStore":17}],16:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var resolveAsyncState = _dereq_('../utils/resolveAsyncState'); /** * A mixin for route handler component classes that fetch at least * part of their state asynchronously. Classes that use it should * declare a static `getInitialAsyncState` method that fetches state * for a component after it mounts. This function is given three * arguments: 1) the current route params, 2) the current query and * 3) a function that can be used to set state as it is received. * * Much like the familiar `getInitialState` method, `getInitialAsyncState` * should return a hash of key/value pairs to use in the component's * state. The difference is that the values may be promises. As these * values resolve, the component's state is updated. You should only * ever need to use the setState function for doing things like * streaming data and/or updating progress. * * Example: * * var User = React.createClass({ * * statics: { * * getInitialAsyncState: function (params, query, setState) { * // Return a hash with keys named after the state variables * // you want to set, as you normally do in getInitialState, * // except the values may be immediate values or promises. * // The state is automatically updated as promises resolve. * return { * user: getUserByID(params.userID) // may be a promise * }; * * // Or, use the setState function to stream data! * var buffer = ''; * * return { * * // Same as above, the stream state variable is set to the * // value returned by this promise when it resolves. * stream: getStreamingData(params.userID, function (chunk) { * buffer += chunk; * * // Notify of progress. * setState({ * streamBuffer: buffer * }); * }) * * }; * } * * }, * * getInitialState: function () { * return { * user: null, // Receives a value when getUserByID resolves. * stream: null, // Receives a value when getStreamingData resolves. * streamBuffer: '' // Used to track data as it loads. * }; * }, * * render: function () { * if (!this.state.user) * return ; * * return ( *
*

Welcome {this.state.user.name}!

*

So far, you've received {this.state.streamBuffer.length} data!

*
* ); * } * * }); * * When testing, use the `initialAsyncState` prop to simulate asynchronous * data fetching. When this prop is present, no attempt is made to retrieve * additional state via `getInitialAsyncState`. */ var AsyncState = { propTypes: { initialAsyncState: React.PropTypes.object }, getInitialState: function () { return this.props.initialAsyncState || null; }, updateAsyncState: function (state) { if (this.isMounted()) this.setState(state); }, componentDidMount: function () { if (this.props.initialAsyncState || typeof this.constructor.getInitialAsyncState !== 'function') return; resolveAsyncState( this.constructor.getInitialAsyncState(this.props.params, this.props.query, this.updateAsyncState), this.updateAsyncState ); } }; module.exports = AsyncState; },{"../utils/resolveAsyncState":27}],17:[function(_dereq_,module,exports){ var EventEmitter = _dereq_('events').EventEmitter; var CHANGE_EVENT = 'change'; var _events = new EventEmitter; _events.setMaxListeners(0); function notifyChange() { _events.emit(CHANGE_EVENT); } var _activeRoutes = []; var _activeParams = {}; var _activeQuery = {}; function routeIsActive(routeName) { return _activeRoutes.some(function (route) { return route.props.name === routeName; }); } function paramsAreActive(params) { for (var property in params) { if (_activeParams[property] !== String(params[property])) return false; } return true; } function queryIsActive(query) { for (var property in query) { if (_activeQuery[property] !== String(query[property])) return false; } return true; } /** * The ActiveStore keeps track of which routes, URL and query parameters are * currently active on a page. s subscribe to the ActiveStore to know * whether or not they are active. */ var ActiveStore = { addChangeListener: function (listener) { _events.on(CHANGE_EVENT, listener); }, removeChangeListener: function (listener) { _events.removeListener(CHANGE_EVENT, listener); }, /** * Updates the currently active state and notifies all listeners. * This is automatically called by routes as they become active. */ updateState: function (state) { state = state || {}; _activeRoutes = state.activeRoutes || []; _activeParams = state.activeParams || {}; _activeQuery = state.activeQuery || {}; notifyChange(); }, /** * Returns true if the route with the given name, URL parameters, and query * are all currently active. */ isActive: function (routeName, params, query) { var isActive = routeIsActive(routeName) && paramsAreActive(params); if (query) return isActive && queryIsActive(query); return isActive; } }; module.exports = ActiveStore; },{"events":30}],18:[function(_dereq_,module,exports){ var warning = _dereq_('react/lib/warning'); var EventEmitter = _dereq_('events').EventEmitter; var LocationActions = _dereq_('../actions/LocationActions'); var LocationDispatcher = _dereq_('../dispatchers/LocationDispatcher'); var supportsHistory = _dereq_('../utils/supportsHistory'); var HistoryLocation = _dereq_('../locations/HistoryLocation'); var RefreshLocation = _dereq_('../locations/RefreshLocation'); var CHANGE_EVENT = 'change'; var _events = new EventEmitter; function notifyChange() { _events.emit(CHANGE_EVENT); } var _scrollPositions = {}; function recordScrollPosition(path) { _scrollPositions[path] = { x: window.scrollX, y: window.scrollY }; } function updateScrollPosition(path) { var p = PathStore.getScrollPosition(path); window.scrollTo(p.x, p.y); } var _location; /** * The PathStore keeps track of the current URL path and manages * the location strategy that is used to update the URL. */ var PathStore = { addChangeListener: function (listener) { _events.on(CHANGE_EVENT, listener); }, removeChangeListener: function (listener) { _events.removeListener(CHANGE_EVENT, listener); // Automatically teardown when the last listener is removed. if (EventEmitter.listenerCount(_events, CHANGE_EVENT) === 0) PathStore.teardown(); }, setup: function (location) { // When using HistoryLocation, automatically fallback // to RefreshLocation in browsers that do not support // the HTML5 history API. if (location === HistoryLocation && !supportsHistory()) location = RefreshLocation; if (_location == null) { _location = location; if (_location && typeof _location.setup === 'function') _location.setup(notifyChange); } else { warning( _location === location, 'Cannot use location %s, already using %s', location, _location ); } }, teardown: function () { _events.removeAllListeners(CHANGE_EVENT); if (_location && typeof _location.teardown === 'function') _location.teardown(); _location = null; }, /** * Returns the location object currently in use. */ getLocation: function () { return _location; }, /** * Returns the current URL path. */ getCurrentPath: function () { return _location.getCurrentPath(); }, /** * Returns the last known scroll position for the given path. */ getScrollPosition: function (path) { return _scrollPositions[path] || { x: 0, y: 0 }; }, dispatchToken: LocationDispatcher.register(function (payload) { var action = payload.action; var currentPath = _location.getCurrentPath(); switch (action.type) { case LocationActions.PUSH: if (currentPath !== action.path) { recordScrollPosition(currentPath); _location.push(action.path); } break; case LocationActions.REPLACE: if (currentPath !== action.path) { recordScrollPosition(currentPath); _location.replace(action.path); } break; case LocationActions.POP: recordScrollPosition(currentPath); _location.pop(); break; case LocationActions.UPDATE_SCROLL: updateScrollPosition(currentPath); break; } }) }; module.exports = PathStore; },{"../actions/LocationActions":1,"../dispatchers/LocationDispatcher":8,"../locations/HistoryLocation":12,"../locations/RefreshLocation":14,"../utils/supportsHistory":28,"events":30,"react/lib/warning":48}],19:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var invariant = _dereq_('react/lib/invariant'); var warning = _dereq_('react/lib/warning'); var Path = _dereq_('../utils/Path'); var _namedRoutes = {}; /** * The RouteStore contains a directory of all s in the system. It is * used primarily for looking up routes by name so that s can use a * route name in the "to" prop and users can use route names in `Router.transitionTo` * and other high-level utility methods. */ var RouteStore = { /** * Removes all references to s from the store. Should only ever * really be used in tests to clear the store between test runs. */ unregisterAllRoutes: function () { _namedRoutes = {}; }, /** * Removes the reference to the given and all of its children * from the store. */ unregisterRoute: function (route) { var props = route.props; if (props.name) delete _namedRoutes[props.name]; React.Children.forEach(props.children, RouteStore.unregisterRoute); }, /** * Registers a and all of its children with the store. Also, * does some normalization and validation on route props. */ registerRoute: function (route, parentRoute) { // Note: parentRoute may be a _or_ a . var props = route.props; invariant( React.isValidClass(props.handler), 'The handler for the "%s" route must be a valid React class', props.name || props.path ); var parentPath = (parentRoute && parentRoute.props.path) || '/'; if ((props.path || props.name) && !props.isDefault && !props.catchAll) { var path = props.path || props.name; // Relative paths extend their parent. if (!Path.isAbsolute(path)) path = Path.join(parentPath, path); props.path = Path.normalize(path); } else { props.path = parentPath; if (props.catchAll) props.path += '*'; } props.paramNames = Path.extractParamNames(props.path); // Make sure the route's path has all params its parent needs. if (parentRoute && Array.isArray(parentRoute.props.paramNames)) { parentRoute.props.paramNames.forEach(function (paramName) { invariant( props.paramNames.indexOf(paramName) !== -1, 'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"', props.path, paramName, parentRoute.props.path ); }); } // Make sure the route can be looked up by s. if (props.name) { var existingRoute = _namedRoutes[props.name]; invariant( !existingRoute || route === existingRoute, 'You cannot use the name "%s" for more than one route', props.name ); _namedRoutes[props.name] = route; } if (props.catchAll) { invariant( parentRoute, ' must have a parent ' ); invariant( parentRoute.props.notFoundRoute == null, 'You may not have more than one per ' ); parentRoute.props.notFoundRoute = route; return null; } if (props.isDefault) { invariant( parentRoute, ' must have a parent ' ); invariant( parentRoute.props.defaultRoute == null, 'You may not have more than one per ' ); parentRoute.props.defaultRoute = route; return null; } // Make sure children is an array. props.children = RouteStore.registerChildren(props.children, route); return route; }, /** * Registers many children routes at once, always returning an array. */ registerChildren: function (children, parentRoute) { var routes = []; React.Children.forEach(children, function (child) { // Exclude s. if (child = RouteStore.registerRoute(child, parentRoute)) routes.push(child); }); return routes; }, /** * Returns the Route object with the given name, if one exists. */ getRouteByName: function (routeName) { return _namedRoutes[routeName] || null; } }; module.exports = RouteStore; },{"../utils/Path":20,"react/lib/invariant":42,"react/lib/warning":48}],20:[function(_dereq_,module,exports){ var invariant = _dereq_('react/lib/invariant'); var merge = _dereq_('qs/lib/utils').merge; var qs = _dereq_('qs'); function encodeURL(url) { return encodeURIComponent(url).replace(/%20/g, '+'); } function decodeURL(url) { return decodeURIComponent(url.replace(/\+/g, ' ')); } function encodeURLPath(path) { return String(path).split('/').map(encodeURL).join('/'); } var paramMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; var queryMatcher = /\?(.+)/; var _compiledPatterns = {}; function compilePattern(pattern) { if (!(pattern in _compiledPatterns)) { var paramNames = []; var source = pattern.replace(paramMatcher, function (match, paramName) { if (paramName) { paramNames.push(paramName); return '([^./?#]+)'; } else if (match === '*') { paramNames.push('splat'); return '(.*?)'; } else { return '\\' + match; } }); _compiledPatterns[pattern] = { matcher: new RegExp('^' + source + '$', 'i'), paramNames: paramNames }; } return _compiledPatterns[pattern]; } var Path = { /** * Returns an array of the names of all parameters in the given pattern. */ extractParamNames: function (pattern) { return compilePattern(pattern).paramNames; }, /** * Extracts the portions of the given URL path that match the given pattern * and returns an object of param name => value pairs. Returns null if the * pattern does not match the given path. */ extractParams: function (pattern, path) { var object = compilePattern(pattern); var match = decodeURL(path).match(object.matcher); if (!match) return null; var params = {}; object.paramNames.forEach(function (paramName, index) { params[paramName] = match[index + 1]; }); return params; }, /** * Returns a version of the given route path with params interpolated. Throws * if there is a dynamic segment of the route path for which there is no param. */ injectParams: function (pattern, params) { params = params || {}; var splatIndex = 0; return pattern.replace(paramMatcher, function (match, paramName) { paramName = paramName || 'splat'; invariant( params[paramName] != null, 'Missing "' + paramName + '" parameter for path "' + pattern + '"' ); var segment; if (paramName === 'splat' && Array.isArray(params[paramName])) { segment = params[paramName][splatIndex++]; invariant( segment != null, 'Missing splat # ' + splatIndex + ' for path "' + pattern + '"' ); } else { segment = params[paramName]; } return encodeURLPath(segment); }); }, /** * Returns an object that is the result of parsing any query string contained * in the given path, null if the path contains no query string. */ extractQuery: function (path) { var match = decodeURL(path).match(queryMatcher); return match && qs.parse(match[1]); }, /** * Returns a version of the given path without the query string. */ withoutQuery: function (path) { return path.replace(queryMatcher, ''); }, /** * Returns a version of the given path with the parameters in the given * query merged into the query string. */ withQuery: function (path, query) { var existingQuery = Path.extractQuery(path); if (existingQuery) query = query ? merge(existingQuery, query) : existingQuery; var queryString = query && qs.stringify(query); if (queryString) return Path.withoutQuery(path) + '?' + queryString; return path; }, /** * Returns true if the given path is absolute. */ isAbsolute: function (path) { return path.charAt(0) === '/'; }, /** * Returns a normalized version of the given path. */ normalize: function (path, parentRoute) { return path.replace(/^\/*/, '/'); }, /** * Joins two URL paths together. */ join: function (a, b) { return a.replace(/\/*$/, '/') + b; } }; module.exports = Path; },{"qs":34,"qs/lib/utils":38,"react/lib/invariant":42}],21:[function(_dereq_,module,exports){ /** * Encapsulates a redirect to the given route. */ function Redirect(to, params, query) { this.to = to; this.params = params; this.query = query; } module.exports = Redirect; },{}],22:[function(_dereq_,module,exports){ var mixInto = _dereq_('react/lib/mixInto'); var transitionTo = _dereq_('../actions/LocationActions').transitionTo; var Redirect = _dereq_('./Redirect'); /** * Encapsulates a transition to a given path. * * The willTransitionTo and willTransitionFrom handlers receive * an instance of this class as their first argument. */ function Transition(path) { this.path = path; this.abortReason = null; this.isAborted = false; } mixInto(Transition, { abort: function (reason) { this.abortReason = reason; this.isAborted = true; }, redirect: function (to, params, query) { this.abort(new Redirect(to, params, query)); }, retry: function () { transitionTo(this.path); } }); module.exports = Transition; },{"../actions/LocationActions":1,"./Redirect":21,"react/lib/mixInto":47}],23:[function(_dereq_,module,exports){ /** * Returns the current URL path from `window.location`, including query string */ function getWindowPath() { return window.location.pathname + window.location.search; } module.exports = getWindowPath; },{}],24:[function(_dereq_,module,exports){ module.exports = Function.prototype.call.bind(Object.prototype.hasOwnProperty); },{}],25:[function(_dereq_,module,exports){ var HashLocation = _dereq_('../locations/HashLocation'); var PathStore = _dereq_('../stores/PathStore'); var makePath = _dereq_('./makePath'); /** * Returns a string that may safely be used as the href of a * link to the route with the given name. */ function makeHref(to, params, query) { var path = makePath(to, params, query); if (PathStore.getLocation() === HashLocation) return '#' + path; return path; } module.exports = makeHref; },{"../locations/HashLocation":11,"../stores/PathStore":18,"./makePath":26}],26:[function(_dereq_,module,exports){ var invariant = _dereq_('react/lib/invariant'); var RouteStore = _dereq_('../stores/RouteStore'); var Path = _dereq_('./Path'); /** * Returns an absolute URL path created from the given route name, URL * parameters, and query values. */ function makePath(to, params, query) { var path; if (Path.isAbsolute(to)) { path = Path.normalize(to); } else { var route = RouteStore.getRouteByName(to); invariant( route, 'Unable to find a route named "' + to + '". Make sure you have ' + 'a defined somewhere in your routes' ); path = route.props.path; } return Path.withQuery(Path.injectParams(path, params), query); } module.exports = makePath; },{"../stores/RouteStore":19,"./Path":20,"react/lib/invariant":42}],27:[function(_dereq_,module,exports){ var Promise = _dereq_('when/lib/Promise'); /** * Resolves all values in asyncState and calls the setState * function with new state as they resolve. Returns a promise * that resolves after all values are resolved. */ function resolveAsyncState(asyncState, setState) { if (asyncState == null) return Promise.resolve(); var keys = Object.keys(asyncState); return Promise.all( keys.map(function (key) { return Promise.resolve(asyncState[key]).then(function (value) { var newState = {}; newState[key] = value; setState(newState); }); }) ); } module.exports = resolveAsyncState; },{"when/lib/Promise":49}],28:[function(_dereq_,module,exports){ function supportsHistory() { /*! taken from modernizr * https://github.com/Modernizr/Modernizr/blob/master/LICENSE * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js */ var ua = navigator.userAgent; if ((ua.indexOf('Android 2.') !== -1 || (ua.indexOf('Android 4.0') !== -1)) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1) { return false; } return (window.history && 'pushState' in window.history); } module.exports = supportsHistory; },{}],29:[function(_dereq_,module,exports){ function withoutProperties(object, properties) { var result = {}; for (var property in object) { if (object.hasOwnProperty(property) && !properties[property]) result[property] = object[property]; } return result; } module.exports = withoutProperties; },{}],30:[function(_dereq_,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; }; EventEmitter.prototype.emit = function(type) { var er, handler, len, args, i, listeners; if (!this._events) this._events = {}; // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || (isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event } else { throw TypeError('Uncaught, unspecified "error" event.'); } return false; } } handler = this._events[type]; if (isUndefined(handler)) return false; if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: handler.call(this); break; case 2: handler.call(this, arguments[1]); break; case 3: handler.call(this, arguments[1], arguments[2]); break; // slower default: len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; handler.apply(this, args); } } else if (isObject(handler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; listeners = handler.slice(); len = listeners.length; for (i = 0; i < len; i++) listeners[i].apply(this, args); } return true; }; EventEmitter.prototype.addListener = function(type, listener) { var m; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; // Check for listener leak if (isObject(this._events[type]) && !this._events[type].warned) { var m; if (!isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; } if (m && m > 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.listenerCount = function(emitter, type) { var ret; if (!emitter._events || !emitter._events[type]) ret = 0; else if (isFunction(emitter._events[type])) ret = 1; else ret = emitter._events[type].length; return ret; }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } },{}],31:[function(_dereq_,module,exports){ /** * Copyright (c) 2014, 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. */ module.exports.Dispatcher = _dereq_('./lib/Dispatcher') },{"./lib/Dispatcher":32}],32:[function(_dereq_,module,exports){ /* * Copyright (c) 2014, 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. * * @providesModule Dispatcher * @typechecks */ var invariant = _dereq_('./invariant'); var _lastID = 1; var _prefix = 'ID_'; /** * Dispatcher is used to broadcast payloads to registered callbacks. This is * different from generic pub-sub systems in two ways: * * 1) Callbacks are not subscribed to particular events. Every payload is * dispatched to every registered callback. * 2) Callbacks can be deferred in whole or part until other callbacks have * been executed. * * For example, consider this hypothetical flight destination form, which * selects a default city when a country is selected: * * var flightDispatcher = new Dispatcher(); * * // Keeps track of which country is selected * var CountryStore = {country: null}; * * // Keeps track of which city is selected * var CityStore = {city: null}; * * // Keeps track of the base flight price of the selected city * var FlightPriceStore = {price: null} * * When a user changes the selected city, we dispatch the payload: * * flightDispatcher.dispatch({ * actionType: 'city-update', * selectedCity: 'paris' * }); * * This payload is digested by `CityStore`: * * flightDispatcher.register(function(payload) { * if (payload.actionType === 'city-update') { * CityStore.city = payload.selectedCity; * } * }); * * When the user selects a country, we dispatch the payload: * * flightDispatcher.dispatch({ * actionType: 'country-update', * selectedCountry: 'australia' * }); * * This payload is digested by both stores: * * CountryStore.dispatchToken = flightDispatcher.register(function(payload) { * if (payload.actionType === 'country-update') { * CountryStore.country = payload.selectedCountry; * } * }); * * When the callback to update `CountryStore` is registered, we save a reference * to the returned token. Using this token with `waitFor()`, we can guarantee * that `CountryStore` is updated before the callback that updates `CityStore` * needs to query its data. * * CityStore.dispatchToken = flightDispatcher.register(function(payload) { * if (payload.actionType === 'country-update') { * // `CountryStore.country` may not be updated. * flightDispatcher.waitFor([CountryStore.dispatchToken]); * // `CountryStore.country` is now guaranteed to be updated. * * // Select the default city for the new country * CityStore.city = getDefaultCityForCountry(CountryStore.country); * } * }); * * The usage of `waitFor()` can be chained, for example: * * FlightPriceStore.dispatchToken = * flightDispatcher.register(function(payload) { * switch (payload.actionType) { * case 'country-update': * flightDispatcher.waitFor([CityStore.dispatchToken]); * FlightPriceStore.price = * getFlightPriceStore(CountryStore.country, CityStore.city); * break; * * case 'city-update': * FlightPriceStore.price = * FlightPriceStore(CountryStore.country, CityStore.city); * break; * } * }); * * The `country-update` payload will be guaranteed to invoke the stores' * registered callbacks in order: `CountryStore`, `CityStore`, then * `FlightPriceStore`. */ function Dispatcher() {"use strict"; this.$Dispatcher_callbacks = {}; this.$Dispatcher_isPending = {}; this.$Dispatcher_isHandled = {}; this.$Dispatcher_isDispatching = false; this.$Dispatcher_pendingPayload = null; } /** * Registers a callback to be invoked with every dispatched payload. Returns * a token that can be used with `waitFor()`. * * @param {function} callback * @return {string} */ Dispatcher.prototype.register=function(callback) {"use strict"; var id = _prefix + _lastID++; this.$Dispatcher_callbacks[id] = callback; return id; }; /** * Removes a callback based on its token. * * @param {string} id */ Dispatcher.prototype.unregister=function(id) {"use strict"; invariant( this.$Dispatcher_callbacks[id], 'Dispatcher.unregister(...): `%s` does not map to a registered callback.', id ); delete this.$Dispatcher_callbacks[id]; }; /** * Waits for the callbacks specified to be invoked before continuing execution * of the current callback. This method should only be used by a callback in * response to a dispatched payload. * * @param {array} ids */ Dispatcher.prototype.waitFor=function(ids) {"use strict"; invariant( this.$Dispatcher_isDispatching, 'Dispatcher.waitFor(...): Must be invoked while dispatching.' ); for (var ii = 0; ii < ids.length; ii++) { var id = ids[ii]; if (this.$Dispatcher_isPending[id]) { invariant( this.$Dispatcher_isHandled[id], 'Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.', id ); continue; } invariant( this.$Dispatcher_callbacks[id], 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', id ); this.$Dispatcher_invokeCallback(id); } }; /** * Dispatches a payload to all registered callbacks. * * @param {object} payload */ Dispatcher.prototype.dispatch=function(payload) {"use strict"; invariant( !this.$Dispatcher_isDispatching, 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.' ); this.$Dispatcher_startDispatching(payload); try { for (var id in this.$Dispatcher_callbacks) { if (this.$Dispatcher_isPending[id]) { continue; } this.$Dispatcher_invokeCallback(id); } } finally { this.$Dispatcher_stopDispatching(); } }; /** * Is this Dispatcher currently dispatching. * * @return {boolean} */ Dispatcher.prototype.isDispatching=function() {"use strict"; return this.$Dispatcher_isDispatching; }; /** * Call the callback stored with the given id. Also do some internal * bookkeeping. * * @param {string} id * @internal */ Dispatcher.prototype.$Dispatcher_invokeCallback=function(id) {"use strict"; this.$Dispatcher_isPending[id] = true; this.$Dispatcher_callbacks[id](this.$Dispatcher_pendingPayload); this.$Dispatcher_isHandled[id] = true; }; /** * Set up bookkeeping needed when dispatching. * * @param {object} payload * @internal */ Dispatcher.prototype.$Dispatcher_startDispatching=function(payload) {"use strict"; for (var id in this.$Dispatcher_callbacks) { this.$Dispatcher_isPending[id] = false; this.$Dispatcher_isHandled[id] = false; } this.$Dispatcher_pendingPayload = payload; this.$Dispatcher_isDispatching = true; }; /** * Clear bookkeeping used for dispatching. * * @internal */ Dispatcher.prototype.$Dispatcher_stopDispatching=function() {"use strict"; this.$Dispatcher_pendingPayload = null; this.$Dispatcher_isDispatching = false; }; module.exports = Dispatcher; },{"./invariant":33}],33:[function(_dereq_,module,exports){ /** * Copyright (c) 2014, 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. * * @providesModule invariant */ "use strict"; /** * Use invariant() to assert state which your program assumes to be true. * * Provide sprintf-style format (only %s is supported) and arguments * to provide information about what broke and what you were * expecting. * * The invariant message will be stripped in production, but the invariant * will remain to ensure logic does not differ in production. */ var invariant = function(condition, format, a, b, c, d, e, f) { if (false) { if (format === undefined) { throw new Error('invariant requires an error message argument'); } } if (!condition) { var error; if (format === undefined) { error = new Error( 'Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.' ); } else { var args = [a, b, c, d, e, f]; var argIndex = 0; error = new Error( 'Invariant Violation: ' + format.replace(/%s/g, function() { return args[argIndex++]; }) ); } error.framesToPop = 1; // we don't care about invariant's own frame throw error; } }; module.exports = invariant; },{}],34:[function(_dereq_,module,exports){ module.exports = _dereq_('./lib'); },{"./lib":35}],35:[function(_dereq_,module,exports){ // Load modules var Stringify = _dereq_('./stringify'); var Parse = _dereq_('./parse'); // Declare internals var internals = {}; module.exports = { stringify: Stringify, parse: Parse }; },{"./parse":36,"./stringify":37}],36:[function(_dereq_,module,exports){ // Load modules var Utils = _dereq_('./utils'); // Declare internals var internals = { delimiter: '&', depth: 5, arrayLimit: 20, parameterLimit: 1000 }; internals.parseValues = function (str, options) { var obj = {}; var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); for (var i = 0, il = parts.length; i < il; ++i) { var part = parts[i]; var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; if (pos === -1) { obj[Utils.decode(part)] = ''; } else { var key = Utils.decode(part.slice(0, pos)); var val = Utils.decode(part.slice(pos + 1)); if (!obj[key]) { obj[key] = val; } else { obj[key] = [].concat(obj[key]).concat(val); } } } return obj; }; internals.parseObject = function (chain, val, options) { if (!chain.length) { return val; } var root = chain.shift(); var obj = {}; if (root === '[]') { obj = []; obj = obj.concat(internals.parseObject(chain, val, options)); } else { var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; var index = parseInt(cleanRoot, 10); if (!isNaN(index) && root !== cleanRoot && index <= options.arrayLimit) { obj = []; obj[index] = internals.parseObject(chain, val, options); } else { obj[cleanRoot] = internals.parseObject(chain, val, options); } } return obj; }; internals.parseKeys = function (key, val, options) { if (!key) { return; } // The regex chunks var parent = /^([^\[\]]*)/; var child = /(\[[^\[\]]*\])/g; // Get the parent var segment = parent.exec(key); // Don't allow them to overwrite object prototype properties if (Object.prototype.hasOwnProperty(segment[1])) { return; } // Stash the parent if it exists var keys = []; if (segment[1]) { keys.push(segment[1]); } // Loop through children appending to the array until we hit depth var i = 0; while ((segment = child.exec(key)) !== null && i < options.depth) { ++i; if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { keys.push(segment[1]); } } // If there's a remainder, just add whatever is left if (segment) { keys.push('[' + key.slice(segment.index) + ']'); } return internals.parseObject(keys, val, options); }; module.exports = function (str, options) { if (str === '' || str === null || typeof str === 'undefined') { return {}; } options = options || {}; options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; var obj = {}; // Iterate over the keys and setup the new object var keys = Object.keys(tempObj); for (var i = 0, il = keys.length; i < il; ++i) { var key = keys[i]; var newObj = internals.parseKeys(key, tempObj[key], options); obj = Utils.merge(obj, newObj); } return Utils.compact(obj); }; },{"./utils":38}],37:[function(_dereq_,module,exports){ // Load modules var Utils = _dereq_('./utils'); // Declare internals var internals = { delimiter: '&' }; internals.stringify = function (obj, prefix) { if (Utils.isBuffer(obj)) { obj = obj.toString(); } else if (obj instanceof Date) { obj = obj.toISOString(); } else if (obj === null) { obj = ''; } if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean') { return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; } var values = []; for (var key in obj) { if (obj.hasOwnProperty(key)) { values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']')); } } return values; }; module.exports = function (obj, options) { options = options || {}; var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; var keys = []; for (var key in obj) { if (obj.hasOwnProperty(key)) { keys = keys.concat(internals.stringify(obj[key], key)); } } return keys.join(delimiter); }; },{"./utils":38}],38:[function(_dereq_,module,exports){ // Load modules // Declare internals var internals = {}; exports.arrayToObject = function (source) { var obj = {}; for (var i = 0, il = source.length; i < il; ++i) { if (typeof source[i] !== 'undefined') { obj[i] = source[i]; } } return obj; }; exports.merge = function (target, source) { if (!source) { return target; } if (Array.isArray(source)) { for (var i = 0, il = source.length; i < il; ++i) { if (typeof source[i] !== 'undefined') { if (typeof target[i] === 'object') { target[i] = exports.merge(target[i], source[i]); } else { target[i] = source[i]; } } } return target; } if (Array.isArray(target)) { if (typeof source !== 'object') { target.push(source); return target; } else { target = exports.arrayToObject(target); } } var keys = Object.keys(source); for (var k = 0, kl = keys.length; k < kl; ++k) { var key = keys[k]; var value = source[key]; if (value && typeof value === 'object') { if (!target[key]) { target[key] = value; } else { target[key] = exports.merge(target[key], value); } } else { target[key] = value; } } return target; }; exports.decode = function (str) { try { return decodeURIComponent(str.replace(/\+/g, ' ')); } catch (e) { return str; } }; exports.compact = function (obj, refs) { if (typeof obj !== 'object' || obj === null) { return obj; } refs = refs || []; var lookup = refs.indexOf(obj); if (lookup !== -1) { return refs[lookup]; } refs.push(obj); if (Array.isArray(obj)) { var compacted = []; for (var i = 0, l = obj.length; i < l; ++i) { if (typeof obj[i] !== 'undefined') { compacted.push(obj[i]); } } return compacted; } var keys = Object.keys(obj); for (var i = 0, il = keys.length; i < il; ++i) { var key = keys[i]; obj[key] = exports.compact(obj[key], refs); } return obj; }; exports.isRegExp = function (obj) { return Object.prototype.toString.call(obj) === '[object RegExp]'; }; exports.isBuffer = function (obj) { if (typeof Buffer !== 'undefined') { return Buffer.isBuffer(obj); } else { return false; } }; },{}],39:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ExecutionEnvironment */ /*jslint evil: true */ "use strict"; var canUseDOM = !!( typeof window !== 'undefined' && window.document && window.document.createElement ); /** * Simple, lightweight module assisting with the detection and context of * Worker. Helps avoid circular dependencies and allows code to reason about * whether or not they are in a Worker, even if they never include the main * `ReactWorker` dependency. */ var ExecutionEnvironment = { canUseDOM: canUseDOM, canUseWorkers: typeof Worker !== 'undefined', canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), canUseViewport: canUseDOM && !!window.screen, isInWorker: !canUseDOM // For now, this is true - might change in the future. }; module.exports = ExecutionEnvironment; },{}],40:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule copyProperties */ /** * Copy properties from one or more objects (up to 5) into the first object. * This is a shallow copy. It mutates the first object and also returns it. * * NOTE: `arguments` has a very significant performance penalty, which is why * we don't support unlimited arguments. */ function copyProperties(obj, a, b, c, d, e, f) { obj = obj || {}; if ("production" !== "production") { if (f) { throw new Error('Too many arguments passed to copyProperties'); } } var args = [a, b, c, d, e]; var ii = 0, v; while (args[ii]) { v = args[ii++]; for (var k in v) { obj[k] = v[k]; } // IE ignores toString in object iteration.. See: // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html if (v.hasOwnProperty && v.hasOwnProperty('toString') && (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) { obj.toString = v.toString; } } return obj; } module.exports = copyProperties; },{}],41:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule emptyFunction */ var copyProperties = _dereq_("./copyProperties"); function makeEmptyFunction(arg) { return function() { return arg; }; } /** * This function accepts and discards inputs; it has no side effects. This is * primarily useful idiomatically for overridable function endpoints which * always need to be callable, since JS lacks a null-call idiom ala Cocoa. */ function emptyFunction() {} copyProperties(emptyFunction, { thatReturns: makeEmptyFunction, thatReturnsFalse: makeEmptyFunction(false), thatReturnsTrue: makeEmptyFunction(true), thatReturnsNull: makeEmptyFunction(null), thatReturnsThis: function() { return this; }, thatReturnsArgument: function(arg) { return arg; } }); module.exports = emptyFunction; },{"./copyProperties":40}],42:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule invariant */ "use strict"; /** * Use invariant() to assert state which your program assumes to be true. * * Provide sprintf-style format (only %s is supported) and arguments * to provide information about what broke and what you were * expecting. * * The invariant message will be stripped in production, but the invariant * will remain to ensure logic does not differ in production. */ var invariant = function(condition, format, a, b, c, d, e, f) { if ("production" !== "production") { if (format === undefined) { throw new Error('invariant requires an error message argument'); } } if (!condition) { var error; if (format === undefined) { error = new Error( 'Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.' ); } else { var args = [a, b, c, d, e, f]; var argIndex = 0; error = new Error( 'Invariant Violation: ' + format.replace(/%s/g, function() { return args[argIndex++]; }) ); } error.framesToPop = 1; // we don't care about invariant's own frame throw error; } }; module.exports = invariant; },{}],43:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule keyMirror * @typechecks static-only */ "use strict"; var invariant = _dereq_("./invariant"); /** * Constructs an enumeration with keys equal to their value. * * For example: * * var COLORS = keyMirror({blue: null, red: null}); * var myColor = COLORS.blue; * var isColorValid = !!COLORS[myColor]; * * The last line could not be performed if the values of the generated enum were * not equal to their keys. * * Input: {key1: val1, key2: val2} * Output: {key1: key1, key2: key2} * * @param {object} obj * @return {object} */ var keyMirror = function(obj) { var ret = {}; var key; ("production" !== "production" ? invariant( obj instanceof Object && !Array.isArray(obj), 'keyMirror(...): Argument must be an object.' ) : invariant(obj instanceof Object && !Array.isArray(obj))); for (key in obj) { if (!obj.hasOwnProperty(key)) { continue; } ret[key] = key; } return ret; }; module.exports = keyMirror; },{"./invariant":42}],44:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule merge */ "use strict"; var mergeInto = _dereq_("./mergeInto"); /** * Shallow merges two structures into a return value, without mutating either. * * @param {?object} one Optional object with properties to merge from. * @param {?object} two Optional object with properties to merge from. * @return {object} The shallow extension of one by two. */ var merge = function(one, two) { var result = {}; mergeInto(result, one); mergeInto(result, two); return result; }; module.exports = merge; },{"./mergeInto":46}],45:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule mergeHelpers * * requiresPolyfills: Array.isArray */ "use strict"; var invariant = _dereq_("./invariant"); var keyMirror = _dereq_("./keyMirror"); /** * Maximum number of levels to traverse. Will catch circular structures. * @const */ var MAX_MERGE_DEPTH = 36; /** * We won't worry about edge cases like new String('x') or new Boolean(true). * Functions are considered terminals, and arrays are not. * @param {*} o The item/object/value to test. * @return {boolean} true iff the argument is a terminal. */ var isTerminal = function(o) { return typeof o !== 'object' || o === null; }; var mergeHelpers = { MAX_MERGE_DEPTH: MAX_MERGE_DEPTH, isTerminal: isTerminal, /** * Converts null/undefined values into empty object. * * @param {?Object=} arg Argument to be normalized (nullable optional) * @return {!Object} */ normalizeMergeArg: function(arg) { return arg === undefined || arg === null ? {} : arg; }, /** * If merging Arrays, a merge strategy *must* be supplied. If not, it is * likely the caller's fault. If this function is ever called with anything * but `one` and `two` being `Array`s, it is the fault of the merge utilities. * * @param {*} one Array to merge into. * @param {*} two Array to merge from. */ checkMergeArrayArgs: function(one, two) { ("production" !== "production" ? invariant( Array.isArray(one) && Array.isArray(two), 'Tried to merge arrays, instead got %s and %s.', one, two ) : invariant(Array.isArray(one) && Array.isArray(two))); }, /** * @param {*} one Object to merge into. * @param {*} two Object to merge from. */ checkMergeObjectArgs: function(one, two) { mergeHelpers.checkMergeObjectArg(one); mergeHelpers.checkMergeObjectArg(two); }, /** * @param {*} arg */ checkMergeObjectArg: function(arg) { ("production" !== "production" ? invariant( !isTerminal(arg) && !Array.isArray(arg), 'Tried to merge an object, instead got %s.', arg ) : invariant(!isTerminal(arg) && !Array.isArray(arg))); }, /** * @param {*} arg */ checkMergeIntoObjectArg: function(arg) { ("production" !== "production" ? invariant( (!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg), 'Tried to merge into an object, instead got %s.', arg ) : invariant((!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg))); }, /** * Checks that a merge was not given a circular object or an object that had * too great of depth. * * @param {number} Level of recursion to validate against maximum. */ checkMergeLevel: function(level) { ("production" !== "production" ? invariant( level < MAX_MERGE_DEPTH, 'Maximum deep merge depth exceeded. You may be attempting to merge ' + 'circular structures in an unsupported way.' ) : invariant(level < MAX_MERGE_DEPTH)); }, /** * Checks that the supplied merge strategy is valid. * * @param {string} Array merge strategy. */ checkArrayStrategy: function(strategy) { ("production" !== "production" ? invariant( strategy === undefined || strategy in mergeHelpers.ArrayStrategies, 'You must provide an array strategy to deep merge functions to ' + 'instruct the deep merge how to resolve merging two arrays.' ) : invariant(strategy === undefined || strategy in mergeHelpers.ArrayStrategies)); }, /** * Set of possible behaviors of merge algorithms when encountering two Arrays * that must be merged together. * - `clobber`: The left `Array` is ignored. * - `indexByIndex`: The result is achieved by recursively deep merging at * each index. (not yet supported.) */ ArrayStrategies: keyMirror({ Clobber: true, IndexByIndex: true }) }; module.exports = mergeHelpers; },{"./invariant":42,"./keyMirror":43}],46:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule mergeInto * @typechecks static-only */ "use strict"; var mergeHelpers = _dereq_("./mergeHelpers"); var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg; var checkMergeIntoObjectArg = mergeHelpers.checkMergeIntoObjectArg; /** * Shallow merges two structures by mutating the first parameter. * * @param {object|function} one Object to be merged into. * @param {?object} two Optional object with properties to merge from. */ function mergeInto(one, two) { checkMergeIntoObjectArg(one); if (two != null) { checkMergeObjectArg(two); for (var key in two) { if (!two.hasOwnProperty(key)) { continue; } one[key] = two[key]; } } } module.exports = mergeInto; },{"./mergeHelpers":45}],47:[function(_dereq_,module,exports){ /** * Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule mixInto */ "use strict"; /** * Simply copies properties to the prototype. */ var mixInto = function(constructor, methodBag) { var methodName; for (methodName in methodBag) { if (!methodBag.hasOwnProperty(methodName)) { continue; } constructor.prototype[methodName] = methodBag[methodName]; } }; module.exports = mixInto; },{}],48:[function(_dereq_,module,exports){ /** * Copyright 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule warning */ "use strict"; var emptyFunction = _dereq_("./emptyFunction"); /** * Similar to invariant but only logs a warning if the condition is not met. * This can be used to log issues in development environments in critical * paths. Removing the logging code for production environments will keep the * same logic and follow the same code paths. */ var warning = emptyFunction; if ("production" !== "production") { warning = function(condition, format ) {var args=Array.prototype.slice.call(arguments,2); if (format === undefined) { throw new Error( '`warning(condition, format, ...args)` requires a warning ' + 'message argument' ); } if (!condition) { var argIndex = 0; console.warn('Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];})); } }; } module.exports = warning; },{"./emptyFunction":41}],49:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ (function(define) { 'use strict'; define(function (_dereq_) { var makePromise = _dereq_('./makePromise'); var Scheduler = _dereq_('./Scheduler'); var async = _dereq_('./async'); return makePromise({ scheduler: new Scheduler(async) }); }); })(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(_dereq_); }); },{"./Scheduler":51,"./async":52,"./makePromise":53}],50:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ (function(define) { 'use strict'; define(function() { /** * Circular queue * @param {number} capacityPow2 power of 2 to which this queue's capacity * will be set initially. eg when capacityPow2 == 3, queue capacity * will be 8. * @constructor */ function Queue(capacityPow2) { this.head = this.tail = this.length = 0; this.buffer = new Array(1 << capacityPow2); } Queue.prototype.push = function(x) { if(this.length === this.buffer.length) { this._ensureCapacity(this.length * 2); } this.buffer[this.tail] = x; this.tail = (this.tail + 1) & (this.buffer.length - 1); ++this.length; return this.length; }; Queue.prototype.shift = function() { var x = this.buffer[this.head]; this.buffer[this.head] = void 0; this.head = (this.head + 1) & (this.buffer.length - 1); --this.length; return x; }; Queue.prototype._ensureCapacity = function(capacity) { var head = this.head; var buffer = this.buffer; var newBuffer = new Array(capacity); var i = 0; var len; if(head === 0) { len = this.length; for(; i 0) { queue.shift().run(); } } return Scheduler; }); }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); },{"./Queue":50}],52:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ (function(define) { 'use strict'; define(function(_dereq_) { // Sniff "best" async scheduling option // Prefer process.nextTick or MutationObserver, then check for // vertx and finally fall back to setTimeout /*jshint maxcomplexity:6*/ /*global process,document,setTimeout,MutationObserver,WebKitMutationObserver*/ var nextTick, MutationObs; if (typeof process !== 'undefined' && process !== null && typeof process.nextTick === 'function') { nextTick = function(f) { process.nextTick(f); }; } else if (MutationObs = (typeof MutationObserver === 'function' && MutationObserver) || (typeof WebKitMutationObserver === 'function' && WebKitMutationObserver)) { nextTick = (function (document, MutationObserver) { var scheduled; var el = document.createElement('div'); var o = new MutationObserver(run); o.observe(el, { attributes: true }); function run() { var f = scheduled; scheduled = void 0; f(); } return function (f) { scheduled = f; el.setAttribute('class', 'x'); }; }(document, MutationObs)); } else { nextTick = (function(cjsRequire) { try { // vert.x 1.x || 2.x return cjsRequire('vertx').runOnLoop || cjsRequire('vertx').runOnContext; } catch (ignore) {} // capture setTimeout to avoid being caught by fake timers // used in time based tests var capturedSetTimeout = setTimeout; return function (t) { capturedSetTimeout(t, 0); }; }(_dereq_)); } return nextTick; }); }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); },{}],53:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ (function(define) { 'use strict'; define(function() { return function makePromise(environment) { var tasks = environment.scheduler; var objectCreate = Object.create || function(proto) { function Child() {} Child.prototype = proto; return new Child(); }; /** * Create a promise whose fate is determined by resolver * @constructor * @returns {Promise} promise * @name Promise */ function Promise(resolver, handler) { this._handler = resolver === Handler ? handler : init(resolver); } /** * Run the supplied resolver * @param resolver * @returns {Pending} */ function init(resolver) { var handler = new Pending(); try { resolver(promiseResolve, promiseReject, promiseNotify); } catch (e) { promiseReject(e); } return handler; /** * Transition from pre-resolution state to post-resolution state, notifying * all listeners of the ultimate fulfillment or rejection * @param {*} x resolution value */ function promiseResolve (x) { handler.resolve(x); } /** * Reject this promise with reason, which will be used verbatim * @param {Error|*} reason rejection reason, strongly suggested * to be an Error type */ function promiseReject (reason) { handler.reject(reason); } /** * Issue a progress event, notifying all progress listeners * @param {*} x progress event payload to pass to all listeners */ function promiseNotify (x) { handler.notify(x); } } // Creation Promise.resolve = resolve; Promise.reject = reject; Promise.never = never; Promise._defer = defer; Promise._handler = getHandler; /** * Returns a trusted promise. If x is already a trusted promise, it is * returned, otherwise returns a new trusted Promise which follows x. * @param {*} x * @return {Promise} promise */ function resolve(x) { return isPromise(x) ? x : new Promise(Handler, new Async(getHandler(x))); } /** * Return a reject promise with x as its reason (x is used verbatim) * @param {*} x * @returns {Promise} rejected promise */ function reject(x) { return new Promise(Handler, new Async(new Rejected(x))); } /** * Return a promise that remains pending forever * @returns {Promise} forever-pending promise. */ function never() { return foreverPendingPromise; // Should be frozen } /** * Creates an internal {promise, resolver} pair * @private * @returns {Promise} */ function defer() { return new Promise(Handler, new Pending()); } // Transformation and flow control /** * Transform this promise's fulfillment value, returning a new Promise * for the transformed result. If the promise cannot be fulfilled, onRejected * is called with the reason. onProgress *may* be called with updates toward * this promise's fulfillment. * @param {function=} onFulfilled fulfillment handler * @param {function=} onRejected rejection handler * @deprecated @param {function=} onProgress progress handler * @return {Promise} new promise */ Promise.prototype.then = function(onFulfilled, onRejected) { var parent = this._handler; if (typeof onFulfilled !== 'function' && parent.join().state() > 0) { // Short circuit: value will not change, simply share handler return new Promise(Handler, parent); } var p = this._beget(); var child = p._handler; parent.chain(child, parent.receiver, onFulfilled, onRejected, arguments.length > 2 ? arguments[2] : void 0); return p; }; /** * If this promise cannot be fulfilled due to an error, call onRejected to * handle the error. Shortcut for .then(undefined, onRejected) * @param {function?} onRejected * @return {Promise} */ Promise.prototype['catch'] = function(onRejected) { return this.then(void 0, onRejected); }; /** * Creates a new, pending promise of the same type as this promise * @private * @returns {Promise} */ Promise.prototype._beget = function() { var parent = this._handler; var child = new Pending(parent.receiver, parent.join().context); return new this.constructor(Handler, child); }; // Array combinators Promise.all = all; Promise.race = race; /** * Return a promise that will fulfill when all promises in the * input array have fulfilled, or will reject when one of the * promises rejects. * @param {array} promises array of promises * @returns {Promise} promise for array of fulfillment values */ function all(promises) { /*jshint maxcomplexity:8*/ var resolver = new Pending(); var pending = promises.length >>> 0; var results = new Array(pending); var i, h, x, s; for (i = 0; i < promises.length; ++i) { x = promises[i]; if (x === void 0 && !(i in promises)) { --pending; continue; } if (maybeThenable(x)) { h = isPromise(x) ? x._handler.join() : getHandlerUntrusted(x); s = h.state(); if (s === 0) { h.fold(settleAt, i, results, resolver); } else if (s > 0) { results[i] = h.value; --pending; } else { resolver.become(h); break; } } else { results[i] = x; --pending; } } if(pending === 0) { resolver.become(new Fulfilled(results)); } return new Promise(Handler, resolver); function settleAt(i, x, resolver) { /*jshint validthis:true*/ this[i] = x; if(--pending === 0) { resolver.become(new Fulfilled(this)); } } } /** * Fulfill-reject competitive race. Return a promise that will settle * to the same state as the earliest input promise to settle. * * WARNING: The ES6 Promise spec requires that race()ing an empty array * must return a promise that is pending forever. This implementation * returns a singleton forever-pending promise, the same singleton that is * returned by Promise.never(), thus can be checked with === * * @param {array} promises array of promises to race * @returns {Promise} if input is non-empty, a promise that will settle * to the same outcome as the earliest input promise to settle. if empty * is empty, returns a promise that will never settle. */ function race(promises) { // Sigh, race([]) is untestable unless we return *something* // that is recognizable without calling .then() on it. if(Object(promises) === promises && promises.length === 0) { return never(); } var h = new Pending(); var i, x; for(i=0; i