diff --git a/dist/react-router.js b/dist/react-router.js index 4147693423..0ddf702738 100644 --- a/dist/react-router.js +++ b/dist/react-router.js @@ -1,3891 +1,4241 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.ReactRouter=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o component is a special kind of that - * renders when its parent matches but none of its siblings do. - * Only one such route may be used at any given level in the - * route hierarchy. - */ -var DefaultRoute = React.createClass({ - - displayName: 'DefaultRoute', - - mixins: [ FakeNode ], - - propTypes: { - name: React.PropTypes.string, - path: PropTypes.falsy, - handler: React.PropTypes.func.isRequired - } - -}); - -module.exports = DefaultRoute; - -},{"../mixins/FakeNode":14,"../utils/PropTypes":25}],5:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var classSet = _dereq_('react/lib/cx'); -var assign = _dereq_('react/lib/Object.assign'); -var Navigation = _dereq_('../mixins/Navigation'); -var State = _dereq_('../mixins/State'); - -function isLeftClickEvent(event) { - return event.button === 0; -} - -function isModifiedEvent(event) { - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); -} - -/** - * components are used to create an element that links to a route. - * When that route is active, the link gets an "active" class name (or the - * value of its `activeClassName` prop). - * - * For example, assuming you have the following route: - * - * - * - * You could use the following component to link to that route: - * - * - * - * In addition to params, links may pass along query string parameters - * using the `query` prop. - * - * - */ -var Link = React.createClass({ - - displayName: 'Link', - - mixins: [ Navigation, State ], - - propTypes: { - activeClassName: React.PropTypes.string.isRequired, - to: React.PropTypes.string.isRequired, - params: React.PropTypes.object, - query: React.PropTypes.object, - onClick: React.PropTypes.func - }, - - getDefaultProps: function () { - return { - activeClassName: 'active' - }; - }, - - handleClick: function (event) { - var allowTransition = true; - var clickResult; - - if (this.props.onClick) - clickResult = this.props.onClick(event); - - if (isModifiedEvent(event) || !isLeftClickEvent(event)) - return; - - if (clickResult === false || event.defaultPrevented === true) - allowTransition = false; - - event.preventDefault(); - - if (allowTransition) - this.transitionTo(this.props.to, this.props.params, this.props.query); - }, - - /** - * Returns the value of the "href" attribute to use on the DOM element. - */ - getHref: function () { - return this.makeHref(this.props.to, this.props.params, this.props.query); - }, - - /** - * Returns the value of the "class" attribute to use on the DOM element, which contains - * the value of the activeClassName property when this is active. - */ - getClassName: function () { - var classNames = {}; - - if (this.props.className) - classNames[this.props.className] = true; - - if (this.isActive(this.props.to, this.props.params, this.props.query)) - classNames[this.props.activeClassName] = true; - - return classSet(classNames); - }, - - render: function () { - var props = assign({}, this.props, { - href: this.getHref(), - className: this.getClassName(), - onClick: this.handleClick - }); - - return React.DOM.a(props, this.props.children); - } - -}); - -module.exports = Link; - -},{"../mixins/Navigation":15,"../mixins/State":19,"react/lib/Object.assign":40,"react/lib/cx":41}],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 is a special kind of that - * renders when the beginning of its parent's path matches - * but none of its siblings do, including any . - * Only one such route may be used at any given level in the - * route hierarchy. - */ -var NotFoundRoute = React.createClass({ - - displayName: 'NotFoundRoute', - - mixins: [ FakeNode ], - - propTypes: { - name: React.PropTypes.string, - path: PropTypes.falsy, - handler: React.PropTypes.func.isRequired - } - -}); - -module.exports = NotFoundRoute; - -},{"../mixins/FakeNode":14,"../utils/PropTypes":25}],7:[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. - */ -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; - -},{"../mixins/FakeNode":14,"../utils/PropTypes":25}],8:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var FakeNode = _dereq_('../mixins/FakeNode'); - -/** - * components specify components that are rendered to the page when the - * URL matches a given pattern. - * - * Routes are arranged in a nested tree structure. When a new URL is requested, - * the tree is searched depth-first to find a route whose path matches the URL. - * When one is found, all routes in the tree that lead to it are considered - * "active" and their components are rendered into the DOM, nested in the same - * order as they are in the tree. - * - * 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. - * - * var routes = [ - * - * - * - * - * - * ]; - * - * Router.run(routes, function (Handler) { - * React.render(, document.body); - * }); - * - * Handlers for Route components that contain children can render their active - * child route using a element. - * - * var App = React.createClass({ - * render: function () { - * return ( - *
- * - *
- * ); - * } - * }); - */ -var Route = React.createClass({ - - displayName: 'Route', - - mixins: [ FakeNode ], - - propTypes: { - name: React.PropTypes.string, - path: React.PropTypes.string, - handler: React.PropTypes.func.isRequired, - ignoreScrollBehavior: React.PropTypes.bool - } - -}); - -module.exports = Route; - -},{"../mixins/FakeNode":14}],9:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); -var RouteHandlerMixin = _dereq_('../mixins/RouteHandler'); - -/** - * A component renders the active child route handler - * when routes are nested. - */ -var RouteHandler = React.createClass({ - - displayName: 'RouteHandler', - - mixins: [RouteHandlerMixin], - - getDefaultProps: function () { - return { - ref: '__routeHandler__' - }; - }, - - render: function () { - return this.getRouteHandler(); - } - -}); - -module.exports = RouteHandler; - -},{"../mixins/RouteHandler":17}],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.RouteHandler = _dereq_('./components/RouteHandler'); - -exports.HashLocation = _dereq_('./locations/HashLocation'); -exports.HistoryLocation = _dereq_('./locations/HistoryLocation'); -exports.RefreshLocation = _dereq_('./locations/RefreshLocation'); - -exports.ImitateBrowserBehavior = _dereq_('./behaviors/ImitateBrowserBehavior'); -exports.ScrollToTopBehavior = _dereq_('./behaviors/ScrollToTopBehavior'); - -exports.Navigation = _dereq_('./mixins/Navigation'); -exports.State = _dereq_('./mixins/State'); - -exports.create = _dereq_('./utils/createRouter'); -exports.run = _dereq_('./utils/runRouter'); - -exports.History = _dereq_('./utils/History'); - -},{"./behaviors/ImitateBrowserBehavior":2,"./behaviors/ScrollToTopBehavior":3,"./components/DefaultRoute":4,"./components/Link":5,"./components/NotFoundRoute":6,"./components/Redirect":7,"./components/Route":8,"./components/RouteHandler":9,"./locations/HashLocation":11,"./locations/HistoryLocation":12,"./locations/RefreshLocation":13,"./mixins/Navigation":15,"./mixins/State":19,"./utils/History":22,"./utils/createRouter":28,"./utils/runRouter":32}],11:[function(_dereq_,module,exports){ -var LocationActions = _dereq_('../actions/LocationActions'); -var History = _dereq_('../utils/History'); -var Path = _dereq_('../utils/Path'); - -/** - * Returns the current URL path from the `hash` portion of the URL, including - * query string. - */ -function getHashPath() { - return Path.decode( - // We can't use window.location.hash here because it's not - // consistent across browsers - Firefox will pre-decode it! - window.location.href.split('#')[1] || '' - ); -} - -var _actionType; - -function ensureSlash() { - var path = getHashPath(); - - if (path.charAt(0) === '/') - return true; +var ReactRouter = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + exports.DefaultRoute = __webpack_require__(1); + exports.Link = __webpack_require__(2); + exports.NotFoundRoute = __webpack_require__(3); + exports.Redirect = __webpack_require__(4); + exports.Route = __webpack_require__(5); + exports.RouteHandler = __webpack_require__(6); + + exports.HashLocation = __webpack_require__(7); + exports.HistoryLocation = __webpack_require__(8); + exports.RefreshLocation = __webpack_require__(9); + + exports.ImitateBrowserBehavior = __webpack_require__(10); + exports.ScrollToTopBehavior = __webpack_require__(11); + + exports.Navigation = __webpack_require__(12); + exports.State = __webpack_require__(13); + + exports.create = __webpack_require__(14); + exports.run = __webpack_require__(15); + + exports.History = __webpack_require__(16); + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__(17); + var FakeNode = __webpack_require__(18); + var PropTypes = __webpack_require__(19); - HashLocation.replace('/' + path); + /** + * A component is a special kind of that + * renders when its parent matches but none of its siblings do. + * Only one such route may be used at any given level in the + * route hierarchy. + */ + var DefaultRoute = React.createClass({ + + displayName: 'DefaultRoute', + + mixins: [ FakeNode ], + + propTypes: { + name: React.PropTypes.string, + path: PropTypes.falsy, + handler: React.PropTypes.func.isRequired + } + + }); + + module.exports = DefaultRoute; + + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__(17); + var classSet = __webpack_require__(34); + var assign = __webpack_require__(35); + var Navigation = __webpack_require__(12); + var State = __webpack_require__(13); + + function isLeftClickEvent(event) { + return event.button === 0; + } + + function isModifiedEvent(event) { + return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); + } + + /** + * components are used to create an
element that links to a route. + * When that route is active, the link gets an "active" class name (or the + * value of its `activeClassName` prop). + * + * For example, assuming you have the following route: + * + * + * + * You could use the following component to link to that route: + * + * + * + * In addition to params, links may pass along query string parameters + * using the `query` prop. + * + * + */ + var Link = React.createClass({ + + displayName: 'Link', + + mixins: [ Navigation, State ], - return false; -} + propTypes: { + activeClassName: React.PropTypes.string.isRequired, + to: React.PropTypes.string.isRequired, + params: React.PropTypes.object, + query: React.PropTypes.object, + onClick: React.PropTypes.func + }, -var _changeListeners = []; + getDefaultProps: function () { + return { + activeClassName: 'active' + }; + }, -function notifyChange(type) { - if (type === LocationActions.PUSH) - History.length += 1; + handleClick: function (event) { + var allowTransition = true; + var clickResult; - var change = { - path: getHashPath(), - type: type - }; + if (this.props.onClick) + clickResult = this.props.onClick(event); - _changeListeners.forEach(function (listener) { - listener(change); - }); -} + if (isModifiedEvent(event) || !isLeftClickEvent(event)) + return; -var _isListening = false; - -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; - } -} + if (clickResult === false || event.defaultPrevented === true) + allowTransition = false; -/** - * A Location that uses `window.location.hash`. - */ -var HashLocation = { - - addChangeListener: function (listener) { - _changeListeners.push(listener); - - // Do this BEFORE listening for hashchange. - ensureSlash(); - - if (_isListening) - return; + event.preventDefault(); - if (window.addEventListener) { - window.addEventListener('hashchange', onHashChange, false); - } else { - window.attachEvent('onhashchange', onHashChange); - } - - _isListening = true; - }, - - removeChangeListener: function(listener) { - for (var i = 0, l = _changeListeners.length; i < l; i ++) { - if (_changeListeners[i] === listener) { - _changeListeners.splice(i, 1); - break; - } - } - - if (window.removeEventListener) { - window.removeEventListener('hashchange', onHashChange, false); - } else { - window.removeEvent('onhashchange', onHashChange); - } - - if (_changeListeners.length === 0) - _isListening = false; - }, - - - - push: function (path) { - _actionType = LocationActions.PUSH; - window.location.hash = Path.encode(path); - }, - - replace: function (path) { - _actionType = LocationActions.REPLACE; - window.location.replace(window.location.pathname + '#' + Path.encode(path)); - }, - - pop: function () { - _actionType = LocationActions.POP; - History.back(); - }, + if (allowTransition) + this.transitionTo(this.props.to, this.props.params, this.props.query); + }, - getCurrentPath: getHashPath, + /** + * Returns the value of the "href" attribute to use on the DOM element. + */ + getHref: function () { + return this.makeHref(this.props.to, this.props.params, this.props.query); + }, - toString: function () { - return ''; - } + /** + * Returns the value of the "class" attribute to use on the DOM element, which contains + * the value of the activeClassName property when this is active. + */ + getClassName: function () { + var classNames = {}; -}; + if (this.props.className) + classNames[this.props.className] = true; -module.exports = HashLocation; + if (this.isActive(this.props.to, this.props.params, this.props.query)) + classNames[this.props.activeClassName] = true; -},{"../actions/LocationActions":1,"../utils/History":22,"../utils/Path":23}],12:[function(_dereq_,module,exports){ -var LocationActions = _dereq_('../actions/LocationActions'); -var History = _dereq_('../utils/History'); -var Path = _dereq_('../utils/Path'); - -/** - * Returns the current URL path from `window.location`, including query string. - */ -function getWindowPath() { - return Path.decode( - window.location.pathname + window.location.search - ); -} - -var _changeListeners = []; - -function notifyChange(type) { - var change = { - path: getWindowPath(), - type: type - }; - - _changeListeners.forEach(function (listener) { - listener(change); - }); -} + return classSet(classNames); + }, -var _isListening = false; + render: function () { + var props = assign({}, this.props, { + href: this.getHref(), + className: this.getClassName(), + onClick: this.handleClick + }); -function onPopState() { - notifyChange(LocationActions.POP); -} + return React.DOM.a(props, this.props.children); + } -/** - * A Location that uses HTML5 history. - */ -var HistoryLocation = { + }); + + module.exports = Link; - addChangeListener: function (listener) { - _changeListeners.push(listener); - if (_isListening) - return; +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { - if (window.addEventListener) { - window.addEventListener('popstate', onPopState, false); - } else { - window.attachEvent('popstate', onPopState); - } + var React = __webpack_require__(17); + var FakeNode = __webpack_require__(18); + var PropTypes = __webpack_require__(19); + + /** + * A is a special kind of that + * renders when the beginning of its parent's path matches + * but none of its siblings do, including any . + * Only one such route may be used at any given level in the + * route hierarchy. + */ + var NotFoundRoute = React.createClass({ - _isListening = true; - }, + displayName: 'NotFoundRoute', - removeChangeListener: function(listener) { - for (var i = 0, l = _changeListeners.length; i < l; i ++) { - if (_changeListeners[i] === listener) { - _changeListeners.splice(i, 1); - break; - } - } + mixins: [ FakeNode ], - if (window.addEventListener) { - window.removeEventListener('popstate', onPopState); - } else { - window.removeEvent('popstate', onPopState); - } + propTypes: { + name: React.PropTypes.string, + path: PropTypes.falsy, + handler: React.PropTypes.func.isRequired + } - if (_changeListeners.length === 0) - _isListening = false; - }, + }); + module.exports = NotFoundRoute; - push: function (path) { - window.history.pushState({ path: path }, '', Path.encode(path)); - History.length += 1; - notifyChange(LocationActions.PUSH); - }, - - replace: function (path) { - window.history.replaceState({ path: path }, '', Path.encode(path)); - notifyChange(LocationActions.REPLACE); - }, - - pop: History.back, - - getCurrentPath: getWindowPath, - - toString: function () { - return ''; - } - -}; - -module.exports = HistoryLocation; - -},{"../actions/LocationActions":1,"../utils/History":22,"../utils/Path":23}],13:[function(_dereq_,module,exports){ -var HistoryLocation = _dereq_('./HistoryLocation'); -var History = _dereq_('../utils/History'); -var Path = _dereq_('../utils/Path'); - -/** - * 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.encode(path); - }, - - replace: function (path) { - window.location.replace(Path.encode(path)); - }, - - pop: History.back, - - getCurrentPath: HistoryLocation.getCurrentPath, - - toString: function () { - return ''; - } - -}; - -module.exports = RefreshLocation; - -},{"../utils/History":22,"../utils/Path":23,"./HistoryLocation":12}],14:[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":43}],15:[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 - }, - - /** - * 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); - }, - - /** - * 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); - }, - - /** - * 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; - -},{}],16:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); - -/** - * Provides the router with context for Router.Navigation. - */ -var 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; - -},{}],17:[function(_dereq_,module,exports){ -var React = (typeof window !== "undefined" ? window.React : typeof global !== "undefined" ? global.React : null); - -module.exports = { - contextTypes: { - getRouteAtDepth: React.PropTypes.func.isRequired, - getRouteComponents: React.PropTypes.func.isRequired, - routeHandlers: React.PropTypes.array.isRequired - }, - - childContextTypes: { - routeHandlers: React.PropTypes.array.isRequired - }, - - getChildContext: function () { - return { - routeHandlers: this.context.routeHandlers.concat([ this ]) - }; - }, - - getRouteDepth: function () { - return this.context.routeHandlers.length - 1; - }, - - componentDidMount: function () { - this._updateRouteComponent(); - }, - - componentDidUpdate: function () { - this._updateRouteComponent(); - }, - - _updateRouteComponent: function () { - var depth = this.getRouteDepth(); - var components = this.context.getRouteComponents(); - components[depth] = this.refs[this.props.ref || '__routeHandler__']; - }, - - getRouteHandler: function (props) { - var route = this.context.getRouteAtDepth(this.getRouteDepth()); - return route ? React.createElement(route.handler, props || this.props) : null; - } -}; -},{}],18:[function(_dereq_,module,exports){ -var invariant = _dereq_('react/lib/invariant'); -var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; -var getWindowScrollPosition = _dereq_('../utils/getWindowScrollPosition'); - -function shouldUpdateScroll(state, prevState) { - if (!prevState) - return true; - - // Don't update scroll position when only the query has changed. - if (state.pathname === prevState.pathname) - return false; - - var routes = state.routes; - var prevRoutes = prevState.routes; - - var sharedAncestorRoutes = routes.filter(function (route) { - return prevRoutes.indexOf(route) !== -1; - }); - - return !sharedAncestorRoutes.some(function (route) { - return route.ignoreScrollBehavior; - }); -} - -/** - * Provides the router with the ability to manage window scroll position - * according to its scroll behavior. - */ -var Scrolling = { - - statics: { - /** - * Records curent scroll position as the last known position for the given URL path. - */ - recordScrollPosition: function (path) { - if (!this.scrollHistory) - this.scrollHistory = {}; - - this.scrollHistory[path] = getWindowScrollPosition(); - }, - - /** - * Returns the last known scroll position for the given URL path. - */ - getScrollPosition: function (path) { - if (!this.scrollHistory) - this.scrollHistory = {}; - - return this.scrollHistory[path] || null; - } - }, - - componentWillMount: function () { - invariant( - this.getScrollBehavior() == null || canUseDOM, - 'Cannot use scroll behavior without a DOM' - ); - }, - - componentDidMount: function () { - this._updateScroll(); - }, - - componentDidUpdate: function (prevProps, prevState) { - this._updateScroll(prevState); - }, - - _updateScroll: function (prevState) { - if (!shouldUpdateScroll(this.state, prevState)) - return; - - var scrollBehavior = this.getScrollBehavior(); - - if (scrollBehavior) - scrollBehavior.updateScrollPosition( - this.constructor.getScrollPosition(this.state.path), - this.state.action - ); - } - -}; - -module.exports = Scrolling; - -},{"../utils/getWindowScrollPosition":30,"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43}],19:[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 path, routes, URL - * params and query that are currently active. - * - * Example: - * - * var AboutLink = React.createClass({ - * mixins: [ Router.State ], - * render: function () { - * var className = this.props.className; - * - * if (this.isActive('about')) - * className += ' is-active'; - * - * return React.DOM.a({ className: className }, this.props.children); - * } - * }); - */ -var State = { - - contextTypes: { - getCurrentPath: React.PropTypes.func.isRequired, - getCurrentRoutes: React.PropTypes.func.isRequired, - getCurrentPathname: 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. - */ - getRoutes: function () { - return this.context.getCurrentRoutes(); - }, - - /** - * Returns the current URL path without the query string. - */ - getPathname: function () { - return this.context.getCurrentPathname(); - }, - - /** - * Returns an object of the URL params that are currently active. - */ - getParams: function () { - return this.context.getCurrentParams(); - }, - - /** - * Returns an object of the query params that are currently active. - */ - getQuery: function () { - return this.context.getCurrentQuery(); - }, - - /** - * A helper method to determine if a given route, params, and query - * are active. - */ - isActive: function (to, params, query) { - return this.context.isActive(to, params, query); - } - -}; - -module.exports = State; - -},{}],20:[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'); - -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; - - return true; -} - -function queryIsActive(activeQuery, query) { - for (var property in query) - if (String(activeQuery[property]) !== String(query[property])) - return false; - - return true; -} - -/** - * Provides the router with context for Router.State. - */ -var StateContext = { - - /** - * Returns the current URL path + query string. - */ - getCurrentPath: function () { - return this.state.path; - }, - - /** - * Returns a read-only array of the currently active routes. - */ - getCurrentRoutes: function () { - return this.state.routes.slice(0); - }, - - /** - * Returns the current URL path without the query string. - */ - getCurrentPathname: function () { - return this.state.pathname; - }, - - /** - * Returns a read-only object of the currently active URL parameters. - */ - getCurrentParams: function () { - return assign({}, this.state.params); - }, - - /** - * Returns a read-only object of the currently active query parameters. - */ - getCurrentQuery: function () { - return assign({}, this.state.query); - }, - - /** - * Returns true if the given route, params, and query are active. - */ - isActive: function (to, params, query) { - if (Path.isAbsolute(to)) - return to === this.state.path; - - return routeIsActive(this.state.routes, to) && - paramsAreActive(this.state.params, params) && - (query == null || queryIsActive(this.state.query, query)); - }, - - childContextTypes: { - getCurrentPath: React.PropTypes.func.isRequired, - getCurrentRoutes: React.PropTypes.func.isRequired, - getCurrentPathname: 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, - getCurrentPathname: this.getCurrentPathname, - getCurrentParams: this.getCurrentParams, - getCurrentQuery: this.getCurrentQuery, - isActive: this.isActive - }; - } - -}; - -module.exports = StateContext; - -},{"../utils/Path":23,"react/lib/Object.assign":40}],21:[function(_dereq_,module,exports){ -/** - * Represents a cancellation caused by navigating away - * before the previous transition has fully resolved. - */ -function Cancellation() { } - -module.exports = Cancellation; - -},{}],22:[function(_dereq_,module,exports){ -var invariant = _dereq_('react/lib/invariant'); -var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; - -var History = { - - /** - * Sends the browser back one entry in the history. - */ - back: function () { - invariant( - canUseDOM, - 'Cannot use History.back without a DOM' - ); - - // Do this first so that History.length will - // be accurate in location change listeners. - History.length -= 1; - - window.history.back(); - }, - - /** - * The current number of entries in the history. - */ - length: 1 - -}; - -module.exports = History; - -},{"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43}],23:[function(_dereq_,module,exports){ -var invariant = _dereq_('react/lib/invariant'); -var merge = _dereq_('qs/lib/utils').merge; -var qs = _dereq_('qs'); - -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 = { - - /** - * Safely decodes special characters in the given URL path. - */ - decode: function (path) { - return decodeURI(path.replace(/\+/g, ' ')); - }, - - /** - * Safely encodes special characters in the given URL path. - */ - encode: function (path) { - return encodeURI(path).replace(/%20/g, '+'); - }, - - /** - * 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 = 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 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":34,"qs/lib/utils":38,"react/lib/invariant":43}],24:[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":45}],25:[function(_dereq_,module,exports){ -var PropTypes = { - - /** - * Requires that the value of a prop be falsy. - */ - falsy: function (props, propName, componentName) { - if (props[propName]) - return new Error('<' + componentName + '> may not have a "' + propName + '" prop'); - } - -}; - -module.exports = PropTypes; - -},{}],26:[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; - -},{}],27:[function(_dereq_,module,exports){ -var assign = _dereq_('react/lib/Object.assign'); -var reversedArray = _dereq_('./reversedArray'); -var Redirect = _dereq_('./Redirect'); -var Promise = _dereq_('./Promise'); - -/** - * 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) { - var promise; - try { - 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. - } - - if (promise) { - // Use setTimeout to break the promise chain. - promise.then(function () { - setTimeout(callback); - }, function (error) { - setTimeout(function () { - callback(error); - }); - }); - } else { - callback(); - } -} - -/** - * 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); - - 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; - transition._promise = null; - - return promise; - }; - }); - - runHooks(hooks, callback); -} - -/** - * 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. - */ -function runTransitionToHooks(transition, routes, params, query, callback) { - var hooks = routes.map(function (route) { - return function () { - var handler = route.handler; - - if (!transition.isAborted && handler.willTransitionTo) - handler.willTransitionTo(transition, params, query); - - var promise = transition._promise; - transition._promise = null; - - return promise; - }; - }); - - runHooks(hooks, callback); -} - -/** - * Encapsulates a transition to a given path. - * - * The willTransitionTo and willTransitionFrom handlers receive - * an instance of this class as their first argument. - */ -function Transition(path, retry) { - this.path = path; - this.abortReason = null; - this.isAborted = false; - this.retry = retry.bind(this); - this._promise = null; -} - -assign(Transition.prototype, { - - abort: function (reason) { - if (this.isAborted) { - // First abort wins. - return; - } - - this.abortReason = reason; - this.isAborted = true; - }, - - 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":24,"./Redirect":26,"./reversedArray":31,"react/lib/Object.assign":40}],28:[function(_dereq_,module,exports){ -/* jshint -W058 */ -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 LocationActions = _dereq_('../actions/LocationActions'); -var HashLocation = _dereq_('../locations/HashLocation'); -var HistoryLocation = _dereq_('../locations/HistoryLocation'); -var RefreshLocation = _dereq_('../locations/RefreshLocation'); -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 History = _dereq_('./History'); -var Cancellation = _dereq_('./Cancellation'); -var Path = _dereq_('./Path'); - -/** - * The default location for new routers. - */ -var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/'; - -/** - * The default scroll behavior for new routers. - */ -var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null; - -/** - * The default error handler for new routers. - */ -function defaultErrorHandler(error) { - // Throw so we don't silently swallow async errors. - throw error; // This error probably originated in a transition hook. -} - -/** - * The default aborted transition handler for new routers. - */ -function defaultAbortHandler(abortReason, location) { - if (typeof location === 'string') - throw new Error('Unhandled aborted transition! Reason: ' + abortReason); - - if (abortReason instanceof Cancellation) { - return; - } else if (abortReason instanceof Redirect) { - location.replace(this.makePath(abortReason.to, abortReason.params, abortReason.query)); - } else { - location.pop(); - } -} - -function findMatch(pathname, routes, defaultRoute, notFoundRoute) { - var match, route, params; - - for (var i = 0, len = routes.length; i < len; ++i) { - route = routes[i]; - - // Check the subtree first to find the most deeply-nested match. - match = findMatch(pathname, route.childRoutes, route.defaultRoute, route.notFoundRoute); - - if (match != null) { - match.routes.unshift(route); - return match; - } - - // No routes in the subtree matched, so check this route. - params = Path.extractParams(route.path, pathname); - - if (params) - return createMatch(route, params); - } - - // No routes matched, so try the default route if there is one. - if (defaultRoute && (params = Path.extractParams(defaultRoute.path, pathname))) - return createMatch(defaultRoute, params); - - // Last attempt: does the "not found" route match? - if (notFoundRoute && (params = Path.extractParams(notFoundRoute.path, pathname))) - return createMatch(notFoundRoute, params); - - return match; -} - -function createMatch(route, params) { - return { routes: [ route ], params: params }; -} - -function hasProperties(object, properties) { - for (var propertyName in properties) - if (properties.hasOwnProperty(propertyName) && object[propertyName] !== properties[propertyName]) - return false; - - return true; -} - -function hasMatch(routes, route, prevParams, nextParams, prevQuery, nextQuery) { - return routes.some(function (r) { - if (r !== route) - return false; - - var paramNames = route.paramNames; - var paramName; - - // Ensure that all params the route cares about did not change. - for (var i = 0, len = paramNames.length; i < len; ++i) { - paramName = paramNames[i]; - - if (nextParams[paramName] !== prevParams[paramName]) - return false; - } - - // Ensure the query hasn't changed. - return hasProperties(prevQuery, nextQuery) && hasProperties(nextQuery, prevQuery); - }); -} - -/** - * 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. - * - * Options may be any of the following: - * - * - 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 - * - * 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. - */ -function createRouter(options) { - options = options || {}; - - if (typeof options === 'function') { - options = { routes: options }; // Router.create() - } else if (Array.isArray(options)) { - options = { routes: options }; // Router.create([ , ]) - } - - 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 = {}; - var nextState = {}; - var pendingTransition = null; - - function updateState() { - state = nextState; - nextState = {}; - } - - 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' - ); - } else { - invariant( - canUseDOM, - 'You cannot use %s without a DOM', - location - ); - } - - // Automatically fall back to full page refreshes in - // browsers that don't support the HTML history API. - if (location === HistoryLocation && !supportsHistory()) - location = RefreshLocation; - - var router = React.createClass({ - - displayName: 'Router', - - mixins: [ NavigationContext, StateContext, Scrolling ], - - statics: { - - 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]; - - invariant( - route, - 'Unable to find ', - to - ); - - path = route.path; - } - - 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 path = this.makePath(to, params, query); - - if (pendingTransition) { - // Replace so pending location does not stay in history. - location.replace(path); - } else { - location.push(path); - } - }, - - /** - * 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' - ); - - location.replace(this.makePath(to, params, query)); - }, - - /** - * Transitions to the previous URL if one is available. Returns true if the - * router was able to go back, false otherwise. - * - * Note: The router only tracks history entries in your application, not the - * current browser session, so you can safely call this function without guarding - * against sending the user back to some other site. However, when using - * RefreshLocation (which is the fallback for HistoryLocation in browsers that - * don't support HTML5 history) this method will *always* send the client back - * because we cannot reliably track history length. - */ - goBack: function () { - invariant( - typeof location !== 'string', - 'You cannot use goBack with a static location' - ); - - if (History.length > 1 || location === RefreshLocation) { - location.pop(); - return true; - } - - warning(false, 'goBack() was ignored because there is no router history'); - - return false; - }, - - /** - * Performs a match of the given pathname against this router and returns an object - * with the { routes, params } that match. Returns null if no match can be made. - */ - match: function (pathname) { - return findMatch(pathname, 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 (pendingTransition) { - pendingTransition.abort(new Cancellation); - pendingTransition = null; - } - - var prevPath = state.path; - if (prevPath === path) - return; // Nothing to do! - - // Record the scroll position as early as possible to - // get it before browsers try update it automatically. - if (prevPath && action !== LocationActions.REPLACE) - this.recordScrollPosition(prevPath); - - var pathname = Path.withoutQuery(path); - var match = this.match(pathname); - - warning( - match != null, - 'No route matches path "%s". Make sure you have somewhere in your routes', - path, path - ); - - if (match == null) - match = {}; - - var prevRoutes = state.routes || []; - var prevParams = state.params || {}; - var prevQuery = state.query || {}; - - var nextRoutes = match.routes || []; - var nextParams = match.params || {}; - var nextQuery = Path.extractQuery(path) || {}; - - var fromRoutes, toRoutes; - if (prevRoutes.length) { - fromRoutes = prevRoutes.filter(function (route) { - return !hasMatch(nextRoutes, route, prevParams, nextParams, prevQuery, nextQuery); - }); - - toRoutes = nextRoutes.filter(function (route) { - return !hasMatch(prevRoutes, route, prevParams, nextParams, prevQuery, nextQuery); - }); - } else { - fromRoutes = []; - toRoutes = nextRoutes; - } - - var transition = new Transition(path, this.replaceWith.bind(this, path)); - pendingTransition = transition; - - transition.from(fromRoutes, components, function (error) { - if (error || transition.isAborted) - return callback.call(router, error, transition); - - transition.to(toRoutes, nextParams, nextQuery, function (error) { - if (error || transition.isAborted) - return callback.call(router, error, transition); - - nextState.path = path; - nextState.action = action; - nextState.pathname = pathname; - nextState.routes = nextRoutes; - nextState.params = nextParams; - nextState.query = nextQuery; - - 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) { - var dispatchHandler = function (error, transition) { - pendingTransition = null; - - if (error) { - onError.call(router, error); - } else if (transition.isAborted) { - onAbort.call(router, transition.abortReason, location); - } else { - callback.call(router, router, nextState); - } - }; - - if (typeof location === 'string') { - router.dispatch(location, null, dispatchHandler); - } else { - // Listen for changes to the location. - var changeListener = function (change) { - router.dispatch(change.path, change.type, dispatchHandler); - }; - - if (location.addChangeListener) - location.addChangeListener(changeListener); - - // Bootstrap using the current path. - router.dispatch(location.getCurrentPath(), null, dispatchHandler); - } - }, - - teardown: function() { - location.removeChangeListener(this.changeListener); - } - - }, - - 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 () { - updateState(); - return state; - }, - - componentWillReceiveProps: function () { - updateState(); - this.setState(state); - }, - - componentWillUnmount: function() { - router.teardown(); - }, - - 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 ] - }; - } - - }); - - if (options.routes) - router.addRoutes(options.routes); - - return router; -} - -module.exports = createRouter; - -},{"../actions/LocationActions":1,"../behaviors/ImitateBrowserBehavior":2,"../components/RouteHandler":9,"../locations/HashLocation":11,"../locations/HistoryLocation":12,"../locations/RefreshLocation":13,"../mixins/NavigationContext":16,"../mixins/Scrolling":18,"../mixins/StateContext":20,"./Cancellation":21,"./History":22,"./Path":23,"./PropTypes":25,"./Redirect":26,"./Transition":27,"./createRoutesFromChildren":29,"./supportsHistory":33,"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43,"react/lib/warning":44}],29:[function(_dereq_,module,exports){ -/* jshint -W084 */ -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 -]; - -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); - - if (error instanceof Error) - warning(false, error.message); - } - } -} - -function createRoute(element, parentRoute, namedRoutes) { - var type = element.type; - var props = element.props; - var componentName = (type && type.displayName) || 'UnknownComponent'; - - invariant( - CONFIG_ELEMENT_TYPES.indexOf(type) !== -1, - 'Unrecognized route configuration element "<%s>"', - componentName - ); - - if (type.propTypes) - checkPropTypes(componentName, type.propTypes, props); - - var route = { name: props.name }; - - if (props.ignoreScrollBehavior) { - route.ignoreScrollBehavior = true; - } - - 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 parentPath = (parentRoute && parentRoute.path) || '/'; - - if ((props.path || props.name) && type !== DefaultRoute.type && type !== NotFoundRoute.type) { - var path = props.path || props.name; - - // Relative paths extend their parent. - if (!Path.isAbsolute(path)) - path = Path.join(parentPath, path); - - route.path = Path.normalize(path); - } else { - route.path = parentPath; - - if (type === NotFoundRoute.type) - route.path += '*'; - } - - route.paramNames = Path.extractParamNames(route.path); - - // 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 - ); - }); - } - - // 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 - ); - - namedRoutes[props.name] = route; - } - - // Handle . - if (type === NotFoundRoute.type) { - invariant( - parentRoute, - ' must have a parent ' - ); - - invariant( - parentRoute.notFoundRoute == null, - 'You may not have more than one per ' - ); - - parentRoute.notFoundRoute = route; - - return null; - } - - // Handle . - if (type === DefaultRoute.type) { - invariant( - parentRoute, - ' must have a parent ' - ); - - invariant( - parentRoute.defaultRoute == null, - 'You may not have more than one per ' - ); - - parentRoute.defaultRoute = route; - - return null; - } - - route.childRoutes = createRoutesFromChildren(props.children, route, namedRoutes); - - return route; -} - -/** - * Creates and returns an array of route objects from the given ReactChildren. - */ -function createRoutesFromChildren(children, parentRoute, namedRoutes) { - var routes = []; - - React.Children.forEach(children, function (child) { - // Exclude s and s. - if (child = createRoute(child, parentRoute, namedRoutes)) - routes.push(child); - }); - - return routes; -} - -module.exports = createRoutesFromChildren; - -},{"../components/DefaultRoute":4,"../components/NotFoundRoute":6,"../components/Redirect":7,"../components/Route":8,"./Path":23,"react/lib/invariant":43,"react/lib/warning":44}],30:[function(_dereq_,module,exports){ -var invariant = _dereq_('react/lib/invariant'); -var canUseDOM = _dereq_('react/lib/ExecutionEnvironment').canUseDOM; - -/** - * Returns the current scroll position of the window as { x, y }. - */ -function getWindowScrollPosition() { - invariant( - canUseDOM, - 'Cannot get current scroll position without a DOM' - ); - - return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop - }; -} - -module.exports = getWindowScrollPosition; - -},{"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43}],31:[function(_dereq_,module,exports){ -function reversedArray(array) { - return array.slice(0).reverse(); -} - -module.exports = reversedArray; - -},{}],32:[function(_dereq_,module,exports){ -var createRouter = _dereq_('./createRouter'); - -/** - * A high-level convenience method that creates, configures, and - * runs a router in one shot. The method signature is: - * - * 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. - * - * 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; - } - - var router = createRouter({ - routes: routes, - location: location - }); - - router.run(callback); - - return router; -} - -module.exports = runRouter; - -},{"./createRouter":28}],33:[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 - * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 - */ - 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 && - ua.indexOf('Windows Phone') === -1) { - return false; - } - return (window.history && 'pushState' in window.history); -} - -module.exports = supportsHistory; - -},{}],34:[function(_dereq_,module,exports){ -module.exports = _dereq_('./lib'); - -},{"./lib":35}],35:[function(_dereq_,module,exports){ -// Load modules - -var Stringify = _dereq_('./stringify'); -var Parse = _dereq_('./parse'); - - -// Declare internals - -var internals = {}; - - -module.exports = { - stringify: Stringify, - parse: Parse -}; - -},{"./parse":36,"./stringify":37}],36:[function(_dereq_,module,exports){ -// Load modules - -var Utils = _dereq_('./utils'); - - -// Declare internals - -var internals = { - delimiter: '&', - depth: 5, - arrayLimit: 20, - parameterLimit: 1000 -}; - - -internals.parseValues = function (str, options) { - - var obj = {}; - var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); - - for (var i = 0, il = parts.length; i < il; ++i) { - var part = parts[i]; - var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { - if (pos === -1) { - obj[Utils.decode(part)] = ''; - } - else { - var key = Utils.decode(part.slice(0, pos)); - var val = Utils.decode(part.slice(pos + 1)); + var React = __webpack_require__(17); + var FakeNode = __webpack_require__(18); + var PropTypes = __webpack_require__(19); - if (!obj[key]) { - obj[key] = val; - } - else { - obj[key] = [].concat(obj[key]).concat(val); - } - } - } + /** + * A component is a special kind of that always + * redirects to another route when it matches. + */ + var Redirect = React.createClass({ - return obj; -}; + displayName: 'Redirect', + mixins: [ FakeNode ], -internals.parseObject = function (chain, val, options) { + propTypes: { + path: React.PropTypes.string, + from: React.PropTypes.string, // Alias for path. + to: React.PropTypes.string, + handler: PropTypes.falsy + } - if (!chain.length) { - return val; - } + }); - var root = chain.shift(); + module.exports = Redirect; - 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); - } - } +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { - return obj; -}; + var React = __webpack_require__(17); + var FakeNode = __webpack_require__(18); + /** + * components specify components that are rendered to the page when the + * URL matches a given pattern. + * + * Routes are arranged in a nested tree structure. When a new URL is requested, + * the tree is searched depth-first to find a route whose path matches the URL. + * When one is found, all routes in the tree that lead to it are considered + * "active" and their components are rendered into the DOM, nested in the same + * order as they are in the tree. + * + * 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. + * + * var routes = [ + * + * + * + * + * + * ]; + * + * Router.run(routes, function (Handler) { + * React.render(, document.body); + * }); + * + * Handlers for Route components that contain children can render their active + * child route using a element. + * + * var App = React.createClass({ + * render: function () { + * return ( + *
+ * + *
+ * ); + * } + * }); + */ + var Route = React.createClass({ -internals.parseKeys = function (key, val, options) { + displayName: 'Route', - if (!key) { - return; - } + mixins: [ FakeNode ], - // The regex chunks + propTypes: { + name: React.PropTypes.string, + path: React.PropTypes.string, + handler: React.PropTypes.func.isRequired, + ignoreScrollBehavior: React.PropTypes.bool + } - var parent = /^([^\[\]]*)/; - var child = /(\[[^\[\]]*\])/g; + }); - // Get the parent + module.exports = Route; - var segment = parent.exec(key); - // Don't allow them to overwrite object prototype properties +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { - if (Object.prototype.hasOwnProperty(segment[1])) { - return; - } + var React = __webpack_require__(17); + var RouteHandlerMixin = __webpack_require__(20); - // Stash the parent if it exists + /** + * A component renders the active child route handler + * when routes are nested. + */ + var RouteHandler = React.createClass({ - var keys = []; - if (segment[1]) { - keys.push(segment[1]); - } + displayName: 'RouteHandler', - // Loop through children appending to the array until we hit depth + mixins: [RouteHandlerMixin], - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { + getDefaultProps: function () { + return { + ref: '__routeHandler__' + }; + }, - ++i; - if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { - keys.push(segment[1]); - } - } + render: function () { + return this.getRouteHandler(); + } - // If there's a remainder, just add whatever is left + }); - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); - } + module.exports = RouteHandler; - return internals.parseObject(keys, val, options); -}; +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { -module.exports = function (str, options) { + var LocationActions = __webpack_require__(30); + var History = __webpack_require__(16); + var Path = __webpack_require__(21); - if (str === '' || - str === null || - typeof str === 'undefined') { + /** + * Returns the current URL path from the `hash` portion of the URL, including + * query string. + */ + function getHashPath() { + return Path.decode( + // We can't use window.location.hash here because it's not + // consistent across browsers - Firefox will pre-decode it! + window.location.href.split('#')[1] || '' + ); + } - return {}; - } + var _actionType; - 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 ensureSlash() { + var path = getHashPath(); - var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; - var obj = {}; + if (path.charAt(0) === '/') + return true; - // Iterate over the keys and setup the new object + HashLocation.replace('/' + path); - 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 false; + } - return Utils.compact(obj); -}; + var _changeListeners = []; -},{"./utils":38}],37:[function(_dereq_,module,exports){ -// Load modules + function notifyChange(type) { + if (type === LocationActions.PUSH) + History.length += 1; -var Utils = _dereq_('./utils'); + var change = { + path: getHashPath(), + type: type + }; + _changeListeners.forEach(function (listener) { + listener(change); + }); + } -// Declare internals + var _isListening = false; + + 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; + } + } -var internals = { - delimiter: '&' -}; + /** + * A Location that uses `window.location.hash`. + */ + var HashLocation = { + addChangeListener: function (listener) { + _changeListeners.push(listener); -internals.stringify = function (obj, prefix) { + // Do this BEFORE listening for hashchange. + ensureSlash(); - if (Utils.isBuffer(obj)) { - obj = obj.toString(); - } - else if (obj instanceof Date) { - obj = obj.toISOString(); - } - else if (obj === null) { - obj = ''; - } + if (_isListening) + return; - if (typeof obj === 'string' || - typeof obj === 'number' || - typeof obj === 'boolean') { + if (window.addEventListener) { + window.addEventListener('hashchange', onHashChange, false); + } else { + window.attachEvent('onhashchange', onHashChange); + } - return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; - } + _isListening = true; + }, - var values = []; + removeChangeListener: function(listener) { + for (var i = 0, l = _changeListeners.length; i < l; i ++) { + if (_changeListeners[i] === listener) { + _changeListeners.splice(i, 1); + break; + } + } - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']')); - } - } + if (window.removeEventListener) { + window.removeEventListener('hashchange', onHashChange, false); + } else { + window.removeEvent('onhashchange', onHashChange); + } - return values; -}; + if (_changeListeners.length === 0) + _isListening = false; + }, -module.exports = function (obj, options) { - options = options || {}; - var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; + push: function (path) { + _actionType = LocationActions.PUSH; + window.location.hash = Path.encode(path); + }, - var keys = []; + replace: function (path) { + _actionType = LocationActions.REPLACE; + window.location.replace(window.location.pathname + '#' + Path.encode(path)); + }, - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - keys = keys.concat(internals.stringify(obj[key], key)); - } - } + pop: function () { + _actionType = LocationActions.POP; + History.back(); + }, - return keys.join(delimiter); -}; + getCurrentPath: getHashPath, -},{"./utils":38}],38:[function(_dereq_,module,exports){ -// Load modules + toString: function () { + return ''; + } + }; -// Declare internals + module.exports = HashLocation; -var internals = {}; +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { -exports.arrayToObject = function (source) { + var LocationActions = __webpack_require__(30); + var History = __webpack_require__(16); + var Path = __webpack_require__(21); - var obj = {}; - for (var i = 0, il = source.length; i < il; ++i) { - if (typeof source[i] !== 'undefined') { + /** + * Returns the current URL path from `window.location`, including query string. + */ + function getWindowPath() { + return Path.decode( + window.location.pathname + window.location.search + ); + } - obj[i] = source[i]; - } - } + var _changeListeners = []; - return obj; -}; + function notifyChange(type) { + var change = { + path: getWindowPath(), + type: type + }; + _changeListeners.forEach(function (listener) { + listener(change); + }); + } -exports.merge = function (target, source) { + var _isListening = false; - if (!source) { - return target; - } + function onPopState() { + notifyChange(LocationActions.POP); + } - 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]; - } - } - } + /** + * A Location that uses HTML5 history. + */ + var HistoryLocation = { - return target; - } + addChangeListener: function (listener) { + _changeListeners.push(listener); - if (Array.isArray(target)) { - if (typeof source !== 'object') { - target.push(source); - return target; - } - else { - target = exports.arrayToObject(target); - } - } + if (_isListening) + return; - var keys = Object.keys(source); - for (var k = 0, kl = keys.length; k < kl; ++k) { - var key = keys[k]; - var value = source[key]; + if (window.addEventListener) { + window.addEventListener('popstate', onPopState, false); + } else { + window.attachEvent('popstate', onPopState); + } - if (value && - typeof value === 'object') { + _isListening = true; + }, - if (!target[key]) { - target[key] = value; - } - else { - target[key] = exports.merge(target[key], value); - } - } - else { - target[key] = value; - } - } + removeChangeListener: function(listener) { + for (var i = 0, l = _changeListeners.length; i < l; i ++) { + if (_changeListeners[i] === listener) { + _changeListeners.splice(i, 1); + break; + } + } - return target; -}; + if (window.addEventListener) { + window.removeEventListener('popstate', onPopState); + } else { + window.removeEvent('popstate', onPopState); + } + if (_changeListeners.length === 0) + _isListening = false; + }, -exports.decode = function (str) { - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (e) { - return str; - } -}; + push: function (path) { + window.history.pushState({ path: path }, '', Path.encode(path)); + History.length += 1; + notifyChange(LocationActions.PUSH); + }, -exports.compact = function (obj, refs) { + replace: function (path) { + window.history.replaceState({ path: path }, '', Path.encode(path)); + notifyChange(LocationActions.REPLACE); + }, - if (typeof obj !== 'object' || - obj === null) { + pop: History.back, - return obj; - } + getCurrentPath: getWindowPath, - refs = refs || []; - var lookup = refs.indexOf(obj); - if (lookup !== -1) { - return refs[lookup]; - } + toString: function () { + return ''; + } - refs.push(obj); + }; - if (Array.isArray(obj)) { - var compacted = []; + module.exports = HistoryLocation; - for (var i = 0, l = obj.length; i < l; ++i) { - if (typeof obj[i] !== 'undefined') { - compacted.push(obj[i]); - } - } - - return compacted; - } - - var keys = Object.keys(obj); - for (var i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - obj[key] = exports.compact(obj[key], refs); - } - - return obj; -}; - - -exports.isRegExp = function (obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; -}; - - -exports.isBuffer = function (obj) { - - if (typeof Buffer !== 'undefined') { - return Buffer.isBuffer(obj); - } - else { - return false; - } -}; - -},{}],39:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * 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; - -},{}],40:[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 - */ - -// 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; -}; - -module.exports = assign; - -},{}],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 cx - */ - -/** - * This function is used to mark string literals representing CSS class names - * so that they can be transformed statically. This allows for modularization - * and minification of CSS class names. - * - * In static_upstream, this function is actually implemented, but it should - * eventually be replaced with something more descriptive, and the transform - * that is used in the main stack should be ported for use elsewhere. - * - * @param string|object className to modularize, or an object of key/values. - * In the object case, the values are conditions that - * determine if the className keys should be included. - * @param [string ...] Variable list of classNames in the string case. - * @return string Renderable space-separated CSS className. - */ -function cx(classNames) { - if (typeof classNames == 'object') { - return Object.keys(classNames).filter(function(className) { - return classNames[className]; - }).join(' '); - } else { - return Array.prototype.join.call(arguments, ' '); - } -} - -module.exports = cx; - -},{}],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 emptyFunction - */ - -function makeEmptyFunction(arg) { - return function() { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -function emptyFunction() {} - -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function() { return this; }; -emptyFunction.thatReturnsArgument = function(arg) { return arg; }; - -module.exports = emptyFunction; - -},{}],43:[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 invariant - */ - -"use strict"; - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if ("production" !== "production") { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - 'Invariant Violation: ' + - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; - -},{}],44:[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 warning - */ - -"use strict"; - -var emptyFunction = _dereq_("./emptyFunction"); - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = emptyFunction; - -if ("production" !== "production") { - warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); - } - - if (!condition) { - var argIndex = 0; - console.warn('Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];})); - } - }; -} - -module.exports = warning; - -},{"./emptyFunction":42}],45:[function(_dereq_,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ - -(function(define) { 'use strict'; -define(function (_dereq_) { - - var makePromise = _dereq_('./makePromise'); - var Scheduler = _dereq_('./Scheduler'); - var async = _dereq_('./async'); - - return makePromise({ - scheduler: new Scheduler(async) - }); -}); -})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(_dereq_); }); +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { -},{"./Scheduler":47,"./async":48,"./makePromise":49}],46:[function(_dereq_,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ + var HistoryLocation = __webpack_require__(8); + var History = __webpack_require__(16); + var Path = __webpack_require__(21); -(function(define) { 'use strict'; -define(function() { /** - * Circular queue - * @param {number} capacityPow2 power of 2 to which this queue's capacity - * will be set initially. eg when capacityPow2 == 3, queue capacity - * will be 8. - * @constructor + * 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. */ - function Queue(capacityPow2) { - this.head = this.tail = this.length = 0; - this.buffer = new Array(1 << capacityPow2); - } + var RefreshLocation = { - Queue.prototype.push = function(x) { - if(this.length === this.buffer.length) { - this._ensureCapacity(this.length * 2); - } + push: function (path) { + window.location = Path.encode(path); + }, - this.buffer[this.tail] = x; - this.tail = (this.tail + 1) & (this.buffer.length - 1); - ++this.length; - return this.length; - }; + replace: function (path) { + window.location.replace(Path.encode(path)); + }, - Queue.prototype.shift = function() { - var x = this.buffer[this.head]; - this.buffer[this.head] = void 0; - this.head = (this.head + 1) & (this.buffer.length - 1); - --this.length; - return x; - }; + pop: History.back, - Queue.prototype._ensureCapacity = function(capacity) { - var head = this.head; - var buffer = this.buffer; - var newBuffer = new Array(capacity); - var i = 0; - var len; - - if(head === 0) { - len = this.length; - for(; i'; + } - this.buffer = newBuffer; - this.head = 0; - this.tail = this.length; }; - return Queue; + module.exports = RefreshLocation; + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { -}); -}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); + var LocationActions = __webpack_require__(30); -},{}],47:[function(_dereq_,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ + /** + * A scroll behavior that attempts to imitate the default behavior + * of modern browsers. + */ + var ImitateBrowserBehavior = { + + updateScrollPosition: function (position, actionType) { + switch (actionType) { + case LocationActions.PUSH: + case LocationActions.REPLACE: + window.scrollTo(0, 0); + break; + case LocationActions.POP: + if (position) { + window.scrollTo(position.x, position.y); + } else { + window.scrollTo(0, 0); + } + break; + } + } + + }; -(function(define) { 'use strict'; -define(function(_dereq_) { + module.exports = ImitateBrowserBehavior; - var Queue = _dereq_('./Queue'); - // Credit to Twisol (https://github.com/Twisol) for suggesting - // this type of extensible queue + trampoline approach for next-tick conflation. +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { /** - * Async task scheduler - * @param {function} async function to schedule a single async function - * @constructor + * A scroll behavior that always scrolls to the top of the page + * after a transition. */ - function Scheduler(async) { - this._async = async; - this._queue = new Queue(15); - this._afterQueue = new Queue(5); - this._running = false; - - var self = this; - this.drain = function() { - self._drain(); - }; - } + var ScrollToTopBehavior = { + + updateScrollPosition: function () { + window.scrollTo(0, 0); + } + + }; + + module.exports = ScrollToTopBehavior; + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__(17); /** - * Enqueue a task - * @param {{ run:function }} task + * 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! + * ); + * } + * }); */ - Scheduler.prototype.enqueue = function(task) { - this._add(this._queue, task); + 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 + }, + + /** + * 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); + }, + + /** + * 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); + }, + + /** + * 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; + + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__(17); + /** - * Enqueue a task to run after the main task queue - * @param {{ run:function }} task + * 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.State ], + * render: function () { + * var className = this.props.className; + * + * if (this.isActive('about')) + * className += ' is-active'; + * + * return React.DOM.a({ className: className }, this.props.children); + * } + * }); */ - Scheduler.prototype.afterQueue = function(task) { - this._add(this._afterQueue, task); + var State = { + + contextTypes: { + getCurrentPath: React.PropTypes.func.isRequired, + getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentPathname: 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. + */ + getRoutes: function () { + return this.context.getCurrentRoutes(); + }, + + /** + * Returns the current URL path without the query string. + */ + getPathname: function () { + return this.context.getCurrentPathname(); + }, + + /** + * Returns an object of the URL params that are currently active. + */ + getParams: function () { + return this.context.getCurrentParams(); + }, + + /** + * Returns an object of the query params that are currently active. + */ + getQuery: function () { + return this.context.getCurrentQuery(); + }, + + /** + * A helper method to determine if a given route, params, and query + * are active. + */ + isActive: function (to, params, query) { + return this.context.isActive(to, params, query); + } + }; + module.exports = State; + + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + /* jshint -W058 */ + var React = __webpack_require__(17); + var warning = __webpack_require__(36); + var invariant = __webpack_require__(37); + var canUseDOM = __webpack_require__(38).canUseDOM; + var ImitateBrowserBehavior = __webpack_require__(10); + var RouteHandler = __webpack_require__(6); + var LocationActions = __webpack_require__(30); + var HashLocation = __webpack_require__(7); + var HistoryLocation = __webpack_require__(8); + var RefreshLocation = __webpack_require__(9); + var NavigationContext = __webpack_require__(22); + var StateContext = __webpack_require__(23); + var Scrolling = __webpack_require__(24); + var createRoutesFromChildren = __webpack_require__(25); + var supportsHistory = __webpack_require__(26); + var Transition = __webpack_require__(27); + var PropTypes = __webpack_require__(19); + var Redirect = __webpack_require__(28); + var History = __webpack_require__(16); + var Cancellation = __webpack_require__(29); + var Path = __webpack_require__(21); + /** - * Drain the handler queue entirely, and then the after queue + * The default location for new routers. */ - Scheduler.prototype._drain = function() { - runQueue(this._queue); - this._running = false; - runQueue(this._afterQueue); - }; + var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/'; /** - * Add a task to the q, and schedule drain if not already scheduled - * @param {Queue} queue - * @param {{run:function}} task - * @private + * The default scroll behavior for new routers. */ - Scheduler.prototype._add = function(queue, task) { - queue.push(task); - if(!this._running) { - this._running = true; - this._async(this.drain); - } - }; + var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null; /** - * Run all the tasks in the q - * @param queue + * The default error handler for new routers. */ - function runQueue(queue) { - while(queue.length > 0) { - queue.shift().run(); - } + function defaultErrorHandler(error) { + // Throw so we don't silently swallow async errors. + throw error; // This error probably originated in a transition hook. } - return Scheduler; + /** + * The default aborted transition handler for new routers. + */ + function defaultAbortHandler(abortReason, location) { + if (typeof location === 'string') + throw new Error('Unhandled aborted transition! Reason: ' + abortReason); + + if (abortReason instanceof Cancellation) { + return; + } else if (abortReason instanceof Redirect) { + location.replace(this.makePath(abortReason.to, abortReason.params, abortReason.query)); + } else { + location.pop(); + } + } -}); -}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); + function findMatch(pathname, routes, defaultRoute, notFoundRoute) { + var match, route, params; -},{"./Queue":46}],48:[function(_dereq_,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ + for (var i = 0, len = routes.length; i < len; ++i) { + route = routes[i]; -(function(define) { 'use strict'; -define(function(_dereq_) { + // Check the subtree first to find the most deeply-nested match. + match = findMatch(pathname, route.childRoutes, route.defaultRoute, route.notFoundRoute); - // Sniff "best" async scheduling option - // Prefer process.nextTick or MutationObserver, then check for - // vertx and finally fall back to setTimeout + if (match != null) { + match.routes.unshift(route); + return match; + } - /*jshint maxcomplexity:6*/ - /*global process,document,setTimeout,MutationObserver,WebKitMutationObserver*/ - var nextTick, MutationObs; + // No routes in the subtree matched, so check this route. + params = Path.extractParams(route.path, pathname); - if (typeof process !== 'undefined' && process !== null && - typeof process.nextTick === 'function') { - nextTick = function(f) { - process.nextTick(f); - }; + if (params) + return createMatch(route, params); + } - } else if (MutationObs = - (typeof MutationObserver === 'function' && MutationObserver) || - (typeof WebKitMutationObserver === 'function' && WebKitMutationObserver)) { - nextTick = (function (document, MutationObserver) { - var scheduled; - var el = document.createElement('div'); - var o = new MutationObserver(run); - o.observe(el, { attributes: true }); - - function run() { - var f = scheduled; - scheduled = void 0; - f(); - } + // No routes matched, so try the default route if there is one. + if (defaultRoute && (params = Path.extractParams(defaultRoute.path, pathname))) + return createMatch(defaultRoute, params); - return function (f) { - scheduled = f; - el.setAttribute('class', 'x'); - }; - }(document, MutationObs)); - - } else { - nextTick = (function(cjsRequire) { - var vertx; - try { - // vert.x 1.x || 2.x - vertx = cjsRequire('vertx'); - } catch (ignore) {} - - if (vertx) { - if (typeof vertx.runOnLoop === 'function') { - return vertx.runOnLoop; - } - if (typeof vertx.runOnContext === 'function') { - return vertx.runOnContext; - } - } + // Last attempt: does the "not found" route match? + if (notFoundRoute && (params = Path.extractParams(notFoundRoute.path, pathname))) + return createMatch(notFoundRoute, params); - // capture setTimeout to avoid being caught by fake timers - // used in time based tests - var capturedSetTimeout = setTimeout; - return function (t) { - capturedSetTimeout(t, 0); - }; - }(_dereq_)); + return match; } - return nextTick; -}); -}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(_dereq_); })); + function createMatch(route, params) { + return { routes: [ route ], params: params }; + } -},{}],49:[function(_dereq_,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ + function hasProperties(object, properties) { + for (var propertyName in properties) + if (properties.hasOwnProperty(propertyName) && object[propertyName] !== properties[propertyName]) + return false; -(function(define) { 'use strict'; -define(function() { + return true; + } - return function makePromise(environment) { + function hasMatch(routes, route, prevParams, nextParams, prevQuery, nextQuery) { + return routes.some(function (r) { + if (r !== route) + return false; - var tasks = environment.scheduler; + var paramNames = route.paramNames; + var paramName; - var objectCreate = Object.create || - function(proto) { - function Child() {} - Child.prototype = proto; - return new Child(); - }; + // Ensure that all params the route cares about did not change. + for (var i = 0, len = paramNames.length; i < len; ++i) { + paramName = paramNames[i]; - /** - * Create a promise whose fate is determined by resolver - * @constructor - * @returns {Promise} promise - * @name Promise - */ - function Promise(resolver, handler) { - this._handler = resolver === Handler ? handler : init(resolver); - } + if (nextParams[paramName] !== prevParams[paramName]) + return false; + } - /** - * Run the supplied resolver - * @param resolver - * @returns {Pending} - */ - function init(resolver) { - var handler = new Pending(); + // Ensure the query hasn't changed. + return hasProperties(prevQuery, nextQuery) && hasProperties(nextQuery, prevQuery); + }); + } - try { - resolver(promiseResolve, promiseReject, promiseNotify); - } catch (e) { - promiseReject(e); - } + /** + * 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. + * + * Options may be any of the following: + * + * - 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 + * + * 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. + */ + function createRouter(options) { + options = options || {}; + + if (typeof options === 'function') { + options = { routes: options }; // Router.create() + } else if (Array.isArray(options)) { + options = { routes: options }; // Router.create([ , ]) + } + + 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 = {}; + var nextState = {}; + var pendingTransition = null; + + function updateState() { + state = nextState; + nextState = {}; + } + + 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' + ); + } else { + invariant( + canUseDOM, + 'You cannot use %s without a DOM', + location + ); + } + + // Automatically fall back to full page refreshes in + // browsers that don't support the HTML history API. + if (location === HistoryLocation && !supportsHistory()) + location = RefreshLocation; + + var router = React.createClass({ + + displayName: 'Router', + + mixins: [ NavigationContext, StateContext, Scrolling ], + + statics: { + + 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]; + + invariant( + route, + 'Unable to find ', + to + ); + + path = route.path; + } + + 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 path = this.makePath(to, params, query); + + if (pendingTransition) { + // Replace so pending location does not stay in history. + location.replace(path); + } else { + location.push(path); + } + }, + + /** + * 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' + ); + + location.replace(this.makePath(to, params, query)); + }, + + /** + * Transitions to the previous URL if one is available. Returns true if the + * router was able to go back, false otherwise. + * + * Note: The router only tracks history entries in your application, not the + * current browser session, so you can safely call this function without guarding + * against sending the user back to some other site. However, when using + * RefreshLocation (which is the fallback for HistoryLocation in browsers that + * don't support HTML5 history) this method will *always* send the client back + * because we cannot reliably track history length. + */ + goBack: function () { + invariant( + typeof location !== 'string', + 'You cannot use goBack with a static location' + ); + + if (History.length > 1 || location === RefreshLocation) { + location.pop(); + return true; + } + + warning(false, 'goBack() was ignored because there is no router history'); + + return false; + }, + + /** + * Performs a match of the given pathname against this router and returns an object + * with the { routes, params } that match. Returns null if no match can be made. + */ + match: function (pathname) { + return findMatch(pathname, 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 (pendingTransition) { + pendingTransition.abort(new Cancellation); + pendingTransition = null; + } + + var prevPath = state.path; + if (prevPath === path) + return; // Nothing to do! + + // Record the scroll position as early as possible to + // get it before browsers try update it automatically. + if (prevPath && action !== LocationActions.REPLACE) + this.recordScrollPosition(prevPath); + + var pathname = Path.withoutQuery(path); + var match = this.match(pathname); + + warning( + match != null, + 'No route matches path "%s". Make sure you have somewhere in your routes', + path, path + ); + + if (match == null) + match = {}; + + var prevRoutes = state.routes || []; + var prevParams = state.params || {}; + var prevQuery = state.query || {}; + + var nextRoutes = match.routes || []; + var nextParams = match.params || {}; + var nextQuery = Path.extractQuery(path) || {}; + + var fromRoutes, toRoutes; + if (prevRoutes.length) { + fromRoutes = prevRoutes.filter(function (route) { + return !hasMatch(nextRoutes, route, prevParams, nextParams, prevQuery, nextQuery); + }); + + toRoutes = nextRoutes.filter(function (route) { + return !hasMatch(prevRoutes, route, prevParams, nextParams, prevQuery, nextQuery); + }); + } else { + fromRoutes = []; + toRoutes = nextRoutes; + } + + var transition = new Transition(path, this.replaceWith.bind(this, path)); + pendingTransition = transition; + + transition.from(fromRoutes, components, function (error) { + if (error || transition.isAborted) + return callback.call(router, error, transition); + + transition.to(toRoutes, nextParams, nextQuery, function (error) { + if (error || transition.isAborted) + return callback.call(router, error, transition); + + nextState.path = path; + nextState.action = action; + nextState.pathname = pathname; + nextState.routes = nextRoutes; + nextState.params = nextParams; + nextState.query = nextQuery; + + 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) { + var dispatchHandler = function (error, transition) { + pendingTransition = null; + + if (error) { + onError.call(router, error); + } else if (transition.isAborted) { + onAbort.call(router, transition.abortReason, location); + } else { + callback.call(router, router, nextState); + } + }; + + if (typeof location === 'string') { + router.dispatch(location, null, dispatchHandler); + } else { + // Listen for changes to the location. + var changeListener = function (change) { + router.dispatch(change.path, change.type, dispatchHandler); + }; + + if (location.addChangeListener) + location.addChangeListener(changeListener); + + // Bootstrap using the current path. + router.dispatch(location.getCurrentPath(), null, dispatchHandler); + } + }, + + teardown: function() { + location.removeChangeListener(this.changeListener); + } + + }, + + 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 () { + updateState(); + return state; + }, + + componentWillReceiveProps: function () { + updateState(); + this.setState(state); + }, + + componentWillUnmount: function() { + router.teardown(); + }, + + 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 ] + }; + } + + }); + + if (options.routes) + router.addRoutes(options.routes); + + return router; + } - return handler; + module.exports = createRouter; - /** - * Transition from pre-resolution state to post-resolution state, notifying - * all listeners of the ultimate fulfillment or rejection - * @param {*} x resolution value - */ - function promiseResolve (x) { - handler.resolve(x); - } - /** - * Reject this promise with reason, which will be used verbatim - * @param {Error|*} reason rejection reason, strongly suggested - * to be an Error type - */ - function promiseReject (reason) { - handler.reject(reason); - } - /** - * Issue a progress event, notifying all progress listeners - * @param {*} x progress event payload to pass to all listeners - */ - function promiseNotify (x) { - handler.notify(x); - } - } +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { - // Creation + var createRouter = __webpack_require__(14); - Promise.resolve = resolve; - Promise.reject = reject; - Promise.never = never; + /** + * A high-level convenience method that creates, configures, and + * runs a router in one shot. The method signature is: + * + * 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. + * + * 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; + } - Promise._defer = defer; - Promise._handler = getHandler; + var router = createRouter({ + routes: routes, + location: location + }); - /** - * Returns a trusted promise. If x is already a trusted promise, it is - * returned, otherwise returns a new trusted Promise which follows x. - * @param {*} x - * @return {Promise} promise - */ - function resolve(x) { - return isPromise(x) ? x - : new Promise(Handler, new Async(getHandler(x))); - } + router.run(callback); - /** - * Return a reject promise with x as its reason (x is used verbatim) - * @param {*} x - * @returns {Promise} rejected promise - */ - function reject(x) { - return new Promise(Handler, new Async(new Rejected(x))); - } + return router; + } - /** - * Return a promise that remains pending forever - * @returns {Promise} forever-pending promise. - */ - function never() { - return foreverPendingPromise; // Should be frozen - } + module.exports = runRouter; - /** - * Creates an internal {promise, resolver} pair - * @private - * @returns {Promise} - */ - function defer() { - return new Promise(Handler, new Pending()); - } - // Transformation and flow control +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { - /** - * Transform this promise's fulfillment value, returning a new Promise - * for the transformed result. If the promise cannot be fulfilled, onRejected - * is called with the reason. onProgress *may* be called with updates toward - * this promise's fulfillment. - * @param {function=} onFulfilled fulfillment handler - * @param {function=} onRejected rejection handler - * @deprecated @param {function=} onProgress progress handler - * @return {Promise} new promise - */ - Promise.prototype.then = function(onFulfilled, onRejected) { - var parent = this._handler; - var state = parent.join().state(); - - if ((typeof onFulfilled !== 'function' && state > 0) || - (typeof onRejected !== 'function' && state < 0)) { - // Short circuit: value will not change, simply share handler - return new this.constructor(Handler, parent); - } + var invariant = __webpack_require__(37); + var canUseDOM = __webpack_require__(38).canUseDOM; - var p = this._beget(); - var child = p._handler; + var History = { - parent.chain(child, parent.receiver, onFulfilled, onRejected, - arguments.length > 2 ? arguments[2] : void 0); + /** + * Sends the browser back one entry in the history. + */ + back: function () { + invariant( + canUseDOM, + 'Cannot use History.back without a DOM' + ); - return p; - }; + // Do this first so that History.length will + // be accurate in location change listeners. + History.length -= 1; - /** - * If this promise cannot be fulfilled due to an error, call onRejected to - * handle the error. Shortcut for .then(undefined, onRejected) - * @param {function?} onRejected - * @return {Promise} - */ - Promise.prototype['catch'] = function(onRejected) { - return this.then(void 0, onRejected); - }; + window.history.back(); + }, - /** - * Creates a new, pending promise of the same type as this promise - * @private - * @returns {Promise} - */ - Promise.prototype._beget = function() { - var parent = this._handler; - var child = new Pending(parent.receiver, parent.join().context); - return new this.constructor(Handler, child); - }; + /** + * The current number of entries in the history. + */ + length: 1 - // Array combinators + }; - Promise.all = all; - Promise.race = race; + module.exports = History; - /** - * Return a promise that will fulfill when all promises in the - * input array have fulfilled, or will reject when one of the - * promises rejects. - * @param {array} promises array of promises - * @returns {Promise} promise for array of fulfillment values - */ - function all(promises) { - /*jshint maxcomplexity:8*/ - var resolver = new Pending(); - var pending = promises.length >>> 0; - var results = new Array(pending); - - var i, h, x, s; - for (i = 0; i < promises.length; ++i) { - x = promises[i]; - - if (x === void 0 && !(i in promises)) { - --pending; - continue; - } - if (maybeThenable(x)) { - h = getHandlerMaybeThenable(x); +/***/ }, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { - s = h.state(); - if (s === 0) { - h.fold(settleAt, i, results, resolver); - } else if (s > 0) { - results[i] = h.value; - --pending; - } else { - unreportRemaining(promises, i+1, h); - resolver.become(h); - break; - } + module.exports = React; - } else { - results[i] = x; - --pending; - } - } +/***/ }, +/* 18 */ +/***/ function(module, exports, __webpack_require__) { - if(pending === 0) { - resolver.become(new Fulfilled(results)); - } + var invariant = __webpack_require__(37); - return new Promise(Handler, resolver); + var FakeNode = { - function settleAt(i, x, resolver) { - /*jshint validthis:true*/ - this[i] = x; - if(--pending === 0) { - resolver.become(new Fulfilled(this)); - } - } - } + render: function () { + invariant( + false, + '%s elements should not be rendered', + this.constructor.displayName + ); + } - function unreportRemaining(promises, start, rejectedHandler) { - var i, h, x; - for(i=start; i may not have a "' + propName + '" prop'); + } - /** - * Get a handler for thenable x. - * NOTE: You must only call this if maybeThenable(x) == true - * @param {object|function|Promise} x - * @returns {object} handler - */ - function getHandlerMaybeThenable(x) { - return isPromise(x) ? x._handler.join() : getHandlerUntrusted(x); - } + }; - /** - * Get a handler for potentially untrusted thenable x - * @param {*} x - * @returns {object} handler - */ - function getHandlerUntrusted(x) { - try { - var untrustedThen = x.then; - return typeof untrustedThen === 'function' - ? new Thenable(untrustedThen, x) - : new Fulfilled(x); - } catch(e) { - return new Rejected(e); - } - } + module.exports = PropTypes; - /** - * Handler for a promise that is pending forever - * @constructor - */ - function Handler() {} - Handler.prototype.when - = Handler.prototype.become - = Handler.prototype.notify - = Handler.prototype.fail - = Handler.prototype._unreport - = Handler.prototype._report - = noop; +/***/ }, +/* 20 */ +/***/ function(module, exports, __webpack_require__) { - Handler.prototype._state = 0; + var React = __webpack_require__(17); - Handler.prototype.state = function() { - return this._state; - }; + module.exports = { + contextTypes: { + getRouteAtDepth: React.PropTypes.func.isRequired, + getRouteComponents: React.PropTypes.func.isRequired, + routeHandlers: React.PropTypes.array.isRequired + }, - /** - * Recursively collapse handler chain to find the handler - * nearest to the fully resolved value. - * @returns {object} handler nearest the fully resolved value - */ - Handler.prototype.join = function() { - var h = this; - while(h.handler !== void 0) { - h = h.handler; - } - return h; - }; + childContextTypes: { + routeHandlers: React.PropTypes.array.isRequired + }, - Handler.prototype.chain = function(to, receiver, fulfilled, rejected, progress) { - this.when({ - resolver: to, - receiver: receiver, - fulfilled: fulfilled, - rejected: rejected, - progress: progress - }); - }; + getChildContext: function () { + return { + routeHandlers: this.context.routeHandlers.concat([ this ]) + }; + }, - Handler.prototype.visit = function(receiver, fulfilled, rejected, progress) { - this.chain(failIfRejected, receiver, fulfilled, rejected, progress); - }; + getRouteDepth: function () { + return this.context.routeHandlers.length - 1; + }, - Handler.prototype.fold = function(f, z, c, to) { - this.visit(to, function(x) { - f.call(c, z, x, this); - }, to.reject, to.notify); - }; + componentDidMount: function () { + this._updateRouteComponent(); + }, - /** - * Handler that invokes fail() on any handler it becomes - * @constructor - */ - function FailIfRejected() {} + componentDidUpdate: function () { + this._updateRouteComponent(); + }, - inherit(Handler, FailIfRejected); + _updateRouteComponent: function () { + var depth = this.getRouteDepth(); + var components = this.context.getRouteComponents(); + components[depth] = this.refs[this.props.ref || '__routeHandler__']; + }, - FailIfRejected.prototype.become = function(h) { - h.fail(); - }; + getRouteHandler: function (props) { + var route = this.context.getRouteAtDepth(this.getRouteDepth()); + return route ? React.createElement(route.handler, props || this.props) : null; + } + }; - var failIfRejected = new FailIfRejected(); +/***/ }, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { + + var invariant = __webpack_require__(37); + var merge = __webpack_require__(40).merge; + var qs = __webpack_require__(39); + + 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]; + } - /** - * Handler that manages a queue of consumers waiting on a pending promise - * @constructor - */ - function Pending(receiver, inheritedContext) { - Promise.createContext(this, inheritedContext); + var Path = { + + /** + * Safely decodes special characters in the given URL path. + */ + decode: function (path) { + return decodeURI(path.replace(/\+/g, ' ')); + }, + + /** + * Safely encodes special characters in the given URL path. + */ + encode: function (path) { + return encodeURI(path).replace(/%20/g, '+'); + }, + + /** + * 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 = 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 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; + } - this.consumers = void 0; - this.receiver = receiver; - this.handler = void 0; - this.resolved = false; - } + }; - inherit(Handler, Pending); + module.exports = Path; - Pending.prototype._state = 0; - Pending.prototype.resolve = function(x) { - this.become(getHandler(x)); - }; +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { - Pending.prototype.reject = function(x) { - if(this.resolved) { - return; - } + var React = __webpack_require__(17); - this.become(new Rejected(x)); - }; + /** + * Provides the router with context for Router.Navigation. + */ + var 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 + }; + } - Pending.prototype.join = function() { - if (!this.resolved) { - return this; - } + }; - var h = this; + module.exports = NavigationContext; - while (h.handler !== void 0) { - h = h.handler; - if (h === this) { - return this.handler = cycle(); - } - } - return h; - }; +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { - Pending.prototype.run = function() { - var q = this.consumers; - var handler = this.join(); - this.consumers = void 0; + var React = __webpack_require__(17); + var assign = __webpack_require__(35); + var Path = __webpack_require__(21); - for (var i = 0; i < q.length; ++i) { - handler.when(q[i]); - } - }; + function routeIsActive(activeRoutes, routeName) { + return activeRoutes.some(function (route) { + return route.name === routeName; + }); + } - Pending.prototype.become = function(handler) { - if(this.resolved) { - return; - } + function paramsAreActive(activeParams, params) { + for (var property in params) + if (String(activeParams[property]) !== String(params[property])) + return false; - this.resolved = true; - this.handler = handler; - if(this.consumers !== void 0) { - tasks.enqueue(this); - } + return true; + } - if(this.context !== void 0) { - handler._report(this.context); - } - }; + function queryIsActive(activeQuery, query) { + for (var property in query) + if (String(activeQuery[property]) !== String(query[property])) + return false; - Pending.prototype.when = function(continuation) { - if(this.resolved) { - tasks.enqueue(new ContinuationTask(continuation, this.handler)); - } else { - if(this.consumers === void 0) { - this.consumers = [continuation]; - } else { - this.consumers.push(continuation); - } - } - }; + return true; + } - Pending.prototype.notify = function(x) { - if(!this.resolved) { - tasks.enqueue(new ProgressTask(x, this)); - } - }; + /** + * Provides the router with context for Router.State. + */ + var StateContext = { + + /** + * Returns the current URL path + query string. + */ + getCurrentPath: function () { + return this.state.path; + }, + + /** + * Returns a read-only array of the currently active routes. + */ + getCurrentRoutes: function () { + return this.state.routes.slice(0); + }, + + /** + * Returns the current URL path without the query string. + */ + getCurrentPathname: function () { + return this.state.pathname; + }, + + /** + * Returns a read-only object of the currently active URL parameters. + */ + getCurrentParams: function () { + return assign({}, this.state.params); + }, + + /** + * Returns a read-only object of the currently active query parameters. + */ + getCurrentQuery: function () { + return assign({}, this.state.query); + }, + + /** + * Returns true if the given route, params, and query are active. + */ + isActive: function (to, params, query) { + if (Path.isAbsolute(to)) + return to === this.state.path; + + return routeIsActive(this.state.routes, to) && + paramsAreActive(this.state.params, params) && + (query == null || queryIsActive(this.state.query, query)); + }, + + childContextTypes: { + getCurrentPath: React.PropTypes.func.isRequired, + getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentPathname: 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, + getCurrentPathname: this.getCurrentPathname, + getCurrentParams: this.getCurrentParams, + getCurrentQuery: this.getCurrentQuery, + isActive: this.isActive + }; + } - Pending.prototype.fail = function(context) { - var c = typeof context === 'undefined' ? this.context : context; - this.resolved && this.handler.join().fail(c); - }; + }; - Pending.prototype._report = function(context) { - this.resolved && this.handler.join()._report(context); - }; + module.exports = StateContext; - Pending.prototype._unreport = function() { - this.resolved && this.handler.join()._unreport(); - }; - /** - * Wrap another handler and force it into a future stack - * @param {object} handler - * @constructor - */ - function Async(handler) { - this.handler = handler; - } +/***/ }, +/* 24 */ +/***/ function(module, exports, __webpack_require__) { - inherit(Handler, Async); + var invariant = __webpack_require__(37); + var canUseDOM = __webpack_require__(38).canUseDOM; + var getWindowScrollPosition = __webpack_require__(31); - Async.prototype.when = function(continuation) { - tasks.enqueue(new ContinuationTask(continuation, this)); - }; + function shouldUpdateScroll(state, prevState) { + if (!prevState) + return true; - Async.prototype._report = function(context) { - this.join()._report(context); - }; + // Don't update scroll position when only the query has changed. + if (state.pathname === prevState.pathname) + return false; - Async.prototype._unreport = function() { - this.join()._unreport(); - }; + var routes = state.routes; + var prevRoutes = prevState.routes; - /** - * Handler that wraps an untrusted thenable and assimilates it in a future stack - * @param {function} then - * @param {{then: function}} thenable - * @constructor - */ - function Thenable(then, thenable) { - Pending.call(this); - tasks.enqueue(new AssimilateTask(then, thenable, this)); - } + var sharedAncestorRoutes = routes.filter(function (route) { + return prevRoutes.indexOf(route) !== -1; + }); - inherit(Pending, Thenable); + return !sharedAncestorRoutes.some(function (route) { + return route.ignoreScrollBehavior; + }); + } - /** - * Handler for a fulfilled promise - * @param {*} x fulfillment value - * @constructor - */ - function Fulfilled(x) { - Promise.createContext(this); - this.value = x; - } + /** + * Provides the router with the ability to manage window scroll position + * according to its scroll behavior. + */ + var Scrolling = { + + statics: { + /** + * Records curent scroll position as the last known position for the given URL path. + */ + recordScrollPosition: function (path) { + if (!this.scrollHistory) + this.scrollHistory = {}; + + this.scrollHistory[path] = getWindowScrollPosition(); + }, + + /** + * Returns the last known scroll position for the given URL path. + */ + getScrollPosition: function (path) { + if (!this.scrollHistory) + this.scrollHistory = {}; + + return this.scrollHistory[path] || null; + } + }, + + componentWillMount: function () { + invariant( + this.getScrollBehavior() == null || canUseDOM, + 'Cannot use scroll behavior without a DOM' + ); + }, + + componentDidMount: function () { + this._updateScroll(); + }, + + componentDidUpdate: function (prevProps, prevState) { + this._updateScroll(prevState); + }, + + _updateScroll: function (prevState) { + if (!shouldUpdateScroll(this.state, prevState)) + return; + + var scrollBehavior = this.getScrollBehavior(); + + if (scrollBehavior) + scrollBehavior.updateScrollPosition( + this.constructor.getScrollPosition(this.state.path), + this.state.action + ); + } + + }; + + module.exports = Scrolling; + + +/***/ }, +/* 25 */ +/***/ function(module, exports, __webpack_require__) { + + /* jshint -W084 */ + var React = __webpack_require__(17); + var warning = __webpack_require__(36); + var invariant = __webpack_require__(37); + var DefaultRoute = __webpack_require__(1); + var NotFoundRoute = __webpack_require__(3); + var Redirect = __webpack_require__(4); + var Route = __webpack_require__(5); + var Path = __webpack_require__(21); + + var CONFIG_ELEMENT_TYPES = [ + DefaultRoute.type, + NotFoundRoute.type, + Redirect.type, + Route.type + ]; + + 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); + + if (error instanceof Error) + warning(false, error.message); + } + } + } + + function createRoute(element, parentRoute, namedRoutes) { + var type = element.type; + var props = element.props; + var componentName = (type && type.displayName) || 'UnknownComponent'; + + invariant( + CONFIG_ELEMENT_TYPES.indexOf(type) !== -1, + 'Unrecognized route configuration element "<%s>"', + componentName + ); + + if (type.propTypes) + checkPropTypes(componentName, type.propTypes, props); + + var route = { name: props.name }; + + if (props.ignoreScrollBehavior) { + route.ignoreScrollBehavior = true; + } + + 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 parentPath = (parentRoute && parentRoute.path) || '/'; + + if ((props.path || props.name) && type !== DefaultRoute.type && type !== NotFoundRoute.type) { + var path = props.path || props.name; + + // Relative paths extend their parent. + if (!Path.isAbsolute(path)) + path = Path.join(parentPath, path); + + route.path = Path.normalize(path); + } else { + route.path = parentPath; + + if (type === NotFoundRoute.type) + route.path += '*'; + } + + route.paramNames = Path.extractParamNames(route.path); + + // 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 + ); + }); + } + + // 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 + ); + + namedRoutes[props.name] = route; + } + + // Handle . + if (type === NotFoundRoute.type) { + invariant( + parentRoute, + ' must have a parent ' + ); + + invariant( + parentRoute.notFoundRoute == null, + 'You may not have more than one per ' + ); + + parentRoute.notFoundRoute = route; + + return null; + } + + // Handle . + if (type === DefaultRoute.type) { + invariant( + parentRoute, + ' must have a parent ' + ); + + invariant( + parentRoute.defaultRoute == null, + 'You may not have more than one per ' + ); + + parentRoute.defaultRoute = route; + + return null; + } + + route.childRoutes = createRoutesFromChildren(props.children, route, namedRoutes); + + return route; + } + + /** + * Creates and returns an array of route objects from the given ReactChildren. + */ + function createRoutesFromChildren(children, parentRoute, namedRoutes) { + var routes = []; + + React.Children.forEach(children, function (child) { + // Exclude s and s. + if (child = createRoute(child, parentRoute, namedRoutes)) + routes.push(child); + }); + + return routes; + } + + module.exports = createRoutesFromChildren; + + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + function supportsHistory() { + /*! taken from modernizr + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js + * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 + */ + 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 && + ua.indexOf('Windows Phone') === -1) { + return false; + } + return (window.history && 'pushState' in window.history); + } + + module.exports = supportsHistory; + + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + var assign = __webpack_require__(35); + var reversedArray = __webpack_require__(32); + var Redirect = __webpack_require__(28); + var Promise = __webpack_require__(33); + + /** + * 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) { + var promise; + try { + 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. + } + + if (promise) { + // Use setTimeout to break the promise chain. + promise.then(function () { + setTimeout(callback); + }, function (error) { + setTimeout(function () { + callback(error); + }); + }); + } else { + callback(); + } + } + + /** + * 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); + + 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; + transition._promise = null; + + return promise; + }; + }); + + runHooks(hooks, callback); + } + + /** + * 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. + */ + function runTransitionToHooks(transition, routes, params, query, callback) { + var hooks = routes.map(function (route) { + return function () { + var handler = route.handler; + + if (!transition.isAborted && handler.willTransitionTo) + handler.willTransitionTo(transition, params, query); + + var promise = transition._promise; + transition._promise = null; + + return promise; + }; + }); + + runHooks(hooks, callback); + } + + /** + * Encapsulates a transition to a given path. + * + * The willTransitionTo and willTransitionFrom handlers receive + * an instance of this class as their first argument. + */ + function Transition(path, retry) { + this.path = path; + this.abortReason = null; + this.isAborted = false; + this.retry = retry.bind(this); + this._promise = null; + } + + assign(Transition.prototype, { + + abort: function (reason) { + if (this.isAborted) { + // First abort wins. + return; + } + + this.abortReason = reason; + this.isAborted = true; + }, + + 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; + + +/***/ }, +/* 28 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Encapsulates a redirect to the given route. + */ + function Redirect(to, params, query) { + this.to = to; + this.params = params; + this.query = query; + } + + module.exports = Redirect; + + +/***/ }, +/* 29 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Represents a cancellation caused by navigating away + * before the previous transition has fully resolved. + */ + function Cancellation() { } + + module.exports = Cancellation; + + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Actions that modify the URL. + */ + var LocationActions = { + + /** + * Indicates a new location is being pushed to the history stack. + */ + PUSH: 'push', + + /** + * Indicates the current location should be replaced. + */ + REPLACE: 'replace', + + /** + * Indicates the most recent entry should be removed from the history stack. + */ + POP: 'pop' + + }; + + module.exports = LocationActions; + + +/***/ }, +/* 31 */ +/***/ function(module, exports, __webpack_require__) { + + var invariant = __webpack_require__(37); + var canUseDOM = __webpack_require__(38).canUseDOM; + + /** + * Returns the current scroll position of the window as { x, y }. + */ + function getWindowScrollPosition() { + invariant( + canUseDOM, + 'Cannot get current scroll position without a DOM' + ); + + return { + x: window.pageXOffset || document.documentElement.scrollLeft, + y: window.pageYOffset || document.documentElement.scrollTop + }; + } + + module.exports = getWindowScrollPosition; + + +/***/ }, +/* 32 */ +/***/ function(module, exports, __webpack_require__) { + + function reversedArray(array) { + return array.slice(0).reverse(); + } + + module.exports = reversedArray; + + +/***/ }, +/* 33 */ +/***/ function(module, exports, __webpack_require__) { + + var Promise = __webpack_require__(43); + + // TODO: Use process.env.NODE_ENV check + envify to enable + // when's promise monitor here when in dev. + + module.exports = Promise; + + +/***/ }, +/* 34 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 cx + */ + + /** + * This function is used to mark string literals representing CSS class names + * so that they can be transformed statically. This allows for modularization + * and minification of CSS class names. + * + * In static_upstream, this function is actually implemented, but it should + * eventually be replaced with something more descriptive, and the transform + * that is used in the main stack should be ported for use elsewhere. + * + * @param string|object className to modularize, or an object of key/values. + * In the object case, the values are conditions that + * determine if the className keys should be included. + * @param [string ...] Variable list of classNames in the string case. + * @return string Renderable space-separated CSS className. + */ + function cx(classNames) { + if (typeof classNames == 'object') { + return Object.keys(classNames).filter(function(className) { + return classNames[className]; + }).join(' '); + } else { + return Array.prototype.join.call(arguments, ' '); + } + } + + module.exports = cx; + + +/***/ }, +/* 35 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 + */ + + // 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; + }; + + module.exports = assign; + + +/***/ }, +/* 36 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 warning + */ + + "use strict"; + + var emptyFunction = __webpack_require__(41); + + /** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + + var warning = emptyFunction; + + if (false) { + warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + if (format === undefined) { + throw new Error( + '`warning(condition, format, ...args)` requires a warning ' + + 'message argument' + ); + } + + if (!condition) { + var argIndex = 0; + console.warn('Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];})); + } + }; + } + + module.exports = warning; + + +/***/ }, +/* 37 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 invariant + */ + + "use strict"; + + /** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + + var invariant = function(condition, format, a, b, c, d, e, f) { + if (false) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + 'Invariant Violation: ' + + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } + }; + + module.exports = invariant; + + +/***/ }, +/* 38 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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; + + +/***/ }, +/* 39 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__(42); + + +/***/ }, +/* 40 */ +/***/ function(module, exports, __webpack_require__) { + + // 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; + } + }; + + +/***/ }, +/* 41 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 emptyFunction + */ + + function makeEmptyFunction(arg) { + return function() { + return arg; + }; + } + + /** + * This function accepts and discards inputs; it has no side effects. This is + * primarily useful idiomatically for overridable function endpoints which + * always need to be callable, since JS lacks a null-call idiom ala Cocoa. + */ + function emptyFunction() {} + + emptyFunction.thatReturns = makeEmptyFunction; + emptyFunction.thatReturnsFalse = makeEmptyFunction(false); + emptyFunction.thatReturnsTrue = makeEmptyFunction(true); + emptyFunction.thatReturnsNull = makeEmptyFunction(null); + emptyFunction.thatReturnsThis = function() { return this; }; + emptyFunction.thatReturnsArgument = function(arg) { return arg; }; + + module.exports = emptyFunction; + + +/***/ }, +/* 42 */ +/***/ function(module, exports, __webpack_require__) { + + // Load modules + + var Stringify = __webpack_require__(44); + var Parse = __webpack_require__(45); + + + // Declare internals + + var internals = {}; + + + module.exports = { + stringify: Stringify, + parse: Parse + }; + + +/***/ }, +/* 43 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/** @license MIT License (c) copyright 2010-2014 original author or authors */ + /** @author Brian Cavalier */ + /** @author John Hann */ + + (function(define) { 'use strict'; + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + + var makePromise = __webpack_require__(46); + var Scheduler = __webpack_require__(47); + var async = __webpack_require__(48); + + return makePromise({ + scheduler: new Scheduler(async) + }); + + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + })(__webpack_require__(50)); + + +/***/ }, +/* 44 */ +/***/ function(module, exports, __webpack_require__) { + + // Load modules + + var Utils = __webpack_require__(40); + + + // 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); + }; + + +/***/ }, +/* 45 */ +/***/ function(module, exports, __webpack_require__) { + + // Load modules + + var Utils = __webpack_require__(40); + + + // 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); + }; + + +/***/ }, +/* 46 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/** @license MIT License (c) copyright 2010-2014 original author or authors */ + /** @author Brian Cavalier */ + /** @author John Hann */ + + (function(define) { 'use strict'; + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { + + return function makePromise(environment) { + + var tasks = environment.scheduler; + + var objectCreate = Object.create || + function(proto) { + function Child() {} + Child.prototype = proto; + return new Child(); + }; + + /** + * Create a promise whose fate is determined by resolver + * @constructor + * @returns {Promise} promise + * @name Promise + */ + function Promise(resolver, handler) { + this._handler = resolver === Handler ? handler : init(resolver); + } + + /** + * Run the supplied resolver + * @param resolver + * @returns {Pending} + */ + function init(resolver) { + var handler = new Pending(); + + try { + resolver(promiseResolve, promiseReject, promiseNotify); + } catch (e) { + promiseReject(e); + } + + return handler; + + /** + * Transition from pre-resolution state to post-resolution state, notifying + * all listeners of the ultimate fulfillment or rejection + * @param {*} x resolution value + */ + function promiseResolve (x) { + handler.resolve(x); + } + /** + * Reject this promise with reason, which will be used verbatim + * @param {Error|*} reason rejection reason, strongly suggested + * to be an Error type + */ + function promiseReject (reason) { + handler.reject(reason); + } + + /** + * Issue a progress event, notifying all progress listeners + * @param {*} x progress event payload to pass to all listeners + */ + function promiseNotify (x) { + handler.notify(x); + } + } + + // Creation + + Promise.resolve = resolve; + Promise.reject = reject; + Promise.never = never; + + Promise._defer = defer; + Promise._handler = getHandler; + + /** + * Returns a trusted promise. If x is already a trusted promise, it is + * returned, otherwise returns a new trusted Promise which follows x. + * @param {*} x + * @return {Promise} promise + */ + function resolve(x) { + return isPromise(x) ? x + : new Promise(Handler, new Async(getHandler(x))); + } + + /** + * Return a reject promise with x as its reason (x is used verbatim) + * @param {*} x + * @returns {Promise} rejected promise + */ + function reject(x) { + return new Promise(Handler, new Async(new Rejected(x))); + } + + /** + * Return a promise that remains pending forever + * @returns {Promise} forever-pending promise. + */ + function never() { + return foreverPendingPromise; // Should be frozen + } + + /** + * Creates an internal {promise, resolver} pair + * @private + * @returns {Promise} + */ + function defer() { + return new Promise(Handler, new Pending()); + } + + // Transformation and flow control + + /** + * Transform this promise's fulfillment value, returning a new Promise + * for the transformed result. If the promise cannot be fulfilled, onRejected + * is called with the reason. onProgress *may* be called with updates toward + * this promise's fulfillment. + * @param {function=} onFulfilled fulfillment handler + * @param {function=} onRejected rejection handler + * @deprecated @param {function=} onProgress progress handler + * @return {Promise} new promise + */ + Promise.prototype.then = function(onFulfilled, onRejected) { + var parent = this._handler; + var state = parent.join().state(); + + if ((typeof onFulfilled !== 'function' && state > 0) || + (typeof onRejected !== 'function' && state < 0)) { + // Short circuit: value will not change, simply share handler + return new this.constructor(Handler, parent); + } + + var p = this._beget(); + var child = p._handler; + + parent.chain(child, parent.receiver, onFulfilled, onRejected, + arguments.length > 2 ? arguments[2] : void 0); + + return p; + }; + + /** + * If this promise cannot be fulfilled due to an error, call onRejected to + * handle the error. Shortcut for .then(undefined, onRejected) + * @param {function?} onRejected + * @return {Promise} + */ + Promise.prototype['catch'] = function(onRejected) { + return this.then(void 0, onRejected); + }; + + /** + * Creates a new, pending promise of the same type as this promise + * @private + * @returns {Promise} + */ + Promise.prototype._beget = function() { + var parent = this._handler; + var child = new Pending(parent.receiver, parent.join().context); + return new this.constructor(Handler, child); + }; + + // Array combinators + + Promise.all = all; + Promise.race = race; + + /** + * Return a promise that will fulfill when all promises in the + * input array have fulfilled, or will reject when one of the + * promises rejects. + * @param {array} promises array of promises + * @returns {Promise} promise for array of fulfillment values + */ + function all(promises) { + /*jshint maxcomplexity:8*/ + var resolver = new Pending(); + var pending = promises.length >>> 0; + var results = new Array(pending); + + var i, h, x, s; + for (i = 0; i < promises.length; ++i) { + x = promises[i]; + + if (x === void 0 && !(i in promises)) { + --pending; + continue; + } + + if (maybeThenable(x)) { + h = getHandlerMaybeThenable(x); + + s = h.state(); + if (s === 0) { + h.fold(settleAt, i, results, resolver); + } else if (s > 0) { + results[i] = h.value; + --pending; + } else { + unreportRemaining(promises, i+1, h); + resolver.become(h); + break; + } + + } else { + results[i] = x; + --pending; + } + } + + if(pending === 0) { + resolver.become(new Fulfilled(results)); + } + + return new Promise(Handler, resolver); + + function settleAt(i, x, resolver) { + /*jshint validthis:true*/ + this[i] = x; + if(--pending === 0) { + resolver.become(new Fulfilled(this)); + } + } + } + + function unreportRemaining(promises, start, rejectedHandler) { + var i, h, x; + for(i=start; i 0) { + queue.shift().run(); + } } - AssimilateTask.prototype.run = function() { - var h = this.resolver; - tryAssimilate(this._then, this.thenable, _resolve, _reject, _notify); + return Scheduler; - function _resolve(x) { h.resolve(x); } - function _reject(x) { h.reject(x); } - function _notify(x) { h.notify(x); } - }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + }(__webpack_require__(50))); - function tryAssimilate(then, thenable, resolve, reject, notify) { - try { - then.call(thenable, resolve, reject, notify); - } catch (e) { - reject(e); - } - } - // Other helpers +/***/ }, +/* 48 */ +/***/ function(module, exports, __webpack_require__) { - /** - * @param {*} x - * @returns {boolean} true iff x is a trusted Promise - */ - function isPromise(x) { - return x instanceof Promise; - } + var __WEBPACK_AMD_DEFINE_RESULT__;var require;/* WEBPACK VAR INJECTION */(function(process) {/** @license MIT License (c) copyright 2010-2014 original author or authors */ + /** @author Brian Cavalier */ + /** @author John Hann */ - /** - * Test just enough to rule out primitives, in order to take faster - * paths in some code - * @param {*} x - * @returns {boolean} false iff x is guaranteed *not* to be a thenable - */ - function maybeThenable(x) { - return (typeof x === 'object' || typeof x === 'function') && x !== null; - } + (function(define) { 'use strict'; + !(__WEBPACK_AMD_DEFINE_RESULT__ = function(require) { - function runContinuation1(f, h, receiver, next) { - if(typeof f !== 'function') { - return next.become(h); - } + // Sniff "best" async scheduling option + // Prefer process.nextTick or MutationObserver, then check for + // vertx and finally fall back to setTimeout - Promise.enterContext(h); - tryCatchReject(f, h.value, receiver, next); - Promise.exitContext(); - } + /*jshint maxcomplexity:6*/ + /*global process,document,setTimeout,MutationObserver,WebKitMutationObserver*/ + var nextTick, MutationObs; - function runContinuation3(f, x, h, receiver, next) { - if(typeof f !== 'function') { - return next.become(h); - } + if (typeof process !== 'undefined' && process !== null && + typeof process.nextTick === 'function') { + nextTick = function(f) { + process.nextTick(f); + }; - Promise.enterContext(h); - tryCatchReject3(f, x, h.value, receiver, next); - Promise.exitContext(); - } + } else if (MutationObs = + (typeof MutationObserver === 'function' && MutationObserver) || + (typeof WebKitMutationObserver === 'function' && WebKitMutationObserver)) { + nextTick = (function (document, MutationObserver) { + var scheduled; + var el = document.createElement('div'); + var o = new MutationObserver(run); + o.observe(el, { attributes: true }); + + function run() { + var f = scheduled; + scheduled = void 0; + f(); + } - function runNotify(f, x, h, receiver, next) { - if(typeof f !== 'function') { - return next.notify(x); - } + return function (f) { + scheduled = f; + el.setAttribute('class', 'x'); + }; + }(document, MutationObs)); + + } else { + nextTick = (function(cjsRequire) { + var vertx; + try { + // vert.x 1.x || 2.x + vertx = __webpack_require__(49); + } catch (ignore) {} + + if (vertx) { + if (typeof vertx.runOnLoop === 'function') { + return vertx.runOnLoop; + } + if (typeof vertx.runOnContext === 'function') { + return vertx.runOnContext; + } + } - Promise.enterContext(h); - tryCatchReturn(f, x, receiver, next); - Promise.exitContext(); + // capture setTimeout to avoid being caught by fake timers + // used in time based tests + var capturedSetTimeout = setTimeout; + return function (t) { + capturedSetTimeout(t, 0); + }; + }(require)); } + return nextTick; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + }(__webpack_require__(50))); + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(52))) + +/***/ }, +/* 49 */ +/***/ function(module, exports, __webpack_require__) { + + /* (ignored) */ + +/***/ }, +/* 50 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = function() { throw new Error("define cannot be used indirect"); }; + + +/***/ }, +/* 51 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/** @license MIT License (c) copyright 2010-2014 original author or authors */ + /** @author Brian Cavalier */ + /** @author John Hann */ + + (function(define) { 'use strict'; + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { /** - * Return f.call(thisArg, x), or if it throws return a rejected promise for - * the thrown exception + * Circular queue + * @param {number} capacityPow2 power of 2 to which this queue's capacity + * will be set initially. eg when capacityPow2 == 3, queue capacity + * will be 8. + * @constructor */ - function tryCatchReject(f, x, thisArg, next) { - try { - next.become(getHandler(f.call(thisArg, x))); - } catch(e) { - next.become(new Rejected(e)); - } + function Queue(capacityPow2) { + this.head = this.tail = this.length = 0; + this.buffer = new Array(1 << capacityPow2); } - /** - * Same as above, but includes the extra argument parameter. - */ - function tryCatchReject3(f, x, y, thisArg, next) { - try { - f.call(thisArg, x, y, next); - } catch(e) { - next.become(new Rejected(e)); + Queue.prototype.push = function(x) { + if(this.length === this.buffer.length) { + this._ensureCapacity(this.length * 2); } - } - /** - * Return f.call(thisArg, x), or if it throws, *return* the exception - */ - function tryCatchReturn(f, x, thisArg, next) { - try { - next.notify(f.call(thisArg, x)); - } catch(e) { - next.notify(e); + this.buffer[this.tail] = x; + this.tail = (this.tail + 1) & (this.buffer.length - 1); + ++this.length; + return this.length; + }; + + Queue.prototype.shift = function() { + var x = this.buffer[this.head]; + this.buffer[this.head] = void 0; + this.head = (this.head + 1) & (this.buffer.length - 1); + --this.length; + return x; + }; + + Queue.prototype._ensureCapacity = function(capacity) { + var head = this.head; + var buffer = this.buffer; + var newBuffer = new Array(capacity); + var i = 0; + var len; + + if(head === 0) { + len = this.length; + for(; i 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; + })(); + + process.title = 'browser'; + process.browser = true; + process.env = {}; + process.argv = []; + + function noop() {} + + process.on = noop; + process.addListener = noop; + process.once = noop; + process.off = noop; + process.removeListener = noop; + process.removeAllListeners = noop; + process.emit = noop; + + process.binding = function (name) { + throw new Error('process.binding is not supported'); + }; - return Promise; + // TODO(shtylman) + process.cwd = function () { return '/' }; + process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); }; -}); -}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); -},{}]},{},[10]) -(10) -}); \ No newline at end of file + +/***/ } +/******/ ]) \ No newline at end of file diff --git a/dist/react-router.min.js b/dist/react-router.min.js index 922d4089d9..9f50570d75 100644 --- a/dist/react-router.min.js +++ b/dist/react-router.min.js @@ -1,2 +1,11 @@ -!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;oi;i++)if(_changeListeners[i]===listener){_changeListeners.splice(i,1);break}window.removeEventListener?window.removeEventListener("hashchange",onHashChange,!1):window.removeEvent("onhashchange",onHashChange),0===_changeListeners.length&&(_isListening=!1)},push:function(path){_actionType=LocationActions.PUSH,window.location.hash=Path.encode(path)},replace:function(path){_actionType=LocationActions.REPLACE,window.location.replace(window.location.pathname+"#"+Path.encode(path))},pop:function(){_actionType=LocationActions.POP,History.back()},getCurrentPath:getHashPath,toString:function(){return""}};module.exports=HashLocation},{"../actions/LocationActions":1,"../utils/History":22,"../utils/Path":23}],12:[function(_dereq_,module){function getWindowPath(){return 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 LocationActions=_dereq_("../actions/LocationActions"),History=_dereq_("../utils/History"),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)},removeChangeListener:function(listener){for(var i=0,l=_changeListeners.length;l>i;i++)if(_changeListeners[i]===listener){_changeListeners.splice(i,1);break}window.addEventListener?window.removeEventListener("popstate",onPopState):window.removeEvent("popstate",onPopState),0===_changeListeners.length&&(_isListening=!1)},push:function(path){window.history.pushState({path:path},"",Path.encode(path)),History.length+=1,notifyChange(LocationActions.PUSH)},replace:function(path){window.history.replaceState({path:path},"",Path.encode(path)),notifyChange(LocationActions.REPLACE)},pop:History.back,getCurrentPath:getWindowPath,toString:function(){return""}};module.exports=HistoryLocation},{"../actions/LocationActions":1,"../utils/History":22,"../utils/Path":23}],13:[function(_dereq_,module){var HistoryLocation=_dereq_("./HistoryLocation"),History=_dereq_("../utils/History"),Path=_dereq_("../utils/Path"),RefreshLocation={push:function(path){window.location=Path.encode(path)},replace:function(path){window.location.replace(Path.encode(path))},pop:History.back,getCurrentPath:HistoryLocation.getCurrentPath,toString:function(){return""}};module.exports=RefreshLocation},{"../utils/History":22,"../utils/Path":23,"./HistoryLocation":12}],14:[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":43}],15:[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},{}],16:[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},{}],17:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null;module.exports={contextTypes:{getRouteAtDepth:React.PropTypes.func.isRequired,getRouteComponents:React.PropTypes.func.isRequired,routeHandlers:React.PropTypes.array.isRequired},childContextTypes:{routeHandlers:React.PropTypes.array.isRequired},getChildContext:function(){return{routeHandlers:this.context.routeHandlers.concat([this])}},getRouteDepth:function(){return this.context.routeHandlers.length-1},componentDidMount:function(){this._updateRouteComponent()},componentDidUpdate:function(){this._updateRouteComponent()},_updateRouteComponent:function(){var depth=this.getRouteDepth(),components=this.context.getRouteComponents();components[depth]=this.refs[this.props.ref||"__routeHandler__"]},getRouteHandler:function(props){var route=this.context.getRouteAtDepth(this.getRouteDepth());return route?React.createElement(route.handler,props||this.props):null}}},{}],18:[function(_dereq_,module){function shouldUpdateScroll(state,prevState){if(!prevState)return!0;if(state.pathname===prevState.pathname)return!1;var routes=state.routes,prevRoutes=prevState.routes,sharedAncestorRoutes=routes.filter(function(route){return-1!==prevRoutes.indexOf(route)});return!sharedAncestorRoutes.some(function(route){return route.ignoreScrollBehavior})}var invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM,getWindowScrollPosition=_dereq_("../utils/getWindowScrollPosition"),Scrolling={statics:{recordScrollPosition:function(path){this.scrollHistory||(this.scrollHistory={}),this.scrollHistory[path]=getWindowScrollPosition()},getScrollPosition:function(path){return this.scrollHistory||(this.scrollHistory={}),this.scrollHistory[path]||null}},componentWillMount:function(){invariant(null==this.getScrollBehavior()||canUseDOM,"Cannot use scroll behavior without a DOM")},componentDidMount:function(){this._updateScroll()},componentDidUpdate:function(prevProps,prevState){this._updateScroll(prevState)},_updateScroll:function(prevState){if(shouldUpdateScroll(this.state,prevState)){var scrollBehavior=this.getScrollBehavior();scrollBehavior&&scrollBehavior.updateScrollPosition(this.constructor.getScrollPosition(this.state.path),this.state.action)}}};module.exports=Scrolling},{"../utils/getWindowScrollPosition":30,"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43}],19:[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,getCurrentPathname: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()},getPathname:function(){return this.context.getCurrentPathname()},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},{}],20:[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)},getCurrentPathname:function(){return this.state.pathname},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,getCurrentPathname: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,getCurrentPathname:this.getCurrentPathname,getCurrentParams:this.getCurrentParams,getCurrentQuery:this.getCurrentQuery,isActive:this.isActive}}};module.exports=StateContext},{"../utils/Path":23,"react/lib/Object.assign":40}],21:[function(_dereq_,module){function Cancellation(){}module.exports=Cancellation},{}],22:[function(_dereq_,module){var invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM,History={back:function(){invariant(canUseDOM,"Cannot use History.back without a DOM"),History.length-=1,window.history.back()},length:1};module.exports=History},{"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43}],23:[function(_dereq_,module){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 decodeURI(path.replace(/\+/g," "))},encode:function(path){return encodeURI(path).replace(/%20/g,"+")},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:34,"qs/lib/utils":38,"react/lib/invariant":43}],24:[function(_dereq_,module){var Promise=_dereq_("when/lib/Promise");module.exports=Promise},{"when/lib/Promise":45}],25:[function(_dereq_,module){var PropTypes={falsy:function(props,propName,componentName){return props[propName]?new Error("<"+componentName+'> may not have a "'+propName+'" prop'):void 0}};module.exports=PropTypes},{}],26:[function(_dereq_,module){function Redirect(to,params,query){this.to=to,this.params=params,this.query=query}module.exports=Redirect},{}],27:[function(_dereq_,module){function runHooks(hooks,callback){var promise;try{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.isAborted||(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":24,"./Redirect":26,"./reversedArray":31,"react/lib/Object.assign":40}],28:[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 Cancellation||(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 hasProperties(object,properties){for(var propertyName in properties)if(properties.hasOwnProperty(propertyName)&&object[propertyName]!==properties[propertyName])return!1;return!0}function hasMatch(routes,route,prevParams,nextParams,prevQuery,nextQuery){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 hasProperties(prevQuery,nextQuery)&&hasProperties(nextQuery,prevQuery)})}function createRouter(options){function updateState(){state=nextState,nextState={}}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={},nextState={},pendingTransition=null;"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"):invariant(canUseDOM,"You cannot use %s without a DOM",location),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");var path=this.makePath(to,params,query);pendingTransition?location.replace(path):location.push(path)},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(){return invariant("string"!=typeof location,"You cannot use goBack with a static location"),History.length>1||location===RefreshLocation?(location.pop(),!0):(warning(!1,"goBack() was ignored because there is no router history"),!1)},match:function(pathname){return findMatch(pathname,routes,this.defaultRoute,this.notFoundRoute)||null},dispatch:function(path,action,callback){pendingTransition&&(pendingTransition.abort(new Cancellation),pendingTransition=null);var prevPath=state.path;if(prevPath!==path){prevPath&&action!==LocationActions.REPLACE&&this.recordScrollPosition(prevPath);var pathname=Path.withoutQuery(path),match=this.match(pathname);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||{},prevQuery=state.query||{},nextRoutes=match.routes||[],nextParams=match.params||{},nextQuery=Path.extractQuery(path)||{};prevRoutes.length?(fromRoutes=prevRoutes.filter(function(route){return!hasMatch(nextRoutes,route,prevParams,nextParams,prevQuery,nextQuery)}),toRoutes=nextRoutes.filter(function(route){return!hasMatch(prevRoutes,route,prevParams,nextParams,prevQuery,nextQuery)})):(fromRoutes=[],toRoutes=nextRoutes);var transition=new Transition(path,this.replaceWith.bind(this,path));pendingTransition=transition,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):(nextState.path=path,nextState.action=action,nextState.pathname=pathname,nextState.routes=nextRoutes,nextState.params=nextParams,nextState.query=nextQuery,void callback.call(router,null,transition))})})}},run:function(callback){var dispatchHandler=function(error,transition){pendingTransition=null,error?onError.call(router,error):transition.isAborted?onAbort.call(router,transition.abortReason,location):callback.call(router,router,nextState)};if("string"==typeof location)router.dispatch(location,null,dispatchHandler);else{var changeListener=function(change){router.dispatch(change.path,change.type,dispatchHandler)};location.addChangeListener&&location.addChangeListener(changeListener),router.dispatch(location.getCurrentPath(),null,dispatchHandler)}},teardown:function(){location.removeChangeListener(this.changeListener)}},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 updateState(),state},componentWillReceiveProps:function(){updateState(),this.setState(state)},componentWillUnmount:function(){router.teardown()},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"),LocationActions=_dereq_("../actions/LocationActions"),HashLocation=_dereq_("../locations/HashLocation"),HistoryLocation=_dereq_("../locations/HistoryLocation"),RefreshLocation=_dereq_("../locations/RefreshLocation"),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"),History=_dereq_("./History"),Cancellation=_dereq_("./Cancellation"),Path=_dereq_("./Path"),DEFAULT_LOCATION=canUseDOM?HashLocation:"/",DEFAULT_SCROLL_BEHAVIOR=canUseDOM?ImitateBrowserBehavior:null;module.exports=createRouter},{"../actions/LocationActions":1,"../behaviors/ImitateBrowserBehavior":2,"../components/RouteHandler":9,"../locations/HashLocation":11,"../locations/HistoryLocation":12,"../locations/RefreshLocation":13,"../mixins/NavigationContext":16,"../mixins/Scrolling":18,"../mixins/StateContext":20,"./Cancellation":21,"./History":22,"./Path":23,"./PropTypes":25,"./Redirect":26,"./Transition":27,"./createRoutesFromChildren":29,"./supportsHistory":33,"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43,"react/lib/warning":44}],29:[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};props.ignoreScrollBehavior&&(route.ignoreScrollBehavior=!0),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":4,"../components/NotFoundRoute":6,"../components/Redirect":7,"../components/Route":8,"./Path":23,"react/lib/invariant":43,"react/lib/warning":44}],30:[function(_dereq_,module){function getWindowScrollPosition(){return invariant(canUseDOM,"Cannot get current scroll position without a DOM"),{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}}var invariant=_dereq_("react/lib/invariant"),canUseDOM=_dereq_("react/lib/ExecutionEnvironment").canUseDOM;module.exports=getWindowScrollPosition},{"react/lib/ExecutionEnvironment":39,"react/lib/invariant":43}],31:[function(_dereq_,module){function reversedArray(array){return array.slice(0).reverse()}module.exports=reversedArray},{}],32:[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":28}],33:[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")||-1!==ua.indexOf("Windows Phone")?window.history&&"pushState"in window.history:!1}module.exports=supportsHistory},{}],34:[function(_dereq_,module){module.exports=_dereq_("./lib")},{"./lib":35}],35:[function(_dereq_,module){var Stringify=_dereq_("./stringify"),Parse=_dereq_("./parse");module.exports={stringify:Stringify,parse:Parse}},{"./parse":36,"./stringify":37}],36:[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":38}],37:[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":38}],38:[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}},{}],39:[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},{}],40:[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()})},{}],47:[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":46}],48:[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_)})},{}],49:[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;ie;e++)if(f[e]===t){f.splice(e,1);break}window.removeEventListener?window.removeEventListener("hashchange",u,!1):window.removeEvent("onhashchange",u),0===f.length&&(h=!1)},push:function(t){s=a.PUSH,window.location.hash=p.encode(t)},replace:function(t){s=a.REPLACE,window.location.replace(window.location.pathname+"#"+p.encode(t))},pop:function(){s=a.POP,c.back()},getCurrentPath:r,toString:function(){return""}};t.exports=l},function(t,e,n){function r(){return a.decode(window.location.pathname+window.location.search)}function o(t){var e={path:r(),type:t};c.forEach(function(t){t(e)})}function i(){o(u.POP)}var u=n(30),s=n(16),a=n(21),c=[],p=!1,f={addChangeListener:function(t){c.push(t),p||(window.addEventListener?window.addEventListener("popstate",i,!1):window.attachEvent("popstate",i),p=!0)},removeChangeListener:function(t){for(var e=0,n=c.length;n>e;e++)if(c[e]===t){c.splice(e,1);break}window.addEventListener?window.removeEventListener("popstate",i):window.removeEvent("popstate",i),0===c.length&&(p=!1)},push:function(t){window.history.pushState({path:t},"",a.encode(t)),s.length+=1,o(u.PUSH)},replace:function(t){window.history.replaceState({path:t},"",a.encode(t)),o(u.REPLACE)},pop:s.back,getCurrentPath:r,toString:function(){return""}};t.exports=f},function(t,e,n){var r=n(8),o=n(16),i=n(21),u={push:function(t){window.location=i.encode(t)},replace:function(t){window.location.replace(i.encode(t))},pop:o.back,getCurrentPath:r.getCurrentPath,toString:function(){return""}};t.exports=u},function(t,e,n){var r=n(30),o={updateScrollPosition:function(t,e){switch(e){case r.PUSH:case r.REPLACE:window.scrollTo(0,0);break;case r.POP:t?window.scrollTo(t.x,t.y):window.scrollTo(0,0)}}};t.exports=o},function(t){var e={updateScrollPosition:function(){window.scrollTo(0,0)}};t.exports=e},function(t,e,n){var r=n(17),o={contextTypes:{makePath:r.PropTypes.func.isRequired,makeHref:r.PropTypes.func.isRequired,transitionTo:r.PropTypes.func.isRequired,replaceWith:r.PropTypes.func.isRequired,goBack:r.PropTypes.func.isRequired},makePath:function(t,e,n){return this.context.makePath(t,e,n)},makeHref:function(t,e,n){return this.context.makeHref(t,e,n)},transitionTo:function(t,e,n){this.context.transitionTo(t,e,n)},replaceWith:function(t,e,n){this.context.replaceWith(t,e,n)},goBack:function(){this.context.goBack()}};t.exports=o},function(t,e,n){var r=n(17),o={contextTypes:{getCurrentPath:r.PropTypes.func.isRequired,getCurrentRoutes:r.PropTypes.func.isRequired,getCurrentPathname:r.PropTypes.func.isRequired,getCurrentParams:r.PropTypes.func.isRequired,getCurrentQuery:r.PropTypes.func.isRequired,isActive:r.PropTypes.func.isRequired},getPath:function(){return this.context.getCurrentPath()},getRoutes:function(){return this.context.getCurrentRoutes()},getPathname:function(){return this.context.getCurrentPathname()},getParams:function(){return this.context.getCurrentParams()},getQuery:function(){return this.context.getCurrentQuery()},isActive:function(t,e,n){return this.context.isActive(t,e,n)}};t.exports=o},function(t,e,n){function r(t){throw t}function o(t,e){if("string"==typeof e)throw new Error("Unhandled aborted transition! Reason: "+t);t instanceof A||(t instanceof j?e.replace(this.makePath(t.to,t.params,t.query)):e.pop())}function i(t,e,n,r){for(var o,s,a,c=0,p=e.length;p>c;++c){if(s=e[c],o=i(t,s.childRoutes,s.defaultRoute,s.notFoundRoute),null!=o)return o.routes.unshift(s),o;if(a=k.extractParams(s.path,t))return u(s,a)}return n&&(a=k.extractParams(n.path,t))?u(n,a):r&&(a=k.extractParams(r.path,t))?u(r,a):o}function u(t,e){return{routes:[t],params:e}}function s(t,e){for(var n in e)if(e.hasOwnProperty(n)&&t[n]!==e[n])return!1;return!0}function a(t,e,n,r,o,i){return t.some(function(t){if(t!==e)return!1;for(var u,a=e.paramNames,c=0,p=a.length;p>c;++c)if(u=a[c],r[u]!==n[u])return!1;return s(o,i)&&s(i,o)})}function c(t){function e(){H=S,S={}}t=t||{},"function"==typeof t?t={routes:t}:Array.isArray(t)&&(t={routes:t});var n=[],u={},s=[],c=t.location||E,d=t.scrollBehavior||q,j=t.onError||r,L=t.onAbort||o,H={},S={},N=null;"string"==typeof c?f(!l||!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"):h(l,"You cannot use %s without a DOM",c),c!==g||C()||(c=w);var D=p.createClass({displayName:"Router",mixins:[x,P,R],statics:{defaultRoute:null,notFoundRoute:null,addRoutes:function(t){n.push.apply(n,b(t,this,u))},makePath:function(t,e,n){var r;if(k.isAbsolute(t))r=k.normalize(t);else{var o=u[t];h(o,'Unable to find ',t),r=o.path}return k.withQuery(k.injectParams(r,e),n)},makeHref:function(t,e,n){var r=this.makePath(t,e,n);return c===m?"#"+r:r},transitionTo:function(t,e,n){h("string"!=typeof c,"You cannot use transitionTo with a static location");var r=this.makePath(t,e,n);N?c.replace(r):c.push(r)},replaceWith:function(t,e,n){h("string"!=typeof c,"You cannot use replaceWith with a static location"),c.replace(this.makePath(t,e,n))},goBack:function(){return h("string"!=typeof c,"You cannot use goBack with a static location"),O.length>1||c===w?(c.pop(),!0):(f(!1,"goBack() was ignored because there is no router history"),!1)},match:function(t){return i(t,n,this.defaultRoute,this.notFoundRoute)||null},dispatch:function(t,e,n){N&&(N.abort(new A),N=null);var r=H.path;if(r!==t){r&&e!==v.REPLACE&&this.recordScrollPosition(r);var o=k.withoutQuery(t),i=this.match(o);f(null!=i,'No route matches path "%s". Make sure you have somewhere in your routes',t,t),null==i&&(i={});var u,c,p=H.routes||[],h=H.params||{},l=H.query||{},d=i.routes||[],y=i.params||{},m=k.extractQuery(t)||{};p.length?(u=p.filter(function(t){return!a(d,t,h,y,l,m)}),c=d.filter(function(t){return!a(p,t,h,y,l,m)})):(u=[],c=d);var g=new T(t,this.replaceWith.bind(this,t));N=g,g.from(u,s,function(r){return r||g.isAborted?n.call(D,r,g):void g.to(c,y,m,function(r){return r||g.isAborted?n.call(D,r,g):(S.path=t,S.action=e,S.pathname=o,S.routes=d,S.params=y,S.query=m,void n.call(D,null,g))})})}},run:function(t){var e=function(e,n){N=null,e?j.call(D,e):n.isAborted?L.call(D,n.abortReason,c):t.call(D,D,S)};if("string"==typeof c)D.dispatch(c,null,e);else{var n=function(t){D.dispatch(t.path,t.type,e)};c.addChangeListener&&c.addChangeListener(n),D.dispatch(c.getCurrentPath(),null,e)}},teardown:function(){c.removeChangeListener(this.changeListener)}},propTypes:{children:_.falsy},getLocation:function(){return c},getScrollBehavior:function(){return d},getRouteAtDepth:function(t){var e=this.state.routes;return e&&e[t]},getRouteComponents:function(){return s},getInitialState:function(){return e(),H},componentWillReceiveProps:function(){e(),this.setState(H)},componentWillUnmount:function(){D.teardown()},render:function(){return this.getRouteAtDepth(0)?p.createElement(y,this.props):null},childContextTypes:{getRouteAtDepth:p.PropTypes.func.isRequired,getRouteComponents:p.PropTypes.func.isRequired,routeHandlers:p.PropTypes.array.isRequired},getChildContext:function(){return{getRouteComponents:this.getRouteComponents,getRouteAtDepth:this.getRouteAtDepth,routeHandlers:[this]}}});return t.routes&&D.addRoutes(t.routes),D}var p=n(17),f=n(36),h=n(37),l=n(38).canUseDOM,d=n(10),y=n(6),v=n(30),m=n(7),g=n(8),w=n(9),x=n(22),P=n(23),R=n(24),b=n(25),C=n(26),T=n(27),_=n(19),j=n(28),O=n(16),A=n(29),k=n(21),E=l?m:"/",q=l?d:null;t.exports=c},function(t,e,n){function r(t,e,n){"function"==typeof e&&(n=e,e=null);var r=o({routes:t,location:e});return r.run(n),r}var o=n(14);t.exports=r},function(t,e,n){var r=n(37),o=n(38).canUseDOM,i={back:function(){r(o,"Cannot use History.back without a DOM"),i.length-=1,window.history.back()},length:1};t.exports=i},function(t){t.exports=React},function(t,e,n){var r=n(37),o={render:function(){r(!1,"%s elements should not be rendered",this.constructor.displayName)}};t.exports=o},function(t){var e={falsy:function(t,e,n){return t[e]?new Error("<"+n+'> may not have a "'+e+'" prop'):void 0}};t.exports=e},function(t,e,n){var r=n(17);t.exports={contextTypes:{getRouteAtDepth:r.PropTypes.func.isRequired,getRouteComponents:r.PropTypes.func.isRequired,routeHandlers:r.PropTypes.array.isRequired},childContextTypes:{routeHandlers:r.PropTypes.array.isRequired},getChildContext:function(){return{routeHandlers:this.context.routeHandlers.concat([this])}},getRouteDepth:function(){return this.context.routeHandlers.length-1},componentDidMount:function(){this._updateRouteComponent()},componentDidUpdate:function(){this._updateRouteComponent()},_updateRouteComponent:function(){var t=this.getRouteDepth(),e=this.context.getRouteComponents();e[t]=this.refs[this.props.ref||"__routeHandler__"]},getRouteHandler:function(t){var e=this.context.getRouteAtDepth(this.getRouteDepth());return e?r.createElement(e.handler,t||this.props):null}}},function(t,e,n){function r(t){if(!(t in f)){var e=[],n=t.replace(s,function(t,n){return n?(e.push(n),"([^/?#]+)"):"*"===t?(e.push("splat"),"(.*?)"):"\\"+t});f[t]={matcher:new RegExp("^"+n+"$","i"),paramNames:e}}return f[t]}var o=n(37),i=n(40).merge,u=n(39),s=/:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g,a=/:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g,c=/\/\/\?|\/\?/g,p=/\?(.+)/,f={},h={decode:function(t){return decodeURI(t.replace(/\+/g," "))},encode:function(t){return encodeURI(t).replace(/%20/g,"+")},extractParamNames:function(t){return r(t).paramNames},extractParams:function(t,e){var n=r(t),o=e.match(n.matcher);if(!o)return null;var i={};return n.paramNames.forEach(function(t,e){i[t]=o[e+1]}),i},injectParams:function(t,e){e=e||{};var n=0;return t.replace(a,function(r,i){if(i=i||"splat","?"!==i.slice(-1))o(null!=e[i],'Missing "'+i+'" parameter for path "'+t+'"');else if(i=i.slice(0,-1),null==e[i])return"";var u;return"splat"===i&&Array.isArray(e[i])?(u=e[i][n++],o(null!=u,"Missing splat # "+n+' for path "'+t+'"')):u=e[i],u}).replace(c,"/")},extractQuery:function(t){var e=t.match(p);return e&&u.parse(e[1])},withoutQuery:function(t){return t.replace(p,"")},withQuery:function(t,e){var n=h.extractQuery(t);n&&(e=e?i(n,e):n);var r=e&&u.stringify(e);return r?h.withoutQuery(t)+"?"+r:t},isAbsolute:function(t){return"/"===t.charAt(0)},normalize:function(t){return t.replace(/^\/*/,"/")},join:function(t,e){return t.replace(/\/*$/,"/")+e}};t.exports=h},function(t,e,n){var r=n(17),o={childContextTypes:{makePath:r.PropTypes.func.isRequired,makeHref:r.PropTypes.func.isRequired,transitionTo:r.PropTypes.func.isRequired,replaceWith:r.PropTypes.func.isRequired,goBack:r.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}}};t.exports=o},function(t,e,n){function r(t,e){return t.some(function(t){return t.name===e})}function o(t,e){for(var n in e)if(String(t[n])!==String(e[n]))return!1;return!0}function i(t,e){for(var n in e)if(String(t[n])!==String(e[n]))return!1;return!0}var u=n(17),s=n(35),a=n(21),c={getCurrentPath:function(){return this.state.path},getCurrentRoutes:function(){return this.state.routes.slice(0)},getCurrentPathname:function(){return this.state.pathname},getCurrentParams:function(){return s({},this.state.params)},getCurrentQuery:function(){return s({},this.state.query)},isActive:function(t,e,n){return a.isAbsolute(t)?t===this.state.path:r(this.state.routes,t)&&o(this.state.params,e)&&(null==n||i(this.state.query,n))},childContextTypes:{getCurrentPath:u.PropTypes.func.isRequired,getCurrentRoutes:u.PropTypes.func.isRequired,getCurrentPathname:u.PropTypes.func.isRequired,getCurrentParams:u.PropTypes.func.isRequired,getCurrentQuery:u.PropTypes.func.isRequired,isActive:u.PropTypes.func.isRequired},getChildContext:function(){return{getCurrentPath:this.getCurrentPath,getCurrentRoutes:this.getCurrentRoutes,getCurrentPathname:this.getCurrentPathname,getCurrentParams:this.getCurrentParams,getCurrentQuery:this.getCurrentQuery,isActive:this.isActive}}};t.exports=c},function(t,e,n){function r(t,e){if(!e)return!0;if(t.pathname===e.pathname)return!1;var n=t.routes,r=e.routes,o=n.filter(function(t){return-1!==r.indexOf(t)});return!o.some(function(t){return t.ignoreScrollBehavior})}var o=n(37),i=n(38).canUseDOM,u=n(31),s={statics:{recordScrollPosition:function(t){this.scrollHistory||(this.scrollHistory={}),this.scrollHistory[t]=u()},getScrollPosition:function(t){return this.scrollHistory||(this.scrollHistory={}),this.scrollHistory[t]||null}},componentWillMount:function(){o(null==this.getScrollBehavior()||i,"Cannot use scroll behavior without a DOM")},componentDidMount:function(){this._updateScroll()},componentDidUpdate:function(t,e){this._updateScroll(e)},_updateScroll:function(t){if(r(this.state,t)){var e=this.getScrollBehavior();e&&e.updateScrollPosition(this.constructor.getScrollPosition(this.state.path),this.state.action)}}};t.exports=s},function(t,e,n){function r(t,e,n){return s.createClass({statics:{willTransitionTo:function(r,o,i){r.redirect(t,e||o,n||i)}},render:function(){return null}})}function o(t,e,n){for(var r in e)if(e.hasOwnProperty(r)){var o=e[r](n,r,t);o instanceof Error&&a(!1,o.message)}}function i(t,e,n){var i=t.type,s=t.props,a=i&&i.displayName||"UnknownComponent";c(-1!==y.indexOf(i),'Unrecognized route configuration element "<%s>"',a),i.propTypes&&o(a,i.propTypes,s);var l={name:s.name};s.ignoreScrollBehavior&&(l.ignoreScrollBehavior=!0),i===h.type?(l.handler=r(s.to,s.params,s.query),s.path=s.path||s.from||"*"):l.handler=s.handler;var v=e&&e.path||"/";if((s.path||s.name)&&i!==p.type&&i!==f.type){var m=s.path||s.name;d.isAbsolute(m)||(m=d.join(v,m)),l.path=d.normalize(m)}else l.path=v,i===f.type&&(l.path+="*");return l.paramNames=d.extractParamNames(l.path),e&&Array.isArray(e.paramNames)&&e.paramNames.forEach(function(t){c(-1!==l.paramNames.indexOf(t),'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"',l.path,t,e.path)}),s.name&&(c(null==n[s.name],'You cannot use the name "%s" for more than one route',s.name),n[s.name]=l),i===f.type?(c(e," must have a parent "),c(null==e.notFoundRoute,"You may not have more than one per "),e.notFoundRoute=l,null):i===p.type?(c(e," must have a parent "),c(null==e.defaultRoute,"You may not have more than one per "),e.defaultRoute=l,null):(l.childRoutes=u(s.children,l,n),l)}function u(t,e,n){var r=[];return s.Children.forEach(t,function(t){(t=i(t,e,n))&&r.push(t)}),r}var s=n(17),a=n(36),c=n(37),p=n(1),f=n(3),h=n(4),l=n(5),d=n(21),y=[p.type,f.type,h.type,l.type];t.exports=u},function(t){function e(){/*! taken from modernizr + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js + * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586 + */ +var t=navigator.userAgent;return-1===t.indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone")?window.history&&"pushState"in window.history:!1}t.exports=e},function(t,e,n){function r(t,e){var n;try{n=t.reduce(function(t,e){return t?t.then(e):e()},null)}catch(r){return e(r)}n?n.then(function(){setTimeout(e)},function(t){setTimeout(function(){e(t)})}):e()}function o(t,e,n,o){n=a(n);var i=a(e).map(function(e,r){return function(){var o=e.handler;if(!t.isAborted&&o.willTransitionFrom)return o.willTransitionFrom(t,n[r]);var i=t._promise;return t._promise=null,i}});r(i,o)}function i(t,e,n,o,i){var u=e.map(function(e){return function(){var r=e.handler;!t.isAborted&&r.willTransitionTo&&r.willTransitionTo(t,n,o);var i=t._promise;return t._promise=null,i}});r(u,i)}function u(t,e){this.path=t,this.abortReason=null,this.isAborted=!1,this.retry=e.bind(this),this._promise=null}var s=n(35),a=n(32),c=n(28),p=n(33);s(u.prototype,{abort:function(t){this.isAborted||(this.abortReason=t,this.isAborted=!0)},redirect:function(t,e,n){this.abort(new c(t,e,n))},wait:function(t){this._promise=p.resolve(t)},from:function(t,e,n){return o(this,t,e,n)},to:function(t,e,n,r){return i(this,t,e,n,r)}}),t.exports=u},function(t){function e(t,e,n){this.to=t,this.params=e,this.query=n}t.exports=e},function(t){function e(){}t.exports=e},function(t){var e={PUSH:"push",REPLACE:"replace",POP:"pop"};t.exports=e},function(t,e,n){function r(){return o(i,"Cannot get current scroll position without a DOM"),{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}}var o=n(37),i=n(38).canUseDOM;t.exports=r},function(t){function e(t){return t.slice(0).reverse()}t.exports=e},function(t,e,n){var r=n(43);t.exports=r},function(t){function e(t){return"object"==typeof t?Object.keys(t).filter(function(e){return t[e]}).join(" "):Array.prototype.join.call(arguments," ")}t.exports=e},function(t){function e(t){if(null==t)throw new TypeError("Object.assign target cannot be null or undefined");for(var e=Object(t),n=Object.prototype.hasOwnProperty,r=1;rn;++n)"undefined"!=typeof t[n]&&(e[n]=t[n]);return e},e.merge=function(t,n){if(!n)return t;if(Array.isArray(n)){for(var r=0,o=n.length;o>r;++r)"undefined"!=typeof n[r]&&(t[r]="object"==typeof t[r]?e.merge(t[r],n[r]):n[r]);return t}if(Array.isArray(t)){if("object"!=typeof n)return t.push(n),t;t=e.arrayToObject(t)}for(var i=Object.keys(n),u=0,s=i.length;s>u;++u){var a=i[u],c=n[a];t[a]=c&&"object"==typeof c&&t[a]?e.merge(t[a],c):c}return t},e.decode=function(t){try{return decodeURIComponent(t.replace(/\+/g," "))}catch(e){return t}},e.compact=function(t,n){if("object"!=typeof t||null===t)return t;n=n||[];var r=n.indexOf(t);if(-1!==r)return n[r];if(n.push(t),Array.isArray(t)){for(var o=[],i=0,u=t.length;u>i;++i)"undefined"!=typeof t[i]&&o.push(t[i]);return o}for(var s=Object.keys(t),i=0,a=s.length;a>i;++i){var c=s[i];t[c]=e.compact(t[c],n)}return t},e.isRegExp=function(t){return"[object RegExp]"===Object.prototype.toString.call(t)},e.isBuffer=function(t){return"undefined"!=typeof Buffer?Buffer.isBuffer(t):!1}},function(t){function e(t){return function(){return t}}function n(){}n.thatReturns=e,n.thatReturnsFalse=e(!1),n.thatReturnsTrue=e(!0),n.thatReturnsNull=e(null),n.thatReturnsThis=function(){return this},n.thatReturnsArgument=function(t){return t},t.exports=n},function(t,e,n){var r=n(44),o=n(45);t.exports={stringify:r,parse:o}},function(t,e,n){var r;/** @license MIT License (c) copyright 2010-2014 original author or authors */ +!function(){"use strict";r=function(){var t=n(46),e=n(47),r=n(48);return t({scheduler:new e(r)})}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))}(n(51))},function(t,e,n){var r=n(40),o={delimiter:"&"};o.stringify=function(t,e){if(r.isBuffer(t)?t=t.toString():t instanceof Date?t=t.toISOString():null===t&&(t=""),"string"==typeof t||"number"==typeof t||"boolean"==typeof t)return[encodeURIComponent(e)+"="+encodeURIComponent(t)];var n=[];for(var i in t)t.hasOwnProperty(i)&&(n=n.concat(o.stringify(t[i],e+"["+i+"]")));return n},t.exports=function(t,e){e=e||{};var n="undefined"==typeof e.delimiter?o.delimiter:e.delimiter,r=[];for(var i in t)t.hasOwnProperty(i)&&(r=r.concat(o.stringify(t[i],i)));return r.join(n)}},function(t,e,n){var r=n(40),o={delimiter:"&",depth:5,arrayLimit:20,parameterLimit:1e3};o.parseValues=function(t,e){for(var n={},o=t.split(e.delimiter,1/0===e.parameterLimit?void 0:e.parameterLimit),i=0,u=o.length;u>i;++i){var s=o[i],a=-1===s.indexOf("]=")?s.indexOf("="):s.indexOf("]=")+1;if(-1===a)n[r.decode(s)]="";else{var c=r.decode(s.slice(0,a)),p=r.decode(s.slice(a+1));n[c]=n[c]?[].concat(n[c]).concat(p):p}}return n},o.parseObject=function(t,e,n){if(!t.length)return e;var r=t.shift(),i={};if("[]"===r)i=[],i=i.concat(o.parseObject(t,e,n));else{var u="["===r[0]&&"]"===r[r.length-1]?r.slice(1,r.length-1):r,s=parseInt(u,10);!isNaN(s)&&r!==u&&s<=n.arrayLimit?(i=[],i[s]=o.parseObject(t,e,n)):i[u]=o.parseObject(t,e,n)}return i},o.parseKeys=function(t,e,n){if(t){var r=/^([^\[\]]*)/,i=/(\[[^\[\]]*\])/g,u=r.exec(t);if(!Object.prototype.hasOwnProperty(u[1])){var s=[];u[1]&&s.push(u[1]);for(var a=0;null!==(u=i.exec(t))&&as;++s){var c=u[s],p=o.parseKeys(c,n[c],e);i=r.merge(i,p)}return r.compact(i)}},function(t,e,n){var r;/** @license MIT License (c) copyright 2010-2014 original author or authors */ +!function(){"use strict";r=function(){return function(t){function e(t,e){this._handler=t===l?e:n(t)}function n(t){function e(t){o.resolve(t)}function n(t){o.reject(t)}function r(t){o.notify(t)}var o=new y;try{t(e,n,r)}catch(i){n(i)}return o}function r(t){return j(t)?t:new e(l,new v(p(t)))}function o(t){return new e(l,new v(new w(t)))}function i(){return W}function u(){return new e(l,new y)}function s(t){function n(t,e,n){this[t]=e,0===--c&&n.become(new g(this))}var r,o,i,u,s=new y,c=t.length>>>0,p=new Array(c);for(r=0;r0)){a(t,r+1,o),s.become(o);break}p[r]=o.value,--c}else p[r]=i,--c;else--c;return 0===c&&s.become(new g(p)),new e(l,s)}function a(t,e,n){var r,o,i;for(r=e;r0||"function"!=typeof e&&0>r)return new this.constructor(l,n);var o=this._beget(),i=o._handler;return n.chain(i,n.receiver,t,e,arguments.length>2?arguments[2]:void 0),o},e.prototype["catch"]=function(t){return this.then(void 0,t)},e.prototype._beget=function(){var t=this._handler,e=new y(t.receiver,t.join().context);return new this.constructor(l,e)},e.all=s,e.race=c,l.prototype.when=l.prototype.become=l.prototype.notify=l.prototype.fail=l.prototype._unreport=l.prototype._report=N,l.prototype._state=0,l.prototype.state=function(){return this._state},l.prototype.join=function(){for(var t=this;void 0!==t.handler;)t=t.handler;return t},l.prototype.chain=function(t,e,n,r,o){this.when({resolver:t,receiver:e,fulfilled:n,rejected:r,progress:o})},l.prototype.visit=function(t,e,n,r){this.chain(M,t,e,n,r)},l.prototype.fold=function(t,e,n,r){this.visit(r,function(r){t.call(n,e,r,this)},r.reject,r.notify)},S(l,d),d.prototype.become=function(t){t.fail()};var M=new d;S(l,y),y.prototype._state=0,y.prototype.resolve=function(t){this.become(p(t))},y.prototype.reject=function(t){this.resolved||this.become(new w(t))},y.prototype.join=function(){if(!this.resolved)return this;for(var t=this;void 0!==t.handler;)if(t=t.handler,t===this)return this.handler=R();return t},y.prototype.run=function(){var t=this.consumers,e=this.join();this.consumers=void 0;for(var n=0;n0;)t.shift().run()}var r=n(50);return t.prototype.enqueue=function(t){this._add(this._queue,t)},t.prototype.afterQueue=function(t){this._add(this._afterQueue,t)},t.prototype._drain=function(){e(this._queue),this._running=!1,e(this._afterQueue)},t.prototype._add=function(t,e){t.push(e),this._running||(this._running=!0,this._async(this.drain))},t}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))}(n(51))},function(t,e,n){var r;(function(o){/** @license MIT License (c) copyright 2010-2014 original author or authors */ +!function(){"use strict";r=function(t){var e,r;return e="undefined"!=typeof o&&null!==o&&"function"==typeof o.nextTick?function(t){o.nextTick(t)}:(r="function"==typeof MutationObserver&&MutationObserver||"function"==typeof WebKitMutationObserver&&WebKitMutationObserver)?function(t,e){function n(){var t=r;r=void 0,t()}var r,o=t.createElement("div"),i=new e(n);return i.observe(o,{attributes:!0}),function(t){r=t,o.setAttribute("class","x")}}(document,r):function(){var t;try{t=n(49)}catch(e){}if(t){if("function"==typeof t.runOnLoop)return t.runOnLoop;if("function"==typeof t.runOnContext)return t.runOnContext}var r=setTimeout;return function(t){r(t,0)}}(t)}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))}(n(51))}).call(e,n(52))},function(){},function(t,e,n){var r;/** @license MIT License (c) copyright 2010-2014 original author or authors */ +!function(){"use strict";r=function(){function t(t){this.head=this.tail=this.length=0,this.buffer=new Array(1<i;++i)o[i]=r[i];else{for(t=r.length,e=this.tail;t>n;++i,++n)o[i]=r[n];for(n=0;e>n;++i,++n)o[i]=r[n]}this.buffer=o,this.head=0,this.tail=this.length},t}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))}(n(51))},function(t){t.exports=function(){throw new Error("define cannot be used indirect")}},function(t){function e(){}var n=t.exports={};n.nextTick=function(){var t="undefined"!=typeof window&&window.setImmediate,e="undefined"!=typeof window&&window.MutationObserver,n="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(t)return function(t){return window.setImmediate(t)};var r=[];if(e){var o=document.createElement("div"),i=new MutationObserver(function(){var t=r.slice();r.length=0,t.forEach(function(t){t()})});return i.observe(o,{attributes:!0}),function(t){r.length||o.setAttribute("yes","no"),r.push(t)}}return n?(window.addEventListener("message",function(t){var e=t.source;if((e===window||null===e)&&"process-tick"===t.data&&(t.stopPropagation(),r.length>0)){var n=r.shift();n()}},!0),function(t){r.push(t),window.postMessage("process-tick","*")}):function(t){setTimeout(t,0)}}(),n.title="browser",n.browser=!0,n.env={},n.argv=[],n.on=e,n.addListener=e,n.once=e,n.off=e,n.removeListener=e,n.removeAllListeners=e,n.emit=e,n.binding=function(){throw new Error("process.binding is not supported")},n.cwd=function(){return"/"},n.chdir=function(){throw new Error("process.chdir is not supported")}}]); \ No newline at end of file diff --git a/package.json b/package.json index 63deb0b0bf..098569d32c 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,8 @@ "example": "examples" }, "scripts": { - "build": "webpack modules/index.js dist/react-router.js", - "build-min": "uglifyjs dist/react-router.js --compress warnings=false > dist/react-router.min.js", + "build": "NODE_ENV=production webpack modules/index.js dist/react-router.js", + "build-min": "NODE_ENV=production COMPRESS=1 webpack modules/index.js dist/react-router.min.js", "examples": "webpack-dev-server --config examples/webpack.config.js --no-info --content-base examples", "test": "jsxhint . && karma start" }, @@ -40,7 +40,6 @@ "react": "0.12.x", "rf-release": "0.4.0", "rx": "2.3.18", - "uglify-js": "^2.4.16", "webpack": "^1.4.13", "webpack-dev-server": "^1.6.6" }, diff --git a/webpack.config.js b/webpack.config.js index 07e7775acc..bb7c126b4c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,5 +1,21 @@ var webpack = require('webpack'); +var plugins = [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') + }) +]; + +if (process.env.COMPRESS) { + plugins.push( + new webpack.optimize.UglifyJsPlugin({ + compressor: { + warnings: false + } + }) + ); +} + module.exports = { output: { @@ -11,10 +27,10 @@ module.exports = { react: 'React' }, - plugins: [ - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') - }) - ] + node: { + buffer: false + }, + + plugins: plugins };