├── .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 | [](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 | Add Item
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 |
38 | Clear completed ({markedCount})
39 | ;
40 | }
41 |
42 | return (
43 |
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 |
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 | {this.props.todo.text}
59 |
60 |
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 |
--------------------------------------------------------------------------------