diff --git a/CHANGELOG.md b/CHANGELOG.md index afba1f95f4..5389e483fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +v0.11.0 - Sat, 22 Nov 2014 06:03:21 GMT +--------------------------------------- + +- [5695b9a](../../commit/5695b9a) [removed] addHandlerKey +- [97d7a05](../../commit/97d7a05) [added] ActiveRouteHandler +- [940a0d0](../../commit/940a0d0) [changed] use `Object.assign` instead of `copyProperties` +- [f8cb7f9](../../commit/f8cb7f9) [changed] use `Object.assign` instead of `merge` +- [70b442a](../../commit/70b442a) [added] React 0.12 compatibility + + v0.10.2 - Fri, 31 Oct 2014 16:23:27 GMT --------------------------------------- diff --git a/bower.json b/bower.json index 65c9dcb691..af93516fd4 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "react-router", - "version": "0.10.2", + "version": "0.11.0", "homepage": "https://github.com/rackt/react-router", "authors": [ "Ryan Florence", diff --git a/dist/react-router.js b/dist/react-router.js index 429f2230ac..285708bc80 100644 --- a/dist/react-router.js +++ b/dist/react-router.js @@ -53,23 +53,9 @@ var ImitateBrowserBehavior = { module.exports = ImitateBrowserBehavior; },{"../actions/LocationActions":1}],3:[function(_dereq_,module,exports){ -/** - * A scroll behavior that always scrolls to the top of the page - * after a transition. - */ -var ScrollToTopBehavior = { - - updateScrollPosition: function () { - window.scrollTo(0, 0); - } - -}; - -module.exports = ScrollToTopBehavior; - -},{}],4:[function(_dereq_,module,exports){ -var objectAssign = _dereq_('react/lib/Object.assign'); -var Route = _dereq_('./Route'); +var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); +var FakeNode = _dereq_('../mixins/FakeNode'); +var PropTypes = _dereq_('../utils/PropTypes'); /** * A component is a special kind of that @@ -77,23 +63,28 @@ var Route = _dereq_('./Route'); * Only one such route may be used at any given level in the * route hierarchy. */ -function DefaultRoute(props) { - return Route( - objectAssign({}, props, { - path: null, - isDefault: true - }) - ); -} +var DefaultRoute = React.createClass({ + + displayName: 'DefaultRoute', + + mixins: [ FakeNode ], + + propTypes: { + name: React.PropTypes.string, + path: PropTypes.falsy, + handler: React.PropTypes.func.isRequired + } + +}); module.exports = DefaultRoute; -},{"./Route":8,"react/lib/Object.assign":43}],5:[function(_dereq_,module,exports){ +},{"../mixins/FakeNode":13,"../utils/PropTypes":21}],4:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); var classSet = _dereq_('react/lib/cx'); -var objectAssign = _dereq_('react/lib/Object.assign'); -var ActiveState = _dereq_('../mixins/ActiveState'); +var assign = _dereq_('react/lib/Object.assign'); var Navigation = _dereq_('../mixins/Navigation'); +var State = _dereq_('../mixins/State'); function isLeftClickEvent(event) { return event.button === 0; @@ -125,7 +116,7 @@ var Link = React.createClass({ displayName: 'Link', - mixins: [ ActiveState, Navigation ], + mixins: [ Navigation, State ], propTypes: { activeClassName: React.PropTypes.string.isRequired, @@ -184,7 +175,7 @@ var Link = React.createClass({ }, render: function () { - var props = objectAssign({}, this.props, { + var props = assign({}, this.props, { href: this.getHref(), className: this.getClassName(), onClick: this.handleClick @@ -197,9 +188,10 @@ var Link = React.createClass({ module.exports = Link; -},{"../mixins/ActiveState":15,"../mixins/Navigation":18,"react/lib/Object.assign":43,"react/lib/cx":64}],6:[function(_dereq_,module,exports){ -var objectAssign = _dereq_('react/lib/Object.assign'); -var Route = _dereq_('./Route'); +},{"../mixins/Navigation":14,"../mixins/State":17,"react/lib/Object.assign":36,"react/lib/cx":37}],5:[function(_dereq_,module,exports){ +var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); +var FakeNode = _dereq_('../mixins/FakeNode'); +var PropTypes = _dereq_('../utils/PropTypes'); /** * A is a special kind of that @@ -208,66 +200,51 @@ var Route = _dereq_('./Route'); * Only one such route may be used at any given level in the * route hierarchy. */ -function NotFoundRoute(props) { - return Route( - objectAssign({}, props, { - path: null, - catchAll: true - }) - ); -} +var NotFoundRoute = React.createClass({ -module.exports = NotFoundRoute; + displayName: 'NotFoundRoute', -},{"./Route":8,"react/lib/Object.assign":43}],7:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var Route = _dereq_('./Route'); + mixins: [ FakeNode ], -function createRedirectHandler(to, _params, _query) { - return React.createClass({ - statics: { - willTransitionTo: function (transition, params, query) { - transition.redirect(to, _params || params, _query || query); - } - }, + propTypes: { + name: React.PropTypes.string, + path: PropTypes.falsy, + handler: React.PropTypes.func.isRequired + } - render: function () { - return null; - } - }); -} +}); + +module.exports = NotFoundRoute; + +},{"../mixins/FakeNode":13,"../utils/PropTypes":21}],6:[function(_dereq_,module,exports){ +var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); +var FakeNode = _dereq_('../mixins/FakeNode'); +var PropTypes = _dereq_('../utils/PropTypes'); /** * 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, props.params, props.query) - }); -} +var Redirect = React.createClass({ + + displayName: 'Redirect', + + mixins: [ FakeNode ], + + propTypes: { + path: React.PropTypes.string, + from: React.PropTypes.string, // Alias for path. + to: React.PropTypes.string, + handler: PropTypes.falsy + } + +}); module.exports = Redirect; -},{"./Route":8}],8:[function(_dereq_,module,exports){ +},{"../mixins/FakeNode":13,"../utils/PropTypes":21}],7:[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, - notFoundRoute: true, - paramNames: true, - children: true // ReactChildren -}; +var FakeNode = _dereq_('../mixins/FakeNode'); /** * components specify components that are rendered to the page when the @@ -282,33 +259,26 @@ var RESERVED_PROPS = { * 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(( - * + * var routes = [ + * * * * - * - * ), 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); + * + * ]; + * + * Router.run(routes, function (Handler) { + * React.render(, document.body); + * }); * * Handlers for Route components that contain children can render their active - * child route using the activeRouteHandler prop. + * child route using a element. * * var App = React.createClass({ * render: function () { * return ( *
- * {this.props.activeRouteHandler()} + * *
* ); * } @@ -318,471 +288,366 @@ var Route = React.createClass({ displayName: 'Route', - statics: { - - getUnreservedProps: function (props) { - return withoutProperties(props, RESERVED_PROPS); - } - - }, + mixins: [ FakeNode ], propTypes: { - handler: React.PropTypes.any.isRequired, - path: React.PropTypes.string, name: React.PropTypes.string, + path: React.PropTypes.string, + handler: React.PropTypes.func.isRequired, ignoreScrollBehavior: React.PropTypes.bool - }, - - 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":30}],9:[function(_dereq_,module,exports){ +},{"../mixins/FakeNode":13}],8:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var warning = _dereq_('react/lib/warning'); -var invariant = _dereq_('react/lib/invariant'); -var objectAssign = _dereq_('react/lib/Object.assign'); -var HashLocation = _dereq_('../locations/HashLocation'); -var ActiveContext = _dereq_('../mixins/ActiveContext'); -var LocationContext = _dereq_('../mixins/LocationContext'); -var RouteContext = _dereq_('../mixins/RouteContext'); -var ScrollContext = _dereq_('../mixins/ScrollContext'); -var reversedArray = _dereq_('../utils/reversedArray'); -var Transition = _dereq_('../utils/Transition'); -var Redirect = _dereq_('../utils/Redirect'); -var Path = _dereq_('../utils/Path'); -var Route = _dereq_('./Route'); -function makeMatch(route, params) { - return { route: route, params: params }; -} +/** + * A component renders the active child route handler + * when routes are nested. + */ +var RouteHandler = React.createClass({ -function getRootMatch(matches) { - return matches[matches.length - 1]; -} + displayName: 'RouteHandler', -function findMatches(path, routes, defaultRoute, notFoundRoute) { - var matches = null, route, params; + getDefaultProps: function () { + return { + ref: '__routeHandler__' + }; + }, - for (var i = 0, len = routes.length; i < len; ++i) { - route = routes[i]; + contextTypes: { + getRouteAtDepth: React.PropTypes.func.isRequired, + getRouteComponents: React.PropTypes.func.isRequired, + routeHandlers: React.PropTypes.array.isRequired + }, - // Check the subtree first to find the most deeply-nested match. - matches = findMatches(path, route.props.children, route.props.defaultRoute, route.props.notFoundRoute); + childContextTypes: { + routeHandlers: React.PropTypes.array.isRequired + }, - if (matches != null) { - var rootParams = getRootMatch(matches).params; + getChildContext: function () { + return { + routeHandlers: this.context.routeHandlers.concat([ this ]) + }; + }, - params = route.props.paramNames.reduce(function (params, paramName) { - params[paramName] = rootParams[paramName]; - return params; - }, {}); + getRouteDepth: function () { + return this.context.routeHandlers.length - 1; + }, - matches.unshift(makeMatch(route, params)); + componentDidMount: function () { + this._updateRouteComponent(); + }, - return matches; - } + componentDidUpdate: function () { + this._updateRouteComponent(); + }, - // No routes in the subtree matched, so check this route. - params = Path.extractParams(route.props.path, path); + _updateRouteComponent: function () { + var depth = this.getRouteDepth(); + var components = this.context.getRouteComponents(); + components[depth] = this.refs[this.props.ref]; + }, - if (params) - return [ makeMatch(route, params) ]; + render: function () { + var route = this.context.getRouteAtDepth(this.getRouteDepth()); + return route ? React.createElement(route.handler, this.props) : null; } - // 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 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; - }); -} +module.exports = RouteHandler; -/** - * 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. - * Calls callback(error) when finished. - */ -function runTransitionFromHooks(matches, transition, callback) { - var hooks = reversedArray(matches).map(function (match) { - return function () { - var handler = match.route.props.handler; +},{}],9:[function(_dereq_,module,exports){ +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.RouteHandler = _dereq_('./components/RouteHandler'); - if (!transition.isAborted && handler.willTransitionFrom) - return handler.willTransitionFrom(transition, match.component); +exports.HashLocation = _dereq_('./locations/HashLocation'); +exports.HistoryLocation = _dereq_('./locations/HistoryLocation'); +exports.RefreshLocation = _dereq_('./locations/RefreshLocation'); - var promise = transition.promise; - delete transition.promise; +exports.Navigation = _dereq_('./mixins/Navigation'); +exports.State = _dereq_('./mixins/State'); - return promise; - }; - }); +exports.create = _dereq_('./utils/createRouter'); +exports.run = _dereq_('./utils/runRouter'); - runHooks(hooks, callback); -} +},{"./components/DefaultRoute":3,"./components/Link":4,"./components/NotFoundRoute":5,"./components/Redirect":6,"./components/Route":7,"./components/RouteHandler":8,"./locations/HashLocation":10,"./locations/HistoryLocation":11,"./locations/RefreshLocation":12,"./mixins/Navigation":14,"./mixins/State":17,"./utils/createRouter":24,"./utils/runRouter":28}],10:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; +var LocationActions = _dereq_('../actions/LocationActions'); +var Path = _dereq_('../utils/Path'); /** - * Calls the willTransitionTo hook of all handlers in the given matches - * serially with the transition object and any params that apply to that - * handler. Calls callback(error) when finished. + * Returns the current URL path from `window.location.hash`, including query string */ -function runTransitionToHooks(matches, transition, query, callback) { - var hooks = matches.map(function (match) { - return function () { - var handler = match.route.props.handler; - - if (!transition.isAborted && handler.willTransitionTo) - handler.willTransitionTo(transition, match.params, query); - - var promise = transition.promise; - delete transition.promise; - - return promise; - }; - }); +function getHashPath() { + invariant( + canUseDOM, + 'getHashPath needs a DOM' + ); - runHooks(hooks, callback); + return Path.decode( + window.location.hash.substr(1) + ); } -/** - * Runs all hook functions serially and calls callback(error) when finished. - * A hook may return a promise if it needs to execute asynchronously. - */ -function runHooks(hooks, callback) { - try { - var promise = hooks.reduce(function (promise, hook) { - // The first hook to use transition.wait makes the rest - // of the transition async from that point forward. - return promise ? promise.then(hook) : hook(); - }, null); - } catch (error) { - return callback(error); // Sync error. - } +var _actionType; - if (promise) { - // Use setTimeout to break the promise chain. - promise.then(function () { - setTimeout(callback); - }, function (error) { - setTimeout(function () { - callback(error); - }); - }); - } else { - callback(); - } -} +function ensureSlash() { + var path = getHashPath(); -function updateMatchComponents(matches, refs) { - var match; - for (var i = 0, len = matches.length; i < len; ++i) { - match = matches[i]; - match.component = refs.__activeRoute__; + if (path.charAt(0) === '/') + return true; - if (match.component == null) - break; // End of the tree. + HashLocation.replace('/' + path); - refs = match.component.refs; - } + return false; } -function shouldUpdateScroll(currentMatches, previousMatches) { - var commonMatches = currentMatches.filter(function (match) { - return previousMatches.indexOf(match) !== -1; - }); - - return !commonMatches.some(function (match) { - return match.route.props.ignoreScrollBehavior; - }); -} +var _changeListeners = []; -function returnNull() { - return null; -} +function notifyChange(type) { + var change = { + path: getHashPath(), + type: type + }; -function routeIsActive(activeRoutes, routeName) { - return activeRoutes.some(function (route) { - return route.props.name === routeName; + _changeListeners.forEach(function (listener) { + listener(change); }); } -function paramsAreActive(activeParams, params) { - for (var property in params) - if (String(activeParams[property]) !== String(params[property])) - return false; - - return true; -} - -function queryIsActive(activeQuery, query) { - for (var property in query) - if (String(activeQuery[property]) !== String(query[property])) - return false; - - return true; -} +var _isListening = false; -function defaultTransitionErrorHandler(error) { - // Throw so we don't silently swallow async errors. - throw error; // This error probably originated in a transition hook. +function onHashChange() { + if (ensureSlash()) { + // If we don't have an _actionType then all we know is the hash + // changed. It was probably caused by the user clicking the Back + // button, but may have also been the Forward button or manual + // manipulation. So just guess 'pop'. + notifyChange(_actionType || LocationActions.POP); + _actionType = null; + } } /** - * 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. + * A Location that uses `window.location.hash`. */ -var Routes = React.createClass({ +var HashLocation = { - displayName: 'Routes', + addChangeListener: function (listener) { + _changeListeners.push(listener); - mixins: [ RouteContext, ActiveContext, LocationContext, ScrollContext ], + // Do this BEFORE listening for hashchange. + ensureSlash(); - propTypes: { - initialPath: React.PropTypes.string, - initialMatches: React.PropTypes.array, - onChange: React.PropTypes.func, - onError: React.PropTypes.func.isRequired - }, + if (_isListening) + return; - getDefaultProps: function () { - return { - initialPath: null, - initialMatches: [], - onError: defaultTransitionErrorHandler - }; - }, + if (window.addEventListener) { + window.addEventListener('hashchange', onHashChange, false); + } else { + window.attachEvent('onhashchange', onHashChange); + } - getInitialState: function () { - return { - path: this.props.initialPath, - matches: this.props.initialMatches - }; + _isListening = true; }, - componentDidMount: function () { - warning( - this._owner == null, - ' should be rendered directly using React.renderComponent, not ' + - 'inside some other component\'s render method' - ); - - this._handleStateChange(); + push: function (path) { + _actionType = LocationActions.PUSH; + window.location.hash = Path.encode(path); }, - componentDidUpdate: function () { - this._handleStateChange(); + replace: function (path) { + _actionType = LocationActions.REPLACE; + window.location.replace(window.location.pathname + '#' + Path.encode(path)); }, - /** - * 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) { - var routes = this.getRoutes(); - return findMatches(Path.withoutQuery(path), routes, this.props.defaultRoute, this.props.notFoundRoute); + pop: function () { + _actionType = LocationActions.POP; + window.history.back(); }, - updateLocation: function (path, actionType) { - if (this.state.path === path) - return; // Nothing to do! + getCurrentPath: getHashPath, - if (this.state.path) - this.recordScroll(this.state.path); + toString: function () { + return ''; + } - this.dispatch(path, function (error, abortReason, nextState) { - if (error) { - this.props.onError.call(this, error); - } else if (abortReason instanceof Redirect) { - this.replaceWith(abortReason.to, abortReason.params, abortReason.query); - } else if (abortReason) { - this.goBack(); - } else { - this._nextStateChangeHandler = this._finishTransitionTo.bind(this, path, actionType, this.state.matches); - this.setState(nextState); - } - }); - }, +}; - _handleStateChange: function () { - if (this._nextStateChangeHandler) { - this._nextStateChangeHandler(); - delete this._nextStateChangeHandler; - } - }, +module.exports = HashLocation; - _finishTransitionTo: function (path, actionType, previousMatches) { - var currentMatches = this.state.matches; - updateMatchComponents(currentMatches, this.refs); +},{"../actions/LocationActions":1,"../utils/Path":19,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],11:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; +var LocationActions = _dereq_('../actions/LocationActions'); +var Path = _dereq_('../utils/Path'); - if (shouldUpdateScroll(currentMatches, previousMatches)) - this.updateScroll(path, actionType); +/** + * Returns the current URL path from `window.location`, including query string + */ +function getWindowPath() { + invariant( + canUseDOM, + 'getWindowPath needs a DOM' + ); - if (this.props.onChange) - this.props.onChange.call(this); - }, + return Path.decode( + window.location.pathname + window.location.search + ); +} - /** - * Performs a transition to the given path and calls callback(error, abortReason, nextState) - * when the transition is finished. If there was an error, the first argument will not be null. - * Otherwise, if the transition was aborted for some reason, it will be given in the second arg. - * - * In a transition, the router first determines which routes are involved by 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 hook is invoked - * on all route handlers we're transitioning away from, in reverse nesting order. Likewise, the - * willTransitionTo hook is invoked on all route handlers we're transitioning to. - * - * Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the transition. - * To resolve asynchronously, they may use transition.wait(promise). If no hooks wait, the - * transition will be synchronous. - */ - dispatch: function (path, callback) { - var transition = new Transition(this, path); - var currentMatches = this.state ? this.state.matches : []; // No state server-side. - var nextMatches = this.match(path) || []; - - warning( - nextMatches.length, - 'No route matches path "%s". Make sure you have somewhere in your ', - path, path - ); +var _changeListeners = []; - var fromMatches, toMatches; - if (currentMatches.length) { - fromMatches = currentMatches.filter(function (match) { - return !hasMatch(nextMatches, match); - }); +function notifyChange(type) { + var change = { + path: getWindowPath(), + type: type + }; - toMatches = nextMatches.filter(function (match) { - return !hasMatch(currentMatches, match); - }); + _changeListeners.forEach(function (listener) { + listener(change); + }); +} + +var _isListening = false; + +function onPopState() { + notifyChange(LocationActions.POP); +} + +/** + * A Location that uses HTML5 history. + */ +var HistoryLocation = { + + addChangeListener: function (listener) { + _changeListeners.push(listener); + + if (_isListening) + return; + + if (window.addEventListener) { + window.addEventListener('popstate', onPopState, false); } else { - fromMatches = []; - toMatches = nextMatches; + window.attachEvent('popstate', onPopState); } - var callbackScope = this; - var query = Path.extractQuery(path) || {}; - - runTransitionFromHooks(fromMatches, transition, function (error) { - if (error || transition.isAborted) - return callback.call(callbackScope, error, transition.abortReason); + _isListening = true; + }, - runTransitionToHooks(toMatches, transition, query, function (error) { - if (error || transition.isAborted) - return callback.call(callbackScope, error, transition.abortReason); + push: function (path) { + window.history.pushState({ path: path }, '', Path.encode(path)); + notifyChange(LocationActions.PUSH); + }, - var matches = currentMatches.slice(0, currentMatches.length - fromMatches.length).concat(toMatches); - var rootMatch = getRootMatch(matches); - var params = (rootMatch && rootMatch.params) || {}; - var routes = matches.map(function (match) { - return match.route; - }); + replace: function (path) { + window.history.replaceState({ path: path }, '', Path.encode(path)); + notifyChange(LocationActions.REPLACE); + }, - callback.call(callbackScope, null, null, { - path: path, - matches: matches, - activeRoutes: routes, - activeParams: params, - activeQuery: query - }); - }); - }); + pop: function () { + window.history.back(); }, - /** - * Returns the props that should be used for the top-level route handler. - */ - getHandlerProps: function () { - var matches = this.state.matches; - var query = this.state.activeQuery; - var handler = returnNull; - var props = { - ref: null, - params: null, - query: null, - activeRouteHandler: handler, - key: null - }; + getCurrentPath: getWindowPath, - reversedArray(matches).forEach(function (match) { - var route = match.route; + toString: function () { + return ''; + } - props = Route.getUnreservedProps(route.props); +}; - props.ref = '__activeRoute__'; - props.params = match.params; - props.query = query; - props.activeRouteHandler = handler; +module.exports = HistoryLocation; - // TODO: Can we remove addHandlerKey? - if (route.props.addHandlerKey) - props.key = Path.injectParams(route.props.path, match.params); +},{"../actions/LocationActions":1,"../utils/Path":19,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],12:[function(_dereq_,module,exports){ +var HistoryLocation = _dereq_('./HistoryLocation'); +var Path = _dereq_('../utils/Path'); - handler = function (props, addedProps) { - if (arguments.length > 2 && typeof arguments[2] !== 'undefined') - throw new Error('Passing children to a route handler is not supported'); +/** + * 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 = { - return route.props.handler( - objectAssign(props, addedProps) - ); - }.bind(this, props); - }); + push: function (path) { + window.location = Path.encode(path); + }, - return props; + replace: function (path) { + window.location.replace(Path.encode(path)); }, - /** - * Returns a reference to the active route handler's component instance. - */ - getActiveComponent: function () { - return this.refs.__activeRoute__; + pop: function () { + window.history.back(); }, - /** - * Returns the current URL path. - */ - getCurrentPath: function () { - return this.state.path; + getCurrentPath: HistoryLocation.getCurrentPath, + + toString: function () { + return ''; + } + +}; + +module.exports = RefreshLocation; + +},{"../utils/Path":19,"./HistoryLocation":11}],13:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); + +var FakeNode = { + + render: function () { + invariant( + false, + '%s elements should not be rendered', + this.constructor.displayName + ); + } + +}; + +module.exports = FakeNode; + +},{"react/lib/invariant":39}],14:[function(_dereq_,module,exports){ +var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); + +/** + * A mixin for components that modify the URL. + * + * Example: + * + * var MyLink = React.createClass({ + * mixins: [ Router.Navigation ], + * handleClick: function (event) { + * event.preventDefault(); + * this.transitionTo('aRoute', { the: 'params' }, { the: 'query' }); + * }, + * render: function () { + * return ( + * Click me! + * ); + * } + * }); + */ +var Navigation = { + + contextTypes: { + makePath: React.PropTypes.func.isRequired, + makeHref: React.PropTypes.func.isRequired, + transitionTo: React.PropTypes.func.isRequired, + replaceWith: React.PropTypes.func.isRequired, + goBack: React.PropTypes.func.isRequired }, /** @@ -790,23 +655,7 @@ var Routes = React.createClass({ * name, URL parameters, and query values. */ makePath: function (to, params, query) { - var path; - if (Path.isAbsolute(to)) { - path = Path.normalize(to); - } else { - var namedRoutes = this.getNamedRoutes(); - var route = namedRoutes[to]; - - invariant( - route, - 'Unable to find a route named "%s". Make sure you have somewhere in your ', - to, to - ); - - path = route.props.path; - } - - return Path.withQuery(Path.injectParams(path, params), query); + return this.context.makePath(to, params, query); }, /** @@ -814,27 +663,15 @@ var Routes = React.createClass({ * link to the route with the given name. */ makeHref: function (to, params, query) { - var path = this.makePath(to, params, query); - - if (this.getLocation() === HashLocation) - return '#' + path; - - return path; + return this.context.makeHref(to, params, query); }, - /** + /** * Transitions to the URL specified in the arguments by pushing * a new URL onto the history stack. */ transitionTo: function (to, params, query) { - var location = this.getLocation(); - - invariant( - location, - 'You cannot use transitionTo without a location' - ); - - location.push(this.makePath(to, params, query)); + this.context.transitionTo(to, params, query); }, /** @@ -842,367 +679,118 @@ var Routes = React.createClass({ * the current URL in the history stack. */ replaceWith: function (to, params, query) { - var location = this.getLocation(); - - invariant( - location, - 'You cannot use replaceWith without a location' - ); - - location.replace(this.makePath(to, params, query)); + this.context.replaceWith(to, params, query); }, /** * Transitions to the previous URL. */ goBack: function () { - var location = this.getLocation(); - - invariant( - location, - 'You cannot use goBack without a location' - ); - - location.pop(); - }, - - /** - * Returns true if the given route, params, and query are active. - */ - isActive: function (to, params, query) { - if (Path.isAbsolute(to)) - return to === this.getCurrentPath(); + this.context.goBack(); + } - return routeIsActive(this.getActiveRoutes(), to) && - paramsAreActive(this.getActiveParams(), params) && - (query == null || queryIsActive(this.getActiveQuery(), query)); - }, +}; - render: function () { - var match = this.state.matches[0]; +module.exports = Navigation; - if (match == null) - return null; +},{}],15:[function(_dereq_,module,exports){ +var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); - return match.route.props.handler( - this.getHandlerProps() - ); - }, +/** + * Provides the router with context for Router.Navigation. + */ +var NavigationContext = { childContextTypes: { - currentPath: React.PropTypes.string, makePath: React.PropTypes.func.isRequired, makeHref: React.PropTypes.func.isRequired, transitionTo: React.PropTypes.func.isRequired, replaceWith: React.PropTypes.func.isRequired, - goBack: React.PropTypes.func.isRequired, - isActive: React.PropTypes.func.isRequired + goBack: React.PropTypes.func.isRequired }, getChildContext: function () { return { - currentPath: this.getCurrentPath(), - makePath: this.makePath, - makeHref: this.makeHref, - transitionTo: this.transitionTo, - replaceWith: this.replaceWith, - goBack: this.goBack, - isActive: this.isActive + makePath: this.constructor.makePath, + makeHref: this.constructor.makeHref, + transitionTo: this.constructor.transitionTo, + replaceWith: this.constructor.replaceWith, + goBack: this.constructor.goBack }; } -}); - -module.exports = Routes; - -},{"../locations/HashLocation":11,"../mixins/ActiveContext":14,"../mixins/LocationContext":17,"../mixins/RouteContext":19,"../mixins/ScrollContext":20,"../utils/Path":22,"../utils/Redirect":24,"../utils/Transition":26,"../utils/reversedArray":28,"./Route":8,"react/lib/Object.assign":43,"react/lib/invariant":69,"react/lib/warning":75}],10:[function(_dereq_,module,exports){ -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.CurrentPath = _dereq_('./mixins/CurrentPath'); -exports.Navigation = _dereq_('./mixins/Navigation'); - -exports.renderRoutesToString = _dereq_('./utils/ServerRendering').renderRoutesToString; -exports.renderRoutesToStaticMarkup = _dereq_('./utils/ServerRendering').renderRoutesToStaticMarkup; - -},{"./components/DefaultRoute":4,"./components/Link":5,"./components/NotFoundRoute":6,"./components/Redirect":7,"./components/Route":8,"./components/Routes":9,"./mixins/ActiveState":15,"./mixins/CurrentPath":16,"./mixins/Navigation":18,"./utils/ServerRendering":25}],11:[function(_dereq_,module,exports){ -var LocationActions = _dereq_('../actions/LocationActions'); -var getWindowPath = _dereq_('../utils/getWindowPath'); - -function getHashPath() { - return window.location.hash.substr(1); -} - -var _actionType; - -function ensureSlash() { - var path = getHashPath(); - - if (path.charAt(0) === '/') - return true; - - HashLocation.replace('/' + path); - - return false; -} - -var _onChange; +}; -function onHashChange() { - if (ensureSlash()) { - var path = getHashPath(); - - _onChange({ - // If we don't have an _actionType then all we know is the hash - // changed. It was probably caused by the user clicking the Back - // button, but may have also been the Forward button or manual - // manipulation. So just guess 'pop'. - type: _actionType || LocationActions.POP, - path: getHashPath() - }); +module.exports = NavigationContext; - _actionType = null; - } -} +},{}],16:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; +var getWindowScrollPosition = _dereq_('../utils/getWindowScrollPosition'); /** - * A Location that uses `window.location.hash`. + * Provides the router with the ability to manage window scroll position + * according to its scroll behavior. */ -var HashLocation = { +var Scrolling = { - setup: function (onChange) { - _onChange = onChange; + componentWillMount: function () { + invariant( + this.getScrollBehavior() == null || canUseDOM, + 'Cannot use scroll behavior without a DOM' + ); - // Do this BEFORE listening for hashchange. - ensureSlash(); + this._scrollHistory = {}; + }, - if (window.addEventListener) { - window.addEventListener('hashchange', onHashChange, false); - } else { - window.attachEvent('onhashchange', onHashChange); - } + componentDidMount: function () { + this._updateScroll(); }, - teardown: function () { - if (window.removeEventListener) { - window.removeEventListener('hashchange', onHashChange, false); - } else { - window.detachEvent('onhashchange', onHashChange); - } + componentWillUpdate: function () { + this._scrollHistory[this.state.path] = getWindowScrollPosition(); }, - push: function (path) { - _actionType = LocationActions.PUSH; - window.location.hash = path; + componentDidUpdate: function () { + this._updateScroll(); }, - replace: function (path) { - _actionType = LocationActions.REPLACE; - window.location.replace(getWindowPath() + '#' + path); + componentWillUnmount: function () { + delete this._scrollHistory; }, - pop: function () { - _actionType = LocationActions.POP; - window.history.back(); + /** + * Returns the last known scroll position for the given URL path. + */ + getScrollPosition: function (path) { + return this._scrollHistory[path] || null; }, - getCurrentPath: getHashPath, + _updateScroll: function () { + var scrollBehavior = this.getScrollBehavior(); - toString: function () { - return ''; - } - -}; - -module.exports = HashLocation; - -},{"../actions/LocationActions":1,"../utils/getWindowPath":27}],12:[function(_dereq_,module,exports){ -var LocationActions = _dereq_('../actions/LocationActions'); -var getWindowPath = _dereq_('../utils/getWindowPath'); - -var _onChange; - -function onPopState() { - _onChange({ - type: LocationActions.POP, - path: getWindowPath() - }); -} - -/** - * A Location that uses HTML5 history. - */ -var HistoryLocation = { - - setup: function (onChange) { - _onChange = onChange; - - if (window.addEventListener) { - window.addEventListener('popstate', onPopState, false); - } else { - window.attachEvent('popstate', onPopState); - } - }, - - teardown: function () { - if (window.removeEventListener) { - window.removeEventListener('popstate', onPopState, false); - } else { - window.detachEvent('popstate', onPopState); - } - }, - - push: function (path) { - window.history.pushState({ path: path }, '', path); - - _onChange({ - type: LocationActions.PUSH, - path: getWindowPath() - }); - }, - - replace: function (path) { - window.history.replaceState({ path: path }, '', path); - - _onChange({ - type: LocationActions.REPLACE, - path: getWindowPath() - }); - }, - - pop: function () { - window.history.back(); - }, - - getCurrentPath: getWindowPath, - - toString: function () { - return ''; - } - -}; - -module.exports = HistoryLocation; - -},{"../actions/LocationActions":1,"../utils/getWindowPath":27}],13:[function(_dereq_,module,exports){ -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 = { - - 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":27}],14:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var objectAssign = _dereq_('react/lib/Object.assign'); - -/** - * A mixin for components that store the active state of routes, - * URL parameters, and query. - */ -var ActiveContext = { - - propTypes: { - initialActiveRoutes: React.PropTypes.array.isRequired, - initialActiveParams: React.PropTypes.object.isRequired, - initialActiveQuery: React.PropTypes.object.isRequired - }, - - getDefaultProps: function () { - return { - initialActiveRoutes: [], - initialActiveParams: {}, - initialActiveQuery: {} - }; - }, - - getInitialState: function () { - return { - activeRoutes: this.props.initialActiveRoutes, - activeParams: this.props.initialActiveParams, - activeQuery: this.props.initialActiveQuery - }; - }, - - /** - * Returns a read-only array of the currently active routes. - */ - getActiveRoutes: function () { - return this.state.activeRoutes.slice(0); - }, - - /** - * Returns a read-only object of the currently active URL parameters. - */ - getActiveParams: function () { - return objectAssign({}, this.state.activeParams); - }, - - /** - * Returns a read-only object of the currently active query parameters. - */ - getActiveQuery: function () { - return objectAssign({}, this.state.activeQuery); - }, - - childContextTypes: { - activeRoutes: React.PropTypes.array.isRequired, - activeParams: React.PropTypes.object.isRequired, - activeQuery: React.PropTypes.object.isRequired - }, - - getChildContext: function () { - return { - activeRoutes: this.getActiveRoutes(), - activeParams: this.getActiveParams(), - activeQuery: this.getActiveQuery() - }; + if (scrollBehavior) + scrollBehavior.updateScrollPosition( + this.getScrollPosition(this.state.path), + this.state.action + ); } }; -module.exports = ActiveContext; +module.exports = Scrolling; -},{"react/lib/Object.assign":43}],15:[function(_dereq_,module,exports){ +},{"../utils/getWindowScrollPosition":26,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],17:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); /** - * A mixin for components that need to know the routes, URL + * A mixin for components that need to know the path, routes, URL * params and query that are currently active. * * Example: * * var AboutLink = React.createClass({ - * mixins: [ Router.ActiveState ], + * mixins: [ Router.State ], * render: function () { * var className = this.props.className; * @@ -1213,34 +801,42 @@ var React = (typeof window !== "undefined" ? window.React : typeof global !== "u * } * }); */ -var ActiveState = { +var State = { contextTypes: { - activeRoutes: React.PropTypes.array.isRequired, - activeParams: React.PropTypes.object.isRequired, - activeQuery: React.PropTypes.object.isRequired, + getCurrentPath: React.PropTypes.func.isRequired, + getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentParams: React.PropTypes.func.isRequired, + getCurrentQuery: React.PropTypes.func.isRequired, isActive: React.PropTypes.func.isRequired }, + /** + * Returns the current URL path. + */ + getPath: function () { + return this.context.getCurrentPath(); + }, + /** * Returns an array of the routes that are currently active. */ - getActiveRoutes: function () { - return this.context.activeRoutes; + getRoutes: function () { + return this.context.getCurrentRoutes(); }, /** * Returns an object of the URL params that are currently active. */ - getActiveParams: function () { - return this.context.activeParams; + getParams: function () { + return this.context.getCurrentParams(); }, /** * Returns an object of the query params that are currently active. */ - getActiveQuery: function () { - return this.context.activeQuery; + getQuery: function () { + return this.context.getCurrentQuery(); }, /** @@ -1253,5023 +849,1508 @@ var ActiveState = { }; -module.exports = ActiveState; +module.exports = State; -},{}],16:[function(_dereq_,module,exports){ +},{}],18:[function(_dereq_,module,exports){ var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); +var assign = _dereq_('react/lib/Object.assign'); +var Path = _dereq_('../utils/Path'); -/** - * A mixin for components that need to know the current URL path. - * - * Example: - * - * var ShowThePath = React.createClass({ - * mixins: [ Router.CurrentPath ], - * render: function () { - * return ( - *
The current path is: {this.getCurrentPath()}
- * ); - * } - * }); - */ -var CurrentPath = { - - contextTypes: { - currentPath: React.PropTypes.string.isRequired - }, - - /** - * Returns the current URL path. - */ - getCurrentPath: function () { - return this.context.currentPath; - } +function routeIsActive(activeRoutes, routeName) { + return activeRoutes.some(function (route) { + return route.name === routeName; + }); +} -}; +function paramsAreActive(activeParams, params) { + for (var property in params) + if (String(activeParams[property]) !== String(params[property])) + return false; -module.exports = CurrentPath; + return true; +} -},{}],17:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var invariant = _dereq_('react/lib/invariant'); -var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; -var HashLocation = _dereq_('../locations/HashLocation'); -var HistoryLocation = _dereq_('../locations/HistoryLocation'); -var RefreshLocation = _dereq_('../locations/RefreshLocation'); -var PathStore = _dereq_('../stores/PathStore'); -var supportsHistory = _dereq_('../utils/supportsHistory'); +function queryIsActive(activeQuery, query) { + for (var property in query) + if (String(activeQuery[property]) !== String(query[property])) + return false; -/** - * A hash of { name: location } pairs. - */ -var NAMED_LOCATIONS = { - none: null, - hash: HashLocation, - history: HistoryLocation, - refresh: RefreshLocation -}; + return true; +} /** - * A mixin for components that manage location. + * Provides the router with context for Router.State. */ -var LocationContext = { - - propTypes: { - 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); - } - }, +var StateContext = { - getDefaultProps: function () { - return { - location: canUseDOM ? HashLocation : null - }; + /** + * Returns the current URL path + query string. + */ + getCurrentPath: function () { + return this.state.path; }, - componentWillMount: function () { - var location = this.getLocation(); - - invariant( - location == null || canUseDOM, - 'Cannot use location without a DOM' - ); - - if (location) { - PathStore.setup(location); - PathStore.addChangeListener(this.handlePathChange); - - if (this.updateLocation) - this.updateLocation(PathStore.getCurrentPath(), PathStore.getCurrentActionType()); - } + /** + * Returns a read-only array of the currently active routes. + */ + getCurrentRoutes: function () { + return this.state.routes.slice(0); }, - componentWillUnmount: function () { - if (this.getLocation()) - PathStore.removeChangeListener(this.handlePathChange); + /** + * Returns a read-only object of the currently active URL parameters. + */ + getCurrentParams: function () { + return assign({}, this.state.params); }, - handlePathChange: function () { - if (this.updateLocation) - this.updateLocation(PathStore.getCurrentPath(), PathStore.getCurrentActionType()); + /** + * Returns a read-only object of the currently active query parameters. + */ + getCurrentQuery: function () { + return assign({}, this.state.query); }, /** - * Returns the location object this component uses. + * Returns true if the given route, params, and query are active. */ - getLocation: function () { - if (this._location == null) { - var location = this.props.location; - - if (typeof location === 'string') - location = NAMED_LOCATIONS[location]; - - // Automatically fall back to full page refreshes in - // browsers that do not support HTML5 history. - if (location === HistoryLocation && !supportsHistory()) - location = RefreshLocation; - - this._location = location; - } + isActive: function (to, params, query) { + if (Path.isAbsolute(to)) + return to === this.state.path; - return this._location; + return routeIsActive(this.state.routes, to) && + paramsAreActive(this.state.params, params) && + (query == null || queryIsActive(this.state.query, query)); }, childContextTypes: { - location: React.PropTypes.object // Not required on the server. + getCurrentPath: React.PropTypes.func.isRequired, + getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentParams: React.PropTypes.func.isRequired, + getCurrentQuery: React.PropTypes.func.isRequired, + isActive: React.PropTypes.func.isRequired }, getChildContext: function () { return { - location: this.getLocation() + getCurrentPath: this.getCurrentPath, + getCurrentRoutes: this.getCurrentRoutes, + getCurrentParams: this.getCurrentParams, + getCurrentQuery: this.getCurrentQuery, + isActive: this.isActive }; } }; -module.exports = LocationContext; +module.exports = StateContext; -},{"../locations/HashLocation":11,"../locations/HistoryLocation":12,"../locations/RefreshLocation":13,"../stores/PathStore":21,"../utils/supportsHistory":29,"react/lib/ExecutionEnvironment":42,"react/lib/invariant":69}],18:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); +},{"../utils/Path":19,"react/lib/Object.assign":36}],19:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var merge = _dereq_('qs/lib/utils').merge; +var qs = _dereq_('qs'); -/** - * A mixin for components that modify the URL. - */ -var Navigation = { +function decodePathSegment(string) { + return decodeURIComponent(string.replace(/\+/g, ' ')); +} - contextTypes: { - makePath: React.PropTypes.func.isRequired, - makeHref: React.PropTypes.func.isRequired, - transitionTo: React.PropTypes.func.isRequired, - replaceWith: React.PropTypes.func.isRequired, - goBack: React.PropTypes.func.isRequired - }, +function encodePathSegment(string) { + return encodeURIComponent(string).replace(/%20/g, '+'); +} - /** - * Returns an absolute URL path created from the given route - * name, URL parameters, and query values. - */ - makePath: function (to, params, query) { - return this.context.makePath(to, params, query); - }, +var paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; +var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g; +var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?/g; +var queryMatcher = /\?(.+)/; - /** - * Returns a string that may safely be used as the href of a - * link to the route with the given name. - */ - makeHref: function (to, params, query) { - return this.context.makeHref(to, params, query); - }, +var _compiledPatterns = {}; - /** - * Transitions to the URL specified in the arguments by pushing - * a new URL onto the history stack. - */ - transitionTo: function (to, params, query) { - this.context.transitionTo(to, params, query); - }, - - /** - * Transitions to the URL specified in the arguments by replacing - * the current URL in the history stack. - */ - replaceWith: function (to, params, query) { - this.context.replaceWith(to, params, query); - }, - - /** - * Transitions to the previous URL. - */ - goBack: function () { - this.context.goBack(); - } - -}; - -module.exports = Navigation; - -},{}],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 Path = _dereq_('../utils/Path'); - -/** - * Performs some normalization and validation on a component and - * all of its children. - */ -function processRoute(route, container, namedRoutes) { - // Note: parentRoute may be a _or_ a . - var props = route.props; - - // TODO: use isValidElement when we update everything for React 0.12 - //invariant( - //React.isValidClass(props.handler), - //'The handler for the "%s" route must be a valid React class', - //props.name || props.path - //); - - var parentPath = (container && container.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 (container && Array.isArray(container.props.paramNames)) { - container.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, container.props.path - ); +function compilePattern(pattern) { + if (!(pattern in _compiledPatterns)) { + var paramNames = []; + var source = pattern.replace(paramCompileMatcher, function (match, paramName) { + if (paramName) { + paramNames.push(paramName); + return '([^/?#]+)'; + } else if (match === '*') { + paramNames.push('splat'); + return '(.*?)'; + } else { + return '\\' + match; + } }); - } - - // 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; - } - - // Handle . - if (props.catchAll) { - invariant( - container, - ' must have a parent ' - ); - - invariant( - container.props.notFoundRoute == null, - 'You may not have more than one per ' - ); - - container.props.notFoundRoute = route; - - return null; - } - - // Handle . - if (props.isDefault) { - invariant( - container, - ' must have a parent ' - ); - - invariant( - container.props.defaultRoute == null, - 'You may not have more than one per ' - ); - - container.props.defaultRoute = route; - return null; + _compiledPatterns[pattern] = { + matcher: new RegExp('^' + source + '$', 'i'), + paramNames: paramNames + }; } - // Make sure children is an array. - props.children = processRoutes(props.children, route, namedRoutes); - - return route; -} - -/** - * Processes many children s at once, always returning an array. - */ -function processRoutes(children, container, namedRoutes) { - var routes = []; - - React.Children.forEach(children, function (child) { - // Exclude s and s. - if (child = processRoute(child, container, namedRoutes)) - routes.push(child); - }); - - return routes; + return _compiledPatterns[pattern]; } -/** - * A mixin for components that have children. - */ -var RouteContext = { - - _processRoutes: function () { - this._namedRoutes = {}; - this._routes = processRoutes(this.props.children, this, this._namedRoutes); - }, +var Path = { /** - * Returns an array of s in this container. + * Safely decodes special characters in the given URL path. */ - getRoutes: function () { - if (this._routes == null) - this._processRoutes(); - - return this._routes; + decode: function decodePath(path) { + return String(path).split('/').map(decodePathSegment).join('/'); }, /** - * Returns a hash { name: route } of all named s in this container. + * Safely encodes special characters in the given URL path. */ - getNamedRoutes: function () { - if (this._namedRoutes == null) - this._processRoutes(); - - return this._namedRoutes; + encode: function encodePath(path) { + return String(path).split('/').map(encodePathSegment).join('/'); }, /** - * Returns the route with the given name. + * Returns an array of the names of all parameters in the given pattern. */ - getRouteByName: function (routeName) { - var namedRoutes = this.getNamedRoutes(); - return namedRoutes[routeName] || null; + extractParamNames: function (pattern) { + return compilePattern(pattern).paramNames; }, - childContextTypes: { - routes: React.PropTypes.array.isRequired, - namedRoutes: React.PropTypes.object.isRequired - }, + /** + * 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 = path.match(object.matcher); - getChildContext: function () { - return { - routes: this.getRoutes(), - namedRoutes: this.getNamedRoutes(), - }; - } + if (!match) + return null; -}; + var params = {}; -module.exports = RouteContext; + object.paramNames.forEach(function (paramName, index) { + params[paramName] = match[index + 1]; + }); -},{"../utils/Path":22,"react/lib/invariant":69}],20:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var invariant = _dereq_('react/lib/invariant'); -var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; -var ImitateBrowserBehavior = _dereq_('../behaviors/ImitateBrowserBehavior'); -var ScrollToTopBehavior = _dereq_('../behaviors/ScrollToTopBehavior'); + return params; + }, -function getWindowScrollPosition() { - invariant( - canUseDOM, - 'Cannot get current scroll position without a DOM' - ); + /** + * 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 || {}; - return { - x: window.scrollX, - y: window.scrollY - }; -} + var splatIndex = 0; -/** - * A hash of { name: scrollBehavior } pairs. - */ -var NAMED_SCROLL_BEHAVIORS = { - none: null, - browser: ImitateBrowserBehavior, - imitateBrowser: ImitateBrowserBehavior, - scrollToTop: ScrollToTopBehavior -}; + return pattern.replace(paramInjectMatcher, function (match, paramName) { + paramName = paramName || 'splat'; -/** - * A mixin for components that manage scroll position. - */ -var ScrollContext = { + // If param is optional don't check for existence + if (paramName.slice(-1) !== '?') { + invariant( + params[paramName] != null, + 'Missing "' + paramName + '" parameter for path "' + pattern + '"' + ); + } else { + paramName = paramName.slice(0, -1); - propTypes: { - scrollBehavior: function (props, propName, componentName) { - var behavior = props[propName]; + if (params[paramName] == null) + return ''; + } - if (typeof behavior === 'string' && !(behavior in NAMED_SCROLL_BEHAVIORS)) - return new Error('Unknown scroll behavior "' + behavior + '", see ' + componentName); - } - }, + var segment; + if (paramName === 'splat' && Array.isArray(params[paramName])) { + segment = params[paramName][splatIndex++]; - getDefaultProps: function () { - return { - scrollBehavior: canUseDOM ? ImitateBrowserBehavior : null - }; - }, + invariant( + segment != null, + 'Missing splat # ' + splatIndex + ' for path "' + pattern + '"' + ); + } else { + segment = params[paramName]; + } - componentWillMount: function () { - invariant( - this.getScrollBehavior() == null || canUseDOM, - 'Cannot use scroll behavior without a DOM' - ); + return segment; + }).replace(paramInjectTrailingSlashMatcher, '/'); }, - recordScroll: function (path) { - var positions = this.getScrollPositions(); - positions[path] = getWindowScrollPosition(); + /** + * 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 = path.match(queryMatcher); + return match && qs.parse(match[1]); }, - updateScroll: function (path, actionType) { - var behavior = this.getScrollBehavior(); - var position = this.getScrollPosition(path) || null; - - if (behavior) - behavior.updateScrollPosition(position, actionType); + /** + * Returns a version of the given path without the query string. + */ + withoutQuery: function (path) { + return path.replace(queryMatcher, ''); }, /** - * Returns the scroll behavior object this component uses. + * Returns a version of the given path with the parameters in the given + * query merged into the query string. */ - getScrollBehavior: function () { - if (this._scrollBehavior == null) { - var behavior = this.props.scrollBehavior; + withQuery: function (path, query) { + var existingQuery = Path.extractQuery(path); - if (typeof behavior === 'string') - behavior = NAMED_SCROLL_BEHAVIORS[behavior]; + if (existingQuery) + query = query ? merge(existingQuery, query) : existingQuery; - this._scrollBehavior = behavior; - } + var queryString = query && qs.stringify(query); + + if (queryString) + return Path.withoutQuery(path) + '?' + queryString; - return this._scrollBehavior; + return path; }, /** - * Returns a hash of URL paths to their last known scroll positions. + * Returns true if the given path is absolute. */ - getScrollPositions: function () { - if (this._scrollPositions == null) - this._scrollPositions = {}; - - return this._scrollPositions; + isAbsolute: function (path) { + return path.charAt(0) === '/'; }, /** - * Returns the last known scroll position for the given URL path. + * Returns a normalized version of the given path. */ - getScrollPosition: function (path) { - var positions = this.getScrollPositions(); - return positions[path]; - }, - - childContextTypes: { - scrollBehavior: React.PropTypes.object // Not required on the server. + normalize: function (path, parentRoute) { + return path.replace(/^\/*/, '/'); }, - getChildContext: function () { - return { - scrollBehavior: this.getScrollBehavior() - }; + /** + * Joins two URL paths together. + */ + join: function (a, b) { + return a.replace(/\/*$/, '/') + b; } }; -module.exports = ScrollContext; +module.exports = Path; -},{"../behaviors/ImitateBrowserBehavior":2,"../behaviors/ScrollToTopBehavior":3,"react/lib/ExecutionEnvironment":42,"react/lib/invariant":69}],21:[function(_dereq_,module,exports){ -var invariant = _dereq_('react/lib/invariant'); -var EventEmitter = _dereq_('events').EventEmitter; -var LocationActions = _dereq_('../actions/LocationActions'); +},{"qs":30,"qs/lib/utils":34,"react/lib/invariant":39}],20:[function(_dereq_,module,exports){ +var Promise = _dereq_('when/lib/Promise'); -var CHANGE_EVENT = 'change'; -var _events = new EventEmitter; +// TODO: Use process.env.NODE_ENV check + envify to enable +// when's promise monitor here when in dev. -function notifyChange() { - _events.emit(CHANGE_EVENT); -} - -var _currentLocation, _currentActionType; -var _currentPath = '/'; - -function handleLocationChangeAction(action) { - if (_currentPath !== action.path) { - _currentPath = action.path; - _currentActionType = action.type; - notifyChange(); - } -} - -/** - * The PathStore keeps track of the current URL path. - */ -var PathStore = { - - addChangeListener: function (listener) { - _events.addListener(CHANGE_EVENT, listener); - }, - - removeChangeListener: function (listener) { - _events.removeListener(CHANGE_EVENT, listener); - }, - - removeAllChangeListeners: function () { - _events.removeAllListeners(CHANGE_EVENT); - }, - - /** - * Setup the PathStore to use the given location. - */ - setup: function (location) { - invariant( - _currentLocation == null || _currentLocation === location, - 'You cannot use %s and %s on the same page', - _currentLocation, location - ); - - if (_currentLocation !== location) { - if (location.setup) - location.setup(handleLocationChangeAction); - - _currentPath = location.getCurrentPath(); - } - - _currentLocation = location; - }, - - /** - * Tear down the PathStore. Really only used for testing. - */ - teardown: function () { - if (_currentLocation && _currentLocation.teardown) - _currentLocation.teardown(); - - _currentLocation = _currentActionType = null; - _currentPath = '/'; - - PathStore.removeAllChangeListeners(); - }, - - /** - * Returns the current URL path. - */ - getCurrentPath: function () { - return _currentPath; - }, - - /** - * Returns the type of the action that changed the URL. - */ - getCurrentActionType: function () { - return _currentActionType; - } - -}; - -module.exports = PathStore; - -},{"../actions/LocationActions":1,"events":31,"react/lib/invariant":69}],22:[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 paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; -var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g; -var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?/g; -var queryMatcher = /\?(.+)/; - -var _compiledPatterns = {}; - -function compilePattern(pattern) { - if (!(pattern in _compiledPatterns)) { - var paramNames = []; - var source = pattern.replace(paramCompileMatcher, 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(paramInjectMatcher, function (match, paramName) { - paramName = paramName || 'splat'; - - // If param is optional don't check for existence - if (paramName.slice(-1) !== '?') { - invariant( - params[paramName] != null, - 'Missing "' + paramName + '" parameter for path "' + pattern + '"' - ); - } else { - paramName = paramName.slice(0, -1) - if (params[paramName] == null) { - return ''; - } - } - - 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); - }).replace(paramInjectTrailingSlashMatcher, '/'); - }, - - /** - * 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 = 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":32,"qs/lib/utils":36,"react/lib/invariant":69}],23:[function(_dereq_,module,exports){ -var Promise = _dereq_('when/lib/Promise'); - -// TODO: Use process.env.NODE_ENV check + envify to enable -// when's promise monitor here when in dev. - -module.exports = Promise; - -},{"when/lib/Promise":76}],24:[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; - -},{}],25:[function(_dereq_,module,exports){ -var ReactElement = _dereq_('react/lib/ReactElement'); -var ReactInstanceHandles = _dereq_('react/lib/ReactInstanceHandles'); -var ReactMarkupChecksum = _dereq_('react/lib/ReactMarkupChecksum'); -var ReactServerRenderingTransaction = _dereq_('react/lib/ReactServerRenderingTransaction'); - -var cloneWithProps = _dereq_('react/lib/cloneWithProps'); -var objectAssign = _dereq_('react/lib/Object.assign'); -var instantiateReactComponent = _dereq_('react/lib/instantiateReactComponent'); -var invariant = _dereq_('react/lib/invariant'); - -function cloneRoutesForServerRendering(routes) { - return cloneWithProps(routes, { - location: 'none', - scrollBehavior: 'none' - }); -} - -function mergeStateIntoInitialProps(state, props) { - objectAssign(props, { - initialPath: state.path, - initialMatches: state.matches, - initialActiveRoutes: state.activeRoutes, - initialActiveParams: state.activeParams, - initialActiveQuery: state.activeQuery - }); -} - -/** - * Renders a component to a string of HTML at the given URL - * path and calls callback(error, abortReason, html) when finished. - * - * If there was an error during the transition, it is passed to the - * callback. Otherwise, if the transition was aborted for some reason, - * it is given in the abortReason argument (with the exception of - * internal redirects which are transparently handled for you). - * - * TODO: should be handled specially so servers know - * to use a 404 status code. - */ -function renderRoutesToString(routes, path, callback) { - invariant( - ReactElement.isValidElement(routes), - 'You must pass a valid ReactComponent to renderRoutesToString' - ); - - var component = instantiateReactComponent( - cloneRoutesForServerRendering(routes) - ); - - component.dispatch(path, function (error, abortReason, nextState) { - if (error || abortReason) - return callback(error, abortReason); - - mergeStateIntoInitialProps(nextState, component.props); - - var transaction; - try { - var id = ReactInstanceHandles.createReactRootID(); - transaction = ReactServerRenderingTransaction.getPooled(false); - - transaction.perform(function () { - var markup = component.mountComponent(id, transaction, 0); - callback(null, null, ReactMarkupChecksum.addChecksumToMarkup(markup)); - }, null); - } finally { - ReactServerRenderingTransaction.release(transaction); - } - }); -} - -/** - * Renders a component to static markup at the given URL - * path and calls callback(error, abortReason, markup) when finished. - */ -function renderRoutesToStaticMarkup(routes, path, callback) { - invariant( - ReactElement.isValidElement(routes), - 'You must pass a valid ReactComponent to renderRoutesToStaticMarkup' - ); - - var component = instantiateReactComponent( - cloneRoutesForServerRendering(routes) - ); - - component.dispatch(path, function (error, abortReason, nextState) { - if (error || abortReason) - return callback(error, abortReason); - - mergeStateIntoInitialProps(nextState, component.props); - - var transaction; - try { - var id = ReactInstanceHandles.createReactRootID(); - transaction = ReactServerRenderingTransaction.getPooled(false); - - transaction.perform(function () { - callback(null, null, component.mountComponent(id, transaction, 0)); - }, null); - } finally { - ReactServerRenderingTransaction.release(transaction); - } - }); -} - -module.exports = { - renderRoutesToString: renderRoutesToString, - renderRoutesToStaticMarkup: renderRoutesToStaticMarkup -}; - -},{"react/lib/Object.assign":43,"react/lib/ReactElement":48,"react/lib/ReactInstanceHandles":51,"react/lib/ReactMarkupChecksum":53,"react/lib/ReactServerRenderingTransaction":58,"react/lib/cloneWithProps":63,"react/lib/instantiateReactComponent":68,"react/lib/invariant":69}],26:[function(_dereq_,module,exports){ -var Promise = _dereq_('./Promise'); -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(routesComponent, path) { - this.routesComponent = routesComponent; - this.path = path; - this.abortReason = null; - this.isAborted = false; -} - -Transition.prototype.abort = function (reason) { - this.abortReason = reason; - this.isAborted = true; -}; - -Transition.prototype.redirect = function (to, params, query) { - this.abort(new Redirect(to, params, query)); -}; - -Transition.prototype.wait = function (value) { - this.promise = Promise.resolve(value); -}; - -Transition.prototype.retry = function () { - this.routesComponent.replaceWith(this.path); -}; - -module.exports = Transition; - -},{"./Promise":23,"./Redirect":24}],27:[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; - -},{}],28:[function(_dereq_,module,exports){ -function reversedArray(array) { - return array.slice(0).reverse(); -} - -module.exports = reversedArray; - -},{}],29:[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; - -},{}],30:[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; - -},{}],31:[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; -} - -},{}],32:[function(_dereq_,module,exports){ -module.exports = _dereq_('./lib'); - -},{"./lib":33}],33:[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":34,"./stringify":35}],34:[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":36}],35:[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":36}],36:[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; - } -}; - -},{}],37:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 CallbackQueue - */ - -"use strict"; - -var PooledClass = _dereq_("./PooledClass"); - -var assign = _dereq_("./Object.assign"); -var invariant = _dereq_("./invariant"); - -/** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. - * - * @class ReactMountReady - * @implements PooledClass - * @internal - */ -function CallbackQueue() { - this._callbacks = null; - this._contexts = null; -} - -assign(CallbackQueue.prototype, { - - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - enqueue: function(callback, context) { - this._callbacks = this._callbacks || []; - this._contexts = this._contexts || []; - this._callbacks.push(callback); - this._contexts.push(context); - }, - - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - notifyAll: function() { - var callbacks = this._callbacks; - var contexts = this._contexts; - if (callbacks) { - ("production" !== "production" ? invariant( - callbacks.length === contexts.length, - "Mismatched list of contexts in callback queue" - ) : invariant(callbacks.length === contexts.length)); - this._callbacks = null; - this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { - callbacks[i].call(contexts[i]); - } - callbacks.length = 0; - contexts.length = 0; - } - }, - - /** - * Resets the internal queue. - * - * @internal - */ - reset: function() { - this._callbacks = null; - this._contexts = null; - }, - - /** - * `PooledClass` looks for this. - */ - destructor: function() { - this.reset(); - } - -}); - -PooledClass.addPoolingTo(CallbackQueue); - -module.exports = CallbackQueue; - -},{"./Object.assign":43,"./PooledClass":44,"./invariant":69}],38:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 EventConstants - */ - -"use strict"; - -var keyMirror = _dereq_("./keyMirror"); - -var PropagationPhases = keyMirror({bubbled: null, captured: null}); - -/** - * Types of raw signals from the browser caught at the top level. - */ -var topLevelTypes = keyMirror({ - topBlur: null, - topChange: null, - topClick: null, - topCompositionEnd: null, - topCompositionStart: null, - topCompositionUpdate: null, - topContextMenu: null, - topCopy: null, - topCut: null, - topDoubleClick: null, - topDrag: null, - topDragEnd: null, - topDragEnter: null, - topDragExit: null, - topDragLeave: null, - topDragOver: null, - topDragStart: null, - topDrop: null, - topError: null, - topFocus: null, - topInput: null, - topKeyDown: null, - topKeyPress: null, - topKeyUp: null, - topLoad: null, - topMouseDown: null, - topMouseMove: null, - topMouseOut: null, - topMouseOver: null, - topMouseUp: null, - topPaste: null, - topReset: null, - topScroll: null, - topSelectionChange: null, - topSubmit: null, - topTextInput: null, - topTouchCancel: null, - topTouchEnd: null, - topTouchMove: null, - topTouchStart: null, - topWheel: null -}); - -var EventConstants = { - topLevelTypes: topLevelTypes, - PropagationPhases: PropagationPhases -}; - -module.exports = EventConstants; - -},{"./keyMirror":72}],39:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 EventPluginHub - */ - -"use strict"; - -var EventPluginRegistry = _dereq_("./EventPluginRegistry"); -var EventPluginUtils = _dereq_("./EventPluginUtils"); - -var accumulateInto = _dereq_("./accumulateInto"); -var forEachAccumulated = _dereq_("./forEachAccumulated"); -var invariant = _dereq_("./invariant"); - -/** - * Internal store for event listeners - */ -var listenerBank = {}; - -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ -var eventQueue = null; - -/** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private - */ -var executeDispatchesAndRelease = function(event) { - if (event) { - var executeDispatch = EventPluginUtils.executeDispatch; - // Plugins can provide custom behavior when dispatching events. - var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event); - if (PluginModule && PluginModule.executeDispatch) { - executeDispatch = PluginModule.executeDispatch; - } - EventPluginUtils.executeDispatchesInOrder(event, executeDispatch); - - if (!event.isPersistent()) { - event.constructor.release(event); - } - } -}; - -/** - * - `InstanceHandle`: [required] Module that performs logical traversals of DOM - * hierarchy given ids of the logical DOM elements involved. - */ -var InstanceHandle = null; - -function validateInstanceHandle() { - var invalid = !InstanceHandle|| - !InstanceHandle.traverseTwoPhase || - !InstanceHandle.traverseEnterLeave; - if (invalid) { - throw new Error('InstanceHandle not injected before use!'); - } -} - -/** - * This is a unified interface for event plugins to be installed and configured. - * - * Event plugins can implement the following properties: - * - * `extractEvents` {function(string, DOMEventTarget, string, object): *} - * Required. When a top-level event is fired, this method is expected to - * extract synthetic events that will in turn be queued and dispatched. - * - * `eventTypes` {object} - * Optional, plugins that fire events must publish a mapping of registration - * names that are used to register listeners. Values of this mapping must - * be objects that contain `registrationName` or `phasedRegistrationNames`. - * - * `executeDispatch` {function(object, function, string)} - * Optional, allows plugins to override how an event gets dispatched. By - * default, the listener is simply invoked. - * - * Each plugin that is injected into `EventsPluginHub` is immediately operable. - * - * @public - */ -var EventPluginHub = { - - /** - * Methods for injecting dependencies. - */ - injection: { - - /** - * @param {object} InjectedMount - * @public - */ - injectMount: EventPluginUtils.injection.injectMount, - - /** - * @param {object} InjectedInstanceHandle - * @public - */ - injectInstanceHandle: function(InjectedInstanceHandle) { - InstanceHandle = InjectedInstanceHandle; - if ("production" !== "production") { - validateInstanceHandle(); - } - }, - - getInstanceHandle: function() { - if ("production" !== "production") { - validateInstanceHandle(); - } - return InstanceHandle; - }, - - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, - - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName - - }, - - eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs, - - registrationNameModules: EventPluginRegistry.registrationNameModules, - - /** - * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {?function} listener The callback to store. - */ - putListener: function(id, registrationName, listener) { - ("production" !== "production" ? invariant( - !listener || typeof listener === 'function', - 'Expected %s listener to be a function, instead got type %s', - registrationName, typeof listener - ) : invariant(!listener || typeof listener === 'function')); - - var bankForRegistrationName = - listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[id] = listener; - }, - - /** - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - getListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - return bankForRegistrationName && bankForRegistrationName[id]; - }, - - /** - * Deletes a listener from the registration bank. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - */ - deleteListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - if (bankForRegistrationName) { - delete bankForRegistrationName[id]; - } - }, - - /** - * Deletes all listeners for the DOM element with the supplied ID. - * - * @param {string} id ID of the DOM element. - */ - deleteAllListeners: function(id) { - for (var registrationName in listenerBank) { - delete listenerBank[registrationName][id]; - } - }, - - /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @internal - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var events; - var plugins = EventPluginRegistry.plugins; - for (var i = 0, l = plugins.length; i < l; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ); - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); - } - } - } - return events; - }, - - /** - * Enqueues a synthetic event that should be dispatched when - * `processEventQueue` is invoked. - * - * @param {*} events An accumulation of synthetic events. - * @internal - */ - enqueueEvents: function(events) { - if (events) { - eventQueue = accumulateInto(eventQueue, events); - } - }, - - /** - * Dispatches all synthetic events on the event queue. - * - * @internal - */ - processEventQueue: function() { - // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. - var processingEventQueue = eventQueue; - eventQueue = null; - forEachAccumulated(processingEventQueue, executeDispatchesAndRelease); - ("production" !== "production" ? invariant( - !eventQueue, - 'processEventQueue(): Additional events were enqueued while processing ' + - 'an event queue. Support for this has not yet been implemented.' - ) : invariant(!eventQueue)); - }, - - /** - * These are needed for tests only. Do not use! - */ - __purge: function() { - listenerBank = {}; - }, - - __getListenerBank: function() { - return listenerBank; - } - -}; - -module.exports = EventPluginHub; - -},{"./EventPluginRegistry":40,"./EventPluginUtils":41,"./accumulateInto":61,"./forEachAccumulated":66,"./invariant":69}],40:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 EventPluginRegistry - * @typechecks static-only - */ - -"use strict"; - -var invariant = _dereq_("./invariant"); - -/** - * Injectable ordering of event plugins. - */ -var EventPluginOrder = null; - -/** - * Injectable mapping from names to event plugin modules. - */ -var namesToPlugins = {}; - -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ -function recomputePluginOrdering() { - if (!EventPluginOrder) { - // Wait until an `EventPluginOrder` is injected. - return; - } - for (var pluginName in namesToPlugins) { - var PluginModule = namesToPlugins[pluginName]; - var pluginIndex = EventPluginOrder.indexOf(pluginName); - ("production" !== "production" ? invariant( - pluginIndex > -1, - 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + - 'the plugin ordering, `%s`.', - pluginName - ) : invariant(pluginIndex > -1)); - if (EventPluginRegistry.plugins[pluginIndex]) { - continue; - } - ("production" !== "production" ? invariant( - PluginModule.extractEvents, - 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + - 'method, but `%s` does not.', - pluginName - ) : invariant(PluginModule.extractEvents)); - EventPluginRegistry.plugins[pluginIndex] = PluginModule; - var publishedEvents = PluginModule.eventTypes; - for (var eventName in publishedEvents) { - ("production" !== "production" ? invariant( - publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ), - 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', - eventName, - pluginName - ) : invariant(publishEventForPlugin( - publishedEvents[eventName], - PluginModule, - eventName - ))); - } - } -} - -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ -function publishEventForPlugin(dispatchConfig, PluginModule, eventName) { - ("production" !== "production" ? invariant( - !EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName), - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'event name, `%s`.', - eventName - ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName))); - EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; - - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - PluginModule, - eventName - ); - } - } - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - PluginModule, - eventName - ); - return true; - } - return false; -} - -/** - * Publishes a registration name that is used to identify dispatched events and - * can be used with `EventPluginHub.putListener` to register listeners. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ -function publishRegistrationName(registrationName, PluginModule, eventName) { - ("production" !== "production" ? invariant( - !EventPluginRegistry.registrationNameModules[registrationName], - 'EventPluginHub: More than one plugin attempted to publish the same ' + - 'registration name, `%s`.', - registrationName - ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName])); - EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; - EventPluginRegistry.registrationNameDependencies[registrationName] = - PluginModule.eventTypes[eventName].dependencies; -} - -/** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} - */ -var EventPluginRegistry = { - - /** - * Ordered list of injected plugins. - */ - plugins: [], - - /** - * Mapping from event name to dispatch config - */ - eventNameDispatchConfigs: {}, - - /** - * Mapping from registration name to plugin module - */ - registrationNameModules: {}, - - /** - * Mapping from registration name to event name - */ - registrationNameDependencies: {}, - - /** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - * @see {EventPluginHub.injection.injectEventPluginOrder} - */ - injectEventPluginOrder: function(InjectedEventPluginOrder) { - ("production" !== "production" ? invariant( - !EventPluginOrder, - 'EventPluginRegistry: Cannot inject event plugin ordering more than ' + - 'once. You are likely trying to load more than one copy of React.' - ) : invariant(!EventPluginOrder)); - // Clone the ordering so it cannot be dynamically mutated. - EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); - recomputePluginOrdering(); - }, - - /** - * Injects plugins to be used by `EventPluginHub`. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - * @see {EventPluginHub.injection.injectEventPluginsByName} - */ - injectEventPluginsByName: function(injectedNamesToPlugins) { - var isOrderingDirty = false; - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } - var PluginModule = injectedNamesToPlugins[pluginName]; - if (!namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== PluginModule) { - ("production" !== "production" ? invariant( - !namesToPlugins[pluginName], - 'EventPluginRegistry: Cannot inject two different event plugins ' + - 'using the same name, `%s`.', - pluginName - ) : invariant(!namesToPlugins[pluginName])); - namesToPlugins[pluginName] = PluginModule; - isOrderingDirty = true; - } - } - if (isOrderingDirty) { - recomputePluginOrdering(); - } - }, +module.exports = Promise; - /** - * Looks up the plugin for the supplied event. - * - * @param {object} event A synthetic event. - * @return {?object} The plugin that created the supplied event. - * @internal - */ - getPluginModuleForEvent: function(event) { - var dispatchConfig = event.dispatchConfig; - if (dispatchConfig.registrationName) { - return EventPluginRegistry.registrationNameModules[ - dispatchConfig.registrationName - ] || null; - } - for (var phase in dispatchConfig.phasedRegistrationNames) { - if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) { - continue; - } - var PluginModule = EventPluginRegistry.registrationNameModules[ - dispatchConfig.phasedRegistrationNames[phase] - ]; - if (PluginModule) { - return PluginModule; - } - } - return null; - }, +},{"when/lib/Promise":41}],21:[function(_dereq_,module,exports){ +var PropTypes = { /** - * Exposed for unit testing. - * @private + * Requires that the value of a prop be falsy. */ - _resetEventPlugins: function() { - EventPluginOrder = null; - for (var pluginName in namesToPlugins) { - if (namesToPlugins.hasOwnProperty(pluginName)) { - delete namesToPlugins[pluginName]; - } - } - EventPluginRegistry.plugins.length = 0; - - var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; - for (var eventName in eventNameDispatchConfigs) { - if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { - delete eventNameDispatchConfigs[eventName]; - } - } - - var registrationNameModules = EventPluginRegistry.registrationNameModules; - for (var registrationName in registrationNameModules) { - if (registrationNameModules.hasOwnProperty(registrationName)) { - delete registrationNameModules[registrationName]; - } - } + falsy: function (props, propName, elementName) { + if (props[propName]) + return new Error('<' + elementName + '> may not have a "' + propName + '" prop'); } }; -module.exports = EventPluginRegistry; - -},{"./invariant":69}],41:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 EventPluginUtils - */ - -"use strict"; - -var EventConstants = _dereq_("./EventConstants"); - -var invariant = _dereq_("./invariant"); - -/** - * Injected dependencies: - */ - -/** - * - `Mount`: [required] Module that can convert between React dom IDs and - * actual node references. - */ -var injection = { - Mount: null, - injectMount: function(InjectedMount) { - injection.Mount = InjectedMount; - if ("production" !== "production") { - ("production" !== "production" ? invariant( - InjectedMount && InjectedMount.getNode, - 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' + - 'is missing getNode.' - ) : invariant(InjectedMount && InjectedMount.getNode)); - } - } -}; - -var topLevelTypes = EventConstants.topLevelTypes; - -function isEndish(topLevelType) { - return topLevelType === topLevelTypes.topMouseUp || - topLevelType === topLevelTypes.topTouchEnd || - topLevelType === topLevelTypes.topTouchCancel; -} - -function isMoveish(topLevelType) { - return topLevelType === topLevelTypes.topMouseMove || - topLevelType === topLevelTypes.topTouchMove; -} -function isStartish(topLevelType) { - return topLevelType === topLevelTypes.topMouseDown || - topLevelType === topLevelTypes.topTouchStart; -} - - -var validateEventDispatches; -if ("production" !== "production") { - validateEventDispatches = function(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - - var listenersIsArr = Array.isArray(dispatchListeners); - var idsIsArr = Array.isArray(dispatchIDs); - var IDsLen = idsIsArr ? dispatchIDs.length : dispatchIDs ? 1 : 0; - var listenersLen = listenersIsArr ? - dispatchListeners.length : - dispatchListeners ? 1 : 0; - - ("production" !== "production" ? invariant( - idsIsArr === listenersIsArr && IDsLen === listenersLen, - 'EventPluginUtils: Invalid `event`.' - ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen)); - }; -} +module.exports = PropTypes; +},{}],22:[function(_dereq_,module,exports){ /** - * Invokes `cb(event, listener, id)`. Avoids using call if no scope is - * provided. The `(listener,id)` pair effectively forms the "dispatch" but are - * kept separate to conserve memory. + * Encapsulates a redirect to the given route. */ -function forEachEventDispatch(event, cb) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - if ("production" !== "production") { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and IDs are two parallel arrays that are always in sync. - cb(event, dispatchListeners[i], dispatchIDs[i]); - } - } else if (dispatchListeners) { - cb(event, dispatchListeners, dispatchIDs); - } +function Redirect(to, params, query) { + this.to = to; + this.params = params; + this.query = query; } -/** - * Default implementation of PluginModule.executeDispatch(). - * @param {SyntheticEvent} SyntheticEvent to handle - * @param {function} Application-level callback - * @param {string} domID DOM id to pass to the callback. - */ -function executeDispatch(event, listener, domID) { - event.currentTarget = injection.Mount.getNode(domID); - var returnValue = listener(event, domID); - event.currentTarget = null; - return returnValue; -} +module.exports = Redirect; -/** - * Standard/simple iteration through an event's collected dispatches. - */ -function executeDispatchesInOrder(event, executeDispatch) { - forEachEventDispatch(event, executeDispatch); - event._dispatchListeners = null; - event._dispatchIDs = null; -} +},{}],23:[function(_dereq_,module,exports){ +var assign = _dereq_('react/lib/Object.assign'); +var reversedArray = _dereq_('./reversedArray'); +var Redirect = _dereq_('./Redirect'); +var Promise = _dereq_('./Promise'); /** - * Standard/simple iteration through an event's collected dispatches, but stops - * at the first dispatch execution returning true, and returns that id. - * - * @return id of the first dispatch execution who's listener returns true, or - * null if no listener returned true. + * Runs all hook functions serially and calls callback(error) when finished. + * A hook may return a promise if it needs to execute asynchronously. */ -function executeDispatchesInOrderStopAtTrueImpl(event) { - var dispatchListeners = event._dispatchListeners; - var dispatchIDs = event._dispatchIDs; - if ("production" !== "production") { - validateEventDispatches(event); - } - if (Array.isArray(dispatchListeners)) { - for (var i = 0; i < dispatchListeners.length; i++) { - if (event.isPropagationStopped()) { - break; - } - // Listeners and IDs are two parallel arrays that are always in sync. - if (dispatchListeners[i](event, dispatchIDs[i])) { - return dispatchIDs[i]; - } - } - } else if (dispatchListeners) { - if (dispatchListeners(event, dispatchIDs)) { - return dispatchIDs; - } +function runHooks(hooks, callback) { + try { + var promise = hooks.reduce(function (promise, hook) { + // The first hook to use transition.wait makes the rest + // of the transition async from that point forward. + return promise ? promise.then(hook) : hook(); + }, null); + } catch (error) { + return callback(error); // Sync error. } - return null; -} - -/** - * @see executeDispatchesInOrderStopAtTrueImpl - */ -function executeDispatchesInOrderStopAtTrue(event) { - var ret = executeDispatchesInOrderStopAtTrueImpl(event); - event._dispatchIDs = null; - event._dispatchListeners = null; - return ret; -} -/** - * Execution of a "direct" dispatch - there must be at most one dispatch - * accumulated on the event or it is considered an error. It doesn't really make - * sense for an event with multiple dispatches (bubbled) to keep track of the - * return values at each dispatch execution, but it does tend to make sense when - * dealing with "direct" dispatches. - * - * @return The return value of executing the single dispatch. - */ -function executeDirectDispatch(event) { - if ("production" !== "production") { - validateEventDispatches(event); + if (promise) { + // Use setTimeout to break the promise chain. + promise.then(function () { + setTimeout(callback); + }, function (error) { + setTimeout(function () { + callback(error); + }); + }); + } else { + callback(); } - var dispatchListener = event._dispatchListeners; - var dispatchID = event._dispatchIDs; - ("production" !== "production" ? invariant( - !Array.isArray(dispatchListener), - 'executeDirectDispatch(...): Invalid `event`.' - ) : invariant(!Array.isArray(dispatchListener))); - var res = dispatchListener ? - dispatchListener(event, dispatchID) : - null; - event._dispatchListeners = null; - event._dispatchIDs = null; - return res; -} - -/** - * @param {SyntheticEvent} event - * @return {bool} True iff number of dispatches accumulated is greater than 0. - */ -function hasDispatches(event) { - return !!event._dispatchListeners; } /** - * General utilities that are useful in creating custom Event Plugins. - */ -var EventPluginUtils = { - isEndish: isEndish, - isMoveish: isMoveish, - isStartish: isStartish, - - executeDirectDispatch: executeDirectDispatch, - executeDispatch: executeDispatch, - executeDispatchesInOrder: executeDispatchesInOrder, - executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, - hasDispatches: hasDispatches, - injection: injection, - useTouchEvents: false -}; - -module.exports = EventPluginUtils; - -},{"./EventConstants":38,"./invariant":69}],42:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 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; - -},{}],43:[function(_dereq_,module,exports){ -/** - * Copyright 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 Object.assign + * 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. + * Calls callback(error) when finished. */ +function runTransitionFromHooks(transition, routes, components, callback) { + components = reversedArray(components); -// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign - -function assign(target, sources) { - if (target == null) { - throw new TypeError('Object.assign target cannot be null or undefined'); - } - - var to = Object(target); - var hasOwnProperty = Object.prototype.hasOwnProperty; - - for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { - var nextSource = arguments[nextIndex]; - if (nextSource == null) { - continue; - } - - var from = Object(nextSource); - - // We don't currently support accessors nor proxies. Therefore this - // copy cannot throw. If we ever supported this then we must handle - // exceptions and side-effects. We don't support symbols so they won't - // be transferred. - - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } - } - - return to; -}; + var hooks = reversedArray(routes).map(function (route, index) { + return function () { + var handler = route.handler; -module.exports = assign; + if (!transition.isAborted && handler.willTransitionFrom) + return handler.willTransitionFrom(transition, components[index]); -},{}],44:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 PooledClass - */ + var promise = transition._promise; + transition._promise = null; -"use strict"; + return promise; + }; + }); -var invariant = _dereq_("./invariant"); + runHooks(hooks, callback); +} /** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. + * Calls the willTransitionTo hook of all handlers in the given matches + * serially with the transition object and any params that apply to that + * handler. Calls callback(error) when finished. */ -var oneArgumentPooler = function(copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function(a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; +function runTransitionToHooks(transition, routes, params, query, callback) { + var hooks = routes.map(function (route) { + return function () { + var handler = route.handler; -var threeArgumentPooler = function(a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; + if (!transition.isAborted && handler.willTransitionTo) + handler.willTransitionTo(transition, params, query); -var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4, a5); - return instance; - } else { - return new Klass(a1, a2, a3, a4, a5); - } -}; + var promise = transition._promise; + transition._promise = null; -var standardReleaser = function(instance) { - var Klass = this; - ("production" !== "production" ? invariant( - instance instanceof Klass, - 'Trying to release an instance into a pool of a different type.' - ) : invariant(instance instanceof Klass)); - if (instance.destructor) { - instance.destructor(); - } - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; + return promise; + }; + }); -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; + runHooks(hooks, callback); +} /** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances (optional). + * Encapsulates a transition to a given path. * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. + * The willTransitionTo and willTransitionFrom handlers receive + * an instance of this class as their first argument. */ -var addPoolingTo = function(CopyConstructor, pooler) { - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; +function Transition(path, retry) { + this.path = path; + this.abortReason = null; + this.isAborted = false; + this.retry = retry.bind(this); + this._promise = null; +} -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fiveArgumentPooler: fiveArgumentPooler -}; +assign(Transition.prototype, { + + abort: function (reason) { + this.abortReason = reason; + this.isAborted = true; + }, -module.exports = PooledClass; + redirect: function (to, params, query) { + this.abort(new Redirect(to, params, query)); + }, -},{"./invariant":69}],45:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactBrowserEventEmitter - * @typechecks static-only - */ + wait: function (value) { + this._promise = Promise.resolve(value); + }, -"use strict"; + from: function (routes, components, callback) { + return runTransitionFromHooks(this, routes, components, callback); + }, + + to: function (routes, params, query, callback) { + return runTransitionToHooks(this, routes, params, query, callback); + } -var EventConstants = _dereq_("./EventConstants"); -var EventPluginHub = _dereq_("./EventPluginHub"); -var EventPluginRegistry = _dereq_("./EventPluginRegistry"); -var ReactEventEmitterMixin = _dereq_("./ReactEventEmitterMixin"); -var ViewportMetrics = _dereq_("./ViewportMetrics"); +}); + +module.exports = Transition; -var assign = _dereq_("./Object.assign"); -var isEventSupported = _dereq_("./isEventSupported"); +},{"./Promise":20,"./Redirect":22,"./reversedArray":27,"react/lib/Object.assign":36}],24:[function(_dereq_,module,exports){ +var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); +var warning = _dereq_('react/lib/warning'); +var invariant = _dereq_('react/lib/invariant'); +var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; +var ImitateBrowserBehavior = _dereq_('../behaviors/ImitateBrowserBehavior'); +var RouteHandler = _dereq_('../components/RouteHandler'); +var HashLocation = _dereq_('../locations/HashLocation'); +var HistoryLocation = _dereq_('../locations/HistoryLocation'); +var NavigationContext = _dereq_('../mixins/NavigationContext'); +var StateContext = _dereq_('../mixins/StateContext'); +var Scrolling = _dereq_('../mixins/Scrolling'); +var createRoutesFromChildren = _dereq_('./createRoutesFromChildren'); +var supportsHistory = _dereq_('./supportsHistory'); +var Transition = _dereq_('./Transition'); +var PropTypes = _dereq_('./PropTypes'); +var Redirect = _dereq_('./Redirect'); +var Path = _dereq_('./Path'); /** - * Summary of `ReactBrowserEventEmitter` event handling: - * - * - Top-level delegation is used to trap most native browser events. This - * may only occur in the main thread and is the responsibility of - * ReactEventListener, which is injected and can therefore support pluggable - * event sources. This is the only work that occurs in the main thread. - * - * - We normalize and de-duplicate events to account for browser quirks. This - * may be done in the worker thread. - * - * - Forward these native events (with the associated top-level type used to - * trap it) to `EventPluginHub`, which in turn will ask plugins if they want - * to extract any synthetic events. - * - * - The `EventPluginHub` will then process each event by annotating them with - * "dispatches", a sequence of listeners and IDs that care about that event. - * - * - The `EventPluginHub` then dispatches the events. - * - * Overview of React and the event system: - * - * +------------+ . - * | DOM | . - * +------------+ . - * | . - * v . - * +------------+ . - * | ReactEvent | . - * | Listener | . - * +------------+ . +-----------+ - * | . +--------+|SimpleEvent| - * | . | |Plugin | - * +-----|------+ . v +-----------+ - * | | | . +--------------+ +------------+ - * | +-----------.--->|EventPluginHub| | Event | - * | | . | | +-----------+ | Propagators| - * | ReactEvent | . | | |TapEvent | |------------| - * | Emitter | . | |<---+|Plugin | |other plugin| - * | | . | | +-----------+ | utilities | - * | +-----------.--->| | +------------+ - * | | | . +--------------+ - * +-----|------+ . ^ +-----------+ - * | . | |Enter/Leave| - * + . +-------+|Plugin | - * +-------------+ . +-----------+ - * | application | . - * |-------------| . - * | | . - * | | . - * +-------------+ . - * . - * React Core . General Purpose Event Plugin System + * The default location for new routers. */ +var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/'; -var alreadyListeningTo = {}; -var isMonitoringScrollValue = false; -var reactTopListenersCounter = 0; - -// For events like 'submit' which don't consistently bubble (which we trap at a -// lower node than `document`), binding at `document` would cause duplicate -// events so we don't include them here -var topEventMapping = { - topBlur: 'blur', - topChange: 'change', - topClick: 'click', - topCompositionEnd: 'compositionend', - topCompositionStart: 'compositionstart', - topCompositionUpdate: 'compositionupdate', - topContextMenu: 'contextmenu', - topCopy: 'copy', - topCut: 'cut', - topDoubleClick: 'dblclick', - topDrag: 'drag', - topDragEnd: 'dragend', - topDragEnter: 'dragenter', - topDragExit: 'dragexit', - topDragLeave: 'dragleave', - topDragOver: 'dragover', - topDragStart: 'dragstart', - topDrop: 'drop', - topFocus: 'focus', - topInput: 'input', - topKeyDown: 'keydown', - topKeyPress: 'keypress', - topKeyUp: 'keyup', - topMouseDown: 'mousedown', - topMouseMove: 'mousemove', - topMouseOut: 'mouseout', - topMouseOver: 'mouseover', - topMouseUp: 'mouseup', - topPaste: 'paste', - topScroll: 'scroll', - topSelectionChange: 'selectionchange', - topTextInput: 'textInput', - topTouchCancel: 'touchcancel', - topTouchEnd: 'touchend', - topTouchMove: 'touchmove', - topTouchStart: 'touchstart', - topWheel: 'wheel' -}; +/** + * The default scroll behavior for new routers. + */ +var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null; /** - * To ensure no conflicts with other potential React instances on the page + * The default error handler for new routers. */ -var topListenersIDKey = "_reactListenersID" + String(Math.random()).slice(2); - -function getListeningForDocument(mountAt) { - // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` - // directly. - if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { - mountAt[topListenersIDKey] = reactTopListenersCounter++; - alreadyListeningTo[mountAt[topListenersIDKey]] = {}; - } - return alreadyListeningTo[mountAt[topListenersIDKey]]; +function defaultErrorHandler(error) { + // Throw so we don't silently swallow async errors. + throw error; // This error probably originated in a transition hook. } /** - * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For - * example: - * - * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction); - * - * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. - * - * @internal + * The default aborted transition handler for new routers. */ -var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { - - /** - * Injectable event backend - */ - ReactEventListener: null, - - injection: { - /** - * @param {object} ReactEventListener - */ - injectReactEventListener: function(ReactEventListener) { - ReactEventListener.setHandleTopLevel( - ReactBrowserEventEmitter.handleTopLevel - ); - ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; - } - }, +function defaultAbortHandler(abortReason, location) { + if (typeof location === 'string') + throw new Error('Unhandled aborted transition! Reason: ' + abortReason); - /** - * Sets whether or not any created callbacks should be enabled. - * - * @param {boolean} enabled True if callbacks should be enabled. - */ - setEnabled: function(enabled) { - if (ReactBrowserEventEmitter.ReactEventListener) { - ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); - } - }, + if (abortReason instanceof Redirect) { + location.replace(this.makePath(abortReason.to, abortReason.params, abortReason.query)); + } else { + location.pop(); + } +} - /** - * @return {boolean} True if callbacks are enabled. - */ - isEnabled: function() { - return !!( - ReactBrowserEventEmitter.ReactEventListener && - ReactBrowserEventEmitter.ReactEventListener.isEnabled() - ); - }, +function findMatch(pathname, routes, defaultRoute, notFoundRoute) { + var match, route, params; - /** - * We listen for bubbled touch events on the document object. - * - * Firefox v8.01 (and possibly others) exhibited strange behavior when - * mounting `onmousemove` events at some node that was not the document - * element. The symptoms were that if your mouse is not moving over something - * contained within that mount point (for example on the background) the - * top-level listeners for `onmousemove` won't be called. However, if you - * register the `mousemove` on the document object, then it will of course - * catch all `mousemove`s. This along with iOS quirks, justifies restricting - * top-level listeners to the document object only, at least for these - * movement types of events and possibly all events. - * - * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - * - * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but - * they bubble to document. - * - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {object} contentDocumentHandle Document which owns the container - */ - listenTo: function(registrationName, contentDocumentHandle) { - var mountAt = contentDocumentHandle; - var isListening = getListeningForDocument(mountAt); - var dependencies = EventPluginRegistry. - registrationNameDependencies[registrationName]; - - var topLevelTypes = EventConstants.topLevelTypes; - for (var i = 0, l = dependencies.length; i < l; i++) { - var dependency = dependencies[i]; - if (!( - isListening.hasOwnProperty(dependency) && - isListening[dependency] - )) { - if (dependency === topLevelTypes.topWheel) { - if (isEventSupported('wheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'wheel', - mountAt - ); - } else if (isEventSupported('mousewheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'mousewheel', - mountAt - ); - } else { - // Firefox needs to capture a different mouse scroll event. - // @see http://www.quirksmode.org/dom/events/tests/scroll.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'DOMMouseScroll', - mountAt - ); - } - } else if (dependency === topLevelTypes.topScroll) { - - if (isEventSupported('scroll', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topScroll, - 'scroll', - mountAt - ); - } else { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topScroll, - 'scroll', - ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE - ); - } - } else if (dependency === topLevelTypes.topFocus || - dependency === topLevelTypes.topBlur) { - - if (isEventSupported('focus', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topFocus, - 'focus', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topBlur, - 'blur', - mountAt - ); - } else if (isEventSupported('focusin')) { - // IE has `focusin` and `focusout` events which bubble. - // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topFocus, - 'focusin', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topBlur, - 'focusout', - mountAt - ); - } + for (var i = 0, len = routes.length; i < len; ++i) { + route = routes[i]; - // to make sure blur and focus event listeners are only attached once - isListening[topLevelTypes.topBlur] = true; - isListening[topLevelTypes.topFocus] = true; - } else if (topEventMapping.hasOwnProperty(dependency)) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - dependency, - topEventMapping[dependency], - mountAt - ); - } + // Check the subtree first to find the most deeply-nested match. + match = findMatch(pathname, route.childRoutes, route.defaultRoute, route.notFoundRoute); - isListening[dependency] = true; - } + if (match != null) { + match.routes.unshift(route); + return match; } - }, - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelType, - handlerBaseName, - handle - ); - }, + // No routes in the subtree matched, so check this route. + params = Path.extractParams(route.path, pathname); - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelType, - handlerBaseName, - handle - ); - }, + if (params) + return createMatch(route, params); + } - /** - * Listens to window scroll and resize events. We cache scroll values so that - * application code can access them without triggering reflows. - * - * NOTE: Scroll events do not bubble. - * - * @see http://www.quirksmode.org/dom/events/scroll.html - */ - ensureScrollValueMonitoring: function(){ - if (!isMonitoringScrollValue) { - var refresh = ViewportMetrics.refreshScrollValues; - ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); - isMonitoringScrollValue = true; - } - }, + // No routes matched, so try the default route if there is one. + if (defaultRoute && (params = Path.extractParams(defaultRoute.path, pathname))) + return createMatch(defaultRoute, params); - eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, + // Last attempt: does the "not found" route match? + if (notFoundRoute && (params = Path.extractParams(notFoundRoute.path, pathname))) + return createMatch(notFoundRoute, params); - registrationNameModules: EventPluginHub.registrationNameModules, + return match; +} - putListener: EventPluginHub.putListener, +function createMatch(route, params) { + return { routes: [ route ], params: params }; +} - getListener: EventPluginHub.getListener, +function hasMatch(routes, route, prevParams, nextParams) { + return routes.some(function (r) { + if (r !== route) + return false; - deleteListener: EventPluginHub.deleteListener, + var paramNames = route.paramNames; + var paramName; - deleteAllListeners: EventPluginHub.deleteAllListeners + for (var i = 0, len = paramNames.length; i < len; ++i) { + paramName = paramNames[i]; -}); + if (nextParams[paramName] !== prevParams[paramName]) + return false; + } -module.exports = ReactBrowserEventEmitter; + return true; + }); +} -},{"./EventConstants":38,"./EventPluginHub":39,"./EventPluginRegistry":40,"./Object.assign":43,"./ReactEventEmitterMixin":50,"./ViewportMetrics":60,"./isEventSupported":70}],46:[function(_dereq_,module,exports){ /** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. + * Creates and returns a new router using the given options. A router + * is a ReactComponent class that knows how to react to changes in the + * URL and keep the contents of the page in sync. * - * 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. + * Options may be any of the following: * - * @providesModule ReactContext - */ - -"use strict"; - -var assign = _dereq_("./Object.assign"); - -/** - * Keeps track of the current context. + * - routes (required) The route config + * - location The location to use. Defaults to HashLocation when + * the DOM is available, "/" otherwise + * - scrollBehavior The scroll behavior to use. Defaults to ImitateBrowserBehavior + * when the DOM is available, null otherwise + * - onError A function that is used to handle errors + * - onAbort A function that is used to handle aborted transitions * - * The context is automatically passed down the component ownership hierarchy - * and is accessible via `this.context` on ReactCompositeComponents. + * When rendering in a server-side environment, the location should simply + * be the URL path that was used in the request, including the query string. */ -var ReactContext = { +function createRouter(options) { + options = options || {}; - /** - * @internal - * @type {object} - */ - current: {}, - - /** - * Temporarily extends the current context while executing scopedCallback. - * - * A typical use case might look like - * - * render: function() { - * var children = ReactContext.withContext({foo: 'foo'}, () => ( - * - * )); - * return
{children}
; - * } - * - * @param {object} newContext New context to merge into the existing context - * @param {function} scopedCallback Callback to run with the new context - * @return {ReactComponent|array} - */ - withContext: function(newContext, scopedCallback) { - var result; - var previousContext = ReactContext.current; - ReactContext.current = assign({}, previousContext, newContext); - try { - result = scopedCallback(); - } finally { - ReactContext.current = previousContext; - } - return result; + if (typeof options === 'function') { + options = { routes: options }; // Router.create() + } else if (Array.isArray(options)) { + options = { routes: options }; // Router.create([ , ]) } -}; - -module.exports = ReactContext; + var routes = []; + var namedRoutes = {}; + var components = []; + var location = options.location || DEFAULT_LOCATION; + var scrollBehavior = options.scrollBehavior || DEFAULT_SCROLL_BEHAVIOR; + var onError = options.onError || defaultErrorHandler; + var onAbort = options.onAbort || defaultAbortHandler; + var state = {}; -},{"./Object.assign":43}],47:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactCurrentOwner - */ + // Automatically fall back to full page refreshes in + // browsers that don't support the HTML history API. + if (location === HistoryLocation && !supportsHistory()) + location = RefreshLocation; -"use strict"; + var router = React.createClass({ -/** - * Keeps track of the current owner. - * - * The current owner is the component who should own any components that are - * currently being constructed. - * - * The depth indicate how many composite components are above this render level. - */ -var ReactCurrentOwner = { + displayName: 'Router', - /** - * @internal - * @type {ReactComponent} - */ - current: null + mixins: [ NavigationContext, StateContext, Scrolling ], -}; + statics: { -module.exports = ReactCurrentOwner; + defaultRoute: null, + notFoundRoute: null, + + /** + * Adds routes to this router from the given children object (see ReactChildren). + */ + addRoutes: function (children) { + routes.push.apply(routes, createRoutesFromChildren(children, this, namedRoutes)); + }, + + /** + * Returns an absolute URL path created from the given route + * name, URL parameters, and query. + */ + makePath: function (to, params, query) { + var path; + if (Path.isAbsolute(to)) { + path = Path.normalize(to); + } else { + var route = namedRoutes[to]; -},{}],48:[function(_dereq_,module,exports){ -/** - * Copyright 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 ReactElement - */ + invariant( + route, + 'Unable to find ', + to + ); -"use strict"; + path = route.path; + } -var ReactContext = _dereq_("./ReactContext"); -var ReactCurrentOwner = _dereq_("./ReactCurrentOwner"); + return Path.withQuery(Path.injectParams(path, params), query); + }, + + /** + * Returns a string that may safely be used as the href of a link + * to the route with the given name, URL parameters, and query. + */ + makeHref: function (to, params, query) { + var path = this.makePath(to, params, query); + return (location === HashLocation) ? '#' + path : path; + }, + + /** + * Transitions to the URL specified in the arguments by pushing + * a new URL onto the history stack. + */ + transitionTo: function (to, params, query) { + invariant( + typeof location !== 'string', + 'You cannot use transitionTo with a static location' + ); -var warning = _dereq_("./warning"); + location.push(this.makePath(to, params, query)); + }, -var RESERVED_PROPS = { - key: true, - ref: true -}; + /** + * Transitions to the URL specified in the arguments by replacing + * the current URL in the history stack. + */ + replaceWith: function (to, params, query) { + invariant( + typeof location !== 'string', + 'You cannot use replaceWith with a static location' + ); -/** - * Warn for mutations. - * - * @internal - * @param {object} object - * @param {string} key - */ -function defineWarningProperty(object, key) { - Object.defineProperty(object, key, { + location.replace(this.makePath(to, params, query)); + }, - configurable: false, - enumerable: true, + /** + * Transitions to the previous URL. + */ + goBack: function () { + invariant( + typeof location !== 'string', + 'You cannot use goBack with a static location' + ); - get: function() { - if (!this._store) { - return null; - } - return this._store[key]; - }, + location.pop(); + }, + + /** + * Performs a match of the given path against this router and returns an object with + * the { path, routes, params, query } that match. Returns null if no match can be made. + */ + match: function (path) { + return findMatch(Path.withoutQuery(path), routes, this.defaultRoute, this.notFoundRoute) || null; + }, + + /** + * Performs a transition to the given path and calls callback(error, abortReason) + * when the transition is finished. If both arguments are null the router's state + * was updated. Otherwise the transition did not complete. + * + * In a transition, a router first determines which routes are involved by 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 hook is invoked on all route handlers we're transitioning away + * from, in reverse nesting order. Likewise, the willTransitionTo hook is invoked on + * all route handlers we're transitioning to. + * + * Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the + * transition. To resolve asynchronously, they may use transition.wait(promise). If no + * hooks wait, the transition is fully synchronous. + */ + dispatch: function (path, action, callback) { + if (state.path === path) + return; // Nothing to do! + + var match = this.match(path); + + warning( + match != null, + 'No route matches path "%s". Make sure you have somewhere in your routes', + path, path + ); - set: function(value) { - ("production" !== "production" ? warning( - false, - 'Don\'t set the ' + key + ' property of the component. ' + - 'Mutate the existing props object instead.' - ) : null); - this._store[key] = value; - } + if (match == null) + match = {}; - }); -} + var prevRoutes = state.routes || []; + var prevParams = state.params || {}; -/** - * This is updated to true if the membrane is successfully created. - */ -var useMutationMembrane = false; + var nextRoutes = match.routes || []; + var nextParams = match.params || {}; + var nextQuery = Path.extractQuery(path) || {}; -/** - * Warn for mutations. - * - * @internal - * @param {object} element - */ -function defineMutationMembrane(prototype) { - try { - var pseudoFrozenProperties = { - props: true - }; - for (var key in pseudoFrozenProperties) { - defineWarningProperty(prototype, key); - } - useMutationMembrane = true; - } catch (x) { - // IE will fail on defineProperty - } -} + var fromRoutes, toRoutes; + if (prevRoutes.length) { + fromRoutes = prevRoutes.filter(function (route) { + return !hasMatch(nextRoutes, route, prevParams, nextParams); + }); -/** - * Base constructor for all React elements. This is only used to make this - * work with a dynamic instanceof check. Nothing should live on this prototype. - * - * @param {*} type - * @param {string|object} ref - * @param {*} key - * @param {*} props - * @internal - */ -var ReactElement = function(type, key, ref, owner, context, props) { - // Built-in properties that belong on the element - this.type = type; - this.key = key; - this.ref = ref; + toRoutes = nextRoutes.filter(function (route) { + return !hasMatch(prevRoutes, route, prevParams, nextParams); + }); + } else { + fromRoutes = []; + toRoutes = nextRoutes; + } - // Record the component responsible for creating this element. - this._owner = owner; + var transition = new Transition(path, this.replaceWith.bind(this, path)); - // TODO: Deprecate withContext, and then the context becomes accessible - // through the owner. - this._context = context; + transition.from(fromRoutes, components, function (error) { + if (error || transition.isAborted) + return callback.call(router, error, transition); - if ("production" !== "production") { - // The validation flag and props are currently mutative. We put them on - // an external backing store so that we can freeze the whole object. - // This can be replaced with a WeakMap once they are implemented in - // commonly used development environments. - this._store = { validated: false, props: props }; - - // We're not allowed to set props directly on the object so we early - // return and rely on the prototype membrane to forward to the backing - // store. - if (useMutationMembrane) { - Object.freeze(this); - return; - } - } + transition.to(toRoutes, nextParams, nextQuery, function (error) { + if (error || transition.isAborted) + return callback.call(router, error, transition); - this.props = props; -}; + state.path = path; + state.action = action; + state.routes = nextRoutes; + state.params = nextParams; + state.query = nextQuery; -// We intentionally don't expose the function on the constructor property. -// ReactElement should be indistinguishable from a plain object. -ReactElement.prototype = { - _isReactElement: true -}; + callback.call(router, null, transition); + }); + }); + }, + + /** + * Starts this router and calls callback(router, state) when the route changes. + * + * If the router's location is static (i.e. a URL path in a server environment) + * the callback is called only once. Otherwise, the location should be one of the + * Router.*Location objects (e.g. Router.HashLocation or Router.HistoryLocation). + */ + run: function (callback) { + function dispatchHandler(error, transition) { + if (error) { + onError.call(router, error); + } else if (transition.isAborted) { + onAbort.call(router, transition.abortReason, location); + } else { + callback.call(router, router, state); + } + } -if ("production" !== "production") { - defineMutationMembrane(ReactElement.prototype); -} + if (typeof location === 'string') { + warning( + !canUseDOM || "production" === 'test', + 'You should not use a static location in a DOM environment because ' + + 'the router will not be kept in sync with the current URL' + ); -ReactElement.createElement = function(type, config, children) { - var propName; + // Dispatch the location. + router.dispatch(location, null, dispatchHandler); + } else { + invariant( + canUseDOM, + 'You cannot use %s in a non-DOM environment', + location + ); - // Reserved names are extracted - var props = {}; + // Listen for changes to the location. + function changeListener(change) { + router.dispatch(change.path, change.type, dispatchHandler); + } - var key = null; - var ref = null; + if (location.addChangeListener) + location.addChangeListener(changeListener); - if (config != null) { - ref = config.ref === undefined ? null : config.ref; - if ("production" !== "production") { - ("production" !== "production" ? warning( - config.key !== null, - 'createElement(...): Encountered component with a `key` of null. In ' + - 'a future version, this will be treated as equivalent to the string ' + - '\'null\'; instead, provide an explicit key or use undefined.' - ) : null); - } - // TODO: Change this back to `config.key === undefined` - key = config.key == null ? null : '' + config.key; - // Remaining properties are added to a new props object - for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; + // Bootstrap using the current path. + router.dispatch(location.getCurrentPath(), null, dispatchHandler); + } } - } - } - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } + }, - // Resolve default props - if (type.defaultProps) { - var defaultProps = type.defaultProps; - for (propName in defaultProps) { - if (typeof props[propName] === 'undefined') { - props[propName] = defaultProps[propName]; - } - } - } + propTypes: { + children: PropTypes.falsy + }, - return new ReactElement( - type, - key, - ref, - ReactCurrentOwner.current, - ReactContext.current, - props - ); -}; + getLocation: function () { + return location; + }, -ReactElement.createFactory = function(type) { - var factory = ReactElement.createElement.bind(null, type); - // Expose the type on the factory and the prototype so that it can be - // easily accessed on elements. E.g. .type === Foo.type. - // This should not be named `constructor` since this may not be the function - // that created the element, and it may not even be a constructor. - factory.type = type; - return factory; -}; + getScrollBehavior: function () { + return scrollBehavior; + }, -ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { - var newElement = new ReactElement( - oldElement.type, - oldElement.key, - oldElement.ref, - oldElement._owner, - oldElement._context, - newProps - ); + getRouteAtDepth: function (depth) { + var routes = this.state.routes; + return routes && routes[depth]; + }, - if ("production" !== "production") { - // If the key on the original is valid, then the clone is valid - newElement._store.validated = oldElement._store.validated; - } - return newElement; -}; + getRouteComponents: function () { + return components; + }, -/** - * @param {?object} object - * @return {boolean} True if `object` is a valid component. - * @final - */ -ReactElement.isValidElement = function(object) { - // ReactTestUtils is often used outside of beforeEach where as React is - // within it. This leads to two different instances of React on the same - // page. To identify a element from a different React instance we use - // a flag instead of an instanceof check. - var isElement = !!(object && object._isReactElement); - // if (isElement && !(object instanceof ReactElement)) { - // This is an indicator that you're using multiple versions of React at the - // same time. This will screw with ownership and stuff. Fix it, please. - // TODO: We could possibly warn here. - // } - return isElement; -}; + getInitialState: function () { + return state; + }, -module.exports = ReactElement; + componentWillReceiveProps: function () { + this.setState(state); + }, -},{"./ReactContext":46,"./ReactCurrentOwner":47,"./warning":75}],49:[function(_dereq_,module,exports){ -/** - * Copyright 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 ReactEmptyComponent - */ + render: function () { + return this.getRouteAtDepth(0) ? React.createElement(RouteHandler, this.props) : null; + }, + + childContextTypes: { + getRouteAtDepth: React.PropTypes.func.isRequired, + getRouteComponents: React.PropTypes.func.isRequired, + routeHandlers: React.PropTypes.array.isRequired + }, + + getChildContext: function () { + return { + getRouteComponents: this.getRouteComponents, + getRouteAtDepth: this.getRouteAtDepth, + routeHandlers: [ this ] + }; + } + + }); -"use strict"; + if (options.routes) + router.addRoutes(options.routes); -var ReactElement = _dereq_("./ReactElement"); + return router; +} -var invariant = _dereq_("./invariant"); +module.exports = createRouter; -var component; -// This registry keeps track of the React IDs of the components that rendered to -// `null` (in reality a placeholder such as `noscript`) -var nullComponentIdsRegistry = {}; +},{"../behaviors/ImitateBrowserBehavior":2,"../components/RouteHandler":8,"../locations/HashLocation":10,"../locations/HistoryLocation":11,"../mixins/NavigationContext":15,"../mixins/Scrolling":16,"../mixins/StateContext":18,"./Path":19,"./PropTypes":21,"./Redirect":22,"./Transition":23,"./createRoutesFromChildren":25,"./supportsHistory":29,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39,"react/lib/warning":40}],25:[function(_dereq_,module,exports){ +var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); +var warning = _dereq_('react/lib/warning'); +var invariant = _dereq_('react/lib/invariant'); +var DefaultRoute = _dereq_('../components/DefaultRoute'); +var NotFoundRoute = _dereq_('../components/NotFoundRoute'); +var Redirect = _dereq_('../components/Redirect'); +var Route = _dereq_('../components/Route'); +var Path = _dereq_('./Path'); + +var CONFIG_ELEMENT_TYPES = [ + DefaultRoute.type, + NotFoundRoute.type, + Redirect.type, + Route.type +]; -var ReactEmptyComponentInjection = { - injectEmptyComponent: function(emptyComponent) { - component = ReactElement.createFactory(emptyComponent); - } -}; +function createRedirectHandler(to, _params, _query) { + return React.createClass({ + statics: { + willTransitionTo: function (transition, params, query) { + transition.redirect(to, _params || params, _query || query); + } + }, -/** - * @return {ReactComponent} component The injected empty component. - */ -function getEmptyComponent() { - ("production" !== "production" ? invariant( - component, - 'Trying to return null from a render, but no null placeholder component ' + - 'was injected.' - ) : invariant(component)); - return component(); + render: function () { + return null; + } + }); } -/** - * Mark the component as having rendered to null. - * @param {string} id Component's `_rootNodeID`. - */ -function registerNullComponentID(id) { - nullComponentIdsRegistry[id] = true; -} +function checkPropTypes(componentName, propTypes, props) { + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error = propTypes[propName](props, propName, componentName); -/** - * Unmark the component as having rendered to null: it renders to something now. - * @param {string} id Component's `_rootNodeID`. - */ -function deregisterNullComponentID(id) { - delete nullComponentIdsRegistry[id]; + if (error instanceof Error) + warning(false, error.message); + } + } } -/** - * @param {string} id Component's `_rootNodeID`. - * @return {boolean} True if the component is rendered to null. - */ -function isNullComponentID(id) { - return nullComponentIdsRegistry[id]; -} +function createRoute(element, parentRoute, namedRoutes) { + var type = element.type; + var props = element.props; + var componentName = (type && type.displayName) || 'UnknownComponent'; -var ReactEmptyComponent = { - deregisterNullComponentID: deregisterNullComponentID, - getEmptyComponent: getEmptyComponent, - injection: ReactEmptyComponentInjection, - isNullComponentID: isNullComponentID, - registerNullComponentID: registerNullComponentID -}; + invariant( + CONFIG_ELEMENT_TYPES.indexOf(type) !== -1, + 'Unrecognized route configuration element "<%s>"', + componentName + ); -module.exports = ReactEmptyComponent; + if (type.propTypes) + checkPropTypes(componentName, type.propTypes, props); -},{"./ReactElement":48,"./invariant":69}],50:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactEventEmitterMixin - */ + var route = { name: props.name }; -"use strict"; + if (type === Redirect.type) { + route.handler = createRedirectHandler(props.to, props.params, props.query); + props.path = props.path || props.from; + } else { + route.handler = props.handler; + } -var EventPluginHub = _dereq_("./EventPluginHub"); + var parentPath = (parentRoute && parentRoute.path) || '/'; -function runEventQueueInBatch(events) { - EventPluginHub.enqueueEvents(events); - EventPluginHub.processEventQueue(); -} + if ((props.path || props.name) && type !== DefaultRoute.type && type !== NotFoundRoute.type) { + var path = props.path || props.name; -var ReactEventEmitterMixin = { + // Relative paths extend their parent. + if (!Path.isAbsolute(path)) + path = Path.join(parentPath, path); - /** - * Streams a fired top-level event to `EventPluginHub` where plugins have the - * opportunity to create `ReactEvent`s to be dispatched. - * - * @param {string} topLevelType Record from `EventConstants`. - * @param {object} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native environment event. - */ - handleTopLevel: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - var events = EventPluginHub.extractEvents( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ); + route.path = Path.normalize(path); + } else { + route.path = parentPath; - runEventQueueInBatch(events); + if (type === NotFoundRoute.type) + route.path += '*'; } -}; -module.exports = ReactEventEmitterMixin; - -},{"./EventPluginHub":39}],51:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactInstanceHandles - * @typechecks static-only - */ + route.paramNames = Path.extractParamNames(route.path); -"use strict"; + // Make sure the route's path has all params its parent needs. + if (parentRoute && Array.isArray(parentRoute.paramNames)) { + parentRoute.paramNames.forEach(function (paramName) { + invariant( + route.paramNames.indexOf(paramName) !== -1, + 'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"', + route.path, paramName, parentRoute.path + ); + }); + } -var ReactRootIndex = _dereq_("./ReactRootIndex"); + // Make sure the route can be looked up by s. + if (props.name) { + invariant( + namedRoutes[props.name] == null, + 'You cannot use the name "%s" for more than one route', + props.name + ); -var invariant = _dereq_("./invariant"); + namedRoutes[props.name] = route; + } -var SEPARATOR = '.'; -var SEPARATOR_LENGTH = SEPARATOR.length; + // Handle . + if (type === NotFoundRoute.type) { + invariant( + parentRoute, + ' must have a parent ' + ); -/** - * Maximum depth of traversals before we consider the possibility of a bad ID. - */ -var MAX_TREE_DEPTH = 100; + invariant( + parentRoute.notFoundRoute == null, + 'You may not have more than one per ' + ); -/** - * Creates a DOM ID prefix to use when mounting React components. - * - * @param {number} index A unique integer - * @return {string} React root ID. - * @internal - */ -function getReactRootIDString(index) { - return SEPARATOR + index.toString(36); -} + parentRoute.notFoundRoute = route; -/** - * Checks if a character in the supplied ID is a separator or the end. - * - * @param {string} id A React DOM ID. - * @param {number} index Index of the character to check. - * @return {boolean} True if the character is a separator or end of the ID. - * @private - */ -function isBoundary(id, index) { - return id.charAt(index) === SEPARATOR || index === id.length; -} + return null; + } -/** - * Checks if the supplied string is a valid React DOM ID. - * - * @param {string} id A React DOM ID, maybe. - * @return {boolean} True if the string is a valid React DOM ID. - * @private - */ -function isValidID(id) { - return id === '' || ( - id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR - ); -} + // Handle . + if (type === DefaultRoute.type) { + invariant( + parentRoute, + ' must have a parent ' + ); -/** - * Checks if the first ID is an ancestor of or equal to the second ID. - * - * @param {string} ancestorID - * @param {string} descendantID - * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. - * @internal - */ -function isAncestorIDOf(ancestorID, descendantID) { - return ( - descendantID.indexOf(ancestorID) === 0 && - isBoundary(descendantID, ancestorID.length) - ); -} + invariant( + parentRoute.defaultRoute == null, + 'You may not have more than one per ' + ); -/** - * Gets the parent ID of the supplied React DOM ID, `id`. - * - * @param {string} id ID of a component. - * @return {string} ID of the parent, or an empty string. - * @private - */ -function getParentID(id) { - return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : ''; -} + parentRoute.defaultRoute = route; -/** - * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the - * supplied `destinationID`. If they are equal, the ID is returned. - * - * @param {string} ancestorID ID of an ancestor node of `destinationID`. - * @param {string} destinationID ID of the destination node. - * @return {string} Next ID on the path from `ancestorID` to `destinationID`. - * @private - */ -function getNextDescendantID(ancestorID, destinationID) { - ("production" !== "production" ? invariant( - isValidID(ancestorID) && isValidID(destinationID), - 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', - ancestorID, - destinationID - ) : invariant(isValidID(ancestorID) && isValidID(destinationID))); - ("production" !== "production" ? invariant( - isAncestorIDOf(ancestorID, destinationID), - 'getNextDescendantID(...): React has made an invalid assumption about ' + - 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', - ancestorID, - destinationID - ) : invariant(isAncestorIDOf(ancestorID, destinationID))); - if (ancestorID === destinationID) { - return ancestorID; - } - // Skip over the ancestor and the immediate separator. Traverse until we hit - // another separator or we reach the end of `destinationID`. - var start = ancestorID.length + SEPARATOR_LENGTH; - for (var i = start; i < destinationID.length; i++) { - if (isBoundary(destinationID, i)) { - break; - } + return null; } - return destinationID.substr(0, i); -} -/** - * Gets the nearest common ancestor ID of two IDs. - * - * Using this ID scheme, the nearest common ancestor ID is the longest common - * prefix of the two IDs that immediately preceded a "marker" in both strings. - * - * @param {string} oneID - * @param {string} twoID - * @return {string} Nearest common ancestor ID, or the empty string if none. - * @private - */ -function getFirstCommonAncestorID(oneID, twoID) { - var minLength = Math.min(oneID.length, twoID.length); - if (minLength === 0) { - return ''; - } - var lastCommonMarkerIndex = 0; - // Use `<=` to traverse until the "EOL" of the shorter string. - for (var i = 0; i <= minLength; i++) { - if (isBoundary(oneID, i) && isBoundary(twoID, i)) { - lastCommonMarkerIndex = i; - } else if (oneID.charAt(i) !== twoID.charAt(i)) { - break; - } - } - var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); - ("production" !== "production" ? invariant( - isValidID(longestCommonID), - 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', - oneID, - twoID, - longestCommonID - ) : invariant(isValidID(longestCommonID))); - return longestCommonID; -} + route.childRoutes = createRoutesFromChildren(props.children, route, namedRoutes); -/** - * Traverses the parent path between two IDs (either up or down). The IDs must - * not be the same, and there must exist a parent path between them. If the - * callback returns `false`, traversal is stopped. - * - * @param {?string} start ID at which to start traversal. - * @param {?string} stop ID at which to end traversal. - * @param {function} cb Callback to invoke each ID with. - * @param {?boolean} skipFirst Whether or not to skip the first node. - * @param {?boolean} skipLast Whether or not to skip the last node. - * @private - */ -function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { - start = start || ''; - stop = stop || ''; - ("production" !== "production" ? invariant( - start !== stop, - 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', - start - ) : invariant(start !== stop)); - var traverseUp = isAncestorIDOf(stop, start); - ("production" !== "production" ? invariant( - traverseUp || isAncestorIDOf(start, stop), - 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + - 'not have a parent path.', - start, - stop - ) : invariant(traverseUp || isAncestorIDOf(start, stop))); - // Traverse from `start` to `stop` one depth at a time. - var depth = 0; - var traverse = traverseUp ? getParentID : getNextDescendantID; - for (var id = start; /* until break */; id = traverse(id, stop)) { - var ret; - if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { - ret = cb(id, traverseUp, arg); - } - if (ret === false || id === stop) { - // Only break //after// visiting `stop`. - break; - } - ("production" !== "production" ? invariant( - depth++ < MAX_TREE_DEPTH, - 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + - 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', - start, stop - ) : invariant(depth++ < MAX_TREE_DEPTH)); - } + return route; } /** - * Manages the IDs assigned to DOM representations of React components. This - * uses a specific scheme in order to traverse the DOM efficiently (e.g. in - * order to simulate events). - * - * @internal + * Creates and returns an array of route objects from the given ReactChildren. */ -var ReactInstanceHandles = { - - /** - * Constructs a React root ID - * @return {string} A React root ID. - */ - createReactRootID: function() { - return getReactRootIDString(ReactRootIndex.createReactRootIndex()); - }, - - /** - * Constructs a React ID by joining a root ID with a name. - * - * @param {string} rootID Root ID of a parent component. - * @param {string} name A component's name (as flattened children). - * @return {string} A React ID. - * @internal - */ - createReactID: function(rootID, name) { - return rootID + name; - }, +function createRoutesFromChildren(children, parentRoute, namedRoutes) { + var routes = []; - /** - * Gets the DOM ID of the React component that is the root of the tree that - * contains the React component with the supplied DOM ID. - * - * @param {string} id DOM ID of a React component. - * @return {?string} DOM ID of the React component that is the root. - * @internal - */ - getReactRootIDFromNodeID: function(id) { - if (id && id.charAt(0) === SEPARATOR && id.length > 1) { - var index = id.indexOf(SEPARATOR, 1); - return index > -1 ? id.substr(0, index) : id; - } - return null; - }, + React.Children.forEach(children, function (child) { + // Exclude s and s. + if (child = createRoute(child, parentRoute, namedRoutes)) + routes.push(child); + }); - /** - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that - * should would receive a `mouseEnter` or `mouseLeave` event. - * - * NOTE: Does not invoke the callback on the nearest common ancestor because - * nothing "entered" or "left" that element. - * - * @param {string} leaveID ID being left. - * @param {string} enterID ID being entered. - * @param {function} cb Callback to invoke on each entered/left ID. - * @param {*} upArg Argument to invoke the callback with on left IDs. - * @param {*} downArg Argument to invoke the callback with on entered IDs. - * @internal - */ - traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { - var ancestorID = getFirstCommonAncestorID(leaveID, enterID); - if (ancestorID !== leaveID) { - traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); - } - if (ancestorID !== enterID) { - traverseParentPath(ancestorID, enterID, cb, downArg, true, false); - } - }, + return routes; +} - /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseTwoPhase: function(targetID, cb, arg) { - if (targetID) { - traverseParentPath('', targetID, cb, arg, true, false); - traverseParentPath(targetID, '', cb, arg, false, true); - } - }, +module.exports = createRoutesFromChildren; - /** - * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For - * example, passing `.0.$row-0.1` would result in `cb` getting called - * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseAncestors: function(targetID, cb, arg) { - traverseParentPath('', targetID, cb, arg, true, false); - }, +},{"../components/DefaultRoute":3,"../components/NotFoundRoute":5,"../components/Redirect":6,"../components/Route":7,"./Path":19,"react/lib/invariant":39,"react/lib/warning":40}],26:[function(_dereq_,module,exports){ +var invariant = _dereq_('react/lib/invariant'); +var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; - /** - * Exposed for unit testing. - * @private - */ - _getFirstCommonAncestorID: getFirstCommonAncestorID, +/** + * Returns the current scroll position of the window as { x, y }. + */ +function getWindowScrollPosition() { + invariant( + canUseDOM, + 'Cannot get current scroll position without a DOM' + ); - /** - * Exposed for unit testing. - * @private - */ - _getNextDescendantID: getNextDescendantID, + return { + x: window.scrollX, + y: window.scrollY + }; +} - isAncestorIDOf: isAncestorIDOf, +module.exports = getWindowScrollPosition; - SEPARATOR: SEPARATOR +},{"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],27:[function(_dereq_,module,exports){ +function reversedArray(array) { + return array.slice(0).reverse(); +} -}; +module.exports = reversedArray; -module.exports = ReactInstanceHandles; +},{}],28:[function(_dereq_,module,exports){ +var createRouter = _dereq_('./createRouter'); -},{"./ReactRootIndex":57,"./invariant":69}],52:[function(_dereq_,module,exports){ /** - * Copyright 2014, Facebook, Inc. - * All rights reserved. + * A high-level convenience method that creates, configures, and + * runs a router in one shot. The method signature is: * - * 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. + * Router.run(routes[, location ], callback); + * + * Using `window.location.hash` to manage the URL, you could do: + * + * Router.run(routes, function (Handler) { + * React.render(, document.body); + * }); + * + * Using HTML5 history and a custom "cursor" prop: + * + * Router.run(routes, Router.HistoryLocation, function (Handler) { + * React.render(, document.body); + * }); + * + * Returns the newly created router. * - * @providesModule ReactLegacyElement + * Note: If you need to specify further options for your router such + * as error/abort handling or custom scroll behavior, use Router.create + * instead. + * + * var router = Router.create(options); + * router.run(function (Handler) { + * // ... + * }); */ +function runRouter(routes, location, callback) { + if (typeof location === 'function') { + callback = location; + location = null; + } -"use strict"; - -var ReactCurrentOwner = _dereq_("./ReactCurrentOwner"); - -var invariant = _dereq_("./invariant"); -var monitorCodeUse = _dereq_("./monitorCodeUse"); -var warning = _dereq_("./warning"); + var router = createRouter({ + routes: routes, + location: location + }); -var legacyFactoryLogs = {}; -function warnForLegacyFactoryCall() { - if (!ReactLegacyElementFactory._isLegacyCallWarningEnabled) { - return; - } - var owner = ReactCurrentOwner.current; - var name = owner && owner.constructor ? owner.constructor.displayName : ''; - if (!name) { - name = 'Something'; - } - if (legacyFactoryLogs.hasOwnProperty(name)) { - return; - } - legacyFactoryLogs[name] = true; - ("production" !== "production" ? warning( - false, - name + ' is calling a React component directly. ' + - 'Use a factory or JSX instead. See: http://fb.me/react-legacyfactory' - ) : null); - monitorCodeUse('react_legacy_factory_call', { version: 3, name: name }); -} + router.run(callback); -function warnForPlainFunctionType(type) { - var isReactClass = - type.prototype && - typeof type.prototype.mountComponent === 'function' && - typeof type.prototype.receiveComponent === 'function'; - if (isReactClass) { - ("production" !== "production" ? warning( - false, - 'Did not expect to get a React class here. Use `Component` instead ' + - 'of `Component.type` or `this.constructor`.' - ) : null); - } else { - if (!type._reactWarnedForThisType) { - try { - type._reactWarnedForThisType = true; - } catch (x) { - // just incase this is a frozen object or some special object - } - monitorCodeUse( - 'react_non_component_in_jsx', - { version: 3, name: type.name } - ); - } - ("production" !== "production" ? warning( - false, - 'This JSX uses a plain function. Only React components are ' + - 'valid in React\'s JSX transform.' - ) : null); - } + return router; } -function warnForNonLegacyFactory(type) { - ("production" !== "production" ? warning( - false, - 'Do not pass React.DOM.' + type.type + ' to JSX or createFactory. ' + - 'Use the string "' + type.type + '" instead.' - ) : null); -} +module.exports = runRouter; -/** - * Transfer static properties from the source to the target. Functions are - * rebound to have this reflect the original source. - */ -function proxyStaticMethods(target, source) { - if (typeof source !== 'function') { - return; - } - for (var key in source) { - if (source.hasOwnProperty(key)) { - var value = source[key]; - if (typeof value === 'function') { - var bound = value.bind(source); - // Copy any properties defined on the function, such as `isRequired` on - // a PropTypes validator. - for (var k in value) { - if (value.hasOwnProperty(k)) { - bound[k] = value[k]; - } - } - target[key] = bound; - } else { - target[key] = value; - } - } +},{"./createRouter":24}],29:[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); } -// We use an object instead of a boolean because booleans are ignored by our -// mocking libraries when these factories gets mocked. -var LEGACY_MARKER = {}; -var NON_LEGACY_MARKER = {}; - -var ReactLegacyElementFactory = {}; - -ReactLegacyElementFactory.wrapCreateFactory = function(createFactory) { - var legacyCreateFactory = function(type) { - if (typeof type !== 'function') { - // Non-function types cannot be legacy factories - return createFactory(type); - } - - if (type.isReactNonLegacyFactory) { - // This is probably a factory created by ReactDOM we unwrap it to get to - // the underlying string type. It shouldn't have been passed here so we - // warn. - if ("production" !== "production") { - warnForNonLegacyFactory(type); - } - return createFactory(type.type); - } - - if (type.isReactLegacyFactory) { - // This is probably a legacy factory created by ReactCompositeComponent. - // We unwrap it to get to the underlying class. - return createFactory(type.type); - } +module.exports = supportsHistory; - if ("production" !== "production") { - warnForPlainFunctionType(type); - } +},{}],30:[function(_dereq_,module,exports){ +module.exports = _dereq_('./lib'); - // Unless it's a legacy factory, then this is probably a plain function, - // that is expecting to be invoked by JSX. We can just return it as is. - return type; - }; - return legacyCreateFactory; -}; +},{"./lib":31}],31:[function(_dereq_,module,exports){ +// Load modules -ReactLegacyElementFactory.wrapCreateElement = function(createElement) { - var legacyCreateElement = function(type, props, children) { - if (typeof type !== 'function') { - // Non-function types cannot be legacy factories - return createElement.apply(this, arguments); - } +var Stringify = _dereq_('./stringify'); +var Parse = _dereq_('./parse'); - var args; - if (type.isReactNonLegacyFactory) { - // This is probably a factory created by ReactDOM we unwrap it to get to - // the underlying string type. It shouldn't have been passed here so we - // warn. - if ("production" !== "production") { - warnForNonLegacyFactory(type); - } - args = Array.prototype.slice.call(arguments, 0); - args[0] = type.type; - return createElement.apply(this, args); - } +// Declare internals - if (type.isReactLegacyFactory) { - // This is probably a legacy factory created by ReactCompositeComponent. - // We unwrap it to get to the underlying class. - if (type._isMockFunction) { - // If this is a mock function, people will expect it to be called. We - // will actually call the original mock factory function instead. This - // future proofs unit testing that assume that these are classes. - type.type._mockedReactClassConstructor = type; - } - args = Array.prototype.slice.call(arguments, 0); - args[0] = type.type; - return createElement.apply(this, args); - } +var internals = {}; - if ("production" !== "production") { - warnForPlainFunctionType(type); - } - // This is being called with a plain function we should invoke it - // immediately as if this was used with legacy JSX. - return type.apply(null, Array.prototype.slice.call(arguments, 1)); - }; - return legacyCreateElement; +module.exports = { + stringify: Stringify, + parse: Parse }; -ReactLegacyElementFactory.wrapFactory = function(factory) { - ("production" !== "production" ? invariant( - typeof factory === 'function', - 'This is suppose to accept a element factory' - ) : invariant(typeof factory === 'function')); - var legacyElementFactory = function(config, children) { - // This factory should not be called when JSX is used. Use JSX instead. - if ("production" !== "production") { - warnForLegacyFactoryCall(); - } - return factory.apply(this, arguments); - }; - proxyStaticMethods(legacyElementFactory, factory.type); - legacyElementFactory.isReactLegacyFactory = LEGACY_MARKER; - legacyElementFactory.type = factory.type; - return legacyElementFactory; -}; +},{"./parse":32,"./stringify":33}],32:[function(_dereq_,module,exports){ +// Load modules -// This is used to mark a factory that will remain. E.g. we're allowed to call -// it as a function. However, you're not suppose to pass it to createElement -// or createFactory, so it will warn you if you do. -ReactLegacyElementFactory.markNonLegacyFactory = function(factory) { - factory.isReactNonLegacyFactory = NON_LEGACY_MARKER; - return factory; -}; +var Utils = _dereq_('./utils'); -// Checks if a factory function is actually a legacy factory pretending to -// be a class. -ReactLegacyElementFactory.isValidFactory = function(factory) { - // TODO: This will be removed and moved into a class validator or something. - return typeof factory === 'function' && - factory.isReactLegacyFactory === LEGACY_MARKER; -}; -ReactLegacyElementFactory.isValidClass = function(factory) { - if ("production" !== "production") { - ("production" !== "production" ? warning( - false, - 'isValidClass is deprecated and will be removed in a future release. ' + - 'Use a more specific validator instead.' - ) : null); - } - return ReactLegacyElementFactory.isValidFactory(factory); -}; +// Declare internals -ReactLegacyElementFactory._isLegacyCallWarningEnabled = true; +var internals = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000 +}; -module.exports = ReactLegacyElementFactory; -},{"./ReactCurrentOwner":47,"./invariant":69,"./monitorCodeUse":74,"./warning":75}],53:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactMarkupChecksum - */ +internals.parseValues = function (str, options) { -"use strict"; + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); -var adler32 = _dereq_("./adler32"); + for (var i = 0, il = parts.length; i < il; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; -var ReactMarkupChecksum = { - CHECKSUM_ATTR_NAME: 'data-react-checksum', + if (pos === -1) { + obj[Utils.decode(part)] = ''; + } + else { + var key = Utils.decode(part.slice(0, pos)); + var val = Utils.decode(part.slice(pos + 1)); - /** - * @param {string} markup Markup string - * @return {string} Markup string with checksum attribute attached - */ - addChecksumToMarkup: function(markup) { - var checksum = adler32(markup); - return markup.replace( - '>', - ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' - ); - }, + if (!obj[key]) { + obj[key] = val; + } + else { + obj[key] = [].concat(obj[key]).concat(val); + } + } + } - /** - * @param {string} markup to use - * @param {DOMElement} element root React element - * @returns {boolean} whether or not the markup is the same - */ - canReuseMarkup: function(markup, element) { - var existingChecksum = element.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); - existingChecksum = existingChecksum && parseInt(existingChecksum, 10); - var markupChecksum = adler32(markup); - return markupChecksum === existingChecksum; - } + return obj; }; -module.exports = ReactMarkupChecksum; - -},{"./adler32":62}],54:[function(_dereq_,module,exports){ -/** - * Copyright 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 ReactNativeComponent - */ -"use strict"; +internals.parseObject = function (chain, val, options) { -var assign = _dereq_("./Object.assign"); -var invariant = _dereq_("./invariant"); + if (!chain.length) { + return val; + } -var genericComponentClass = null; -// This registry keeps track of wrapper classes around native tags -var tagToComponentClass = {}; + var root = chain.shift(); -var ReactNativeComponentInjection = { - // This accepts a class that receives the tag string. This is a catch all - // that can render any kind of tag. - injectGenericComponentClass: function(componentClass) { - genericComponentClass = componentClass; - }, - // This accepts a keyed object with classes as values. Each key represents a - // tag. That particular tag will use this class instead of the generic one. - injectComponentClasses: function(componentClasses) { - assign(tagToComponentClass, componentClasses); - } -}; + 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) { -/** - * Create an internal class for a specific tag. - * - * @param {string} tag The tag for which to create an internal instance. - * @param {any} props The props passed to the instance constructor. - * @return {ReactComponent} component The injected empty component. - */ -function createInstanceForTag(tag, props, parentType) { - var componentClass = tagToComponentClass[tag]; - if (componentClass == null) { - ("production" !== "production" ? invariant( - genericComponentClass, - 'There is no registered component for the tag %s', - tag - ) : invariant(genericComponentClass)); - return new genericComponentClass(tag, props); - } - if (parentType === tag) { - // Avoid recursion - ("production" !== "production" ? invariant( - genericComponentClass, - 'There is no registered component for the tag %s', - tag - ) : invariant(genericComponentClass)); - return new genericComponentClass(tag, props); - } - // Unwrap legacy factories - return new componentClass.type(props); -} + obj = []; + obj[index] = internals.parseObject(chain, val, options); + } + else { + obj[cleanRoot] = internals.parseObject(chain, val, options); + } + } -var ReactNativeComponent = { - createInstanceForTag: createInstanceForTag, - injection: ReactNativeComponentInjection, + return obj; }; -module.exports = ReactNativeComponent; -},{"./Object.assign":43,"./invariant":69}],55:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactPropTransferer - */ +internals.parseKeys = function (key, val, options) { -"use strict"; + if (!key) { + return; + } -var assign = _dereq_("./Object.assign"); -var emptyFunction = _dereq_("./emptyFunction"); -var invariant = _dereq_("./invariant"); -var joinClasses = _dereq_("./joinClasses"); -var warning = _dereq_("./warning"); + // The regex chunks -var didWarn = false; + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; -/** - * Creates a transfer strategy that will merge prop values using the supplied - * `mergeStrategy`. If a prop was previously unset, this just sets it. - * - * @param {function} mergeStrategy - * @return {function} - */ -function createTransferStrategy(mergeStrategy) { - return function(props, key, value) { - if (!props.hasOwnProperty(key)) { - props[key] = value; - } else { - props[key] = mergeStrategy(props[key], value); - } - }; -} + // Get the parent -var transferStrategyMerge = createTransferStrategy(function(a, b) { - // `merge` overrides the first object's (`props[key]` above) keys using the - // second object's (`value`) keys. An object's style's existing `propA` would - // get overridden. Flip the order here. - return assign({}, b, a); -}); + var segment = parent.exec(key); -/** - * Transfer strategies dictate how props are transferred by `transferPropsTo`. - * NOTE: if you add any more exceptions to this list you should be sure to - * update `cloneWithProps()` accordingly. - */ -var TransferStrategies = { - /** - * Never transfer `children`. - */ - children: emptyFunction, - /** - * Transfer the `className` prop by merging them. - */ - className: createTransferStrategy(joinClasses), - /** - * Transfer the `style` prop (which is an object) by merging them. - */ - style: transferStrategyMerge -}; + // Don't allow them to overwrite object prototype properties -/** - * Mutates the first argument by transferring the properties from the second - * argument. - * - * @param {object} props - * @param {object} newProps - * @return {object} - */ -function transferInto(props, newProps) { - for (var thisKey in newProps) { - if (!newProps.hasOwnProperty(thisKey)) { - continue; + if (Object.prototype.hasOwnProperty(segment[1])) { + return; } - var transferStrategy = TransferStrategies[thisKey]; + // Stash the parent if it exists - if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { - transferStrategy(props, thisKey, newProps[thisKey]); - } else if (!props.hasOwnProperty(thisKey)) { - props[thisKey] = newProps[thisKey]; + var keys = []; + if (segment[1]) { + keys.push(segment[1]); } - } - return props; -} - -/** - * ReactPropTransferer are capable of transferring props to another component - * using a `transferPropsTo` method. - * - * @class ReactPropTransferer - */ -var ReactPropTransferer = { - TransferStrategies: TransferStrategies, + // Loop through children appending to the array until we hit depth - /** - * Merge two props objects using TransferStrategies. - * - * @param {object} oldProps original props (they take precedence) - * @param {object} newProps new props to merge in - * @return {object} a new object containing both sets of props merged. - */ - mergeProps: function(oldProps, newProps) { - return transferInto(assign({}, oldProps), newProps); - }, + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { - /** - * @lends {ReactPropTransferer.prototype} - */ - Mixin: { - - /** - * Transfer props from this component to a target component. - * - * Props that do not have an explicit transfer strategy will be transferred - * only if the target component does not already have the prop set. - * - * This is usually used to pass down props to a returned root component. - * - * @param {ReactElement} element Component receiving the properties. - * @return {ReactElement} The supplied `component`. - * @final - * @protected - */ - transferPropsTo: function(element) { - ("production" !== "production" ? invariant( - element._owner === this, - '%s: You can\'t call transferPropsTo() on a component that you ' + - 'don\'t own, %s. This usually means you are calling ' + - 'transferPropsTo() on a component passed in as props or children.', - this.constructor.displayName, - typeof element.type === 'string' ? - element.type : - element.type.displayName - ) : invariant(element._owner === this)); - - if ("production" !== "production") { - if (!didWarn) { - didWarn = true; - ("production" !== "production" ? warning( - false, - 'transferPropsTo is deprecated. ' + - 'See http://fb.me/react-transferpropsto for more information.' - ) : null); + ++i; + if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + keys.push(segment[1]); } - } + } - // Because elements are immutable we have to merge into the existing - // props object rather than clone it. - transferInto(element.props, this.props); + // If there's a remainder, just add whatever is left - return element; + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); } - } + return internals.parseObject(keys, val, options); }; -module.exports = ReactPropTransferer; -},{"./Object.assign":43,"./emptyFunction":65,"./invariant":69,"./joinClasses":71,"./warning":75}],56:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactPutListenerQueue - */ +module.exports = function (str, options) { -"use strict"; + if (str === '' || + str === null || + typeof str === 'undefined') { -var PooledClass = _dereq_("./PooledClass"); -var ReactBrowserEventEmitter = _dereq_("./ReactBrowserEventEmitter"); + return {}; + } -var assign = _dereq_("./Object.assign"); + 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; -function ReactPutListenerQueue() { - this.listenersToPut = []; -} + var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; + var obj = {}; -assign(ReactPutListenerQueue.prototype, { - enqueuePutListener: function(rootNodeID, propKey, propValue) { - this.listenersToPut.push({ - rootNodeID: rootNodeID, - propKey: propKey, - propValue: propValue - }); - }, + // Iterate over the keys and setup the new object - putListeners: function() { - for (var i = 0; i < this.listenersToPut.length; i++) { - var listenerToPut = this.listenersToPut[i]; - ReactBrowserEventEmitter.putListener( - listenerToPut.rootNodeID, - listenerToPut.propKey, - listenerToPut.propValue - ); + 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); } - }, - - reset: function() { - this.listenersToPut.length = 0; - }, - - destructor: function() { - this.reset(); - } -}); -PooledClass.addPoolingTo(ReactPutListenerQueue); + return Utils.compact(obj); +}; -module.exports = ReactPutListenerQueue; +},{"./utils":34}],33:[function(_dereq_,module,exports){ +// Load modules -},{"./Object.assign":43,"./PooledClass":44,"./ReactBrowserEventEmitter":45}],57:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ReactRootIndex - * @typechecks - */ +var Utils = _dereq_('./utils'); -"use strict"; -var ReactRootIndexInjection = { - /** - * @param {function} _createReactRootIndex - */ - injectCreateReactRootIndex: function(_createReactRootIndex) { - ReactRootIndex.createReactRootIndex = _createReactRootIndex; - } -}; +// Declare internals -var ReactRootIndex = { - createReactRootIndex: null, - injection: ReactRootIndexInjection +var internals = { + delimiter: '&' }; -module.exports = ReactRootIndex; - -},{}],58:[function(_dereq_,module,exports){ -/** - * Copyright 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 ReactServerRenderingTransaction - * @typechecks - */ -"use strict"; +internals.stringify = function (obj, prefix) { -var PooledClass = _dereq_("./PooledClass"); -var CallbackQueue = _dereq_("./CallbackQueue"); -var ReactPutListenerQueue = _dereq_("./ReactPutListenerQueue"); -var Transaction = _dereq_("./Transaction"); + if (Utils.isBuffer(obj)) { + obj = obj.toString(); + } + else if (obj instanceof Date) { + obj = obj.toISOString(); + } + else if (obj === null) { + obj = ''; + } -var assign = _dereq_("./Object.assign"); -var emptyFunction = _dereq_("./emptyFunction"); + if (typeof obj === 'string' || + typeof obj === 'number' || + typeof obj === 'boolean') { -/** - * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks - * during the performing of the transaction. - */ -var ON_DOM_READY_QUEUEING = { - /** - * Initializes the internal `onDOMReady` queue. - */ - initialize: function() { - this.reactMountReady.reset(); - }, + return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; + } - close: emptyFunction -}; + var values = []; -var PUT_LISTENER_QUEUEING = { - initialize: function() { - this.putListenerQueue.reset(); - }, + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']')); + } + } - close: emptyFunction + return values; }; -/** - * Executed within the scope of the `Transaction` instance. Consider these as - * being member methods, but with an implied ordering while being isolated from - * each other. - */ -var TRANSACTION_WRAPPERS = [ - PUT_LISTENER_QUEUEING, - ON_DOM_READY_QUEUEING -]; - -/** - * @class ReactServerRenderingTransaction - * @param {boolean} renderToStaticMarkup - */ -function ReactServerRenderingTransaction(renderToStaticMarkup) { - this.reinitializeTransaction(); - this.renderToStaticMarkup = renderToStaticMarkup; - this.reactMountReady = CallbackQueue.getPooled(null); - this.putListenerQueue = ReactPutListenerQueue.getPooled(); -} -var Mixin = { - /** - * @see Transaction - * @abstract - * @final - * @return {array} Empty list of operation wrap proceedures. - */ - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, +module.exports = function (obj, options) { - /** - * @return {object} The queue to collect `onDOMReady` callbacks with. - */ - getReactMountReady: function() { - return this.reactMountReady; - }, + options = options || {}; + var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; - getPutListenerQueue: function() { - return this.putListenerQueue; - }, + var keys = []; - /** - * `PooledClass` looks for this, and will invoke this before allowing this - * instance to be resused. - */ - destructor: function() { - CallbackQueue.release(this.reactMountReady); - this.reactMountReady = null; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + keys = keys.concat(internals.stringify(obj[key], key)); + } + } - ReactPutListenerQueue.release(this.putListenerQueue); - this.putListenerQueue = null; - } + return keys.join(delimiter); }; +},{"./utils":34}],34:[function(_dereq_,module,exports){ +// Load modules -assign( - ReactServerRenderingTransaction.prototype, - Transaction.Mixin, - Mixin -); -PooledClass.addPoolingTo(ReactServerRenderingTransaction); +// Declare internals -module.exports = ReactServerRenderingTransaction; +var internals = {}; -},{"./CallbackQueue":37,"./Object.assign":43,"./PooledClass":44,"./ReactPutListenerQueue":56,"./Transaction":59,"./emptyFunction":65}],59:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 Transaction - */ -"use strict"; +exports.arrayToObject = function (source) { -var invariant = _dereq_("./invariant"); + var obj = {}; + for (var i = 0, il = source.length; i < il; ++i) { + if (typeof source[i] !== 'undefined') { -/** - * `Transaction` creates a black box that is able to wrap any method such that - * certain invariants are maintained before and after the method is invoked - * (Even if an exception is thrown while invoking the wrapped method). Whoever - * instantiates a transaction can provide enforcers of the invariants at - * creation time. The `Transaction` class itself will supply one additional - * automatic invariant for you - the invariant that any transaction instance - * should not be run while it is already being run. You would typically create a - * single instance of a `Transaction` for reuse multiple times, that potentially - * is used to wrap several different methods. Wrappers are extremely simple - - * they only require implementing two methods. - * - *
- *                       wrappers (injected at creation time)
- *                                      +        +
- *                                      |        |
- *                    +-----------------|--------|--------------+
- *                    |                 v        |              |
- *                    |      +---------------+   |              |
- *                    |   +--|    wrapper1   |---|----+         |
- *                    |   |  +---------------+   v    |         |
- *                    |   |          +-------------+  |         |
- *                    |   |     +----|   wrapper2  |--------+   |
- *                    |   |     |    +-------------+  |     |   |
- *                    |   |     |                     |     |   |
- *                    |   v     v                     v     v   | wrapper
- *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
- * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
- * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | +---+ +---+   +---------+   +---+ +---+ |
- *                    |  initialize                    close    |
- *                    +-----------------------------------------+
- * 
- * - * Use cases: - * - Preserving the input selection ranges before/after reconciliation. - * Restoring selection even in the event of an unexpected error. - * - Deactivating events while rearranging the DOM, preventing blurs/focuses, - * while guaranteeing that afterwards, the event system is reactivated. - * - Flushing a queue of collected DOM mutations to the main UI thread after a - * reconciliation takes place in a worker thread. - * - Invoking any collected `componentDidUpdate` callbacks after rendering new - * content. - * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue - * to preserve the `scrollTop` (an automatic scroll aware DOM). - * - (Future use case): Layout calculations before and after DOM upates. - * - * Transactional plugin API: - * - A module that has an `initialize` method that returns any precomputation. - * - and a `close` method that accepts the precomputation. `close` is invoked - * when the wrapped process is completed, or has failed. - * - * @param {Array} transactionWrapper Wrapper modules - * that implement `initialize` and `close`. - * @return {Transaction} Single transaction for reuse in thread. - * - * @class Transaction - */ -var Mixin = { - /** - * Sets up this instance so that it is prepared for collecting metrics. Does - * so such that this setup method may be used on an instance that is already - * initialized, in a way that does not consume additional memory upon reuse. - * That can be useful if you decide to make your subclass of this mixin a - * "PooledClass". - */ - reinitializeTransaction: function() { - this.transactionWrappers = this.getTransactionWrappers(); - if (!this.wrapperInitData) { - this.wrapperInitData = []; - } else { - this.wrapperInitData.length = 0; + obj[i] = source[i]; + } } - this._isInTransaction = false; - }, - _isInTransaction: false, + return obj; +}; - /** - * @abstract - * @return {Array} Array of transaction wrappers. - */ - getTransactionWrappers: null, - isInTransaction: function() { - return !!this._isInTransaction; - }, +exports.merge = function (target, source) { - /** - * Executes the function within a safety window. Use this for the top level - * methods that result in large amounts of computation/mutations that would - * need to be safety checked. - * - * @param {function} method Member of scope to call. - * @param {Object} scope Scope to invoke from. - * @param {Object?=} args... Arguments to pass to the method (optional). - * Helps prevent need to bind in many cases. - * @return Return value from `method`. - */ - perform: function(method, scope, a, b, c, d, e, f) { - ("production" !== "production" ? invariant( - !this.isInTransaction(), - 'Transaction.perform(...): Cannot initialize a transaction when there ' + - 'is already an outstanding transaction.' - ) : invariant(!this.isInTransaction())); - var errorThrown; - var ret; - try { - this._isInTransaction = true; - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // one of these calls threw. - errorThrown = true; - this.initializeAll(0); - ret = method.call(scope, a, b, c, d, e, f); - errorThrown = false; - } finally { - try { - if (errorThrown) { - // If `method` throws, prefer to show that stack trace over any thrown - // by invoking `closeAll`. - try { - this.closeAll(0); - } catch (err) { - } - } else { - // Since `method` didn't throw, we don't want to silence the exception - // here. - this.closeAll(0); - } - } finally { - this._isInTransaction = false; - } + if (!source) { + return target; } - return ret; - }, - initializeAll: function(startIndex) { - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - try { - // Catching errors makes debugging more difficult, so we start with the - // OBSERVED_ERROR state before overwriting it with the real return value - // of initialize -- if it's still set to OBSERVED_ERROR in the finally - // block, it means wrapper.initialize threw. - this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; - this.wrapperInitData[i] = wrapper.initialize ? - wrapper.initialize.call(this) : - null; - } finally { - if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { - // The initializer for wrapper i threw an error; initialize the - // remaining wrappers but silence any exceptions from them to ensure - // that the first error is the one to bubble up. - try { - this.initializeAll(i + 1); - } catch (err) { - } + 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; } - }, - /** - * Invokes each of `this.transactionWrappers.close[i]` functions, passing into - * them the respective return values of `this.transactionWrappers.init[i]` - * (`close`rs that correspond to initializers that failed will not be - * invoked). - */ - closeAll: function(startIndex) { - ("production" !== "production" ? invariant( - this.isInTransaction(), - 'Transaction.closeAll(): Cannot close transaction when none are open.' - ) : invariant(this.isInTransaction())); - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - var initData = this.wrapperInitData[i]; - var errorThrown; - try { - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // wrapper.close threw. - errorThrown = true; - if (initData !== Transaction.OBSERVED_ERROR) { - wrapper.close && wrapper.close.call(this, initData); + if (Array.isArray(target)) { + if (typeof source !== 'object') { + target.push(source); + return target; } - errorThrown = false; - } finally { - if (errorThrown) { - // The closer for wrapper i threw an error; close the remaining - // wrappers but silence any exceptions from them to ensure that the - // first error is the one to bubble up. - try { - this.closeAll(i + 1); - } catch (e) { - } + else { + target = exports.arrayToObject(target); } - } } - this.wrapperInitData.length = 0; - } -}; -var Transaction = { + var keys = Object.keys(source); + for (var k = 0, kl = keys.length; k < kl; ++k) { + var key = keys[k]; + var value = source[key]; - Mixin: Mixin, + if (value && + typeof value === 'object') { - /** - * Token to look for to determine if an error occured. - */ - OBSERVED_ERROR: {} + if (!target[key]) { + target[key] = value; + } + else { + target[key] = exports.merge(target[key], value); + } + } + else { + target[key] = value; + } + } + return target; }; -module.exports = Transaction; - -},{"./invariant":69}],60:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 ViewportMetrics - */ - -"use strict"; -var getUnboundedScrollPosition = _dereq_("./getUnboundedScrollPosition"); +exports.decode = function (str) { -var ViewportMetrics = { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } +}; - currentScrollLeft: 0, - currentScrollTop: 0, +exports.compact = function (obj, refs) { - refreshScrollValues: function() { - var scrollPosition = getUnboundedScrollPosition(window); - ViewportMetrics.currentScrollLeft = scrollPosition.x; - ViewportMetrics.currentScrollTop = scrollPosition.y; - } + if (typeof obj !== 'object' || + obj === null) { -}; + return obj; + } -module.exports = ViewportMetrics; + refs = refs || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } -},{"./getUnboundedScrollPosition":67}],61:[function(_dereq_,module,exports){ -/** - * Copyright 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 accumulateInto - */ + refs.push(obj); -"use strict"; + if (Array.isArray(obj)) { + var compacted = []; -var invariant = _dereq_("./invariant"); + for (var i = 0, l = obj.length; i < l; ++i) { + if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } -/** - * - * Accumulates items that must not be null or undefined into the first one. This - * is used to conserve memory by avoiding array allocations, and thus sacrifices - * API cleanness. Since `current` can be null before being passed in and not - * null after this function, make sure to assign it back to `current`: - * - * `a = accumulateInto(a, b);` - * - * This API should be sparingly used. Try `accumulate` for something cleaner. - * - * @return {*|array<*>} An accumulation of items. - */ + return compacted; + } -function accumulateInto(current, next) { - ("production" !== "production" ? invariant( - next != null, - 'accumulateInto(...): Accumulated items must not be null or undefined.' - ) : invariant(next != null)); - if (current == null) { - return next; - } + 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); + } - // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). - var currentIsArray = Array.isArray(current); - var nextIsArray = Array.isArray(next); + return obj; +}; - if (currentIsArray && nextIsArray) { - current.push.apply(current, next); - return current; - } - if (currentIsArray) { - current.push(next); - return current; - } +exports.isRegExp = function (obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +}; - if (nextIsArray) { - // A bit too dangerous to mutate `next`. - return [current].concat(next); - } - return [current, next]; -} +exports.isBuffer = function (obj) { -module.exports = accumulateInto; + if (typeof Buffer !== 'undefined') { + return Buffer.isBuffer(obj); + } + else { + return false; + } +}; -},{"./invariant":69}],62:[function(_dereq_,module,exports){ +},{}],35:[function(_dereq_,module,exports){ /** * Copyright 2013-2014, Facebook, Inc. * All rights reserved. @@ -6278,89 +2359,90 @@ module.exports = accumulateInto; * 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 adler32 + * @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 = { -/* jslint bitwise:true */ + canUseDOM: canUseDOM, -"use strict"; + canUseWorkers: typeof Worker !== 'undefined', -var MOD = 65521; - -// This is a clean-room implementation of adler32 designed for detecting -// if markup is not what we expect it to be. It does not need to be -// cryptographically strong, only reasonably good at detecting if markup -// generated on the server is different than that on the client. -function adler32(data) { - var a = 1; - var b = 0; - for (var i = 0; i < data.length; i++) { - a = (a + data.charCodeAt(i)) % MOD; - b = (b + a) % MOD; - } - return a | (b << 16); -} + canUseEventListeners: + canUseDOM && !!(window.addEventListener || window.attachEvent), + + canUseViewport: canUseDOM && !!window.screen, + + isInWorker: !canUseDOM // For now, this is true - might change in the future. + +}; -module.exports = adler32; +module.exports = ExecutionEnvironment; -},{}],63:[function(_dereq_,module,exports){ +},{}],36:[function(_dereq_,module,exports){ /** - * Copyright 2013-2014, Facebook, Inc. + * Copyright 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. * - * @typechecks - * @providesModule cloneWithProps + * @providesModule Object.assign */ -"use strict"; +// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign -var ReactElement = _dereq_("./ReactElement"); -var ReactPropTransferer = _dereq_("./ReactPropTransferer"); +function assign(target, sources) { + if (target == null) { + throw new TypeError('Object.assign target cannot be null or undefined'); + } -var keyOf = _dereq_("./keyOf"); -var warning = _dereq_("./warning"); + var to = Object(target); + var hasOwnProperty = Object.prototype.hasOwnProperty; -var CHILDREN_PROP = keyOf({children: null}); + for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { + var nextSource = arguments[nextIndex]; + if (nextSource == null) { + continue; + } -/** - * Sometimes you want to change the props of a child passed to you. Usually - * this is to add a CSS class. - * - * @param {object} child child component you'd like to clone - * @param {object} props props you'd like to modify. They will be merged - * as if you used `transferPropsTo()`. - * @return {object} a clone of child with props merged in. - */ -function cloneWithProps(child, props) { - if ("production" !== "production") { - ("production" !== "production" ? warning( - !child.ref, - 'You are calling cloneWithProps() on a child with a ref. This is ' + - 'dangerous because you\'re creating a new child which will not be ' + - 'added as a ref to its parent.' - ) : null); - } + var from = Object(nextSource); - var newProps = ReactPropTransferer.mergeProps(props, child.props); + // We don't currently support accessors nor proxies. Therefore this + // copy cannot throw. If we ever supported this then we must handle + // exceptions and side-effects. We don't support symbols so they won't + // be transferred. - // Use `child.props.children` if it is provided. - if (!newProps.hasOwnProperty(CHILDREN_PROP) && - child.props.hasOwnProperty(CHILDREN_PROP)) { - newProps.children = child.props.children; + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } } - // The current API doesn't retain _owner and _context, which is why this - // doesn't use ReactElement.cloneAndReplaceProps. - return ReactElement.createElement(child.type, newProps); -} + return to; +}; -module.exports = cloneWithProps; +module.exports = assign; -},{"./ReactElement":48,"./ReactPropTransferer":55,"./keyOf":73,"./warning":75}],64:[function(_dereq_,module,exports){ +},{}],37:[function(_dereq_,module,exports){ /** * Copyright 2013-2014, Facebook, Inc. * All rights reserved. @@ -6399,7 +2481,7 @@ function cx(classNames) { module.exports = cx; -},{}],65:[function(_dereq_,module,exports){ +},{}],38:[function(_dereq_,module,exports){ /** * Copyright 2013-2014, Facebook, Inc. * All rights reserved. @@ -6433,190 +2515,7 @@ emptyFunction.thatReturnsArgument = function(arg) { return arg; }; module.exports = emptyFunction; -},{}],66:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 forEachAccumulated - */ - -"use strict"; - -/** - * @param {array} an "accumulation" of items which is either an Array or - * a single item. Useful when paired with the `accumulate` module. This is a - * simple utility that allows us to reason about a collection of items, but - * handling the case when there is exactly one item (and we do not need to - * allocate an array). - */ -var forEachAccumulated = function(arr, cb, scope) { - if (Array.isArray(arr)) { - arr.forEach(cb, scope); - } else if (arr) { - cb.call(scope, arr); - } -}; - -module.exports = forEachAccumulated; - -},{}],67:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 getUnboundedScrollPosition - * @typechecks - */ - -"use strict"; - -/** - * Gets the scroll position of the supplied element or window. - * - * The return values are unbounded, unlike `getScrollPosition`. This means they - * may be negative or exceed the element boundaries (which is possible using - * inertial scrolling). - * - * @param {DOMWindow|DOMElement} scrollable - * @return {object} Map with `x` and `y` keys. - */ -function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; - } - return { - x: scrollable.scrollLeft, - y: scrollable.scrollTop - }; -} - -module.exports = getUnboundedScrollPosition; - -},{}],68:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 instantiateReactComponent - * @typechecks static-only - */ - -"use strict"; - -var warning = _dereq_("./warning"); - -var ReactElement = _dereq_("./ReactElement"); -var ReactLegacyElement = _dereq_("./ReactLegacyElement"); -var ReactNativeComponent = _dereq_("./ReactNativeComponent"); -var ReactEmptyComponent = _dereq_("./ReactEmptyComponent"); - -/** - * Given an `element` create an instance that will actually be mounted. - * - * @param {object} element - * @param {*} parentCompositeType The composite type that resolved this. - * @return {object} A new instance of the element's constructor. - * @protected - */ -function instantiateReactComponent(element, parentCompositeType) { - var instance; - - if ("production" !== "production") { - ("production" !== "production" ? warning( - element && (typeof element.type === 'function' || - typeof element.type === 'string'), - 'Only functions or strings can be mounted as React components.' - ) : null); - - // Resolve mock instances - if (element.type._mockedReactClassConstructor) { - // If this is a mocked class, we treat the legacy factory as if it was the - // class constructor for future proofing unit tests. Because this might - // be mocked as a legacy factory, we ignore any warnings triggerd by - // this temporary hack. - ReactLegacyElement._isLegacyCallWarningEnabled = false; - try { - instance = new element.type._mockedReactClassConstructor( - element.props - ); - } finally { - ReactLegacyElement._isLegacyCallWarningEnabled = true; - } - - // If the mock implementation was a legacy factory, then it returns a - // element. We need to turn this into a real component instance. - if (ReactElement.isValidElement(instance)) { - instance = new instance.type(instance.props); - } - - var render = instance.render; - if (!render) { - // For auto-mocked factories, the prototype isn't shimmed and therefore - // there is no render function on the instance. We replace the whole - // component with an empty component instance instead. - element = ReactEmptyComponent.getEmptyComponent(); - } else { - if (render._isMockFunction && !render._getMockImplementation()) { - // Auto-mocked components may have a prototype with a mocked render - // function. For those, we'll need to mock the result of the render - // since we consider undefined to be invalid results from render. - render.mockImplementation( - ReactEmptyComponent.getEmptyComponent - ); - } - instance.construct(element); - return instance; - } - } - } - - // Special case string values - if (typeof element.type === 'string') { - instance = ReactNativeComponent.createInstanceForTag( - element.type, - element.props, - parentCompositeType - ); - } else { - // Normal case for non-mocks and non-strings - instance = new element.type(element.props); - } - - if ("production" !== "production") { - ("production" !== "production" ? warning( - typeof instance.construct === 'function' && - typeof instance.mountComponent === 'function' && - typeof instance.receiveComponent === 'function', - 'Only React Components can be mounted.' - ) : null); - } - - // This actually sets up the internal instance. This will become decoupled - // from the public instance in a future diff. - instance.construct(element); - - return instance; -} - -module.exports = instantiateReactComponent; - -},{"./ReactElement":48,"./ReactEmptyComponent":49,"./ReactLegacyElement":52,"./ReactNativeComponent":54,"./warning":75}],69:[function(_dereq_,module,exports){ +},{}],39:[function(_dereq_,module,exports){ /** * Copyright 2013-2014, Facebook, Inc. * All rights reserved. @@ -6671,234 +2570,7 @@ var invariant = function(condition, format, a, b, c, d, e, f) { module.exports = invariant; -},{}],70:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 isEventSupported - */ - -"use strict"; - -var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); - -var useHasFeature; -if (ExecutionEnvironment.canUseDOM) { - useHasFeature = - document.implementation && - document.implementation.hasFeature && - // always returns true in newer browsers as per the standard. - // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature - document.implementation.hasFeature('', '') !== true; -} - -/** - * Checks if an event is supported in the current execution environment. - * - * NOTE: This will not work correctly for non-generic events such as `change`, - * `reset`, `load`, `error`, and `select`. - * - * Borrows from Modernizr. - * - * @param {string} eventNameSuffix Event name, e.g. "click". - * @param {?boolean} capture Check if the capture phase is supported. - * @return {boolean} True if the event is supported. - * @internal - * @license Modernizr 3.0.0pre (Custom Build) | MIT - */ -function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || - capture && !('addEventListener' in document)) { - return false; - } - - var eventName = 'on' + eventNameSuffix; - var isSupported = eventName in document; - - if (!isSupported) { - var element = document.createElement('div'); - element.setAttribute(eventName, 'return;'); - isSupported = typeof element[eventName] === 'function'; - } - - if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { - // This is the only way to test support for the `wheel` event in IE9+. - isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); - } - - return isSupported; -} - -module.exports = isEventSupported; - -},{"./ExecutionEnvironment":42}],71:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 joinClasses - * @typechecks static-only - */ - -"use strict"; - -/** - * Combines multiple className strings into one. - * http://jsperf.com/joinclasses-args-vs-array - * - * @param {...?string} classes - * @return {string} - */ -function joinClasses(className/*, ... */) { - if (!className) { - className = ''; - } - var nextClass; - var argLength = arguments.length; - if (argLength > 1) { - for (var ii = 1; ii < argLength; ii++) { - nextClass = arguments[ii]; - if (nextClass) { - className = (className ? className + ' ' : '') + nextClass; - } - } - } - return className; -} - -module.exports = joinClasses; - -},{}],72:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 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":69}],73:[function(_dereq_,module,exports){ -/** - * Copyright 2013-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 keyOf - */ - -/** - * Allows extraction of a minified key. Let's the build system minify keys - * without loosing the ability to dynamically use key strings as values - * themselves. Pass in an object with a single key/val pair and it will return - * you the string key of that single record. Suppose you want to grab the - * value for a key 'className' inside of an object. Key/val minification may - * have aliased that key to be 'xa12'. keyOf({className: null}) will return - * 'xa12' in that case. Resolve keys you want to use once at startup time, then - * reuse those resolutions. - */ -var keyOf = function(oneKeyObj) { - var key; - for (key in oneKeyObj) { - if (!oneKeyObj.hasOwnProperty(key)) { - continue; - } - return key; - } - return null; -}; - - -module.exports = keyOf; - -},{}],74:[function(_dereq_,module,exports){ -/** - * Copyright 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 monitorCodeUse - */ - -"use strict"; - -var invariant = _dereq_("./invariant"); - -/** - * Provides open-source compatible instrumentation for monitoring certain API - * uses before we're ready to issue a warning or refactor. It accepts an event - * name which may only contain the characters [a-z0-9_] and an optional data - * object with further information. - */ - -function monitorCodeUse(eventName, data) { - ("production" !== "production" ? invariant( - eventName && !/[^a-z0-9_]/.test(eventName), - 'You must provide an eventName using only the characters [a-z0-9_]' - ) : invariant(eventName && !/[^a-z0-9_]/.test(eventName))); -} - -module.exports = monitorCodeUse; - -},{"./invariant":69}],75:[function(_dereq_,module,exports){ +},{}],40:[function(_dereq_,module,exports){ /** * Copyright 2014, Facebook, Inc. * All rights reserved. @@ -6941,7 +2613,7 @@ if ("production" !== "production") { module.exports = warning; -},{"./emptyFunction":65}],76:[function(_dereq_,module,exports){ +},{"./emptyFunction":38}],41:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ @@ -6960,7 +2632,7 @@ define(function (_dereq_) { }); })(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(_dereq_); }); -},{"./Scheduler":78,"./async":79,"./makePromise":80}],77:[function(_dereq_,module,exports){ +},{"./Scheduler":43,"./async":44,"./makePromise":45}],42:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ @@ -7032,7 +2704,7 @@ define(function() { }); }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); -},{}],78:[function(_dereq_,module,exports){ +},{}],43:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ @@ -7116,7 +2788,7 @@ define(function(_dereq_) { }); }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); -},{"./Queue":77}],79:[function(_dereq_,module,exports){ +},{"./Queue":42}],44:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ @@ -7189,7 +2861,7 @@ define(function(_dereq_) { }); }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); -},{}],80:[function(_dereq_,module,exports){ +},{}],45:[function(_dereq_,module,exports){ /** @license MIT License (c) copyright 2010-2014 original author or authors */ /** @author Brian Cavalier */ /** @author John Hann */ @@ -7987,6 +3659,6 @@ define(function() { }); }(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); -},{}]},{},[10]) -(10) +},{}]},{},[9]) +(9) }); \ No newline at end of file diff --git a/dist/react-router.min.js b/dist/react-router.min.js index ae04b6d23f..e3245277dc 100644 --- a/dist/react-router.min.js +++ b/dist/react-router.min.js @@ -1,4 +1,2 @@ -!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;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&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}for(var i="function"==typeof require&&require,o=0;o component should not be rendered directly. You may be missing a wrapper around your list of routes.")}});module.exports=Route},{"../utils/withoutProperties":30}],9:[function(_dereq_,module){function makeMatch(route,params){return{route:route,params:params}}function getRootMatch(matches){return matches[matches.length-1]}function findMatches(path,routes,defaultRoute,notFoundRoute){for(var route,params,matches=null,i=0,len=routes.length;len>i;++i){if(route=routes[i],matches=findMatches(path,route.props.children,route.props.defaultRoute,route.props.notFoundRoute),null!=matches){var rootParams=getRootMatch(matches).params;return params=route.props.paramNames.reduce(function(params,paramName){return params[paramName]=rootParams[paramName],params},{}),matches.unshift(makeMatch(route,params)),matches}if(params=Path.extractParams(route.props.path,path))return[makeMatch(route,params)]}return defaultRoute&&(params=Path.extractParams(defaultRoute.props.path,path))?[makeMatch(defaultRoute,params)]:notFoundRoute&&(params=Path.extractParams(notFoundRoute.props.path,path))?[makeMatch(notFoundRoute,params)]:matches}function hasMatch(matches,match){return matches.some(function(m){if(m.route!==match.route)return!1;for(var property in m.params)if(m.params[property]!==match.params[property])return!1;return!0})}function runTransitionFromHooks(matches,transition,callback){var hooks=reversedArray(matches).map(function(match){return function(){var handler=match.route.props.handler;if(!transition.isAborted&&handler.willTransitionFrom)return handler.willTransitionFrom(transition,match.component);var promise=transition.promise;return delete transition.promise,promise}});runHooks(hooks,callback)}function runTransitionToHooks(matches,transition,query,callback){var hooks=matches.map(function(match){return function(){var handler=match.route.props.handler;!transition.isAborted&&handler.willTransitionTo&&handler.willTransitionTo(transition,match.params,query);var promise=transition.promise;return delete transition.promise,promise}});runHooks(hooks,callback)}function runHooks(hooks,callback){try{var promise=hooks.reduce(function(promise,hook){return promise?promise.then(hook):hook()},null)}catch(error){return callback(error)}promise?promise.then(function(){setTimeout(callback)},function(error){setTimeout(function(){callback(error)})}):callback()}function updateMatchComponents(matches,refs){for(var match,i=0,len=matches.length;len>i&&(match=matches[i],match.component=refs.__activeRoute__,null!=match.component);++i)refs=match.component.refs}function shouldUpdateScroll(currentMatches,previousMatches){var commonMatches=currentMatches.filter(function(match){return-1!==previousMatches.indexOf(match)});return!commonMatches.some(function(match){return match.route.props.ignoreScrollBehavior})}function returnNull(){return null}function routeIsActive(activeRoutes,routeName){return activeRoutes.some(function(route){return route.props.name===routeName})}function paramsAreActive(activeParams,params){for(var property in params)if(String(activeParams[property])!==String(params[property]))return!1;return!0}function queryIsActive(activeQuery,query){for(var property in query)if(String(activeQuery[property])!==String(query[property]))return!1;return!0}function defaultTransitionErrorHandler(error){throw error}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,warning=_dereq_("react/lib/warning"),invariant=_dereq_("react/lib/invariant"),objectAssign=_dereq_("react/lib/Object.assign"),HashLocation=_dereq_("../locations/HashLocation"),ActiveContext=_dereq_("../mixins/ActiveContext"),LocationContext=_dereq_("../mixins/LocationContext"),RouteContext=_dereq_("../mixins/RouteContext"),ScrollContext=_dereq_("../mixins/ScrollContext"),reversedArray=_dereq_("../utils/reversedArray"),Transition=_dereq_("../utils/Transition"),Redirect=_dereq_("../utils/Redirect"),Path=_dereq_("../utils/Path"),Route=_dereq_("./Route"),Routes=React.createClass({displayName:"Routes",mixins:[RouteContext,ActiveContext,LocationContext,ScrollContext],propTypes:{initialPath:React.PropTypes.string,initialMatches:React.PropTypes.array,onChange:React.PropTypes.func,onError:React.PropTypes.func.isRequired},getDefaultProps:function(){return{initialPath:null,initialMatches:[],onError:defaultTransitionErrorHandler}},getInitialState:function(){return{path:this.props.initialPath,matches:this.props.initialMatches}},componentDidMount:function(){warning(null==this._owner," should be rendered directly using React.renderComponent, not inside some other component's render method"),this._handleStateChange()},componentDidUpdate:function(){this._handleStateChange()},match:function(path){var routes=this.getRoutes();return findMatches(Path.withoutQuery(path),routes,this.props.defaultRoute,this.props.notFoundRoute)},updateLocation:function(path,actionType){this.state.path!==path&&(this.state.path&&this.recordScroll(this.state.path),this.dispatch(path,function(error,abortReason,nextState){error?this.props.onError.call(this,error):abortReason instanceof Redirect?this.replaceWith(abortReason.to,abortReason.params,abortReason.query):abortReason?this.goBack():(this._nextStateChangeHandler=this._finishTransitionTo.bind(this,path,actionType,this.state.matches),this.setState(nextState))}))},_handleStateChange:function(){this._nextStateChangeHandler&&(this._nextStateChangeHandler(),delete this._nextStateChangeHandler)},_finishTransitionTo:function(path,actionType,previousMatches){var currentMatches=this.state.matches;updateMatchComponents(currentMatches,this.refs),shouldUpdateScroll(currentMatches,previousMatches)&&this.updateScroll(path,actionType),this.props.onChange&&this.props.onChange.call(this)},dispatch:function(path,callback){var transition=new Transition(this,path),currentMatches=this.state?this.state.matches:[],nextMatches=this.match(path)||[];warning(nextMatches.length,'No route matches path "%s". Make sure you have somewhere in your ',path,path);var fromMatches,toMatches;currentMatches.length?(fromMatches=currentMatches.filter(function(match){return!hasMatch(nextMatches,match)}),toMatches=nextMatches.filter(function(match){return!hasMatch(currentMatches,match)})):(fromMatches=[],toMatches=nextMatches);var callbackScope=this,query=Path.extractQuery(path)||{};runTransitionFromHooks(fromMatches,transition,function(error){return error||transition.isAborted?callback.call(callbackScope,error,transition.abortReason):void runTransitionToHooks(toMatches,transition,query,function(error){if(error||transition.isAborted)return callback.call(callbackScope,error,transition.abortReason);var matches=currentMatches.slice(0,currentMatches.length-fromMatches.length).concat(toMatches),rootMatch=getRootMatch(matches),params=rootMatch&&rootMatch.params||{},routes=matches.map(function(match){return match.route});callback.call(callbackScope,null,null,{path:path,matches:matches,activeRoutes:routes,activeParams:params,activeQuery:query})})})},getHandlerProps:function(){var matches=this.state.matches,query=this.state.activeQuery,handler=returnNull,props={ref:null,params:null,query:null,activeRouteHandler:handler,key:null};return reversedArray(matches).forEach(function(match){var route=match.route;props=Route.getUnreservedProps(route.props),props.ref="__activeRoute__",props.params=match.params,props.query=query,props.activeRouteHandler=handler,route.props.addHandlerKey&&(props.key=Path.injectParams(route.props.path,match.params)),handler=function(props,addedProps){if(arguments.length>2&&"undefined"!=typeof arguments[2])throw new Error("Passing children to a route handler is not supported");return route.props.handler(objectAssign(props,addedProps))}.bind(this,props)}),props},getActiveComponent:function(){return this.refs.__activeRoute__},getCurrentPath:function(){return this.state.path},makePath:function(to,params,query){var path;if(Path.isAbsolute(to))path=Path.normalize(to);else{var namedRoutes=this.getNamedRoutes(),route=namedRoutes[to];invariant(route,'Unable to find a route named "%s". Make sure you have somewhere in your ',to,to),path=route.props.path}return Path.withQuery(Path.injectParams(path,params),query)},makeHref:function(to,params,query){var path=this.makePath(to,params,query);return this.getLocation()===HashLocation?"#"+path:path},transitionTo:function(to,params,query){var location=this.getLocation();invariant(location,"You cannot use transitionTo without a location"),location.push(this.makePath(to,params,query))},replaceWith:function(to,params,query){var location=this.getLocation();invariant(location,"You cannot use replaceWith without a location"),location.replace(this.makePath(to,params,query))},goBack:function(){var location=this.getLocation();invariant(location,"You cannot use goBack without a location"),location.pop()},isActive:function(to,params,query){return Path.isAbsolute(to)?to===this.getCurrentPath():routeIsActive(this.getActiveRoutes(),to)&¶msAreActive(this.getActiveParams(),params)&&(null==query||queryIsActive(this.getActiveQuery(),query))},render:function(){var match=this.state.matches[0];return null==match?null:match.route.props.handler(this.getHandlerProps())},childContextTypes:{currentPath:React.PropTypes.string,makePath:React.PropTypes.func.isRequired,makeHref:React.PropTypes.func.isRequired,transitionTo:React.PropTypes.func.isRequired,replaceWith:React.PropTypes.func.isRequired,goBack:React.PropTypes.func.isRequired,isActive:React.PropTypes.func.isRequired},getChildContext:function(){return{currentPath:this.getCurrentPath(),makePath:this.makePath,makeHref:this.makeHref,transitionTo:this.transitionTo,replaceWith:this.replaceWith,goBack:this.goBack,isActive:this.isActive}}});module.exports=Routes},{"../locations/HashLocation":11,"../mixins/ActiveContext":14,"../mixins/LocationContext":17,"../mixins/RouteContext":19,"../mixins/ScrollContext":20,"../utils/Path":22,"../utils/Redirect":24,"../utils/Transition":26,"../utils/reversedArray":28,"./Route":8,"react/lib/Object.assign":43,"react/lib/invariant":69,"react/lib/warning":75}],10:[function(_dereq_,module,exports){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.CurrentPath=_dereq_("./mixins/CurrentPath"),exports.Navigation=_dereq_("./mixins/Navigation"),exports.renderRoutesToString=_dereq_("./utils/ServerRendering").renderRoutesToString,exports.renderRoutesToStaticMarkup=_dereq_("./utils/ServerRendering").renderRoutesToStaticMarkup},{"./components/DefaultRoute":4,"./components/Link":5,"./components/NotFoundRoute":6,"./components/Redirect":7,"./components/Route":8,"./components/Routes":9,"./mixins/ActiveState":15,"./mixins/CurrentPath":16,"./mixins/Navigation":18,"./utils/ServerRendering":25}],11:[function(_dereq_,module){function getHashPath(){return window.location.hash.substr(1)}function ensureSlash(){var path=getHashPath();return"/"===path.charAt(0)?!0:(HashLocation.replace("/"+path),!1)}function onHashChange(){if(ensureSlash()){{getHashPath()}_onChange({type:_actionType||LocationActions.POP,path:getHashPath()}),_actionType=null}}var _actionType,_onChange,LocationActions=_dereq_("../actions/LocationActions"),getWindowPath=_dereq_("../utils/getWindowPath"),HashLocation={setup:function(onChange){_onChange=onChange,ensureSlash(),window.addEventListener?window.addEventListener("hashchange",onHashChange,!1):window.attachEvent("onhashchange",onHashChange)},teardown:function(){window.removeEventListener?window.removeEventListener("hashchange",onHashChange,!1):window.detachEvent("onhashchange",onHashChange)},push:function(path){_actionType=LocationActions.PUSH,window.location.hash=path},replace:function(path){_actionType=LocationActions.REPLACE,window.location.replace(getWindowPath()+"#"+path)},pop:function(){_actionType=LocationActions.POP,window.history.back()},getCurrentPath:getHashPath,toString:function(){return""}};module.exports=HashLocation},{"../actions/LocationActions":1,"../utils/getWindowPath":27}],12:[function(_dereq_,module){function onPopState(){_onChange({type:LocationActions.POP,path:getWindowPath()})}var _onChange,LocationActions=_dereq_("../actions/LocationActions"),getWindowPath=_dereq_("../utils/getWindowPath"),HistoryLocation={setup:function(onChange){_onChange=onChange,window.addEventListener?window.addEventListener("popstate",onPopState,!1):window.attachEvent("popstate",onPopState)},teardown:function(){window.removeEventListener?window.removeEventListener("popstate",onPopState,!1):window.detachEvent("popstate",onPopState)},push:function(path){window.history.pushState({path:path},"",path),_onChange({type:LocationActions.PUSH,path:getWindowPath()})},replace:function(path){window.history.replaceState({path:path},"",path),_onChange({type:LocationActions.REPLACE,path:getWindowPath()})},pop:function(){window.history.back()},getCurrentPath:getWindowPath,toString:function(){return""}};module.exports=HistoryLocation},{"../actions/LocationActions":1,"../utils/getWindowPath":27}],13:[function(_dereq_,module){var getWindowPath=_dereq_("../utils/getWindowPath"),RefreshLocation={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":27}],14:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,objectAssign=_dereq_("react/lib/Object.assign"),ActiveContext={propTypes:{initialActiveRoutes:React.PropTypes.array.isRequired,initialActiveParams:React.PropTypes.object.isRequired,initialActiveQuery:React.PropTypes.object.isRequired},getDefaultProps:function(){return{initialActiveRoutes:[],initialActiveParams:{},initialActiveQuery:{}}},getInitialState:function(){return{activeRoutes:this.props.initialActiveRoutes,activeParams:this.props.initialActiveParams,activeQuery:this.props.initialActiveQuery}},getActiveRoutes:function(){return this.state.activeRoutes.slice(0)},getActiveParams:function(){return objectAssign({},this.state.activeParams)},getActiveQuery:function(){return objectAssign({},this.state.activeQuery)},childContextTypes:{activeRoutes:React.PropTypes.array.isRequired,activeParams:React.PropTypes.object.isRequired,activeQuery:React.PropTypes.object.isRequired},getChildContext:function(){return{activeRoutes:this.getActiveRoutes(),activeParams:this.getActiveParams(),activeQuery:this.getActiveQuery()}}};module.exports=ActiveContext},{"react/lib/Object.assign":43}],15:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,ActiveState={contextTypes:{activeRoutes:React.PropTypes.array.isRequired,activeParams:React.PropTypes.object.isRequired,activeQuery:React.PropTypes.object.isRequired,isActive:React.PropTypes.func.isRequired},getActiveRoutes:function(){return this.context.activeRoutes},getActiveParams:function(){return this.context.activeParams},getActiveQuery:function(){return this.context.activeQuery},isActive:function(to,params,query){return this.context.isActive(to,params,query)}};module.exports=ActiveState},{}],16:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,CurrentPath={contextTypes:{currentPath:React.PropTypes.string.isRequired},getCurrentPath:function(){return this.context.currentPath}};module.exports=CurrentPath},{}],17:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM,HashLocation=_dereq_("../locations/HashLocation"),HistoryLocation=_dereq_("../locations/HistoryLocation"),RefreshLocation=_dereq_("../locations/RefreshLocation"),PathStore=_dereq_("../stores/PathStore"),supportsHistory=_dereq_("../utils/supportsHistory"),NAMED_LOCATIONS={none:null,hash:HashLocation,history:HistoryLocation,refresh:RefreshLocation},LocationContext={propTypes:{location:function(props,propName,componentName){var location=props[propName];return"string"!=typeof location||location in NAMED_LOCATIONS?void 0:new Error('Unknown location "'+location+'", see '+componentName)}},getDefaultProps:function(){return{location:canUseDOM?HashLocation:null}},componentWillMount:function(){var location=this.getLocation();invariant(null==location||canUseDOM,"Cannot use location without a DOM"),location&&(PathStore.setup(location),PathStore.addChangeListener(this.handlePathChange),this.updateLocation&&this.updateLocation(PathStore.getCurrentPath(),PathStore.getCurrentActionType()))},componentWillUnmount:function(){this.getLocation()&&PathStore.removeChangeListener(this.handlePathChange)},handlePathChange:function(){this.updateLocation&&this.updateLocation(PathStore.getCurrentPath(),PathStore.getCurrentActionType())},getLocation:function(){if(null==this._location){var location=this.props.location;"string"==typeof location&&(location=NAMED_LOCATIONS[location]),location!==HistoryLocation||supportsHistory()||(location=RefreshLocation),this._location=location}return this._location},childContextTypes:{location:React.PropTypes.object},getChildContext:function(){return{location:this.getLocation()}}};module.exports=LocationContext},{"../locations/HashLocation":11,"../locations/HistoryLocation":12,"../locations/RefreshLocation":13,"../stores/PathStore":21,"../utils/supportsHistory":29,"react/lib/ExecutionEnvironment":42,"react/lib/invariant":69}],18:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,Navigation={contextTypes:{makePath:React.PropTypes.func.isRequired,makeHref:React.PropTypes.func.isRequired,transitionTo:React.PropTypes.func.isRequired,replaceWith:React.PropTypes.func.isRequired,goBack:React.PropTypes.func.isRequired},makePath:function(to,params,query){return this.context.makePath(to,params,query)},makeHref:function(to,params,query){return this.context.makeHref(to,params,query)},transitionTo:function(to,params,query){this.context.transitionTo(to,params,query)},replaceWith:function(to,params,query){this.context.replaceWith(to,params,query)},goBack:function(){this.context.goBack()}};module.exports=Navigation},{}],19:[function(_dereq_,module){function processRoute(route,container,namedRoutes){var props=route.props,parentPath=container&&container.props.path||"/";if(!props.path&&!props.name||props.isDefault||props.catchAll)props.path=parentPath,props.catchAll&&(props.path+="*");else{var path=props.path||props.name;Path.isAbsolute(path)||(path=Path.join(parentPath,path)),props.path=Path.normalize(path)}if(props.paramNames=Path.extractParamNames(props.path),container&&Array.isArray(container.props.paramNames)&&container.props.paramNames.forEach(function(paramName){invariant(-1!==props.paramNames.indexOf(paramName),'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"',props.path,paramName,container.props.path)}),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}return props.catchAll?(invariant(container," must have a parent "),invariant(null==container.props.notFoundRoute,"You may not have more than one per "),container.props.notFoundRoute=route,null):props.isDefault?(invariant(container," must have a parent "),invariant(null==container.props.defaultRoute,"You may not have more than one per "),container.props.defaultRoute=route,null):(props.children=processRoutes(props.children,route,namedRoutes),route)}function processRoutes(children,container,namedRoutes){var routes=[];return React.Children.forEach(children,function(child){(child=processRoute(child,container,namedRoutes))&&routes.push(child)}),routes}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,invariant=_dereq_("react/lib/invariant"),Path=_dereq_("../utils/Path"),RouteContext={_processRoutes:function(){this._namedRoutes={},this._routes=processRoutes(this.props.children,this,this._namedRoutes)},getRoutes:function(){return null==this._routes&&this._processRoutes(),this._routes},getNamedRoutes:function(){return null==this._namedRoutes&&this._processRoutes(),this._namedRoutes},getRouteByName:function(routeName){var namedRoutes=this.getNamedRoutes();return namedRoutes[routeName]||null},childContextTypes:{routes:React.PropTypes.array.isRequired,namedRoutes:React.PropTypes.object.isRequired},getChildContext:function(){return{routes:this.getRoutes(),namedRoutes:this.getNamedRoutes()}}};module.exports=RouteContext},{"../utils/Path":22,"react/lib/invariant":69}],20:[function(_dereq_,module){function getWindowScrollPosition(){return invariant(canUseDOM,"Cannot get current scroll position without a DOM"),{x:window.scrollX,y:window.scrollY}}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM,ImitateBrowserBehavior=_dereq_("../behaviors/ImitateBrowserBehavior"),ScrollToTopBehavior=_dereq_("../behaviors/ScrollToTopBehavior"),NAMED_SCROLL_BEHAVIORS={none:null,browser:ImitateBrowserBehavior,imitateBrowser:ImitateBrowserBehavior,scrollToTop:ScrollToTopBehavior},ScrollContext={propTypes:{scrollBehavior:function(props,propName,componentName){var behavior=props[propName];return"string"!=typeof behavior||behavior in NAMED_SCROLL_BEHAVIORS?void 0:new Error('Unknown scroll behavior "'+behavior+'", see '+componentName)}},getDefaultProps:function(){return{scrollBehavior:canUseDOM?ImitateBrowserBehavior:null}},componentWillMount:function(){invariant(null==this.getScrollBehavior()||canUseDOM,"Cannot use scroll behavior without a DOM")},recordScroll:function(path){var positions=this.getScrollPositions();positions[path]=getWindowScrollPosition()},updateScroll:function(path,actionType){var behavior=this.getScrollBehavior(),position=this.getScrollPosition(path)||null;behavior&&behavior.updateScrollPosition(position,actionType)},getScrollBehavior:function(){if(null==this._scrollBehavior){var behavior=this.props.scrollBehavior;"string"==typeof behavior&&(behavior=NAMED_SCROLL_BEHAVIORS[behavior]),this._scrollBehavior=behavior}return this._scrollBehavior},getScrollPositions:function(){return null==this._scrollPositions&&(this._scrollPositions={}),this._scrollPositions},getScrollPosition:function(path){var positions=this.getScrollPositions();return positions[path]},childContextTypes:{scrollBehavior:React.PropTypes.object},getChildContext:function(){return{scrollBehavior:this.getScrollBehavior()}}};module.exports=ScrollContext},{"../behaviors/ImitateBrowserBehavior":2,"../behaviors/ScrollToTopBehavior":3,"react/lib/ExecutionEnvironment":42,"react/lib/invariant":69}],21:[function(_dereq_,module){function notifyChange(){_events.emit(CHANGE_EVENT)}function handleLocationChangeAction(action){_currentPath!==action.path&&(_currentPath=action.path,_currentActionType=action.type,notifyChange())}var _currentLocation,_currentActionType,invariant=_dereq_("react/lib/invariant"),EventEmitter=_dereq_("events").EventEmitter,CHANGE_EVENT=(_dereq_("../actions/LocationActions"),"change"),_events=new EventEmitter,_currentPath="/",PathStore={addChangeListener:function(listener){_events.addListener(CHANGE_EVENT,listener)},removeChangeListener:function(listener){_events.removeListener(CHANGE_EVENT,listener)},removeAllChangeListeners:function(){_events.removeAllListeners(CHANGE_EVENT)},setup:function(location){invariant(null==_currentLocation||_currentLocation===location,"You cannot use %s and %s on the same page",_currentLocation,location),_currentLocation!==location&&(location.setup&&location.setup(handleLocationChangeAction),_currentPath=location.getCurrentPath()),_currentLocation=location},teardown:function(){_currentLocation&&_currentLocation.teardown&&_currentLocation.teardown(),_currentLocation=_currentActionType=null,_currentPath="/",PathStore.removeAllChangeListeners()},getCurrentPath:function(){return _currentPath},getCurrentActionType:function(){return _currentActionType}};module.exports=PathStore},{"../actions/LocationActions":1,events:31,"react/lib/invariant":69}],22:[function(_dereq_,module){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("/")}function compilePattern(pattern){if(!(pattern in _compiledPatterns)){var paramNames=[],source=pattern.replace(paramCompileMatcher,function(match,paramName){return paramName?(paramNames.push(paramName),"([^/?#]+)"):"*"===match?(paramNames.push("splat"),"(.*?)"):"\\"+match});_compiledPatterns[pattern]={matcher:new RegExp("^"+source+"$","i"),paramNames:paramNames}}return _compiledPatterns[pattern]}var invariant=_dereq_("react/lib/invariant"),merge=_dereq_("qs/lib/utils").merge,qs=_dereq_("qs"),paramCompileMatcher=/:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g,paramInjectMatcher=/:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g,paramInjectTrailingSlashMatcher=/\/\/\?|\/\?/g,queryMatcher=/\?(.+)/,_compiledPatterns={},Path={extractParamNames:function(pattern){return compilePattern(pattern).paramNames},extractParams:function(pattern,path){var object=compilePattern(pattern),match=decodeURL(path).match(object.matcher);if(!match)return null;var params={};return object.paramNames.forEach(function(paramName,index){params[paramName]=match[index+1]}),params},injectParams:function(pattern,params){params=params||{};var splatIndex=0;return pattern.replace(paramInjectMatcher,function(match,paramName){if(paramName=paramName||"splat","?"!==paramName.slice(-1))invariant(null!=params[paramName],'Missing "'+paramName+'" parameter for path "'+pattern+'"');else if(paramName=paramName.slice(0,-1),null==params[paramName])return"";var segment;return"splat"===paramName&&Array.isArray(params[paramName])?(segment=params[paramName][splatIndex++],invariant(null!=segment,"Missing splat # "+splatIndex+' for path "'+pattern+'"')):segment=params[paramName],encodeURLPath(segment)}).replace(paramInjectTrailingSlashMatcher,"/")},extractQuery:function(path){var match=path.match(queryMatcher);return match&&qs.parse(match[1])},withoutQuery:function(path){return path.replace(queryMatcher,"")},withQuery:function(path,query){var existingQuery=Path.extractQuery(path);existingQuery&&(query=query?merge(existingQuery,query):existingQuery);var queryString=query&&qs.stringify(query); -return queryString?Path.withoutQuery(path)+"?"+queryString:path},isAbsolute:function(path){return"/"===path.charAt(0)},normalize:function(path){return path.replace(/^\/*/,"/")},join:function(a,b){return a.replace(/\/*$/,"/")+b}};module.exports=Path},{qs:32,"qs/lib/utils":36,"react/lib/invariant":69}],23:[function(_dereq_,module){var Promise=_dereq_("when/lib/Promise");module.exports=Promise},{"when/lib/Promise":76}],24:[function(_dereq_,module){function Redirect(to,params,query){this.to=to,this.params=params,this.query=query}module.exports=Redirect},{}],25:[function(_dereq_,module){function cloneRoutesForServerRendering(routes){return cloneWithProps(routes,{location:"none",scrollBehavior:"none"})}function mergeStateIntoInitialProps(state,props){objectAssign(props,{initialPath:state.path,initialMatches:state.matches,initialActiveRoutes:state.activeRoutes,initialActiveParams:state.activeParams,initialActiveQuery:state.activeQuery})}function renderRoutesToString(routes,path,callback){invariant(ReactElement.isValidElement(routes),"You must pass a valid ReactComponent to renderRoutesToString");var component=instantiateReactComponent(cloneRoutesForServerRendering(routes));component.dispatch(path,function(error,abortReason,nextState){if(error||abortReason)return callback(error,abortReason);mergeStateIntoInitialProps(nextState,component.props);var transaction;try{var id=ReactInstanceHandles.createReactRootID();transaction=ReactServerRenderingTransaction.getPooled(!1),transaction.perform(function(){var markup=component.mountComponent(id,transaction,0);callback(null,null,ReactMarkupChecksum.addChecksumToMarkup(markup))},null)}finally{ReactServerRenderingTransaction.release(transaction)}})}function renderRoutesToStaticMarkup(routes,path,callback){invariant(ReactElement.isValidElement(routes),"You must pass a valid ReactComponent to renderRoutesToStaticMarkup");var component=instantiateReactComponent(cloneRoutesForServerRendering(routes));component.dispatch(path,function(error,abortReason,nextState){if(error||abortReason)return callback(error,abortReason);mergeStateIntoInitialProps(nextState,component.props);var transaction;try{var id=ReactInstanceHandles.createReactRootID();transaction=ReactServerRenderingTransaction.getPooled(!1),transaction.perform(function(){callback(null,null,component.mountComponent(id,transaction,0))},null)}finally{ReactServerRenderingTransaction.release(transaction)}})}var ReactElement=_dereq_("react/lib/ReactElement"),ReactInstanceHandles=_dereq_("react/lib/ReactInstanceHandles"),ReactMarkupChecksum=_dereq_("react/lib/ReactMarkupChecksum"),ReactServerRenderingTransaction=_dereq_("react/lib/ReactServerRenderingTransaction"),cloneWithProps=_dereq_("react/lib/cloneWithProps"),objectAssign=_dereq_("react/lib/Object.assign"),instantiateReactComponent=_dereq_("react/lib/instantiateReactComponent"),invariant=_dereq_("react/lib/invariant");module.exports={renderRoutesToString:renderRoutesToString,renderRoutesToStaticMarkup:renderRoutesToStaticMarkup}},{"react/lib/Object.assign":43,"react/lib/ReactElement":48,"react/lib/ReactInstanceHandles":51,"react/lib/ReactMarkupChecksum":53,"react/lib/ReactServerRenderingTransaction":58,"react/lib/cloneWithProps":63,"react/lib/instantiateReactComponent":68,"react/lib/invariant":69}],26:[function(_dereq_,module){function Transition(routesComponent,path){this.routesComponent=routesComponent,this.path=path,this.abortReason=null,this.isAborted=!1}var Promise=_dereq_("./Promise"),Redirect=_dereq_("./Redirect");Transition.prototype.abort=function(reason){this.abortReason=reason,this.isAborted=!0},Transition.prototype.redirect=function(to,params,query){this.abort(new Redirect(to,params,query))},Transition.prototype.wait=function(value){this.promise=Promise.resolve(value)},Transition.prototype.retry=function(){this.routesComponent.replaceWith(this.path)},module.exports=Transition},{"./Promise":23,"./Redirect":24}],27:[function(_dereq_,module){function getWindowPath(){return window.location.pathname+window.location.search}module.exports=getWindowPath},{}],28:[function(_dereq_,module){function reversedArray(array){return array.slice(0).reverse()}module.exports=reversedArray},{}],29:[function(_dereq_,module){function supportsHistory(){var ua=navigator.userAgent;return-1===ua.indexOf("Android 2.")&&-1===ua.indexOf("Android 4.0")||-1===ua.indexOf("Mobile Safari")||-1!==ua.indexOf("Chrome")?window.history&&"pushState"in window.history:!1}module.exports=supportsHistory},{}],30:[function(_dereq_,module){function withoutProperties(object,properties){var result={};for(var property in object)object.hasOwnProperty(property)&&!properties[property]&&(result[property]=object[property]);return result}module.exports=withoutProperties},{}],31:[function(_dereq_,module){function EventEmitter(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function isFunction(arg){return"function"==typeof arg}function isNumber(arg){return"number"==typeof arg}function isObject(arg){return"object"==typeof arg&&null!==arg}function isUndefined(arg){return void 0===arg}module.exports=EventEmitter,EventEmitter.EventEmitter=EventEmitter,EventEmitter.prototype._events=void 0,EventEmitter.prototype._maxListeners=void 0,EventEmitter.defaultMaxListeners=10,EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||0>n||isNaN(n))throw TypeError("n must be a positive number");return this._maxListeners=n,this},EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(this._events||(this._events={}),"error"===type&&(!this._events.error||isObject(this._events.error)&&!this._events.error.length))throw er=arguments[1],er instanceof Error?er:TypeError('Uncaught, unspecified "error" event.');if(handler=this._events[type],isUndefined(handler))return!1;if(isFunction(handler))switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:for(len=arguments.length,args=new Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];handler.apply(this,args)}else if(isObject(handler)){for(len=arguments.length,args=new Array(len-1),i=1;len>i;i++)args[i-1]=arguments[i];for(listeners=handler.slice(),len=listeners.length,i=0;len>i;i++)listeners[i].apply(this,args)}return!0},EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener),this._events[type]?isObject(this._events[type])?this._events[type].push(listener):this._events[type]=[this._events[type],listener]:this._events[type]=listener,isObject(this._events[type])&&!this._events[type].warned){var m;m=isUndefined(this._maxListeners)?EventEmitter.defaultMaxListeners:this._maxListeners,m&&m>0&&this._events[type].length>m&&(this._events[type].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[type].length),"function"==typeof console.trace&&console.trace())}return this},EventEmitter.prototype.on=EventEmitter.prototype.addListener,EventEmitter.prototype.once=function(type,listener){function g(){this.removeListener(type,g),fired||(fired=!0,listener.apply(this,arguments))}if(!isFunction(listener))throw TypeError("listener must be a function");var fired=!1;return g.listener=listener,this.on(type,g),this},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;if(list=this._events[type],length=list.length,position=-1,list===listener||isFunction(list.listener)&&list.listener===listener)delete this._events[type],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(0>position)return this;1===list.length?(list.length=0,delete this._events[type]):list.splice(position,1),this._events.removeListener&&this.emit("removeListener",type,listener)}return this},EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[type]&&delete this._events[type],this;if(0===arguments.length){for(key in this._events)"removeListener"!==key&&this.removeAllListeners(key);return this.removeAllListeners("removeListener"),this._events={},this}if(listeners=this._events[type],isFunction(listeners))this.removeListener(type,listeners);else for(;listeners.length;)this.removeListener(type,listeners[listeners.length-1]);return delete this._events[type],this},EventEmitter.prototype.listeners=function(type){var ret;return ret=this._events&&this._events[type]?isFunction(this._events[type])?[this._events[type]]:this._events[type].slice():[]},EventEmitter.listenerCount=function(emitter,type){var ret;return ret=emitter._events&&emitter._events[type]?isFunction(emitter._events[type])?1:emitter._events[type].length:0}},{}],32:[function(_dereq_,module){module.exports=_dereq_("./lib")},{"./lib":33}],33:[function(_dereq_,module){var Stringify=_dereq_("./stringify"),Parse=_dereq_("./parse");module.exports={stringify:Stringify,parse:Parse}},{"./parse":34,"./stringify":35}],34:[function(_dereq_,module){var Utils=_dereq_("./utils"),internals={delimiter:"&",depth:5,arrayLimit:20,parameterLimit:1e3};internals.parseValues=function(str,options){for(var obj={},parts=str.split(options.delimiter,1/0===options.parameterLimit?void 0:options.parameterLimit),i=0,il=parts.length;il>i;++i){var part=parts[i],pos=-1===part.indexOf("]=")?part.indexOf("="):part.indexOf("]=")+1;if(-1===pos)obj[Utils.decode(part)]="";else{var key=Utils.decode(part.slice(0,pos)),val=Utils.decode(part.slice(pos+1));obj[key]=obj[key]?[].concat(obj[key]).concat(val):val}}return obj},internals.parseObject=function(chain,val,options){if(!chain.length)return val;var root=chain.shift(),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,index=parseInt(cleanRoot,10);!isNaN(index)&&root!==cleanRoot&&index<=options.arrayLimit?(obj=[],obj[index]=internals.parseObject(chain,val,options)):obj[cleanRoot]=internals.parseObject(chain,val,options)}return obj},internals.parseKeys=function(key,val,options){if(key){var parent=/^([^\[\]]*)/,child=/(\[[^\[\]]*\])/g,segment=parent.exec(key);if(!Object.prototype.hasOwnProperty(segment[1])){var keys=[];segment[1]&&keys.push(segment[1]);for(var i=0;null!==(segment=child.exec(key))&&ii;++i){var key=keys[i],newObj=internals.parseKeys(key,tempObj[key],options);obj=Utils.merge(obj,newObj)}return Utils.compact(obj)}},{"./utils":36}],35:[function(_dereq_,module){var Utils=_dereq_("./utils"),internals={delimiter:"&"};internals.stringify=function(obj,prefix){if(Utils.isBuffer(obj)?obj=obj.toString():obj instanceof Date?obj=obj.toISOString():null===obj&&(obj=""),"string"==typeof obj||"number"==typeof obj||"boolean"==typeof obj)return[encodeURIComponent(prefix)+"="+encodeURIComponent(obj)];var values=[];for(var key in obj)obj.hasOwnProperty(key)&&(values=values.concat(internals.stringify(obj[key],prefix+"["+key+"]")));return values},module.exports=function(obj,options){options=options||{};var delimiter="undefined"==typeof options.delimiter?internals.delimiter:options.delimiter,keys=[];for(var key in obj)obj.hasOwnProperty(key)&&(keys=keys.concat(internals.stringify(obj[key],key)));return keys.join(delimiter)}},{"./utils":36}],36:[function(_dereq_,module,exports){exports.arrayToObject=function(source){for(var obj={},i=0,il=source.length;il>i;++i)"undefined"!=typeof source[i]&&(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;il>i;++i)"undefined"!=typeof source[i]&&(target[i]="object"==typeof target[i]?exports.merge(target[i],source[i]):source[i]);return target}if(Array.isArray(target)){if("object"!=typeof source)return target.push(source),target;target=exports.arrayToObject(target)}for(var keys=Object.keys(source),k=0,kl=keys.length;kl>k;++k){var key=keys[k],value=source[key];target[key]=value&&"object"==typeof value&&target[key]?exports.merge(target[key],value):value}return target},exports.decode=function(str){try{return decodeURIComponent(str.replace(/\+/g," "))}catch(e){return str}},exports.compact=function(obj,refs){if("object"!=typeof obj||null===obj)return obj;refs=refs||[];var lookup=refs.indexOf(obj);if(-1!==lookup)return refs[lookup];if(refs.push(obj),Array.isArray(obj)){for(var compacted=[],i=0,l=obj.length;l>i;++i)"undefined"!=typeof obj[i]&&compacted.push(obj[i]);return compacted}for(var keys=Object.keys(obj),i=0,il=keys.length;il>i;++i){var key=keys[i];obj[key]=exports.compact(obj[key],refs)}return obj},exports.isRegExp=function(obj){return"[object RegExp]"===Object.prototype.toString.call(obj)},exports.isBuffer=function(obj){return"undefined"!=typeof Buffer?Buffer.isBuffer(obj):!1}},{}],37:[function(_dereq_,module){"use strict";function CallbackQueue(){this._callbacks=null,this._contexts=null}var PooledClass=_dereq_("./PooledClass"),assign=_dereq_("./Object.assign"),invariant=_dereq_("./invariant");assign(CallbackQueue.prototype,{enqueue:function(callback,context){this._callbacks=this._callbacks||[],this._contexts=this._contexts||[],this._callbacks.push(callback),this._contexts.push(context)},notifyAll:function(){var callbacks=this._callbacks,contexts=this._contexts;if(callbacks){invariant(callbacks.length===contexts.length),this._callbacks=null,this._contexts=null;for(var i=0,l=callbacks.length;l>i;i++)callbacks[i].call(contexts[i]);callbacks.length=0,contexts.length=0}},reset:function(){this._callbacks=null,this._contexts=null},destructor:function(){this.reset()}}),PooledClass.addPoolingTo(CallbackQueue),module.exports=CallbackQueue},{"./Object.assign":43,"./PooledClass":44,"./invariant":69}],38:[function(_dereq_,module){"use strict";var keyMirror=_dereq_("./keyMirror"),PropagationPhases=keyMirror({bubbled:null,captured:null}),topLevelTypes=keyMirror({topBlur:null,topChange:null,topClick:null,topCompositionEnd:null,topCompositionStart:null,topCompositionUpdate:null,topContextMenu:null,topCopy:null,topCut:null,topDoubleClick:null,topDrag:null,topDragEnd:null,topDragEnter:null,topDragExit:null,topDragLeave:null,topDragOver:null,topDragStart:null,topDrop:null,topError:null,topFocus:null,topInput:null,topKeyDown:null,topKeyPress:null,topKeyUp:null,topLoad:null,topMouseDown:null,topMouseMove:null,topMouseOut:null,topMouseOver:null,topMouseUp:null,topPaste:null,topReset:null,topScroll:null,topSelectionChange:null,topSubmit:null,topTextInput:null,topTouchCancel:null,topTouchEnd:null,topTouchMove:null,topTouchStart:null,topWheel:null}),EventConstants={topLevelTypes:topLevelTypes,PropagationPhases:PropagationPhases};module.exports=EventConstants},{"./keyMirror":72}],39:[function(_dereq_,module){"use strict";var EventPluginRegistry=_dereq_("./EventPluginRegistry"),EventPluginUtils=_dereq_("./EventPluginUtils"),accumulateInto=_dereq_("./accumulateInto"),forEachAccumulated=_dereq_("./forEachAccumulated"),invariant=_dereq_("./invariant"),listenerBank={},eventQueue=null,executeDispatchesAndRelease=function(event){if(event){var executeDispatch=EventPluginUtils.executeDispatch,PluginModule=EventPluginRegistry.getPluginModuleForEvent(event);PluginModule&&PluginModule.executeDispatch&&(executeDispatch=PluginModule.executeDispatch),EventPluginUtils.executeDispatchesInOrder(event,executeDispatch),event.isPersistent()||event.constructor.release(event)}},InstanceHandle=null,EventPluginHub={injection:{injectMount:EventPluginUtils.injection.injectMount,injectInstanceHandle:function(InjectedInstanceHandle){InstanceHandle=InjectedInstanceHandle},getInstanceHandle:function(){return InstanceHandle},injectEventPluginOrder:EventPluginRegistry.injectEventPluginOrder,injectEventPluginsByName:EventPluginRegistry.injectEventPluginsByName},eventNameDispatchConfigs:EventPluginRegistry.eventNameDispatchConfigs,registrationNameModules:EventPluginRegistry.registrationNameModules,putListener:function(id,registrationName,listener){invariant(!listener||"function"==typeof listener);var bankForRegistrationName=listenerBank[registrationName]||(listenerBank[registrationName]={});bankForRegistrationName[id]=listener},getListener:function(id,registrationName){var bankForRegistrationName=listenerBank[registrationName];return bankForRegistrationName&&bankForRegistrationName[id]},deleteListener:function(id,registrationName){var bankForRegistrationName=listenerBank[registrationName];bankForRegistrationName&&delete bankForRegistrationName[id]},deleteAllListeners:function(id){for(var registrationName in listenerBank)delete listenerBank[registrationName][id]},extractEvents:function(topLevelType,topLevelTarget,topLevelTargetID,nativeEvent){for(var events,plugins=EventPluginRegistry.plugins,i=0,l=plugins.length;l>i;i++){var possiblePlugin=plugins[i];if(possiblePlugin){var extractedEvents=possiblePlugin.extractEvents(topLevelType,topLevelTarget,topLevelTargetID,nativeEvent);extractedEvents&&(events=accumulateInto(events,extractedEvents))}}return events},enqueueEvents:function(events){events&&(eventQueue=accumulateInto(eventQueue,events))},processEventQueue:function(){var processingEventQueue=eventQueue;eventQueue=null,forEachAccumulated(processingEventQueue,executeDispatchesAndRelease),invariant(!eventQueue)},__purge:function(){listenerBank={}},__getListenerBank:function(){return listenerBank}};module.exports=EventPluginHub},{"./EventPluginRegistry":40,"./EventPluginUtils":41,"./accumulateInto":61,"./forEachAccumulated":66,"./invariant":69}],40:[function(_dereq_,module){"use strict";function recomputePluginOrdering(){if(EventPluginOrder)for(var pluginName in namesToPlugins){var PluginModule=namesToPlugins[pluginName],pluginIndex=EventPluginOrder.indexOf(pluginName);if(invariant(pluginIndex>-1),!EventPluginRegistry.plugins[pluginIndex]){invariant(PluginModule.extractEvents),EventPluginRegistry.plugins[pluginIndex]=PluginModule;var publishedEvents=PluginModule.eventTypes;for(var eventName in publishedEvents)invariant(publishEventForPlugin(publishedEvents[eventName],PluginModule,eventName))}}}function publishEventForPlugin(dispatchConfig,PluginModule,eventName){invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName)),EventPluginRegistry.eventNameDispatchConfigs[eventName]=dispatchConfig;var phasedRegistrationNames=dispatchConfig.phasedRegistrationNames;if(phasedRegistrationNames){for(var phaseName in phasedRegistrationNames)if(phasedRegistrationNames.hasOwnProperty(phaseName)){var phasedRegistrationName=phasedRegistrationNames[phaseName];publishRegistrationName(phasedRegistrationName,PluginModule,eventName)}return!0}return dispatchConfig.registrationName?(publishRegistrationName(dispatchConfig.registrationName,PluginModule,eventName),!0):!1}function publishRegistrationName(registrationName,PluginModule,eventName){invariant(!EventPluginRegistry.registrationNameModules[registrationName]),EventPluginRegistry.registrationNameModules[registrationName]=PluginModule,EventPluginRegistry.registrationNameDependencies[registrationName]=PluginModule.eventTypes[eventName].dependencies}var invariant=_dereq_("./invariant"),EventPluginOrder=null,namesToPlugins={},EventPluginRegistry={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(InjectedEventPluginOrder){invariant(!EventPluginOrder),EventPluginOrder=Array.prototype.slice.call(InjectedEventPluginOrder),recomputePluginOrdering()},injectEventPluginsByName:function(injectedNamesToPlugins){var isOrderingDirty=!1;for(var pluginName in injectedNamesToPlugins)if(injectedNamesToPlugins.hasOwnProperty(pluginName)){var PluginModule=injectedNamesToPlugins[pluginName];namesToPlugins.hasOwnProperty(pluginName)&&namesToPlugins[pluginName]===PluginModule||(invariant(!namesToPlugins[pluginName]),namesToPlugins[pluginName]=PluginModule,isOrderingDirty=!0)}isOrderingDirty&&recomputePluginOrdering()},getPluginModuleForEvent:function(event){var dispatchConfig=event.dispatchConfig;if(dispatchConfig.registrationName)return EventPluginRegistry.registrationNameModules[dispatchConfig.registrationName]||null;for(var phase in dispatchConfig.phasedRegistrationNames)if(dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)){var PluginModule=EventPluginRegistry.registrationNameModules[dispatchConfig.phasedRegistrationNames[phase]];if(PluginModule)return PluginModule}return null},_resetEventPlugins:function(){EventPluginOrder=null;for(var pluginName in namesToPlugins)namesToPlugins.hasOwnProperty(pluginName)&&delete namesToPlugins[pluginName];EventPluginRegistry.plugins.length=0;var eventNameDispatchConfigs=EventPluginRegistry.eventNameDispatchConfigs;for(var eventName in eventNameDispatchConfigs)eventNameDispatchConfigs.hasOwnProperty(eventName)&&delete eventNameDispatchConfigs[eventName];var registrationNameModules=EventPluginRegistry.registrationNameModules;for(var registrationName in registrationNameModules)registrationNameModules.hasOwnProperty(registrationName)&&delete registrationNameModules[registrationName]}};module.exports=EventPluginRegistry},{"./invariant":69}],41:[function(_dereq_,module){"use strict";function isEndish(topLevelType){return topLevelType===topLevelTypes.topMouseUp||topLevelType===topLevelTypes.topTouchEnd||topLevelType===topLevelTypes.topTouchCancel}function isMoveish(topLevelType){return topLevelType===topLevelTypes.topMouseMove||topLevelType===topLevelTypes.topTouchMove}function isStartish(topLevelType){return topLevelType===topLevelTypes.topMouseDown||topLevelType===topLevelTypes.topTouchStart}function forEachEventDispatch(event,cb){var dispatchListeners=event._dispatchListeners,dispatchIDs=event._dispatchIDs;if(Array.isArray(dispatchListeners))for(var i=0;ii;i++){var dependency=dependencies[i];isListening.hasOwnProperty(dependency)&&isListening[dependency]||(dependency===topLevelTypes.topWheel?isEventSupported("wheel")?ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel,"wheel",mountAt):isEventSupported("mousewheel")?ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel,"mousewheel",mountAt):ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topWheel,"DOMMouseScroll",mountAt):dependency===topLevelTypes.topScroll?isEventSupported("scroll",!0)?ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topScroll,"scroll",mountAt):ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topScroll,"scroll",ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE):dependency===topLevelTypes.topFocus||dependency===topLevelTypes.topBlur?(isEventSupported("focus",!0)?(ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topFocus,"focus",mountAt),ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelTypes.topBlur,"blur",mountAt)):isEventSupported("focusin")&&(ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topFocus,"focusin",mountAt),ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelTypes.topBlur,"focusout",mountAt)),isListening[topLevelTypes.topBlur]=!0,isListening[topLevelTypes.topFocus]=!0):topEventMapping.hasOwnProperty(dependency)&&ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency,topEventMapping[dependency],mountAt),isListening[dependency]=!0)}},trapBubbledEvent:function(topLevelType,handlerBaseName,handle){return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType,handlerBaseName,handle) -},trapCapturedEvent:function(topLevelType,handlerBaseName,handle){return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType,handlerBaseName,handle)},ensureScrollValueMonitoring:function(){if(!isMonitoringScrollValue){var refresh=ViewportMetrics.refreshScrollValues;ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh),isMonitoringScrollValue=!0}},eventNameDispatchConfigs:EventPluginHub.eventNameDispatchConfigs,registrationNameModules:EventPluginHub.registrationNameModules,putListener:EventPluginHub.putListener,getListener:EventPluginHub.getListener,deleteListener:EventPluginHub.deleteListener,deleteAllListeners:EventPluginHub.deleteAllListeners});module.exports=ReactBrowserEventEmitter},{"./EventConstants":38,"./EventPluginHub":39,"./EventPluginRegistry":40,"./Object.assign":43,"./ReactEventEmitterMixin":50,"./ViewportMetrics":60,"./isEventSupported":70}],46:[function(_dereq_,module){"use strict";var assign=_dereq_("./Object.assign"),ReactContext={current:{},withContext:function(newContext,scopedCallback){var result,previousContext=ReactContext.current;ReactContext.current=assign({},previousContext,newContext);try{result=scopedCallback()}finally{ReactContext.current=previousContext}return result}};module.exports=ReactContext},{"./Object.assign":43}],47:[function(_dereq_,module){"use strict";var ReactCurrentOwner={current:null};module.exports=ReactCurrentOwner},{}],48:[function(_dereq_,module){"use strict";var ReactContext=_dereq_("./ReactContext"),ReactCurrentOwner=_dereq_("./ReactCurrentOwner"),RESERVED_PROPS=(_dereq_("./warning"),{key:!0,ref:!0}),ReactElement=function(type,key,ref,owner,context,props){this.type=type,this.key=key,this.ref=ref,this._owner=owner,this._context=context,this.props=props};ReactElement.prototype={_isReactElement:!0},ReactElement.createElement=function(type,config,children){var propName,props={},key=null,ref=null;if(null!=config){ref=void 0===config.ref?null:config.ref,key=null==config.key?null:""+config.key;for(propName in config)config.hasOwnProperty(propName)&&!RESERVED_PROPS.hasOwnProperty(propName)&&(props[propName]=config[propName])}var childrenLength=arguments.length-2;if(1===childrenLength)props.children=children;else if(childrenLength>1){for(var childArray=Array(childrenLength),i=0;childrenLength>i;i++)childArray[i]=arguments[i+2];props.children=childArray}if(type.defaultProps){var defaultProps=type.defaultProps;for(propName in defaultProps)"undefined"==typeof props[propName]&&(props[propName]=defaultProps[propName])}return new ReactElement(type,key,ref,ReactCurrentOwner.current,ReactContext.current,props)},ReactElement.createFactory=function(type){var factory=ReactElement.createElement.bind(null,type);return factory.type=type,factory},ReactElement.cloneAndReplaceProps=function(oldElement,newProps){var newElement=new ReactElement(oldElement.type,oldElement.key,oldElement.ref,oldElement._owner,oldElement._context,newProps);return newElement},ReactElement.isValidElement=function(object){var isElement=!(!object||!object._isReactElement);return isElement},module.exports=ReactElement},{"./ReactContext":46,"./ReactCurrentOwner":47,"./warning":75}],49:[function(_dereq_,module){"use strict";function getEmptyComponent(){return invariant(component),component()}function registerNullComponentID(id){nullComponentIdsRegistry[id]=!0}function deregisterNullComponentID(id){delete nullComponentIdsRegistry[id]}function isNullComponentID(id){return nullComponentIdsRegistry[id]}var component,ReactElement=_dereq_("./ReactElement"),invariant=_dereq_("./invariant"),nullComponentIdsRegistry={},ReactEmptyComponentInjection={injectEmptyComponent:function(emptyComponent){component=ReactElement.createFactory(emptyComponent)}},ReactEmptyComponent={deregisterNullComponentID:deregisterNullComponentID,getEmptyComponent:getEmptyComponent,injection:ReactEmptyComponentInjection,isNullComponentID:isNullComponentID,registerNullComponentID:registerNullComponentID};module.exports=ReactEmptyComponent},{"./ReactElement":48,"./invariant":69}],50:[function(_dereq_,module){"use strict";function runEventQueueInBatch(events){EventPluginHub.enqueueEvents(events),EventPluginHub.processEventQueue()}var EventPluginHub=_dereq_("./EventPluginHub"),ReactEventEmitterMixin={handleTopLevel:function(topLevelType,topLevelTarget,topLevelTargetID,nativeEvent){var events=EventPluginHub.extractEvents(topLevelType,topLevelTarget,topLevelTargetID,nativeEvent);runEventQueueInBatch(events)}};module.exports=ReactEventEmitterMixin},{"./EventPluginHub":39}],51:[function(_dereq_,module){"use strict";function getReactRootIDString(index){return SEPARATOR+index.toString(36)}function isBoundary(id,index){return id.charAt(index)===SEPARATOR||index===id.length}function isValidID(id){return""===id||id.charAt(0)===SEPARATOR&&id.charAt(id.length-1)!==SEPARATOR}function isAncestorIDOf(ancestorID,descendantID){return 0===descendantID.indexOf(ancestorID)&&isBoundary(descendantID,ancestorID.length)}function getParentID(id){return id?id.substr(0,id.lastIndexOf(SEPARATOR)):""}function getNextDescendantID(ancestorID,destinationID){if(invariant(isValidID(ancestorID)&&isValidID(destinationID)),invariant(isAncestorIDOf(ancestorID,destinationID)),ancestorID===destinationID)return ancestorID;for(var start=ancestorID.length+SEPARATOR_LENGTH,i=start;i=i;i++)if(isBoundary(oneID,i)&&isBoundary(twoID,i))lastCommonMarkerIndex=i;else if(oneID.charAt(i)!==twoID.charAt(i))break;var longestCommonID=oneID.substr(0,lastCommonMarkerIndex);return invariant(isValidID(longestCommonID)),longestCommonID}function traverseParentPath(start,stop,cb,arg,skipFirst,skipLast){start=start||"",stop=stop||"",invariant(start!==stop);var traverseUp=isAncestorIDOf(stop,start);invariant(traverseUp||isAncestorIDOf(start,stop));for(var depth=0,traverse=traverseUp?getParentID:getNextDescendantID,id=start;;id=traverse(id,stop)){var ret;if(skipFirst&&id===start||skipLast&&id===stop||(ret=cb(id,traverseUp,arg)),ret===!1||id===stop)break;invariant(depth++1){var index=id.indexOf(SEPARATOR,1);return index>-1?id.substr(0,index):id}return null},traverseEnterLeave:function(leaveID,enterID,cb,upArg,downArg){var ancestorID=getFirstCommonAncestorID(leaveID,enterID);ancestorID!==leaveID&&traverseParentPath(leaveID,ancestorID,cb,upArg,!1,!0),ancestorID!==enterID&&traverseParentPath(ancestorID,enterID,cb,downArg,!0,!1)},traverseTwoPhase:function(targetID,cb,arg){targetID&&(traverseParentPath("",targetID,cb,arg,!0,!1),traverseParentPath(targetID,"",cb,arg,!1,!0))},traverseAncestors:function(targetID,cb,arg){traverseParentPath("",targetID,cb,arg,!0,!1)},_getFirstCommonAncestorID:getFirstCommonAncestorID,_getNextDescendantID:getNextDescendantID,isAncestorIDOf:isAncestorIDOf,SEPARATOR:SEPARATOR};module.exports=ReactInstanceHandles},{"./ReactRootIndex":57,"./invariant":69}],52:[function(_dereq_,module){"use strict";function proxyStaticMethods(target,source){if("function"==typeof source)for(var key in source)if(source.hasOwnProperty(key)){var value=source[key];if("function"==typeof value){var bound=value.bind(source);for(var k in value)value.hasOwnProperty(k)&&(bound[k]=value[k]);target[key]=bound}else target[key]=value}}var invariant=(_dereq_("./ReactCurrentOwner"),_dereq_("./invariant")),LEGACY_MARKER=(_dereq_("./monitorCodeUse"),_dereq_("./warning"),{}),NON_LEGACY_MARKER={},ReactLegacyElementFactory={};ReactLegacyElementFactory.wrapCreateFactory=function(createFactory){var legacyCreateFactory=function(type){return"function"!=typeof type?createFactory(type):type.isReactNonLegacyFactory?createFactory(type.type):type.isReactLegacyFactory?createFactory(type.type):type};return legacyCreateFactory},ReactLegacyElementFactory.wrapCreateElement=function(createElement){var legacyCreateElement=function(type){if("function"!=typeof type)return createElement.apply(this,arguments);var args;return type.isReactNonLegacyFactory?(args=Array.prototype.slice.call(arguments,0),args[0]=type.type,createElement.apply(this,args)):type.isReactLegacyFactory?(type._isMockFunction&&(type.type._mockedReactClassConstructor=type),args=Array.prototype.slice.call(arguments,0),args[0]=type.type,createElement.apply(this,args)):type.apply(null,Array.prototype.slice.call(arguments,1))};return legacyCreateElement},ReactLegacyElementFactory.wrapFactory=function(factory){invariant("function"==typeof factory);var legacyElementFactory=function(){return factory.apply(this,arguments)};return proxyStaticMethods(legacyElementFactory,factory.type),legacyElementFactory.isReactLegacyFactory=LEGACY_MARKER,legacyElementFactory.type=factory.type,legacyElementFactory},ReactLegacyElementFactory.markNonLegacyFactory=function(factory){return factory.isReactNonLegacyFactory=NON_LEGACY_MARKER,factory},ReactLegacyElementFactory.isValidFactory=function(factory){return"function"==typeof factory&&factory.isReactLegacyFactory===LEGACY_MARKER},ReactLegacyElementFactory.isValidClass=function(factory){return ReactLegacyElementFactory.isValidFactory(factory)},ReactLegacyElementFactory._isLegacyCallWarningEnabled=!0,module.exports=ReactLegacyElementFactory},{"./ReactCurrentOwner":47,"./invariant":69,"./monitorCodeUse":74,"./warning":75}],53:[function(_dereq_,module){"use strict";var adler32=_dereq_("./adler32"),ReactMarkupChecksum={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(markup){var checksum=adler32(markup);return markup.replace(">"," "+ReactMarkupChecksum.CHECKSUM_ATTR_NAME+'="'+checksum+'">')},canReuseMarkup:function(markup,element){var existingChecksum=element.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);existingChecksum=existingChecksum&&parseInt(existingChecksum,10);var markupChecksum=adler32(markup);return markupChecksum===existingChecksum}};module.exports=ReactMarkupChecksum},{"./adler32":62}],54:[function(_dereq_,module){"use strict";function createInstanceForTag(tag,props,parentType){var componentClass=tagToComponentClass[tag];return null==componentClass?(invariant(genericComponentClass),new genericComponentClass(tag,props)):parentType===tag?(invariant(genericComponentClass),new genericComponentClass(tag,props)):new componentClass.type(props)}var assign=_dereq_("./Object.assign"),invariant=_dereq_("./invariant"),genericComponentClass=null,tagToComponentClass={},ReactNativeComponentInjection={injectGenericComponentClass:function(componentClass){genericComponentClass=componentClass},injectComponentClasses:function(componentClasses){assign(tagToComponentClass,componentClasses)}},ReactNativeComponent={createInstanceForTag:createInstanceForTag,injection:ReactNativeComponentInjection};module.exports=ReactNativeComponent},{"./Object.assign":43,"./invariant":69}],55:[function(_dereq_,module){"use strict";function createTransferStrategy(mergeStrategy){return function(props,key,value){props[key]=props.hasOwnProperty(key)?mergeStrategy(props[key],value):value}}function transferInto(props,newProps){for(var thisKey in newProps)if(newProps.hasOwnProperty(thisKey)){var transferStrategy=TransferStrategies[thisKey];transferStrategy&&TransferStrategies.hasOwnProperty(thisKey)?transferStrategy(props,thisKey,newProps[thisKey]):props.hasOwnProperty(thisKey)||(props[thisKey]=newProps[thisKey])}return props}var assign=_dereq_("./Object.assign"),emptyFunction=_dereq_("./emptyFunction"),invariant=_dereq_("./invariant"),joinClasses=_dereq_("./joinClasses"),transferStrategyMerge=(_dereq_("./warning"),createTransferStrategy(function(a,b){return assign({},b,a)})),TransferStrategies={children:emptyFunction,className:createTransferStrategy(joinClasses),style:transferStrategyMerge},ReactPropTransferer={TransferStrategies:TransferStrategies,mergeProps:function(oldProps,newProps){return transferInto(assign({},oldProps),newProps)},Mixin:{transferPropsTo:function(element){return invariant(element._owner===this),transferInto(element.props,this.props),element}}};module.exports=ReactPropTransferer},{"./Object.assign":43,"./emptyFunction":65,"./invariant":69,"./joinClasses":71,"./warning":75}],56:[function(_dereq_,module){"use strict";function ReactPutListenerQueue(){this.listenersToPut=[]}var PooledClass=_dereq_("./PooledClass"),ReactBrowserEventEmitter=_dereq_("./ReactBrowserEventEmitter"),assign=_dereq_("./Object.assign");assign(ReactPutListenerQueue.prototype,{enqueuePutListener:function(rootNodeID,propKey,propValue){this.listenersToPut.push({rootNodeID:rootNodeID,propKey:propKey,propValue:propValue})},putListeners:function(){for(var i=0;i1)for(var ii=1;argLength>ii;ii++)nextClass=arguments[ii],nextClass&&(className=(className?className+" ":"")+nextClass);return className}module.exports=joinClasses},{}],72:[function(_dereq_,module){"use strict";var invariant=_dereq_("./invariant"),keyMirror=function(obj){var key,ret={};invariant(obj instanceof Object&&!Array.isArray(obj));for(key in obj)obj.hasOwnProperty(key)&&(ret[key]=key);return ret};module.exports=keyMirror},{"./invariant":69}],73:[function(_dereq_,module){var keyOf=function(oneKeyObj){var key;for(key in oneKeyObj)if(oneKeyObj.hasOwnProperty(key))return key;return null};module.exports=keyOf},{}],74:[function(_dereq_,module){"use strict";function monitorCodeUse(eventName){invariant(eventName&&!/[^a-z0-9_]/.test(eventName))}var invariant=_dereq_("./invariant");module.exports=monitorCodeUse},{"./invariant":69}],75:[function(_dereq_,module){"use strict";var emptyFunction=_dereq_("./emptyFunction"),warning=emptyFunction;module.exports=warning},{"./emptyFunction":65}],76:[function(_dereq_,module){!function(define){"use strict";define(function(_dereq_){var makePromise=_dereq_("./makePromise"),Scheduler=_dereq_("./Scheduler"),async=_dereq_("./async");return makePromise({scheduler:new Scheduler(async)})})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory(_dereq_)})},{"./Scheduler":78,"./async":79,"./makePromise":80}],77:[function(_dereq_,module){!function(define){"use strict";define(function(){function Queue(capacityPow2){this.head=this.tail=this.length=0,this.buffer=new Array(1<i;++i)newBuffer[i]=buffer[i];else{for(capacity=buffer.length,len=this.tail;capacity>head;++i,++head)newBuffer[i]=buffer[head];for(head=0;len>head;++i,++head)newBuffer[i]=buffer[head]}this.buffer=newBuffer,this.head=0,this.tail=this.length},Queue})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory()})},{}],78:[function(_dereq_,module){!function(define){"use strict";define(function(_dereq_){function Scheduler(async){this._async=async,this._queue=new Queue(15),this._afterQueue=new Queue(5),this._running=!1;var self=this;this.drain=function(){self._drain()}}function runQueue(queue){for(;queue.length>0;)queue.shift().run()}var Queue=_dereq_("./Queue");return Scheduler.prototype.enqueue=function(task){this._add(this._queue,task)},Scheduler.prototype.afterQueue=function(task){this._add(this._afterQueue,task)},Scheduler.prototype._drain=function(){runQueue(this._queue),this._running=!1,runQueue(this._afterQueue)},Scheduler.prototype._add=function(queue,task){queue.push(task),this._running||(this._running=!0,this._async(this.drain))},Scheduler})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory(_dereq_)})},{"./Queue":77}],79:[function(_dereq_,module){!function(define){"use strict";define(function(_dereq_){var nextTick,MutationObs;return nextTick="undefined"!=typeof process&&null!==process&&"function"==typeof process.nextTick?function(f){process.nextTick(f)}:(MutationObs="function"==typeof MutationObserver&&MutationObserver||"function"==typeof WebKitMutationObserver&&WebKitMutationObserver)?function(document,MutationObserver){function run(){var f=scheduled;scheduled=void 0,f()}var scheduled,el=document.createElement("div"),o=new MutationObserver(run);return o.observe(el,{attributes:!0}),function(f){scheduled=f,el.setAttribute("class","x")}}(document,MutationObs):function(cjsRequire){var vertx;try{vertx=cjsRequire("vertx")}catch(ignore){}if(vertx){if("function"==typeof vertx.runOnLoop)return vertx.runOnLoop;if("function"==typeof vertx.runOnContext)return vertx.runOnContext}var capturedSetTimeout=setTimeout;return function(t){capturedSetTimeout(t,0)}}(_dereq_)})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory(_dereq_)})},{}],80:[function(_dereq_,module){!function(define){"use strict";define(function(){return function(environment){function Promise(resolver,handler){this._handler=resolver===Handler?handler:init(resolver)}function init(resolver){function promiseResolve(x){handler.resolve(x)}function promiseReject(reason){handler.reject(reason)}function promiseNotify(x){handler.notify(x)}var handler=new Pending;try{resolver(promiseResolve,promiseReject,promiseNotify)}catch(e){promiseReject(e)}return handler}function resolve(x){return isPromise(x)?x:new Promise(Handler,new Async(getHandler(x)))}function reject(x){return new Promise(Handler,new Async(new Rejected(x)))}function never(){return foreverPendingPromise}function defer(){return new Promise(Handler,new Pending)}function all(promises){function settleAt(i,x,resolver){this[i]=x,0===--pending&&resolver.become(new Fulfilled(this))}var i,h,x,s,resolver=new Pending,pending=promises.length>>>0,results=new Array(pending);for(i=0;i0)){unreportRemaining(promises,i+1,h),resolver.become(h);break}results[i]=h.value,--pending}else results[i]=x,--pending;else--pending;return 0===pending&&resolver.become(new Fulfilled(results)),new Promise(Handler,resolver)}function unreportRemaining(promises,start,rejectedHandler){var i,h,x;for(i=start;i0||"function"!=typeof onRejected&&0>state)return new this.constructor(Handler,parent);var p=this._beget(),child=p._handler;return parent.chain(child,parent.receiver,onFulfilled,onRejected,arguments.length>2?arguments[2]:void 0),p},Promise.prototype["catch"]=function(onRejected){return this.then(void 0,onRejected)},Promise.prototype._beget=function(){var parent=this._handler,child=new Pending(parent.receiver,parent.join().context);return new this.constructor(Handler,child)},Promise.all=all,Promise.race=race,Handler.prototype.when=Handler.prototype.become=Handler.prototype.notify=Handler.prototype.fail=Handler.prototype._unreport=Handler.prototype._report=noop,Handler.prototype._state=0,Handler.prototype.state=function(){return this._state -},Handler.prototype.join=function(){for(var h=this;void 0!==h.handler;)h=h.handler;return h},Handler.prototype.chain=function(to,receiver,fulfilled,rejected,progress){this.when({resolver:to,receiver:receiver,fulfilled:fulfilled,rejected:rejected,progress:progress})},Handler.prototype.visit=function(receiver,fulfilled,rejected,progress){this.chain(failIfRejected,receiver,fulfilled,rejected,progress)},Handler.prototype.fold=function(f,z,c,to){this.visit(to,function(x){f.call(c,z,x,this)},to.reject,to.notify)},inherit(Handler,FailIfRejected),FailIfRejected.prototype.become=function(h){h.fail()};var failIfRejected=new FailIfRejected;inherit(Handler,Pending),Pending.prototype._state=0,Pending.prototype.resolve=function(x){this.become(getHandler(x))},Pending.prototype.reject=function(x){this.resolved||this.become(new Rejected(x))},Pending.prototype.join=function(){if(!this.resolved)return this;for(var h=this;void 0!==h.handler;)if(h=h.handler,h===this)return this.handler=cycle();return h},Pending.prototype.run=function(){var q=this.consumers,handler=this.join();this.consumers=void 0;for(var i=0;i"}};module.exports=HashLocation},{"../actions/LocationActions":1,"../utils/Path":19,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],11:[function(_dereq_,module){function getWindowPath(){return invariant(canUseDOM,"getWindowPath needs a DOM"),Path.decode(window.location.pathname+window.location.search)}function notifyChange(type){var change={path:getWindowPath(),type:type};_changeListeners.forEach(function(listener){listener(change)})}function onPopState(){notifyChange(LocationActions.POP)}var invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM,LocationActions=_dereq_("../actions/LocationActions"),Path=_dereq_("../utils/Path"),_changeListeners=[],_isListening=!1,HistoryLocation={addChangeListener:function(listener){_changeListeners.push(listener),_isListening||(window.addEventListener?window.addEventListener("popstate",onPopState,!1):window.attachEvent("popstate",onPopState),_isListening=!0)},push:function(path){window.history.pushState({path:path},"",Path.encode(path)),notifyChange(LocationActions.PUSH)},replace:function(path){window.history.replaceState({path:path},"",Path.encode(path)),notifyChange(LocationActions.REPLACE)},pop:function(){window.history.back()},getCurrentPath:getWindowPath,toString:function(){return""}};module.exports=HistoryLocation},{"../actions/LocationActions":1,"../utils/Path":19,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],12:[function(_dereq_,module){var HistoryLocation=_dereq_("./HistoryLocation"),Path=_dereq_("../utils/Path"),RefreshLocation={push:function(path){window.location=Path.encode(path)},replace:function(path){window.location.replace(Path.encode(path))},pop:function(){window.history.back()},getCurrentPath:HistoryLocation.getCurrentPath,toString:function(){return""}};module.exports=RefreshLocation},{"../utils/Path":19,"./HistoryLocation":11}],13:[function(_dereq_,module){var invariant=_dereq_("react/lib/invariant"),FakeNode={render:function(){invariant(!1,"%s elements should not be rendered",this.constructor.displayName)}};module.exports=FakeNode},{"react/lib/invariant":39}],14:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,Navigation={contextTypes:{makePath:React.PropTypes.func.isRequired,makeHref:React.PropTypes.func.isRequired,transitionTo:React.PropTypes.func.isRequired,replaceWith:React.PropTypes.func.isRequired,goBack:React.PropTypes.func.isRequired},makePath:function(to,params,query){return this.context.makePath(to,params,query)},makeHref:function(to,params,query){return this.context.makeHref(to,params,query)},transitionTo:function(to,params,query){this.context.transitionTo(to,params,query)},replaceWith:function(to,params,query){this.context.replaceWith(to,params,query)},goBack:function(){this.context.goBack()}};module.exports=Navigation},{}],15:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,NavigationContext={childContextTypes:{makePath:React.PropTypes.func.isRequired,makeHref:React.PropTypes.func.isRequired,transitionTo:React.PropTypes.func.isRequired,replaceWith:React.PropTypes.func.isRequired,goBack:React.PropTypes.func.isRequired},getChildContext:function(){return{makePath:this.constructor.makePath,makeHref:this.constructor.makeHref,transitionTo:this.constructor.transitionTo,replaceWith:this.constructor.replaceWith,goBack:this.constructor.goBack}}};module.exports=NavigationContext},{}],16:[function(_dereq_,module){var invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM,getWindowScrollPosition=_dereq_("../utils/getWindowScrollPosition"),Scrolling={componentWillMount:function(){invariant(null==this.getScrollBehavior()||canUseDOM,"Cannot use scroll behavior without a DOM"),this._scrollHistory={}},componentDidMount:function(){this._updateScroll()},componentWillUpdate:function(){this._scrollHistory[this.state.path]=getWindowScrollPosition()},componentDidUpdate:function(){this._updateScroll()},componentWillUnmount:function(){delete this._scrollHistory},getScrollPosition:function(path){return this._scrollHistory[path]||null},_updateScroll:function(){var scrollBehavior=this.getScrollBehavior();scrollBehavior&&scrollBehavior.updateScrollPosition(this.getScrollPosition(this.state.path),this.state.action)}};module.exports=Scrolling},{"../utils/getWindowScrollPosition":26,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],17:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,State={contextTypes:{getCurrentPath:React.PropTypes.func.isRequired,getCurrentRoutes:React.PropTypes.func.isRequired,getCurrentParams:React.PropTypes.func.isRequired,getCurrentQuery:React.PropTypes.func.isRequired,isActive:React.PropTypes.func.isRequired},getPath:function(){return this.context.getCurrentPath()},getRoutes:function(){return this.context.getCurrentRoutes()},getParams:function(){return this.context.getCurrentParams()},getQuery:function(){return this.context.getCurrentQuery()},isActive:function(to,params,query){return this.context.isActive(to,params,query)}};module.exports=State},{}],18:[function(_dereq_,module){function routeIsActive(activeRoutes,routeName){return activeRoutes.some(function(route){return route.name===routeName})}function paramsAreActive(activeParams,params){for(var property in params)if(String(activeParams[property])!==String(params[property]))return!1;return!0}function queryIsActive(activeQuery,query){for(var property in query)if(String(activeQuery[property])!==String(query[property]))return!1;return!0}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,assign=_dereq_("react/lib/Object.assign"),Path=_dereq_("../utils/Path"),StateContext={getCurrentPath:function(){return this.state.path},getCurrentRoutes:function(){return this.state.routes.slice(0)},getCurrentParams:function(){return assign({},this.state.params)},getCurrentQuery:function(){return assign({},this.state.query)},isActive:function(to,params,query){return Path.isAbsolute(to)?to===this.state.path:routeIsActive(this.state.routes,to)&¶msAreActive(this.state.params,params)&&(null==query||queryIsActive(this.state.query,query))},childContextTypes:{getCurrentPath:React.PropTypes.func.isRequired,getCurrentRoutes:React.PropTypes.func.isRequired,getCurrentParams:React.PropTypes.func.isRequired,getCurrentQuery:React.PropTypes.func.isRequired,isActive:React.PropTypes.func.isRequired},getChildContext:function(){return{getCurrentPath:this.getCurrentPath,getCurrentRoutes:this.getCurrentRoutes,getCurrentParams:this.getCurrentParams,getCurrentQuery:this.getCurrentQuery,isActive:this.isActive}}};module.exports=StateContext},{"../utils/Path":19,"react/lib/Object.assign":36}],19:[function(_dereq_,module){function decodePathSegment(string){return decodeURIComponent(string.replace(/\+/g," "))}function encodePathSegment(string){return encodeURIComponent(string).replace(/%20/g,"+")}function compilePattern(pattern){if(!(pattern in _compiledPatterns)){var paramNames=[],source=pattern.replace(paramCompileMatcher,function(match,paramName){return paramName?(paramNames.push(paramName),"([^/?#]+)"):"*"===match?(paramNames.push("splat"),"(.*?)"):"\\"+match});_compiledPatterns[pattern]={matcher:new RegExp("^"+source+"$","i"),paramNames:paramNames}}return _compiledPatterns[pattern]}var invariant=_dereq_("react/lib/invariant"),merge=_dereq_("qs/lib/utils").merge,qs=_dereq_("qs"),paramCompileMatcher=/:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g,paramInjectMatcher=/:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g,paramInjectTrailingSlashMatcher=/\/\/\?|\/\?/g,queryMatcher=/\?(.+)/,_compiledPatterns={},Path={decode:function(path){return String(path).split("/").map(decodePathSegment).join("/")},encode:function(path){return String(path).split("/").map(encodePathSegment).join("/")},extractParamNames:function(pattern){return compilePattern(pattern).paramNames},extractParams:function(pattern,path){var object=compilePattern(pattern),match=path.match(object.matcher);if(!match)return null;var params={};return object.paramNames.forEach(function(paramName,index){params[paramName]=match[index+1]}),params},injectParams:function(pattern,params){params=params||{};var splatIndex=0;return pattern.replace(paramInjectMatcher,function(match,paramName){if(paramName=paramName||"splat","?"!==paramName.slice(-1))invariant(null!=params[paramName],'Missing "'+paramName+'" parameter for path "'+pattern+'"');else if(paramName=paramName.slice(0,-1),null==params[paramName])return"";var segment;return"splat"===paramName&&Array.isArray(params[paramName])?(segment=params[paramName][splatIndex++],invariant(null!=segment,"Missing splat # "+splatIndex+' for path "'+pattern+'"')):segment=params[paramName],segment}).replace(paramInjectTrailingSlashMatcher,"/")},extractQuery:function(path){var match=path.match(queryMatcher);return match&&qs.parse(match[1])},withoutQuery:function(path){return path.replace(queryMatcher,"")},withQuery:function(path,query){var existingQuery=Path.extractQuery(path);existingQuery&&(query=query?merge(existingQuery,query):existingQuery);var queryString=query&&qs.stringify(query);return queryString?Path.withoutQuery(path)+"?"+queryString:path},isAbsolute:function(path){return"/"===path.charAt(0)},normalize:function(path){return path.replace(/^\/*/,"/")},join:function(a,b){return a.replace(/\/*$/,"/")+b}};module.exports=Path},{qs:30,"qs/lib/utils":34,"react/lib/invariant":39}],20:[function(_dereq_,module){var Promise=_dereq_("when/lib/Promise");module.exports=Promise},{"when/lib/Promise":41}],21:[function(_dereq_,module){var PropTypes={falsy:function(props,propName,elementName){return props[propName]?new Error("<"+elementName+'> may not have a "'+propName+'" prop'):void 0}};module.exports=PropTypes},{}],22:[function(_dereq_,module){function Redirect(to,params,query){this.to=to,this.params=params,this.query=query}module.exports=Redirect},{}],23:[function(_dereq_,module){function runHooks(hooks,callback){try{var promise=hooks.reduce(function(promise,hook){return promise?promise.then(hook):hook()},null)}catch(error){return callback(error)}promise?promise.then(function(){setTimeout(callback)},function(error){setTimeout(function(){callback(error)})}):callback()}function runTransitionFromHooks(transition,routes,components,callback){components=reversedArray(components);var hooks=reversedArray(routes).map(function(route,index){return function(){var handler=route.handler;if(!transition.isAborted&&handler.willTransitionFrom)return handler.willTransitionFrom(transition,components[index]);var promise=transition._promise;return transition._promise=null,promise}});runHooks(hooks,callback)}function runTransitionToHooks(transition,routes,params,query,callback){var hooks=routes.map(function(route){return function(){var handler=route.handler;!transition.isAborted&&handler.willTransitionTo&&handler.willTransitionTo(transition,params,query);var promise=transition._promise;return transition._promise=null,promise}});runHooks(hooks,callback)}function Transition(path,retry){this.path=path,this.abortReason=null,this.isAborted=!1,this.retry=retry.bind(this),this._promise=null}var assign=_dereq_("react/lib/Object.assign"),reversedArray=_dereq_("./reversedArray"),Redirect=_dereq_("./Redirect"),Promise=_dereq_("./Promise");assign(Transition.prototype,{abort:function(reason){this.abortReason=reason,this.isAborted=!0},redirect:function(to,params,query){this.abort(new Redirect(to,params,query))},wait:function(value){this._promise=Promise.resolve(value)},from:function(routes,components,callback){return runTransitionFromHooks(this,routes,components,callback)},to:function(routes,params,query,callback){return runTransitionToHooks(this,routes,params,query,callback)}}),module.exports=Transition},{"./Promise":20,"./Redirect":22,"./reversedArray":27,"react/lib/Object.assign":36}],24:[function(_dereq_,module){function defaultErrorHandler(error){throw error}function defaultAbortHandler(abortReason,location){if("string"==typeof location)throw new Error("Unhandled aborted transition! Reason: "+abortReason);abortReason instanceof Redirect?location.replace(this.makePath(abortReason.to,abortReason.params,abortReason.query)):location.pop()}function findMatch(pathname,routes,defaultRoute,notFoundRoute){for(var match,route,params,i=0,len=routes.length;len>i;++i){if(route=routes[i],match=findMatch(pathname,route.childRoutes,route.defaultRoute,route.notFoundRoute),null!=match)return match.routes.unshift(route),match;if(params=Path.extractParams(route.path,pathname))return createMatch(route,params)}return defaultRoute&&(params=Path.extractParams(defaultRoute.path,pathname))?createMatch(defaultRoute,params):notFoundRoute&&(params=Path.extractParams(notFoundRoute.path,pathname))?createMatch(notFoundRoute,params):match}function createMatch(route,params){return{routes:[route],params:params}}function hasMatch(routes,route,prevParams,nextParams){return routes.some(function(r){if(r!==route)return!1;for(var paramName,paramNames=route.paramNames,i=0,len=paramNames.length;len>i;++i)if(paramName=paramNames[i],nextParams[paramName]!==prevParams[paramName])return!1;return!0})}function createRouter(options){options=options||{},"function"==typeof options?options={routes:options}:Array.isArray(options)&&(options={routes:options});var routes=[],namedRoutes={},components=[],location=options.location||DEFAULT_LOCATION,scrollBehavior=options.scrollBehavior||DEFAULT_SCROLL_BEHAVIOR,onError=options.onError||defaultErrorHandler,onAbort=options.onAbort||defaultAbortHandler,state={};location!==HistoryLocation||supportsHistory()||(location=RefreshLocation);var router=React.createClass({displayName:"Router",mixins:[NavigationContext,StateContext,Scrolling],statics:{defaultRoute:null,notFoundRoute:null,addRoutes:function(children){routes.push.apply(routes,createRoutesFromChildren(children,this,namedRoutes))},makePath:function(to,params,query){var path;if(Path.isAbsolute(to))path=Path.normalize(to);else{var route=namedRoutes[to];invariant(route,'Unable to find ',to),path=route.path}return Path.withQuery(Path.injectParams(path,params),query)},makeHref:function(to,params,query){var path=this.makePath(to,params,query);return location===HashLocation?"#"+path:path},transitionTo:function(to,params,query){invariant("string"!=typeof location,"You cannot use transitionTo with a static location"),location.push(this.makePath(to,params,query))},replaceWith:function(to,params,query){invariant("string"!=typeof location,"You cannot use replaceWith with a static location"),location.replace(this.makePath(to,params,query))},goBack:function(){invariant("string"!=typeof location,"You cannot use goBack with a static location"),location.pop()},match:function(path){return findMatch(Path.withoutQuery(path),routes,this.defaultRoute,this.notFoundRoute)||null},dispatch:function(path,action,callback){if(state.path!==path){var match=this.match(path);warning(null!=match,'No route matches path "%s". Make sure you have somewhere in your routes',path,path),null==match&&(match={});var fromRoutes,toRoutes,prevRoutes=state.routes||[],prevParams=state.params||{},nextRoutes=match.routes||[],nextParams=match.params||{},nextQuery=Path.extractQuery(path)||{};prevRoutes.length?(fromRoutes=prevRoutes.filter(function(route){return!hasMatch(nextRoutes,route,prevParams,nextParams)}),toRoutes=nextRoutes.filter(function(route){return!hasMatch(prevRoutes,route,prevParams,nextParams)})):(fromRoutes=[],toRoutes=nextRoutes);var transition=new Transition(path,this.replaceWith.bind(this,path));transition.from(fromRoutes,components,function(error){return error||transition.isAborted?callback.call(router,error,transition):void transition.to(toRoutes,nextParams,nextQuery,function(error){return error||transition.isAborted?callback.call(router,error,transition):(state.path=path,state.action=action,state.routes=nextRoutes,state.params=nextParams,state.query=nextQuery,void callback.call(router,null,transition))})})}},run:function(callback){function dispatchHandler(error,transition){error?onError.call(router,error):transition.isAborted?onAbort.call(router,transition.abortReason,location):callback.call(router,router,state)}function changeListener(change){router.dispatch(change.path,change.type,dispatchHandler)}"string"==typeof location?(warning(!canUseDOM||!1,"You should not use a static location in a DOM environment because the router will not be kept in sync with the current URL"),router.dispatch(location,null,dispatchHandler)):(invariant(canUseDOM,"You cannot use %s in a non-DOM environment",location),location.addChangeListener&&location.addChangeListener(changeListener),router.dispatch(location.getCurrentPath(),null,dispatchHandler))}},propTypes:{children:PropTypes.falsy},getLocation:function(){return location},getScrollBehavior:function(){return scrollBehavior},getRouteAtDepth:function(depth){var routes=this.state.routes;return routes&&routes[depth]},getRouteComponents:function(){return components},getInitialState:function(){return state},componentWillReceiveProps:function(){this.setState(state)},render:function(){return this.getRouteAtDepth(0)?React.createElement(RouteHandler,this.props):null},childContextTypes:{getRouteAtDepth:React.PropTypes.func.isRequired,getRouteComponents:React.PropTypes.func.isRequired,routeHandlers:React.PropTypes.array.isRequired},getChildContext:function(){return{getRouteComponents:this.getRouteComponents,getRouteAtDepth:this.getRouteAtDepth,routeHandlers:[this]}}});return options.routes&&router.addRoutes(options.routes),router}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,warning=_dereq_("react/lib/warning"),invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM,ImitateBrowserBehavior=_dereq_("../behaviors/ImitateBrowserBehavior"),RouteHandler=_dereq_("../components/RouteHandler"),HashLocation=_dereq_("../locations/HashLocation"),HistoryLocation=_dereq_("../locations/HistoryLocation"),NavigationContext=_dereq_("../mixins/NavigationContext"),StateContext=_dereq_("../mixins/StateContext"),Scrolling=_dereq_("../mixins/Scrolling"),createRoutesFromChildren=_dereq_("./createRoutesFromChildren"),supportsHistory=_dereq_("./supportsHistory"),Transition=_dereq_("./Transition"),PropTypes=_dereq_("./PropTypes"),Redirect=_dereq_("./Redirect"),Path=_dereq_("./Path"),DEFAULT_LOCATION=canUseDOM?HashLocation:"/",DEFAULT_SCROLL_BEHAVIOR=canUseDOM?ImitateBrowserBehavior:null;module.exports=createRouter},{"../behaviors/ImitateBrowserBehavior":2,"../components/RouteHandler":8,"../locations/HashLocation":10,"../locations/HistoryLocation":11,"../mixins/NavigationContext":15,"../mixins/Scrolling":16,"../mixins/StateContext":18,"./Path":19,"./PropTypes":21,"./Redirect":22,"./Transition":23,"./createRoutesFromChildren":25,"./supportsHistory":29,"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39,"react/lib/warning":40}],25:[function(_dereq_,module){function createRedirectHandler(to,_params,_query){return React.createClass({statics:{willTransitionTo:function(transition,params,query){transition.redirect(to,_params||params,_query||query)}},render:function(){return null}})}function checkPropTypes(componentName,propTypes,props){for(var propName in propTypes)if(propTypes.hasOwnProperty(propName)){var error=propTypes[propName](props,propName,componentName);error instanceof Error&&warning(!1,error.message)}}function createRoute(element,parentRoute,namedRoutes){var type=element.type,props=element.props,componentName=type&&type.displayName||"UnknownComponent";invariant(-1!==CONFIG_ELEMENT_TYPES.indexOf(type),'Unrecognized route configuration element "<%s>"',componentName),type.propTypes&&checkPropTypes(componentName,type.propTypes,props);var route={name:props.name};type===Redirect.type?(route.handler=createRedirectHandler(props.to,props.params,props.query),props.path=props.path||props.from):route.handler=props.handler;var parentPath=parentRoute&&parentRoute.path||"/";if((props.path||props.name)&&type!==DefaultRoute.type&&type!==NotFoundRoute.type){var path=props.path||props.name;Path.isAbsolute(path)||(path=Path.join(parentPath,path)),route.path=Path.normalize(path)}else route.path=parentPath,type===NotFoundRoute.type&&(route.path+="*");return route.paramNames=Path.extractParamNames(route.path),parentRoute&&Array.isArray(parentRoute.paramNames)&&parentRoute.paramNames.forEach(function(paramName){invariant(-1!==route.paramNames.indexOf(paramName),'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"',route.path,paramName,parentRoute.path)}),props.name&&(invariant(null==namedRoutes[props.name],'You cannot use the name "%s" for more than one route',props.name),namedRoutes[props.name]=route),type===NotFoundRoute.type?(invariant(parentRoute," must have a parent "),invariant(null==parentRoute.notFoundRoute,"You may not have more than one per "),parentRoute.notFoundRoute=route,null):type===DefaultRoute.type?(invariant(parentRoute," must have a parent "),invariant(null==parentRoute.defaultRoute,"You may not have more than one per "),parentRoute.defaultRoute=route,null):(route.childRoutes=createRoutesFromChildren(props.children,route,namedRoutes),route)}function createRoutesFromChildren(children,parentRoute,namedRoutes){var routes=[];return React.Children.forEach(children,function(child){(child=createRoute(child,parentRoute,namedRoutes))&&routes.push(child)}),routes}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,warning=_dereq_("react/lib/warning"),invariant=_dereq_("react/lib/invariant"),DefaultRoute=_dereq_("../components/DefaultRoute"),NotFoundRoute=_dereq_("../components/NotFoundRoute"),Redirect=_dereq_("../components/Redirect"),Route=_dereq_("../components/Route"),Path=_dereq_("./Path"),CONFIG_ELEMENT_TYPES=[DefaultRoute.type,NotFoundRoute.type,Redirect.type,Route.type];module.exports=createRoutesFromChildren},{"../components/DefaultRoute":3,"../components/NotFoundRoute":5,"../components/Redirect":6,"../components/Route":7,"./Path":19,"react/lib/invariant":39,"react/lib/warning":40}],26:[function(_dereq_,module){function getWindowScrollPosition(){return invariant(canUseDOM,"Cannot get current scroll position without a DOM"),{x:window.scrollX,y:window.scrollY}}var invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM;module.exports=getWindowScrollPosition},{"react/lib/ExecutionEnvironment":35,"react/lib/invariant":39}],27:[function(_dereq_,module){function reversedArray(array){return array.slice(0).reverse()}module.exports=reversedArray},{}],28:[function(_dereq_,module){function runRouter(routes,location,callback){"function"==typeof location&&(callback=location,location=null);var router=createRouter({routes:routes,location:location});return router.run(callback),router}var createRouter=_dereq_("./createRouter");module.exports=runRouter},{"./createRouter":24}],29:[function(_dereq_,module){function supportsHistory(){var ua=navigator.userAgent;return-1===ua.indexOf("Android 2.")&&-1===ua.indexOf("Android 4.0")||-1===ua.indexOf("Mobile Safari")||-1!==ua.indexOf("Chrome")?window.history&&"pushState"in window.history:!1}module.exports=supportsHistory},{}],30:[function(_dereq_,module){module.exports=_dereq_("./lib")},{"./lib":31}],31:[function(_dereq_,module){var Stringify=_dereq_("./stringify"),Parse=_dereq_("./parse"); +module.exports={stringify:Stringify,parse:Parse}},{"./parse":32,"./stringify":33}],32:[function(_dereq_,module){var Utils=_dereq_("./utils"),internals={delimiter:"&",depth:5,arrayLimit:20,parameterLimit:1e3};internals.parseValues=function(str,options){for(var obj={},parts=str.split(options.delimiter,1/0===options.parameterLimit?void 0:options.parameterLimit),i=0,il=parts.length;il>i;++i){var part=parts[i],pos=-1===part.indexOf("]=")?part.indexOf("="):part.indexOf("]=")+1;if(-1===pos)obj[Utils.decode(part)]="";else{var key=Utils.decode(part.slice(0,pos)),val=Utils.decode(part.slice(pos+1));obj[key]=obj[key]?[].concat(obj[key]).concat(val):val}}return obj},internals.parseObject=function(chain,val,options){if(!chain.length)return val;var root=chain.shift(),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,index=parseInt(cleanRoot,10);!isNaN(index)&&root!==cleanRoot&&index<=options.arrayLimit?(obj=[],obj[index]=internals.parseObject(chain,val,options)):obj[cleanRoot]=internals.parseObject(chain,val,options)}return obj},internals.parseKeys=function(key,val,options){if(key){var parent=/^([^\[\]]*)/,child=/(\[[^\[\]]*\])/g,segment=parent.exec(key);if(!Object.prototype.hasOwnProperty(segment[1])){var keys=[];segment[1]&&keys.push(segment[1]);for(var i=0;null!==(segment=child.exec(key))&&ii;++i){var key=keys[i],newObj=internals.parseKeys(key,tempObj[key],options);obj=Utils.merge(obj,newObj)}return Utils.compact(obj)}},{"./utils":34}],33:[function(_dereq_,module){var Utils=_dereq_("./utils"),internals={delimiter:"&"};internals.stringify=function(obj,prefix){if(Utils.isBuffer(obj)?obj=obj.toString():obj instanceof Date?obj=obj.toISOString():null===obj&&(obj=""),"string"==typeof obj||"number"==typeof obj||"boolean"==typeof obj)return[encodeURIComponent(prefix)+"="+encodeURIComponent(obj)];var values=[];for(var key in obj)obj.hasOwnProperty(key)&&(values=values.concat(internals.stringify(obj[key],prefix+"["+key+"]")));return values},module.exports=function(obj,options){options=options||{};var delimiter="undefined"==typeof options.delimiter?internals.delimiter:options.delimiter,keys=[];for(var key in obj)obj.hasOwnProperty(key)&&(keys=keys.concat(internals.stringify(obj[key],key)));return keys.join(delimiter)}},{"./utils":34}],34:[function(_dereq_,module,exports){exports.arrayToObject=function(source){for(var obj={},i=0,il=source.length;il>i;++i)"undefined"!=typeof source[i]&&(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;il>i;++i)"undefined"!=typeof source[i]&&(target[i]="object"==typeof target[i]?exports.merge(target[i],source[i]):source[i]);return target}if(Array.isArray(target)){if("object"!=typeof source)return target.push(source),target;target=exports.arrayToObject(target)}for(var keys=Object.keys(source),k=0,kl=keys.length;kl>k;++k){var key=keys[k],value=source[key];target[key]=value&&"object"==typeof value&&target[key]?exports.merge(target[key],value):value}return target},exports.decode=function(str){try{return decodeURIComponent(str.replace(/\+/g," "))}catch(e){return str}},exports.compact=function(obj,refs){if("object"!=typeof obj||null===obj)return obj;refs=refs||[];var lookup=refs.indexOf(obj);if(-1!==lookup)return refs[lookup];if(refs.push(obj),Array.isArray(obj)){for(var compacted=[],i=0,l=obj.length;l>i;++i)"undefined"!=typeof obj[i]&&compacted.push(obj[i]);return compacted}for(var keys=Object.keys(obj),i=0,il=keys.length;il>i;++i){var key=keys[i];obj[key]=exports.compact(obj[key],refs)}return obj},exports.isRegExp=function(obj){return"[object RegExp]"===Object.prototype.toString.call(obj)},exports.isBuffer=function(obj){return"undefined"!=typeof Buffer?Buffer.isBuffer(obj):!1}},{}],35:[function(_dereq_,module){"use strict";var canUseDOM=!("undefined"==typeof window||!window.document||!window.document.createElement),ExecutionEnvironment={canUseDOM:canUseDOM,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:canUseDOM&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:canUseDOM&&!!window.screen,isInWorker:!canUseDOM};module.exports=ExecutionEnvironment},{}],36:[function(_dereq_,module){function assign(target){if(null==target)throw new TypeError("Object.assign target cannot be null or undefined");for(var to=Object(target),hasOwnProperty=Object.prototype.hasOwnProperty,nextIndex=1;nextIndexi;++i)newBuffer[i]=buffer[i];else{for(capacity=buffer.length,len=this.tail;capacity>head;++i,++head)newBuffer[i]=buffer[head];for(head=0;len>head;++i,++head)newBuffer[i]=buffer[head]}this.buffer=newBuffer,this.head=0,this.tail=this.length},Queue})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory()})},{}],43:[function(_dereq_,module){!function(define){"use strict";define(function(_dereq_){function Scheduler(async){this._async=async,this._queue=new Queue(15),this._afterQueue=new Queue(5),this._running=!1;var self=this;this.drain=function(){self._drain()}}function runQueue(queue){for(;queue.length>0;)queue.shift().run()}var Queue=_dereq_("./Queue");return Scheduler.prototype.enqueue=function(task){this._add(this._queue,task)},Scheduler.prototype.afterQueue=function(task){this._add(this._afterQueue,task)},Scheduler.prototype._drain=function(){runQueue(this._queue),this._running=!1,runQueue(this._afterQueue)},Scheduler.prototype._add=function(queue,task){queue.push(task),this._running||(this._running=!0,this._async(this.drain))},Scheduler})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory(_dereq_)})},{"./Queue":42}],44:[function(_dereq_,module){!function(define){"use strict";define(function(_dereq_){var nextTick,MutationObs;return nextTick="undefined"!=typeof process&&null!==process&&"function"==typeof process.nextTick?function(f){process.nextTick(f)}:(MutationObs="function"==typeof MutationObserver&&MutationObserver||"function"==typeof WebKitMutationObserver&&WebKitMutationObserver)?function(document,MutationObserver){function run(){var f=scheduled;scheduled=void 0,f()}var scheduled,el=document.createElement("div"),o=new MutationObserver(run);return o.observe(el,{attributes:!0}),function(f){scheduled=f,el.setAttribute("class","x")}}(document,MutationObs):function(cjsRequire){var vertx;try{vertx=cjsRequire("vertx")}catch(ignore){}if(vertx){if("function"==typeof vertx.runOnLoop)return vertx.runOnLoop;if("function"==typeof vertx.runOnContext)return vertx.runOnContext}var capturedSetTimeout=setTimeout;return function(t){capturedSetTimeout(t,0)}}(_dereq_)})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory(_dereq_)})},{}],45:[function(_dereq_,module){!function(define){"use strict";define(function(){return function(environment){function Promise(resolver,handler){this._handler=resolver===Handler?handler:init(resolver)}function init(resolver){function promiseResolve(x){handler.resolve(x)}function promiseReject(reason){handler.reject(reason)}function promiseNotify(x){handler.notify(x)}var handler=new Pending;try{resolver(promiseResolve,promiseReject,promiseNotify)}catch(e){promiseReject(e)}return handler}function resolve(x){return isPromise(x)?x:new Promise(Handler,new Async(getHandler(x)))}function reject(x){return new Promise(Handler,new Async(new Rejected(x)))}function never(){return foreverPendingPromise}function defer(){return new Promise(Handler,new Pending)}function all(promises){function settleAt(i,x,resolver){this[i]=x,0===--pending&&resolver.become(new Fulfilled(this))}var i,h,x,s,resolver=new Pending,pending=promises.length>>>0,results=new Array(pending);for(i=0;i0)){unreportRemaining(promises,i+1,h),resolver.become(h);break}results[i]=h.value,--pending}else results[i]=x,--pending;else--pending;return 0===pending&&resolver.become(new Fulfilled(results)),new Promise(Handler,resolver)}function unreportRemaining(promises,start,rejectedHandler){var i,h,x;for(i=start;i0||"function"!=typeof onRejected&&0>state)return new this.constructor(Handler,parent);var p=this._beget(),child=p._handler;return parent.chain(child,parent.receiver,onFulfilled,onRejected,arguments.length>2?arguments[2]:void 0),p},Promise.prototype["catch"]=function(onRejected){return this.then(void 0,onRejected)},Promise.prototype._beget=function(){var parent=this._handler,child=new Pending(parent.receiver,parent.join().context);return new this.constructor(Handler,child)},Promise.all=all,Promise.race=race,Handler.prototype.when=Handler.prototype.become=Handler.prototype.notify=Handler.prototype.fail=Handler.prototype._unreport=Handler.prototype._report=noop,Handler.prototype._state=0,Handler.prototype.state=function(){return this._state},Handler.prototype.join=function(){for(var h=this;void 0!==h.handler;)h=h.handler;return h},Handler.prototype.chain=function(to,receiver,fulfilled,rejected,progress){this.when({resolver:to,receiver:receiver,fulfilled:fulfilled,rejected:rejected,progress:progress})},Handler.prototype.visit=function(receiver,fulfilled,rejected,progress){this.chain(failIfRejected,receiver,fulfilled,rejected,progress)},Handler.prototype.fold=function(f,z,c,to){this.visit(to,function(x){f.call(c,z,x,this)},to.reject,to.notify)},inherit(Handler,FailIfRejected),FailIfRejected.prototype.become=function(h){h.fail()};var failIfRejected=new FailIfRejected;inherit(Handler,Pending),Pending.prototype._state=0,Pending.prototype.resolve=function(x){this.become(getHandler(x))},Pending.prototype.reject=function(x){this.resolved||this.become(new Rejected(x))},Pending.prototype.join=function(){if(!this.resolved)return this;for(var h=this;void 0!==h.handler;)if(h=h.handler,h===this)return this.handler=cycle();return h},Pending.prototype.run=function(){var q=this.consumers,handler=this.join();this.consumers=void 0;for(var i=0;i