├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── examples └── todomvc │ ├── README.md │ ├── css │ └── app.css │ ├── index.html │ ├── js │ ├── actions │ │ ├── index.js │ │ └── todo.js │ ├── app.js │ ├── bundle.min.js │ ├── components │ │ ├── Footer.react.js │ │ ├── Header.react.js │ │ ├── MainSection.react.js │ │ ├── TodoApp.react.js │ │ ├── TodoItem.react.js │ │ └── TodoTextInput.react.js │ └── stores │ │ ├── index.js │ │ └── todo.js │ ├── package.json │ └── todomvc-common │ ├── .bower.json │ ├── base.css │ ├── bg.png │ ├── bower.json │ └── readme.md ├── lib └── fluky.js ├── package.json ├── src ├── core.js ├── dispatcher.js ├── fevent.js └── fluky.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Fred Chien 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fluky 2 | 3 | Everything is asynchronous event! 4 | 5 | A framework with flux data flow pattern and ECMAScript 6+. With Fluky, asynchronous event is a simple way to control all of frontend data flow. Inspired by Koa, Fluky dispatcher and event handlers were implemented by ES6 generator. 6 | 7 | [![NPM](https://nodei.co/npm/fluky.png)](https://nodei.co/npm/fluky/) 8 | 9 | ## Installation 10 | 11 | Install fluky via NPM: 12 | ``` 13 | npm install fluky 14 | ``` 15 | 16 | Note that fluky is using `require` and `EventEmitter` of Node.js, you must have browserify or webpack to make it work for front-end purpose. 17 | 18 | ## Usage 19 | 20 | With Fluky, event-driven approach is the only way to handle __actions__ and __stores__, it makes everything easy and simple. 21 | 22 | ### Actions and Stores implementation 23 | 24 | Here is sample code below to show how to implement __actions__ and __stores__ with Fluky and ES5/ES6+: 25 | ```js 26 | import Fluky from 'fluky'; 27 | 28 | // ACTION 29 | Fluky.on('action.Todo.toggle', function *(todo) { 30 | if (todo.completed) 31 | Fluky.dispatch('store.Todo.unmark', todo.id); 32 | else 33 | Fluky.dispatch('store.Todo.mark', todo.id); 34 | }); 35 | 36 | // STORE 37 | 38 | // Getting current state. Initialize state if state doesn't exist. 39 | var todoStore = Fluky.getState('Todo', { 40 | todos: []; 41 | }); 42 | 43 | Fluky.on('store.Todo.unmark', function *(id) { 44 | 45 | // Find specific todo item with id 46 | for (var index in todoStore.todos) { 47 | var todo = todoStore.todos[index]; 48 | 49 | if (todo.id == id) { 50 | // Unmark 51 | todo.completed = false; 52 | 53 | // Fire event that store was changed 54 | Fluky.dispatch('store.Todo', 'change'); 55 | break; 56 | } 57 | } 58 | }); 59 | 60 | Fluky.on('store.Todo.mark', function *(id) { 61 | 62 | // Find specific todo item with id 63 | for (var index in todoStore.todos) { 64 | var todo = todoStore.todos[index]; 65 | 66 | if (todo.id == id) { 67 | // Mark 68 | todo.completed = true; 69 | 70 | // Fire event that store was changed 71 | Fluky.dispatch('store.Todo', 'change'); 72 | break; 73 | } 74 | } 75 | }); 76 | 77 | Fluky.on('store.Todo.create', function *(text) { 78 | 79 | // Add a new todo item to store 80 | todoStore.todos.push({ 81 | id: Date.now(), 82 | text: text, 83 | completed: false 84 | }); 85 | 86 | // Fire event that store was changed 87 | Fluky.dispatch('store.Todo', 'change'); 88 | }); 89 | 90 | ``` 91 | 92 | If no action defined, message will be forwarded to store. For instance, `action.Todo.create` isn't defined but forwarding to `store.Todo.create` automatically. 93 | 94 | ### Access Actions and Stores with React.js 95 | 96 | Call action and get data from store both works by using `Fluky.dispatch()` to fire event. 97 | 98 | ```js 99 | import React from 'react'; 100 | import Fluky from 'fluky'; 101 | 102 | // React component (view) 103 | class TodoList extends React.Component { 104 | 105 | constructor() { 106 | // preparing state to initialize component 107 | this.state = { 108 | todos: Fluky.getState('Todo').todos; 109 | }; 110 | } 111 | 112 | componentDidMount() { 113 | Fluky.on('store.Todo', Fluky.bindListener(this.onChange)); 114 | } 115 | 116 | componentWillUnmount() { 117 | Fluky.off('store.Todo', this.onChange); 118 | } 119 | 120 | // Using "() =>" to bind "this" to method 121 | onChange = () => { 122 | 123 | // Updating state 124 | this.setState({ 125 | todos: Fluky.getState('Todo').todos; 126 | }); 127 | } 128 | 129 | create = () => { 130 | // Fire event to create a new todo item 131 | Fluky.dispatch('action.Todo.create', 'Dance'); 132 | } 133 | 134 | render: function() { 135 | var todoList = []; 136 | 137 | this.state.todos.forEach((todo) => { 138 | todoList.push(
{todo.text}
); 139 | }); 140 | 141 | // Template for React 142 | return ( 143 |
144 | {todoList} 145 | 146 |
147 | ); 148 | } 149 | } 150 | ``` 151 | 152 | ### Modular 153 | 154 | You can create a Store without ever touching Action. Fluky provide a way to extend, using `Fluky.load()` to load Actions and Stores. 155 | 156 | ```js 157 | 158 | import Fluky from 'fluky'; 159 | 160 | var todoStore = function *() { 161 | this.on('store.Todo.completeTodoItem', function *() { ... }); 162 | this.on('store.Todo', function *() { ... }); 163 | }; 164 | 165 | Fluky.load(todoStore); 166 | ``` 167 | 168 | Loading multiple modules at one time is possible: 169 | ```js 170 | var actions = [ 171 | todoAction, 172 | userAction 173 | ]; 174 | 175 | var stores = [ 176 | todoStore, 177 | userStore 178 | ]; 179 | 180 | Fluky.load(actions, stores); 181 | ``` 182 | 183 | ### State Management 184 | 185 | In order to make an isomorphic app, initial state should be rendered on the server stage. That's a big challenge because state provided by server usually conflicts with client-side store. Fluky supports state management that a way to solve multiple stores problem. 186 | 187 | On the server-side, developer can use `setInitialState()` to create a initial state: 188 | ```js 189 | Fluky.setInitialState({ 190 | Todo: {} 191 | }); 192 | ``` 193 | 194 | Then you can get state with `getState()` everywhere, modify it and add put stores in it. For example below: 195 | ```js 196 | Fluky.getState('Todo').timestamp = Date.now(); 197 | ``` 198 | 199 | In module, it is possible to get `Fluky` with `this` keyword, then there is the same way to access state: 200 | ```js 201 | var todoStore = function *() { 202 | this.getState('Todo').timestamp = Date.now(); 203 | }; 204 | 205 | ``` 206 | 207 | ## Demo 208 | 209 | Just like other front-end framework, fluky has an TodoMVC example for demostration as well. 210 | 211 | Change working directory then initializing and starting it with NPM command: 212 | ``` 213 | cd examples/todomvc/ 214 | npm install 215 | npm start 216 | ``` 217 | 218 | Now you can open `index.html` with browser immediately. 219 | 220 | ## Authors 221 | 222 | Copyright(c) 2015 Fred Chien <> 223 | 224 | ## License 225 | 226 | Licensed under the MIT License 227 | -------------------------------------------------------------------------------- /examples/todomvc/README.md: -------------------------------------------------------------------------------- 1 | # Fluky TodoMVC Example 2 | 3 | > An application architecture for React utilizing a unidirectional data flow. 4 | 5 | 6 | ## Learning Flux 7 | 8 | The [Flux](http://facebook.github.io/flux) and [React](http://facebook.github.io/react) websites are great resources for getting started. 9 | 10 | Read the blog post announcing Flux: ["An Application Architecture for React"](http://facebook.github.io/react/blog/2014/05/06/flux.html), then read more about the [Flux architecture](http://facebook.github.io/react/docs/flux-overview.html) and a [TodoMVC tutorial](http://facebook.github.io/flux/docs/todo-list.html) explaining the structure of the files in this folder. After you feel comfortable with the TodoMVC example, you may be interested in the [Chat App example](../flux-chat), which is more complex. 11 | 12 | 13 | ## Overview 14 | 15 | Flux applications have three major parts: the ___dispatcher___, the ___stores___, and the ___views___ (React components). These should not be confused with Model-View-Controller. Controllers do exist in a Flux application, but they are ___controller-views___ -- views often found at the top of the hierarchy that retrieve data from the stores and pass this data down to their children. Additionally, ___action creators___ — dispatcher helper methods — are often used to support a semantic dispatcher API. It can be useful to think of them as a fourth part of the Flux update cycle. 16 | 17 | Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with a React ___view___, the view propagates an ___action___ through a central ___dispatcher___, to the various ___stores___ that hold the application's data and business logic, which updates all of the views that are affected. This works especially well with React's declarative programming style, which allows the store to send updates without specifying how to transition views between states. 18 | 19 | We originally set out to deal correctly with derived data: for example, we wanted to show an unread count for message threads while another view showed a list of threads, with the unread ones highlighted. This was difficult to handle with MVC — marking a single thread as read would update the thread model, and then also need to update the unread count model. These dependencies and cascading updates often occur in a large MVC application, leading to a tangled weave of data flow and unpredictable results. 20 | 21 | Control is inverted with ___stores___: the stores accept updates and reconcile them as appropriate, rather than depending on something external to update its data in a consistent way. Nothing outside the store has any insight into how it manages the data for its domain, helping to keep a clear separation of concerns. This also makes stores more testable than models, especially since stores have no direct setter methods like `setAsRead()`, but instead have only an input point for a data payload, which is delivered through the ___dispatcher___ and originates with ___action creators___. 22 | 23 | 24 | ## Structure and Data Flow 25 | 26 | Data in a Flux application flows in a single direction, in a cycle: 27 | 28 | 29 | 30 | A unidirectional data flow is central to the Flux pattern, and in fact Flux takes its name from the Latin word for flow. In the above diagram, the ___dispatcher___, ___stores___ and ___views___ are independent nodes with distinct inputs and outputs. The ___action creators___ are simply discrete, semantic helper functions that facilitate passing data to the ___dispatcher___ in the form of an ___action___. 31 | 32 | All data flows through the ___dispatcher___ as a central hub. ___Actions___ most often originate from user interactions with the ___views___, and ___action creators___ are nothing more than a call into the ___dispatcher___. The ___dispatcher___ then invokes the callbacks that the ___stores___ have registered with it, effectively dispatching the data payload contained in the ___actions___ to all ___stores___. Within their registered callbacks, ___stores___ determine which ___actions___ they are interested in, and respond accordingly. The ___stores___ then emit a "change" event to alert the ___controller-views___ that a change to the data layer has occurred. ___Controller-views___ listen for these events and retrieve data from the ___stores___ in an event handler. The ___controller-views___ call their own `render()` method via `setState()` or `forceUpdate()`, updating themselves and all of their children. 33 | 34 | This structure allows us to reason easily about our application in a way that is reminiscent of functional reactive programming, or more specifically data-flow programming or flow-based programming, where data flows through the application in a single direction — there are no two-way bindings. Application state is maintained only in the ___stores___, allowing the different parts of the application to remain highly decoupled. Where dependencies do occur between ___stores___, they are kept in a strict hierarchy, with synchronous updates managed by the ___dispatcher___. 35 | 36 | We found that two-way data bindings led to cascading updates, where changing one object led to another object changing, which could also trigger more updates. As applications grew, these cascading updates made it very difficult to predict what would change as the result of one user interaction. When updates can only change data within a single round, the system as a whole becomes more predictable. 37 | 38 | Let's look at the various parts of the Flux update cycle up close. A good place to start is the dispatcher. 39 | 40 | 41 | ### A Single Dispatcher 42 | 43 | The dispatcher is the central hub that manages all data flow in a Flux application. It is essentially a registry of callbacks into the stores. Each store registers itself and provides a callback. When the dispatcher is invoked in an action creator method, all stores in the application are sent a data payload via the callbacks in the registry. 44 | 45 | As an application grows, the dispatcher becomes more vital, as it can manage dependencies between stores by invoking the registered callbacks in a specific order. Stores can declaratively wait for other stores to finish updating, and then update themselves accordingly. 46 | 47 | 48 | ### Stores 49 | 50 | Stores contain the application state and logic. Their role is somewhat similar to a model in a traditional MVC, but they manage the state of many objects — they are not instances of one object. Nor are they the same as Backbone's collections. More than simply managing a collection of ORM-style objects, stores manage the application state for a particular __domain__ within the application. 51 | 52 | For example, Facebook's [Lookback Video Editor](https://facebook.com/lookback/edit) utilized a TimeStore that kept track of the playback time position and the playback state. On the other hand, the same application's ImageStore kept track of a collection of images. The TodoStore in our TodoMVC example is similar in that it manages a collection of to-do items. A store exhibits characteristics of both a collection of models and a singleton model of a logical domain. 53 | 54 | As mentioned above, a store registers itself with the dispatcher and provides it with a callback. This callback receives a data payload as a parameter. The payload contains an action with an attribute identifying the action's type. Within the store's registered callback, a switch statement based on the action's type is used to interpret the payload and to provide the proper hooks into the store's internal methods. This allows an action to result in an update to the state of the store, via the dispatcher. After the stores are updated, they broadcast an event declaring that their state has changed, so the views may query the new state and update themselves. 55 | 56 | 57 | ### Views and Controller-Views 58 | 59 | React provides the kind of composable views we need for the view layer. Close to the top of the nested view hierarchy, a special kind of view listens for events that are broadcast by the stores that it depends on. One could call this a ___controller-view___, as it provides the glue code to get the data from the stores and to pass this data down the chain of its descendants. We might have one of these controller-views governing any significant section of the page. 60 | 61 | When it receives the event from the store, it first requests the new data it needs via the stores' public getter methods. It then calls its own `setState()` or `forceUpdate()` methods, causing its `render()` method and the `render()` method of all its descendants to run. 62 | 63 | We often pass the entire state of the store down the chain of views in a single object, allowing different descendants to use what they need. In addition to keeping the controller-like behavior at the top of the hierarchy, and thus keeping our descendant views as functionally pure as possible, passing down the entire state of the store in a single object also has the effect of reducing the number of props we need to manage. 64 | 65 | Occasionally we may need to add additional controller-views deeper in the hierarchy to keep components simple. This might help us to better encapsulate a section of the hierarchy related to a specific data domain. Be aware, however, that controller-views deeper in the hierarchy can violate the singular flow of data by introducing a new, potentially conflicting entry point for the data flow. In making the decision of whether to add a deep controller-view, balance the gain of simpler components against the complexity of multiple data updates flowing into the hierarchy at different points. These multiple data updates can lead to odd effects, with React's render method getting invoked repeatedly by updates from different controller-views, potentially increasing the difficulty of debugging. 66 | 67 | 68 | ### Actions and Action Creators 69 | 70 | The dispatcher exposes a method that allows a view to trigger a dispatch to the stores, and to include a payload of data. This data payload contains an action, an object literal containing the various fields of data and a specific action type. The action construction may be wrapped into a semantic helper method, which we refer to as action creators. These methods provide the payload to the dispatcher. For example, we may want to change the text of a to-do item in a to-do list application. We would create an action creator method like `updateText(todoId, newText)` in our `TodoActions` module. This method may be invoked from within our views' event handlers, so we can call it in response to a user interaction. The action creator method also adds the type to the action, so that when the payload is interpreted in the store, it can respond appropriately to a payload with a particular action type. In our example, this type might be named something like `TODO_UPDATE_TEXT`. 71 | 72 | Actions may also come from other places, such as the server. This happens, for example, during data initialization. It may also happen when the server returns an error code or when the server has updates to provide to the application. We'll talk more about server actions in a future article. In this example application we're only concerned with the basics of the data flow. 73 | 74 | 75 | ### What About that Dispatcher? 76 | 77 | As mentioned earlier, the dispatcher is also able to manage dependencies between stores. This functionality is available through the Dispatcher's `waitFor()` method. The TodoMVC application is extremely simple, so we did not need to use this method, but in a larger, more complex application, this method becomes vital. 78 | 79 | Within the TodoStore's registered callback we can explicitly wait for any dependencies to first update before moving forward: 80 | 81 | ``` 82 | case 'TODO_CREATE': 83 | Dispatcher.waitFor([ 84 | PrependedTextStore.dispatchToken, 85 | YetAnotherStore.dispatchToken 86 | ]); 87 | TodoStore.create(PrependedTextStore.getText() + ' ' + action.text); 88 | TodoStore.emit('change'); 89 | break; 90 | ``` 91 | 92 | The arguments for `waitFor()` are an array of dipatcher registry indexes, which we refer to here as each store's dispatchToken. When waitFor() is encountered in a callback, it tells the Dispatcher to invoke the callbacks for the required stores. After these callbacks complete, the original callback can continue to execute. Thus the store that is invoking `waitFor()` can depend on the state of another store to inform how it should update its own state. 93 | 94 | A problem arises if we create circular dependencies. If Store A waits for Store B, and B waits for A, then we could wind up in an endless loop. The Dispatcher will flag these circular dependencies with console errors. 95 | 96 | 97 | ## TodoMVC Example Implementation 98 | 99 | In this TodoMVC example application, we can see the elements of Flux in our directory structure. Views here are referred to as "components" as they are React components. 100 | 101 |
102 | ./
103 |   index.html
104 |   js/
105 |     actions/
106 |       index.js
107 |       todo.js
108 |     app.js
109 |     bundle.min.js
110 |     components/
111 |       Footer.react.js
112 |       Header.react.js
113 |       MainSection.react.js
114 |       TodoApp.react.js
115 |       TodoItem.react.js
116 |       TodoTextInput.react.js
117 |     stores/
118 |       index.js
119 |       todo.js
120 | 
121 | 122 | The primary entry point into the application is app.js. This file bootstraps the React rendering inside of index.html. TodoApp.react.js is our controller-view and it passes all data down into its child React components. 123 | 124 | TodoActions.js is a collection of action creator methods that views may call from within their event handlers, in response to user interactions. They are nothing more than helpers that call into the AppDispatcher. 125 | 126 | Dispatcher.js is a base class for AppDispatcher.js which extends it with a small amount of application-specific code. 127 | 128 | TodoStore.js is our only store. It provides all of the application logic and in-memory storage. Based on EventEmitter from Node.js, it emits "change" events after responding to actions in the callback it registers with the dispatcher. 129 | 130 | The bundle.js file is automatically genenerated by the build process, explained below. 131 | 132 | 133 | ## Running 134 | 135 | You must have [npm](https://www.npmjs.org/) installed on your computer. 136 | From the root project directory run these commands from the command line: 137 | 138 | npm install 139 | 140 | This will install all dependencies. 141 | 142 | To build the project, first run this command: 143 | 144 | npm start 145 | 146 | This will perform an initial build and start a watcher process that will update build.js with any changes you wish to make. This watcher is based on [Browserify](http://browserify.org/) and [Watchify](https://github.com/substack/watchify), and it transforms React's JSX syntax into standard JavaScript with [Reactify](https://github.com/andreypopp/reactify). 147 | 148 | To run the app, spin up an HTTP server and visit http://localhost/.../todomvc-flux/. Or simply open the index.html file in a browser. 149 | 150 | 151 | ## Credit 152 | 153 | This TodoMVC application was created by [Fred CHien](https://www.facebook.com/fred.chien.9). 154 | 155 | 156 | ## License 157 | Flux is BSD-licensed. We also provide an additional patent grant. 158 | -------------------------------------------------------------------------------- /examples/todomvc/css/app.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | * 9 | * base.css overrides 10 | */ 11 | 12 | /** 13 | * We are not changing from display:none, but rather re-rendering instead. 14 | * Therefore this needs to be displayed normally by default. 15 | */ 16 | #todo-list li .edit { 17 | display: inline; 18 | } 19 | -------------------------------------------------------------------------------- /examples/todomvc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Fluky • TodoMVC 6 | 7 | 8 | 9 | 10 |
11 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /examples/todomvc/js/actions/index.js: -------------------------------------------------------------------------------- 1 | import todo from './todo' 2 | 3 | export default { 4 | todo: todo 5 | } 6 | -------------------------------------------------------------------------------- /examples/todomvc/js/actions/todo.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function *() { 3 | this.on('action.Todo.toggle', function *(todo) { 4 | if (todo.complete) 5 | this.dispatch('store.Todo.unmark', todo.id); 6 | else 7 | this.dispatch('store.Todo.mark', todo.id); 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /examples/todomvc/js/app.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var TodoApp = require('./components/TodoApp.react'); 3 | var Fluky = require('fluky'); 4 | var Actions = require('./actions'); 5 | var Stores = require('./stores'); 6 | 7 | Fluky.load(Actions, Stores); 8 | 9 | React.render( 10 | , 11 | document.getElementById('todoapp') 12 | ); 13 | -------------------------------------------------------------------------------- /examples/todomvc/js/components/Footer.react.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactPropTypes = React.PropTypes; 3 | var Fluky = require('fluky'); 4 | 5 | class Footer extends React.Component { 6 | 7 | static propTypes = { 8 | todos: ReactPropTypes.array.isRequired 9 | }; 10 | 11 | static defaultProps = { 12 | todos: [] 13 | }; 14 | 15 | render() { 16 | const todos = this.props.todos; 17 | const total = todos.length; 18 | 19 | if (total === 0) 20 | return null; 21 | 22 | const markedCount = todos.reduce( 23 | (count, todo) => todo.complete ? count + 1 : count, 24 | 0 25 | ); 26 | 27 | const itemsLeft = total - markedCount; 28 | 29 | let itemsLeftPhrase = (itemsLeft === 1) ? ' item ' : ' items '; 30 | itemsLeftPhrase += 'left'; 31 | 32 | let clearCompletedButton; 33 | if (!itemsLeft) { 34 | clearCompletedButton = 35 | ; 40 | } 41 | 42 | return ( 43 |
44 | 45 | {itemsLeft} 46 | {itemsLeftPhrase} 47 | 48 | {clearCompletedButton} 49 |
50 | ); 51 | } 52 | 53 | onClearCompletedClick = () => { 54 | Fluky.dispatch('action.Todo.destroyCompleted'); 55 | } 56 | 57 | } 58 | 59 | module.exports = Footer; 60 | -------------------------------------------------------------------------------- /examples/todomvc/js/components/Header.react.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var Fluky = require('fluky'); 3 | var TodoTextInput = require('./TodoTextInput.react'); 4 | 5 | class Header extends React.Component { 6 | 7 | render() { 8 | return ( 9 | 17 | ); 18 | } 19 | 20 | save(text) { 21 | if (!text.trim()) 22 | return; 23 | 24 | Fluky.dispatch('action.Todo.create', text); 25 | } 26 | 27 | }; 28 | 29 | module.exports = Header; 30 | -------------------------------------------------------------------------------- /examples/todomvc/js/components/MainSection.react.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactPropTypes = React.PropTypes; 3 | var Fluky = require('fluky'); 4 | var TodoItem = require('./TodoItem.react'); 5 | 6 | class MainSection extends React.Component { 7 | 8 | static propTypes = { 9 | todos: ReactPropTypes.array.isRequired 10 | }; 11 | 12 | static defaultProps = { 13 | todos: [] 14 | }; 15 | 16 | markAll() { 17 | Fluky.dispatch('action.Todo.markAll'); 18 | } 19 | 20 | render() { 21 | const todos = this.props.todos; 22 | 23 | if (todos.length < 1) 24 | return null; 25 | 26 | const markedCount = todos.reduce( 27 | (count, todo) => todo.complete ? count + 1 : count, 28 | 0 29 | ); 30 | const areAllCompleted = (markedCount == todos.length) ? true : false; 31 | 32 | const todoList = []; 33 | todos.forEach((todo) => { 34 | todoList.push(); 35 | }); 36 | 37 | return ( 38 |
39 | 44 | 45 |
    {todoList}
46 |
47 | ); 48 | } 49 | }; 50 | 51 | module.exports = MainSection; 52 | -------------------------------------------------------------------------------- /examples/todomvc/js/components/TodoApp.react.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var Fluky = require('fluky'); 3 | var Footer = require('./Footer.react'); 4 | var Header = require('./Header.react'); 5 | var MainSection = require('./MainSection.react'); 6 | 7 | class TodoApp extends React.Component { 8 | 9 | constructor(props, context) { 10 | super(props, context); 11 | 12 | this.state = { 13 | todos: Fluky.getState('Todo').todos 14 | }; 15 | } 16 | 17 | componentDidMount() { 18 | Fluky.on('state.Todo', Fluky.bindListener(this.onTodoChanged)); 19 | } 20 | 21 | componentWillUnmount() { 22 | Fluky.off('store.Todo', this.onTodoChanged); 23 | } 24 | 25 | render() { 26 | return ( 27 |
28 |
29 | 30 |
31 |
32 | ); 33 | } 34 | 35 | onTodoChanged = () => { 36 | 37 | this.setState({ 38 | todos: Fluky.getState('Todo').todos 39 | }); 40 | } 41 | }; 42 | 43 | module.exports = TodoApp; 44 | -------------------------------------------------------------------------------- /examples/todomvc/js/components/TodoItem.react.js: -------------------------------------------------------------------------------- 1 | var Fluky = require('fluky'); 2 | var React = require('react'); 3 | var ReactPropTypes = React.PropTypes; 4 | var TodoTextInput = require('./TodoTextInput.react'); 5 | 6 | var cx = require('react/lib/cx'); 7 | 8 | class TodoItem extends React.Component { 9 | 10 | static propTypes = { 11 | todo: ReactPropTypes.object.isRequired 12 | }; 13 | 14 | constructor(props, context) { 15 | super(props, context); 16 | 17 | this.state = { 18 | isEditing: false 19 | } 20 | } 21 | 22 | save = (text) => { 23 | Fluky.dispatch('action.Todo.updateText', this.props.todo.id, text); 24 | this.setState({ isEditing: false }); 25 | } 26 | 27 | toggle = () => { 28 | Fluky.dispatch('action.Todo.toggle', this.props.todo); 29 | } 30 | 31 | render() { 32 | var input; 33 | 34 | if (this.state.isEditing) { 35 | input = 36 | ; 40 | } 41 | 42 | const classNames = cx({ 43 | 'completed': this.props.todo.complete, 44 | 'editing': this.state.isEditing 45 | }); 46 | 47 | return ( 48 |
  • 51 | 52 |
    53 | 58 | 59 |
    61 | {input} 62 |
  • 63 | ); 64 | } 65 | 66 | onDoubleClick = () => { 67 | this.setState({ isEditing: true }); 68 | } 69 | 70 | onDestroyClick = () => { 71 | Fluky.dispatch('action.Todo.destroy', this.props.todo.id); 72 | } 73 | 74 | } 75 | 76 | module.exports = TodoItem; 77 | -------------------------------------------------------------------------------- /examples/todomvc/js/components/TodoTextInput.react.js: -------------------------------------------------------------------------------- 1 | var Fluky = require('fluky'); 2 | var React = require('react'); 3 | var ReactPropTypes = React.PropTypes; 4 | 5 | var ENTER_KEY_CODE = 13; 6 | 7 | class TodoTextInput extends React.Component { 8 | 9 | static propTypes = { 10 | className: ReactPropTypes.string, 11 | id: ReactPropTypes.string, 12 | placeholder: ReactPropTypes.string, 13 | onSave: ReactPropTypes.func.isRequired, 14 | value: ReactPropTypes.string 15 | }; 16 | 17 | constructor(props, context) { 18 | super(props, context); 19 | 20 | this.state = { 21 | value: props.value || '' 22 | }; 23 | } 24 | 25 | render() { 26 | return ( 27 | 36 | ); 37 | } 38 | 39 | save = () => { 40 | this.props.onSave(this.state.value); 41 | this.setState({ 42 | value: '' 43 | }); 44 | } 45 | 46 | onChange = (event) => { 47 | this.setState({ 48 | value: event.target.value 49 | }); 50 | } 51 | 52 | onKeyDown = (event) => { 53 | if (event.keyCode === ENTER_KEY_CODE) { 54 | this.save(); 55 | } 56 | } 57 | 58 | }; 59 | 60 | module.exports = TodoTextInput; 61 | -------------------------------------------------------------------------------- /examples/todomvc/js/stores/index.js: -------------------------------------------------------------------------------- 1 | import todo from './todo' 2 | 3 | export default { 4 | todo: todo 5 | } 6 | -------------------------------------------------------------------------------- /examples/todomvc/js/stores/todo.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function *() { 3 | 4 | // Getting current state. Initialize state if state doesn't exist. 5 | var todoStore = this.getState('Todo', { 6 | todos: [] 7 | }); 8 | 9 | function findTodoItem(id) { 10 | 11 | for (var index in todoStore.todos) { 12 | var todo = todoStore.todos[index]; 13 | if (todo.id == id) { 14 | return index; 15 | } 16 | } 17 | 18 | return -1; 19 | } 20 | 21 | this.on('store.Todo.create', function *(text) { 22 | todoStore.todos.push({ 23 | id: Date.now(), 24 | complete: false, 25 | text: text 26 | }); 27 | 28 | this.dispatch('state.Todo'); 29 | }); 30 | 31 | this.on('store.Todo.destroy', function *(id) { 32 | 33 | var index = findTodoItem(id); 34 | if (index == -1) 35 | return; 36 | 37 | todoStore.todos.splice(index, 1); 38 | 39 | this.dispatch('state.Todo'); 40 | }); 41 | 42 | this.on('store.Todo.updateText', function *(id, text) { 43 | text = text.trim(); 44 | if (text === '') 45 | return; 46 | 47 | var index = findTodoItem(id); 48 | if (index == -1) 49 | return; 50 | 51 | todoStore.todos[index].text = text; 52 | 53 | this.dispatch('state.Todo'); 54 | }); 55 | 56 | this.on('store.Todo.mark', function *(id) { 57 | 58 | var index = findTodoItem(id); 59 | if (index == -1) 60 | return; 61 | 62 | todoStore.todos[index].complete = true; 63 | 64 | this.dispatch('state.Todo'); 65 | }); 66 | 67 | this.on('store.Todo.unmark', function *(id) { 68 | 69 | var index = findTodoItem(id); 70 | if (index == -1) 71 | return; 72 | 73 | todoStore.todos[index].complete = false; 74 | 75 | this.dispatch('state.Todo'); 76 | }); 77 | 78 | this.on('store.Todo.destroyCompleted', function *() { 79 | 80 | var todos = []; 81 | for (var index in todoStore.todos) { 82 | if (!todoStore.todos[index].complete) { 83 | todos.push(todoStore.todos[index]); 84 | } 85 | } 86 | 87 | todoStore.todos = todos; 88 | 89 | this.dispatch('state.Todo'); 90 | }); 91 | 92 | this.on('store.Todo.markAll', function *() { 93 | 94 | var areAllMarked = true; 95 | for (var index in todoStore.todos) { 96 | if (!todoStore.todos[index].complete) { 97 | areAllMarked = false; 98 | break; 99 | } 100 | } 101 | 102 | for (var index in todoStore.todos) { 103 | todoStore.todos[index].complete = !areAllMarked; 104 | } 105 | 106 | this.dispatch('state.Todo'); 107 | }); 108 | }; 109 | -------------------------------------------------------------------------------- /examples/todomvc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todomvc-fluky", 3 | "version": "0.0.2", 4 | "description": "Example Flux architecture.", 5 | "main": "js/app.js", 6 | "dependencies": { 7 | "fluky": "^0.1.10", 8 | "react": ">=0.13.0" 9 | }, 10 | "devDependencies": { 11 | "babel-runtime": "^5.8.20", 12 | "babelify": ">=6.1.3", 13 | "browserify": ">=6.2.0", 14 | "envify": ">=3.0.0", 15 | "jest-cli": ">=0.1.17", 16 | "reactify": ">=0.15.2", 17 | "watchify": ">=2.1.1" 18 | }, 19 | "scripts": { 20 | "start": "watchify -o js/bundle.js -v -d .", 21 | "build": "NODE_ENV=production browserify . > js/bundle.min.js", 22 | "test": "jest" 23 | }, 24 | "author": "Fred Chien", 25 | "browserify": { 26 | "transform": [ 27 | [ 28 | "babelify", 29 | { 30 | "stage": 0, 31 | "optional": [ 32 | "runtime" 33 | ] 34 | } 35 | ], 36 | "reactify", 37 | "envify" 38 | ] 39 | }, 40 | "jest": { 41 | "rootDir": "./js" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /examples/todomvc/todomvc-common/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todomvc-common", 3 | "version": "0.1.9", 4 | "homepage": "https://github.com/tastejs/todomvc-common", 5 | "_release": "0.1.9", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "v0.1.9", 9 | "commit": "7dd61b0ebf56c020e719a69444442cc7ae7242ff" 10 | }, 11 | "_source": "git://github.com/tastejs/todomvc-common.git", 12 | "_target": "~0.1.4", 13 | "_originalSource": "todomvc-common" 14 | } -------------------------------------------------------------------------------- /examples/todomvc/todomvc-common/base.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | button { 8 | margin: 0; 9 | padding: 0; 10 | border: 0; 11 | background: none; 12 | font-size: 100%; 13 | vertical-align: baseline; 14 | font-family: inherit; 15 | color: inherit; 16 | -webkit-appearance: none; 17 | -ms-appearance: none; 18 | -o-appearance: none; 19 | appearance: none; 20 | } 21 | 22 | body { 23 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; 24 | line-height: 1.4em; 25 | background: #eaeaea url('bg.png'); 26 | color: #4d4d4d; 27 | width: 550px; 28 | margin: 0 auto; 29 | -webkit-font-smoothing: antialiased; 30 | -moz-font-smoothing: antialiased; 31 | -ms-font-smoothing: antialiased; 32 | -o-font-smoothing: antialiased; 33 | font-smoothing: antialiased; 34 | } 35 | 36 | button, 37 | input[type="checkbox"] { 38 | outline: none; 39 | } 40 | 41 | #todoapp { 42 | background: #fff; 43 | background: rgba(255, 255, 255, 0.9); 44 | margin: 130px 0 40px 0; 45 | border: 1px solid #ccc; 46 | position: relative; 47 | border-top-left-radius: 2px; 48 | border-top-right-radius: 2px; 49 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2), 50 | 0 25px 50px 0 rgba(0, 0, 0, 0.15); 51 | } 52 | 53 | #todoapp:before { 54 | content: ''; 55 | border-left: 1px solid #f5d6d6; 56 | border-right: 1px solid #f5d6d6; 57 | width: 2px; 58 | position: absolute; 59 | top: 0; 60 | left: 40px; 61 | height: 100%; 62 | } 63 | 64 | #todoapp input::-webkit-input-placeholder { 65 | font-style: italic; 66 | } 67 | 68 | #todoapp input::-moz-placeholder { 69 | font-style: italic; 70 | color: #a9a9a9; 71 | } 72 | 73 | #todoapp h1 { 74 | position: absolute; 75 | top: -120px; 76 | width: 100%; 77 | font-size: 70px; 78 | font-weight: bold; 79 | text-align: center; 80 | color: #b3b3b3; 81 | color: rgba(255, 255, 255, 0.3); 82 | text-shadow: -1px -1px rgba(0, 0, 0, 0.2); 83 | -webkit-text-rendering: optimizeLegibility; 84 | -moz-text-rendering: optimizeLegibility; 85 | -ms-text-rendering: optimizeLegibility; 86 | -o-text-rendering: optimizeLegibility; 87 | text-rendering: optimizeLegibility; 88 | } 89 | 90 | #header { 91 | padding-top: 15px; 92 | border-radius: inherit; 93 | } 94 | 95 | #header:before { 96 | content: ''; 97 | position: absolute; 98 | top: 0; 99 | right: 0; 100 | left: 0; 101 | height: 15px; 102 | z-index: 2; 103 | border-bottom: 1px solid #6c615c; 104 | background: #8d7d77; 105 | background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8))); 106 | background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8)); 107 | background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8)); 108 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670'); 109 | border-top-left-radius: 1px; 110 | border-top-right-radius: 1px; 111 | } 112 | 113 | #new-todo, 114 | .edit { 115 | position: relative; 116 | margin: 0; 117 | width: 100%; 118 | font-size: 24px; 119 | font-family: inherit; 120 | line-height: 1.4em; 121 | border: 0; 122 | outline: none; 123 | color: inherit; 124 | padding: 6px; 125 | border: 1px solid #999; 126 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); 127 | -moz-box-sizing: border-box; 128 | -ms-box-sizing: border-box; 129 | -o-box-sizing: border-box; 130 | box-sizing: border-box; 131 | -webkit-font-smoothing: antialiased; 132 | -moz-font-smoothing: antialiased; 133 | -ms-font-smoothing: antialiased; 134 | -o-font-smoothing: antialiased; 135 | font-smoothing: antialiased; 136 | } 137 | 138 | #new-todo { 139 | padding: 16px 16px 16px 60px; 140 | border: none; 141 | background: rgba(0, 0, 0, 0.02); 142 | z-index: 2; 143 | box-shadow: none; 144 | } 145 | 146 | #main { 147 | position: relative; 148 | z-index: 2; 149 | border-top: 1px dotted #adadad; 150 | } 151 | 152 | label[for='toggle-all'] { 153 | display: none; 154 | } 155 | 156 | #toggle-all { 157 | position: absolute; 158 | top: -42px; 159 | left: -4px; 160 | width: 40px; 161 | text-align: center; 162 | /* Mobile Safari */ 163 | border: none; 164 | } 165 | 166 | #toggle-all:before { 167 | content: '»'; 168 | font-size: 28px; 169 | color: #d9d9d9; 170 | padding: 0 25px 7px; 171 | } 172 | 173 | #toggle-all:checked:before { 174 | color: #737373; 175 | } 176 | 177 | #todo-list { 178 | margin: 0; 179 | padding: 0; 180 | list-style: none; 181 | } 182 | 183 | #todo-list li { 184 | position: relative; 185 | font-size: 24px; 186 | border-bottom: 1px dotted #ccc; 187 | } 188 | 189 | #todo-list li:last-child { 190 | border-bottom: none; 191 | } 192 | 193 | #todo-list li.editing { 194 | border-bottom: none; 195 | padding: 0; 196 | } 197 | 198 | #todo-list li.editing .edit { 199 | display: block; 200 | width: 506px; 201 | padding: 13px 17px 12px 17px; 202 | margin: 0 0 0 43px; 203 | } 204 | 205 | #todo-list li.editing .view { 206 | display: none; 207 | } 208 | 209 | #todo-list li .toggle { 210 | text-align: center; 211 | width: 40px; 212 | /* auto, since non-WebKit browsers doesn't support input styling */ 213 | height: auto; 214 | position: absolute; 215 | top: 0; 216 | bottom: 0; 217 | margin: auto 0; 218 | /* Mobile Safari */ 219 | border: none; 220 | -webkit-appearance: none; 221 | -ms-appearance: none; 222 | -o-appearance: none; 223 | appearance: none; 224 | } 225 | 226 | #todo-list li .toggle:after { 227 | content: '✔'; 228 | /* 40 + a couple of pixels visual adjustment */ 229 | line-height: 43px; 230 | font-size: 20px; 231 | color: #d9d9d9; 232 | text-shadow: 0 -1px 0 #bfbfbf; 233 | } 234 | 235 | #todo-list li .toggle:checked:after { 236 | color: #85ada7; 237 | text-shadow: 0 1px 0 #669991; 238 | bottom: 1px; 239 | position: relative; 240 | } 241 | 242 | #todo-list li label { 243 | white-space: pre; 244 | word-break: break-word; 245 | padding: 15px 60px 15px 15px; 246 | margin-left: 45px; 247 | display: block; 248 | line-height: 1.2; 249 | -webkit-transition: color 0.4s; 250 | transition: color 0.4s; 251 | } 252 | 253 | #todo-list li.completed label { 254 | color: #a9a9a9; 255 | text-decoration: line-through; 256 | } 257 | 258 | #todo-list li .destroy { 259 | display: none; 260 | position: absolute; 261 | top: 0; 262 | right: 10px; 263 | bottom: 0; 264 | width: 40px; 265 | height: 40px; 266 | margin: auto 0; 267 | font-size: 22px; 268 | color: #a88a8a; 269 | -webkit-transition: all 0.2s; 270 | transition: all 0.2s; 271 | } 272 | 273 | #todo-list li .destroy:hover { 274 | text-shadow: 0 0 1px #000, 275 | 0 0 10px rgba(199, 107, 107, 0.8); 276 | -webkit-transform: scale(1.3); 277 | -ms-transform: scale(1.3); 278 | transform: scale(1.3); 279 | } 280 | 281 | #todo-list li .destroy:after { 282 | content: '✖'; 283 | } 284 | 285 | #todo-list li:hover .destroy { 286 | display: block; 287 | } 288 | 289 | #todo-list li .edit { 290 | display: none; 291 | } 292 | 293 | #todo-list li.editing:last-child { 294 | margin-bottom: -1px; 295 | } 296 | 297 | #footer { 298 | color: #777; 299 | padding: 0 15px; 300 | position: absolute; 301 | right: 0; 302 | bottom: -31px; 303 | left: 0; 304 | height: 20px; 305 | z-index: 1; 306 | text-align: center; 307 | } 308 | 309 | #footer:before { 310 | content: ''; 311 | position: absolute; 312 | right: 0; 313 | bottom: 31px; 314 | left: 0; 315 | height: 50px; 316 | z-index: -1; 317 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3), 318 | 0 6px 0 -3px rgba(255, 255, 255, 0.8), 319 | 0 7px 1px -3px rgba(0, 0, 0, 0.3), 320 | 0 43px 0 -6px rgba(255, 255, 255, 0.8), 321 | 0 44px 2px -6px rgba(0, 0, 0, 0.2); 322 | } 323 | 324 | #todo-count { 325 | float: left; 326 | text-align: left; 327 | } 328 | 329 | #filters { 330 | margin: 0; 331 | padding: 0; 332 | list-style: none; 333 | position: absolute; 334 | right: 0; 335 | left: 0; 336 | } 337 | 338 | #filters li { 339 | display: inline; 340 | } 341 | 342 | #filters li a { 343 | color: #83756f; 344 | margin: 2px; 345 | text-decoration: none; 346 | } 347 | 348 | #filters li a.selected { 349 | font-weight: bold; 350 | } 351 | 352 | #clear-completed { 353 | float: right; 354 | position: relative; 355 | line-height: 20px; 356 | text-decoration: none; 357 | background: rgba(0, 0, 0, 0.1); 358 | font-size: 11px; 359 | padding: 0 10px; 360 | border-radius: 3px; 361 | box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2); 362 | } 363 | 364 | #clear-completed:hover { 365 | background: rgba(0, 0, 0, 0.15); 366 | box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3); 367 | } 368 | 369 | #info { 370 | margin: 65px auto 0; 371 | color: #a6a6a6; 372 | font-size: 12px; 373 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); 374 | text-align: center; 375 | } 376 | 377 | #info a { 378 | color: inherit; 379 | } 380 | 381 | /* 382 | Hack to remove background from Mobile Safari. 383 | Can't use it globally since it destroys checkboxes in Firefox and Opera 384 | */ 385 | 386 | @media screen and (-webkit-min-device-pixel-ratio:0) { 387 | #toggle-all, 388 | #todo-list li .toggle { 389 | background: none; 390 | } 391 | 392 | #todo-list li .toggle { 393 | height: 40px; 394 | } 395 | 396 | #toggle-all { 397 | top: -56px; 398 | left: -15px; 399 | width: 65px; 400 | height: 41px; 401 | -webkit-transform: rotate(90deg); 402 | -ms-transform: rotate(90deg); 403 | transform: rotate(90deg); 404 | -webkit-appearance: none; 405 | appearance: none; 406 | } 407 | } 408 | 409 | .hidden { 410 | display: none; 411 | } 412 | 413 | hr { 414 | margin: 20px 0; 415 | border: 0; 416 | border-top: 1px dashed #C5C5C5; 417 | border-bottom: 1px dashed #F7F7F7; 418 | } 419 | 420 | .learn a { 421 | font-weight: normal; 422 | text-decoration: none; 423 | color: #b83f45; 424 | } 425 | 426 | .learn a:hover { 427 | text-decoration: underline; 428 | color: #787e7e; 429 | } 430 | 431 | .learn h3, 432 | .learn h4, 433 | .learn h5 { 434 | margin: 10px 0; 435 | font-weight: 500; 436 | line-height: 1.2; 437 | color: #000; 438 | } 439 | 440 | .learn h3 { 441 | font-size: 24px; 442 | } 443 | 444 | .learn h4 { 445 | font-size: 18px; 446 | } 447 | 448 | .learn h5 { 449 | margin-bottom: 0; 450 | font-size: 14px; 451 | } 452 | 453 | .learn ul { 454 | padding: 0; 455 | margin: 0 0 30px 25px; 456 | } 457 | 458 | .learn li { 459 | line-height: 20px; 460 | } 461 | 462 | .learn p { 463 | font-size: 15px; 464 | font-weight: 300; 465 | line-height: 1.3; 466 | margin-top: 0; 467 | margin-bottom: 0; 468 | } 469 | 470 | .quote { 471 | border: none; 472 | margin: 20px 0 60px 0; 473 | } 474 | 475 | .quote p { 476 | font-style: italic; 477 | } 478 | 479 | .quote p:before { 480 | content: '“'; 481 | font-size: 50px; 482 | opacity: .15; 483 | position: absolute; 484 | top: -20px; 485 | left: 3px; 486 | } 487 | 488 | .quote p:after { 489 | content: '”'; 490 | font-size: 50px; 491 | opacity: .15; 492 | position: absolute; 493 | bottom: -42px; 494 | right: 3px; 495 | } 496 | 497 | .quote footer { 498 | position: absolute; 499 | bottom: -40px; 500 | right: 0; 501 | } 502 | 503 | .quote footer img { 504 | border-radius: 3px; 505 | } 506 | 507 | .quote footer a { 508 | margin-left: 5px; 509 | vertical-align: middle; 510 | } 511 | 512 | .speech-bubble { 513 | position: relative; 514 | padding: 10px; 515 | background: rgba(0, 0, 0, .04); 516 | border-radius: 5px; 517 | } 518 | 519 | .speech-bubble:after { 520 | content: ''; 521 | position: absolute; 522 | top: 100%; 523 | right: 30px; 524 | border: 13px solid transparent; 525 | border-top-color: rgba(0, 0, 0, .04); 526 | } 527 | 528 | .learn-bar > .learn { 529 | position: absolute; 530 | width: 272px; 531 | top: 8px; 532 | left: -300px; 533 | padding: 10px; 534 | border-radius: 5px; 535 | background-color: rgba(255, 255, 255, .6); 536 | -webkit-transition-property: left; 537 | transition-property: left; 538 | -webkit-transition-duration: 500ms; 539 | transition-duration: 500ms; 540 | } 541 | 542 | @media (min-width: 899px) { 543 | .learn-bar { 544 | width: auto; 545 | margin: 0 0 0 300px; 546 | } 547 | 548 | .learn-bar > .learn { 549 | left: 8px; 550 | } 551 | 552 | .learn-bar #todoapp { 553 | width: 550px; 554 | margin: 130px auto 40px auto; 555 | } 556 | } 557 | -------------------------------------------------------------------------------- /examples/todomvc/todomvc-common/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cfsghost/fluky/d7732d045911aff46f15b1e4d5021c46c0fbcb29/examples/todomvc/todomvc-common/bg.png -------------------------------------------------------------------------------- /examples/todomvc/todomvc-common/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todomvc-common", 3 | "version": "0.1.9" 4 | } 5 | -------------------------------------------------------------------------------- /examples/todomvc/todomvc-common/readme.md: -------------------------------------------------------------------------------- 1 | # todomvc-common 2 | 3 | > Bower component for some common utilities we use in every app 4 | 5 | 6 | ## License 7 | 8 | MIT 9 | -------------------------------------------------------------------------------- /lib/fluky.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | /******/ (function(modules) { // webpackBootstrap 3 | /******/ // The module cache 4 | /******/ var installedModules = {}; 5 | 6 | /******/ // The require function 7 | /******/ function __webpack_require__(moduleId) { 8 | 9 | /******/ // Check if module is in cache 10 | /******/ if(installedModules[moduleId]) 11 | /******/ return installedModules[moduleId].exports; 12 | 13 | /******/ // Create a new module (and put it into the cache) 14 | /******/ var module = installedModules[moduleId] = { 15 | /******/ exports: {}, 16 | /******/ id: moduleId, 17 | /******/ loaded: false 18 | /******/ }; 19 | 20 | /******/ // Execute the module function 21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 22 | 23 | /******/ // Flag the module as loaded 24 | /******/ module.loaded = true; 25 | 26 | /******/ // Return the exports of the module 27 | /******/ return module.exports; 28 | /******/ } 29 | 30 | 31 | /******/ // expose the modules object (__webpack_modules__) 32 | /******/ __webpack_require__.m = modules; 33 | 34 | /******/ // expose the module cache 35 | /******/ __webpack_require__.c = installedModules; 36 | 37 | /******/ // __webpack_public_path__ 38 | /******/ __webpack_require__.p = "/lib"; 39 | 40 | /******/ // Load entry module and return exports 41 | /******/ return __webpack_require__(0); 42 | /******/ }) 43 | /************************************************************************/ 44 | /******/ ([ 45 | /* 0 */ 46 | /***/ function(module, exports, __webpack_require__) { 47 | 48 | module.exports = __webpack_require__(1); 49 | 50 | 51 | /***/ }, 52 | /* 1 */ 53 | /***/ function(module, exports, __webpack_require__) { 54 | 55 | 'use strict'; 56 | 57 | var Core = __webpack_require__(2); 58 | 59 | var core = new Core(); 60 | 61 | module.exports = core; 62 | 63 | /***/ }, 64 | /* 2 */ 65 | /***/ function(module, exports, __webpack_require__) { 66 | 67 | 'use strict'; 68 | 69 | var _get = __webpack_require__(3)['default']; 70 | 71 | var _inherits = __webpack_require__(19)['default']; 72 | 73 | var _createClass = __webpack_require__(28)['default']; 74 | 75 | var _classCallCheck = __webpack_require__(31)['default']; 76 | 77 | var _Object$assign = __webpack_require__(82)['default']; 78 | 79 | var _regeneratorRuntime = __webpack_require__(32)['default']; 80 | 81 | var _interopRequireDefault = __webpack_require__(87)['default']; 82 | 83 | Object.defineProperty(exports, '__esModule', { 84 | value: true 85 | }); 86 | 87 | var _co = __webpack_require__(88); 88 | 89 | var _co2 = _interopRequireDefault(_co); 90 | 91 | var _dispatcher = __webpack_require__(89); 92 | 93 | var _dispatcher2 = _interopRequireDefault(_dispatcher); 94 | 95 | var _fevent = __webpack_require__(90); 96 | 97 | var _fevent2 = _interopRequireDefault(_fevent); 98 | 99 | function next() { 100 | return function (done) { 101 | done(null, true); 102 | }; 103 | } 104 | 105 | var Core = (function (_Dispatcher) { 106 | _inherits(Core, _Dispatcher); 107 | 108 | _createClass(Core, [{ 109 | key: 'createInstance', 110 | value: function createInstance() { 111 | return new Core(); 112 | } 113 | }]); 114 | 115 | function Core() { 116 | _classCallCheck(this, Core); 117 | 118 | _get(Object.getPrototypeOf(Core.prototype), 'constructor', this).call(this); 119 | 120 | this.isBrowser = true; 121 | this.options = {}; 122 | this.disabledEventHandler = false; 123 | this.serverRendering = false; 124 | this.middlewares = []; 125 | this.handlers = []; 126 | this.wrapperMap = []; 127 | this._state = {}; 128 | 129 | // Load default state on browser-side 130 | if (typeof window == 'undefined') { 131 | this.isBrowser = false; 132 | } else { 133 | if (window.Fluky) { 134 | if (window.Fluky.state) { 135 | this._state = _Object$assign({}, window.Fluky.state); 136 | } 137 | } 138 | } 139 | 140 | // Action 141 | this.use(_regeneratorRuntime.mark(function callee$2$0(event, next) { 142 | var args, e; 143 | return _regeneratorRuntime.wrap(function callee$2$0$(context$3$0) { 144 | while (1) switch (context$3$0.prev = context$3$0.next) { 145 | case 0: 146 | if (!(event.type != 'action')) { 147 | context$3$0.next = 4; 148 | break; 149 | } 150 | 151 | context$3$0.next = 3; 152 | return next(); 153 | 154 | case 3: 155 | return context$3$0.abrupt('return', context$3$0.sent); 156 | 157 | case 4: 158 | if (!this.hasListeners(event.path)) { 159 | context$3$0.next = 8; 160 | break; 161 | } 162 | 163 | context$3$0.next = 7; 164 | return this.emit.apply(this, event.args); 165 | 166 | case 7: 167 | return context$3$0.abrupt('return'); 168 | 169 | case 8: 170 | args = event.args.slice(0); 171 | 172 | args[0] = 'store.' + event.category + '.' + event.name; 173 | e = new _fevent2['default'](args[0], args); 174 | 175 | this.internalDispatch(e); 176 | 177 | case 12: 178 | case 'end': 179 | return context$3$0.stop(); 180 | } 181 | }, callee$2$0, this); 182 | })); 183 | 184 | // Dispatch events 185 | this.use(_regeneratorRuntime.mark(function callee$2$0(event, next) { 186 | return _regeneratorRuntime.wrap(function callee$2$0$(context$3$0) { 187 | while (1) switch (context$3$0.prev = context$3$0.next) { 188 | case 0: 189 | if (!this.serverRendering) { 190 | context$3$0.next = 3; 191 | break; 192 | } 193 | 194 | if (!(event.type == 'state')) { 195 | context$3$0.next = 3; 196 | break; 197 | } 198 | 199 | return context$3$0.abrupt('return'); 200 | 201 | case 3: 202 | context$3$0.next = 5; 203 | return this.emit.apply(this, event.args); 204 | 205 | case 5: 206 | case 'end': 207 | return context$3$0.stop(); 208 | } 209 | }, callee$2$0, this); 210 | })); 211 | } 212 | 213 | _createClass(Core, [{ 214 | key: 'use', 215 | value: function use() { 216 | this.middlewares.push(arguments[0].bind(this)); 217 | } 218 | }, { 219 | key: 'loadHandler', 220 | value: function loadHandler(handler) { 221 | 222 | var exists = false; 223 | for (var index in this.handlers) { 224 | if (this.handlers[index] == handler) { 225 | exists = true; 226 | break; 227 | } 228 | } 229 | 230 | if (!exists) { 231 | (0, _co2['default'])(handler.bind(this)); 232 | this.handlers.push(handler); 233 | } 234 | } 235 | }, { 236 | key: 'load', 237 | value: function load() { 238 | 239 | for (var k in arguments) { 240 | var handler = arguments[k]; 241 | 242 | // It's an array 243 | if (!(handler instanceof Function)) { 244 | var handlers = handler; 245 | 246 | for (var key in handlers) { 247 | this.loadHandler(handlers[key]); 248 | } 249 | } 250 | } 251 | } 252 | }, { 253 | key: 'dispatch', 254 | value: function dispatch(eventStr) { 255 | 256 | // For isomorphic app, sometimes no need to handle event on server-side 257 | if (this.disabledEventHandler) return; 258 | 259 | var event = new _fevent2['default'](eventStr, arguments); 260 | 261 | this.internalDispatch(event); 262 | } 263 | }, { 264 | key: 'internalDispatch', 265 | value: function internalDispatch(event) { 266 | 267 | // Using all middlewares to handle this event 268 | (0, _co2['default'])(_regeneratorRuntime.mark(function callee$2$0() { 269 | var index, handler, isAlive; 270 | return _regeneratorRuntime.wrap(function callee$2$0$(context$3$0) { 271 | while (1) switch (context$3$0.prev = context$3$0.next) { 272 | case 0: 273 | context$3$0.t0 = _regeneratorRuntime.keys(this.middlewares); 274 | 275 | case 1: 276 | if ((context$3$0.t1 = context$3$0.t0()).done) { 277 | context$3$0.next = 17; 278 | break; 279 | } 280 | 281 | index = context$3$0.t1.value; 282 | handler = this.middlewares[index]; 283 | context$3$0.prev = 4; 284 | return context$3$0.delegateYield(handler(event, next), 't2', 6); 285 | 286 | case 6: 287 | isAlive = context$3$0.t2; 288 | context$3$0.next = 13; 289 | break; 290 | 291 | case 9: 292 | context$3$0.prev = 9; 293 | context$3$0.t3 = context$3$0['catch'](4); 294 | 295 | console.log(context$3$0.t3.stack); 296 | return context$3$0.abrupt('break', 17); 297 | 298 | case 13: 299 | if (isAlive) { 300 | context$3$0.next = 15; 301 | break; 302 | } 303 | 304 | return context$3$0.abrupt('break', 17); 305 | 306 | case 15: 307 | context$3$0.next = 1; 308 | break; 309 | 310 | case 17: 311 | case 'end': 312 | return context$3$0.stop(); 313 | } 314 | }, callee$2$0, this, [[4, 9]]); 315 | }).bind(this)); 316 | } 317 | }, { 318 | key: 'off', 319 | value: function off(eventName, listener) { 320 | // Find listener and remove its generator 321 | for (var index in this.wrapperMap) { 322 | var wrapper = this.wrapperMap[index]; 323 | if (wrapper.listener == listener) { 324 | this.wrapperMap.splice(index, 1); 325 | _get(Object.getPrototypeOf(Core.prototype), 'off', this).call(this, eventName, wrapper.generator); 326 | return; 327 | } 328 | } 329 | 330 | _get(Object.getPrototypeOf(Core.prototype), 'off', this).call(this, eventName, listener); 331 | } 332 | }, { 333 | key: 'bindListener', 334 | value: function bindListener(listener) { 335 | 336 | // Don't wrap again if it exists 337 | for (var index in this.wrapperMap) { 338 | var wrapper = this.wrapperMap[index]; 339 | if (wrapper.listener == listener) return wrapper.generator; 340 | } 341 | 342 | // add to list 343 | var wrapper = { 344 | listener: listener, 345 | generator: _regeneratorRuntime.mark(function generator() { 346 | var args$3$0 = arguments; 347 | return _regeneratorRuntime.wrap(function generator$(context$3$0) { 348 | while (1) switch (context$3$0.prev = context$3$0.next) { 349 | case 0: 350 | listener.apply(this, Array.prototype.slice.call(args$3$0)); 351 | 352 | case 1: 353 | case 'end': 354 | return context$3$0.stop(); 355 | } 356 | }, generator, this); 357 | }) 358 | }; 359 | 360 | this.wrapperMap.push(wrapper); 361 | 362 | return wrapper.generator; 363 | } 364 | }, { 365 | key: 'setInitialState', 366 | value: function setInitialState(state) { 367 | 368 | // Reset state and apply new state 369 | this._state = _Object$assign({}, state); 370 | } 371 | }, { 372 | key: 'getState', 373 | value: function getState(stateName, defState) { 374 | 375 | if (!this._state[stateName]) this._state[stateName] = defState || {}; 376 | 377 | return this._state[stateName]; 378 | } 379 | }, { 380 | key: 'setState', 381 | value: function setState(stateName, state) { 382 | 383 | if (!this._state[stateName]) this._state[stateName] = state;else this._state[stateName] = _Object$assign(this._state[stateName], state); 384 | } 385 | }, { 386 | key: 'state', 387 | get: function get() { 388 | return this._state; 389 | }, 390 | set: function set(val) { 391 | this._state = _Object$assign(this._state, val); 392 | } 393 | }]); 394 | 395 | return Core; 396 | })(_dispatcher2['default']); 397 | 398 | exports['default'] = Core; 399 | module.exports = exports['default']; 400 | 401 | // Using customized handler if it exists 402 | 403 | // Forwarding event to store 404 | 405 | // Ignore state change event 406 | 407 | /***/ }, 408 | /* 3 */ 409 | /***/ function(module, exports, __webpack_require__) { 410 | 411 | "use strict"; 412 | 413 | var _Object$getOwnPropertyDescriptor = __webpack_require__(4)["default"]; 414 | 415 | exports["default"] = function get(_x, _x2, _x3) { 416 | var _again = true; 417 | 418 | _function: while (_again) { 419 | var object = _x, 420 | property = _x2, 421 | receiver = _x3; 422 | _again = false; 423 | if (object === null) object = Function.prototype; 424 | 425 | var desc = _Object$getOwnPropertyDescriptor(object, property); 426 | 427 | if (desc === undefined) { 428 | var parent = Object.getPrototypeOf(object); 429 | 430 | if (parent === null) { 431 | return undefined; 432 | } else { 433 | _x = parent; 434 | _x2 = property; 435 | _x3 = receiver; 436 | _again = true; 437 | desc = parent = undefined; 438 | continue _function; 439 | } 440 | } else if ("value" in desc) { 441 | return desc.value; 442 | } else { 443 | var getter = desc.get; 444 | 445 | if (getter === undefined) { 446 | return undefined; 447 | } 448 | 449 | return getter.call(receiver); 450 | } 451 | } 452 | }; 453 | 454 | exports.__esModule = true; 455 | 456 | /***/ }, 457 | /* 4 */ 458 | /***/ function(module, exports, __webpack_require__) { 459 | 460 | module.exports = { "default": __webpack_require__(5), __esModule: true }; 461 | 462 | /***/ }, 463 | /* 5 */ 464 | /***/ function(module, exports, __webpack_require__) { 465 | 466 | var $ = __webpack_require__(6); 467 | __webpack_require__(7); 468 | module.exports = function getOwnPropertyDescriptor(it, key){ 469 | return $.getDesc(it, key); 470 | }; 471 | 472 | /***/ }, 473 | /* 6 */ 474 | /***/ function(module, exports) { 475 | 476 | var $Object = Object; 477 | module.exports = { 478 | create: $Object.create, 479 | getProto: $Object.getPrototypeOf, 480 | isEnum: {}.propertyIsEnumerable, 481 | getDesc: $Object.getOwnPropertyDescriptor, 482 | setDesc: $Object.defineProperty, 483 | setDescs: $Object.defineProperties, 484 | getKeys: $Object.keys, 485 | getNames: $Object.getOwnPropertyNames, 486 | getSymbols: $Object.getOwnPropertySymbols, 487 | each: [].forEach 488 | }; 489 | 490 | /***/ }, 491 | /* 7 */ 492 | /***/ function(module, exports, __webpack_require__) { 493 | 494 | // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) 495 | var toIObject = __webpack_require__(8); 496 | 497 | __webpack_require__(12)('getOwnPropertyDescriptor', function($getOwnPropertyDescriptor){ 498 | return function getOwnPropertyDescriptor(it, key){ 499 | return $getOwnPropertyDescriptor(toIObject(it), key); 500 | }; 501 | }); 502 | 503 | /***/ }, 504 | /* 8 */ 505 | /***/ function(module, exports, __webpack_require__) { 506 | 507 | // to indexed object, toObject with fallback for non-array-like ES3 strings 508 | var IObject = __webpack_require__(9) 509 | , defined = __webpack_require__(11); 510 | module.exports = function(it){ 511 | return IObject(defined(it)); 512 | }; 513 | 514 | /***/ }, 515 | /* 9 */ 516 | /***/ function(module, exports, __webpack_require__) { 517 | 518 | // fallback for non-array-like ES3 and non-enumerable old V8 strings 519 | var cof = __webpack_require__(10); 520 | module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ 521 | return cof(it) == 'String' ? it.split('') : Object(it); 522 | }; 523 | 524 | /***/ }, 525 | /* 10 */ 526 | /***/ function(module, exports) { 527 | 528 | var toString = {}.toString; 529 | 530 | module.exports = function(it){ 531 | return toString.call(it).slice(8, -1); 532 | }; 533 | 534 | /***/ }, 535 | /* 11 */ 536 | /***/ function(module, exports) { 537 | 538 | // 7.2.1 RequireObjectCoercible(argument) 539 | module.exports = function(it){ 540 | if(it == undefined)throw TypeError("Can't call method on " + it); 541 | return it; 542 | }; 543 | 544 | /***/ }, 545 | /* 12 */ 546 | /***/ function(module, exports, __webpack_require__) { 547 | 548 | // most Object methods by ES6 should accept primitives 549 | var $export = __webpack_require__(13) 550 | , core = __webpack_require__(15) 551 | , fails = __webpack_require__(18); 552 | module.exports = function(KEY, exec){ 553 | var fn = (core.Object || {})[KEY] || Object[KEY] 554 | , exp = {}; 555 | exp[KEY] = exec(fn); 556 | $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp); 557 | }; 558 | 559 | /***/ }, 560 | /* 13 */ 561 | /***/ function(module, exports, __webpack_require__) { 562 | 563 | var global = __webpack_require__(14) 564 | , core = __webpack_require__(15) 565 | , ctx = __webpack_require__(16) 566 | , PROTOTYPE = 'prototype'; 567 | 568 | var $export = function(type, name, source){ 569 | var IS_FORCED = type & $export.F 570 | , IS_GLOBAL = type & $export.G 571 | , IS_STATIC = type & $export.S 572 | , IS_PROTO = type & $export.P 573 | , IS_BIND = type & $export.B 574 | , IS_WRAP = type & $export.W 575 | , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) 576 | , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] 577 | , key, own, out; 578 | if(IS_GLOBAL)source = name; 579 | for(key in source){ 580 | // contains in native 581 | own = !IS_FORCED && target && key in target; 582 | if(own && key in exports)continue; 583 | // export native or passed 584 | out = own ? target[key] : source[key]; 585 | // prevent global pollution for namespaces 586 | exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] 587 | // bind timers to global for call from export context 588 | : IS_BIND && own ? ctx(out, global) 589 | // wrap global constructors for prevent change them in library 590 | : IS_WRAP && target[key] == out ? (function(C){ 591 | var F = function(param){ 592 | return this instanceof C ? new C(param) : C(param); 593 | }; 594 | F[PROTOTYPE] = C[PROTOTYPE]; 595 | return F; 596 | // make static versions for prototype methods 597 | })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; 598 | if(IS_PROTO)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out; 599 | } 600 | }; 601 | // type bitmap 602 | $export.F = 1; // forced 603 | $export.G = 2; // global 604 | $export.S = 4; // static 605 | $export.P = 8; // proto 606 | $export.B = 16; // bind 607 | $export.W = 32; // wrap 608 | module.exports = $export; 609 | 610 | /***/ }, 611 | /* 14 */ 612 | /***/ function(module, exports) { 613 | 614 | // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 615 | var global = module.exports = typeof window != 'undefined' && window.Math == Math 616 | ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); 617 | if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef 618 | 619 | /***/ }, 620 | /* 15 */ 621 | /***/ function(module, exports) { 622 | 623 | var core = module.exports = {version: '1.2.6'}; 624 | if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef 625 | 626 | /***/ }, 627 | /* 16 */ 628 | /***/ function(module, exports, __webpack_require__) { 629 | 630 | // optional / simple context binding 631 | var aFunction = __webpack_require__(17); 632 | module.exports = function(fn, that, length){ 633 | aFunction(fn); 634 | if(that === undefined)return fn; 635 | switch(length){ 636 | case 1: return function(a){ 637 | return fn.call(that, a); 638 | }; 639 | case 2: return function(a, b){ 640 | return fn.call(that, a, b); 641 | }; 642 | case 3: return function(a, b, c){ 643 | return fn.call(that, a, b, c); 644 | }; 645 | } 646 | return function(/* ...args */){ 647 | return fn.apply(that, arguments); 648 | }; 649 | }; 650 | 651 | /***/ }, 652 | /* 17 */ 653 | /***/ function(module, exports) { 654 | 655 | module.exports = function(it){ 656 | if(typeof it != 'function')throw TypeError(it + ' is not a function!'); 657 | return it; 658 | }; 659 | 660 | /***/ }, 661 | /* 18 */ 662 | /***/ function(module, exports) { 663 | 664 | module.exports = function(exec){ 665 | try { 666 | return !!exec(); 667 | } catch(e){ 668 | return true; 669 | } 670 | }; 671 | 672 | /***/ }, 673 | /* 19 */ 674 | /***/ function(module, exports, __webpack_require__) { 675 | 676 | "use strict"; 677 | 678 | var _Object$create = __webpack_require__(20)["default"]; 679 | 680 | var _Object$setPrototypeOf = __webpack_require__(22)["default"]; 681 | 682 | exports["default"] = function (subClass, superClass) { 683 | if (typeof superClass !== "function" && superClass !== null) { 684 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 685 | } 686 | 687 | subClass.prototype = _Object$create(superClass && superClass.prototype, { 688 | constructor: { 689 | value: subClass, 690 | enumerable: false, 691 | writable: true, 692 | configurable: true 693 | } 694 | }); 695 | if (superClass) _Object$setPrototypeOf ? _Object$setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 696 | }; 697 | 698 | exports.__esModule = true; 699 | 700 | /***/ }, 701 | /* 20 */ 702 | /***/ function(module, exports, __webpack_require__) { 703 | 704 | module.exports = { "default": __webpack_require__(21), __esModule: true }; 705 | 706 | /***/ }, 707 | /* 21 */ 708 | /***/ function(module, exports, __webpack_require__) { 709 | 710 | var $ = __webpack_require__(6); 711 | module.exports = function create(P, D){ 712 | return $.create(P, D); 713 | }; 714 | 715 | /***/ }, 716 | /* 22 */ 717 | /***/ function(module, exports, __webpack_require__) { 718 | 719 | module.exports = { "default": __webpack_require__(23), __esModule: true }; 720 | 721 | /***/ }, 722 | /* 23 */ 723 | /***/ function(module, exports, __webpack_require__) { 724 | 725 | __webpack_require__(24); 726 | module.exports = __webpack_require__(15).Object.setPrototypeOf; 727 | 728 | /***/ }, 729 | /* 24 */ 730 | /***/ function(module, exports, __webpack_require__) { 731 | 732 | // 19.1.3.19 Object.setPrototypeOf(O, proto) 733 | var $export = __webpack_require__(13); 734 | $export($export.S, 'Object', {setPrototypeOf: __webpack_require__(25).set}); 735 | 736 | /***/ }, 737 | /* 25 */ 738 | /***/ function(module, exports, __webpack_require__) { 739 | 740 | // Works with __proto__ only. Old v8 can't work with null proto objects. 741 | /* eslint-disable no-proto */ 742 | var getDesc = __webpack_require__(6).getDesc 743 | , isObject = __webpack_require__(26) 744 | , anObject = __webpack_require__(27); 745 | var check = function(O, proto){ 746 | anObject(O); 747 | if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!"); 748 | }; 749 | module.exports = { 750 | set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line 751 | function(test, buggy, set){ 752 | try { 753 | set = __webpack_require__(16)(Function.call, getDesc(Object.prototype, '__proto__').set, 2); 754 | set(test, []); 755 | buggy = !(test instanceof Array); 756 | } catch(e){ buggy = true; } 757 | return function setPrototypeOf(O, proto){ 758 | check(O, proto); 759 | if(buggy)O.__proto__ = proto; 760 | else set(O, proto); 761 | return O; 762 | }; 763 | }({}, false) : undefined), 764 | check: check 765 | }; 766 | 767 | /***/ }, 768 | /* 26 */ 769 | /***/ function(module, exports) { 770 | 771 | module.exports = function(it){ 772 | return typeof it === 'object' ? it !== null : typeof it === 'function'; 773 | }; 774 | 775 | /***/ }, 776 | /* 27 */ 777 | /***/ function(module, exports, __webpack_require__) { 778 | 779 | var isObject = __webpack_require__(26); 780 | module.exports = function(it){ 781 | if(!isObject(it))throw TypeError(it + ' is not an object!'); 782 | return it; 783 | }; 784 | 785 | /***/ }, 786 | /* 28 */ 787 | /***/ function(module, exports, __webpack_require__) { 788 | 789 | "use strict"; 790 | 791 | var _Object$defineProperty = __webpack_require__(29)["default"]; 792 | 793 | exports["default"] = (function () { 794 | function defineProperties(target, props) { 795 | for (var i = 0; i < props.length; i++) { 796 | var descriptor = props[i]; 797 | descriptor.enumerable = descriptor.enumerable || false; 798 | descriptor.configurable = true; 799 | if ("value" in descriptor) descriptor.writable = true; 800 | 801 | _Object$defineProperty(target, descriptor.key, descriptor); 802 | } 803 | } 804 | 805 | return function (Constructor, protoProps, staticProps) { 806 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 807 | if (staticProps) defineProperties(Constructor, staticProps); 808 | return Constructor; 809 | }; 810 | })(); 811 | 812 | exports.__esModule = true; 813 | 814 | /***/ }, 815 | /* 29 */ 816 | /***/ function(module, exports, __webpack_require__) { 817 | 818 | module.exports = { "default": __webpack_require__(30), __esModule: true }; 819 | 820 | /***/ }, 821 | /* 30 */ 822 | /***/ function(module, exports, __webpack_require__) { 823 | 824 | var $ = __webpack_require__(6); 825 | module.exports = function defineProperty(it, key, desc){ 826 | return $.setDesc(it, key, desc); 827 | }; 828 | 829 | /***/ }, 830 | /* 31 */ 831 | /***/ function(module, exports) { 832 | 833 | "use strict"; 834 | 835 | exports["default"] = function (instance, Constructor) { 836 | if (!(instance instanceof Constructor)) { 837 | throw new TypeError("Cannot call a class as a function"); 838 | } 839 | }; 840 | 841 | exports.__esModule = true; 842 | 843 | /***/ }, 844 | /* 32 */ 845 | /***/ function(module, exports, __webpack_require__) { 846 | 847 | // This method of obtaining a reference to the global object needs to be 848 | // kept identical to the way it is obtained in runtime.js 849 | var g = 850 | typeof global === "object" ? global : 851 | typeof window === "object" ? window : 852 | typeof self === "object" ? self : this; 853 | 854 | // Use `getOwnPropertyNames` because not all browsers support calling 855 | // `hasOwnProperty` on the global `self` object in a worker. See #183. 856 | var hadRuntime = g.regeneratorRuntime && 857 | Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0; 858 | 859 | // Save the old regeneratorRuntime in case it needs to be restored later. 860 | var oldRuntime = hadRuntime && g.regeneratorRuntime; 861 | 862 | // Force reevalutation of runtime.js. 863 | g.regeneratorRuntime = undefined; 864 | 865 | module.exports = __webpack_require__(33); 866 | 867 | if (hadRuntime) { 868 | // Restore the original runtime. 869 | g.regeneratorRuntime = oldRuntime; 870 | } else { 871 | // Remove the global property added by runtime.js. 872 | try { 873 | delete g.regeneratorRuntime; 874 | } catch(e) { 875 | g.regeneratorRuntime = undefined; 876 | } 877 | } 878 | 879 | module.exports = { "default": module.exports, __esModule: true }; 880 | 881 | 882 | /***/ }, 883 | /* 33 */ 884 | /***/ function(module, exports, __webpack_require__) { 885 | 886 | /** 887 | * Copyright (c) 2014, Facebook, Inc. 888 | * All rights reserved. 889 | * 890 | * This source code is licensed under the BSD-style license found in the 891 | * https://raw.github.com/facebook/regenerator/master/LICENSE file. An 892 | * additional grant of patent rights can be found in the PATENTS file in 893 | * the same directory. 894 | */ 895 | 896 | "use strict"; 897 | 898 | var _Symbol = __webpack_require__(34)["default"]; 899 | 900 | var _Object$create = __webpack_require__(20)["default"]; 901 | 902 | var _Object$setPrototypeOf = __webpack_require__(22)["default"]; 903 | 904 | var _Promise = __webpack_require__(52)["default"]; 905 | 906 | !(function (global) { 907 | "use strict"; 908 | 909 | var hasOwn = Object.prototype.hasOwnProperty; 910 | var undefined; // More compressible than void 0. 911 | var $Symbol = typeof _Symbol === "function" ? _Symbol : {}; 912 | var iteratorSymbol = $Symbol.iterator || "@@iterator"; 913 | var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; 914 | 915 | var inModule = typeof module === "object"; 916 | var runtime = global.regeneratorRuntime; 917 | if (runtime) { 918 | if (inModule) { 919 | // If regeneratorRuntime is defined globally and we're in a module, 920 | // make the exports object identical to regeneratorRuntime. 921 | module.exports = runtime; 922 | } 923 | // Don't bother evaluating the rest of this file if the runtime was 924 | // already defined globally. 925 | return; 926 | } 927 | 928 | // Define the runtime globally (as expected by generated code) as either 929 | // module.exports (if we're in a module) or a new, empty object. 930 | runtime = global.regeneratorRuntime = inModule ? module.exports : {}; 931 | 932 | function wrap(innerFn, outerFn, self, tryLocsList) { 933 | // If outerFn provided, then outerFn.prototype instanceof Generator. 934 | var generator = _Object$create((outerFn || Generator).prototype); 935 | var context = new Context(tryLocsList || []); 936 | 937 | // The ._invoke method unifies the implementations of the .next, 938 | // .throw, and .return methods. 939 | generator._invoke = makeInvokeMethod(innerFn, self, context); 940 | 941 | return generator; 942 | } 943 | runtime.wrap = wrap; 944 | 945 | // Try/catch helper to minimize deoptimizations. Returns a completion 946 | // record like context.tryEntries[i].completion. This interface could 947 | // have been (and was previously) designed to take a closure to be 948 | // invoked without arguments, but in all the cases we care about we 949 | // already have an existing method we want to call, so there's no need 950 | // to create a new function object. We can even get away with assuming 951 | // the method takes exactly one argument, since that happens to be true 952 | // in every case, so we don't have to touch the arguments object. The 953 | // only additional allocation required is the completion record, which 954 | // has a stable shape and so hopefully should be cheap to allocate. 955 | function tryCatch(fn, obj, arg) { 956 | try { 957 | return { type: "normal", arg: fn.call(obj, arg) }; 958 | } catch (err) { 959 | return { type: "throw", arg: err }; 960 | } 961 | } 962 | 963 | var GenStateSuspendedStart = "suspendedStart"; 964 | var GenStateSuspendedYield = "suspendedYield"; 965 | var GenStateExecuting = "executing"; 966 | var GenStateCompleted = "completed"; 967 | 968 | // Returning this object from the innerFn has the same effect as 969 | // breaking out of the dispatch switch statement. 970 | var ContinueSentinel = {}; 971 | 972 | // Dummy constructor functions that we use as the .constructor and 973 | // .constructor.prototype properties for functions that return Generator 974 | // objects. For full spec compliance, you may wish to configure your 975 | // minifier not to mangle the names of these two functions. 976 | function Generator() {} 977 | function GeneratorFunction() {} 978 | function GeneratorFunctionPrototype() {} 979 | 980 | var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype; 981 | GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; 982 | GeneratorFunctionPrototype.constructor = GeneratorFunction; 983 | GeneratorFunctionPrototype[toStringTagSymbol] = GeneratorFunction.displayName = "GeneratorFunction"; 984 | 985 | // Helper for defining the .next, .throw, and .return methods of the 986 | // Iterator interface in terms of a single ._invoke method. 987 | function defineIteratorMethods(prototype) { 988 | ["next", "throw", "return"].forEach(function (method) { 989 | prototype[method] = function (arg) { 990 | return this._invoke(method, arg); 991 | }; 992 | }); 993 | } 994 | 995 | runtime.isGeneratorFunction = function (genFun) { 996 | var ctor = typeof genFun === "function" && genFun.constructor; 997 | return ctor ? ctor === GeneratorFunction || 998 | // For the native GeneratorFunction constructor, the best we can 999 | // do is to check its .name property. 1000 | (ctor.displayName || ctor.name) === "GeneratorFunction" : false; 1001 | }; 1002 | 1003 | runtime.mark = function (genFun) { 1004 | if (_Object$setPrototypeOf) { 1005 | _Object$setPrototypeOf(genFun, GeneratorFunctionPrototype); 1006 | } else { 1007 | genFun.__proto__ = GeneratorFunctionPrototype; 1008 | if (!(toStringTagSymbol in genFun)) { 1009 | genFun[toStringTagSymbol] = "GeneratorFunction"; 1010 | } 1011 | } 1012 | genFun.prototype = _Object$create(Gp); 1013 | return genFun; 1014 | }; 1015 | 1016 | // Within the body of any async function, `await x` is transformed to 1017 | // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test 1018 | // `value instanceof AwaitArgument` to determine if the yielded value is 1019 | // meant to be awaited. Some may consider the name of this method too 1020 | // cutesy, but they are curmudgeons. 1021 | runtime.awrap = function (arg) { 1022 | return new AwaitArgument(arg); 1023 | }; 1024 | 1025 | function AwaitArgument(arg) { 1026 | this.arg = arg; 1027 | } 1028 | 1029 | function AsyncIterator(generator) { 1030 | function invoke(method, arg, resolve, reject) { 1031 | var record = tryCatch(generator[method], generator, arg); 1032 | if (record.type === "throw") { 1033 | reject(record.arg); 1034 | } else { 1035 | var result = record.arg; 1036 | var value = result.value; 1037 | if (value instanceof AwaitArgument) { 1038 | return _Promise.resolve(value.arg).then(function (value) { 1039 | invoke("next", value, resolve, reject); 1040 | }, function (err) { 1041 | invoke("throw", err, resolve, reject); 1042 | }); 1043 | } 1044 | 1045 | return _Promise.resolve(value).then(function (unwrapped) { 1046 | // When a yielded Promise is resolved, its final value becomes 1047 | // the .value of the Promise<{value,done}> result for the 1048 | // current iteration. If the Promise is rejected, however, the 1049 | // result for this iteration will be rejected with the same 1050 | // reason. Note that rejections of yielded Promises are not 1051 | // thrown back into the generator function, as is the case 1052 | // when an awaited Promise is rejected. This difference in 1053 | // behavior between yield and await is important, because it 1054 | // allows the consumer to decide what to do with the yielded 1055 | // rejection (swallow it and continue, manually .throw it back 1056 | // into the generator, abandon iteration, whatever). With 1057 | // await, by contrast, there is no opportunity to examine the 1058 | // rejection reason outside the generator function, so the 1059 | // only option is to throw it from the await expression, and 1060 | // let the generator function handle the exception. 1061 | result.value = unwrapped; 1062 | resolve(result); 1063 | }, reject); 1064 | } 1065 | } 1066 | 1067 | if (typeof process === "object" && process.domain) { 1068 | invoke = process.domain.bind(invoke); 1069 | } 1070 | 1071 | var previousPromise; 1072 | 1073 | function enqueue(method, arg) { 1074 | function callInvokeWithMethodAndArg() { 1075 | return new _Promise(function (resolve, reject) { 1076 | invoke(method, arg, resolve, reject); 1077 | }); 1078 | } 1079 | 1080 | return previousPromise = 1081 | // If enqueue has been called before, then we want to wait until 1082 | // all previous Promises have been resolved before calling invoke, 1083 | // so that results are always delivered in the correct order. If 1084 | // enqueue has not been called before, then it is important to 1085 | // call invoke immediately, without waiting on a callback to fire, 1086 | // so that the async generator function has the opportunity to do 1087 | // any necessary setup in a predictable way. This predictability 1088 | // is why the Promise constructor synchronously invokes its 1089 | // executor callback, and why async functions synchronously 1090 | // execute code before the first await. Since we implement simple 1091 | // async functions in terms of async generators, it is especially 1092 | // important to get this right, even though it requires care. 1093 | previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, 1094 | // Avoid propagating failures to Promises returned by later 1095 | // invocations of the iterator. 1096 | callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); 1097 | } 1098 | 1099 | // Define the unified helper method that is used to implement .next, 1100 | // .throw, and .return (see defineIteratorMethods). 1101 | this._invoke = enqueue; 1102 | } 1103 | 1104 | defineIteratorMethods(AsyncIterator.prototype); 1105 | 1106 | // Note that simple async functions are implemented on top of 1107 | // AsyncIterator objects; they just return a Promise for the value of 1108 | // the final result produced by the iterator. 1109 | runtime.async = function (innerFn, outerFn, self, tryLocsList) { 1110 | var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList)); 1111 | 1112 | return runtime.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator. 1113 | : iter.next().then(function (result) { 1114 | return result.done ? result.value : iter.next(); 1115 | }); 1116 | }; 1117 | 1118 | function makeInvokeMethod(innerFn, self, context) { 1119 | var state = GenStateSuspendedStart; 1120 | 1121 | return function invoke(method, arg) { 1122 | if (state === GenStateExecuting) { 1123 | throw new Error("Generator is already running"); 1124 | } 1125 | 1126 | if (state === GenStateCompleted) { 1127 | if (method === "throw") { 1128 | throw arg; 1129 | } 1130 | 1131 | // Be forgiving, per 25.3.3.3.3 of the spec: 1132 | // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume 1133 | return doneResult(); 1134 | } 1135 | 1136 | while (true) { 1137 | var delegate = context.delegate; 1138 | if (delegate) { 1139 | if (method === "return" || method === "throw" && delegate.iterator[method] === undefined) { 1140 | // A return or throw (when the delegate iterator has no throw 1141 | // method) always terminates the yield* loop. 1142 | context.delegate = null; 1143 | 1144 | // If the delegate iterator has a return method, give it a 1145 | // chance to clean up. 1146 | var returnMethod = delegate.iterator["return"]; 1147 | if (returnMethod) { 1148 | var record = tryCatch(returnMethod, delegate.iterator, arg); 1149 | if (record.type === "throw") { 1150 | // If the return method threw an exception, let that 1151 | // exception prevail over the original return or throw. 1152 | method = "throw"; 1153 | arg = record.arg; 1154 | continue; 1155 | } 1156 | } 1157 | 1158 | if (method === "return") { 1159 | // Continue with the outer return, now that the delegate 1160 | // iterator has been terminated. 1161 | continue; 1162 | } 1163 | } 1164 | 1165 | var record = tryCatch(delegate.iterator[method], delegate.iterator, arg); 1166 | 1167 | if (record.type === "throw") { 1168 | context.delegate = null; 1169 | 1170 | // Like returning generator.throw(uncaught), but without the 1171 | // overhead of an extra function call. 1172 | method = "throw"; 1173 | arg = record.arg; 1174 | continue; 1175 | } 1176 | 1177 | // Delegate generator ran and handled its own exceptions so 1178 | // regardless of what the method was, we continue as if it is 1179 | // "next" with an undefined arg. 1180 | method = "next"; 1181 | arg = undefined; 1182 | 1183 | var info = record.arg; 1184 | if (info.done) { 1185 | context[delegate.resultName] = info.value; 1186 | context.next = delegate.nextLoc; 1187 | } else { 1188 | state = GenStateSuspendedYield; 1189 | return info; 1190 | } 1191 | 1192 | context.delegate = null; 1193 | } 1194 | 1195 | if (method === "next") { 1196 | if (state === GenStateSuspendedYield) { 1197 | context.sent = arg; 1198 | } else { 1199 | context.sent = undefined; 1200 | } 1201 | } else if (method === "throw") { 1202 | if (state === GenStateSuspendedStart) { 1203 | state = GenStateCompleted; 1204 | throw arg; 1205 | } 1206 | 1207 | if (context.dispatchException(arg)) { 1208 | // If the dispatched exception was caught by a catch block, 1209 | // then let that catch block handle the exception normally. 1210 | method = "next"; 1211 | arg = undefined; 1212 | } 1213 | } else if (method === "return") { 1214 | context.abrupt("return", arg); 1215 | } 1216 | 1217 | state = GenStateExecuting; 1218 | 1219 | var record = tryCatch(innerFn, self, context); 1220 | if (record.type === "normal") { 1221 | // If an exception is thrown from innerFn, we leave state === 1222 | // GenStateExecuting and loop back for another invocation. 1223 | state = context.done ? GenStateCompleted : GenStateSuspendedYield; 1224 | 1225 | var info = { 1226 | value: record.arg, 1227 | done: context.done 1228 | }; 1229 | 1230 | if (record.arg === ContinueSentinel) { 1231 | if (context.delegate && method === "next") { 1232 | // Deliberately forget the last sent value so that we don't 1233 | // accidentally pass it on to the delegate. 1234 | arg = undefined; 1235 | } 1236 | } else { 1237 | return info; 1238 | } 1239 | } else if (record.type === "throw") { 1240 | state = GenStateCompleted; 1241 | // Dispatch the exception by looping back around to the 1242 | // context.dispatchException(arg) call above. 1243 | method = "throw"; 1244 | arg = record.arg; 1245 | } 1246 | } 1247 | }; 1248 | } 1249 | 1250 | // Define Generator.prototype.{next,throw,return} in terms of the 1251 | // unified ._invoke helper method. 1252 | defineIteratorMethods(Gp); 1253 | 1254 | Gp[iteratorSymbol] = function () { 1255 | return this; 1256 | }; 1257 | 1258 | Gp[toStringTagSymbol] = "Generator"; 1259 | 1260 | Gp.toString = function () { 1261 | return "[object Generator]"; 1262 | }; 1263 | 1264 | function pushTryEntry(locs) { 1265 | var entry = { tryLoc: locs[0] }; 1266 | 1267 | if (1 in locs) { 1268 | entry.catchLoc = locs[1]; 1269 | } 1270 | 1271 | if (2 in locs) { 1272 | entry.finallyLoc = locs[2]; 1273 | entry.afterLoc = locs[3]; 1274 | } 1275 | 1276 | this.tryEntries.push(entry); 1277 | } 1278 | 1279 | function resetTryEntry(entry) { 1280 | var record = entry.completion || {}; 1281 | record.type = "normal"; 1282 | delete record.arg; 1283 | entry.completion = record; 1284 | } 1285 | 1286 | function Context(tryLocsList) { 1287 | // The root entry object (effectively a try statement without a catch 1288 | // or a finally block) gives us a place to store values thrown from 1289 | // locations where there is no enclosing try statement. 1290 | this.tryEntries = [{ tryLoc: "root" }]; 1291 | tryLocsList.forEach(pushTryEntry, this); 1292 | this.reset(true); 1293 | } 1294 | 1295 | runtime.keys = function (object) { 1296 | var keys = []; 1297 | for (var key in object) { 1298 | keys.push(key); 1299 | } 1300 | keys.reverse(); 1301 | 1302 | // Rather than returning an object with a next method, we keep 1303 | // things simple and return the next function itself. 1304 | return function next() { 1305 | while (keys.length) { 1306 | var key = keys.pop(); 1307 | if (key in object) { 1308 | next.value = key; 1309 | next.done = false; 1310 | return next; 1311 | } 1312 | } 1313 | 1314 | // To avoid creating an additional object, we just hang the .value 1315 | // and .done properties off the next function object itself. This 1316 | // also ensures that the minifier will not anonymize the function. 1317 | next.done = true; 1318 | return next; 1319 | }; 1320 | }; 1321 | 1322 | function values(iterable) { 1323 | if (iterable) { 1324 | var iteratorMethod = iterable[iteratorSymbol]; 1325 | if (iteratorMethod) { 1326 | return iteratorMethod.call(iterable); 1327 | } 1328 | 1329 | if (typeof iterable.next === "function") { 1330 | return iterable; 1331 | } 1332 | 1333 | if (!isNaN(iterable.length)) { 1334 | var i = -1, 1335 | next = function next() { 1336 | while (++i < iterable.length) { 1337 | if (hasOwn.call(iterable, i)) { 1338 | next.value = iterable[i]; 1339 | next.done = false; 1340 | return next; 1341 | } 1342 | } 1343 | 1344 | next.value = undefined; 1345 | next.done = true; 1346 | 1347 | return next; 1348 | }; 1349 | 1350 | return next.next = next; 1351 | } 1352 | } 1353 | 1354 | // Return an iterator with no values. 1355 | return { next: doneResult }; 1356 | } 1357 | runtime.values = values; 1358 | 1359 | function doneResult() { 1360 | return { value: undefined, done: true }; 1361 | } 1362 | 1363 | Context.prototype = { 1364 | constructor: Context, 1365 | 1366 | reset: function reset(skipTempReset) { 1367 | this.prev = 0; 1368 | this.next = 0; 1369 | this.sent = undefined; 1370 | this.done = false; 1371 | this.delegate = null; 1372 | 1373 | this.tryEntries.forEach(resetTryEntry); 1374 | 1375 | if (!skipTempReset) { 1376 | for (var name in this) { 1377 | // Not sure about the optimal order of these conditions: 1378 | if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) { 1379 | this[name] = undefined; 1380 | } 1381 | } 1382 | } 1383 | }, 1384 | 1385 | stop: function stop() { 1386 | this.done = true; 1387 | 1388 | var rootEntry = this.tryEntries[0]; 1389 | var rootRecord = rootEntry.completion; 1390 | if (rootRecord.type === "throw") { 1391 | throw rootRecord.arg; 1392 | } 1393 | 1394 | return this.rval; 1395 | }, 1396 | 1397 | dispatchException: function dispatchException(exception) { 1398 | if (this.done) { 1399 | throw exception; 1400 | } 1401 | 1402 | var context = this; 1403 | function handle(loc, caught) { 1404 | record.type = "throw"; 1405 | record.arg = exception; 1406 | context.next = loc; 1407 | return !!caught; 1408 | } 1409 | 1410 | for (var i = this.tryEntries.length - 1; i >= 0; --i) { 1411 | var entry = this.tryEntries[i]; 1412 | var record = entry.completion; 1413 | 1414 | if (entry.tryLoc === "root") { 1415 | // Exception thrown outside of any try block that could handle 1416 | // it, so set the completion value of the entire function to 1417 | // throw the exception. 1418 | return handle("end"); 1419 | } 1420 | 1421 | if (entry.tryLoc <= this.prev) { 1422 | var hasCatch = hasOwn.call(entry, "catchLoc"); 1423 | var hasFinally = hasOwn.call(entry, "finallyLoc"); 1424 | 1425 | if (hasCatch && hasFinally) { 1426 | if (this.prev < entry.catchLoc) { 1427 | return handle(entry.catchLoc, true); 1428 | } else if (this.prev < entry.finallyLoc) { 1429 | return handle(entry.finallyLoc); 1430 | } 1431 | } else if (hasCatch) { 1432 | if (this.prev < entry.catchLoc) { 1433 | return handle(entry.catchLoc, true); 1434 | } 1435 | } else if (hasFinally) { 1436 | if (this.prev < entry.finallyLoc) { 1437 | return handle(entry.finallyLoc); 1438 | } 1439 | } else { 1440 | throw new Error("try statement without catch or finally"); 1441 | } 1442 | } 1443 | } 1444 | }, 1445 | 1446 | abrupt: function abrupt(type, arg) { 1447 | for (var i = this.tryEntries.length - 1; i >= 0; --i) { 1448 | var entry = this.tryEntries[i]; 1449 | if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { 1450 | var finallyEntry = entry; 1451 | break; 1452 | } 1453 | } 1454 | 1455 | if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) { 1456 | // Ignore the finally entry if control is not jumping to a 1457 | // location outside the try/catch block. 1458 | finallyEntry = null; 1459 | } 1460 | 1461 | var record = finallyEntry ? finallyEntry.completion : {}; 1462 | record.type = type; 1463 | record.arg = arg; 1464 | 1465 | if (finallyEntry) { 1466 | this.next = finallyEntry.finallyLoc; 1467 | } else { 1468 | this.complete(record); 1469 | } 1470 | 1471 | return ContinueSentinel; 1472 | }, 1473 | 1474 | complete: function complete(record, afterLoc) { 1475 | if (record.type === "throw") { 1476 | throw record.arg; 1477 | } 1478 | 1479 | if (record.type === "break" || record.type === "continue") { 1480 | this.next = record.arg; 1481 | } else if (record.type === "return") { 1482 | this.rval = record.arg; 1483 | this.next = "end"; 1484 | } else if (record.type === "normal" && afterLoc) { 1485 | this.next = afterLoc; 1486 | } 1487 | }, 1488 | 1489 | finish: function finish(finallyLoc) { 1490 | for (var i = this.tryEntries.length - 1; i >= 0; --i) { 1491 | var entry = this.tryEntries[i]; 1492 | if (entry.finallyLoc === finallyLoc) { 1493 | this.complete(entry.completion, entry.afterLoc); 1494 | resetTryEntry(entry); 1495 | return ContinueSentinel; 1496 | } 1497 | } 1498 | }, 1499 | 1500 | "catch": function _catch(tryLoc) { 1501 | for (var i = this.tryEntries.length - 1; i >= 0; --i) { 1502 | var entry = this.tryEntries[i]; 1503 | if (entry.tryLoc === tryLoc) { 1504 | var record = entry.completion; 1505 | if (record.type === "throw") { 1506 | var thrown = record.arg; 1507 | resetTryEntry(entry); 1508 | } 1509 | return thrown; 1510 | } 1511 | } 1512 | 1513 | // The context.catch method must only be called with a location 1514 | // argument that corresponds to a known catch block. 1515 | throw new Error("illegal catch attempt"); 1516 | }, 1517 | 1518 | delegateYield: function delegateYield(iterable, resultName, nextLoc) { 1519 | this.delegate = { 1520 | iterator: values(iterable), 1521 | resultName: resultName, 1522 | nextLoc: nextLoc 1523 | }; 1524 | 1525 | return ContinueSentinel; 1526 | } 1527 | }; 1528 | })( 1529 | // Among the various tricks for obtaining a reference to the global 1530 | // object, this seems to be the most reliable technique that does not 1531 | // use indirect eval (which violates Content Security Policy). 1532 | typeof global === "object" ? global : typeof window === "object" ? window : typeof self === "object" ? self : undefined); 1533 | 1534 | /***/ }, 1535 | /* 34 */ 1536 | /***/ function(module, exports, __webpack_require__) { 1537 | 1538 | module.exports = { "default": __webpack_require__(35), __esModule: true }; 1539 | 1540 | /***/ }, 1541 | /* 35 */ 1542 | /***/ function(module, exports, __webpack_require__) { 1543 | 1544 | __webpack_require__(36); 1545 | __webpack_require__(51); 1546 | module.exports = __webpack_require__(15).Symbol; 1547 | 1548 | /***/ }, 1549 | /* 36 */ 1550 | /***/ function(module, exports, __webpack_require__) { 1551 | 1552 | 'use strict'; 1553 | // ECMAScript 6 symbols shim 1554 | var $ = __webpack_require__(6) 1555 | , global = __webpack_require__(14) 1556 | , has = __webpack_require__(37) 1557 | , DESCRIPTORS = __webpack_require__(38) 1558 | , $export = __webpack_require__(13) 1559 | , redefine = __webpack_require__(39) 1560 | , $fails = __webpack_require__(18) 1561 | , shared = __webpack_require__(42) 1562 | , setToStringTag = __webpack_require__(43) 1563 | , uid = __webpack_require__(45) 1564 | , wks = __webpack_require__(44) 1565 | , keyOf = __webpack_require__(46) 1566 | , $names = __webpack_require__(47) 1567 | , enumKeys = __webpack_require__(48) 1568 | , isArray = __webpack_require__(49) 1569 | , anObject = __webpack_require__(27) 1570 | , toIObject = __webpack_require__(8) 1571 | , createDesc = __webpack_require__(41) 1572 | , getDesc = $.getDesc 1573 | , setDesc = $.setDesc 1574 | , _create = $.create 1575 | , getNames = $names.get 1576 | , $Symbol = global.Symbol 1577 | , $JSON = global.JSON 1578 | , _stringify = $JSON && $JSON.stringify 1579 | , setter = false 1580 | , HIDDEN = wks('_hidden') 1581 | , isEnum = $.isEnum 1582 | , SymbolRegistry = shared('symbol-registry') 1583 | , AllSymbols = shared('symbols') 1584 | , useNative = typeof $Symbol == 'function' 1585 | , ObjectProto = Object.prototype; 1586 | 1587 | // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 1588 | var setSymbolDesc = DESCRIPTORS && $fails(function(){ 1589 | return _create(setDesc({}, 'a', { 1590 | get: function(){ return setDesc(this, 'a', {value: 7}).a; } 1591 | })).a != 7; 1592 | }) ? function(it, key, D){ 1593 | var protoDesc = getDesc(ObjectProto, key); 1594 | if(protoDesc)delete ObjectProto[key]; 1595 | setDesc(it, key, D); 1596 | if(protoDesc && it !== ObjectProto)setDesc(ObjectProto, key, protoDesc); 1597 | } : setDesc; 1598 | 1599 | var wrap = function(tag){ 1600 | var sym = AllSymbols[tag] = _create($Symbol.prototype); 1601 | sym._k = tag; 1602 | DESCRIPTORS && setter && setSymbolDesc(ObjectProto, tag, { 1603 | configurable: true, 1604 | set: function(value){ 1605 | if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false; 1606 | setSymbolDesc(this, tag, createDesc(1, value)); 1607 | } 1608 | }); 1609 | return sym; 1610 | }; 1611 | 1612 | var isSymbol = function(it){ 1613 | return typeof it == 'symbol'; 1614 | }; 1615 | 1616 | var $defineProperty = function defineProperty(it, key, D){ 1617 | if(D && has(AllSymbols, key)){ 1618 | if(!D.enumerable){ 1619 | if(!has(it, HIDDEN))setDesc(it, HIDDEN, createDesc(1, {})); 1620 | it[HIDDEN][key] = true; 1621 | } else { 1622 | if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false; 1623 | D = _create(D, {enumerable: createDesc(0, false)}); 1624 | } return setSymbolDesc(it, key, D); 1625 | } return setDesc(it, key, D); 1626 | }; 1627 | var $defineProperties = function defineProperties(it, P){ 1628 | anObject(it); 1629 | var keys = enumKeys(P = toIObject(P)) 1630 | , i = 0 1631 | , l = keys.length 1632 | , key; 1633 | while(l > i)$defineProperty(it, key = keys[i++], P[key]); 1634 | return it; 1635 | }; 1636 | var $create = function create(it, P){ 1637 | return P === undefined ? _create(it) : $defineProperties(_create(it), P); 1638 | }; 1639 | var $propertyIsEnumerable = function propertyIsEnumerable(key){ 1640 | var E = isEnum.call(this, key); 1641 | return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] 1642 | ? E : true; 1643 | }; 1644 | var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){ 1645 | var D = getDesc(it = toIObject(it), key); 1646 | if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true; 1647 | return D; 1648 | }; 1649 | var $getOwnPropertyNames = function getOwnPropertyNames(it){ 1650 | var names = getNames(toIObject(it)) 1651 | , result = [] 1652 | , i = 0 1653 | , key; 1654 | while(names.length > i)if(!has(AllSymbols, key = names[i++]) && key != HIDDEN)result.push(key); 1655 | return result; 1656 | }; 1657 | var $getOwnPropertySymbols = function getOwnPropertySymbols(it){ 1658 | var names = getNames(toIObject(it)) 1659 | , result = [] 1660 | , i = 0 1661 | , key; 1662 | while(names.length > i)if(has(AllSymbols, key = names[i++]))result.push(AllSymbols[key]); 1663 | return result; 1664 | }; 1665 | var $stringify = function stringify(it){ 1666 | if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined 1667 | var args = [it] 1668 | , i = 1 1669 | , $$ = arguments 1670 | , replacer, $replacer; 1671 | while($$.length > i)args.push($$[i++]); 1672 | replacer = args[1]; 1673 | if(typeof replacer == 'function')$replacer = replacer; 1674 | if($replacer || !isArray(replacer))replacer = function(key, value){ 1675 | if($replacer)value = $replacer.call(this, key, value); 1676 | if(!isSymbol(value))return value; 1677 | }; 1678 | args[1] = replacer; 1679 | return _stringify.apply($JSON, args); 1680 | }; 1681 | var buggyJSON = $fails(function(){ 1682 | var S = $Symbol(); 1683 | // MS Edge converts symbol values to JSON as {} 1684 | // WebKit converts symbol values to JSON as null 1685 | // V8 throws on boxed symbols 1686 | return _stringify([S]) != '[null]' || _stringify({a: S}) != '{}' || _stringify(Object(S)) != '{}'; 1687 | }); 1688 | 1689 | // 19.4.1.1 Symbol([description]) 1690 | if(!useNative){ 1691 | $Symbol = function Symbol(){ 1692 | if(isSymbol(this))throw TypeError('Symbol is not a constructor'); 1693 | return wrap(uid(arguments.length > 0 ? arguments[0] : undefined)); 1694 | }; 1695 | redefine($Symbol.prototype, 'toString', function toString(){ 1696 | return this._k; 1697 | }); 1698 | 1699 | isSymbol = function(it){ 1700 | return it instanceof $Symbol; 1701 | }; 1702 | 1703 | $.create = $create; 1704 | $.isEnum = $propertyIsEnumerable; 1705 | $.getDesc = $getOwnPropertyDescriptor; 1706 | $.setDesc = $defineProperty; 1707 | $.setDescs = $defineProperties; 1708 | $.getNames = $names.get = $getOwnPropertyNames; 1709 | $.getSymbols = $getOwnPropertySymbols; 1710 | 1711 | if(DESCRIPTORS && !__webpack_require__(50)){ 1712 | redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); 1713 | } 1714 | } 1715 | 1716 | var symbolStatics = { 1717 | // 19.4.2.1 Symbol.for(key) 1718 | 'for': function(key){ 1719 | return has(SymbolRegistry, key += '') 1720 | ? SymbolRegistry[key] 1721 | : SymbolRegistry[key] = $Symbol(key); 1722 | }, 1723 | // 19.4.2.5 Symbol.keyFor(sym) 1724 | keyFor: function keyFor(key){ 1725 | return keyOf(SymbolRegistry, key); 1726 | }, 1727 | useSetter: function(){ setter = true; }, 1728 | useSimple: function(){ setter = false; } 1729 | }; 1730 | // 19.4.2.2 Symbol.hasInstance 1731 | // 19.4.2.3 Symbol.isConcatSpreadable 1732 | // 19.4.2.4 Symbol.iterator 1733 | // 19.4.2.6 Symbol.match 1734 | // 19.4.2.8 Symbol.replace 1735 | // 19.4.2.9 Symbol.search 1736 | // 19.4.2.10 Symbol.species 1737 | // 19.4.2.11 Symbol.split 1738 | // 19.4.2.12 Symbol.toPrimitive 1739 | // 19.4.2.13 Symbol.toStringTag 1740 | // 19.4.2.14 Symbol.unscopables 1741 | $.each.call(( 1742 | 'hasInstance,isConcatSpreadable,iterator,match,replace,search,' + 1743 | 'species,split,toPrimitive,toStringTag,unscopables' 1744 | ).split(','), function(it){ 1745 | var sym = wks(it); 1746 | symbolStatics[it] = useNative ? sym : wrap(sym); 1747 | }); 1748 | 1749 | setter = true; 1750 | 1751 | $export($export.G + $export.W, {Symbol: $Symbol}); 1752 | 1753 | $export($export.S, 'Symbol', symbolStatics); 1754 | 1755 | $export($export.S + $export.F * !useNative, 'Object', { 1756 | // 19.1.2.2 Object.create(O [, Properties]) 1757 | create: $create, 1758 | // 19.1.2.4 Object.defineProperty(O, P, Attributes) 1759 | defineProperty: $defineProperty, 1760 | // 19.1.2.3 Object.defineProperties(O, Properties) 1761 | defineProperties: $defineProperties, 1762 | // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) 1763 | getOwnPropertyDescriptor: $getOwnPropertyDescriptor, 1764 | // 19.1.2.7 Object.getOwnPropertyNames(O) 1765 | getOwnPropertyNames: $getOwnPropertyNames, 1766 | // 19.1.2.8 Object.getOwnPropertySymbols(O) 1767 | getOwnPropertySymbols: $getOwnPropertySymbols 1768 | }); 1769 | 1770 | // 24.3.2 JSON.stringify(value [, replacer [, space]]) 1771 | $JSON && $export($export.S + $export.F * (!useNative || buggyJSON), 'JSON', {stringify: $stringify}); 1772 | 1773 | // 19.4.3.5 Symbol.prototype[@@toStringTag] 1774 | setToStringTag($Symbol, 'Symbol'); 1775 | // 20.2.1.9 Math[@@toStringTag] 1776 | setToStringTag(Math, 'Math', true); 1777 | // 24.3.3 JSON[@@toStringTag] 1778 | setToStringTag(global.JSON, 'JSON', true); 1779 | 1780 | /***/ }, 1781 | /* 37 */ 1782 | /***/ function(module, exports) { 1783 | 1784 | var hasOwnProperty = {}.hasOwnProperty; 1785 | module.exports = function(it, key){ 1786 | return hasOwnProperty.call(it, key); 1787 | }; 1788 | 1789 | /***/ }, 1790 | /* 38 */ 1791 | /***/ function(module, exports, __webpack_require__) { 1792 | 1793 | // Thank's IE8 for his funny defineProperty 1794 | module.exports = !__webpack_require__(18)(function(){ 1795 | return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; 1796 | }); 1797 | 1798 | /***/ }, 1799 | /* 39 */ 1800 | /***/ function(module, exports, __webpack_require__) { 1801 | 1802 | module.exports = __webpack_require__(40); 1803 | 1804 | /***/ }, 1805 | /* 40 */ 1806 | /***/ function(module, exports, __webpack_require__) { 1807 | 1808 | var $ = __webpack_require__(6) 1809 | , createDesc = __webpack_require__(41); 1810 | module.exports = __webpack_require__(38) ? function(object, key, value){ 1811 | return $.setDesc(object, key, createDesc(1, value)); 1812 | } : function(object, key, value){ 1813 | object[key] = value; 1814 | return object; 1815 | }; 1816 | 1817 | /***/ }, 1818 | /* 41 */ 1819 | /***/ function(module, exports) { 1820 | 1821 | module.exports = function(bitmap, value){ 1822 | return { 1823 | enumerable : !(bitmap & 1), 1824 | configurable: !(bitmap & 2), 1825 | writable : !(bitmap & 4), 1826 | value : value 1827 | }; 1828 | }; 1829 | 1830 | /***/ }, 1831 | /* 42 */ 1832 | /***/ function(module, exports, __webpack_require__) { 1833 | 1834 | var global = __webpack_require__(14) 1835 | , SHARED = '__core-js_shared__' 1836 | , store = global[SHARED] || (global[SHARED] = {}); 1837 | module.exports = function(key){ 1838 | return store[key] || (store[key] = {}); 1839 | }; 1840 | 1841 | /***/ }, 1842 | /* 43 */ 1843 | /***/ function(module, exports, __webpack_require__) { 1844 | 1845 | var def = __webpack_require__(6).setDesc 1846 | , has = __webpack_require__(37) 1847 | , TAG = __webpack_require__(44)('toStringTag'); 1848 | 1849 | module.exports = function(it, tag, stat){ 1850 | if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); 1851 | }; 1852 | 1853 | /***/ }, 1854 | /* 44 */ 1855 | /***/ function(module, exports, __webpack_require__) { 1856 | 1857 | var store = __webpack_require__(42)('wks') 1858 | , uid = __webpack_require__(45) 1859 | , Symbol = __webpack_require__(14).Symbol; 1860 | module.exports = function(name){ 1861 | return store[name] || (store[name] = 1862 | Symbol && Symbol[name] || (Symbol || uid)('Symbol.' + name)); 1863 | }; 1864 | 1865 | /***/ }, 1866 | /* 45 */ 1867 | /***/ function(module, exports) { 1868 | 1869 | var id = 0 1870 | , px = Math.random(); 1871 | module.exports = function(key){ 1872 | return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); 1873 | }; 1874 | 1875 | /***/ }, 1876 | /* 46 */ 1877 | /***/ function(module, exports, __webpack_require__) { 1878 | 1879 | var $ = __webpack_require__(6) 1880 | , toIObject = __webpack_require__(8); 1881 | module.exports = function(object, el){ 1882 | var O = toIObject(object) 1883 | , keys = $.getKeys(O) 1884 | , length = keys.length 1885 | , index = 0 1886 | , key; 1887 | while(length > index)if(O[key = keys[index++]] === el)return key; 1888 | }; 1889 | 1890 | /***/ }, 1891 | /* 47 */ 1892 | /***/ function(module, exports, __webpack_require__) { 1893 | 1894 | // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window 1895 | var toIObject = __webpack_require__(8) 1896 | , getNames = __webpack_require__(6).getNames 1897 | , toString = {}.toString; 1898 | 1899 | var windowNames = typeof window == 'object' && Object.getOwnPropertyNames 1900 | ? Object.getOwnPropertyNames(window) : []; 1901 | 1902 | var getWindowNames = function(it){ 1903 | try { 1904 | return getNames(it); 1905 | } catch(e){ 1906 | return windowNames.slice(); 1907 | } 1908 | }; 1909 | 1910 | module.exports.get = function getOwnPropertyNames(it){ 1911 | if(windowNames && toString.call(it) == '[object Window]')return getWindowNames(it); 1912 | return getNames(toIObject(it)); 1913 | }; 1914 | 1915 | /***/ }, 1916 | /* 48 */ 1917 | /***/ function(module, exports, __webpack_require__) { 1918 | 1919 | // all enumerable object keys, includes symbols 1920 | var $ = __webpack_require__(6); 1921 | module.exports = function(it){ 1922 | var keys = $.getKeys(it) 1923 | , getSymbols = $.getSymbols; 1924 | if(getSymbols){ 1925 | var symbols = getSymbols(it) 1926 | , isEnum = $.isEnum 1927 | , i = 0 1928 | , key; 1929 | while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))keys.push(key); 1930 | } 1931 | return keys; 1932 | }; 1933 | 1934 | /***/ }, 1935 | /* 49 */ 1936 | /***/ function(module, exports, __webpack_require__) { 1937 | 1938 | // 7.2.2 IsArray(argument) 1939 | var cof = __webpack_require__(10); 1940 | module.exports = Array.isArray || function(arg){ 1941 | return cof(arg) == 'Array'; 1942 | }; 1943 | 1944 | /***/ }, 1945 | /* 50 */ 1946 | /***/ function(module, exports) { 1947 | 1948 | module.exports = true; 1949 | 1950 | /***/ }, 1951 | /* 51 */ 1952 | /***/ function(module, exports) { 1953 | 1954 | 1955 | 1956 | /***/ }, 1957 | /* 52 */ 1958 | /***/ function(module, exports, __webpack_require__) { 1959 | 1960 | module.exports = { "default": __webpack_require__(53), __esModule: true }; 1961 | 1962 | /***/ }, 1963 | /* 53 */ 1964 | /***/ function(module, exports, __webpack_require__) { 1965 | 1966 | __webpack_require__(51); 1967 | __webpack_require__(54); 1968 | __webpack_require__(60); 1969 | __webpack_require__(64); 1970 | module.exports = __webpack_require__(15).Promise; 1971 | 1972 | /***/ }, 1973 | /* 54 */ 1974 | /***/ function(module, exports, __webpack_require__) { 1975 | 1976 | 'use strict'; 1977 | var $at = __webpack_require__(55)(true); 1978 | 1979 | // 21.1.3.27 String.prototype[@@iterator]() 1980 | __webpack_require__(57)(String, 'String', function(iterated){ 1981 | this._t = String(iterated); // target 1982 | this._i = 0; // next index 1983 | // 21.1.5.2.1 %StringIteratorPrototype%.next() 1984 | }, function(){ 1985 | var O = this._t 1986 | , index = this._i 1987 | , point; 1988 | if(index >= O.length)return {value: undefined, done: true}; 1989 | point = $at(O, index); 1990 | this._i += point.length; 1991 | return {value: point, done: false}; 1992 | }); 1993 | 1994 | /***/ }, 1995 | /* 55 */ 1996 | /***/ function(module, exports, __webpack_require__) { 1997 | 1998 | var toInteger = __webpack_require__(56) 1999 | , defined = __webpack_require__(11); 2000 | // true -> String#at 2001 | // false -> String#codePointAt 2002 | module.exports = function(TO_STRING){ 2003 | return function(that, pos){ 2004 | var s = String(defined(that)) 2005 | , i = toInteger(pos) 2006 | , l = s.length 2007 | , a, b; 2008 | if(i < 0 || i >= l)return TO_STRING ? '' : undefined; 2009 | a = s.charCodeAt(i); 2010 | return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff 2011 | ? TO_STRING ? s.charAt(i) : a 2012 | : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; 2013 | }; 2014 | }; 2015 | 2016 | /***/ }, 2017 | /* 56 */ 2018 | /***/ function(module, exports) { 2019 | 2020 | // 7.1.4 ToInteger 2021 | var ceil = Math.ceil 2022 | , floor = Math.floor; 2023 | module.exports = function(it){ 2024 | return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); 2025 | }; 2026 | 2027 | /***/ }, 2028 | /* 57 */ 2029 | /***/ function(module, exports, __webpack_require__) { 2030 | 2031 | 'use strict'; 2032 | var LIBRARY = __webpack_require__(50) 2033 | , $export = __webpack_require__(13) 2034 | , redefine = __webpack_require__(39) 2035 | , hide = __webpack_require__(40) 2036 | , has = __webpack_require__(37) 2037 | , Iterators = __webpack_require__(58) 2038 | , $iterCreate = __webpack_require__(59) 2039 | , setToStringTag = __webpack_require__(43) 2040 | , getProto = __webpack_require__(6).getProto 2041 | , ITERATOR = __webpack_require__(44)('iterator') 2042 | , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` 2043 | , FF_ITERATOR = '@@iterator' 2044 | , KEYS = 'keys' 2045 | , VALUES = 'values'; 2046 | 2047 | var returnThis = function(){ return this; }; 2048 | 2049 | module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ 2050 | $iterCreate(Constructor, NAME, next); 2051 | var getMethod = function(kind){ 2052 | if(!BUGGY && kind in proto)return proto[kind]; 2053 | switch(kind){ 2054 | case KEYS: return function keys(){ return new Constructor(this, kind); }; 2055 | case VALUES: return function values(){ return new Constructor(this, kind); }; 2056 | } return function entries(){ return new Constructor(this, kind); }; 2057 | }; 2058 | var TAG = NAME + ' Iterator' 2059 | , DEF_VALUES = DEFAULT == VALUES 2060 | , VALUES_BUG = false 2061 | , proto = Base.prototype 2062 | , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] 2063 | , $default = $native || getMethod(DEFAULT) 2064 | , methods, key; 2065 | // Fix native 2066 | if($native){ 2067 | var IteratorPrototype = getProto($default.call(new Base)); 2068 | // Set @@toStringTag to native iterators 2069 | setToStringTag(IteratorPrototype, TAG, true); 2070 | // FF fix 2071 | if(!LIBRARY && has(proto, FF_ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); 2072 | // fix Array#{values, @@iterator}.name in V8 / FF 2073 | if(DEF_VALUES && $native.name !== VALUES){ 2074 | VALUES_BUG = true; 2075 | $default = function values(){ return $native.call(this); }; 2076 | } 2077 | } 2078 | // Define iterator 2079 | if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ 2080 | hide(proto, ITERATOR, $default); 2081 | } 2082 | // Plug for library 2083 | Iterators[NAME] = $default; 2084 | Iterators[TAG] = returnThis; 2085 | if(DEFAULT){ 2086 | methods = { 2087 | values: DEF_VALUES ? $default : getMethod(VALUES), 2088 | keys: IS_SET ? $default : getMethod(KEYS), 2089 | entries: !DEF_VALUES ? $default : getMethod('entries') 2090 | }; 2091 | if(FORCED)for(key in methods){ 2092 | if(!(key in proto))redefine(proto, key, methods[key]); 2093 | } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); 2094 | } 2095 | return methods; 2096 | }; 2097 | 2098 | /***/ }, 2099 | /* 58 */ 2100 | /***/ function(module, exports) { 2101 | 2102 | module.exports = {}; 2103 | 2104 | /***/ }, 2105 | /* 59 */ 2106 | /***/ function(module, exports, __webpack_require__) { 2107 | 2108 | 'use strict'; 2109 | var $ = __webpack_require__(6) 2110 | , descriptor = __webpack_require__(41) 2111 | , setToStringTag = __webpack_require__(43) 2112 | , IteratorPrototype = {}; 2113 | 2114 | // 25.1.2.1.1 %IteratorPrototype%[@@iterator]() 2115 | __webpack_require__(40)(IteratorPrototype, __webpack_require__(44)('iterator'), function(){ return this; }); 2116 | 2117 | module.exports = function(Constructor, NAME, next){ 2118 | Constructor.prototype = $.create(IteratorPrototype, {next: descriptor(1, next)}); 2119 | setToStringTag(Constructor, NAME + ' Iterator'); 2120 | }; 2121 | 2122 | /***/ }, 2123 | /* 60 */ 2124 | /***/ function(module, exports, __webpack_require__) { 2125 | 2126 | __webpack_require__(61); 2127 | var Iterators = __webpack_require__(58); 2128 | Iterators.NodeList = Iterators.HTMLCollection = Iterators.Array; 2129 | 2130 | /***/ }, 2131 | /* 61 */ 2132 | /***/ function(module, exports, __webpack_require__) { 2133 | 2134 | 'use strict'; 2135 | var addToUnscopables = __webpack_require__(62) 2136 | , step = __webpack_require__(63) 2137 | , Iterators = __webpack_require__(58) 2138 | , toIObject = __webpack_require__(8); 2139 | 2140 | // 22.1.3.4 Array.prototype.entries() 2141 | // 22.1.3.13 Array.prototype.keys() 2142 | // 22.1.3.29 Array.prototype.values() 2143 | // 22.1.3.30 Array.prototype[@@iterator]() 2144 | module.exports = __webpack_require__(57)(Array, 'Array', function(iterated, kind){ 2145 | this._t = toIObject(iterated); // target 2146 | this._i = 0; // next index 2147 | this._k = kind; // kind 2148 | // 22.1.5.2.1 %ArrayIteratorPrototype%.next() 2149 | }, function(){ 2150 | var O = this._t 2151 | , kind = this._k 2152 | , index = this._i++; 2153 | if(!O || index >= O.length){ 2154 | this._t = undefined; 2155 | return step(1); 2156 | } 2157 | if(kind == 'keys' )return step(0, index); 2158 | if(kind == 'values')return step(0, O[index]); 2159 | return step(0, [index, O[index]]); 2160 | }, 'values'); 2161 | 2162 | // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) 2163 | Iterators.Arguments = Iterators.Array; 2164 | 2165 | addToUnscopables('keys'); 2166 | addToUnscopables('values'); 2167 | addToUnscopables('entries'); 2168 | 2169 | /***/ }, 2170 | /* 62 */ 2171 | /***/ function(module, exports) { 2172 | 2173 | module.exports = function(){ /* empty */ }; 2174 | 2175 | /***/ }, 2176 | /* 63 */ 2177 | /***/ function(module, exports) { 2178 | 2179 | module.exports = function(done, value){ 2180 | return {value: value, done: !!done}; 2181 | }; 2182 | 2183 | /***/ }, 2184 | /* 64 */ 2185 | /***/ function(module, exports, __webpack_require__) { 2186 | 2187 | 'use strict'; 2188 | var $ = __webpack_require__(6) 2189 | , LIBRARY = __webpack_require__(50) 2190 | , global = __webpack_require__(14) 2191 | , ctx = __webpack_require__(16) 2192 | , classof = __webpack_require__(65) 2193 | , $export = __webpack_require__(13) 2194 | , isObject = __webpack_require__(26) 2195 | , anObject = __webpack_require__(27) 2196 | , aFunction = __webpack_require__(17) 2197 | , strictNew = __webpack_require__(66) 2198 | , forOf = __webpack_require__(67) 2199 | , setProto = __webpack_require__(25).set 2200 | , same = __webpack_require__(72) 2201 | , SPECIES = __webpack_require__(44)('species') 2202 | , speciesConstructor = __webpack_require__(73) 2203 | , asap = __webpack_require__(74) 2204 | , PROMISE = 'Promise' 2205 | , process = global.process 2206 | , isNode = classof(process) == 'process' 2207 | , P = global[PROMISE] 2208 | , Wrapper; 2209 | 2210 | var testResolve = function(sub){ 2211 | var test = new P(function(){}); 2212 | if(sub)test.constructor = Object; 2213 | return P.resolve(test) === test; 2214 | }; 2215 | 2216 | var USE_NATIVE = function(){ 2217 | var works = false; 2218 | function P2(x){ 2219 | var self = new P(x); 2220 | setProto(self, P2.prototype); 2221 | return self; 2222 | } 2223 | try { 2224 | works = P && P.resolve && testResolve(); 2225 | setProto(P2, P); 2226 | P2.prototype = $.create(P.prototype, {constructor: {value: P2}}); 2227 | // actual Firefox has broken subclass support, test that 2228 | if(!(P2.resolve(5).then(function(){}) instanceof P2)){ 2229 | works = false; 2230 | } 2231 | // actual V8 bug, https://code.google.com/p/v8/issues/detail?id=4162 2232 | if(works && __webpack_require__(38)){ 2233 | var thenableThenGotten = false; 2234 | P.resolve($.setDesc({}, 'then', { 2235 | get: function(){ thenableThenGotten = true; } 2236 | })); 2237 | works = thenableThenGotten; 2238 | } 2239 | } catch(e){ works = false; } 2240 | return works; 2241 | }(); 2242 | 2243 | // helpers 2244 | var sameConstructor = function(a, b){ 2245 | // library wrapper special case 2246 | if(LIBRARY && a === P && b === Wrapper)return true; 2247 | return same(a, b); 2248 | }; 2249 | var getConstructor = function(C){ 2250 | var S = anObject(C)[SPECIES]; 2251 | return S != undefined ? S : C; 2252 | }; 2253 | var isThenable = function(it){ 2254 | var then; 2255 | return isObject(it) && typeof (then = it.then) == 'function' ? then : false; 2256 | }; 2257 | var PromiseCapability = function(C){ 2258 | var resolve, reject; 2259 | this.promise = new C(function($$resolve, $$reject){ 2260 | if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor'); 2261 | resolve = $$resolve; 2262 | reject = $$reject; 2263 | }); 2264 | this.resolve = aFunction(resolve), 2265 | this.reject = aFunction(reject) 2266 | }; 2267 | var perform = function(exec){ 2268 | try { 2269 | exec(); 2270 | } catch(e){ 2271 | return {error: e}; 2272 | } 2273 | }; 2274 | var notify = function(record, isReject){ 2275 | if(record.n)return; 2276 | record.n = true; 2277 | var chain = record.c; 2278 | asap(function(){ 2279 | var value = record.v 2280 | , ok = record.s == 1 2281 | , i = 0; 2282 | var run = function(reaction){ 2283 | var handler = ok ? reaction.ok : reaction.fail 2284 | , resolve = reaction.resolve 2285 | , reject = reaction.reject 2286 | , result, then; 2287 | try { 2288 | if(handler){ 2289 | if(!ok)record.h = true; 2290 | result = handler === true ? value : handler(value); 2291 | if(result === reaction.promise){ 2292 | reject(TypeError('Promise-chain cycle')); 2293 | } else if(then = isThenable(result)){ 2294 | then.call(result, resolve, reject); 2295 | } else resolve(result); 2296 | } else reject(value); 2297 | } catch(e){ 2298 | reject(e); 2299 | } 2300 | }; 2301 | while(chain.length > i)run(chain[i++]); // variable length - can't use forEach 2302 | chain.length = 0; 2303 | record.n = false; 2304 | if(isReject)setTimeout(function(){ 2305 | var promise = record.p 2306 | , handler, console; 2307 | if(isUnhandled(promise)){ 2308 | if(isNode){ 2309 | process.emit('unhandledRejection', value, promise); 2310 | } else if(handler = global.onunhandledrejection){ 2311 | handler({promise: promise, reason: value}); 2312 | } else if((console = global.console) && console.error){ 2313 | console.error('Unhandled promise rejection', value); 2314 | } 2315 | } record.a = undefined; 2316 | }, 1); 2317 | }); 2318 | }; 2319 | var isUnhandled = function(promise){ 2320 | var record = promise._d 2321 | , chain = record.a || record.c 2322 | , i = 0 2323 | , reaction; 2324 | if(record.h)return false; 2325 | while(chain.length > i){ 2326 | reaction = chain[i++]; 2327 | if(reaction.fail || !isUnhandled(reaction.promise))return false; 2328 | } return true; 2329 | }; 2330 | var $reject = function(value){ 2331 | var record = this; 2332 | if(record.d)return; 2333 | record.d = true; 2334 | record = record.r || record; // unwrap 2335 | record.v = value; 2336 | record.s = 2; 2337 | record.a = record.c.slice(); 2338 | notify(record, true); 2339 | }; 2340 | var $resolve = function(value){ 2341 | var record = this 2342 | , then; 2343 | if(record.d)return; 2344 | record.d = true; 2345 | record = record.r || record; // unwrap 2346 | try { 2347 | if(record.p === value)throw TypeError("Promise can't be resolved itself"); 2348 | if(then = isThenable(value)){ 2349 | asap(function(){ 2350 | var wrapper = {r: record, d: false}; // wrap 2351 | try { 2352 | then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); 2353 | } catch(e){ 2354 | $reject.call(wrapper, e); 2355 | } 2356 | }); 2357 | } else { 2358 | record.v = value; 2359 | record.s = 1; 2360 | notify(record, false); 2361 | } 2362 | } catch(e){ 2363 | $reject.call({r: record, d: false}, e); // wrap 2364 | } 2365 | }; 2366 | 2367 | // constructor polyfill 2368 | if(!USE_NATIVE){ 2369 | // 25.4.3.1 Promise(executor) 2370 | P = function Promise(executor){ 2371 | aFunction(executor); 2372 | var record = this._d = { 2373 | p: strictNew(this, P, PROMISE), // <- promise 2374 | c: [], // <- awaiting reactions 2375 | a: undefined, // <- checked in isUnhandled reactions 2376 | s: 0, // <- state 2377 | d: false, // <- done 2378 | v: undefined, // <- value 2379 | h: false, // <- handled rejection 2380 | n: false // <- notify 2381 | }; 2382 | try { 2383 | executor(ctx($resolve, record, 1), ctx($reject, record, 1)); 2384 | } catch(err){ 2385 | $reject.call(record, err); 2386 | } 2387 | }; 2388 | __webpack_require__(79)(P.prototype, { 2389 | // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) 2390 | then: function then(onFulfilled, onRejected){ 2391 | var reaction = new PromiseCapability(speciesConstructor(this, P)) 2392 | , promise = reaction.promise 2393 | , record = this._d; 2394 | reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; 2395 | reaction.fail = typeof onRejected == 'function' && onRejected; 2396 | record.c.push(reaction); 2397 | if(record.a)record.a.push(reaction); 2398 | if(record.s)notify(record, false); 2399 | return promise; 2400 | }, 2401 | // 25.4.5.1 Promise.prototype.catch(onRejected) 2402 | 'catch': function(onRejected){ 2403 | return this.then(undefined, onRejected); 2404 | } 2405 | }); 2406 | } 2407 | 2408 | $export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: P}); 2409 | __webpack_require__(43)(P, PROMISE); 2410 | __webpack_require__(80)(PROMISE); 2411 | Wrapper = __webpack_require__(15)[PROMISE]; 2412 | 2413 | // statics 2414 | $export($export.S + $export.F * !USE_NATIVE, PROMISE, { 2415 | // 25.4.4.5 Promise.reject(r) 2416 | reject: function reject(r){ 2417 | var capability = new PromiseCapability(this) 2418 | , $$reject = capability.reject; 2419 | $$reject(r); 2420 | return capability.promise; 2421 | } 2422 | }); 2423 | $export($export.S + $export.F * (!USE_NATIVE || testResolve(true)), PROMISE, { 2424 | // 25.4.4.6 Promise.resolve(x) 2425 | resolve: function resolve(x){ 2426 | // instanceof instead of internal slot check because we should fix it without replacement native Promise core 2427 | if(x instanceof P && sameConstructor(x.constructor, this))return x; 2428 | var capability = new PromiseCapability(this) 2429 | , $$resolve = capability.resolve; 2430 | $$resolve(x); 2431 | return capability.promise; 2432 | } 2433 | }); 2434 | $export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(81)(function(iter){ 2435 | P.all(iter)['catch'](function(){}); 2436 | })), PROMISE, { 2437 | // 25.4.4.1 Promise.all(iterable) 2438 | all: function all(iterable){ 2439 | var C = getConstructor(this) 2440 | , capability = new PromiseCapability(C) 2441 | , resolve = capability.resolve 2442 | , reject = capability.reject 2443 | , values = []; 2444 | var abrupt = perform(function(){ 2445 | forOf(iterable, false, values.push, values); 2446 | var remaining = values.length 2447 | , results = Array(remaining); 2448 | if(remaining)$.each.call(values, function(promise, index){ 2449 | var alreadyCalled = false; 2450 | C.resolve(promise).then(function(value){ 2451 | if(alreadyCalled)return; 2452 | alreadyCalled = true; 2453 | results[index] = value; 2454 | --remaining || resolve(results); 2455 | }, reject); 2456 | }); 2457 | else resolve(results); 2458 | }); 2459 | if(abrupt)reject(abrupt.error); 2460 | return capability.promise; 2461 | }, 2462 | // 25.4.4.4 Promise.race(iterable) 2463 | race: function race(iterable){ 2464 | var C = getConstructor(this) 2465 | , capability = new PromiseCapability(C) 2466 | , reject = capability.reject; 2467 | var abrupt = perform(function(){ 2468 | forOf(iterable, false, function(promise){ 2469 | C.resolve(promise).then(capability.resolve, reject); 2470 | }); 2471 | }); 2472 | if(abrupt)reject(abrupt.error); 2473 | return capability.promise; 2474 | } 2475 | }); 2476 | 2477 | /***/ }, 2478 | /* 65 */ 2479 | /***/ function(module, exports, __webpack_require__) { 2480 | 2481 | // getting tag from 19.1.3.6 Object.prototype.toString() 2482 | var cof = __webpack_require__(10) 2483 | , TAG = __webpack_require__(44)('toStringTag') 2484 | // ES3 wrong here 2485 | , ARG = cof(function(){ return arguments; }()) == 'Arguments'; 2486 | 2487 | module.exports = function(it){ 2488 | var O, T, B; 2489 | return it === undefined ? 'Undefined' : it === null ? 'Null' 2490 | // @@toStringTag case 2491 | : typeof (T = (O = Object(it))[TAG]) == 'string' ? T 2492 | // builtinTag case 2493 | : ARG ? cof(O) 2494 | // ES3 arguments fallback 2495 | : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; 2496 | }; 2497 | 2498 | /***/ }, 2499 | /* 66 */ 2500 | /***/ function(module, exports) { 2501 | 2502 | module.exports = function(it, Constructor, name){ 2503 | if(!(it instanceof Constructor))throw TypeError(name + ": use the 'new' operator!"); 2504 | return it; 2505 | }; 2506 | 2507 | /***/ }, 2508 | /* 67 */ 2509 | /***/ function(module, exports, __webpack_require__) { 2510 | 2511 | var ctx = __webpack_require__(16) 2512 | , call = __webpack_require__(68) 2513 | , isArrayIter = __webpack_require__(69) 2514 | , anObject = __webpack_require__(27) 2515 | , toLength = __webpack_require__(70) 2516 | , getIterFn = __webpack_require__(71); 2517 | module.exports = function(iterable, entries, fn, that){ 2518 | var iterFn = getIterFn(iterable) 2519 | , f = ctx(fn, that, entries ? 2 : 1) 2520 | , index = 0 2521 | , length, step, iterator; 2522 | if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!'); 2523 | // fast case for arrays with default iterator 2524 | if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){ 2525 | entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); 2526 | } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){ 2527 | call(iterator, f, step.value, entries); 2528 | } 2529 | }; 2530 | 2531 | /***/ }, 2532 | /* 68 */ 2533 | /***/ function(module, exports, __webpack_require__) { 2534 | 2535 | // call something on iterator step with safe closing on error 2536 | var anObject = __webpack_require__(27); 2537 | module.exports = function(iterator, fn, value, entries){ 2538 | try { 2539 | return entries ? fn(anObject(value)[0], value[1]) : fn(value); 2540 | // 7.4.6 IteratorClose(iterator, completion) 2541 | } catch(e){ 2542 | var ret = iterator['return']; 2543 | if(ret !== undefined)anObject(ret.call(iterator)); 2544 | throw e; 2545 | } 2546 | }; 2547 | 2548 | /***/ }, 2549 | /* 69 */ 2550 | /***/ function(module, exports, __webpack_require__) { 2551 | 2552 | // check on default Array iterator 2553 | var Iterators = __webpack_require__(58) 2554 | , ITERATOR = __webpack_require__(44)('iterator') 2555 | , ArrayProto = Array.prototype; 2556 | 2557 | module.exports = function(it){ 2558 | return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); 2559 | }; 2560 | 2561 | /***/ }, 2562 | /* 70 */ 2563 | /***/ function(module, exports, __webpack_require__) { 2564 | 2565 | // 7.1.15 ToLength 2566 | var toInteger = __webpack_require__(56) 2567 | , min = Math.min; 2568 | module.exports = function(it){ 2569 | return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 2570 | }; 2571 | 2572 | /***/ }, 2573 | /* 71 */ 2574 | /***/ function(module, exports, __webpack_require__) { 2575 | 2576 | var classof = __webpack_require__(65) 2577 | , ITERATOR = __webpack_require__(44)('iterator') 2578 | , Iterators = __webpack_require__(58); 2579 | module.exports = __webpack_require__(15).getIteratorMethod = function(it){ 2580 | if(it != undefined)return it[ITERATOR] 2581 | || it['@@iterator'] 2582 | || Iterators[classof(it)]; 2583 | }; 2584 | 2585 | /***/ }, 2586 | /* 72 */ 2587 | /***/ function(module, exports) { 2588 | 2589 | // 7.2.9 SameValue(x, y) 2590 | module.exports = Object.is || function is(x, y){ 2591 | return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y; 2592 | }; 2593 | 2594 | /***/ }, 2595 | /* 73 */ 2596 | /***/ function(module, exports, __webpack_require__) { 2597 | 2598 | // 7.3.20 SpeciesConstructor(O, defaultConstructor) 2599 | var anObject = __webpack_require__(27) 2600 | , aFunction = __webpack_require__(17) 2601 | , SPECIES = __webpack_require__(44)('species'); 2602 | module.exports = function(O, D){ 2603 | var C = anObject(O).constructor, S; 2604 | return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); 2605 | }; 2606 | 2607 | /***/ }, 2608 | /* 74 */ 2609 | /***/ function(module, exports, __webpack_require__) { 2610 | 2611 | var global = __webpack_require__(14) 2612 | , macrotask = __webpack_require__(75).set 2613 | , Observer = global.MutationObserver || global.WebKitMutationObserver 2614 | , process = global.process 2615 | , Promise = global.Promise 2616 | , isNode = __webpack_require__(10)(process) == 'process' 2617 | , head, last, notify; 2618 | 2619 | var flush = function(){ 2620 | var parent, domain, fn; 2621 | if(isNode && (parent = process.domain)){ 2622 | process.domain = null; 2623 | parent.exit(); 2624 | } 2625 | while(head){ 2626 | domain = head.domain; 2627 | fn = head.fn; 2628 | if(domain)domain.enter(); 2629 | fn(); // <- currently we use it only for Promise - try / catch not required 2630 | if(domain)domain.exit(); 2631 | head = head.next; 2632 | } last = undefined; 2633 | if(parent)parent.enter(); 2634 | }; 2635 | 2636 | // Node.js 2637 | if(isNode){ 2638 | notify = function(){ 2639 | process.nextTick(flush); 2640 | }; 2641 | // browsers with MutationObserver 2642 | } else if(Observer){ 2643 | var toggle = 1 2644 | , node = document.createTextNode(''); 2645 | new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new 2646 | notify = function(){ 2647 | node.data = toggle = -toggle; 2648 | }; 2649 | // environments with maybe non-completely correct, but existent Promise 2650 | } else if(Promise && Promise.resolve){ 2651 | notify = function(){ 2652 | Promise.resolve().then(flush); 2653 | }; 2654 | // for other environments - macrotask based on: 2655 | // - setImmediate 2656 | // - MessageChannel 2657 | // - window.postMessag 2658 | // - onreadystatechange 2659 | // - setTimeout 2660 | } else { 2661 | notify = function(){ 2662 | // strange IE + webpack dev server bug - use .call(global) 2663 | macrotask.call(global, flush); 2664 | }; 2665 | } 2666 | 2667 | module.exports = function asap(fn){ 2668 | var task = {fn: fn, next: undefined, domain: isNode && process.domain}; 2669 | if(last)last.next = task; 2670 | if(!head){ 2671 | head = task; 2672 | notify(); 2673 | } last = task; 2674 | }; 2675 | 2676 | /***/ }, 2677 | /* 75 */ 2678 | /***/ function(module, exports, __webpack_require__) { 2679 | 2680 | var ctx = __webpack_require__(16) 2681 | , invoke = __webpack_require__(76) 2682 | , html = __webpack_require__(77) 2683 | , cel = __webpack_require__(78) 2684 | , global = __webpack_require__(14) 2685 | , process = global.process 2686 | , setTask = global.setImmediate 2687 | , clearTask = global.clearImmediate 2688 | , MessageChannel = global.MessageChannel 2689 | , counter = 0 2690 | , queue = {} 2691 | , ONREADYSTATECHANGE = 'onreadystatechange' 2692 | , defer, channel, port; 2693 | var run = function(){ 2694 | var id = +this; 2695 | if(queue.hasOwnProperty(id)){ 2696 | var fn = queue[id]; 2697 | delete queue[id]; 2698 | fn(); 2699 | } 2700 | }; 2701 | var listner = function(event){ 2702 | run.call(event.data); 2703 | }; 2704 | // Node.js 0.9+ & IE10+ has setImmediate, otherwise: 2705 | if(!setTask || !clearTask){ 2706 | setTask = function setImmediate(fn){ 2707 | var args = [], i = 1; 2708 | while(arguments.length > i)args.push(arguments[i++]); 2709 | queue[++counter] = function(){ 2710 | invoke(typeof fn == 'function' ? fn : Function(fn), args); 2711 | }; 2712 | defer(counter); 2713 | return counter; 2714 | }; 2715 | clearTask = function clearImmediate(id){ 2716 | delete queue[id]; 2717 | }; 2718 | // Node.js 0.8- 2719 | if(__webpack_require__(10)(process) == 'process'){ 2720 | defer = function(id){ 2721 | process.nextTick(ctx(run, id, 1)); 2722 | }; 2723 | // Browsers with MessageChannel, includes WebWorkers 2724 | } else if(MessageChannel){ 2725 | channel = new MessageChannel; 2726 | port = channel.port2; 2727 | channel.port1.onmessage = listner; 2728 | defer = ctx(port.postMessage, port, 1); 2729 | // Browsers with postMessage, skip WebWorkers 2730 | // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' 2731 | } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ 2732 | defer = function(id){ 2733 | global.postMessage(id + '', '*'); 2734 | }; 2735 | global.addEventListener('message', listner, false); 2736 | // IE8- 2737 | } else if(ONREADYSTATECHANGE in cel('script')){ 2738 | defer = function(id){ 2739 | html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ 2740 | html.removeChild(this); 2741 | run.call(id); 2742 | }; 2743 | }; 2744 | // Rest old browsers 2745 | } else { 2746 | defer = function(id){ 2747 | setTimeout(ctx(run, id, 1), 0); 2748 | }; 2749 | } 2750 | } 2751 | module.exports = { 2752 | set: setTask, 2753 | clear: clearTask 2754 | }; 2755 | 2756 | /***/ }, 2757 | /* 76 */ 2758 | /***/ function(module, exports) { 2759 | 2760 | // fast apply, http://jsperf.lnkit.com/fast-apply/5 2761 | module.exports = function(fn, args, that){ 2762 | var un = that === undefined; 2763 | switch(args.length){ 2764 | case 0: return un ? fn() 2765 | : fn.call(that); 2766 | case 1: return un ? fn(args[0]) 2767 | : fn.call(that, args[0]); 2768 | case 2: return un ? fn(args[0], args[1]) 2769 | : fn.call(that, args[0], args[1]); 2770 | case 3: return un ? fn(args[0], args[1], args[2]) 2771 | : fn.call(that, args[0], args[1], args[2]); 2772 | case 4: return un ? fn(args[0], args[1], args[2], args[3]) 2773 | : fn.call(that, args[0], args[1], args[2], args[3]); 2774 | } return fn.apply(that, args); 2775 | }; 2776 | 2777 | /***/ }, 2778 | /* 77 */ 2779 | /***/ function(module, exports, __webpack_require__) { 2780 | 2781 | module.exports = __webpack_require__(14).document && document.documentElement; 2782 | 2783 | /***/ }, 2784 | /* 78 */ 2785 | /***/ function(module, exports, __webpack_require__) { 2786 | 2787 | var isObject = __webpack_require__(26) 2788 | , document = __webpack_require__(14).document 2789 | // in old IE typeof document.createElement is 'object' 2790 | , is = isObject(document) && isObject(document.createElement); 2791 | module.exports = function(it){ 2792 | return is ? document.createElement(it) : {}; 2793 | }; 2794 | 2795 | /***/ }, 2796 | /* 79 */ 2797 | /***/ function(module, exports, __webpack_require__) { 2798 | 2799 | var redefine = __webpack_require__(39); 2800 | module.exports = function(target, src){ 2801 | for(var key in src)redefine(target, key, src[key]); 2802 | return target; 2803 | }; 2804 | 2805 | /***/ }, 2806 | /* 80 */ 2807 | /***/ function(module, exports, __webpack_require__) { 2808 | 2809 | 'use strict'; 2810 | var core = __webpack_require__(15) 2811 | , $ = __webpack_require__(6) 2812 | , DESCRIPTORS = __webpack_require__(38) 2813 | , SPECIES = __webpack_require__(44)('species'); 2814 | 2815 | module.exports = function(KEY){ 2816 | var C = core[KEY]; 2817 | if(DESCRIPTORS && C && !C[SPECIES])$.setDesc(C, SPECIES, { 2818 | configurable: true, 2819 | get: function(){ return this; } 2820 | }); 2821 | }; 2822 | 2823 | /***/ }, 2824 | /* 81 */ 2825 | /***/ function(module, exports, __webpack_require__) { 2826 | 2827 | var ITERATOR = __webpack_require__(44)('iterator') 2828 | , SAFE_CLOSING = false; 2829 | 2830 | try { 2831 | var riter = [7][ITERATOR](); 2832 | riter['return'] = function(){ SAFE_CLOSING = true; }; 2833 | Array.from(riter, function(){ throw 2; }); 2834 | } catch(e){ /* empty */ } 2835 | 2836 | module.exports = function(exec, skipClosing){ 2837 | if(!skipClosing && !SAFE_CLOSING)return false; 2838 | var safe = false; 2839 | try { 2840 | var arr = [7] 2841 | , iter = arr[ITERATOR](); 2842 | iter.next = function(){ safe = true; }; 2843 | arr[ITERATOR] = function(){ return iter; }; 2844 | exec(arr); 2845 | } catch(e){ /* empty */ } 2846 | return safe; 2847 | }; 2848 | 2849 | /***/ }, 2850 | /* 82 */ 2851 | /***/ function(module, exports, __webpack_require__) { 2852 | 2853 | module.exports = { "default": __webpack_require__(83), __esModule: true }; 2854 | 2855 | /***/ }, 2856 | /* 83 */ 2857 | /***/ function(module, exports, __webpack_require__) { 2858 | 2859 | __webpack_require__(84); 2860 | module.exports = __webpack_require__(15).Object.assign; 2861 | 2862 | /***/ }, 2863 | /* 84 */ 2864 | /***/ function(module, exports, __webpack_require__) { 2865 | 2866 | // 19.1.3.1 Object.assign(target, source) 2867 | var $export = __webpack_require__(13); 2868 | 2869 | $export($export.S + $export.F, 'Object', {assign: __webpack_require__(85)}); 2870 | 2871 | /***/ }, 2872 | /* 85 */ 2873 | /***/ function(module, exports, __webpack_require__) { 2874 | 2875 | // 19.1.2.1 Object.assign(target, source, ...) 2876 | var $ = __webpack_require__(6) 2877 | , toObject = __webpack_require__(86) 2878 | , IObject = __webpack_require__(9); 2879 | 2880 | // should work with symbols and should have deterministic property order (V8 bug) 2881 | module.exports = __webpack_require__(18)(function(){ 2882 | var a = Object.assign 2883 | , A = {} 2884 | , B = {} 2885 | , S = Symbol() 2886 | , K = 'abcdefghijklmnopqrst'; 2887 | A[S] = 7; 2888 | K.split('').forEach(function(k){ B[k] = k; }); 2889 | return a({}, A)[S] != 7 || Object.keys(a({}, B)).join('') != K; 2890 | }) ? function assign(target, source){ // eslint-disable-line no-unused-vars 2891 | var T = toObject(target) 2892 | , $$ = arguments 2893 | , $$len = $$.length 2894 | , index = 1 2895 | , getKeys = $.getKeys 2896 | , getSymbols = $.getSymbols 2897 | , isEnum = $.isEnum; 2898 | while($$len > index){ 2899 | var S = IObject($$[index++]) 2900 | , keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S) 2901 | , length = keys.length 2902 | , j = 0 2903 | , key; 2904 | while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key]; 2905 | } 2906 | return T; 2907 | } : Object.assign; 2908 | 2909 | /***/ }, 2910 | /* 86 */ 2911 | /***/ function(module, exports, __webpack_require__) { 2912 | 2913 | // 7.1.13 ToObject(argument) 2914 | var defined = __webpack_require__(11); 2915 | module.exports = function(it){ 2916 | return Object(defined(it)); 2917 | }; 2918 | 2919 | /***/ }, 2920 | /* 87 */ 2921 | /***/ function(module, exports) { 2922 | 2923 | "use strict"; 2924 | 2925 | exports["default"] = function (obj) { 2926 | return obj && obj.__esModule ? obj : { 2927 | "default": obj 2928 | }; 2929 | }; 2930 | 2931 | exports.__esModule = true; 2932 | 2933 | /***/ }, 2934 | /* 88 */ 2935 | /***/ function(module, exports) { 2936 | 2937 | 2938 | /** 2939 | * slice() reference. 2940 | */ 2941 | 2942 | var slice = Array.prototype.slice; 2943 | 2944 | /** 2945 | * Expose `co`. 2946 | */ 2947 | 2948 | module.exports = co['default'] = co.co = co; 2949 | 2950 | /** 2951 | * Wrap the given generator `fn` into a 2952 | * function that returns a promise. 2953 | * This is a separate function so that 2954 | * every `co()` call doesn't create a new, 2955 | * unnecessary closure. 2956 | * 2957 | * @param {GeneratorFunction} fn 2958 | * @return {Function} 2959 | * @api public 2960 | */ 2961 | 2962 | co.wrap = function (fn) { 2963 | createPromise.__generatorFunction__ = fn; 2964 | return createPromise; 2965 | function createPromise() { 2966 | return co.call(this, fn.apply(this, arguments)); 2967 | } 2968 | }; 2969 | 2970 | /** 2971 | * Execute the generator function or a generator 2972 | * and return a promise. 2973 | * 2974 | * @param {Function} fn 2975 | * @return {Promise} 2976 | * @api public 2977 | */ 2978 | 2979 | function co(gen) { 2980 | var ctx = this; 2981 | var args = slice.call(arguments, 1) 2982 | 2983 | // we wrap everything in a promise to avoid promise chaining, 2984 | // which leads to memory leak errors. 2985 | // see https://github.com/tj/co/issues/180 2986 | return new Promise(function(resolve, reject) { 2987 | if (typeof gen === 'function') gen = gen.apply(ctx, args); 2988 | if (!gen || typeof gen.next !== 'function') return resolve(gen); 2989 | 2990 | onFulfilled(); 2991 | 2992 | /** 2993 | * @param {Mixed} res 2994 | * @return {Promise} 2995 | * @api private 2996 | */ 2997 | 2998 | function onFulfilled(res) { 2999 | var ret; 3000 | try { 3001 | ret = gen.next(res); 3002 | } catch (e) { 3003 | return reject(e); 3004 | } 3005 | next(ret); 3006 | } 3007 | 3008 | /** 3009 | * @param {Error} err 3010 | * @return {Promise} 3011 | * @api private 3012 | */ 3013 | 3014 | function onRejected(err) { 3015 | var ret; 3016 | try { 3017 | ret = gen.throw(err); 3018 | } catch (e) { 3019 | return reject(e); 3020 | } 3021 | next(ret); 3022 | } 3023 | 3024 | /** 3025 | * Get the next value in the generator, 3026 | * return a promise. 3027 | * 3028 | * @param {Object} ret 3029 | * @return {Promise} 3030 | * @api private 3031 | */ 3032 | 3033 | function next(ret) { 3034 | if (ret.done) return resolve(ret.value); 3035 | var value = toPromise.call(ctx, ret.value); 3036 | if (value && isPromise(value)) return value.then(onFulfilled, onRejected); 3037 | return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, ' 3038 | + 'but the following object was passed: "' + String(ret.value) + '"')); 3039 | } 3040 | }); 3041 | } 3042 | 3043 | /** 3044 | * Convert a `yield`ed value into a promise. 3045 | * 3046 | * @param {Mixed} obj 3047 | * @return {Promise} 3048 | * @api private 3049 | */ 3050 | 3051 | function toPromise(obj) { 3052 | if (!obj) return obj; 3053 | if (isPromise(obj)) return obj; 3054 | if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj); 3055 | if ('function' == typeof obj) return thunkToPromise.call(this, obj); 3056 | if (Array.isArray(obj)) return arrayToPromise.call(this, obj); 3057 | if (isObject(obj)) return objectToPromise.call(this, obj); 3058 | return obj; 3059 | } 3060 | 3061 | /** 3062 | * Convert a thunk to a promise. 3063 | * 3064 | * @param {Function} 3065 | * @return {Promise} 3066 | * @api private 3067 | */ 3068 | 3069 | function thunkToPromise(fn) { 3070 | var ctx = this; 3071 | return new Promise(function (resolve, reject) { 3072 | fn.call(ctx, function (err, res) { 3073 | if (err) return reject(err); 3074 | if (arguments.length > 2) res = slice.call(arguments, 1); 3075 | resolve(res); 3076 | }); 3077 | }); 3078 | } 3079 | 3080 | /** 3081 | * Convert an array of "yieldables" to a promise. 3082 | * Uses `Promise.all()` internally. 3083 | * 3084 | * @param {Array} obj 3085 | * @return {Promise} 3086 | * @api private 3087 | */ 3088 | 3089 | function arrayToPromise(obj) { 3090 | return Promise.all(obj.map(toPromise, this)); 3091 | } 3092 | 3093 | /** 3094 | * Convert an object of "yieldables" to a promise. 3095 | * Uses `Promise.all()` internally. 3096 | * 3097 | * @param {Object} obj 3098 | * @return {Promise} 3099 | * @api private 3100 | */ 3101 | 3102 | function objectToPromise(obj){ 3103 | var results = new obj.constructor(); 3104 | var keys = Object.keys(obj); 3105 | var promises = []; 3106 | for (var i = 0; i < keys.length; i++) { 3107 | var key = keys[i]; 3108 | var promise = toPromise.call(this, obj[key]); 3109 | if (promise && isPromise(promise)) defer(promise, key); 3110 | else results[key] = obj[key]; 3111 | } 3112 | return Promise.all(promises).then(function () { 3113 | return results; 3114 | }); 3115 | 3116 | function defer(promise, key) { 3117 | // predefine the key in the result 3118 | results[key] = undefined; 3119 | promises.push(promise.then(function (res) { 3120 | results[key] = res; 3121 | })); 3122 | } 3123 | } 3124 | 3125 | /** 3126 | * Check if `obj` is a promise. 3127 | * 3128 | * @param {Object} obj 3129 | * @return {Boolean} 3130 | * @api private 3131 | */ 3132 | 3133 | function isPromise(obj) { 3134 | return 'function' == typeof obj.then; 3135 | } 3136 | 3137 | /** 3138 | * Check if `obj` is a generator. 3139 | * 3140 | * @param {Mixed} obj 3141 | * @return {Boolean} 3142 | * @api private 3143 | */ 3144 | 3145 | function isGenerator(obj) { 3146 | return 'function' == typeof obj.next && 'function' == typeof obj.throw; 3147 | } 3148 | 3149 | /** 3150 | * Check if `obj` is a generator function. 3151 | * 3152 | * @param {Mixed} obj 3153 | * @return {Boolean} 3154 | * @api private 3155 | */ 3156 | function isGeneratorFunction(obj) { 3157 | var constructor = obj.constructor; 3158 | if (!constructor) return false; 3159 | if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true; 3160 | return isGenerator(constructor.prototype); 3161 | } 3162 | 3163 | /** 3164 | * Check for plain object. 3165 | * 3166 | * @param {Mixed} val 3167 | * @return {Boolean} 3168 | * @api private 3169 | */ 3170 | 3171 | function isObject(val) { 3172 | return Object == val.constructor; 3173 | } 3174 | 3175 | 3176 | /***/ }, 3177 | /* 89 */ 3178 | /***/ function(module, exports, __webpack_require__) { 3179 | 3180 | 'use strict'; 3181 | 3182 | var _createClass = __webpack_require__(28)['default']; 3183 | 3184 | var _classCallCheck = __webpack_require__(31)['default']; 3185 | 3186 | var _regeneratorRuntime = __webpack_require__(32)['default']; 3187 | 3188 | var _interopRequireDefault = __webpack_require__(87)['default']; 3189 | 3190 | Object.defineProperty(exports, '__esModule', { 3191 | value: true 3192 | }); 3193 | 3194 | var _co = __webpack_require__(88); 3195 | 3196 | var _co2 = _interopRequireDefault(_co); 3197 | 3198 | var Dispatcher = (function () { 3199 | function Dispatcher() { 3200 | _classCallCheck(this, Dispatcher); 3201 | 3202 | this.listeners = {}; 3203 | this._refs = 0; 3204 | } 3205 | 3206 | _createClass(Dispatcher, [{ 3207 | key: 'on', 3208 | value: function on(eventName, handler) { 3209 | var e = this.listeners[eventName] || []; 3210 | 3211 | // Whether handler exists or not 3212 | if (e.indexOf(handler) > -1) return; 3213 | 3214 | // Register 3215 | e.push(handler); 3216 | this.listeners[eventName] = e; 3217 | } 3218 | }, { 3219 | key: 'off', 3220 | value: function off(eventName, handler) { 3221 | var e = this.listeners[eventName] || null; 3222 | if (!e) return; 3223 | 3224 | // Whether handler exists or not 3225 | var index = e.indexOf(handler); 3226 | if (index == -1) return; 3227 | 3228 | // Remove 3229 | e.splice(index, 1); 3230 | } 3231 | }, { 3232 | key: 'hasListeners', 3233 | value: function hasListeners(eventName) { 3234 | var e = this.listeners[eventName] || []; 3235 | if (!e.length) return false; 3236 | 3237 | return true; 3238 | } 3239 | }, { 3240 | key: 'emit', 3241 | value: function emit(eventName) { 3242 | var idleEvent = eventName == 'idle'; 3243 | var e = this.listeners[eventName] || []; 3244 | var args = Array.prototype.slice.call(arguments); 3245 | args.shift(); 3246 | 3247 | // Increase reference counter 3248 | if (!idleEvent) { 3249 | this._refs++; 3250 | } 3251 | 3252 | return (function (done) { 3253 | 3254 | (0, _co2['default'])(_regeneratorRuntime.mark(function callee$3$0() { 3255 | var index, handler; 3256 | return _regeneratorRuntime.wrap(function callee$3$0$(context$4$0) { 3257 | while (1) switch (context$4$0.prev = context$4$0.next) { 3258 | case 0: 3259 | context$4$0.t0 = _regeneratorRuntime.keys(e); 3260 | 3261 | case 1: 3262 | if ((context$4$0.t1 = context$4$0.t0()).done) { 3263 | context$4$0.next = 17; 3264 | break; 3265 | } 3266 | 3267 | index = context$4$0.t1.value; 3268 | handler = _co2['default'].wrap(e[index]); 3269 | context$4$0.prev = 4; 3270 | context$4$0.next = 7; 3271 | return (function (done) { 3272 | handler.apply(this, args).then(function (ret) { 3273 | if (ret === undefined) { 3274 | done(null, args); 3275 | } else { 3276 | done(null, [ret]); 3277 | } 3278 | }, function (err) { 3279 | done(err); 3280 | }); 3281 | }).bind(this); 3282 | 3283 | case 7: 3284 | args = context$4$0.sent; 3285 | context$4$0.next = 15; 3286 | break; 3287 | 3288 | case 10: 3289 | context$4$0.prev = 10; 3290 | context$4$0.t2 = context$4$0['catch'](4); 3291 | 3292 | if (!(context$4$0.t2.message != 'document is not defined' || context$4$0.t2.stack.indexOf('at getActiveElement') == -1)) { 3293 | context$4$0.next = 15; 3294 | break; 3295 | } 3296 | 3297 | done(context$4$0.t2); 3298 | return context$4$0.abrupt('return'); 3299 | 3300 | case 15: 3301 | context$4$0.next = 1; 3302 | break; 3303 | 3304 | case 17: 3305 | 3306 | // Decrease reference counter 3307 | if (!idleEvent) { 3308 | this._refs--; 3309 | } 3310 | 3311 | done(); 3312 | 3313 | // Everything is done, fire the idle event 3314 | 3315 | if (!(!this._refs && !idleEvent)) { 3316 | context$4$0.next = 22; 3317 | break; 3318 | } 3319 | 3320 | context$4$0.next = 22; 3321 | return this.emit('idle'); 3322 | 3323 | case 22: 3324 | case 'end': 3325 | return context$4$0.stop(); 3326 | } 3327 | }, callee$3$0, this, [[4, 10]]); 3328 | }).bind(this)); 3329 | }).bind(this); 3330 | } 3331 | }]); 3332 | 3333 | return Dispatcher; 3334 | })(); 3335 | 3336 | exports['default'] = Dispatcher; 3337 | module.exports = exports['default']; 3338 | 3339 | // Callback is a generator 3340 | 3341 | // Run and wait 3342 | 3343 | // Workaround: React 0.13 has a bug on server rendering that document object wasn't found. 3344 | // Just ignore it because it doesn't affect anything on server-side. 3345 | 3346 | /***/ }, 3347 | /* 90 */ 3348 | /***/ function(module, exports, __webpack_require__) { 3349 | 3350 | 'use strict'; 3351 | 3352 | var _classCallCheck = __webpack_require__(31)['default']; 3353 | 3354 | var FEvent = function FEvent(event, args) { 3355 | _classCallCheck(this, FEvent); 3356 | 3357 | var parts = event.split('.'); 3358 | 3359 | this.path = event; 3360 | this.type = parts.shift(); 3361 | this.category = parts.shift(); 3362 | this.name = parts.join('.'); 3363 | this.args = Array.prototype.slice.call(args); 3364 | }; 3365 | 3366 | module.exports = FEvent; 3367 | 3368 | /***/ } 3369 | /******/ ]); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fluky", 3 | "version": "0.1.22", 4 | "description": "Framework for flux data flow pattern", 5 | "main": "./lib/fluky.js", 6 | "scripts": { 7 | "watch": "webpack -w", 8 | "compile": "webpack -p", 9 | "prepublish": "npm run compile", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [ 13 | "framework", 14 | "flux" 15 | ], 16 | "author": "Fred Chien ", 17 | "license": "MIT", 18 | "devDependencies": { 19 | "co": "^4.6.0", 20 | "babel-core": "^5.8.29", 21 | "babel-loader": "^5.3.3", 22 | "babel-runtime": "^5.8.29", 23 | "webpack": "^1.12.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/core.js: -------------------------------------------------------------------------------- 1 | import co from 'co'; 2 | import Dispatcher from './dispatcher'; 3 | import FEvent from './fevent'; 4 | 5 | function next() { 6 | return function(done) { 7 | done(null, true); 8 | }; 9 | } 10 | 11 | class Core extends Dispatcher { 12 | 13 | createInstance() { 14 | return new Core(); 15 | } 16 | 17 | constructor() { 18 | super(); 19 | 20 | this.isBrowser = true; 21 | this.options = {}; 22 | this.disabledEventHandler = false; 23 | this.serverRendering = false; 24 | this.middlewares = []; 25 | this.handlers = []; 26 | this.wrapperMap = []; 27 | this._state = {}; 28 | 29 | // Load default state on browser-side 30 | if (typeof window == 'undefined') { 31 | this.isBrowser = false; 32 | } else { 33 | if (window.Fluky) { 34 | if (window.Fluky.state) { 35 | this._state = Object.assign({}, window.Fluky.state); 36 | } 37 | } 38 | } 39 | 40 | // Action 41 | this.use(function *(event, next) { 42 | 43 | if (event.type != 'action') 44 | return yield next(); 45 | 46 | // Using customized handler if it exists 47 | if (this.hasListeners(event.path)) { 48 | yield this.emit.apply(this, event.args); 49 | return; 50 | } 51 | 52 | // Forwarding event to store 53 | var args = event.args.slice(0); 54 | args[0] = 'store.' + event.category + '.' + event.name; 55 | const e = new FEvent(args[0], args); 56 | 57 | this.internalDispatch(e); 58 | }); 59 | 60 | // Dispatch events 61 | this.use(function *(event, next) { 62 | 63 | if (this.serverRendering) { 64 | // Ignore state change event 65 | if (event.type == 'state') 66 | return; 67 | } 68 | 69 | yield this.emit.apply(this, event.args); 70 | }); 71 | } 72 | 73 | use() { 74 | this.middlewares.push(arguments[0].bind(this)); 75 | } 76 | 77 | loadHandler(handler) { 78 | 79 | var exists = false; 80 | for (var index in this.handlers) { 81 | if (this.handlers[index] == handler) { 82 | exists = true; 83 | break; 84 | } 85 | } 86 | 87 | if (!exists) { 88 | co(handler.bind(this)); 89 | this.handlers.push(handler); 90 | } 91 | } 92 | 93 | load() { 94 | 95 | for (var k in arguments) { 96 | var handler = arguments[k]; 97 | 98 | // It's an array 99 | if (!(handler instanceof Function)) { 100 | var handlers = handler; 101 | 102 | for (var key in handlers) { 103 | this.loadHandler(handlers[key]); 104 | } 105 | } 106 | } 107 | } 108 | 109 | dispatch(eventStr) { 110 | 111 | // For isomorphic app, sometimes no need to handle event on server-side 112 | if (this.disabledEventHandler) 113 | return; 114 | 115 | const event = new FEvent(eventStr, arguments); 116 | 117 | this.internalDispatch(event); 118 | } 119 | 120 | internalDispatch(event) { 121 | 122 | // Using all middlewares to handle this event 123 | co(function *() { 124 | for (var index in this.middlewares) { 125 | var handler = this.middlewares[index]; 126 | 127 | try { 128 | var isAlive = yield* handler(event, next); 129 | } catch(e) { 130 | console.log(e.stack); 131 | break; 132 | } 133 | 134 | if (!isAlive) 135 | break; 136 | } 137 | }.bind(this)); 138 | } 139 | 140 | off(eventName, listener) { 141 | // Find listener and remove its generator 142 | for (var index in this.wrapperMap) { 143 | var wrapper = this.wrapperMap[index]; 144 | if (wrapper.listener == listener) { 145 | this.wrapperMap.splice(index, 1); 146 | super.off(eventName, wrapper.generator); 147 | return; 148 | } 149 | } 150 | 151 | super.off(eventName, listener); 152 | } 153 | 154 | bindListener(listener) { 155 | 156 | // Don't wrap again if it exists 157 | for (var index in this.wrapperMap) { 158 | var wrapper = this.wrapperMap[index]; 159 | if (wrapper.listener == listener) 160 | return wrapper.generator; 161 | } 162 | 163 | // add to list 164 | var wrapper = { 165 | listener: listener, 166 | generator: function *() { 167 | listener.apply(this, Array.prototype.slice.call(arguments)); 168 | } 169 | }; 170 | 171 | this.wrapperMap.push(wrapper); 172 | 173 | return wrapper.generator; 174 | } 175 | 176 | setInitialState(state) { 177 | 178 | // Reset state and apply new state 179 | this._state = Object.assign({}, state); 180 | } 181 | 182 | getState(stateName, defState) { 183 | 184 | if (!this._state[stateName]) 185 | this._state[stateName] = defState || {}; 186 | 187 | return this._state[stateName]; 188 | } 189 | 190 | setState(stateName, state) { 191 | 192 | if (!this._state[stateName]) 193 | this._state[stateName] = state; 194 | else 195 | this._state[stateName] = Object.assign(this._state[stateName], state); 196 | } 197 | 198 | get state() { 199 | return this._state; 200 | } 201 | 202 | set state(val) { 203 | this._state = Object.assign(this._state, val); 204 | } 205 | } 206 | 207 | export default Core; 208 | -------------------------------------------------------------------------------- /src/dispatcher.js: -------------------------------------------------------------------------------- 1 | import co from 'co'; 2 | 3 | class Dispatcher { 4 | 5 | constructor() { 6 | this.listeners = {}; 7 | this._refs = 0; 8 | } 9 | 10 | on(eventName, handler) { 11 | var e = this.listeners[eventName] || []; 12 | 13 | // Whether handler exists or not 14 | if (e.indexOf(handler) > -1) 15 | return; 16 | 17 | // Register 18 | e.push(handler); 19 | this.listeners[eventName] = e; 20 | } 21 | 22 | off(eventName, handler) { 23 | var e = this.listeners[eventName] || null; 24 | if (!e) 25 | return; 26 | 27 | // Whether handler exists or not 28 | const index = e.indexOf(handler); 29 | if (index == -1) 30 | return; 31 | 32 | // Remove 33 | e.splice(index, 1); 34 | } 35 | 36 | hasListeners(eventName) { 37 | var e = this.listeners[eventName] || []; 38 | if (!e.length) 39 | return false; 40 | 41 | return true; 42 | } 43 | 44 | emit(eventName) { 45 | var idleEvent = (eventName == 'idle'); 46 | var e = this.listeners[eventName] || []; 47 | var args = Array.prototype.slice.call(arguments); 48 | args.shift(); 49 | 50 | // Increase reference counter 51 | if (!idleEvent) { 52 | this._refs++; 53 | } 54 | 55 | return function(done) { 56 | 57 | co(function *() { 58 | 59 | for (var index in e) { 60 | 61 | // Callback is a generator 62 | var handler = co.wrap(e[index]); 63 | 64 | // Run and wait 65 | try { 66 | args = yield function(done) { 67 | handler 68 | .apply(this, args) 69 | .then(function(ret) { 70 | if (ret === undefined) { 71 | done(null, args); 72 | } else { 73 | done(null, [ ret ]); 74 | } 75 | }, function(err) { 76 | done(err); 77 | }); 78 | }.bind(this); 79 | 80 | } catch(e) { 81 | // Workaround: React 0.13 has a bug on server rendering that document object wasn't found. 82 | // Just ignore it because it doesn't affect anything on server-side. 83 | if (e.message != 'document is not defined' || e.stack.indexOf('at getActiveElement') == -1) { 84 | done(e); 85 | return; 86 | } 87 | } 88 | 89 | } 90 | 91 | // Decrease reference counter 92 | if (!idleEvent) { 93 | this._refs--; 94 | } 95 | 96 | done(); 97 | 98 | // Everything is done, fire the idle event 99 | if (!this._refs && !idleEvent) 100 | yield this.emit('idle'); 101 | }.bind(this)); 102 | }.bind(this) 103 | } 104 | } 105 | 106 | export default Dispatcher; 107 | -------------------------------------------------------------------------------- /src/fevent.js: -------------------------------------------------------------------------------- 1 | 2 | class FEvent { 3 | 4 | constructor(event, args) { 5 | var parts = event.split('.'); 6 | 7 | this.path = event; 8 | this.type = parts.shift(); 9 | this.category = parts.shift(); 10 | this.name = parts.join('.'); 11 | this.args = Array.prototype.slice.call(args); 12 | } 13 | } 14 | 15 | module.exports = FEvent; 16 | -------------------------------------------------------------------------------- /src/fluky.js: -------------------------------------------------------------------------------- 1 | var Core = require('./core'); 2 | 3 | var core = new Core(); 4 | 5 | module.exports = core; 6 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var configs = module.exports = { 2 | entry: { 3 | app: [ 4 | './src/fluky.js' 5 | ] 6 | }, 7 | output: { 8 | libraryTarget: 'commonjs2', 9 | path: __dirname + '/lib', 10 | publicPath: '/lib', 11 | filename: 'fluky.js' 12 | }, 13 | target: 'node', 14 | module: { 15 | loaders: [ 16 | { 17 | test: /\.js?$/, 18 | loader: 'babel', 19 | exclude: /(node_modules|bower_components)/, 20 | query: { 21 | stage: 0, 22 | optional: [ 'runtime' ] 23 | } 24 | }, 25 | ] 26 | } 27 | }; 28 | --------------------------------------------------------------------------------