Changeset 5976


Ignore:
Timestamp:
02/13/15 11:45:30 (9 years ago)
Author:
emanuel.dima@uni-tuebingen.de
Message:
  1. alpha 20: routing and direct links, improved UI for statistics, bugfixes
Location:
SRUAggregator/trunk
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • SRUAggregator/trunk/aggregator.yml

    r5971 r5976  
    11aggregatorParams:
    22  CENTER_REGISTRY_URL: http://centres.clarin.eu/restxml/
    3 #  additionalCQLEndpoints:
    4 #    - https://clarin.ids-mannheim.de/digibibsru-new
    5     # - https://lux17.mpi.nl/ds/cqlsearch
    6     # - http://www.meertens.knaw.nl/mimore/srucql/
    7     # - http://gysseling.corpus.taalbanknederlands.inl.nl/gyssru/
    8     # - http://brievenalsbuit.inl.nl/zbsru/
    9     # - http://corpus3.aac.ac.at/ddconsru/
     3 # additionalCQLEndpoints:
     4 #    - https://clarin.ids-mannheim.de/digibibsru-new
     5 #    - https://lux17.mpi.nl/ds/cqlsearch
     6 #    - http://www.meertens.knaw.nl/mimore/srucql/
     7 #    - http://gysseling.corpus.taalbanknederlands.inl.nl/gyssru/
     8 #    - http://brievenalsbuit.inl.nl/zbsru/
     9 #    - http://corpus3.aac.ac.at/ddconsru/
     10#      - http://dspin.dwds.de:8088/ddc-sru/dta/
    1011
    1112  # AGGREGATOR_FILE_PATH: /data/fcsAggregator/fcsAggregatorCorpora.json
     
    2021  SEARCH_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT: 4
    2122
    22   ENDPOINTS_SCAN_TIMEOUT_MS: 10000
     23  ENDPOINTS_SCAN_TIMEOUT_MS: 60000
    2324  ENDPOINTS_SEARCH_TIMEOUT_MS: 30000
    2425  EXECUTOR_SHUTDOWN_TIMEOUT_MS: 1000
  • SRUAggregator/trunk/build.sh

    r5971 r5976  
    1313
    1414        npm install bower react-tools
    15         node_modules/bower/bin/bower install jquery bootstrap react react-addons react-router font-awesome
     15        node_modules/bower/bin/bower install jquery bootstrap react react-addons font-awesome
    1616
    1717        cp bower_components/bootstrap/dist/css/bootstrap.min.css $LIBDIR/
     
    2121        cp bower_components/react/react-with-addons.js $LIBDIR/
    2222        cp bower_components/react/react-with-addons.min.js $LIBDIR/
    23         cp bower_components/react-router/dist/react-router.min.js $LIBDIR/
    2423        cp bower_components/font-awesome/css/font-awesome.min.css $LIBDIR/
    2524
  • SRUAggregator/trunk/pom.xml

    r5971 r5976  
    88        <groupId>eu.clarin.sru.fcs</groupId>
    99        <artifactId>Aggregator2</artifactId>
    10         <version>2.0.0-alpha-19</version>
     10        <version>2.0.0-alpha-20</version>
    1111        <name>FCS Aggregator</name>
    1212
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/Aggregator.java

    r5971 r5976  
    8888 * @author edima
    8989 *
    90  * TODO: Send mail to Dieter with centers that do not accept recordSchema
    91  * parameter
    92  *
    93  * TODO: mail to LINDAT-Clarin devel about matching whole word in search
    94  *
    95  * TODO: routing
    96  *
    97  * TODO: stats page as tabs
    98  *
    9990 * TODO: Download search results as csv, excel, tcf, plain text
    10091 *
     
    157148        @Override
    158149        public void initialize(Bootstrap<AggregatorConfiguration> bootstrap) {
    159                 bootstrap.addBundle(new AssetsBundle("/assets", "/", "index.html"));
    160         }
     150                bootstrap.addBundle(new AssetsBundle("/assets", "/", "index.html", "static"));
     151        }
     152
    161153
    162154        @Override
     
    172164                }
    173165
     166                environment.getApplicationContext().setErrorHandler(new ErrorPageHandler());
    174167                environment.jersey().setUrlPattern("/rest/*");
    175168                environment.jersey().register(new RestService());
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/rest/RestService.java

    r5960 r5976  
    7575                Object j = new HashMap<String, Object>() {
    7676                        {
    77                                 put("lastScanStats", new HashMap<String, Object>() {
     77                                put("Last Scan", new HashMap<String, Object>() {
    7878                                        {
    7979                                                put("maxConcurrentScanRequestsPerEndpoint",
    8080                                                                Aggregator.getInstance().getParams().getSCAN_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT());
    8181                                                put("timeout", params.getENDPOINTS_SCAN_TIMEOUT_MS() / 1000.);
     82                                                put("isScan", true);
    8283                                                put("institutions", scan.getInstitutions());
    8384                                        }
    8485                                });
    85                                 put("searchStats", new HashMap<String, Object>() {
     86                                put("Recent Searches", new HashMap<String, Object>() {
    8687                                        {
    8788                                                put("maxConcurrentSearchRequestsPerEndpoint",
    8889                                                                Aggregator.getInstance().getParams().getSEARCH_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT());
    8990                                                put("timeout", params.getENDPOINTS_SEARCH_TIMEOUT_MS() / 1000.);
     91                                                put("isScan", false);
    9092                                                put("institutions", search.getInstitutions());
    9193                                        }
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/ScanCrawler.java

    r5971 r5976  
    270270                                                        if (corpora.addCorpus(c, parentCorpus)) {
    271271                                                                new ScanTask(institution, endpoint, c, corpora, depth + 1).start();
    272                                                                 statistics.addEndpointCollection(institution, endpoint, c.getTitle());
     272                                                                if (parentCorpus == null) {
     273                                                                        statistics.addEndpointCollection(institution, endpoint, c.getTitle());
     274                                                                }
    273275                                                        }
    274276                                                }
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/search/Search.java

    r5971 r5976  
    66import eu.clarin.sru.client.SRUSearchRetrieveRequest;
    77import eu.clarin.sru.client.SRUSearchRetrieveResponse;
     8import eu.clarin.sru.client.fcs.ClarinFCSRecordData;
    89import eu.clarin.sru.fcs.aggregator.client.ThrottledClient;
    910import eu.clarin.sru.fcs.aggregator.scan.Corpus;
     
    6364                searchRequest.setVersion(version);
    6465                searchRequest.setMaximumRecords(maxRecords);
    65                 FCSProtocolVersion fcsVersion = corpus.getEndpoint().getProtocol();
    66 //              searchRequest.setRecordSchema(
    67 //                              fcsVersion.equals(FCSProtocolVersion.LEGACY)
    68 //                                              ? ClarinFCSRecordData.LEGACY_RECORD_SCHEMA
    69 //                                              : ClarinFCSRecordData.RECORD_SCHEMA);
     66                boolean legacy = corpus.getEndpoint().getProtocol().equals(FCSProtocolVersion.LEGACY);
     67                searchRequest.setRecordSchema(legacy
     68                                ? ClarinFCSRecordData.LEGACY_RECORD_SCHEMA
     69                                : ClarinFCSRecordData.RECORD_SCHEMA);
    7070                searchRequest.setQuery("\"" + searchString + "\"");
    7171                searchRequest.setStartRecord(startRecord);
    7272                if (corpus.getHandle() != null) {
    73                         searchRequest.setExtraRequestData(
    74                                         fcsVersion.equals(FCSProtocolVersion.LEGACY)
    75                                                         ? SRUCQL.SEARCH_CORPUS_HANDLE_LEGACY_PARAMETER
    76                                                         : SRUCQL.SEARCH_CORPUS_HANDLE_PARAMETER,
     73                        searchRequest.setExtraRequestData(legacy
     74                                        ? SRUCQL.SEARCH_CORPUS_HANDLE_LEGACY_PARAMETER
     75                                        : SRUCQL.SEARCH_CORPUS_HANDLE_PARAMETER,
    7776                                        corpus.getHandle());
    7877                }
  • SRUAggregator/trunk/src/main/resources/assets/js/main.js

    r5971 r5976  
    33"use strict";
    44
    5 var VERSION = "VERSION 2.0.0.α18";
     5var VERSION = "VERSION 2.0.0.α20";
     6var URLROOT = "/Aggregator-testing";
    67
    78var PT = React.PropTypes;
     
    1112
    1213var Main = React.createClass({displayName: 'Main',
     14        componentWillMount: function() {
     15                routeFromLocation(this);
     16        },
     17
    1318        getInitialState: function () {
    1419                return {
     
    6166        },
    6267
     68        toggleCollapse: function() {
     69                this.setState({navbarCollapse: !this.state.navbarCollapse});
     70        },
     71
    6372        renderAggregator: function() {
    6473                return React.createElement(AggregatorPage, {ajax: this.ajax, corpora: this.state.corpora, languageMap: this.state.languageMap});
     
    7079
    7180        renderAbout: function() {
    72                 return React.createElement(AboutPage, {statistics: this.statistics});
     81                return React.createElement(AboutPage, null);
    7382        },
    7483
     
    7786        },
    7887
    79         toggleCollapse: function() {
    80                 this.setState({navbarCollapse: !this.state.navbarCollapse});
    81         },
    82 
    83         about: function(e) {
    84                 this.setState({navbarPageFn: this.renderAbout});
    85         },
    86         statistics: function(e) {
    87                 this.setState({navbarPageFn: this.renderStatistics});
    88         },
    89 
    90 
    91         setNavbarPageFn: function(pageFn) {
    92                 this.setState({navbarPageFn:pageFn});
    93         },
     88        getPageFns: function() {
     89                return {
     90                        '': this.renderAggregator,
     91                        'help': this.renderHelp,
     92                        'about': this.renderAbout,
     93                        'stats': this.renderStatistics,
     94                };
     95        },
     96
     97        gotoPage: function(doPushHistory, pageFnName) {
     98                var pageFn = this.getPageFns()[pageFnName];
     99                if (this.state.navbarPageFn !== pageFn) {
     100                        if (doPushHistory) {
     101                                window.history.pushState({page:pageFnName}, '', URLROOT+"/"+pageFnName);
     102                        }
     103                        this.setState({navbarPageFn: pageFn});
     104                        console.log("new page: " + document.location + ", name: " + pageFnName);
     105                }
     106        },
     107
     108        toAggregator: function(doPushHistory) { this.gotoPage(doPushHistory, ''); },
     109        toHelp: function(doPushHistory) { this.gotoPage(doPushHistory, 'help'); },
     110        toAbout: function(doPushHistory) { this.gotoPage(doPushHistory, 'about'); },
     111        toStatistics: function(doPushHistory) { this.gotoPage(doPushHistory, 'stats'); },
    94112
    95113        renderCollapsible: function() {
     
    99117                                React.createElement("ul", {className: "nav navbar-nav"},
    100118                                        React.createElement("li", {className: this.state.navbarPageFn === this.renderAggregator ? "active":""},
    101                                                 React.createElement("a", {className: "link", tabIndex: "-1",
    102                                                         onClick: this.setNavbarPageFn.bind(this, this.renderAggregator)}, "Aggregator")
     119                                                React.createElement("a", {className: "link", tabIndex: "-1", onClick: this.toAggregator.bind(this, true)}, "Aggregator")
    103120                                        ),
    104121                                        React.createElement("li", {className: this.state.navbarPageFn === this.renderHelp ? "active":""},
    105                                                 React.createElement("a", {className: "link", tabIndex: "-1",
    106                                                         onClick: this.setNavbarPageFn.bind(this, this.renderHelp)}, "Help")
     122                                                React.createElement("a", {className: "link", tabIndex: "-1", onClick: this.toHelp.bind(this, true)}, "Help")
    107123                                        )
    108124                                ),
     
    154170
    155171
    156 
    157172var StatisticsPage = React.createClass({displayName: 'StatisticsPage',
    158173        propTypes: {
     
    162177        getInitialState: function () {
    163178                return {
    164                         searchStats: {},
    165                         lastScanStats: {},
     179                        stats: {},
     180                        activeTab: 0,
     181                        // searchStats: {},
     182                        // lastScanStats: {},
    166183                };
    167184        },
     
    175192                        url: 'rest/statistics',
    176193                        success: function(json, textStatus, jqXHR) {
    177                                 this.setState({
    178                                         searchStats: json.searchStats,
    179                                         lastScanStats: json.lastScanStats,
    180                                 });
     194                                this.setState({stats: json});
    181195                                console.log("stats:", json);
    182196                        }.bind(this),
     
    205219                                                        colls.length, " root collection(s):",
    206220                                                        React.createElement("ul", {className: "list-unstyled", style: {marginLeft:40}},
    207                                                                  colls.map(function(name) { return React.createElement("div", null, name); })
     221                                                                 colls.map(function(name, i) { return React.createElement("div", {key: i}, name); })
    208222                                                        )
    209223                                                )
     
    215229                return  React.createElement("div", {key: d.diagnostic.uri},
    216230                                        React.createElement("div", {className: "inline alert alert-warning"},
    217                                                 React.createElement("div", null, "Diagnostic: ", d.diagnostic.message, ": ", d.diagnostic.diagnostic),
     231                                                React.createElement("div", null,
     232                                                         d.counter <= 1 ? false :
     233                                                                React.createElement("div", {className: "inline", style: {margin:"5px 5px 5px 5px"}},
     234                                                                        React.createElement("span", {className: "badge", style: {backgroundColor:'#ae7241'}}, "x ", d.counter)
     235                                                                ),
     236                                                       
     237                                                        "Diagnostic: ", d.diagnostic.message, ": ", d.diagnostic.diagnostic
     238                                                ),
    218239                                                React.createElement("div", null, "Context: ", React.createElement("a", {href: d.context}, d.context))
    219                                         ),
    220                                         " ",
    221                                         React.createElement("div", {className: "inline"}, React.createElement("span", {className: "badge"}, "x ", d.counter))
     240                                        )
    222241                                );
    223242        },
     
    227246                return  React.createElement("div", {key: xc.message},
    228247                                        React.createElement("div", {className: "inline alert alert-danger", role: "alert"},
    229                                                 React.createElement("div", null, "Exception: ", xc.message),
     248                                                React.createElement("div", null,
     249                                                         e.counter <= 1 ? false :
     250                                                                React.createElement("div", {className: "inline", style: {margin:"5px 5px 5px 5px"}},
     251                                                                        React.createElement("span", {className: "badge", style: {backgroundColor:'#c94442'}}, "x ", e.counter, " ")
     252                                                                ),
     253                                                       
     254                                                        "Exception: ", xc.message
     255                                                ),
    230256                                                React.createElement("div", null, "Context: ", React.createElement("a", {href: e.context}, e.context)),
    231257                                                 xc.cause ? React.createElement("div", null, "Caused by: ", xc.cause) : false
    232                                         ),
    233                                         " ",
    234                                         React.createElement("div", {className: "inline"}, React.createElement("span", {className: "badge"}, "x ", e.counter))
     258                                        )
    235259                                );
    236260        },
     
    240264                var errors = _.values(stat.errors);
    241265                var diagnostics = _.values(stat.diagnostics);
    242                 return React.createElement("div", {style: {marginTop:10}},
     266                return React.createElement("div", {style: {marginTop:10}, key: endpoint[0]},
    243267                                        React.createElement("ul", {className: "list-inline list-unstyled", style: {marginBottom:0}},
    244268                                                React.createElement("li", null,
     
    270294
    271295        renderInstitution: function(isScan, inst) {
    272                 return  React.createElement("div", {style: {marginBottom:30}},
     296                return  React.createElement("div", {style: {marginBottom:30}, key: inst[0]},
    273297                                        React.createElement("h4", null, inst[0]),
    274298                                        React.createElement("div", {style: {marginLeft:20}}, " ", _.pairs(inst[1]).map(this.renderEndpoint.bind(this, isScan)) )
     
    276300        },
    277301
    278         renderStatistics: function(isScan, stats) {
    279                 return  React.createElement("div", {className: "container"},
     302        renderStatistics: function(stats) {
     303                return  React.createElement("div", {className: "container statistics", style: {marginTop:20}},
    280304                                        React.createElement("ul", {className: "list-inline list-unstyled"},
    281305                                                 stats.maxConcurrentScanRequestsPerEndpoint ?
     
    291315                                                React.createElement("li", null, "timeout:", " ", React.createElement("kbd", null, stats.timeout, " seconds"))
    292316                                        ),
    293                                         React.createElement("div", null, " ",  _.pairs(stats.institutions).map(this.renderInstitution.bind(this, isScan)), " ")
     317                                        React.createElement("div", null, " ",  _.pairs(stats.institutions).map(this.renderInstitution.bind(this, stats.isScan)), " ")
    294318                                )
    295319                                 ;
     320        },
     321
     322        setTab: function(idx) {
     323                this.setState({activeTab:idx});
    296324        },
    297325
     
    299327                return  (
    300328                        React.createElement("div", null,
    301                                 React.createElement("div", {className: "top-gap statistics"},
     329                                React.createElement("div", {className: "top-gap"},
    302330                                        React.createElement("h1", null, "Statistics"),
    303                                         React.createElement("h2", null, "Last scan"),
    304                                         this.renderStatistics(true, this.state.lastScanStats),
    305                                         React.createElement("h2", null, "Searches since last scan"),
    306                                         this.renderStatistics(false, this.state.searchStats)
     331                                        React.createElement("p", null),
     332                                        React.createElement("div", {role: "tabpanel"},
     333                                                React.createElement("ul", {className: "nav nav-tabs", role: "tablist"},
     334                                                         _.pairs(this.state.stats).map(function(st, idx){
     335                                                                        var classname = idx === this.state.activeTab ? "active":"";
     336                                                                        return  React.createElement("li", {role: "presentation", className: classname, key: st[0]},
     337                                                                                                React.createElement("a", {href: "#", role: "tab", onClick: this.setTab.bind(this, idx)}, st[0])
     338                                                                                        );
     339                                                                }.bind(this))
     340                                                       
     341                                                ),
     342
     343                                                React.createElement("div", {className: "tab-content"},
     344                                                         _.pairs(this.state.stats).map(function(st, idx){
     345                                                                        var classname = idx === this.state.activeTab ? "tab-pane active" : "tab-pane";
     346                                                                        return  React.createElement("div", {role: "tabpanel", className: classname, key: st[0]},
     347                                                                                                this.renderStatistics(st[1])
     348                                                                                        );
     349                                                                }.bind(this))
     350                                                       
     351                                                )
     352                                        )
    307353                                )
    308354                        )
     
    358404
    359405var AboutPage = React.createClass({displayName: 'AboutPage',
    360         propTypes: {
    361                 statistics: PT.func.isRequired,
    362         },
    363 
    364406        render: function() {
    365407                return  React.createElement("div", null,
     
    421463
    422464                                                React.createElement("h3", null, "Statistics"),
    423                                                 React.createElement("button", {type: "button", className: "btn btn-default btn-lg", onClick: this.props.statistics},
     465                                                React.createElement("button", {type: "button", className: "btn btn-default btn-lg", onClick: function() {main.toStatistics(true);}},
    424466                                                        React.createElement("span", {className: "glyphicon glyphicon-cog", 'aria-hidden': "true"}, " "),
    425467                                                        "View server log"
     
    431473
    432474var Footer = React.createClass({displayName: 'Footer',
    433         about: function(e) {
    434                 main.about();
     475        toAbout: function(e) {
     476                main.toAbout(true);
    435477                e.preventDefault();
    436478                e.stopPropagation();
     
    441483                        React.createElement("div", {className: "container"},
    442484                                React.createElement("div", {id: "CLARIN_footer_left"},
    443                                                 React.createElement("a", {title: "about", href: "#", onClick: this.about},
     485                                                React.createElement("a", {title: "about", href: "about", onClick: this.toAbout},
    444486                                                React.createElement("span", {className: "glyphicon glyphicon-info-sign"}),
    445487                                                React.createElement("span", null, VERSION)
     
    462504});
    463505
     506function endsWith(str, suffix) {
     507    return str.indexOf(suffix, str.length - suffix.length) !== -1;
     508}
     509
     510var routeFromLocation = function(com) {
     511        var path = window.location.pathname.split('/');
     512        if (path.length === 3) {
     513                var p = path[2];
     514                if (p === 'help') {
     515                        com.toHelp(false);
     516                } else if (p === 'about') {
     517                        com.toAbout(false);
     518                } else if (p === 'stats') {
     519                        com.toStatistics(false);
     520                } else {
     521                        com.toAggregator(false);
     522                }
     523        } else {
     524                com.toAggregator(false);
     525        }
     526};
     527
    464528var main = React.render(React.createElement(Main, null),  document.getElementById('body'));
    465529React.render(React.createElement(Footer, null), document.getElementById('footer') );
    466530
     531window.onpopstate = function(event) {
     532        console.log("popped location: " + document.location + ", state: " + JSON.stringify(event.state));
     533        routeFromLocation(main);
     534};
     535
     536window.main = main;
     537
    467538})();
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
     549
     550
     551
     552
     553
     554
     555
     556
     557
  • SRUAggregator/trunk/src/main/resources/assets/js/main.jsx

    r5971 r5976  
    33"use strict";
    44
    5 var VERSION = "VERSION 2.0.0.α19";
     5var VERSION = "VERSION 2.0.0.α20";
     6var URLROOT = "/Aggregator-testing";
    67
    78var PT = React.PropTypes;
     
    1112
    1213var Main = React.createClass({
     14        componentWillMount: function() {
     15                routeFromLocation(this);
     16        },
     17
    1318        getInitialState: function () {
    1419                return {
     
    6166        },
    6267
     68        toggleCollapse: function() {
     69                this.setState({navbarCollapse: !this.state.navbarCollapse});
     70        },
     71
    6372        renderAggregator: function() {
    6473                return <AggregatorPage ajax={this.ajax} corpora={this.state.corpora} languageMap={this.state.languageMap} />;
     
    7079
    7180        renderAbout: function() {
    72                 return <AboutPage statistics={this.statistics}/>;
     81                return <AboutPage/>;
    7382        },
    7483
     
    7786        },
    7887
    79         toggleCollapse: function() {
    80                 this.setState({navbarCollapse: !this.state.navbarCollapse});
    81         },
    82 
    83         about: function(e) {
    84                 this.setState({navbarPageFn: this.renderAbout});
    85         },
    86         statistics: function(e) {
    87                 this.setState({navbarPageFn: this.renderStatistics});
    88         },
    89 
    90 
    91         setNavbarPageFn: function(pageFn) {
    92                 this.setState({navbarPageFn:pageFn});
    93         },
     88        getPageFns: function() {
     89                return {
     90                        '': this.renderAggregator,
     91                        'help': this.renderHelp,
     92                        'about': this.renderAbout,
     93                        'stats': this.renderStatistics,
     94                };
     95        },
     96
     97        gotoPage: function(doPushHistory, pageFnName) {
     98                var pageFn = this.getPageFns()[pageFnName];
     99                if (this.state.navbarPageFn !== pageFn) {
     100                        if (doPushHistory) {
     101                                window.history.pushState({page:pageFnName}, '', URLROOT+"/"+pageFnName);
     102                        }
     103                        this.setState({navbarPageFn: pageFn});
     104                        console.log("new page: " + document.location + ", name: " + pageFnName);
     105                }
     106        },
     107
     108        toAggregator: function(doPushHistory) { this.gotoPage(doPushHistory, ''); },
     109        toHelp: function(doPushHistory) { this.gotoPage(doPushHistory, 'help'); },
     110        toAbout: function(doPushHistory) { this.gotoPage(doPushHistory, 'about'); },
     111        toStatistics: function(doPushHistory) { this.gotoPage(doPushHistory, 'stats'); },
    94112
    95113        renderCollapsible: function() {
     
    99117                                <ul className="nav navbar-nav">
    100118                                        <li className={this.state.navbarPageFn === this.renderAggregator ? "active":""}>
    101                                                 <a className="link" tabIndex="-1"
    102                                                         onClick={this.setNavbarPageFn.bind(this, this.renderAggregator)}>Aggregator</a>
     119                                                <a className="link" tabIndex="-1" onClick={this.toAggregator.bind(this, true)}>Aggregator</a>
    103120                                        </li>
    104121                                        <li className={this.state.navbarPageFn === this.renderHelp ? "active":""}>
    105                                                 <a className="link" tabIndex="-1"
    106                                                         onClick={this.setNavbarPageFn.bind(this, this.renderHelp)}>Help</a>
     122                                                <a className="link" tabIndex="-1" onClick={this.toHelp.bind(this, true)}>Help</a>
    107123                                        </li>
    108124                                </ul>
     
    154170
    155171
    156 
    157172var StatisticsPage = React.createClass({
    158173        propTypes: {
     
    162177        getInitialState: function () {
    163178                return {
    164                         searchStats: {},
    165                         lastScanStats: {},
     179                        stats: {},
     180                        activeTab: 0,
     181                        // searchStats: {},
     182                        // lastScanStats: {},
    166183                };
    167184        },
     
    175192                        url: 'rest/statistics',
    176193                        success: function(json, textStatus, jqXHR) {
    177                                 this.setState({
    178                                         searchStats: json.searchStats,
    179                                         lastScanStats: json.lastScanStats,
    180                                 });
     194                                this.setState({stats: json});
    181195                                console.log("stats:", json);
    182196                        }.bind(this),
     
    205219                                                        {colls.length} root collection(s):
    206220                                                        <ul className='list-unstyled' style={{marginLeft:40}}>
    207                                                                 { colls.map(function(name) { return <div>{name}</div>; }) }
     221                                                                { colls.map(function(name, i) { return <div key={i}>{name}</div>; }) }
    208222                                                        </ul>
    209223                                                </div>
     
    215229                return  <div key={d.diagnostic.uri}>
    216230                                        <div className="inline alert alert-warning">
    217                                                 <div>Diagnostic: {d.diagnostic.message}: {d.diagnostic.diagnostic}</div>
     231                                                <div>
     232                                                        { d.counter <= 1 ? false :
     233                                                                <div className="inline" style={{margin:"5px 5px 5px 5px"}}>
     234                                                                        <span className="badge" style={{backgroundColor:'#ae7241'}}>x {d.counter}</span>
     235                                                                </div>
     236                                                        }
     237                                                        Diagnostic: {d.diagnostic.message}: {d.diagnostic.diagnostic}
     238                                                </div>
    218239                                                <div>Context: <a href={d.context}>{d.context}</a></div>
    219240                                        </div>
    220                                         {" "}
    221                                         <div className="inline"><span className="badge">x {d.counter}</span></div>
    222241                                </div>;
    223242        },
     
    227246                return  <div key={xc.message}>
    228247                                        <div className="inline alert alert-danger" role="alert">
    229                                                 <div>Exception: {xc.message}</div>
     248                                                <div>
     249                                                        { e.counter <= 1 ? false :
     250                                                                <div className="inline" style={{margin:"5px 5px 5px 5px"}}>
     251                                                                        <span className="badge" style={{backgroundColor:'#c94442'}}>x {e.counter} </span>
     252                                                                </div>
     253                                                        }
     254                                                        Exception: {xc.message}
     255                                                </div>
    230256                                                <div>Context: <a href={e.context}>{e.context}</a></div>
    231257                                                { xc.cause ? <div>Caused by: {xc.cause}</div> : false}
    232258                                        </div>
    233                                         {" "}
    234                                         <div className="inline"><span className="badge">x {e.counter}</span></div>
    235259                                </div>;
    236260        },
     
    240264                var errors = _.values(stat.errors);
    241265                var diagnostics = _.values(stat.diagnostics);
    242                 return <div style={{marginTop:10}}>
     266                return <div style={{marginTop:10}} key={endpoint[0]}>
    243267                                        <ul className='list-inline list-unstyled' style={{marginBottom:0}}>
    244268                                                <li>
     
    270294
    271295        renderInstitution: function(isScan, inst) {
    272                 return  <div style={{marginBottom:30}}>
     296                return  <div style={{marginBottom:30}} key={inst[0]}>
    273297                                        <h4>{inst[0]}</h4>
    274298                                        <div style={{marginLeft:20}}> {_.pairs(inst[1]).map(this.renderEndpoint.bind(this, isScan)) }</div>
     
    276300        },
    277301
    278         renderStatistics: function(isScan, stats) {
    279                 return  <div className="container">
     302        renderStatistics: function(stats) {
     303                return  <div className="container statistics" style={{marginTop:20}}>
    280304                                        <ul className='list-inline list-unstyled'>
    281305                                                { stats.maxConcurrentScanRequestsPerEndpoint ?
     
    291315                                                <li>timeout:{" "}<kbd>{stats.timeout} seconds</kbd></li>
    292316                                        </ul>
    293                                         <div> { _.pairs(stats.institutions).map(this.renderInstitution.bind(this, isScan)) } </div>
     317                                        <div> { _.pairs(stats.institutions).map(this.renderInstitution.bind(this, stats.isScan)) } </div>
    294318                                </div>
    295319                                 ;
     320        },
     321
     322        setTab: function(idx) {
     323                this.setState({activeTab:idx});
    296324        },
    297325
     
    299327                return  (
    300328                        <div>
    301                                 <div className="top-gap statistics">
     329                                <div className="top-gap">
    302330                                        <h1>Statistics</h1>
    303                                         <h2>Last scan</h2>
    304                                         {this.renderStatistics(true, this.state.lastScanStats)}
    305                                         <h2>Searches since last scan</h2>
    306                                         {this.renderStatistics(false, this.state.searchStats)}
     331                                        <p/>
     332                                        <div role="tabpanel">
     333                                                <ul className="nav nav-tabs" role="tablist">
     334                                                        { _.pairs(this.state.stats).map(function(st, idx){
     335                                                                        var classname = idx === this.state.activeTab ? "active":"";
     336                                                                        return  <li role="presentation" className={classname} key={st[0]}>
     337                                                                                                <a href="#" role="tab" onClick={this.setTab.bind(this, idx)}>{st[0]}</a>
     338                                                                                        </li>;
     339                                                                }.bind(this))
     340                                                        }
     341                                                </ul>
     342
     343                                                <div className="tab-content">
     344                                                        { _.pairs(this.state.stats).map(function(st, idx){
     345                                                                        var classname = idx === this.state.activeTab ? "tab-pane active" : "tab-pane";
     346                                                                        return  <div role="tabpanel" className={classname} key={st[0]}>
     347                                                                                                {this.renderStatistics(st[1])}
     348                                                                                        </div>;
     349                                                                }.bind(this))
     350                                                        }
     351                                                </div>
     352                                        </div>
    307353                                </div>
    308354                        </div>
     
    358404
    359405var AboutPage = React.createClass({
    360         propTypes: {
    361                 statistics: PT.func.isRequired,
    362         },
    363 
    364406        render: function() {
    365407                return  <div>
     
    421463
    422464                                                <h3>Statistics</h3>
    423                                                 <button type="button" className="btn btn-default btn-lg" onClick={this.props.statistics} >
     465                                                <button type="button" className="btn btn-default btn-lg" onClick={function() {main.toStatistics(true);}} >
    424466                                                        <span className="glyphicon glyphicon-cog" aria-hidden="true"> </span>
    425467                                                        View server log
     
    431473
    432474var Footer = React.createClass({
    433         about: function(e) {
    434                 main.about();
     475        toAbout: function(e) {
     476                main.toAbout(true);
    435477                e.preventDefault();
    436478                e.stopPropagation();
     
    441483                        <div className="container">
    442484                                <div id="CLARIN_footer_left">
    443                                                 <a title="about" href="#" onClick={this.about}>
     485                                                <a title="about" href="about" onClick={this.toAbout}>
    444486                                                <span className="glyphicon glyphicon-info-sign"></span>
    445487                                                <span>{VERSION}</span>
     
    462504});
    463505
     506function endsWith(str, suffix) {
     507    return str.indexOf(suffix, str.length - suffix.length) !== -1;
     508}
     509
     510var routeFromLocation = function(com) {
     511        var path = window.location.pathname.split('/');
     512        if (path.length === 3) {
     513                var p = path[2];
     514                if (p === 'help') {
     515                        com.toHelp(false);
     516                } else if (p === 'about') {
     517                        com.toAbout(false);
     518                } else if (p === 'stats') {
     519                        com.toStatistics(false);
     520                } else {
     521                        com.toAggregator(false);
     522                }
     523        } else {
     524                com.toAggregator(false);
     525        }
     526};
     527
    464528var main = React.render(<Main />,  document.getElementById('body'));
    465529React.render(<Footer />, document.getElementById('footer') );
    466530
     531window.onpopstate = function(event) {
     532        console.log("popped location: " + document.location + ", state: " + JSON.stringify(event.state));
     533        routeFromLocation(main);
     534};
     535
     536window.main = main;
     537
    467538})();
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
     549
     550
     551
     552
     553
     554
     555
     556
     557
  • SRUAggregator/trunk/src/main/resources/assets/lib/react-router.min.js

    r5919 r5976  
    1 !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.ReactRouter=e()}}(function(){var define;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module){var LocationActions={PUSH:"push",REPLACE:"replace",POP:"pop"};module.exports=LocationActions},{}],2:[function(_dereq_,module){var LocationActions=_dereq_("../actions/LocationActions"),ImitateBrowserBehavior={updateScrollPosition:function(position,actionType){switch(actionType){case LocationActions.PUSH:case LocationActions.REPLACE:window.scrollTo(0,0);break;case LocationActions.POP:position?window.scrollTo(position.x,position.y):window.scrollTo(0,0)}}};module.exports=ImitateBrowserBehavior},{"../actions/LocationActions":1}],3:[function(_dereq_,module){var ScrollToTopBehavior={updateScrollPosition:function(){window.scrollTo(0,0)}};module.exports=ScrollToTopBehavior},{}],4:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,FakeNode=_dereq_("../mixins/FakeNode"),PropTypes=_dereq_("../utils/PropTypes"),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){function isLeftClickEvent(event){return 0===event.button}function isModifiedEvent(event){return!!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,classSet=_dereq_("react/lib/cx"),assign=_dereq_("react/lib/Object.assign"),Navigation=_dereq_("../mixins/Navigation"),State=_dereq_("../mixins/State"),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 clickResult,allowTransition=!0;this.props.onClick&&(clickResult=this.props.onClick(event)),!isModifiedEvent(event)&&isLeftClickEvent(event)&&((clickResult===!1||event.defaultPrevented===!0)&&(allowTransition=!1),event.preventDefault(),allowTransition&&this.transitionTo(this.props.to,this.props.params,this.props.query))},getHref:function(){return this.makeHref(this.props.to,this.props.params,this.props.query)},getClassName:function(){var classNames={};return this.props.className&&(classNames[this.props.className]=!0),this.isActive(this.props.to,this.props.params,this.props.query)&&(classNames[this.props.activeClassName]=!0),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){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,FakeNode=_dereq_("../mixins/FakeNode"),PropTypes=_dereq_("../utils/PropTypes"),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){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,FakeNode=_dereq_("../mixins/FakeNode"),PropTypes=_dereq_("../utils/PropTypes"),Redirect=React.createClass({displayName:"Redirect",mixins:[FakeNode],propTypes:{path:React.PropTypes.string,from:React.PropTypes.string,to:React.PropTypes.string,handler:PropTypes.falsy}});module.exports=Redirect},{"../mixins/FakeNode":14,"../utils/PropTypes":25}],8:[function(_dereq_,module){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,FakeNode=_dereq_("../mixins/FakeNode"),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){var React="undefined"!=typeof window?window.React:"undefined"!=typeof global?global.React:null,RouteHandlerMixin=_dereq_("../mixins/RouteHandler"),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){function getHashPath(){return Path.decode(window.location.href.split("#")[1]||"")}function ensureSlash(){var path=getHashPath();return"/"===path.charAt(0)?!0:(HashLocation.replace("/"+path),!1)}function notifyChange(type){type===LocationActions.PUSH&&(History.length+=1);var change={path:getHashPath(),type:type};_changeListeners.forEach(function(listener){listener(change)})}function onHashChange(){ensureSlash()&&(notifyChange(_actionType||LocationActions.POP),_actionType=null)}var _actionType,LocationActions=_dereq_("../actions/LocationActions"),History=_dereq_("../utils/History"),Path=_dereq_("../utils/Path"),_changeListeners=[],_isListening=!1,HashLocation={addChangeListener:function(listener){_changeListeners.push(listener),ensureSlash(),_isListening||(window.addEventListener?window.addEventListener("hashchange",onHashChange,!1):window.attachEvent("onhashchange",onHashChange),_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.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"<HashLocation>"}};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"<HistoryLocation>"}};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"<RefreshLocation>"}};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)&&paramsAreActive(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 <Route name="%s">',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 <Route path="%s"> 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;
    2 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,"<NotFoundRoute> must have a parent <Route>"),invariant(null==parentRoute.notFoundRoute,"You may not have more than one <NotFoundRoute> per <Route>"),parentRoute.notFoundRoute=route,null):type===DefaultRoute.type?(invariant(parentRoute,"<DefaultRoute> must have a parent <Route>"),invariant(null==parentRoute.defaultRoute,"You may not have more than one <DefaultRoute> per <Route>"),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))&&i<options.depth;)++i,Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g,""))||keys.push(segment[1]);return segment&&keys.push("["+key.slice(segment.index)+"]"),internals.parseObject(keys,val,options)}}},module.exports=function(str,options){if(""===str||null===str||"undefined"==typeof str)return{};options=options||{},options.delimiter="string"==typeof options.delimiter||Utils.isRegExp(options.delimiter)?options.delimiter:internals.delimiter,options.depth="number"==typeof options.depth?options.depth:internals.depth,options.arrayLimit="number"==typeof options.arrayLimit?options.arrayLimit:internals.arrayLimit,options.parameterLimit="number"==typeof options.parameterLimit?options.parameterLimit:internals.parameterLimit;for(var tempObj="string"==typeof str?internals.parseValues(str,options):str,obj={},keys=Object.keys(tempObj),i=0,il=keys.length;il>i;++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;nextIndex<arguments.length;nextIndex++){var nextSource=arguments[nextIndex];if(null!=nextSource){var from=Object(nextSource);for(var key in from)hasOwnProperty.call(from,key)&&(to[key]=from[key])}}return to}module.exports=assign},{}],41:[function(_dereq_,module){function cx(classNames){return"object"==typeof classNames?Object.keys(classNames).filter(function(className){return classNames[className]}).join(" "):Array.prototype.join.call(arguments," ")}module.exports=cx},{}],42:[function(_dereq_,module){function makeEmptyFunction(arg){return function(){return arg}}function emptyFunction(){}emptyFunction.thatReturns=makeEmptyFunction,emptyFunction.thatReturnsFalse=makeEmptyFunction(!1),emptyFunction.thatReturnsTrue=makeEmptyFunction(!0),emptyFunction.thatReturnsNull=makeEmptyFunction(null),emptyFunction.thatReturnsThis=function(){return this},emptyFunction.thatReturnsArgument=function(arg){return arg},module.exports=emptyFunction},{}],43:[function(_dereq_,module){"use strict";var invariant=function(condition,format,a,b,c,d,e,f){if(!condition){var error;if(void 0===format)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],argIndex=0;error=new Error("Invariant Violation: "+format.replace(/%s/g,function(){return args[argIndex++]}))}throw error.framesToPop=1,error}};module.exports=invariant},{}],44:[function(_dereq_,module){"use strict";var emptyFunction=_dereq_("./emptyFunction"),warning=emptyFunction;module.exports=warning},{"./emptyFunction":42}],45:[function(_dereq_,module){!function(define){"use strict";define(function(_dereq_){var makePromise=_dereq_("./makePromise"),Scheduler=_dereq_("./Scheduler"),async=_dereq_("./async");return makePromise({scheduler:new Scheduler(async)})})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory(_dereq_)})},{"./Scheduler":47,"./async":48,"./makePromise":49}],46:[function(_dereq_,module){!function(define){"use strict";define(function(){function Queue(capacityPow2){this.head=this.tail=this.length=0,this.buffer=new Array(1<<capacityPow2)}return Queue.prototype.push=function(x){return this.length===this.buffer.length&&this._ensureCapacity(2*this.length),this.buffer[this.tail]=x,this.tail=this.tail+1&this.buffer.length-1,++this.length,this.length},Queue.prototype.shift=function(){var x=this.buffer[this.head];return this.buffer[this.head]=void 0,this.head=this.head+1&this.buffer.length-1,--this.length,x},Queue.prototype._ensureCapacity=function(capacity){var len,head=this.head,buffer=this.buffer,newBuffer=new Array(capacity),i=0;if(0===head)for(len=this.length;len>i;++i)newBuffer[i]=buffer[i];else{for(capacity=buffer.length,len=this.tail;capacity>head;++i,++head)newBuffer[i]=buffer[head];for(head=0;len>head;++i,++head)newBuffer[i]=buffer[head]}this.buffer=newBuffer,this.head=0,this.tail=this.length},Queue})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory()})},{}],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;i<promises.length;++i)if(x=promises[i],void 0!==x||i in promises)if(maybeThenable(x))if(h=getHandlerMaybeThenable(x),s=h.state(),0===s)h.fold(settleAt,i,results,resolver);else{if(!(s>0)){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;i<promises.length;++i)x=promises[i],maybeThenable(x)&&(h=getHandlerMaybeThenable(x),h!==rejectedHandler&&h.visit(h,void 0,h._unreport))}function race(promises){if(Object(promises)===promises&&0===promises.length)return never();var i,x,h=new Pending;for(i=0;i<promises.length;++i)x=promises[i],void 0!==x&&i in promises&&getHandler(x).visit(h,h.resolve,h.reject);return new Promise(Handler,h)}function getHandler(x){return isPromise(x)?x._handler.join():maybeThenable(x)?getHandlerUntrusted(x):new Fulfilled(x)}function getHandlerMaybeThenable(x){return isPromise(x)?x._handler.join():getHandlerUntrusted(x)}function getHandlerUntrusted(x){try{var untrustedThen=x.then;return"function"==typeof untrustedThen?new Thenable(untrustedThen,x):new Fulfilled(x)}catch(e){return new Rejected(e)}}function Handler(){}function FailIfRejected(){}function Pending(receiver,inheritedContext){Promise.createContext(this,inheritedContext),this.consumers=void 0,this.receiver=receiver,this.handler=void 0,this.resolved=!1}function Async(handler){this.handler=handler}function Thenable(then,thenable){Pending.call(this),tasks.enqueue(new AssimilateTask(then,thenable,this))}function Fulfilled(x){Promise.createContext(this),this.value=x}function Rejected(x){Promise.createContext(this),this.id=++errorId,this.value=x,this.handled=!1,this.reported=!1,this._report()}function ReportTask(rejection,context){this.rejection=rejection,this.context=context}function UnreportTask(rejection){this.rejection=rejection}function cycle(){return new Rejected(new TypeError("Promise cycle"))}function ContinuationTask(continuation,handler){this.continuation=continuation,this.handler=handler}function ProgressTask(value,handler){this.handler=handler,this.value=value}function AssimilateTask(then,thenable,resolver){this._then=then,this.thenable=thenable,this.resolver=resolver}function tryAssimilate(then,thenable,resolve,reject,notify){try{then.call(thenable,resolve,reject,notify)}catch(e){reject(e)}}function isPromise(x){return x instanceof Promise}function maybeThenable(x){return("object"==typeof x||"function"==typeof x)&&null!==x}function runContinuation1(f,h,receiver,next){return"function"!=typeof f?next.become(h):(Promise.enterContext(h),tryCatchReject(f,h.value,receiver,next),void Promise.exitContext())}function runContinuation3(f,x,h,receiver,next){return"function"!=typeof f?next.become(h):(Promise.enterContext(h),tryCatchReject3(f,x,h.value,receiver,next),void Promise.exitContext())}function runNotify(f,x,h,receiver,next){return"function"!=typeof f?next.notify(x):(Promise.enterContext(h),tryCatchReturn(f,x,receiver,next),void Promise.exitContext())}function tryCatchReject(f,x,thisArg,next){try{next.become(getHandler(f.call(thisArg,x)))}catch(e){next.become(new Rejected(e))}}function tryCatchReject3(f,x,y,thisArg,next){try{f.call(thisArg,x,y,next)}catch(e){next.become(new Rejected(e))}}function tryCatchReturn(f,x,thisArg,next){try{next.notify(f.call(thisArg,x))}catch(e){next.notify(e)}}function inherit(Parent,Child){Child.prototype=objectCreate(Parent.prototype),Child.prototype.constructor=Child}function noop(){}var tasks=environment.scheduler,objectCreate=Object.create||function(proto){function Child(){}return Child.prototype=proto,new Child};Promise.resolve=resolve,Promise.reject=reject,Promise.never=never,Promise._defer=defer,Promise._handler=getHandler,Promise.prototype.then=function(onFulfilled,onRejected){var parent=this._handler,state=parent.join().state();if("function"!=typeof onFulfilled&&state>0||"function"!=typeof onRejected&&0>state)return new this.constructor(Handler,parent);var p=this._beget(),child=p._handler;return parent.chain(child,parent.receiver,onFulfilled,onRejected,arguments.length>2?arguments[2]:void 0),p},Promise.prototype["catch"]=function(onRejected){return this.then(void 0,onRejected)},Promise.prototype._beget=function(){var parent=this._handler,child=new Pending(parent.receiver,parent.join().context);return new this.constructor(Handler,child)},Promise.all=all,Promise.race=race,Handler.prototype.when=Handler.prototype.become=Handler.prototype.notify=Handler.prototype.fail=Handler.prototype._unreport=Handler.prototype._report=noop,Handler.prototype._state=0,Handler.prototype.state=function(){return this._state},Handler.prototype.join=function(){for(var h=this;void 0!==h.handler;)h=h.handler;return h},Handler.prototype.chain=function(to,receiver,fulfilled,rejected,progress){this.when({resolver:to,receiver:receiver,fulfilled:fulfilled,rejected:rejected,progress:progress})},Handler.prototype.visit=function(receiver,fulfilled,rejected,progress){this.chain(failIfRejected,receiver,fulfilled,rejected,progress)},Handler.prototype.fold=function(f,z,c,to){this.visit(to,function(x){f.call(c,z,x,this)},to.reject,to.notify)},inherit(Handler,FailIfRejected),FailIfRejected.prototype.become=function(h){h.fail()};var failIfRejected=new FailIfRejected;inherit(Handler,Pending),Pending.prototype._state=0,Pending.prototype.resolve=function(x){this.become(getHandler(x))},Pending.prototype.reject=function(x){this.resolved||this.become(new Rejected(x))},Pending.prototype.join=function(){if(!this.resolved)return this;for(var h=this;void 0!==h.handler;)if(h=h.handler,h===this)return this.handler=cycle();return h},Pending.prototype.run=function(){var q=this.consumers,handler=this.join();this.consumers=void 0;for(var i=0;i<q.length;++i)handler.when(q[i])},Pending.prototype.become=function(handler){this.resolved||(this.resolved=!0,this.handler=handler,void 0!==this.consumers&&tasks.enqueue(this),void 0!==this.context&&handler._report(this.context))},Pending.prototype.when=function(continuation){this.resolved?tasks.enqueue(new ContinuationTask(continuation,this.handler)):void 0===this.consumers?this.consumers=[continuation]:this.consumers.push(continuation)},Pending.prototype.notify=function(x){this.resolved||tasks.enqueue(new ProgressTask(x,this))},Pending.prototype.fail=function(context){var c="undefined"==typeof context?this.context:context;this.resolved&&this.handler.join().fail(c)},Pending.prototype._report=function(context){this.resolved&&this.handler.join()._report(context)},Pending.prototype._unreport=function(){this.resolved&&this.handler.join()._unreport()},inherit(Handler,Async),Async.prototype.when=function(continuation){tasks.enqueue(new ContinuationTask(continuation,this))},Async.prototype._report=function(context){this.join()._report(context)},Async.prototype._unreport=function(){this.join()._unreport()},inherit(Pending,Thenable),inherit(Handler,Fulfilled),Fulfilled.prototype._state=1,Fulfilled.prototype.fold=function(f,z,c,to){runContinuation3(f,z,this,c,to)},Fulfilled.prototype.when=function(cont){runContinuation1(cont.fulfilled,this,cont.receiver,cont.resolver)};var errorId=0;inherit(Handler,Rejected),Rejected.prototype._state=-1,Rejected.prototype.fold=function(f,z,c,to){to.become(this)},Rejected.prototype.when=function(cont){"function"==typeof cont.rejected&&this._unreport(),runContinuation1(cont.rejected,this,cont.receiver,cont.resolver)},Rejected.prototype._report=function(context){tasks.afterQueue(new ReportTask(this,context))},Rejected.prototype._unreport=function(){this.handled=!0,tasks.afterQueue(new UnreportTask(this))},Rejected.prototype.fail=function(context){Promise.onFatalRejection(this,void 0===context?this.context:context)},ReportTask.prototype.run=function(){this.rejection.handled||(this.rejection.reported=!0,Promise.onPotentiallyUnhandledRejection(this.rejection,this.context))},UnreportTask.prototype.run=function(){this.rejection.reported&&Promise.onPotentiallyUnhandledRejectionHandled(this.rejection)},Promise.createContext=Promise.enterContext=Promise.exitContext=Promise.onPotentiallyUnhandledRejection=Promise.onPotentiallyUnhandledRejectionHandled=Promise.onFatalRejection=noop;var foreverPendingHandler=new Handler,foreverPendingPromise=new Promise(Handler,foreverPendingHandler);return ContinuationTask.prototype.run=function(){this.handler.join().when(this.continuation)},ProgressTask.prototype.run=function(){var q=this.handler.consumers;if(void 0!==q)for(var c,i=0;i<q.length;++i)c=q[i],runNotify(c.progress,this.value,this.handler,c.receiver,c.resolver)},AssimilateTask.prototype.run=function(){function _resolve(x){h.resolve(x)}function _reject(x){h.reject(x)}function _notify(x){h.notify(x)}var h=this.resolver;tryAssimilate(this._then,this.thenable,_resolve,_reject,_notify)},Promise}})}("function"==typeof define&&define.amd?define:function(factory){module.exports=factory()})},{}]},{},[10])(10)});
     1!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("react")):"function"==typeof define&&define.amd?define(["react"],e):"object"==typeof exports?exports.ReactRouter=e(require("react")):t.ReactRouter=e(t.React)}(this,function(t){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){e.DefaultRoute=n(1),e.Link=n(2),e.NotFoundRoute=n(3),e.Redirect=n(4),e.Route=n(5),e.RouteHandler=n(6),e.HashLocation=n(7),e.HistoryLocation=n(8),e.RefreshLocation=n(9),e.ImitateBrowserBehavior=n(10),e.ScrollToTopBehavior=n(11),e.History=n(12),e.Navigation=n(13),e.RouteHandlerMixin=n(14),e.State=n(15),e.create=n(16),e.run=n(17)},function(t,e,n){var r=n(18),o=n(19),i=n(20),a=r.createClass({displayName:"DefaultRoute",mixins:[o],propTypes:{name:i.string,path:i.falsy,children:i.falsy,handler:i.func.isRequired}});t.exports=a},function(t,e,n){function r(t){return 0===t.button}function o(t){return!!(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)}var i=n(18),a=n(32),s=n(33),u=n(13),c=n(15),l=n(20),h=i.createClass({displayName:"Link",mixins:[u,c],propTypes:{activeClassName:l.string.isRequired,to:l.string.isRequired,params:l.object,query:l.object,onClick:l.func},getDefaultProps:function(){return{activeClassName:"active"}},handleClick:function(t){var e,n=!0;this.props.onClick&&(e=this.props.onClick(t)),!o(t)&&r(t)&&((e===!1||t.defaultPrevented===!0)&&(n=!1),t.preventDefault(),n&&this.transitionTo(this.props.to,this.props.params,this.props.query))},getHref:function(){return this.makeHref(this.props.to,this.props.params,this.props.query)},getClassName:function(){var t={};return this.props.className&&(t[this.props.className]=!0),this.isActive(this.props.to,this.props.params,this.props.query)&&(t[this.props.activeClassName]=!0),a(t)},render:function(){var t=s({},this.props,{href:this.getHref(),className:this.getClassName(),onClick:this.handleClick});return i.DOM.a(t,this.props.children)}});t.exports=h},function(t,e,n){var r=n(18),o=n(19),i=n(20),a=r.createClass({displayName:"NotFoundRoute",mixins:[o],propTypes:{name:i.string,path:i.falsy,children:i.falsy,handler:i.func.isRequired}});t.exports=a},function(t,e,n){var r=n(18),o=n(19),i=n(20),a=r.createClass({displayName:"Redirect",mixins:[o],propTypes:{path:i.string,from:i.string,to:i.string,handler:i.falsy}});t.exports=a},function(t,e,n){var r=n(18),o=n(19),i=n(20),a=n(6),s=r.createClass({displayName:"Route",mixins:[o],propTypes:{name:i.string,path:i.string,handler:i.func,ignoreScrollBehavior:i.bool},getDefaultProps:function(){return{handler:a}}});t.exports=s},function(t,e,n){var r=n(18),o=n(14),i=r.createClass({displayName:"RouteHandler",mixins:[o],render:function(){return this.createChildRouteHandler()}});t.exports=i},function(t,e,n){function r(){return decodeURI(window.location.href.split("#")[1]||"")}function o(){var t=r();return"/"===t.charAt(0)?!0:(f.replace("/"+t),!1)}function i(t){t===u.PUSH&&(c.length+=1);var e={path:r(),type:t};l.forEach(function(t){t(e)})}function a(){o()&&(i(s||u.POP),s=null)}var s,u=n(21),c=n(12),l=[],h=!1,f={addChangeListener:function(t){l.push(t),o(),h||(window.addEventListener?window.addEventListener("hashchange",a,!1):window.attachEvent("onhashchange",a),h=!0)},removeChangeListener:function(t){l=l.filter(function(e){return e!==t}),0===l.length&&(window.removeEventListener?window.removeEventListener("hashchange",a,!1):window.removeEvent("onhashchange",a),h=!1)},push:function(t){s=u.PUSH,window.location.hash=encodeURI(t)},replace:function(t){s=u.REPLACE,window.location.replace(window.location.pathname+window.location.search+"#"+encodeURI(t))},pop:function(){s=u.POP,c.back()},getCurrentPath:r,toString:function(){return"<HashLocation>"}};t.exports=f},function(t,e,n){function r(){return decodeURI(window.location.pathname+window.location.search)}function o(t){var e={path:r(),type:t};u.forEach(function(t){t(e)})}function i(){o(a.POP)}var a=n(21),s=n(12),u=[],c=!1,l={addChangeListener:function(t){u.push(t),c||(window.addEventListener?window.addEventListener("popstate",i,!1):window.attachEvent("popstate",i),c=!0)},removeChangeListener:function(t){u=u.filter(function(e){return e!==t}),0===u.length&&(window.addEventListener?window.removeEventListener("popstate",i):window.removeEvent("popstate",i),c=!1)},push:function(t){window.history.pushState({path:t},"",encodeURI(t)),s.length+=1,o(a.PUSH)},replace:function(t){window.history.replaceState({path:t},"",encodeURI(t)),o(a.REPLACE)},pop:s.back,getCurrentPath:r,toString:function(){return"<HistoryLocation>"}};t.exports=l},function(t,e,n){var r=n(8),o=n(12),i={push:function(t){window.location=encodeURI(t)},replace:function(t){window.location.replace(encodeURI(t))},pop:o.back,getCurrentPath:r.getCurrentPath,toString:function(){return"<RefreshLocation>"}};t.exports=i},function(t,e,n){var r=n(21),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(34),o=n(35).canUseDOM,i={length:1,back:function(){r(o,"Cannot use History.back without a DOM"),i.length-=1,window.history.back()}};t.exports=i},function(t,e,n){var r=n(20),o={contextTypes:{makePath:r.func.isRequired,makeHref:r.func.isRequired,transitionTo:r.func.isRequired,replaceWith:r.func.isRequired,goBack:r.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(18),o=n(33),i=n(20),a="__routeHandler__",s={contextTypes:{getRouteAtDepth:i.func.isRequired,setRouteComponentAtDepth:i.func.isRequired,routeHandlers:i.array.isRequired},childContextTypes:{routeHandlers:i.array.isRequired},getChildContext:function(){return{routeHandlers:this.context.routeHandlers.concat([this])}},componentDidMount:function(){this._updateRouteComponent()},componentDidUpdate:function(){this._updateRouteComponent()},componentWillUnmount:function(){this.context.setRouteComponentAtDepth(this.getRouteDepth(),null)},_updateRouteComponent:function(){this.context.setRouteComponentAtDepth(this.getRouteDepth(),this.refs[a])},getRouteDepth:function(){return this.context.routeHandlers.length},createChildRouteHandler:function(t){var e=this.context.getRouteAtDepth(this.getRouteDepth());return e?r.createElement(e.handler,o({},t||this.props,{ref:a})):null}};t.exports=s},function(t,e,n){var r=n(20),o={contextTypes:{getCurrentPath:r.func.isRequired,getCurrentRoutes:r.func.isRequired,getCurrentPathname:r.func.isRequired,getCurrentParams:r.func.isRequired,getCurrentQuery:r.func.isRequired,isActive:r.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,e,n,r){return{routes:[t],params:e,pathname:n,query:r}}function o(t,e,n,i,a){for(var s,u,c,l=0,h=t.length;h>l;++l){if(s=t[l],u=o(s.routes,s.defaultRoute,s.notFoundRoute,i,a),null!=u)return u.routes.unshift(s),u;if(c=k.extractParams(s.path,i))return r(s,c,i,a)}return e&&(c=k.extractParams(e.path,i))?r(e,c,i,a):n&&(c=k.extractParams(n.path,i))?r(n,c,i,a):null}function i(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,a){return t.some(function(t){if(t!==e)return!1;for(var s,u=e.paramNames,c=0,l=u.length;l>c;++c)if(s=u[c],r[s]!==n[s])return!1;return i(o,a)&&i(a,o)})}function s(t){t=t||{},x(t)&&(t={routes:t});var e=[],n=t.location||L,r=t.scrollBehavior||q,i={},s={},p=null,E=null;"string"==typeof n?c(!h||!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"):l(h||n.needsDOM===!1,"You cannot use %s without a DOM",n),n!==m||O()||(n=g);var S=u.createClass({displayName:"Router",statics:{isRunning:!1,cancelPendingTransition:function(){p&&(p.abort(new A),p=null)},clearAllRoutes:function(){this.cancelPendingTransition(),this.defaultRoute=null,this.notFoundRoute=null,this.namedRoutes={},this.routes=[]},addRoutes:function(t){x(t)&&(t=w(t,this,this.namedRoutes)),this.routes.push.apply(this.routes,t)},replaceRoutes:function(t){this.clearAllRoutes(),this.addRoutes(t),this.refresh()},match:function(t){return o(this.routes,this.defaultRoute,this.notFoundRoute,k.withoutQuery(t),k.extractQuery(t))},makePath:function(t,e,n){var r;if(k.isAbsolute(t))r=k.normalize(t);else{var o=this.namedRoutes[t];l(o,'Unable to find <Route name="%s">',t),r=o.path}return k.withQuery(k.injectParams(r,e),n)},makeHref:function(t,e,r){var o=this.makePath(t,e,r);return n===d?"#"+o:o},transitionTo:function(t,e,r){l("string"!=typeof n,"You cannot use transitionTo with a static location");var o=this.makePath(t,e,r);p?n.replace(o):n.push(o)},replaceWith:function(t,e,r){l("string"!=typeof n,"You cannot use replaceWith with a static location"),n.replace(this.makePath(t,e,r))},goBack:function(){return l("string"!=typeof n,"You cannot use goBack with a static location"),T.length>1||n===g?(n.pop(),!0):(c(!1,"goBack() was ignored because there is no router history"),!1)},handleAbort:t.onAbort||function(t){if("string"==typeof n)throw new Error("Unhandled aborted transition! Reason: "+t);t instanceof A||(t instanceof b?n.replace(this.makePath(t.to,t.params,t.query)):n.pop())},handleError:t.onError||function(t){throw t},handleLocationChange:function(t){this.dispatch(t.path,t.type)},dispatch:function(t,n){this.cancelPendingTransition();var r=i.path,o=null==n;if(r!==t||o){r&&n===f.PUSH&&this.recordScrollPosition(r);var s=this.match(t);c(null!=s,'No route matches path "%s". Make sure you have <Route path="%s"> somewhere in your routes',t,t),null==s&&(s={});var u,l,h=i.routes||[],d=i.params||{},m=i.query||{},g=s.routes||[],y=s.params||{},v=s.query||{};h.length?(u=h.filter(function(t){return!a(g,t,d,y,m,v)}),l=g.filter(function(t){return!a(h,t,d,y,m,v)})):(u=[],l=g);var R=new C(t,this.replaceWith.bind(this,t));p=R;var w=e.slice(h.length-u.length);R.from(u,w,function(e){return e||R.abortReason?E.call(S,e,R):void R.to(l,y,v,function(e){E.call(S,e,R,{path:t,action:n,pathname:s.pathname,routes:g,params:y,query:v})})})}},run:function(t){l(!this.isRunning,"Router is already running"),E=function(e,n,r){e&&S.handleError(e),p===n&&(p=null,n.abortReason?S.handleAbort(n.abortReason):t.call(this,this,s=r))},"string"==typeof n?S.dispatch(n,null):(n.addChangeListener&&n.addChangeListener(S.handleLocationChange),this.isRunning=!0,this.refresh())},refresh:function(){S.dispatch(n.getCurrentPath(),null)},stop:function(){this.cancelPendingTransition(),n.removeChangeListener&&n.removeChangeListener(S.handleLocationChange),this.isRunning=!1}},mixins:[y,v,R],propTypes:{children:P.falsy},childContextTypes:{getRouteAtDepth:u.PropTypes.func.isRequired,setRouteComponentAtDepth:u.PropTypes.func.isRequired,routeHandlers:u.PropTypes.array.isRequired},getChildContext:function(){return{getRouteAtDepth:this.getRouteAtDepth,setRouteComponentAtDepth:this.setRouteComponentAtDepth,routeHandlers:[this]}},getInitialState:function(){return i=s},componentWillReceiveProps:function(){this.setState(i=s)},componentWillUnmount:function(){S.stop()},getLocation:function(){return n},getScrollBehavior:function(){return r},getRouteAtDepth:function(t){var e=this.state.routes;return e&&e[t]},setRouteComponentAtDepth:function(t,n){e[t]=n},render:function(){var t=this.getRouteAtDepth(0);return t?u.createElement(t.handler,this.props):null}});return S.clearAllRoutes(),t.routes&&S.addRoutes(t.routes),S}var u=n(18),c=n(36),l=n(34),h=n(35).canUseDOM,f=n(21),p=n(10),d=n(7),m=n(8),g=n(9),y=n(22),v=n(23),R=n(24),w=n(25).createRoutesFromReactChildren,x=n(26),C=n(27),P=n(20),b=n(28),T=n(12),A=n(29),O=n(30),k=n(31),L=h?d:"/",q=h?p:null;t.exports=s},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(16);t.exports=r},function(e){e.exports=t},function(t,e,n){function r(t,e,n){for(var r in e)if(e.hasOwnProperty(r)){var i=e[r](n,r,t);i instanceof Error&&o(!1,i.message)}}var o=n(36),i=n(34),a={statics:{validateProps:function(t){r(this.displayName,this.propTypes,t)}},render:function(){i(!1,"%s elements are for router configuration only and should not be rendered",this.constructor.displayName)}};t.exports=a},function(t,e,n){var r=n(33),o=n(18).PropTypes,i=r({falsy:function(t,e,n){return t[e]?new Error("<"+n+'> may not have a "'+e+'" prop'):void 0}},o);t.exports=i},function(t){var e={PUSH:"push",REPLACE:"replace",POP:"pop"};t.exports=e},function(t,e,n){var r=n(20),o={childContextTypes:{makePath:r.func.isRequired,makeHref:r.func.isRequired,transitionTo:r.func.isRequired,replaceWith:r.func.isRequired,goBack:r.func.isRequired},getChildContext:function(){return{makePath:this.constructor.makePath.bind(this.constructor),makeHref:this.constructor.makeHref.bind(this.constructor),transitionTo:this.constructor.transitionTo.bind(this.constructor),replaceWith:this.constructor.replaceWith.bind(this.constructor),goBack:this.constructor.goBack.bind(this.constructor)}}};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 a=n(33),s=n(20),u=n(31),c={getCurrentPath:function(){return this.state.path},getCurrentRoutes:function(){return this.state.routes.slice(0)},getCurrentPathname:function(){return this.state.pathname},getCurrentParams:function(){return a({},this.state.params)},getCurrentQuery:function(){return a({},this.state.query)},isActive:function(t,e,n){return u.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:s.func.isRequired,getCurrentRoutes:s.func.isRequired,getCurrentPathname:s.func.isRequired,getCurrentParams:s.func.isRequired,getCurrentQuery:s.func.isRequired,isActive:s.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(34),i=n(35).canUseDOM,a=n(37),s={statics:{recordScrollPosition:function(t){this.scrollHistory||(this.scrollHistory={}),this.scrollHistory[t]=a()},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 function(r,o,i){r.redirect(t,e||o,n||i)}}function o(t,e,n){var o=t.type,s=t.props;o.validateProps&&o.validateProps(s);var p={name:s.name,ignoreScrollBehavior:!!s.ignoreScrollBehavior};o===h.type?(p.willTransitionTo=r(s.to,s.params,s.query),s.path=s.path||s.from||"*"):(p.handler=s.handler,p.willTransitionTo=s.handler&&s.handler.willTransitionTo,p.willTransitionFrom=s.handler&&s.handler.willTransitionFrom);var d=e&&e.path||"/";if((s.path||s.name)&&o!==c.type&&o!==l.type){var m=s.path||s.name;f.isAbsolute(m)||(m=f.join(d,m)),p.path=f.normalize(m)}else p.path=d,o===l.type&&(p.path+="*");p.paramNames=f.extractParamNames(p.path),e&&Array.isArray(e.paramNames)&&e.paramNames.forEach(function(t){u(-1!==p.paramNames.indexOf(t),'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"',p.path,t,e.path)});var g=new a(p);return s.name&&(u(null==n[s.name],'You cannot use the name "%s" for more than one route',s.name),n[s.name]=g),o===l.type?(u(e,"<NotFoundRoute> must have a parent <Route>"),u(null==e.notFoundRoute,"You may not have more than one <NotFoundRoute> per <Route>"),u(null==s.children,"<NotFoundRoute> must not have children"),e.notFoundRoute=g,null):o===c.type?(u(e,"<DefaultRoute> must have a parent <Route>"),u(null==e.defaultRoute,"You may not have more than one <DefaultRoute> per <Route>"),u(null==s.children,"<DefaultRoute> must not have children"),e.defaultRoute=g,null):(g.routes=i(s.children,g,n),g)}function i(t,e,n){var r=[];return s.Children.forEach(t,function(t){s.isValidElement(t)&&(t=o(t,e,n))&&r.push(t)}),r}function a(t){t=t||{},this.name=t.name,this.path=t.path||"/",this.paramNames=t.paramNames||f.extractParamNames(this.path),this.ignoreScrollBehavior=!!t.ignoreScrollBehavior,this.willTransitionTo=t.willTransitionTo,this.willTransitionFrom=t.willTransitionFrom,this.handler=t.handler}var s=n(18),u=n(34),c=n(1),l=n(3),h=n(4),f=n(31);t.exports={createRoutesFromReactChildren:i,Route:a}},function(t,e,n){function r(t){return null==t||i.isValidElement(t)}function o(t){return r(t)||Array.isArray(t)&&t.every(r)}var i=n(18);t.exports=o},function(t,e,n){function r(t,e){this.path=t,this.abortReason=null,this.retry=e.bind(this)}var o=n(33),i=n(28);o(r.prototype,{abort:function(t){null==this.abortReason&&(this.abortReason=t||"ABORT")},redirect:function(t,e,n){this.abort(new i(t,e,n))},from:function(t,e,n){var r=this,o=t.reduce(function(t,n,o){return function(i){if(i||r.abortReason)t(i);else if(n.willTransitionFrom)try{n.willTransitionFrom(r,e[o],t),n.willTransitionFrom.length<3&&t()}catch(a){t(a)}else t()}},n);o()},to:function(t,e,n,r){var o=this,i=t.reduceRight(function(t,r){return function(i){if(i||o.abortReason)t(i);else if(r.willTransitionTo)try{r.willTransitionTo(o,e,n,t),r.willTransitionTo.length<4&&t()}catch(a){t(a)}else t()}},r);i()}}),t.exports=r},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){function e(){/*! taken from modernizr
     2           * https://github.com/Modernizr/Modernizr/blob/master/LICENSE
     3           * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
     4           * changed to avoid false negatives for Windows Phones: https://github.com/rackt/react-router/issues/586
     5           */
     6var 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){if(!(t in h)){var e=[],n=t.replace(s,function(t,n){return n?(e.push(n),"([^/?#]+)"):"*"===t?(e.push("splat"),"(.*?)"):"\\"+t});h[t]={matcher:new RegExp("^"+n+"$","i"),paramNames:e}}return h[t]}var o=n(34),i=n(39).merge,a=n(38),s=/:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g,u=/:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g,c=/\/\/\?|\/\?\/|\/\?/g,l=/\?(.+)/,h={},f={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(u,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 a;return"splat"===i&&Array.isArray(e[i])?(a=e[i][n++],o(null!=a,"Missing splat # "+n+' for path "'+t+'"')):a=e[i],a}).replace(c,"/")},extractQuery:function(t){var e=t.match(l);return e&&a.parse(e[1])},withoutQuery:function(t){return t.replace(l,"")},withQuery:function(t,e){var n=f.extractQuery(t);n&&(e=e?i(n,e):n);var r=a.stringify(e,{indices:!1});return r?f.withoutQuery(t)+"?"+decodeURIComponent(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=f},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;r<arguments.length;r++){var o=arguments[r];if(null!=o){var i=Object(o);for(var a in i)n.call(i,a)&&(e[a]=i[a])}}return e}t.exports=e},function(t){"use strict";var e=function(t,e,n,r,o,i,a,s){if(!t){var u;if(void 0===e)u=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,o,i,a,s],l=0;u=new Error("Invariant Violation: "+e.replace(/%s/g,function(){return c[l++]}))}throw u.framesToPop=1,u}};t.exports=e},function(t){"use strict";var e=!("undefined"==typeof window||!window.document||!window.document.createElement),n={canUseDOM:e,canUseWorkers:"undefined"!=typeof Worker,canUseEventListeners:e&&!(!window.addEventListener&&!window.attachEvent),canUseViewport:e&&!!window.screen,isInWorker:!e};t.exports=n},function(t,e,n){"use strict";var r=n(40),o=r;t.exports=o},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(34),i=n(35).canUseDOM;t.exports=r},function(t,e,n){t.exports=n(41)},function(t,e){e.arrayToObject=function(t){for(var e={},n=0,r=t.length;r>n;++n)"undefined"!=typeof t[n]&&(e[n]=t[n]);return e},e.merge=function(t,n){if(!n)return t;if("object"!=typeof n)return Array.isArray(t)?t.push(n):t[n]=!0,t;if("object"!=typeof t)return t=[t].concat(n);Array.isArray(t)&&!Array.isArray(n)&&(t=e.arrayToObject(t));for(var r=Object.keys(n),o=0,i=r.length;i>o;++o){var a=r[o],s=n[a];t[a]=t[a]?e.merge(t[a],s):s}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,a=t.length;a>i;++i)"undefined"!=typeof t[i]&&o.push(t[i]);return o}var s=Object.keys(t);for(i=0,a=s.length;a>i;++i){var u=s[i];t[u]=e.compact(t[u],n)}return t},e.isRegExp=function(t){return"[object RegExp]"===Object.prototype.toString.call(t)},e.isBuffer=function(t){return null===t||"undefined"==typeof t?!1:!!(t.constructor&&t.constructor.isBuffer&&t.constructor.isBuffer(t))}},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(42),o=n(43);t.exports={stringify:r,parse:o}},function(t,e,n){var r=n(39),o={delimiter:"&",indices:!0};o.stringify=function(t,e,n){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 i=[];if("undefined"==typeof t)return i;for(var a=Object.keys(t),s=0,u=a.length;u>s;++s){var c=a[s];i=i.concat(!n.indices&&Array.isArray(t)?o.stringify(t[c],e,n):o.stringify(t[c],e+"["+c+"]",n))}return i},t.exports=function(t,e){e=e||{};var n="undefined"==typeof e.delimiter?o.delimiter:e.delimiter;e.indices="boolean"==typeof e.indices?e.indices:o.indices;var r=[];if("object"!=typeof t||null===t)return"";for(var i=Object.keys(t),a=0,s=i.length;s>a;++a){var u=i[a];r=r.concat(o.stringify(t[u],u,e))}return r.join(n)}},function(t,e,n){var r=n(39),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,a=o.length;a>i;++i){var s=o[i],u=-1===s.indexOf("]=")?s.indexOf("="):s.indexOf("]=")+1;if(-1===u)n[r.decode(s)]="";else{var c=r.decode(s.slice(0,u)),l=r.decode(s.slice(u+1));n[c]=n.hasOwnProperty(c)?[].concat(n[c]).concat(l):l}}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 a="["===r[0]&&"]"===r[r.length-1]?r.slice(1,r.length-1):r,s=parseInt(a,10),u=""+s;!isNaN(s)&&r!==a&&u===a&&s>=0&&s<=n.arrayLimit?(i=[],i[s]=o.parseObject(t,e,n)):i[a]=o.parseObject(t,e,n)}return i},o.parseKeys=function(t,e,n){if(t){var r=/^([^\[\]]*)/,i=/(\[[^\[\]]*\])/g,a=r.exec(t);if(!Object.prototype.hasOwnProperty(a[1])){var s=[];a[1]&&s.push(a[1]);for(var u=0;null!==(a=i.exec(t))&&u<n.depth;)++u,Object.prototype.hasOwnProperty(a[1].replace(/\[|\]/g,""))||s.push(a[1]);return a&&s.push("["+t.slice(a.index)+"]"),o.parseObject(s,e,n)}}},t.exports=function(t,e){if(""===t||null===t||"undefined"==typeof t)return{};e=e||{},e.delimiter="string"==typeof e.delimiter||r.isRegExp(e.delimiter)?e.delimiter:o.delimiter,e.depth="number"==typeof e.depth?e.depth:o.depth,e.arrayLimit="number"==typeof e.arrayLimit?e.arrayLimit:o.arrayLimit,e.parameterLimit="number"==typeof e.parameterLimit?e.parameterLimit:o.parameterLimit;for(var n="string"==typeof t?o.parseValues(t,e):t,i={},a=Object.keys(n),s=0,u=a.length;u>s;++s){var c=a[s],l=o.parseKeys(c,n[c],e);i=r.merge(i,l)}return r.compact(i)}}])});
Note: See TracChangeset for help on using the changeset viewer.