├── .gitignore ├── dist ├── index.features.json ├── index.html ├── index.compiled.js ├── index.bundle.js ├── demo-app.css ├── fake-todos.js └── demo-app.js ├── .npmrc ├── src ├── example.js ├── uuid.js ├── todos-spec.js ├── dictionary.js └── index.js ├── deploy.json ├── demo └── demo-app.js ├── .travis.yml ├── webpack.config.js ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | .grunt/ 4 | -------------------------------------------------------------------------------- /dist/index.features.json: -------------------------------------------------------------------------------- 1 | [ 2 | "letConst", 3 | "numericLiteral" 4 | ] -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=http://registry.npmjs.org/ 2 | save-exact=true 3 | progress=false 4 | -------------------------------------------------------------------------------- /src/example.js: -------------------------------------------------------------------------------- 1 | var generate = require('fake-todos') 2 | var items = generate(3) 3 | console.log(items) 4 | -------------------------------------------------------------------------------- /deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "gh-pages": { 3 | "options": { 4 | "base": "dist" 5 | }, 6 | "src": [ 7 | "index.html", 8 | "demo-app.js", 9 | "demo-app.css" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /demo/demo-app.js: -------------------------------------------------------------------------------- 1 | require('../node_modules/todomvc-common/base.css') 2 | require('../node_modules/todomvc-app-css/index.css') 3 | 4 | var Todos = require('todomvc-model') 5 | Todos.items = require('..')(100) 6 | var virtualDom = require('virtual-todos')(Todos) 7 | var createElement = require('virtual-dom/create-element') 8 | var rootNode = createElement(virtualDom) 9 | document.body.appendChild(rootNode) 10 | -------------------------------------------------------------------------------- /src/uuid.js: -------------------------------------------------------------------------------- 1 | // from http://jsfiddle.net/briguy37/2mvfd/ 2 | function uuid () { 3 | var d = new Date().getTime() 4 | var uuidFormat = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 5 | var uuid = uuidFormat.replace(/[xy]/g, function (c) { 6 | var r = (d + Math.random() * 16) % 16 | 0 7 | d = Math.floor(d / 16) 8 | return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16) 9 | }) 10 | return uuid 11 | } 12 | 13 | export default uuid 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | cache: 4 | directories: 5 | - node_modules 6 | notifications: 7 | email: false 8 | node_js: 9 | - '4' 10 | before_install: 11 | - npm i -g npm@^2.0.0 12 | before_script: 13 | - npm prune 14 | script: 15 | - npm run lint 16 | - npm run test 17 | - npm run example 18 | after_success: 19 | - npm run semantic-release 20 | branches: 21 | except: 22 | - "/^v\\d+\\.\\d+\\.\\d+$/" 23 | -------------------------------------------------------------------------------- /src/todos-spec.js: -------------------------------------------------------------------------------- 1 | const la = require('lazy-ass') 2 | const is = require('check-more-types') 3 | 4 | /* global describe, it */ 5 | describe('fake todos', () => { 6 | const generate = require('..') 7 | 8 | it('is a function', () => { 9 | la(is.fn(generate)) 10 | }) 11 | 12 | it('returns 2 mock todo items', () => { 13 | const todos = generate(2) 14 | la(is.array(todos), 'returns an array') 15 | la(todos.length === 2, 'has 2 items') 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 2 | module.exports = [{ 3 | output: { 4 | library: 'fakeTodos', 5 | libraryTarget: 'umd', 6 | path: './dist', 7 | filename: 'fake-todos.js' 8 | }, 9 | entry: { 10 | 'fake-todos': './src/index' 11 | } 12 | }, { 13 | output: { 14 | path: './dist', 15 | filename: 'demo-app.js' 16 | }, 17 | entry: { 18 | 'demo-app': './demo/demo-app' 19 | }, 20 | module: { 21 | loaders: [ 22 | { 23 | test: /\.css$/, 24 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader') 25 | } 26 | ] 27 | }, 28 | plugins: [ 29 | new ExtractTextPlugin('demo-app.css', { 30 | allChunks: true 31 | }) 32 | ] 33 | }] 34 | -------------------------------------------------------------------------------- /src/dictionary.js: -------------------------------------------------------------------------------- 1 | // add empty modifiers to sometimes not include one 2 | const modifiers = ['try to', 'avoid', 'skip', 'pretend to', 3 | 'help', '', '', '', '', ''] 4 | 5 | const verbs = [ 6 | 'learn', 'clean', 'buy', 'pick', 'do', 'make', 'fix', 'exercise', 7 | 'tweet', 'promote', 'code', 'play', 'find', 'crash', 'submit', 8 | 'skip', 'add', 'forget', 'avoid', 'throw', 'buy', 'sell' 9 | ] 10 | 11 | const nouns = [ 12 | 'Italian', 'milk', 'needle work', 'chess', 'Node.js', 'fines', 13 | 'books', 'boots', 'fishing rod', 'distant relatives', 'charges', 14 | 'knife', 'castle', 'laptop', 'principles', 'adults', 'bird' 15 | ] 16 | 17 | // module.exports = { 18 | // modifiers: modifiers, 19 | // verbs: verbs, 20 | // nouns: nouns 21 | // } 22 | export { modifiers, verbs, nouns } 23 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import la from 'lazy-ass' 2 | import is from 'check-more-types' 3 | import uuid from './uuid' 4 | import { modifiers, verbs, nouns } from './dictionary' 5 | 6 | // TODO handle verbs like "look up" 7 | function suffix (modifier) { 8 | const modifiersToSuffix = { 9 | avoid: 'ing', 10 | skip: 'ing' 11 | } 12 | return modifiersToSuffix[modifier] || '' 13 | } 14 | 15 | function addSuffix (verb, suffix) { 16 | if (!suffix) { 17 | return verb 18 | } 19 | if (/e$/.test(verb)) { 20 | return verb.substr(0, verb.length - 1) + suffix 21 | } 22 | return verb + suffix 23 | } 24 | 25 | function pick (set) { 26 | return set[Math.floor(Math.random() * set.length)] 27 | } 28 | 29 | function generateTodo () { 30 | const modifier = pick(modifiers) 31 | const verb = pick(verbs) 32 | const ending = suffix(modifier) 33 | const noun = pick(nouns) 34 | 35 | return { 36 | what: modifier + (modifier ? ' ' : '') + addSuffix(verb, ending) + ' ' + noun, 37 | due: 'tomorrow', 38 | done: false, 39 | id: uuid() 40 | } 41 | } 42 | 43 | function generateFakeTodos (n) { 44 | la(is.positive(n), 'invalid number of todos to create', n) 45 | var items = new Array(n) 46 | var k 47 | for (k = 0; k < n; k += 1) { 48 | items[k] = generateTodo() 49 | } 50 | return items 51 | } 52 | 53 | module.exports = generateFakeTodos 54 | 55 | function isBrowser () { 56 | return typeof window === 'object' 57 | } 58 | 59 | function isStandalone () { 60 | return !module.parent 61 | } 62 | 63 | if (!isBrowser() && isStandalone()) { 64 | !(function () { 65 | require('console.table') 66 | console.table(generateFakeTodos(5)) 67 | }()) 68 | } 69 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fake todos 5 | 6 | 14 | 15 | 16 | 17 | 18 |

fake

19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fake-todos", 3 | "description": "Generates a list of mock todos for TodoMVC apps ;)", 4 | "main": "dist/index.compiled.js", 5 | "version": "0.0.0-semantic-release", 6 | "scripts": { 7 | "test": "mocha --harmony src/*-spec.js", 8 | "lint": "standard *.js src/*.js", 9 | "semantic-release": "semantic-release pre && npm publish && semantic-release post", 10 | "issues": "git-issues", 11 | "commit": "commit-wizard", 12 | "build": "webpack && build", 13 | "postinstall": "compile", 14 | "deploy": "grunty grunt-gh-pages gh-pages deploy.json", 15 | "size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";", 16 | "example": "NODE_PATH=.. node src/example.js" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/bahmutov/fake-todos.git" 21 | }, 22 | "engines" : { 23 | "node" : ">=4" 24 | }, 25 | "keywords": [ 26 | "fake", 27 | "mock", 28 | "todo", 29 | "todos" 30 | ], 31 | "author": "Gleb Bahmutov ", 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/bahmutov/fake-todos/issues" 35 | }, 36 | "homepage": "https://github.com/bahmutov/fake-todos#readme", 37 | "tonicExampleFilename": "src/example.js", 38 | "devDependencies": { 39 | "css-loader": "0.23.1", 40 | "extract-text-webpack-plugin": "0.9.1", 41 | "git-issues": "1.2.0", 42 | "grunt": "0.4.5", 43 | "grunt-gh-pages": "1.0.0", 44 | "grunty": "0.2.0", 45 | "mocha": "2.3.4", 46 | "pre-git": "3.1.2", 47 | "semantic-release": "^4.3.5", 48 | "standard": "5.4.1", 49 | "style-loader": "0.13.0", 50 | "todomvc-app-css": "2.0.3", 51 | "todomvc-common": "1.0.2", 52 | "todomvc-model": "1.1.0", 53 | "virtual-dom": "2.1.1", 54 | "virtual-todos": "1.2.0", 55 | "webpack": "1.12.9" 56 | }, 57 | "dependencies": { 58 | "check-more-types": "2.10.0", 59 | "compiled": "1.9.1", 60 | "console.table": "0.4.0", 61 | "lazy-ass": "1.3.0" 62 | }, 63 | "files": [ 64 | "dist/fake-todos.js", 65 | "dist/index*", 66 | "src/*.js", 67 | "!src/*-spec.js" 68 | ], 69 | "config": { 70 | "compiled": { 71 | "dir": "dist", 72 | "files": ["src/index.js"] 73 | }, 74 | "pre-git": { 75 | "commit-msg": [ 76 | "simple" 77 | ], 78 | "pre-commit": [ 79 | "npm run lint", 80 | "npm run test" 81 | ], 82 | "pre-push": [ 83 | "npm run example", 84 | "npm run size" 85 | ], 86 | "post-commit": [], 87 | "post-merge": [] 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /dist/index.compiled.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var la = require('lazy-ass'); 4 | la = 'default' in la ? la['default'] : la; 5 | var is = require('check-more-types'); 6 | is = 'default' in is ? is['default'] : is; 7 | 8 | // from http://jsfiddle.net/briguy37/2mvfd/ 9 | function uuid() { 10 | var d = new Date().getTime(); 11 | var uuidFormat = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; 12 | var uuid = uuidFormat.replace(/[xy]/g, function (c) { 13 | var r = (d + Math.random() * 16) % 16 | 0; 14 | d = Math.floor(d / 16); 15 | return (c === 'x' ? r : r & 0x3 | 0x8).toString(16); 16 | }); 17 | return uuid; 18 | } 19 | 20 | // add empty modifiers to sometimes not include one 21 | const modifiers = ['try to', 'avoid', 'skip', 'pretend to', 'help', '', '', '', '', '']; 22 | 23 | const verbs = ['learn', 'clean', 'buy', 'pick', 'do', 'make', 'fix', 'exercise', 'tweet', 'promote', 'code', 'play', 'find', 'crash', 'submit', 'skip', 'add', 'forget', 'avoid', 'throw', 'buy', 'sell']; 24 | 25 | const nouns = ['Italian', 'milk', 'needle work', 'chess', 'Node.js', 'fines', 'books', 'boots', 'fishing rod', 'distant relatives', 'charges', 'knife', 'castle', 'laptop', 'principles', 'adults', 'bird']; 26 | 27 | // TODO handle verbs like "look up" 28 | function suffix(modifier) { 29 | const modifiersToSuffix = { 30 | avoid: 'ing', 31 | skip: 'ing' 32 | }; 33 | return modifiersToSuffix[modifier] || ''; 34 | } 35 | 36 | function addSuffix(verb, suffix) { 37 | if (!suffix) { 38 | return verb; 39 | } 40 | if (/e$/.test(verb)) { 41 | return verb.substr(0, verb.length - 1) + suffix; 42 | } 43 | return verb + suffix; 44 | } 45 | 46 | function pick(set) { 47 | return set[Math.floor(Math.random() * set.length)]; 48 | } 49 | 50 | function generateTodo() { 51 | const modifier = pick(modifiers); 52 | const verb = pick(verbs); 53 | const ending = suffix(modifier); 54 | const noun = pick(nouns); 55 | 56 | return { 57 | what: modifier + (modifier ? ' ' : '') + addSuffix(verb, ending) + ' ' + noun, 58 | due: 'tomorrow', 59 | done: false, 60 | id: uuid() 61 | }; 62 | } 63 | 64 | function generateFakeTodos(n) { 65 | la(is.positive(n), 'invalid number of todos to create', n); 66 | var items = new Array(n); 67 | var k; 68 | for (k = 0; k < n; k += 1) { 69 | items[k] = generateTodo(); 70 | } 71 | return items; 72 | } 73 | 74 | module.exports = generateFakeTodos; 75 | 76 | function isBrowser() { 77 | return typeof window === 'object'; 78 | } 79 | 80 | function isStandalone() { 81 | return !module.parent; 82 | } 83 | 84 | if (!isBrowser() && isStandalone()) { 85 | !function () { 86 | require('console.table'); 87 | console.table(generateFakeTodos(5)); 88 | }(); 89 | } 90 | -------------------------------------------------------------------------------- /dist/index.bundle.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var la = require('lazy-ass'); 4 | la = 'default' in la ? la['default'] : la; 5 | var is = require('check-more-types'); 6 | is = 'default' in is ? is['default'] : is; 7 | 8 | // from http://jsfiddle.net/briguy37/2mvfd/ 9 | function uuid () { 10 | var d = new Date().getTime() 11 | var uuidFormat = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 12 | var uuid = uuidFormat.replace(/[xy]/g, function (c) { 13 | var r = (d + Math.random() * 16) % 16 | 0 14 | d = Math.floor(d / 16) 15 | return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16) 16 | }) 17 | return uuid 18 | } 19 | 20 | // add empty modifiers to sometimes not include one 21 | const modifiers = ['try to', 'avoid', 'skip', 'pretend to', 22 | 'help', '', '', '', '', ''] 23 | 24 | const verbs = [ 25 | 'learn', 'clean', 'buy', 'pick', 'do', 'make', 'fix', 'exercise', 26 | 'tweet', 'promote', 'code', 'play', 'find', 'crash', 'submit', 27 | 'skip', 'add', 'forget', 'avoid', 'throw', 'buy', 'sell' 28 | ] 29 | 30 | const nouns = [ 31 | 'Italian', 'milk', 'needle work', 'chess', 'Node.js', 'fines', 32 | 'books', 'boots', 'fishing rod', 'distant relatives', 'charges', 33 | 'knife', 'castle', 'laptop', 'principles', 'adults', 'bird' 34 | ] 35 | 36 | // TODO handle verbs like "look up" 37 | function suffix (modifier) { 38 | const modifiersToSuffix = { 39 | avoid: 'ing', 40 | skip: 'ing' 41 | } 42 | return modifiersToSuffix[modifier] || '' 43 | } 44 | 45 | function addSuffix (verb, suffix) { 46 | if (!suffix) { 47 | return verb 48 | } 49 | if (/e$/.test(verb)) { 50 | return verb.substr(0, verb.length - 1) + suffix 51 | } 52 | return verb + suffix 53 | } 54 | 55 | function pick (set) { 56 | return set[Math.floor(Math.random() * set.length)] 57 | } 58 | 59 | function generateTodo () { 60 | const modifier = pick(modifiers) 61 | const verb = pick(verbs) 62 | const ending = suffix(modifier) 63 | const noun = pick(nouns) 64 | 65 | return { 66 | what: modifier + (modifier ? ' ' : '') + addSuffix(verb, ending) + ' ' + noun, 67 | due: 'tomorrow', 68 | done: false, 69 | id: uuid() 70 | } 71 | } 72 | 73 | function generateFakeTodos (n) { 74 | la(is.positive(n), 'invalid number of todos to create', n) 75 | var items = new Array(n) 76 | var k 77 | for (k = 0; k < n; k += 1) { 78 | items[k] = generateTodo() 79 | } 80 | return items 81 | } 82 | 83 | module.exports = generateFakeTodos 84 | 85 | function isBrowser () { 86 | return typeof window === 'object' 87 | } 88 | 89 | function isStandalone () { 90 | return !module.parent 91 | } 92 | 93 | if (!isBrowser() && isStandalone()) { 94 | !(function () { 95 | require('console.table') 96 | console.table(generateFakeTodos(5)) 97 | }()) 98 | } 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fake-todos 2 | > Generates a list of mock todos for TodoMVC apps ;) 3 | 4 | [![NPM][fake-todos-icon] ][fake-todos-url] 5 | 6 | [![Build status][fake-todos-ci-image] ][fake-todos-ci-url] 7 | [![semantic-release][semantic-image] ][semantic-url] 8 | [![manpm](https://img.shields.io/badge/manpm-%E2%9C%93-3399ff.svg)](https://github.com/bahmutov/manpm) 9 | 10 | [demo page](http://glebbahmutov.com/fake-todos/) 11 | 12 | ## Install and use 13 | 14 | `npm install --save fake-todos` 15 | 16 | ```js 17 | var generate = require('fake-todos') 18 | var items = generate(100) 19 | // items is a list with 100 items like 20 | /* 21 | { 22 | what: 'learn italian', 23 | done: false, 24 | id: 'x8kk...' 25 | } 26 | */ 27 | ``` 28 | 29 | ## Sample output 30 | 31 | You can see a few examples by running `node src/index.js` 32 | 33 | ``` 34 | what due done id 35 | ------------------------ -------- ----- ------------------------------------ 36 | tweet milk tomorrow false ce889dbb-ce91-49b4-beba-809a9bef8ea6 37 | try to clean needle work tomorrow false 2c956df1-216e-4b16-8b46-2f75a876b0b0 38 | make milk tomorrow false 1f666512-4484-4b1b-846e-ee7650bb4a6c 39 | make distant relatives tomorrow false a052cc1d-012b-40bd-ae3b-07c1efb2432e 40 | learn Node.js tomorrow false 1b00ce60-e419-4eaa-81aa-bf9de737b99f 41 | ``` 42 | 43 | Or you can see yourself the results by reloading the 44 | [demo page](http://glebbahmutov.com/fake-todos/) 45 | 46 | ## Related 47 | 48 | * [virtual-todos](https://github.com/bahmutov/virtual-todos) for rendering virtual DOM from todos 49 | * [todomvc-model](https://github.com/bahmutov/todomvc-model) is the model that keeps 50 | todo items and responds to outside events 51 | 52 | ### Small print 53 | 54 | Author: Gleb Bahmutov © 2015 55 | 56 | * [@bahmutov](https://twitter.com/bahmutov) 57 | * [glebbahmutov.com](http://glebbahmutov.com) 58 | * [blog](http://glebbahmutov.com/blog/) 59 | 60 | License: MIT - do anything with the code, but don't blame me if it does not work. 61 | 62 | Spread the word: tweet, star on github, etc. 63 | 64 | Support: if you find any problems with this module, email / tweet / 65 | [open issue](https://github.com/bahmutov/fake-todos/issues) on Github 66 | 67 | ## MIT License 68 | 69 | Copyright (c) 2015 Gleb Bahmutov 70 | 71 | Permission is hereby granted, free of charge, to any person 72 | obtaining a copy of this software and associated documentation 73 | files (the "Software"), to deal in the Software without 74 | restriction, including without limitation the rights to use, 75 | copy, modify, merge, publish, distribute, sublicense, and/or sell 76 | copies of the Software, and to permit persons to whom the 77 | Software is furnished to do so, subject to the following 78 | conditions: 79 | 80 | The above copyright notice and this permission notice shall be 81 | included in all copies or substantial portions of the Software. 82 | 83 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 84 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 85 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 86 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 87 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 88 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 89 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 90 | OTHER DEALINGS IN THE SOFTWARE. 91 | 92 | [fake-todos-icon]: https://nodei.co/npm/fake-todos.png?downloads=true 93 | [fake-todos-url]: https://npmjs.org/package/fake-todos 94 | [fake-todos-ci-image]: https://travis-ci.org/bahmutov/fake-todos.png?branch=master 95 | [fake-todos-ci-url]: https://travis-ci.org/bahmutov/fake-todos 96 | [semantic-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg 97 | [semantic-url]: https://github.com/semantic-release/semantic-release 98 | -------------------------------------------------------------------------------- /dist/demo-app.css: -------------------------------------------------------------------------------- 1 | hr { 2 | margin: 20px 0; 3 | border: 0; 4 | border-top: 1px dashed #c5c5c5; 5 | border-bottom: 1px dashed #f7f7f7; 6 | } 7 | 8 | .learn a { 9 | font-weight: normal; 10 | text-decoration: none; 11 | color: #b83f45; 12 | } 13 | 14 | .learn a:hover { 15 | text-decoration: underline; 16 | color: #787e7e; 17 | } 18 | 19 | .learn h3, 20 | .learn h4, 21 | .learn h5 { 22 | margin: 10px 0; 23 | font-weight: 500; 24 | line-height: 1.2; 25 | color: #000; 26 | } 27 | 28 | .learn h3 { 29 | font-size: 24px; 30 | } 31 | 32 | .learn h4 { 33 | font-size: 18px; 34 | } 35 | 36 | .learn h5 { 37 | margin-bottom: 0; 38 | font-size: 14px; 39 | } 40 | 41 | .learn ul { 42 | padding: 0; 43 | margin: 0 0 30px 25px; 44 | } 45 | 46 | .learn li { 47 | line-height: 20px; 48 | } 49 | 50 | .learn p { 51 | font-size: 15px; 52 | font-weight: 300; 53 | line-height: 1.3; 54 | margin-top: 0; 55 | margin-bottom: 0; 56 | } 57 | 58 | #issue-count { 59 | display: none; 60 | } 61 | 62 | .quote { 63 | border: none; 64 | margin: 20px 0 60px 0; 65 | } 66 | 67 | .quote p { 68 | font-style: italic; 69 | } 70 | 71 | .quote p:before { 72 | content: '\201C'; 73 | font-size: 50px; 74 | opacity: .15; 75 | position: absolute; 76 | top: -20px; 77 | left: 3px; 78 | } 79 | 80 | .quote p:after { 81 | content: '\201D'; 82 | font-size: 50px; 83 | opacity: .15; 84 | position: absolute; 85 | bottom: -42px; 86 | right: 3px; 87 | } 88 | 89 | .quote footer { 90 | position: absolute; 91 | bottom: -40px; 92 | right: 0; 93 | } 94 | 95 | .quote footer img { 96 | border-radius: 3px; 97 | } 98 | 99 | .quote footer a { 100 | margin-left: 5px; 101 | vertical-align: middle; 102 | } 103 | 104 | .speech-bubble { 105 | position: relative; 106 | padding: 10px; 107 | background: rgba(0, 0, 0, .04); 108 | border-radius: 5px; 109 | } 110 | 111 | .speech-bubble:after { 112 | content: ''; 113 | position: absolute; 114 | top: 100%; 115 | right: 30px; 116 | border: 13px solid transparent; 117 | border-top-color: rgba(0, 0, 0, .04); 118 | } 119 | 120 | .learn-bar > .learn { 121 | position: absolute; 122 | width: 272px; 123 | top: 8px; 124 | left: -300px; 125 | padding: 10px; 126 | border-radius: 5px; 127 | background-color: rgba(255, 255, 255, .6); 128 | transition-property: left; 129 | transition-duration: 500ms; 130 | } 131 | 132 | @media (min-width: 899px) { 133 | .learn-bar { 134 | width: auto; 135 | padding-left: 300px; 136 | } 137 | 138 | .learn-bar > .learn { 139 | left: 8px; 140 | } 141 | } 142 | html, 143 | body { 144 | margin: 0; 145 | padding: 0; 146 | } 147 | 148 | button { 149 | margin: 0; 150 | padding: 0; 151 | border: 0; 152 | background: none; 153 | font-size: 100%; 154 | vertical-align: baseline; 155 | font-family: inherit; 156 | font-weight: inherit; 157 | color: inherit; 158 | -webkit-appearance: none; 159 | appearance: none; 160 | -webkit-font-smoothing: antialiased; 161 | -moz-font-smoothing: antialiased; 162 | font-smoothing: antialiased; 163 | } 164 | 165 | body { 166 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; 167 | line-height: 1.4em; 168 | background: #f5f5f5; 169 | color: #4d4d4d; 170 | min-width: 230px; 171 | max-width: 550px; 172 | margin: 0 auto; 173 | -webkit-font-smoothing: antialiased; 174 | -moz-font-smoothing: antialiased; 175 | font-smoothing: antialiased; 176 | font-weight: 300; 177 | } 178 | 179 | button, 180 | input[type="checkbox"] { 181 | outline: none; 182 | } 183 | 184 | .hidden { 185 | display: none; 186 | } 187 | 188 | .todoapp { 189 | background: #fff; 190 | margin: 130px 0 40px 0; 191 | position: relative; 192 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 193 | 0 25px 50px 0 rgba(0, 0, 0, 0.1); 194 | } 195 | 196 | .todoapp input::-webkit-input-placeholder { 197 | font-style: italic; 198 | font-weight: 300; 199 | color: #e6e6e6; 200 | } 201 | 202 | .todoapp input::-moz-placeholder { 203 | font-style: italic; 204 | font-weight: 300; 205 | color: #e6e6e6; 206 | } 207 | 208 | .todoapp input::input-placeholder { 209 | font-style: italic; 210 | font-weight: 300; 211 | color: #e6e6e6; 212 | } 213 | 214 | .todoapp h1 { 215 | position: absolute; 216 | top: -155px; 217 | width: 100%; 218 | font-size: 100px; 219 | font-weight: 100; 220 | text-align: center; 221 | color: rgba(175, 47, 47, 0.15); 222 | -webkit-text-rendering: optimizeLegibility; 223 | -moz-text-rendering: optimizeLegibility; 224 | text-rendering: optimizeLegibility; 225 | } 226 | 227 | .new-todo, 228 | .edit { 229 | position: relative; 230 | margin: 0; 231 | width: 100%; 232 | font-size: 24px; 233 | font-family: inherit; 234 | font-weight: inherit; 235 | line-height: 1.4em; 236 | border: 0; 237 | outline: none; 238 | color: inherit; 239 | padding: 6px; 240 | border: 1px solid #999; 241 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); 242 | box-sizing: border-box; 243 | -webkit-font-smoothing: antialiased; 244 | -moz-font-smoothing: antialiased; 245 | font-smoothing: antialiased; 246 | } 247 | 248 | .new-todo { 249 | padding: 16px 16px 16px 60px; 250 | border: none; 251 | background: rgba(0, 0, 0, 0.003); 252 | box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); 253 | } 254 | 255 | .main { 256 | position: relative; 257 | z-index: 2; 258 | border-top: 1px solid #e6e6e6; 259 | } 260 | 261 | label[for='toggle-all'] { 262 | display: none; 263 | } 264 | 265 | .toggle-all { 266 | position: absolute; 267 | top: -55px; 268 | left: -12px; 269 | width: 60px; 270 | height: 34px; 271 | text-align: center; 272 | border: none; /* Mobile Safari */ 273 | } 274 | 275 | .toggle-all:before { 276 | content: '\276F'; 277 | font-size: 22px; 278 | color: #e6e6e6; 279 | padding: 10px 27px 10px 27px; 280 | } 281 | 282 | .toggle-all:checked:before { 283 | color: #737373; 284 | } 285 | 286 | .todo-list { 287 | margin: 0; 288 | padding: 0; 289 | list-style: none; 290 | } 291 | 292 | .todo-list li { 293 | position: relative; 294 | font-size: 24px; 295 | border-bottom: 1px solid #ededed; 296 | } 297 | 298 | .todo-list li:last-child { 299 | border-bottom: none; 300 | } 301 | 302 | .todo-list li.editing { 303 | border-bottom: none; 304 | padding: 0; 305 | } 306 | 307 | .todo-list li.editing .edit { 308 | display: block; 309 | width: 506px; 310 | padding: 13px 17px 12px 17px; 311 | margin: 0 0 0 43px; 312 | } 313 | 314 | .todo-list li.editing .view { 315 | display: none; 316 | } 317 | 318 | .todo-list li .toggle { 319 | text-align: center; 320 | width: 40px; 321 | /* auto, since non-WebKit browsers doesn't support input styling */ 322 | height: auto; 323 | position: absolute; 324 | top: 0; 325 | bottom: 0; 326 | margin: auto 0; 327 | border: none; /* Mobile Safari */ 328 | -webkit-appearance: none; 329 | appearance: none; 330 | } 331 | 332 | .todo-list li .toggle:after { 333 | content: url('data:image/svg+xml;utf8,'); 334 | } 335 | 336 | .todo-list li .toggle:checked:after { 337 | content: url('data:image/svg+xml;utf8,'); 338 | } 339 | 340 | .todo-list li label { 341 | white-space: pre-line; 342 | word-break: break-all; 343 | padding: 15px 60px 15px 15px; 344 | margin-left: 45px; 345 | display: block; 346 | line-height: 1.2; 347 | transition: color 0.4s; 348 | } 349 | 350 | .todo-list li.completed label { 351 | color: #d9d9d9; 352 | text-decoration: line-through; 353 | } 354 | 355 | .todo-list li .destroy { 356 | display: none; 357 | position: absolute; 358 | top: 0; 359 | right: 10px; 360 | bottom: 0; 361 | width: 40px; 362 | height: 40px; 363 | margin: auto 0; 364 | font-size: 30px; 365 | color: #cc9a9a; 366 | margin-bottom: 11px; 367 | transition: color 0.2s ease-out; 368 | } 369 | 370 | .todo-list li .destroy:hover { 371 | color: #af5b5e; 372 | } 373 | 374 | .todo-list li .destroy:after { 375 | content: '\D7'; 376 | } 377 | 378 | .todo-list li:hover .destroy { 379 | display: block; 380 | } 381 | 382 | .todo-list li .edit { 383 | display: none; 384 | } 385 | 386 | .todo-list li.editing:last-child { 387 | margin-bottom: -1px; 388 | } 389 | 390 | .footer { 391 | color: #777; 392 | padding: 10px 15px; 393 | height: 20px; 394 | text-align: center; 395 | border-top: 1px solid #e6e6e6; 396 | } 397 | 398 | .footer:before { 399 | content: ''; 400 | position: absolute; 401 | right: 0; 402 | bottom: 0; 403 | left: 0; 404 | height: 50px; 405 | overflow: hidden; 406 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 407 | 0 8px 0 -3px #f6f6f6, 408 | 0 9px 1px -3px rgba(0, 0, 0, 0.2), 409 | 0 16px 0 -6px #f6f6f6, 410 | 0 17px 2px -6px rgba(0, 0, 0, 0.2); 411 | } 412 | 413 | .todo-count { 414 | float: left; 415 | text-align: left; 416 | } 417 | 418 | .todo-count strong { 419 | font-weight: 300; 420 | } 421 | 422 | .filters { 423 | margin: 0; 424 | padding: 0; 425 | list-style: none; 426 | position: absolute; 427 | right: 0; 428 | left: 0; 429 | } 430 | 431 | .filters li { 432 | display: inline; 433 | } 434 | 435 | .filters li a { 436 | color: inherit; 437 | margin: 3px; 438 | padding: 3px 7px; 439 | text-decoration: none; 440 | border: 1px solid transparent; 441 | border-radius: 3px; 442 | } 443 | 444 | .filters li a.selected, 445 | .filters li a:hover { 446 | border-color: rgba(175, 47, 47, 0.1); 447 | } 448 | 449 | .filters li a.selected { 450 | border-color: rgba(175, 47, 47, 0.2); 451 | } 452 | 453 | .clear-completed, 454 | html .clear-completed:active { 455 | float: right; 456 | position: relative; 457 | line-height: 20px; 458 | text-decoration: none; 459 | cursor: pointer; 460 | } 461 | 462 | .clear-completed:hover { 463 | text-decoration: underline; 464 | } 465 | 466 | .info { 467 | margin: 65px auto 0; 468 | color: #bfbfbf; 469 | font-size: 10px; 470 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); 471 | text-align: center; 472 | } 473 | 474 | .info p { 475 | line-height: 1; 476 | } 477 | 478 | .info a { 479 | color: inherit; 480 | text-decoration: none; 481 | font-weight: 400; 482 | } 483 | 484 | .info a:hover { 485 | text-decoration: underline; 486 | } 487 | 488 | /* 489 | Hack to remove background from Mobile Safari. 490 | Can't use it globally since it destroys checkboxes in Firefox 491 | */ 492 | @media screen and (-webkit-min-device-pixel-ratio:0) { 493 | .toggle-all, 494 | .todo-list li .toggle { 495 | background: none; 496 | } 497 | 498 | .todo-list li .toggle { 499 | height: 40px; 500 | } 501 | 502 | .toggle-all { 503 | -webkit-transform: rotate(90deg); 504 | transform: rotate(90deg); 505 | -webkit-appearance: none; 506 | appearance: none; 507 | } 508 | } 509 | 510 | @media (max-width: 430px) { 511 | .footer { 512 | height: 50px; 513 | } 514 | 515 | .filters { 516 | bottom: 10px; 517 | } 518 | } 519 | -------------------------------------------------------------------------------- /dist/fake-todos.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else if(typeof exports === 'object') 7 | exports["fakeTodos"] = factory(); 8 | else 9 | root["fakeTodos"] = factory(); 10 | })(this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) 20 | /******/ return installedModules[moduleId].exports; 21 | 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ exports: {}, 25 | /******/ id: moduleId, 26 | /******/ loaded: false 27 | /******/ }; 28 | 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | 32 | /******/ // Flag the module as loaded 33 | /******/ module.loaded = true; 34 | 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | 39 | 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | 46 | /******/ // __webpack_public_path__ 47 | /******/ __webpack_require__.p = ""; 48 | 49 | /******/ // Load entry module and return exports 50 | /******/ return __webpack_require__(0); 51 | /******/ }) 52 | /************************************************************************/ 53 | /******/ ([ 54 | /* 0 */ 55 | /***/ function(module, exports, __webpack_require__) { 56 | 57 | /* WEBPACK VAR INJECTION */(function(module) {const la = __webpack_require__(2) 58 | const is = __webpack_require__(3) 59 | const uuid = __webpack_require__(4) 60 | 61 | const dictionary = __webpack_require__(5) 62 | const modifiers = dictionary.modifiers 63 | const verbs = dictionary.verbs 64 | const nouns = dictionary.nouns 65 | 66 | // TODO handle verbs like "look up" 67 | function suffix (modifier) { 68 | const modifiersToSuffix = { 69 | avoid: 'ing', 70 | skip: 'ing' 71 | } 72 | return modifiersToSuffix[modifier] || '' 73 | } 74 | 75 | function addSuffix (verb, suffix) { 76 | if (!suffix) { 77 | return verb 78 | } 79 | if (/e$/.test(verb)) { 80 | return verb.substr(0, verb.length - 1) + suffix 81 | } 82 | return verb + suffix 83 | } 84 | 85 | function pick (set) { 86 | return set[Math.floor(Math.random() * set.length)] 87 | } 88 | 89 | function generateTodo () { 90 | const modifier = pick(modifiers) 91 | const verb = pick(verbs) 92 | const ending = suffix(modifier) 93 | const noun = pick(nouns) 94 | 95 | return { 96 | what: modifier + (modifier ? ' ' : '') + addSuffix(verb, ending) + ' ' + noun, 97 | due: 'tomorrow', 98 | done: false, 99 | id: uuid() 100 | } 101 | } 102 | 103 | function generateFakeTodos (n) { 104 | la(is.positive(n), 'invalid number of todos to create', n) 105 | var items = new Array(n) 106 | var k 107 | for (k = 0; k < n; k += 1) { 108 | items[k] = generateTodo() 109 | } 110 | return items 111 | } 112 | 113 | module.exports = generateFakeTodos 114 | 115 | function isBrowser () { 116 | return typeof window === 'object' 117 | } 118 | 119 | function isStandalone () { 120 | return !module.parent 121 | } 122 | 123 | if (!isBrowser() && isStandalone()) { 124 | !(function () { 125 | __webpack_require__(6) 126 | console.table(generateFakeTodos(5)) 127 | }()) 128 | } 129 | 130 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)(module))) 131 | 132 | /***/ }, 133 | /* 1 */ 134 | /***/ function(module, exports) { 135 | 136 | module.exports = function(module) { 137 | if(!module.webpackPolyfill) { 138 | module.deprecate = function() {}; 139 | module.paths = []; 140 | // module.parent = undefined by default 141 | module.children = []; 142 | module.webpackPolyfill = 1; 143 | } 144 | return module; 145 | } 146 | 147 | 148 | /***/ }, 149 | /* 2 */ 150 | /***/ function(module, exports) { 151 | 152 | /* WEBPACK VAR INJECTION */(function(global) {(function initLazyAss() { 153 | 154 | function isArrayLike(a) { 155 | return a && typeof a.length === 'number'; 156 | } 157 | 158 | function toStringArray(arr) { 159 | return 'array with ' + arr.length + ' items.\n[' + 160 | arr.map(toString).join(',') + ']\n'; 161 | } 162 | 163 | function isPrimitive(arg) { 164 | return typeof arg === 'string' || 165 | typeof arg === 'number' || 166 | typeof arg === 'boolean'; 167 | } 168 | 169 | function toString(arg, k) { 170 | if (isPrimitive(arg)) { 171 | return JSON.stringify(arg); 172 | } 173 | if (arg instanceof Error) { 174 | return arg.name + ' ' + arg.message; 175 | } 176 | 177 | if (Array.isArray(arg)) { 178 | return toStringArray(arg); 179 | } 180 | if (isArrayLike(arg)) { 181 | return toStringArray(Array.prototype.slice.call(arg, 0)); 182 | } 183 | var argString; 184 | try { 185 | argString = JSON.stringify(arg, null, 2); 186 | } catch (err) { 187 | argString = '{ cannot stringify arg ' + k + ', it has type "' + typeof arg + '"'; 188 | if (typeof arg === 'object') { 189 | argString += ' with keys ' + Object.keys(arg).join(', ') + ' }'; 190 | } else { 191 | argString += ' }'; 192 | } 193 | } 194 | return argString; 195 | } 196 | 197 | function endsWithNewLine(s) { 198 | return /\n$/.test(s); 199 | } 200 | 201 | function formMessage(args) { 202 | var msg = args.reduce(function (total, arg, k) { 203 | if (k && !endsWithNewLine(total)) { 204 | total += ' '; 205 | } 206 | if (typeof arg === 'string') { 207 | return total + arg; 208 | } 209 | if (typeof arg === 'function') { 210 | var fnResult; 211 | try { 212 | fnResult = arg(); 213 | } catch (err) { 214 | // ignore the error 215 | fnResult = '[function ' + arg.name + ' threw error!]'; 216 | } 217 | return total + fnResult; 218 | } 219 | var argString = toString(arg, k); 220 | return total + argString; 221 | }, ''); 222 | return msg; 223 | } 224 | 225 | function lazyAssLogic(condition) { 226 | var fn = typeof condition === 'function' ? condition : null; 227 | 228 | if (fn) { 229 | condition = fn(); 230 | } 231 | if (!condition) { 232 | var args = [].slice.call(arguments, 1); 233 | if (fn) { 234 | args.unshift(fn.toString()); 235 | } 236 | return new Error(formMessage(args)); 237 | } 238 | } 239 | 240 | var lazyAss = function lazyAss() { 241 | var err = lazyAssLogic.apply(null, arguments); 242 | if (err) { 243 | throw err; 244 | } 245 | }; 246 | 247 | var lazyAssync = function lazyAssync() { 248 | var err = lazyAssLogic.apply(null, arguments); 249 | if (err) { 250 | setTimeout(function () { 251 | throw err; 252 | }, 0); 253 | } 254 | }; 255 | 256 | lazyAss.async = lazyAssync; 257 | 258 | function isNode() { 259 | return typeof global === 'object'; 260 | } 261 | 262 | function isBrowser() { 263 | return typeof window === 'object'; 264 | } 265 | 266 | function isCommonJS() { 267 | return typeof module === 'object'; 268 | } 269 | 270 | function globalRegister() { 271 | if (isNode()) { 272 | /* global global */ 273 | register(global, lazyAss, 'lazyAss', 'la'); 274 | register(global, lazyAssync, 'lazyAssync', 'lac'); 275 | } 276 | } 277 | 278 | function register(root, value, name, alias) { 279 | root[name] = root[alias] = value; 280 | } 281 | 282 | lazyAss.globalRegister = globalRegister; 283 | 284 | if (isBrowser()) { 285 | /* global window */ 286 | register(window, lazyAss, 'lazyAss', 'la'); 287 | register(window, lazyAssync, 'lazyAssync', 'lac'); 288 | } 289 | 290 | if (isCommonJS()) { 291 | /* global module */ 292 | module.exports = lazyAss; 293 | } 294 | 295 | }()); 296 | 297 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 298 | 299 | /***/ }, 300 | /* 3 */ 301 | /***/ function(module, exports, __webpack_require__) { 302 | 303 | /* WEBPACK VAR INJECTION */(function(global) {(function checkMoreTypes() { 304 | 'use strict'; 305 | 306 | /** 307 | Custom assertions and predicates around https://github.com/philbooth/check-types.js 308 | Created by Kensho https://github.com/kensho 309 | Copyright @ 2014 Kensho https://www.kensho.com/ 310 | License: MIT 311 | 312 | @module check 313 | */ 314 | 315 | if (typeof Function.prototype.bind !== 'function') { 316 | throw new Error('Missing Function.prototype.bind, please load es5-shim first'); 317 | } 318 | 319 | // utility method 320 | function curry2(fn, strict2) { 321 | return function curried(a) { 322 | if (strict2 && arguments.length > 2) { 323 | throw new Error('Curry2 function ' + fn.name + 324 | ' called with too many arguments ' + arguments.length); 325 | } 326 | if (arguments.length === 2) { 327 | return fn(arguments[0], arguments[1]); 328 | } 329 | return function second(b) { 330 | return fn(a, b); 331 | }; 332 | }; 333 | } 334 | 335 | // most of the old methods from check-types.js 336 | function isFn(x) { return typeof x === 'function'; } 337 | function isString(x) { return typeof x === 'string'; } 338 | function unemptyString(x) { 339 | return isString(x) && x; 340 | } 341 | function isObject(x) { 342 | return typeof x === 'object' && 343 | !Array.isArray(x) && 344 | !isNull(x) && 345 | !isDate(x); 346 | } 347 | function isEmptyObject(x) { 348 | return isObject(x) && 349 | Object.keys(x).length === 0; 350 | } 351 | function isNumber(x) { 352 | return typeof x === 'number' && 353 | !isNaN(x) && 354 | x !== Infinity && 355 | x !== -Infinity; 356 | } 357 | function isInteger(x) { 358 | return isNumber(x) && x % 1 === 0; 359 | } 360 | function isFloat(x) { 361 | return isNumber(x) && x % 1 !== 0; 362 | } 363 | function isNull(x) { return x === null; } 364 | function positiveNumber(x) { 365 | return isNumber(x) && x > 0; 366 | } 367 | function negativeNumber(x) { 368 | return isNumber(x) && x < 0; 369 | } 370 | function isDate(x) { 371 | return x instanceof Date; 372 | } 373 | function isRegExp(x) { 374 | return x instanceof RegExp; 375 | } 376 | function instance(x, type) { 377 | return x instanceof type; 378 | } 379 | function hasLength(x, k) { 380 | if (typeof x === 'number' && typeof k !== 'number') { 381 | // swap arguments 382 | return hasLength(k, x); 383 | } 384 | return (Array.isArray(x) || isString(x)) && x.length === k; 385 | } 386 | 387 | /** 388 | Checks if the given index is valid in an array or string or -1 389 | 390 | @method found 391 | */ 392 | function found(index) { 393 | return index >= 0; 394 | } 395 | 396 | function startsWith(prefix, x) { 397 | return isString(prefix) && 398 | isString(x) && 399 | x.indexOf(prefix) === 0; 400 | } 401 | 402 | /** 403 | Checks if the type of second argument matches the name in the first 404 | 405 | @method type 406 | */ 407 | function type(expectedType, x) { 408 | return typeof x === expectedType; 409 | } 410 | 411 | var startsWithHttp = startsWith.bind(null, 'http://'); 412 | var startsWithHttps = startsWith.bind(null, 'https://'); 413 | 414 | function webUrl(x) { 415 | return isString(x) && 416 | (startsWithHttp(x) || startsWithHttps(x)); 417 | } 418 | 419 | function every(predicateResults) { 420 | var property, value; 421 | for (property in predicateResults) { 422 | if (predicateResults.hasOwnProperty(property)) { 423 | value = predicateResults[property]; 424 | 425 | if (isObject(value) && every(value) === false) { 426 | return false; 427 | } 428 | 429 | if (value === false) { 430 | return false; 431 | } 432 | } 433 | } 434 | return true; 435 | } 436 | 437 | function map(things, predicates) { 438 | var property, result = {}, predicate; 439 | for (property in predicates) { 440 | if (predicates.hasOwnProperty(property)) { 441 | predicate = predicates[property]; 442 | 443 | if (isFn(predicate)) { 444 | result[property] = predicate(things[property]); 445 | } else if (isObject(predicate)) { 446 | result[property] = map(things[property], predicate); 447 | } 448 | } 449 | } 450 | 451 | return result; 452 | } 453 | 454 | var check = { 455 | maybe: {}, 456 | verify: {}, 457 | not: {}, 458 | every: every, 459 | map: map 460 | }; 461 | 462 | /** 463 | Checks if argument is defined or not 464 | 465 | This method now is part of the check-types.js 466 | @method defined 467 | */ 468 | function defined(value) { 469 | return typeof value !== 'undefined'; 470 | } 471 | 472 | /** 473 | Checks if argument is a valid Date instance 474 | 475 | @method validDate 476 | */ 477 | function validDate(value) { 478 | return check.date(value) && 479 | check.number(Number(value)); 480 | } 481 | 482 | /** 483 | Checks if it is exact semver 484 | 485 | @method semver 486 | */ 487 | function semver(s) { 488 | return check.unemptyString(s) && 489 | /^\d+\.\d+\.\d+$/.test(s); 490 | } 491 | 492 | /** 493 | Returns true if the argument is primitive JavaScript type 494 | 495 | @method primitive 496 | */ 497 | function primitive(value) { 498 | var type = typeof value; 499 | return type === 'number' || 500 | type === 'boolean' || 501 | type === 'string' || 502 | type === 'symbol'; 503 | } 504 | 505 | /** 506 | Returns true if the value is a number 0 507 | 508 | @method zero 509 | */ 510 | function zero(x) { 511 | return typeof x === 'number' && x === 0; 512 | } 513 | 514 | /** 515 | same as === 516 | 517 | @method same 518 | */ 519 | function same(a, b) { 520 | return a === b; 521 | } 522 | 523 | /** 524 | Returns true if the index is valid for give string / array 525 | 526 | @method index 527 | */ 528 | function index(list, k) { 529 | return defined(list) && 530 | has(list, 'length') && 531 | k >= 0 && 532 | k < list.length; 533 | } 534 | 535 | /** 536 | Returns true if both objects are the same type and have same length property 537 | 538 | @method sameLength 539 | */ 540 | function sameLength(a, b) { 541 | return typeof a === typeof b && 542 | a && b && 543 | a.length === b.length; 544 | } 545 | 546 | /** 547 | Returns true if all items in an array are the same reference 548 | 549 | @method allSame 550 | */ 551 | function allSame(arr) { 552 | if (!check.array(arr)) { 553 | return false; 554 | } 555 | if (!arr.length) { 556 | return true; 557 | } 558 | var first = arr[0]; 559 | return arr.every(function (item) { 560 | return item === first; 561 | }); 562 | } 563 | 564 | /** 565 | Returns true if given item is in the array 566 | 567 | @method oneOf 568 | */ 569 | function oneOf(arr, x) { 570 | check.verify.array(arr, 'expected an array'); 571 | return arr.indexOf(x) !== -1; 572 | } 573 | 574 | /** 575 | Returns true for urls of the format `git@....git` 576 | 577 | @method git 578 | */ 579 | function git(url) { 580 | return check.unemptyString(url) && 581 | /^git@/.test(url); 582 | } 583 | 584 | /** 585 | Checks if given value is 0 or 1 586 | 587 | @method bit 588 | */ 589 | function bit(value) { 590 | return value === 0 || value === 1; 591 | } 592 | 593 | /** 594 | Checks if given value is true of false 595 | 596 | @method bool 597 | */ 598 | function bool(value) { 599 | return typeof value === 'boolean'; 600 | } 601 | 602 | /** 603 | Checks if given object has a property 604 | @method has 605 | */ 606 | function has(o, property) { 607 | if (arguments.length !== 2) { 608 | throw new Error('Expected two arguments to check.has, got only ' + arguments.length); 609 | } 610 | return Boolean(o && property && 611 | typeof property === 'string' && 612 | typeof o[property] !== 'undefined'); 613 | } 614 | 615 | /** 616 | Checks if given string is already in lower case 617 | @method lowerCase 618 | */ 619 | function lowerCase(str) { 620 | return check.string(str) && 621 | str.toLowerCase() === str; 622 | } 623 | 624 | /** 625 | Returns true if the argument is an array with at least one value 626 | @method unemptyArray 627 | */ 628 | function unemptyArray(a) { 629 | return check.array(a) && a.length > 0; 630 | } 631 | 632 | /** 633 | Returns true if each item in the array passes the predicate 634 | @method arrayOf 635 | @param rule Predicate function 636 | @param a Array to check 637 | */ 638 | function arrayOf(rule, a) { 639 | return check.array(a) && a.every(rule); 640 | } 641 | 642 | /** 643 | Returns items from array that do not passes the predicate 644 | @method badItems 645 | @param rule Predicate function 646 | @param a Array with items 647 | */ 648 | function badItems(rule, a) { 649 | check.verify.array(a, 'expected array to find bad items'); 650 | return a.filter(notModifier(rule)); 651 | } 652 | 653 | /** 654 | Returns true if given array only has strings 655 | @method arrayOfStrings 656 | @param a Array to check 657 | @param checkLowerCase Checks if all strings are lowercase 658 | */ 659 | function arrayOfStrings(a, checkLowerCase) { 660 | var v = check.array(a) && a.every(check.string); 661 | if (v && check.bool(checkLowerCase) && checkLowerCase) { 662 | return a.every(check.lowerCase); 663 | } 664 | return v; 665 | } 666 | 667 | /** 668 | Returns true if given argument is array of arrays of strings 669 | @method arrayOfArraysOfStrings 670 | @param a Array to check 671 | @param checkLowerCase Checks if all strings are lowercase 672 | */ 673 | function arrayOfArraysOfStrings(a, checkLowerCase) { 674 | return check.array(a) && a.every(function (arr) { 675 | return check.arrayOfStrings(arr, checkLowerCase); 676 | }); 677 | } 678 | 679 | /** 680 | Checks if object passes all rules in predicates. 681 | 682 | check.all({ foo: 'foo' }, { foo: check.string }, 'wrong object'); 683 | 684 | This is a composition of check.every(check.map ...) calls 685 | https://github.com/philbooth/check-types.js#batch-operations 686 | 687 | @method all 688 | @param {object} object object to check 689 | @param {object} predicates rules to check. Usually one per property. 690 | @public 691 | @returns true or false 692 | */ 693 | function all(obj, predicates) { 694 | check.verify.fn(check.every, 'missing check.every method'); 695 | check.verify.fn(check.map, 'missing check.map method'); 696 | 697 | check.verify.object(obj, 'missing object to check'); 698 | check.verify.object(predicates, 'missing predicates object'); 699 | Object.keys(predicates).forEach(function (property) { 700 | if (!check.fn(predicates[property])) { 701 | throw new Error('not a predicate function for ' + property + ' but ' + predicates[property]); 702 | } 703 | }); 704 | return check.every(check.map(obj, predicates)); 705 | } 706 | 707 | /** 708 | Checks given object against predicates object 709 | @method schema 710 | */ 711 | function schema(predicates, obj) { 712 | return all(obj, predicates); 713 | } 714 | 715 | /** Checks if given function raises an error 716 | 717 | @method raises 718 | */ 719 | function raises(fn, errorValidator) { 720 | check.verify.fn(fn, 'expected function that raises'); 721 | try { 722 | fn(); 723 | } catch (err) { 724 | if (typeof errorValidator === 'undefined') { 725 | return true; 726 | } 727 | if (typeof errorValidator === 'function') { 728 | return errorValidator(err); 729 | } 730 | return false; 731 | } 732 | // error has not been raised 733 | return false; 734 | } 735 | 736 | /** 737 | Returns true if given value is '' 738 | @method emptyString 739 | */ 740 | function emptyString(a) { 741 | return a === ''; 742 | } 743 | 744 | /** 745 | Returns true if given value is [], {} or '' 746 | @method empty 747 | */ 748 | function empty(a) { 749 | var hasLength = typeof a === 'string' || 750 | Array.isArray(a); 751 | if (hasLength) { 752 | return !a.length; 753 | } 754 | if (a instanceof Object) { 755 | return !Object.keys(a).length; 756 | } 757 | return false; 758 | } 759 | 760 | /** 761 | Returns true if given value has .length and it is not zero, or has properties 762 | @method unempty 763 | */ 764 | function unempty(a) { 765 | var hasLength = typeof a === 'string' || 766 | Array.isArray(a); 767 | if (hasLength) { 768 | return a.length; 769 | } 770 | if (a instanceof Object) { 771 | return Object.keys(a).length; 772 | } 773 | return true; 774 | } 775 | 776 | /** 777 | Returns true if 0 <= value <= 1 778 | @method unit 779 | */ 780 | function unit(value) { 781 | return check.number(value) && 782 | value >= 0.0 && value <= 1.0; 783 | } 784 | 785 | var rgb = /^#(?:[0-9a-fA-F]{3}){1,2}$/; 786 | /** 787 | Returns true if value is hex RGB between '#000000' and '#FFFFFF' 788 | @method hexRgb 789 | */ 790 | function hexRgb(value) { 791 | return check.string(value) && 792 | rgb.test(value); 793 | } 794 | 795 | // typical git SHA commit id is 40 digit hex string, like 796 | // 3b819803cdf2225ca1338beb17e0c506fdeedefc 797 | var shaReg = /^[0-9a-f]{40}$/; 798 | 799 | /** 800 | Returns true if the given string is 40 digit SHA commit id 801 | @method commitId 802 | */ 803 | function commitId(id) { 804 | return check.string(id) && 805 | id.length === 40 && 806 | shaReg.test(id); 807 | } 808 | 809 | // when using git log --oneline short ids are displayed, first 7 characters 810 | var shortShaReg = /^[0-9a-f]{7}$/; 811 | 812 | /** 813 | Returns true if the given string is short 7 character SHA id part 814 | @method shortCommitId 815 | */ 816 | function shortCommitId(id) { 817 | return check.string(id) && 818 | id.length === 7 && 819 | shortShaReg.test(id); 820 | } 821 | 822 | // 823 | // helper methods 824 | // 825 | 826 | if (!check.defend) { 827 | var checkPredicates = function checksPredicates(fn, predicates, args) { 828 | check.verify.fn(fn, 'expected a function'); 829 | check.verify.array(predicates, 'expected list of predicates'); 830 | check.verify.defined(args, 'missing args'); 831 | 832 | var k = 0, // iterates over predicates 833 | j = 0, // iterates over arguments 834 | n = predicates.length; 835 | 836 | for (k = 0; k < n; k += 1) { 837 | var predicate = predicates[k]; 838 | if (!check.fn(predicate)) { 839 | continue; 840 | } 841 | 842 | if (!predicate.call(null, args[j])) { 843 | var msg = 'Argument ' + (j + 1) + ': ' + args[j] + ' does not pass predicate'; 844 | if (check.unemptyString(predicates[k + 1])) { 845 | msg += ': ' + predicates[k + 1]; 846 | } 847 | throw new Error(msg); 848 | } 849 | 850 | j += 1; 851 | } 852 | return fn.apply(null, args); 853 | }; 854 | 855 | check.defend = function defend(fn) { 856 | var predicates = Array.prototype.slice.call(arguments, 1); 857 | return function () { 858 | return checkPredicates(fn, predicates, arguments); 859 | }; 860 | }; 861 | } 862 | 863 | /** 864 | Combines multiple predicate functions to produce new OR predicate 865 | @method or 866 | */ 867 | function or() { 868 | var predicates = Array.prototype.slice.call(arguments, 0); 869 | if (!predicates.length) { 870 | throw new Error('empty list of arguments to or'); 871 | } 872 | 873 | return function orCheck() { 874 | var values = Array.prototype.slice.call(arguments, 0); 875 | return predicates.some(function (predicate) { 876 | try { 877 | return check.fn(predicate) ? 878 | predicate.apply(null, values) : Boolean(predicate); 879 | } catch (err) { 880 | // treat exceptions as false 881 | return false; 882 | } 883 | }); 884 | }; 885 | } 886 | 887 | /** 888 | Combines multiple predicate functions to produce new AND predicate 889 | @method or 890 | */ 891 | function and() { 892 | var predicates = Array.prototype.slice.call(arguments, 0); 893 | if (!predicates.length) { 894 | throw new Error('empty list of arguments to or'); 895 | } 896 | 897 | return function orCheck() { 898 | var values = Array.prototype.slice.call(arguments, 0); 899 | return predicates.every(function (predicate) { 900 | return check.fn(predicate) ? 901 | predicate.apply(null, values) : Boolean(predicate); 902 | }); 903 | }; 904 | } 905 | 906 | /** 907 | * Public modifier `not`. 908 | * 909 | * Negates `predicate`. 910 | * copied from check-types.js 911 | */ 912 | function notModifier(predicate) { 913 | return function () { 914 | return !predicate.apply(null, arguments); 915 | }; 916 | } 917 | 918 | if (!check.mixin) { 919 | /** Adds new predicate to all objects 920 | @method mixin */ 921 | check.mixin = function mixin(fn, name) { 922 | if (isString(fn) && isFn(name)) { 923 | var tmp = fn; 924 | fn = name; 925 | name = tmp; 926 | } 927 | 928 | if (!isFn(fn)) { 929 | throw new Error('expected predicate function'); 930 | } 931 | if (!unemptyString(name)) { 932 | name = fn.name; 933 | } 934 | if (!unemptyString(name)) { 935 | throw new Error('predicate function missing name\n' + fn.toString()); 936 | } 937 | 938 | function registerPredicate(obj, name, fn) { 939 | if (!isObject(obj)) { 940 | throw new Error('missing object ' + obj); 941 | } 942 | if (!unemptyString(name)) { 943 | throw new Error('missing name'); 944 | } 945 | if (!isFn(fn)) { 946 | throw new Error('missing function'); 947 | } 948 | 949 | if (!obj[name]) { 950 | obj[name] = fn; 951 | } 952 | } 953 | 954 | /** 955 | * Public modifier `maybe`. 956 | * 957 | * Returns `true` if `predicate` is `null` or `undefined`, 958 | * otherwise propagates the return value from `predicate`. 959 | * copied from check-types.js 960 | */ 961 | function maybeModifier(predicate) { 962 | return function () { 963 | if (!check.defined(arguments[0]) || check.nulled(arguments[0])) { 964 | return true; 965 | } 966 | return predicate.apply(null, arguments); 967 | }; 968 | } 969 | 970 | /** 971 | * Public modifier `verify`. 972 | * 973 | * Throws if `predicate` returns `false`. 974 | * copied from check-types.js 975 | */ 976 | function verifyModifier(predicate, defaultMessage) { 977 | return function () { 978 | var message; 979 | if (predicate.apply(null, arguments) === false) { 980 | message = arguments[arguments.length - 1]; 981 | throw new Error(check.unemptyString(message) ? message : defaultMessage); 982 | } 983 | }; 984 | } 985 | 986 | registerPredicate(check, name, fn); 987 | registerPredicate(check.maybe, name, maybeModifier(fn)); 988 | registerPredicate(check.not, name, notModifier(fn)); 989 | registerPredicate(check.verify, name, verifyModifier(fn, name + ' failed')); 990 | }; 991 | } 992 | 993 | if (!check.then) { 994 | /** 995 | Executes given function only if condition is truthy. 996 | @method then 997 | */ 998 | check.then = function then(condition, fn) { 999 | return function () { 1000 | var ok = typeof condition === 'function' ? 1001 | condition.apply(null, arguments) : condition; 1002 | if (ok) { 1003 | return fn.apply(null, arguments); 1004 | } 1005 | }; 1006 | }; 1007 | } 1008 | 1009 | var promiseSchema = { 1010 | then: isFn 1011 | }; 1012 | 1013 | // work around reserved keywords checks 1014 | promiseSchema['catch'] = isFn; 1015 | promiseSchema['finally'] = isFn; 1016 | 1017 | var hasPromiseApi = schema.bind(null, promiseSchema); 1018 | 1019 | /** 1020 | Returns true if argument implements promise api (.then, .catch, .finally) 1021 | @method promise 1022 | */ 1023 | function isPromise(p) { 1024 | return check.object(p) && hasPromiseApi(p); 1025 | } 1026 | 1027 | /** 1028 | Shallow strict comparison 1029 | @method equal 1030 | */ 1031 | function equal(a, b) { 1032 | return a === b; 1033 | } 1034 | 1035 | // new predicates to be added to check object. Use object to preserve names 1036 | var predicates = { 1037 | nulled: isNull, 1038 | fn: isFn, 1039 | string: isString, 1040 | unemptyString: unemptyString, 1041 | object: isObject, 1042 | number: isNumber, 1043 | array: Array.isArray, 1044 | positiveNumber: positiveNumber, 1045 | negativeNumber: negativeNumber, 1046 | // a couple of aliases 1047 | positive: positiveNumber, 1048 | negative: negativeNumber, 1049 | defined: defined, 1050 | same: same, 1051 | allSame: allSame, 1052 | bit: bit, 1053 | bool: bool, 1054 | has: has, 1055 | lowerCase: lowerCase, 1056 | unemptyArray: unemptyArray, 1057 | arrayOfStrings: arrayOfStrings, 1058 | arrayOfArraysOfStrings: arrayOfArraysOfStrings, 1059 | all: all, 1060 | schema: curry2(schema), 1061 | raises: raises, 1062 | empty: empty, 1063 | found: found, 1064 | emptyString: emptyString, 1065 | unempty: unempty, 1066 | unit: unit, 1067 | hexRgb: hexRgb, 1068 | sameLength: sameLength, 1069 | commitId: commitId, 1070 | shortCommitId: shortCommitId, 1071 | index: index, 1072 | git: git, 1073 | arrayOf: arrayOf, 1074 | badItems: badItems, 1075 | oneOf: curry2(oneOf, true), 1076 | promise: isPromise, 1077 | validDate: validDate, 1078 | equal: curry2(equal), 1079 | or: or, 1080 | and: and, 1081 | primitive: primitive, 1082 | zero: zero, 1083 | date: isDate, 1084 | regexp: isRegExp, 1085 | instance: instance, 1086 | emptyObject: isEmptyObject, 1087 | length: curry2(hasLength), 1088 | floatNumber: isFloat, 1089 | intNumber: isInteger, 1090 | startsWith: startsWith, 1091 | webUrl: webUrl, 1092 | semver: semver, 1093 | type: curry2(type) 1094 | }; 1095 | 1096 | Object.keys(predicates).forEach(function (name) { 1097 | check.mixin(predicates[name], name); 1098 | }); 1099 | 1100 | if (true) { 1101 | module.exports = check; 1102 | } 1103 | 1104 | // if we are loaded under Node, but "window" object is available, put a reference 1105 | // there too - maybe we are running inside a synthetic browser environment 1106 | if (typeof window === 'object') { 1107 | window.check = check; 1108 | } 1109 | if (typeof global === 'object') { 1110 | global.check = check; 1111 | } 1112 | 1113 | }()); 1114 | 1115 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 1116 | 1117 | /***/ }, 1118 | /* 4 */ 1119 | /***/ function(module, exports) { 1120 | 1121 | // from http://jsfiddle.net/briguy37/2mvfd/ 1122 | function uuid () { 1123 | var d = new Date().getTime() 1124 | var uuidFormat = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 1125 | var uuid = uuidFormat.replace(/[xy]/g, function (c) { 1126 | var r = (d + Math.random() * 16) % 16 | 0 1127 | d = Math.floor(d / 16) 1128 | return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16) 1129 | }) 1130 | return uuid 1131 | } 1132 | 1133 | module.exports = uuid 1134 | 1135 | 1136 | /***/ }, 1137 | /* 5 */ 1138 | /***/ function(module, exports) { 1139 | 1140 | // add empty modifiers to sometimes not include one 1141 | const modifiers = ['try to', 'avoid', 'skip', 'pretend to', 1142 | 'help', '', '', '', '', ''] 1143 | 1144 | const verbs = [ 1145 | 'learn', 'clean', 'buy', 'pick', 'do', 'make', 'fix', 'exercise', 1146 | 'tweet', 'promote', 'code', 'play', 'find', 'crash', 'submit', 1147 | 'skip', 'add', 'forget', 'avoid', 'throw', 'buy', 'sell' 1148 | ] 1149 | 1150 | const nouns = [ 1151 | 'Italian', 'milk', 'needle work', 'chess', 'Node.js', 'fines', 1152 | 'books', 'boots', 'fishing rod', 'distant relatives', 'charges', 1153 | 'knife', 'castle', 'laptop', 'principles', 'adults', 'bird' 1154 | ] 1155 | 1156 | module.exports = { 1157 | modifiers: modifiers, 1158 | verbs: verbs, 1159 | nouns: nouns 1160 | } 1161 | 1162 | 1163 | /***/ }, 1164 | /* 6 */ 1165 | /***/ function(module, exports, __webpack_require__) { 1166 | 1167 | (function () { 1168 | 'use strict'; 1169 | 1170 | function setupConsoleTable() { 1171 | if (typeof console === 'undefined') { 1172 | throw new Error('Weird, console object is undefined'); 1173 | } 1174 | if (typeof console.table === 'function') { 1175 | return; 1176 | } 1177 | 1178 | var Table = __webpack_require__(7); 1179 | 1180 | function arrayToString(arr) { 1181 | var t = new Table(); 1182 | arr.forEach(function (record) { 1183 | if (typeof record === 'string' || 1184 | typeof record === 'number') { 1185 | t.cell('item', record); 1186 | } else { 1187 | // assume plain object 1188 | Object.keys(record).forEach(function (property) { 1189 | t.cell(property, record[property]); 1190 | }); 1191 | } 1192 | t.newRow(); 1193 | }); 1194 | return t.toString(); 1195 | } 1196 | 1197 | function printTitleTable(title, arr) { 1198 | var str = arrayToString(arr); 1199 | var rowLength = str.indexOf('\n'); 1200 | if (rowLength > 0) { 1201 | if (title.length > rowLength) { 1202 | rowLength = title.length; 1203 | } 1204 | console.log(title); 1205 | var sep = '-', k, line = ''; 1206 | for (k = 0; k < rowLength; k += 1) { 1207 | line += sep; 1208 | } 1209 | console.log(line); 1210 | } 1211 | console.log(str); 1212 | } 1213 | 1214 | function objectToArray(obj) { 1215 | var keys = Object.keys(obj); 1216 | return keys.map(function (key) { 1217 | return { 1218 | key: key, 1219 | value: obj[key] 1220 | }; 1221 | }); 1222 | } 1223 | 1224 | function objectToString(obj) { 1225 | return arrayToString(objectToArray(obj)); 1226 | } 1227 | 1228 | console.table = function () { 1229 | var args = Array.prototype.slice.call(arguments); 1230 | 1231 | if (args.length === 2 && 1232 | typeof args[0] === 'string' && 1233 | Array.isArray(args[1])) { 1234 | 1235 | return printTitleTable(args[0], args[1]); 1236 | } 1237 | args.forEach(function (k) { 1238 | if (typeof k === 'string') { 1239 | return console.log(k); 1240 | } else if (Array.isArray(k)) { 1241 | console.log(arrayToString(k)); 1242 | } else if (typeof k === 'object') { 1243 | console.log(objectToString(k)); 1244 | } 1245 | }); 1246 | }; 1247 | } 1248 | 1249 | setupConsoleTable(); 1250 | }()); 1251 | 1252 | 1253 | /***/ }, 1254 | /* 7 */ 1255 | /***/ function(module, exports, __webpack_require__) { 1256 | 1257 | module.exports = Table 1258 | 1259 | Table.string = function (val) { 1260 | if (val === undefined) return '' 1261 | return String(val) 1262 | } 1263 | 1264 | Table.Number = function (digits) { 1265 | return function (val, width) { 1266 | if (val === undefined) return '' 1267 | if (typeof val != 'number') 1268 | throw new Error(String(val) + ' is not a number') 1269 | var s = digits == null ? String(val) : val.toFixed(digits).toString() 1270 | return Table.padLeft(s, width) 1271 | } 1272 | } 1273 | 1274 | Table.RightPadder = function (char) { 1275 | char = char || ' ' 1276 | return function (val, length) { 1277 | var s = String(val) 1278 | var l = s.length 1279 | for (var i = 0; i < length - l; i++) { 1280 | s += char 1281 | } 1282 | return s 1283 | } 1284 | } 1285 | 1286 | Table.LeftPadder = function (char) { 1287 | char = char || ' ' 1288 | return function (val, length) { 1289 | var ret = '' 1290 | var s = String(val) 1291 | for (var i = 0; i < length - s.length; i++) { 1292 | ret += char 1293 | } 1294 | ret += s 1295 | return ret 1296 | } 1297 | } 1298 | 1299 | Table.padLeft = Table.LeftPadder() 1300 | 1301 | Table.printArray = function (arr, format, cb) { 1302 | format = typeof format == 'function' ? format : Formatter(format) 1303 | cb = cb || function (t) { 1304 | return t.toString() 1305 | } 1306 | 1307 | var t = new Table 1308 | var cell = t.cell.bind(t) 1309 | 1310 | arr.forEach(function (obj) { 1311 | format(obj, cell) 1312 | t.newRow() 1313 | }) 1314 | return cb(t) 1315 | } 1316 | 1317 | Table.printObj = function (obj, format, cb) { 1318 | format = typeof format == 'function' ? format : Formatter(format) 1319 | cb = cb || function (t) { 1320 | return t.printTransposed(' : ') 1321 | } 1322 | 1323 | var t = new Table 1324 | format(obj, t.cell.bind(t)) 1325 | t.newRow() 1326 | return cb(t) 1327 | } 1328 | 1329 | function Formatter (opts) { 1330 | opts = opts || {} 1331 | return function (obj, cell) { 1332 | for (var key in obj) { 1333 | if (!obj.hasOwnProperty(key)) continue 1334 | var o = opts[key] 1335 | cell( 1336 | (o && o.name) || key, 1337 | obj[key], 1338 | o && o.printer, 1339 | o && o.width 1340 | ) 1341 | } 1342 | } 1343 | } 1344 | 1345 | 1346 | Table.Row = Row 1347 | function Row () { 1348 | Object.defineProperties(this, { 1349 | __printers: { 1350 | value: {}, 1351 | enumerable: false 1352 | }, 1353 | __cell: { 1354 | value: function (col, val, printer) { 1355 | this[col] = val 1356 | this.__printers[col] = printer 1357 | }, 1358 | enumerable: false 1359 | } 1360 | }) 1361 | } 1362 | 1363 | 1364 | Table.print = print 1365 | function print (rows, columns, shift) { 1366 | var padSpaces = Table.RightPadder() 1367 | var widths = {} 1368 | 1369 | function setWidth (col, width) { 1370 | var isFixed = columns[col].width != null 1371 | if (isFixed) { 1372 | widths[col] = columns[col].width 1373 | } else { 1374 | if (widths[col] > width) return 1375 | widths[col] = width 1376 | } 1377 | } 1378 | 1379 | function cellPrinter (row, col) { 1380 | return (row.__printers && row.__printers[col]) || Table.string 1381 | } 1382 | 1383 | function calcWidths () { 1384 | rows.forEach(function (row) { 1385 | for (var key in columns) { 1386 | setWidth(key, cellPrinter(row, key).call(row, row[key]).length) 1387 | } 1388 | }) 1389 | } 1390 | 1391 | function printRow (cb) { 1392 | var s = '' 1393 | var firstColumn = true 1394 | for (var key in columns) { 1395 | if (!firstColumn) s += shift 1396 | firstColumn = false 1397 | var width = widths[key] 1398 | s += printCell(cb(key, width), width) 1399 | } 1400 | s += '\n' 1401 | return s 1402 | } 1403 | 1404 | function printCell (s, width) { 1405 | if (s.length <= width) return padSpaces(s, width) 1406 | s = s.slice(0, width) 1407 | if (width > 3) s = s.slice(0, -3).concat('...') 1408 | return s 1409 | } 1410 | 1411 | calcWidths() 1412 | 1413 | return rows.map(function (row) { 1414 | return printRow(function (key, width) { 1415 | return cellPrinter(row, key).call(row, row[key], width) 1416 | }) 1417 | }).join('') 1418 | 1419 | } 1420 | 1421 | 1422 | function Table () { 1423 | this.columns = {} /* @api: public */ 1424 | this.rows = [] /* @api: public */ 1425 | this._row = new Row 1426 | } 1427 | 1428 | 1429 | Table.prototype.cell = function (col, val, printer, width) { 1430 | this._row.__cell(col, val, printer) 1431 | var c = this.columns[col] || (this.columns[col] = {}) 1432 | if (width != null) c.width = width 1433 | return this 1434 | } 1435 | 1436 | Table.prototype.newRow = Table.prototype.newLine = function () { 1437 | this.rows.push(this._row) 1438 | this._row = new Row 1439 | return this 1440 | } 1441 | 1442 | Table.prototype.sort = __webpack_require__(8) 1443 | 1444 | Table.aggr = __webpack_require__(9) 1445 | 1446 | Table.prototype.totals = null /* @api: public */ 1447 | 1448 | Table.prototype.total = function (col, fn, printer) { 1449 | fn = fn || Table.aggr.sum 1450 | printer = printer || fn.printer 1451 | 1452 | this.totals = this.totals || new Row 1453 | 1454 | var val 1455 | var rows = this.rows 1456 | 1457 | this.totals.__cell(col, null, function (_, width) { 1458 | if (width != null) return printer(val, width) 1459 | val = rows.reduce(function (val, row, index) { 1460 | return fn(val, row[col], index, rows.length) 1461 | }, null) 1462 | return printer(val) 1463 | }) 1464 | return this 1465 | } 1466 | 1467 | Table.prototype.shift = ' ' 1468 | 1469 | Table.prototype.print = function () { 1470 | return print(this.rows, this.columns, this.shift) 1471 | } 1472 | 1473 | Table.prototype.printTransposed = function (delimeter) { 1474 | var t = new Table 1475 | if (delimeter) t.shift = delimeter 1476 | 1477 | function Printer (row, key) { 1478 | var p = row.__printers && row.__printers[key] 1479 | if (p) return function (val) { 1480 | return p(val) 1481 | } 1482 | } 1483 | 1484 | for (var key in this.columns) { 1485 | t.cell('h', key) 1486 | this.rows.forEach(function (row, index) { 1487 | t.cell('f' + index, row[key], Printer(row, key)) 1488 | }) 1489 | t.newRow() 1490 | } 1491 | return t.print() 1492 | } 1493 | 1494 | Table.prototype.toString = function () { 1495 | var padWithDashs = Table.RightPadder('-') 1496 | var delimeter = this.createRow(function () { 1497 | return ['', padWithDashs] 1498 | }) 1499 | var head = this.createRow(function (key) { 1500 | return [key] 1501 | }) 1502 | var rows = [head, delimeter].concat(this.rows) 1503 | if (this.totals) { 1504 | rows = rows.concat([delimeter, this.totals]) 1505 | } 1506 | return print(rows, this.columns, this.shift) 1507 | } 1508 | 1509 | Table.prototype.createRow = function (cb) { 1510 | var row = new Row 1511 | for (var key in this.columns) { 1512 | var args = cb(key) 1513 | row.__cell(key, args[0], args[1]) 1514 | } 1515 | return row 1516 | } 1517 | 1518 | /***/ }, 1519 | /* 8 */ 1520 | /***/ function(module, exports) { 1521 | 1522 | module.exports = sort 1523 | 1524 | function sort (comparator) { 1525 | if (typeof comparator != 'function') { 1526 | var sortKeys = Array.isArray(comparator) 1527 | ? comparator 1528 | : Object.keys(this.columns) 1529 | comparator = KeysComparator(sortKeys) 1530 | } 1531 | this.rows.sort(comparator) 1532 | return this 1533 | } 1534 | 1535 | function KeysComparator (keys) { 1536 | var comparators = keys.map(function (key) { 1537 | var sortFn = 'asc' 1538 | 1539 | var m = /(.*)\|\s*(asc|des)\s*$/.exec(key) 1540 | if (m) { 1541 | key = m[1] 1542 | sortFn = m[2] 1543 | } 1544 | 1545 | return function (a, b) { 1546 | var ret = compare(a[key], b[key]) 1547 | return sortFn == 'asc' ? ret : -1 * ret 1548 | } 1549 | }) 1550 | 1551 | return function (a, b) { 1552 | for (var i = 0; i < comparators.length; i++) { 1553 | var res = comparators[i](a, b) 1554 | if (res != 0) return res 1555 | } 1556 | return 0 1557 | } 1558 | } 1559 | 1560 | function compare (a, b) { 1561 | if (a === b) return 0 1562 | if (a === undefined) return 1 1563 | if (b === undefined) return -1 1564 | if (a === null) return 1 1565 | if (b === null) return -1 1566 | if (a > b) return 1 1567 | if (a < b) return -1 1568 | return compare(String(a), String(b)) 1569 | } 1570 | 1571 | /***/ }, 1572 | /* 9 */ 1573 | /***/ function(module, exports, __webpack_require__) { 1574 | 1575 | var padLeft = __webpack_require__(7).padLeft 1576 | 1577 | var Printer = exports.Printer = function (name, format) { 1578 | return function (val, width) { 1579 | var s = name + ' ' + format(val) 1580 | return width == null 1581 | ? s 1582 | : padLeft(s, width) 1583 | } 1584 | } 1585 | 1586 | 1587 | exports.sum = function (sum, val) { 1588 | sum = sum || 0 1589 | return sum += val 1590 | } 1591 | 1592 | exports.sum.printer = Printer('\u2211', String) 1593 | 1594 | 1595 | exports.avg = function (sum, val, index, length) { 1596 | sum = sum || 0 1597 | sum += val 1598 | return index + 1 == length 1599 | ? sum / length 1600 | : sum 1601 | } 1602 | 1603 | exports.avg.printer = Printer('Avg:', String) 1604 | 1605 | /***/ } 1606 | /******/ ]) 1607 | }); 1608 | ; -------------------------------------------------------------------------------- /dist/demo-app.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) 10 | /******/ return installedModules[moduleId].exports; 11 | 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ exports: {}, 15 | /******/ id: moduleId, 16 | /******/ loaded: false 17 | /******/ }; 18 | 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | 22 | /******/ // Flag the module as loaded 23 | /******/ module.loaded = true; 24 | 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | 29 | 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | 36 | /******/ // __webpack_public_path__ 37 | /******/ __webpack_require__.p = ""; 38 | 39 | /******/ // Load entry module and return exports 40 | /******/ return __webpack_require__(0); 41 | /******/ }) 42 | /************************************************************************/ 43 | /******/ ([ 44 | /* 0 */ 45 | /***/ function(module, exports, __webpack_require__) { 46 | 47 | __webpack_require__(1) 48 | __webpack_require__(2) 49 | 50 | var Todos = __webpack_require__(3) 51 | Todos.items = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"..\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()))(100) 52 | var virtualDom = __webpack_require__(8)(Todos) 53 | var createElement = __webpack_require__(31) 54 | var rootNode = createElement(virtualDom) 55 | document.body.appendChild(rootNode) 56 | 57 | 58 | /***/ }, 59 | /* 1 */ 60 | /***/ function(module, exports) { 61 | 62 | // removed by extract-text-webpack-plugin 63 | 64 | /***/ }, 65 | /* 2 */ 66 | /***/ function(module, exports) { 67 | 68 | // removed by extract-text-webpack-plugin 69 | 70 | /***/ }, 71 | /* 3 */ 72 | /***/ function(module, exports, __webpack_require__) { 73 | 74 | const la = __webpack_require__(4) 75 | const is = __webpack_require__(5) 76 | const uuid = __webpack_require__(6) 77 | 78 | var Todos = { 79 | add: function add (what) { 80 | la(is.unemptyString(what), 'expected unempty string', what) 81 | Todos.items.unshift({ 82 | what: what, 83 | done: false, 84 | id: uuid() 85 | }) 86 | }, 87 | mark: function mark (id, done) { 88 | la(is.unemptyString(id), 'expected id', id) 89 | Todos.items.forEach(function (todo) { 90 | if (todo.id === id) { 91 | todo.done = done 92 | } 93 | }) 94 | }, 95 | remove: function remove (todo) { 96 | la(is.object(todo), 'missing todo to remove', todo) 97 | Todos.items = Todos.items.filter(function (t) { 98 | return t.id !== todo.id 99 | }) 100 | }, 101 | clearCompleted: function clearCompleted () { 102 | console.log('clearCompleted not implemented') 103 | }, 104 | items: [] 105 | } 106 | 107 | la(is.array(Todos.items), 'expected list of todos', Todos.items) 108 | 109 | module.exports = Todos 110 | 111 | 112 | /***/ }, 113 | /* 4 */ 114 | /***/ function(module, exports) { 115 | 116 | /* WEBPACK VAR INJECTION */(function(global) {(function initLazyAss() { 117 | 118 | function isArrayLike(a) { 119 | return a && typeof a.length === 'number'; 120 | } 121 | 122 | function toStringArray(arr) { 123 | return 'array with ' + arr.length + ' items.\n[' + 124 | arr.map(toString).join(',') + ']\n'; 125 | } 126 | 127 | function isPrimitive(arg) { 128 | return typeof arg === 'string' || 129 | typeof arg === 'number' || 130 | typeof arg === 'boolean'; 131 | } 132 | 133 | function toString(arg, k) { 134 | if (isPrimitive(arg)) { 135 | return JSON.stringify(arg); 136 | } 137 | if (arg instanceof Error) { 138 | return arg.name + ' ' + arg.message; 139 | } 140 | 141 | if (Array.isArray(arg)) { 142 | return toStringArray(arg); 143 | } 144 | if (isArrayLike(arg)) { 145 | return toStringArray(Array.prototype.slice.call(arg, 0)); 146 | } 147 | var argString; 148 | try { 149 | argString = JSON.stringify(arg, null, 2); 150 | } catch (err) { 151 | argString = '{ cannot stringify arg ' + k + ', it has type "' + typeof arg + '"'; 152 | if (typeof arg === 'object') { 153 | argString += ' with keys ' + Object.keys(arg).join(', ') + ' }'; 154 | } else { 155 | argString += ' }'; 156 | } 157 | } 158 | return argString; 159 | } 160 | 161 | function endsWithNewLine(s) { 162 | return /\n$/.test(s); 163 | } 164 | 165 | function formMessage(args) { 166 | var msg = args.reduce(function (total, arg, k) { 167 | if (k && !endsWithNewLine(total)) { 168 | total += ' '; 169 | } 170 | if (typeof arg === 'string') { 171 | return total + arg; 172 | } 173 | if (typeof arg === 'function') { 174 | var fnResult; 175 | try { 176 | fnResult = arg(); 177 | } catch (err) { 178 | // ignore the error 179 | fnResult = '[function ' + arg.name + ' threw error!]'; 180 | } 181 | return total + fnResult; 182 | } 183 | var argString = toString(arg, k); 184 | return total + argString; 185 | }, ''); 186 | return msg; 187 | } 188 | 189 | function lazyAssLogic(condition) { 190 | var fn = typeof condition === 'function' ? condition : null; 191 | 192 | if (fn) { 193 | condition = fn(); 194 | } 195 | if (!condition) { 196 | var args = [].slice.call(arguments, 1); 197 | if (fn) { 198 | args.unshift(fn.toString()); 199 | } 200 | return new Error(formMessage(args)); 201 | } 202 | } 203 | 204 | var lazyAss = function lazyAss() { 205 | var err = lazyAssLogic.apply(null, arguments); 206 | if (err) { 207 | throw err; 208 | } 209 | }; 210 | 211 | var lazyAssync = function lazyAssync() { 212 | var err = lazyAssLogic.apply(null, arguments); 213 | if (err) { 214 | setTimeout(function () { 215 | throw err; 216 | }, 0); 217 | } 218 | }; 219 | 220 | lazyAss.async = lazyAssync; 221 | 222 | function isNode() { 223 | return typeof global === 'object'; 224 | } 225 | 226 | function isBrowser() { 227 | return typeof window === 'object'; 228 | } 229 | 230 | function isCommonJS() { 231 | return typeof module === 'object'; 232 | } 233 | 234 | function globalRegister() { 235 | if (isNode()) { 236 | /* global global */ 237 | register(global, lazyAss, 'lazyAss', 'la'); 238 | register(global, lazyAssync, 'lazyAssync', 'lac'); 239 | } 240 | } 241 | 242 | function register(root, value, name, alias) { 243 | root[name] = root[alias] = value; 244 | } 245 | 246 | lazyAss.globalRegister = globalRegister; 247 | 248 | if (isBrowser()) { 249 | /* global window */ 250 | register(window, lazyAss, 'lazyAss', 'la'); 251 | register(window, lazyAssync, 'lazyAssync', 'lac'); 252 | } 253 | 254 | if (isCommonJS()) { 255 | /* global module */ 256 | module.exports = lazyAss; 257 | } 258 | 259 | }()); 260 | 261 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 262 | 263 | /***/ }, 264 | /* 5 */ 265 | /***/ function(module, exports, __webpack_require__) { 266 | 267 | /* WEBPACK VAR INJECTION */(function(global) {(function checkMoreTypes() { 268 | 'use strict'; 269 | 270 | /** 271 | Custom assertions and predicates around https://github.com/philbooth/check-types.js 272 | Created by Kensho https://github.com/kensho 273 | Copyright @ 2014 Kensho https://www.kensho.com/ 274 | License: MIT 275 | 276 | @module check 277 | */ 278 | 279 | if (typeof Function.prototype.bind !== 'function') { 280 | throw new Error('Missing Function.prototype.bind, please load es5-shim first'); 281 | } 282 | 283 | // utility method 284 | function curry2(fn, strict2) { 285 | return function curried(a) { 286 | if (strict2 && arguments.length > 2) { 287 | throw new Error('Curry2 function ' + fn.name + 288 | ' called with too many arguments ' + arguments.length); 289 | } 290 | if (arguments.length === 2) { 291 | return fn(arguments[0], arguments[1]); 292 | } 293 | return function second(b) { 294 | return fn(a, b); 295 | }; 296 | }; 297 | } 298 | 299 | // most of the old methods from check-types.js 300 | function isFn(x) { return typeof x === 'function'; } 301 | function isString(x) { return typeof x === 'string'; } 302 | function unemptyString(x) { 303 | return isString(x) && x; 304 | } 305 | function isObject(x) { 306 | return typeof x === 'object' && 307 | !Array.isArray(x) && 308 | !isNull(x) && 309 | !isDate(x); 310 | } 311 | function isEmptyObject(x) { 312 | return isObject(x) && 313 | Object.keys(x).length === 0; 314 | } 315 | function isNumber(x) { 316 | return typeof x === 'number' && 317 | !isNaN(x) && 318 | x !== Infinity && 319 | x !== -Infinity; 320 | } 321 | function isInteger(x) { 322 | return isNumber(x) && x % 1 === 0; 323 | } 324 | function isFloat(x) { 325 | return isNumber(x) && x % 1 !== 0; 326 | } 327 | function isNull(x) { return x === null; } 328 | function positiveNumber(x) { 329 | return isNumber(x) && x > 0; 330 | } 331 | function negativeNumber(x) { 332 | return isNumber(x) && x < 0; 333 | } 334 | function isDate(x) { 335 | return x instanceof Date; 336 | } 337 | function isRegExp(x) { 338 | return x instanceof RegExp; 339 | } 340 | function instance(x, type) { 341 | return x instanceof type; 342 | } 343 | function hasLength(x, k) { 344 | if (typeof x === 'number' && typeof k !== 'number') { 345 | // swap arguments 346 | return hasLength(k, x); 347 | } 348 | return (Array.isArray(x) || isString(x)) && x.length === k; 349 | } 350 | 351 | /** 352 | Checks if the given index is valid in an array or string or -1 353 | 354 | @method found 355 | */ 356 | function found(index) { 357 | return index >= 0; 358 | } 359 | 360 | function startsWith(prefix, x) { 361 | return isString(prefix) && 362 | isString(x) && 363 | x.indexOf(prefix) === 0; 364 | } 365 | 366 | /** 367 | Checks if the type of second argument matches the name in the first 368 | 369 | @method type 370 | */ 371 | function type(expectedType, x) { 372 | return typeof x === expectedType; 373 | } 374 | 375 | var startsWithHttp = startsWith.bind(null, 'http://'); 376 | var startsWithHttps = startsWith.bind(null, 'https://'); 377 | 378 | function webUrl(x) { 379 | return isString(x) && 380 | (startsWithHttp(x) || startsWithHttps(x)); 381 | } 382 | 383 | function every(predicateResults) { 384 | var property, value; 385 | for (property in predicateResults) { 386 | if (predicateResults.hasOwnProperty(property)) { 387 | value = predicateResults[property]; 388 | 389 | if (isObject(value) && every(value) === false) { 390 | return false; 391 | } 392 | 393 | if (value === false) { 394 | return false; 395 | } 396 | } 397 | } 398 | return true; 399 | } 400 | 401 | function map(things, predicates) { 402 | var property, result = {}, predicate; 403 | for (property in predicates) { 404 | if (predicates.hasOwnProperty(property)) { 405 | predicate = predicates[property]; 406 | 407 | if (isFn(predicate)) { 408 | result[property] = predicate(things[property]); 409 | } else if (isObject(predicate)) { 410 | result[property] = map(things[property], predicate); 411 | } 412 | } 413 | } 414 | 415 | return result; 416 | } 417 | 418 | var check = { 419 | maybe: {}, 420 | verify: {}, 421 | not: {}, 422 | every: every, 423 | map: map 424 | }; 425 | 426 | /** 427 | Checks if argument is defined or not 428 | 429 | This method now is part of the check-types.js 430 | @method defined 431 | */ 432 | function defined(value) { 433 | return typeof value !== 'undefined'; 434 | } 435 | 436 | /** 437 | Checks if argument is a valid Date instance 438 | 439 | @method validDate 440 | */ 441 | function validDate(value) { 442 | return check.date(value) && 443 | check.number(Number(value)); 444 | } 445 | 446 | /** 447 | Checks if it is exact semver 448 | 449 | @method semver 450 | */ 451 | function semver(s) { 452 | return check.unemptyString(s) && 453 | /^\d+\.\d+\.\d+$/.test(s); 454 | } 455 | 456 | /** 457 | Returns true if the argument is primitive JavaScript type 458 | 459 | @method primitive 460 | */ 461 | function primitive(value) { 462 | var type = typeof value; 463 | return type === 'number' || 464 | type === 'boolean' || 465 | type === 'string' || 466 | type === 'symbol'; 467 | } 468 | 469 | /** 470 | Returns true if the value is a number 0 471 | 472 | @method zero 473 | */ 474 | function zero(x) { 475 | return typeof x === 'number' && x === 0; 476 | } 477 | 478 | /** 479 | same as === 480 | 481 | @method same 482 | */ 483 | function same(a, b) { 484 | return a === b; 485 | } 486 | 487 | /** 488 | Returns true if the index is valid for give string / array 489 | 490 | @method index 491 | */ 492 | function index(list, k) { 493 | return defined(list) && 494 | has(list, 'length') && 495 | k >= 0 && 496 | k < list.length; 497 | } 498 | 499 | /** 500 | Returns true if both objects are the same type and have same length property 501 | 502 | @method sameLength 503 | */ 504 | function sameLength(a, b) { 505 | return typeof a === typeof b && 506 | a && b && 507 | a.length === b.length; 508 | } 509 | 510 | /** 511 | Returns true if all items in an array are the same reference 512 | 513 | @method allSame 514 | */ 515 | function allSame(arr) { 516 | if (!check.array(arr)) { 517 | return false; 518 | } 519 | if (!arr.length) { 520 | return true; 521 | } 522 | var first = arr[0]; 523 | return arr.every(function (item) { 524 | return item === first; 525 | }); 526 | } 527 | 528 | /** 529 | Returns true if given item is in the array 530 | 531 | @method oneOf 532 | */ 533 | function oneOf(arr, x) { 534 | check.verify.array(arr, 'expected an array'); 535 | return arr.indexOf(x) !== -1; 536 | } 537 | 538 | /** 539 | Returns true for urls of the format `git@....git` 540 | 541 | @method git 542 | */ 543 | function git(url) { 544 | return check.unemptyString(url) && 545 | /^git@/.test(url); 546 | } 547 | 548 | /** 549 | Checks if given value is 0 or 1 550 | 551 | @method bit 552 | */ 553 | function bit(value) { 554 | return value === 0 || value === 1; 555 | } 556 | 557 | /** 558 | Checks if given value is true of false 559 | 560 | @method bool 561 | */ 562 | function bool(value) { 563 | return typeof value === 'boolean'; 564 | } 565 | 566 | /** 567 | Checks if given object has a property 568 | @method has 569 | */ 570 | function has(o, property) { 571 | if (arguments.length !== 2) { 572 | throw new Error('Expected two arguments to check.has, got only ' + arguments.length); 573 | } 574 | return Boolean(o && property && 575 | typeof property === 'string' && 576 | typeof o[property] !== 'undefined'); 577 | } 578 | 579 | /** 580 | Checks if given string is already in lower case 581 | @method lowerCase 582 | */ 583 | function lowerCase(str) { 584 | return check.string(str) && 585 | str.toLowerCase() === str; 586 | } 587 | 588 | /** 589 | Returns true if the argument is an array with at least one value 590 | @method unemptyArray 591 | */ 592 | function unemptyArray(a) { 593 | return check.array(a) && a.length > 0; 594 | } 595 | 596 | /** 597 | Returns true if each item in the array passes the predicate 598 | @method arrayOf 599 | @param rule Predicate function 600 | @param a Array to check 601 | */ 602 | function arrayOf(rule, a) { 603 | return check.array(a) && a.every(rule); 604 | } 605 | 606 | /** 607 | Returns items from array that do not passes the predicate 608 | @method badItems 609 | @param rule Predicate function 610 | @param a Array with items 611 | */ 612 | function badItems(rule, a) { 613 | check.verify.array(a, 'expected array to find bad items'); 614 | return a.filter(notModifier(rule)); 615 | } 616 | 617 | /** 618 | Returns true if given array only has strings 619 | @method arrayOfStrings 620 | @param a Array to check 621 | @param checkLowerCase Checks if all strings are lowercase 622 | */ 623 | function arrayOfStrings(a, checkLowerCase) { 624 | var v = check.array(a) && a.every(check.string); 625 | if (v && check.bool(checkLowerCase) && checkLowerCase) { 626 | return a.every(check.lowerCase); 627 | } 628 | return v; 629 | } 630 | 631 | /** 632 | Returns true if given argument is array of arrays of strings 633 | @method arrayOfArraysOfStrings 634 | @param a Array to check 635 | @param checkLowerCase Checks if all strings are lowercase 636 | */ 637 | function arrayOfArraysOfStrings(a, checkLowerCase) { 638 | return check.array(a) && a.every(function (arr) { 639 | return check.arrayOfStrings(arr, checkLowerCase); 640 | }); 641 | } 642 | 643 | /** 644 | Checks if object passes all rules in predicates. 645 | 646 | check.all({ foo: 'foo' }, { foo: check.string }, 'wrong object'); 647 | 648 | This is a composition of check.every(check.map ...) calls 649 | https://github.com/philbooth/check-types.js#batch-operations 650 | 651 | @method all 652 | @param {object} object object to check 653 | @param {object} predicates rules to check. Usually one per property. 654 | @public 655 | @returns true or false 656 | */ 657 | function all(obj, predicates) { 658 | check.verify.fn(check.every, 'missing check.every method'); 659 | check.verify.fn(check.map, 'missing check.map method'); 660 | 661 | check.verify.object(obj, 'missing object to check'); 662 | check.verify.object(predicates, 'missing predicates object'); 663 | Object.keys(predicates).forEach(function (property) { 664 | if (!check.fn(predicates[property])) { 665 | throw new Error('not a predicate function for ' + property + ' but ' + predicates[property]); 666 | } 667 | }); 668 | return check.every(check.map(obj, predicates)); 669 | } 670 | 671 | /** 672 | Checks given object against predicates object 673 | @method schema 674 | */ 675 | function schema(predicates, obj) { 676 | return all(obj, predicates); 677 | } 678 | 679 | /** Checks if given function raises an error 680 | 681 | @method raises 682 | */ 683 | function raises(fn, errorValidator) { 684 | check.verify.fn(fn, 'expected function that raises'); 685 | try { 686 | fn(); 687 | } catch (err) { 688 | if (typeof errorValidator === 'undefined') { 689 | return true; 690 | } 691 | if (typeof errorValidator === 'function') { 692 | return errorValidator(err); 693 | } 694 | return false; 695 | } 696 | // error has not been raised 697 | return false; 698 | } 699 | 700 | /** 701 | Returns true if given value is '' 702 | @method emptyString 703 | */ 704 | function emptyString(a) { 705 | return a === ''; 706 | } 707 | 708 | /** 709 | Returns true if given value is [], {} or '' 710 | @method empty 711 | */ 712 | function empty(a) { 713 | var hasLength = typeof a === 'string' || 714 | Array.isArray(a); 715 | if (hasLength) { 716 | return !a.length; 717 | } 718 | if (a instanceof Object) { 719 | return !Object.keys(a).length; 720 | } 721 | return false; 722 | } 723 | 724 | /** 725 | Returns true if given value has .length and it is not zero, or has properties 726 | @method unempty 727 | */ 728 | function unempty(a) { 729 | var hasLength = typeof a === 'string' || 730 | Array.isArray(a); 731 | if (hasLength) { 732 | return a.length; 733 | } 734 | if (a instanceof Object) { 735 | return Object.keys(a).length; 736 | } 737 | return true; 738 | } 739 | 740 | /** 741 | Returns true if 0 <= value <= 1 742 | @method unit 743 | */ 744 | function unit(value) { 745 | return check.number(value) && 746 | value >= 0.0 && value <= 1.0; 747 | } 748 | 749 | var rgb = /^#(?:[0-9a-fA-F]{3}){1,2}$/; 750 | /** 751 | Returns true if value is hex RGB between '#000000' and '#FFFFFF' 752 | @method hexRgb 753 | */ 754 | function hexRgb(value) { 755 | return check.string(value) && 756 | rgb.test(value); 757 | } 758 | 759 | // typical git SHA commit id is 40 digit hex string, like 760 | // 3b819803cdf2225ca1338beb17e0c506fdeedefc 761 | var shaReg = /^[0-9a-f]{40}$/; 762 | 763 | /** 764 | Returns true if the given string is 40 digit SHA commit id 765 | @method commitId 766 | */ 767 | function commitId(id) { 768 | return check.string(id) && 769 | id.length === 40 && 770 | shaReg.test(id); 771 | } 772 | 773 | // when using git log --oneline short ids are displayed, first 7 characters 774 | var shortShaReg = /^[0-9a-f]{7}$/; 775 | 776 | /** 777 | Returns true if the given string is short 7 character SHA id part 778 | @method shortCommitId 779 | */ 780 | function shortCommitId(id) { 781 | return check.string(id) && 782 | id.length === 7 && 783 | shortShaReg.test(id); 784 | } 785 | 786 | // 787 | // helper methods 788 | // 789 | 790 | if (!check.defend) { 791 | var checkPredicates = function checksPredicates(fn, predicates, args) { 792 | check.verify.fn(fn, 'expected a function'); 793 | check.verify.array(predicates, 'expected list of predicates'); 794 | check.verify.defined(args, 'missing args'); 795 | 796 | var k = 0, // iterates over predicates 797 | j = 0, // iterates over arguments 798 | n = predicates.length; 799 | 800 | for (k = 0; k < n; k += 1) { 801 | var predicate = predicates[k]; 802 | if (!check.fn(predicate)) { 803 | continue; 804 | } 805 | 806 | if (!predicate.call(null, args[j])) { 807 | var msg = 'Argument ' + (j + 1) + ': ' + args[j] + ' does not pass predicate'; 808 | if (check.unemptyString(predicates[k + 1])) { 809 | msg += ': ' + predicates[k + 1]; 810 | } 811 | throw new Error(msg); 812 | } 813 | 814 | j += 1; 815 | } 816 | return fn.apply(null, args); 817 | }; 818 | 819 | check.defend = function defend(fn) { 820 | var predicates = Array.prototype.slice.call(arguments, 1); 821 | return function () { 822 | return checkPredicates(fn, predicates, arguments); 823 | }; 824 | }; 825 | } 826 | 827 | /** 828 | Combines multiple predicate functions to produce new OR predicate 829 | @method or 830 | */ 831 | function or() { 832 | var predicates = Array.prototype.slice.call(arguments, 0); 833 | if (!predicates.length) { 834 | throw new Error('empty list of arguments to or'); 835 | } 836 | 837 | return function orCheck() { 838 | var values = Array.prototype.slice.call(arguments, 0); 839 | return predicates.some(function (predicate) { 840 | try { 841 | return check.fn(predicate) ? 842 | predicate.apply(null, values) : Boolean(predicate); 843 | } catch (err) { 844 | // treat exceptions as false 845 | return false; 846 | } 847 | }); 848 | }; 849 | } 850 | 851 | /** 852 | Combines multiple predicate functions to produce new AND predicate 853 | @method or 854 | */ 855 | function and() { 856 | var predicates = Array.prototype.slice.call(arguments, 0); 857 | if (!predicates.length) { 858 | throw new Error('empty list of arguments to or'); 859 | } 860 | 861 | return function orCheck() { 862 | var values = Array.prototype.slice.call(arguments, 0); 863 | return predicates.every(function (predicate) { 864 | return check.fn(predicate) ? 865 | predicate.apply(null, values) : Boolean(predicate); 866 | }); 867 | }; 868 | } 869 | 870 | /** 871 | * Public modifier `not`. 872 | * 873 | * Negates `predicate`. 874 | * copied from check-types.js 875 | */ 876 | function notModifier(predicate) { 877 | return function () { 878 | return !predicate.apply(null, arguments); 879 | }; 880 | } 881 | 882 | if (!check.mixin) { 883 | /** Adds new predicate to all objects 884 | @method mixin */ 885 | check.mixin = function mixin(fn, name) { 886 | if (isString(fn) && isFn(name)) { 887 | var tmp = fn; 888 | fn = name; 889 | name = tmp; 890 | } 891 | 892 | if (!isFn(fn)) { 893 | throw new Error('expected predicate function'); 894 | } 895 | if (!unemptyString(name)) { 896 | name = fn.name; 897 | } 898 | if (!unemptyString(name)) { 899 | throw new Error('predicate function missing name\n' + fn.toString()); 900 | } 901 | 902 | function registerPredicate(obj, name, fn) { 903 | if (!isObject(obj)) { 904 | throw new Error('missing object ' + obj); 905 | } 906 | if (!unemptyString(name)) { 907 | throw new Error('missing name'); 908 | } 909 | if (!isFn(fn)) { 910 | throw new Error('missing function'); 911 | } 912 | 913 | if (!obj[name]) { 914 | obj[name] = fn; 915 | } 916 | } 917 | 918 | /** 919 | * Public modifier `maybe`. 920 | * 921 | * Returns `true` if `predicate` is `null` or `undefined`, 922 | * otherwise propagates the return value from `predicate`. 923 | * copied from check-types.js 924 | */ 925 | function maybeModifier(predicate) { 926 | return function () { 927 | if (!check.defined(arguments[0]) || check.nulled(arguments[0])) { 928 | return true; 929 | } 930 | return predicate.apply(null, arguments); 931 | }; 932 | } 933 | 934 | /** 935 | * Public modifier `verify`. 936 | * 937 | * Throws if `predicate` returns `false`. 938 | * copied from check-types.js 939 | */ 940 | function verifyModifier(predicate, defaultMessage) { 941 | return function () { 942 | var message; 943 | if (predicate.apply(null, arguments) === false) { 944 | message = arguments[arguments.length - 1]; 945 | throw new Error(check.unemptyString(message) ? message : defaultMessage); 946 | } 947 | }; 948 | } 949 | 950 | registerPredicate(check, name, fn); 951 | registerPredicate(check.maybe, name, maybeModifier(fn)); 952 | registerPredicate(check.not, name, notModifier(fn)); 953 | registerPredicate(check.verify, name, verifyModifier(fn, name + ' failed')); 954 | }; 955 | } 956 | 957 | if (!check.then) { 958 | /** 959 | Executes given function only if condition is truthy. 960 | @method then 961 | */ 962 | check.then = function then(condition, fn) { 963 | return function () { 964 | var ok = typeof condition === 'function' ? 965 | condition.apply(null, arguments) : condition; 966 | if (ok) { 967 | return fn.apply(null, arguments); 968 | } 969 | }; 970 | }; 971 | } 972 | 973 | var promiseSchema = { 974 | then: isFn 975 | }; 976 | 977 | // work around reserved keywords checks 978 | promiseSchema['catch'] = isFn; 979 | promiseSchema['finally'] = isFn; 980 | 981 | var hasPromiseApi = schema.bind(null, promiseSchema); 982 | 983 | /** 984 | Returns true if argument implements promise api (.then, .catch, .finally) 985 | @method promise 986 | */ 987 | function isPromise(p) { 988 | return check.object(p) && hasPromiseApi(p); 989 | } 990 | 991 | /** 992 | Shallow strict comparison 993 | @method equal 994 | */ 995 | function equal(a, b) { 996 | return a === b; 997 | } 998 | 999 | // new predicates to be added to check object. Use object to preserve names 1000 | var predicates = { 1001 | nulled: isNull, 1002 | fn: isFn, 1003 | string: isString, 1004 | unemptyString: unemptyString, 1005 | object: isObject, 1006 | number: isNumber, 1007 | array: Array.isArray, 1008 | positiveNumber: positiveNumber, 1009 | negativeNumber: negativeNumber, 1010 | // a couple of aliases 1011 | positive: positiveNumber, 1012 | negative: negativeNumber, 1013 | defined: defined, 1014 | same: same, 1015 | allSame: allSame, 1016 | bit: bit, 1017 | bool: bool, 1018 | has: has, 1019 | lowerCase: lowerCase, 1020 | unemptyArray: unemptyArray, 1021 | arrayOfStrings: arrayOfStrings, 1022 | arrayOfArraysOfStrings: arrayOfArraysOfStrings, 1023 | all: all, 1024 | schema: curry2(schema), 1025 | raises: raises, 1026 | empty: empty, 1027 | found: found, 1028 | emptyString: emptyString, 1029 | unempty: unempty, 1030 | unit: unit, 1031 | hexRgb: hexRgb, 1032 | sameLength: sameLength, 1033 | commitId: commitId, 1034 | shortCommitId: shortCommitId, 1035 | index: index, 1036 | git: git, 1037 | arrayOf: arrayOf, 1038 | badItems: badItems, 1039 | oneOf: curry2(oneOf, true), 1040 | promise: isPromise, 1041 | validDate: validDate, 1042 | equal: curry2(equal), 1043 | or: or, 1044 | and: and, 1045 | primitive: primitive, 1046 | zero: zero, 1047 | date: isDate, 1048 | regexp: isRegExp, 1049 | instance: instance, 1050 | emptyObject: isEmptyObject, 1051 | length: curry2(hasLength), 1052 | floatNumber: isFloat, 1053 | intNumber: isInteger, 1054 | startsWith: startsWith, 1055 | webUrl: webUrl, 1056 | semver: semver, 1057 | type: curry2(type) 1058 | }; 1059 | 1060 | Object.keys(predicates).forEach(function (name) { 1061 | check.mixin(predicates[name], name); 1062 | }); 1063 | 1064 | if (true) { 1065 | module.exports = check; 1066 | } 1067 | 1068 | // if we are loaded under Node, but "window" object is available, put a reference 1069 | // there too - maybe we are running inside a synthetic browser environment 1070 | if (typeof window === 'object') { 1071 | window.check = check; 1072 | } 1073 | if (typeof global === 'object') { 1074 | global.check = check; 1075 | } 1076 | 1077 | }()); 1078 | 1079 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 1080 | 1081 | /***/ }, 1082 | /* 6 */ 1083 | /***/ function(module, exports) { 1084 | 1085 | // from http://jsfiddle.net/briguy37/2mvfd/ 1086 | function uuid () { 1087 | var d = new Date().getTime() 1088 | var uuidFormat = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 1089 | var id = uuidFormat.replace(/[xy]/g, function (c) { 1090 | var r = (d + Math.random() * 16) % 16 | 0 1091 | d = Math.floor(d / 16) 1092 | return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16) 1093 | }) 1094 | return id 1095 | } 1096 | 1097 | module.exports = uuid 1098 | 1099 | 1100 | /***/ }, 1101 | /* 7 */, 1102 | /* 8 */ 1103 | /***/ function(module, exports, __webpack_require__) { 1104 | 1105 | const h = __webpack_require__(9) 1106 | const header = __webpack_require__(27) 1107 | const renderTodos = __webpack_require__(28) 1108 | const footer = __webpack_require__(30) 1109 | const la = __webpack_require__(4) 1110 | const is = __webpack_require__(5) 1111 | const isTodos = is.schema({ 1112 | items: is.array, 1113 | clearCompleted: is.fn, 1114 | add: is.fn, 1115 | mark: is.fn, 1116 | remove: is.fn 1117 | }) 1118 | 1119 | function render (Todos) { 1120 | la(isTodos(Todos), 'Todos has incorrect interface', Todos) 1121 | return h('section', {className: 'todoapp'}, [ 1122 | header(Todos), 1123 | renderTodos(Todos), 1124 | footer(Todos) 1125 | ]) 1126 | } 1127 | 1128 | module.exports = render 1129 | 1130 | 1131 | /***/ }, 1132 | /* 9 */ 1133 | /***/ function(module, exports, __webpack_require__) { 1134 | 1135 | var h = __webpack_require__(10) 1136 | 1137 | module.exports = h 1138 | 1139 | 1140 | /***/ }, 1141 | /* 10 */ 1142 | /***/ function(module, exports, __webpack_require__) { 1143 | 1144 | 'use strict'; 1145 | 1146 | var isArray = __webpack_require__(11); 1147 | 1148 | var VNode = __webpack_require__(12); 1149 | var VText = __webpack_require__(18); 1150 | var isVNode = __webpack_require__(14); 1151 | var isVText = __webpack_require__(19); 1152 | var isWidget = __webpack_require__(15); 1153 | var isHook = __webpack_require__(17); 1154 | var isVThunk = __webpack_require__(16); 1155 | 1156 | var parseTag = __webpack_require__(20); 1157 | var softSetHook = __webpack_require__(22); 1158 | var evHook = __webpack_require__(23); 1159 | 1160 | module.exports = h; 1161 | 1162 | function h(tagName, properties, children) { 1163 | var childNodes = []; 1164 | var tag, props, key, namespace; 1165 | 1166 | if (!children && isChildren(properties)) { 1167 | children = properties; 1168 | props = {}; 1169 | } 1170 | 1171 | props = props || properties || {}; 1172 | tag = parseTag(tagName, props); 1173 | 1174 | // support keys 1175 | if (props.hasOwnProperty('key')) { 1176 | key = props.key; 1177 | props.key = undefined; 1178 | } 1179 | 1180 | // support namespace 1181 | if (props.hasOwnProperty('namespace')) { 1182 | namespace = props.namespace; 1183 | props.namespace = undefined; 1184 | } 1185 | 1186 | // fix cursor bug 1187 | if (tag === 'INPUT' && 1188 | !namespace && 1189 | props.hasOwnProperty('value') && 1190 | props.value !== undefined && 1191 | !isHook(props.value) 1192 | ) { 1193 | props.value = softSetHook(props.value); 1194 | } 1195 | 1196 | transformProperties(props); 1197 | 1198 | if (children !== undefined && children !== null) { 1199 | addChild(children, childNodes, tag, props); 1200 | } 1201 | 1202 | 1203 | return new VNode(tag, props, childNodes, key, namespace); 1204 | } 1205 | 1206 | function addChild(c, childNodes, tag, props) { 1207 | if (typeof c === 'string') { 1208 | childNodes.push(new VText(c)); 1209 | } else if (typeof c === 'number') { 1210 | childNodes.push(new VText(String(c))); 1211 | } else if (isChild(c)) { 1212 | childNodes.push(c); 1213 | } else if (isArray(c)) { 1214 | for (var i = 0; i < c.length; i++) { 1215 | addChild(c[i], childNodes, tag, props); 1216 | } 1217 | } else if (c === null || c === undefined) { 1218 | return; 1219 | } else { 1220 | throw UnexpectedVirtualElement({ 1221 | foreignObject: c, 1222 | parentVnode: { 1223 | tagName: tag, 1224 | properties: props 1225 | } 1226 | }); 1227 | } 1228 | } 1229 | 1230 | function transformProperties(props) { 1231 | for (var propName in props) { 1232 | if (props.hasOwnProperty(propName)) { 1233 | var value = props[propName]; 1234 | 1235 | if (isHook(value)) { 1236 | continue; 1237 | } 1238 | 1239 | if (propName.substr(0, 3) === 'ev-') { 1240 | // add ev-foo support 1241 | props[propName] = evHook(value); 1242 | } 1243 | } 1244 | } 1245 | } 1246 | 1247 | function isChild(x) { 1248 | return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x); 1249 | } 1250 | 1251 | function isChildren(x) { 1252 | return typeof x === 'string' || isArray(x) || isChild(x); 1253 | } 1254 | 1255 | function UnexpectedVirtualElement(data) { 1256 | var err = new Error(); 1257 | 1258 | err.type = 'virtual-hyperscript.unexpected.virtual-element'; 1259 | err.message = 'Unexpected virtual child passed to h().\n' + 1260 | 'Expected a VNode / Vthunk / VWidget / string but:\n' + 1261 | 'got:\n' + 1262 | errorString(data.foreignObject) + 1263 | '.\n' + 1264 | 'The parent vnode is:\n' + 1265 | errorString(data.parentVnode) 1266 | '\n' + 1267 | 'Suggested fix: change your `h(..., [ ... ])` callsite.'; 1268 | err.foreignObject = data.foreignObject; 1269 | err.parentVnode = data.parentVnode; 1270 | 1271 | return err; 1272 | } 1273 | 1274 | function errorString(obj) { 1275 | try { 1276 | return JSON.stringify(obj, null, ' '); 1277 | } catch (e) { 1278 | return String(obj); 1279 | } 1280 | } 1281 | 1282 | 1283 | /***/ }, 1284 | /* 11 */ 1285 | /***/ function(module, exports) { 1286 | 1287 | var nativeIsArray = Array.isArray 1288 | var toString = Object.prototype.toString 1289 | 1290 | module.exports = nativeIsArray || isArray 1291 | 1292 | function isArray(obj) { 1293 | return toString.call(obj) === "[object Array]" 1294 | } 1295 | 1296 | 1297 | /***/ }, 1298 | /* 12 */ 1299 | /***/ function(module, exports, __webpack_require__) { 1300 | 1301 | var version = __webpack_require__(13) 1302 | var isVNode = __webpack_require__(14) 1303 | var isWidget = __webpack_require__(15) 1304 | var isThunk = __webpack_require__(16) 1305 | var isVHook = __webpack_require__(17) 1306 | 1307 | module.exports = VirtualNode 1308 | 1309 | var noProperties = {} 1310 | var noChildren = [] 1311 | 1312 | function VirtualNode(tagName, properties, children, key, namespace) { 1313 | this.tagName = tagName 1314 | this.properties = properties || noProperties 1315 | this.children = children || noChildren 1316 | this.key = key != null ? String(key) : undefined 1317 | this.namespace = (typeof namespace === "string") ? namespace : null 1318 | 1319 | var count = (children && children.length) || 0 1320 | var descendants = 0 1321 | var hasWidgets = false 1322 | var hasThunks = false 1323 | var descendantHooks = false 1324 | var hooks 1325 | 1326 | for (var propName in properties) { 1327 | if (properties.hasOwnProperty(propName)) { 1328 | var property = properties[propName] 1329 | if (isVHook(property) && property.unhook) { 1330 | if (!hooks) { 1331 | hooks = {} 1332 | } 1333 | 1334 | hooks[propName] = property 1335 | } 1336 | } 1337 | } 1338 | 1339 | for (var i = 0; i < count; i++) { 1340 | var child = children[i] 1341 | if (isVNode(child)) { 1342 | descendants += child.count || 0 1343 | 1344 | if (!hasWidgets && child.hasWidgets) { 1345 | hasWidgets = true 1346 | } 1347 | 1348 | if (!hasThunks && child.hasThunks) { 1349 | hasThunks = true 1350 | } 1351 | 1352 | if (!descendantHooks && (child.hooks || child.descendantHooks)) { 1353 | descendantHooks = true 1354 | } 1355 | } else if (!hasWidgets && isWidget(child)) { 1356 | if (typeof child.destroy === "function") { 1357 | hasWidgets = true 1358 | } 1359 | } else if (!hasThunks && isThunk(child)) { 1360 | hasThunks = true; 1361 | } 1362 | } 1363 | 1364 | this.count = count + descendants 1365 | this.hasWidgets = hasWidgets 1366 | this.hasThunks = hasThunks 1367 | this.hooks = hooks 1368 | this.descendantHooks = descendantHooks 1369 | } 1370 | 1371 | VirtualNode.prototype.version = version 1372 | VirtualNode.prototype.type = "VirtualNode" 1373 | 1374 | 1375 | /***/ }, 1376 | /* 13 */ 1377 | /***/ function(module, exports) { 1378 | 1379 | module.exports = "2" 1380 | 1381 | 1382 | /***/ }, 1383 | /* 14 */ 1384 | /***/ function(module, exports, __webpack_require__) { 1385 | 1386 | var version = __webpack_require__(13) 1387 | 1388 | module.exports = isVirtualNode 1389 | 1390 | function isVirtualNode(x) { 1391 | return x && x.type === "VirtualNode" && x.version === version 1392 | } 1393 | 1394 | 1395 | /***/ }, 1396 | /* 15 */ 1397 | /***/ function(module, exports) { 1398 | 1399 | module.exports = isWidget 1400 | 1401 | function isWidget(w) { 1402 | return w && w.type === "Widget" 1403 | } 1404 | 1405 | 1406 | /***/ }, 1407 | /* 16 */ 1408 | /***/ function(module, exports) { 1409 | 1410 | module.exports = isThunk 1411 | 1412 | function isThunk(t) { 1413 | return t && t.type === "Thunk" 1414 | } 1415 | 1416 | 1417 | /***/ }, 1418 | /* 17 */ 1419 | /***/ function(module, exports) { 1420 | 1421 | module.exports = isHook 1422 | 1423 | function isHook(hook) { 1424 | return hook && 1425 | (typeof hook.hook === "function" && !hook.hasOwnProperty("hook") || 1426 | typeof hook.unhook === "function" && !hook.hasOwnProperty("unhook")) 1427 | } 1428 | 1429 | 1430 | /***/ }, 1431 | /* 18 */ 1432 | /***/ function(module, exports, __webpack_require__) { 1433 | 1434 | var version = __webpack_require__(13) 1435 | 1436 | module.exports = VirtualText 1437 | 1438 | function VirtualText(text) { 1439 | this.text = String(text) 1440 | } 1441 | 1442 | VirtualText.prototype.version = version 1443 | VirtualText.prototype.type = "VirtualText" 1444 | 1445 | 1446 | /***/ }, 1447 | /* 19 */ 1448 | /***/ function(module, exports, __webpack_require__) { 1449 | 1450 | var version = __webpack_require__(13) 1451 | 1452 | module.exports = isVirtualText 1453 | 1454 | function isVirtualText(x) { 1455 | return x && x.type === "VirtualText" && x.version === version 1456 | } 1457 | 1458 | 1459 | /***/ }, 1460 | /* 20 */ 1461 | /***/ function(module, exports, __webpack_require__) { 1462 | 1463 | 'use strict'; 1464 | 1465 | var split = __webpack_require__(21); 1466 | 1467 | var classIdSplit = /([\.#]?[a-zA-Z0-9\u007F-\uFFFF_:-]+)/; 1468 | var notClassId = /^\.|#/; 1469 | 1470 | module.exports = parseTag; 1471 | 1472 | function parseTag(tag, props) { 1473 | if (!tag) { 1474 | return 'DIV'; 1475 | } 1476 | 1477 | var noId = !(props.hasOwnProperty('id')); 1478 | 1479 | var tagParts = split(tag, classIdSplit); 1480 | var tagName = null; 1481 | 1482 | if (notClassId.test(tagParts[1])) { 1483 | tagName = 'DIV'; 1484 | } 1485 | 1486 | var classes, part, type, i; 1487 | 1488 | for (i = 0; i < tagParts.length; i++) { 1489 | part = tagParts[i]; 1490 | 1491 | if (!part) { 1492 | continue; 1493 | } 1494 | 1495 | type = part.charAt(0); 1496 | 1497 | if (!tagName) { 1498 | tagName = part; 1499 | } else if (type === '.') { 1500 | classes = classes || []; 1501 | classes.push(part.substring(1, part.length)); 1502 | } else if (type === '#' && noId) { 1503 | props.id = part.substring(1, part.length); 1504 | } 1505 | } 1506 | 1507 | if (classes) { 1508 | if (props.className) { 1509 | classes.push(props.className); 1510 | } 1511 | 1512 | props.className = classes.join(' '); 1513 | } 1514 | 1515 | return props.namespace ? tagName : tagName.toUpperCase(); 1516 | } 1517 | 1518 | 1519 | /***/ }, 1520 | /* 21 */ 1521 | /***/ function(module, exports) { 1522 | 1523 | /*! 1524 | * Cross-Browser Split 1.1.1 1525 | * Copyright 2007-2012 Steven Levithan 1526 | * Available under the MIT License 1527 | * ECMAScript compliant, uniform cross-browser split method 1528 | */ 1529 | 1530 | /** 1531 | * Splits a string into an array of strings using a regex or string separator. Matches of the 1532 | * separator are not included in the result array. However, if `separator` is a regex that contains 1533 | * capturing groups, backreferences are spliced into the result each time `separator` is matched. 1534 | * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably 1535 | * cross-browser. 1536 | * @param {String} str String to split. 1537 | * @param {RegExp|String} separator Regex or string to use for separating the string. 1538 | * @param {Number} [limit] Maximum number of items to include in the result array. 1539 | * @returns {Array} Array of substrings. 1540 | * @example 1541 | * 1542 | * // Basic use 1543 | * split('a b c d', ' '); 1544 | * // -> ['a', 'b', 'c', 'd'] 1545 | * 1546 | * // With limit 1547 | * split('a b c d', ' ', 2); 1548 | * // -> ['a', 'b'] 1549 | * 1550 | * // Backreferences in result array 1551 | * split('..word1 word2..', /([a-z]+)(\d+)/i); 1552 | * // -> ['..', 'word', '1', ' ', 'word', '2', '..'] 1553 | */ 1554 | module.exports = (function split(undef) { 1555 | 1556 | var nativeSplit = String.prototype.split, 1557 | compliantExecNpcg = /()??/.exec("")[1] === undef, 1558 | // NPCG: nonparticipating capturing group 1559 | self; 1560 | 1561 | self = function(str, separator, limit) { 1562 | // If `separator` is not a regex, use `nativeSplit` 1563 | if (Object.prototype.toString.call(separator) !== "[object RegExp]") { 1564 | return nativeSplit.call(str, separator, limit); 1565 | } 1566 | var output = [], 1567 | flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6 1568 | (separator.sticky ? "y" : ""), 1569 | // Firefox 3+ 1570 | lastLastIndex = 0, 1571 | // Make `global` and avoid `lastIndex` issues by working with a copy 1572 | separator = new RegExp(separator.source, flags + "g"), 1573 | separator2, match, lastIndex, lastLength; 1574 | str += ""; // Type-convert 1575 | if (!compliantExecNpcg) { 1576 | // Doesn't need flags gy, but they don't hurt 1577 | separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags); 1578 | } 1579 | /* Values for `limit`, per the spec: 1580 | * If undefined: 4294967295 // Math.pow(2, 32) - 1 1581 | * If 0, Infinity, or NaN: 0 1582 | * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; 1583 | * If negative number: 4294967296 - Math.floor(Math.abs(limit)) 1584 | * If other: Type-convert, then use the above rules 1585 | */ 1586 | limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1 1587 | limit >>> 0; // ToUint32(limit) 1588 | while (match = separator.exec(str)) { 1589 | // `separator.lastIndex` is not reliable cross-browser 1590 | lastIndex = match.index + match[0].length; 1591 | if (lastIndex > lastLastIndex) { 1592 | output.push(str.slice(lastLastIndex, match.index)); 1593 | // Fix browsers whose `exec` methods don't consistently return `undefined` for 1594 | // nonparticipating capturing groups 1595 | if (!compliantExecNpcg && match.length > 1) { 1596 | match[0].replace(separator2, function() { 1597 | for (var i = 1; i < arguments.length - 2; i++) { 1598 | if (arguments[i] === undef) { 1599 | match[i] = undef; 1600 | } 1601 | } 1602 | }); 1603 | } 1604 | if (match.length > 1 && match.index < str.length) { 1605 | Array.prototype.push.apply(output, match.slice(1)); 1606 | } 1607 | lastLength = match[0].length; 1608 | lastLastIndex = lastIndex; 1609 | if (output.length >= limit) { 1610 | break; 1611 | } 1612 | } 1613 | if (separator.lastIndex === match.index) { 1614 | separator.lastIndex++; // Avoid an infinite loop 1615 | } 1616 | } 1617 | if (lastLastIndex === str.length) { 1618 | if (lastLength || !separator.test("")) { 1619 | output.push(""); 1620 | } 1621 | } else { 1622 | output.push(str.slice(lastLastIndex)); 1623 | } 1624 | return output.length > limit ? output.slice(0, limit) : output; 1625 | }; 1626 | 1627 | return self; 1628 | })(); 1629 | 1630 | 1631 | /***/ }, 1632 | /* 22 */ 1633 | /***/ function(module, exports) { 1634 | 1635 | 'use strict'; 1636 | 1637 | module.exports = SoftSetHook; 1638 | 1639 | function SoftSetHook(value) { 1640 | if (!(this instanceof SoftSetHook)) { 1641 | return new SoftSetHook(value); 1642 | } 1643 | 1644 | this.value = value; 1645 | } 1646 | 1647 | SoftSetHook.prototype.hook = function (node, propertyName) { 1648 | if (node[propertyName] !== this.value) { 1649 | node[propertyName] = this.value; 1650 | } 1651 | }; 1652 | 1653 | 1654 | /***/ }, 1655 | /* 23 */ 1656 | /***/ function(module, exports, __webpack_require__) { 1657 | 1658 | 'use strict'; 1659 | 1660 | var EvStore = __webpack_require__(24); 1661 | 1662 | module.exports = EvHook; 1663 | 1664 | function EvHook(value) { 1665 | if (!(this instanceof EvHook)) { 1666 | return new EvHook(value); 1667 | } 1668 | 1669 | this.value = value; 1670 | } 1671 | 1672 | EvHook.prototype.hook = function (node, propertyName) { 1673 | var es = EvStore(node); 1674 | var propName = propertyName.substr(3); 1675 | 1676 | es[propName] = this.value; 1677 | }; 1678 | 1679 | EvHook.prototype.unhook = function(node, propertyName) { 1680 | var es = EvStore(node); 1681 | var propName = propertyName.substr(3); 1682 | 1683 | es[propName] = undefined; 1684 | }; 1685 | 1686 | 1687 | /***/ }, 1688 | /* 24 */ 1689 | /***/ function(module, exports, __webpack_require__) { 1690 | 1691 | 'use strict'; 1692 | 1693 | var OneVersionConstraint = __webpack_require__(25); 1694 | 1695 | var MY_VERSION = '7'; 1696 | OneVersionConstraint('ev-store', MY_VERSION); 1697 | 1698 | var hashKey = '__EV_STORE_KEY@' + MY_VERSION; 1699 | 1700 | module.exports = EvStore; 1701 | 1702 | function EvStore(elem) { 1703 | var hash = elem[hashKey]; 1704 | 1705 | if (!hash) { 1706 | hash = elem[hashKey] = {}; 1707 | } 1708 | 1709 | return hash; 1710 | } 1711 | 1712 | 1713 | /***/ }, 1714 | /* 25 */ 1715 | /***/ function(module, exports, __webpack_require__) { 1716 | 1717 | 'use strict'; 1718 | 1719 | var Individual = __webpack_require__(26); 1720 | 1721 | module.exports = OneVersion; 1722 | 1723 | function OneVersion(moduleName, version, defaultValue) { 1724 | var key = '__INDIVIDUAL_ONE_VERSION_' + moduleName; 1725 | var enforceKey = key + '_ENFORCE_SINGLETON'; 1726 | 1727 | var versionValue = Individual(enforceKey, version); 1728 | 1729 | if (versionValue !== version) { 1730 | throw new Error('Can only have one copy of ' + 1731 | moduleName + '.\n' + 1732 | 'You already have version ' + versionValue + 1733 | ' installed.\n' + 1734 | 'This means you cannot install version ' + version); 1735 | } 1736 | 1737 | return Individual(key, defaultValue); 1738 | } 1739 | 1740 | 1741 | /***/ }, 1742 | /* 26 */ 1743 | /***/ function(module, exports) { 1744 | 1745 | /* WEBPACK VAR INJECTION */(function(global) {'use strict'; 1746 | 1747 | /*global window, global*/ 1748 | 1749 | var root = typeof window !== 'undefined' ? 1750 | window : typeof global !== 'undefined' ? 1751 | global : {}; 1752 | 1753 | module.exports = Individual; 1754 | 1755 | function Individual(key, value) { 1756 | if (key in root) { 1757 | return root[key]; 1758 | } 1759 | 1760 | root[key] = value; 1761 | 1762 | return value; 1763 | } 1764 | 1765 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 1766 | 1767 | /***/ }, 1768 | /* 27 */ 1769 | /***/ function(module, exports, __webpack_require__) { 1770 | 1771 | const h = __webpack_require__(9) 1772 | 1773 | function render (Todos) { 1774 | function isEnter (e) { 1775 | return e.keyCode === 13 1776 | } 1777 | function onKey (e) { 1778 | console.log('pressed', e.target.value) 1779 | if (isEnter(e)) { 1780 | Todos.add(e.target.value) 1781 | e.target.value = '' 1782 | } 1783 | } 1784 | 1785 | return h('header', {className: 'header'}, [ 1786 | h('h1', {}, 'todos'), 1787 | h('input', { 1788 | className: 'new-todo', 1789 | placeholder: 'What needs to be done?', 1790 | autofocus: true, 1791 | onkeyup: onKey 1792 | }, []) 1793 | ]) 1794 | } 1795 | 1796 | module.exports = render 1797 | 1798 | 1799 | /***/ }, 1800 | /* 28 */ 1801 | /***/ function(module, exports, __webpack_require__) { 1802 | 1803 | const h = __webpack_require__(9) 1804 | const renderTodo = __webpack_require__(29) 1805 | 1806 | function render (Todos) { 1807 | return h('section', {className: 'main'}, [ 1808 | h('input', { 1809 | className: 'toggle-all', 1810 | type: 'checkbox', 1811 | onclick: function (e) { 1812 | console.log('nothing') 1813 | // Todos.mark(e.target.checked); 1814 | // renderApp(); 1815 | } 1816 | }), 1817 | h('label', {htmlFor: 'toggle-all'}, 'Mark all as complete'), 1818 | h('ul', {className: 'todo-list'}, 1819 | Todos.items.map(renderTodo.bind(null, Todos))) 1820 | ]) 1821 | } 1822 | 1823 | module.exports = render 1824 | 1825 | 1826 | /***/ }, 1827 | /* 29 */ 1828 | /***/ function(module, exports, __webpack_require__) { 1829 | 1830 | const h = __webpack_require__(9) 1831 | 1832 | function render (Todos, todo) { 1833 | return h('li', {className: todo.done ? 'completed' : '', key: todo.id}, [ 1834 | h('div', {className: 'view'}, [ 1835 | h('input', { 1836 | className: 'toggle', 1837 | type: 'checkbox', 1838 | checked: todo.done, 1839 | onchange: function (e) { 1840 | Todos.mark(todo.id, e.target.checked) 1841 | } 1842 | }), 1843 | h('label', todo.what), 1844 | h('button', { 1845 | className: 'destroy', 1846 | onclick: function (e) { 1847 | console.log('nothing') 1848 | Todos.remove(todo) 1849 | } 1850 | }) 1851 | ]) 1852 | ]) 1853 | } 1854 | 1855 | module.exports = render 1856 | 1857 | 1858 | /***/ }, 1859 | /* 30 */ 1860 | /***/ function(module, exports, __webpack_require__) { 1861 | 1862 | const h = __webpack_require__(9) 1863 | 1864 | function hashFragment () { 1865 | return typeof window !== 'undefined' && window.location.hash.split('/')[1] || '' 1866 | } 1867 | 1868 | function countRemaining (todos) { 1869 | return todos.length - todos.reduce(function (count, todo) { 1870 | return count + Number(todo.done) 1871 | }, 0) 1872 | } 1873 | 1874 | function hasCompleted (todos) { 1875 | return todos && todos.some(function (todo) { 1876 | return todo.done 1877 | }) 1878 | } 1879 | 1880 | function render (Todos) { 1881 | const remaining = countRemaining(Todos.items) 1882 | const route = hashFragment() 1883 | 1884 | return h('footer', {className: 'footer'}, [ 1885 | h('span', {className: 'todo-count'}, [ 1886 | h('strong', {}, String(remaining)), 1887 | ' items left' 1888 | ]), 1889 | h('ul', {className: 'filters'}, [ 1890 | h('li', [ 1891 | h('a', { 1892 | className: !route ? 'selected' : '', 1893 | href: '#/' 1894 | }, 'All') 1895 | ]), 1896 | h('li', [ 1897 | h('a', { 1898 | className: route === 'active' ? 'selected' : '', 1899 | href: '#/active' 1900 | }, 'Active') 1901 | ]), 1902 | h('li', [ 1903 | h('a', { 1904 | className: route === 'completed' ? 'selected' : '', 1905 | href: '#/completed' 1906 | }, 'Completed') 1907 | ]) 1908 | ]), 1909 | h('button', { 1910 | className: 'clear-completed', 1911 | style: { 1912 | display: hasCompleted(Todos.items) ? 'block' : 'none' 1913 | }, 1914 | onclick: function () { 1915 | // todos && todos.clearCompleted(); 1916 | // renderApp(); 1917 | } 1918 | }, 'Clear completed') 1919 | ]) 1920 | } 1921 | 1922 | module.exports = render 1923 | 1924 | 1925 | /***/ }, 1926 | /* 31 */ 1927 | /***/ function(module, exports, __webpack_require__) { 1928 | 1929 | var createElement = __webpack_require__(32) 1930 | 1931 | module.exports = createElement 1932 | 1933 | 1934 | /***/ }, 1935 | /* 32 */ 1936 | /***/ function(module, exports, __webpack_require__) { 1937 | 1938 | var document = __webpack_require__(33) 1939 | 1940 | var applyProperties = __webpack_require__(35) 1941 | 1942 | var isVNode = __webpack_require__(14) 1943 | var isVText = __webpack_require__(19) 1944 | var isWidget = __webpack_require__(15) 1945 | var handleThunk = __webpack_require__(37) 1946 | 1947 | module.exports = createElement 1948 | 1949 | function createElement(vnode, opts) { 1950 | var doc = opts ? opts.document || document : document 1951 | var warn = opts ? opts.warn : null 1952 | 1953 | vnode = handleThunk(vnode).a 1954 | 1955 | if (isWidget(vnode)) { 1956 | return vnode.init() 1957 | } else if (isVText(vnode)) { 1958 | return doc.createTextNode(vnode.text) 1959 | } else if (!isVNode(vnode)) { 1960 | if (warn) { 1961 | warn("Item is not a valid virtual dom node", vnode) 1962 | } 1963 | return null 1964 | } 1965 | 1966 | var node = (vnode.namespace === null) ? 1967 | doc.createElement(vnode.tagName) : 1968 | doc.createElementNS(vnode.namespace, vnode.tagName) 1969 | 1970 | var props = vnode.properties 1971 | applyProperties(node, props) 1972 | 1973 | var children = vnode.children 1974 | 1975 | for (var i = 0; i < children.length; i++) { 1976 | var childNode = createElement(children[i], opts) 1977 | if (childNode) { 1978 | node.appendChild(childNode) 1979 | } 1980 | } 1981 | 1982 | return node 1983 | } 1984 | 1985 | 1986 | /***/ }, 1987 | /* 33 */ 1988 | /***/ function(module, exports, __webpack_require__) { 1989 | 1990 | /* WEBPACK VAR INJECTION */(function(global) {var topLevel = typeof global !== 'undefined' ? global : 1991 | typeof window !== 'undefined' ? window : {} 1992 | var minDoc = __webpack_require__(34); 1993 | 1994 | if (typeof document !== 'undefined') { 1995 | module.exports = document; 1996 | } else { 1997 | var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; 1998 | 1999 | if (!doccy) { 2000 | doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; 2001 | } 2002 | 2003 | module.exports = doccy; 2004 | } 2005 | 2006 | /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) 2007 | 2008 | /***/ }, 2009 | /* 34 */ 2010 | /***/ function(module, exports) { 2011 | 2012 | /* (ignored) */ 2013 | 2014 | /***/ }, 2015 | /* 35 */ 2016 | /***/ function(module, exports, __webpack_require__) { 2017 | 2018 | var isObject = __webpack_require__(36) 2019 | var isHook = __webpack_require__(17) 2020 | 2021 | module.exports = applyProperties 2022 | 2023 | function applyProperties(node, props, previous) { 2024 | for (var propName in props) { 2025 | var propValue = props[propName] 2026 | 2027 | if (propValue === undefined) { 2028 | removeProperty(node, propName, propValue, previous); 2029 | } else if (isHook(propValue)) { 2030 | removeProperty(node, propName, propValue, previous) 2031 | if (propValue.hook) { 2032 | propValue.hook(node, 2033 | propName, 2034 | previous ? previous[propName] : undefined) 2035 | } 2036 | } else { 2037 | if (isObject(propValue)) { 2038 | patchObject(node, props, previous, propName, propValue); 2039 | } else { 2040 | node[propName] = propValue 2041 | } 2042 | } 2043 | } 2044 | } 2045 | 2046 | function removeProperty(node, propName, propValue, previous) { 2047 | if (previous) { 2048 | var previousValue = previous[propName] 2049 | 2050 | if (!isHook(previousValue)) { 2051 | if (propName === "attributes") { 2052 | for (var attrName in previousValue) { 2053 | node.removeAttribute(attrName) 2054 | } 2055 | } else if (propName === "style") { 2056 | for (var i in previousValue) { 2057 | node.style[i] = "" 2058 | } 2059 | } else if (typeof previousValue === "string") { 2060 | node[propName] = "" 2061 | } else { 2062 | node[propName] = null 2063 | } 2064 | } else if (previousValue.unhook) { 2065 | previousValue.unhook(node, propName, propValue) 2066 | } 2067 | } 2068 | } 2069 | 2070 | function patchObject(node, props, previous, propName, propValue) { 2071 | var previousValue = previous ? previous[propName] : undefined 2072 | 2073 | // Set attributes 2074 | if (propName === "attributes") { 2075 | for (var attrName in propValue) { 2076 | var attrValue = propValue[attrName] 2077 | 2078 | if (attrValue === undefined) { 2079 | node.removeAttribute(attrName) 2080 | } else { 2081 | node.setAttribute(attrName, attrValue) 2082 | } 2083 | } 2084 | 2085 | return 2086 | } 2087 | 2088 | if(previousValue && isObject(previousValue) && 2089 | getPrototype(previousValue) !== getPrototype(propValue)) { 2090 | node[propName] = propValue 2091 | return 2092 | } 2093 | 2094 | if (!isObject(node[propName])) { 2095 | node[propName] = {} 2096 | } 2097 | 2098 | var replacer = propName === "style" ? "" : undefined 2099 | 2100 | for (var k in propValue) { 2101 | var value = propValue[k] 2102 | node[propName][k] = (value === undefined) ? replacer : value 2103 | } 2104 | } 2105 | 2106 | function getPrototype(value) { 2107 | if (Object.getPrototypeOf) { 2108 | return Object.getPrototypeOf(value) 2109 | } else if (value.__proto__) { 2110 | return value.__proto__ 2111 | } else if (value.constructor) { 2112 | return value.constructor.prototype 2113 | } 2114 | } 2115 | 2116 | 2117 | /***/ }, 2118 | /* 36 */ 2119 | /***/ function(module, exports) { 2120 | 2121 | "use strict"; 2122 | 2123 | module.exports = function isObject(x) { 2124 | return typeof x === "object" && x !== null; 2125 | }; 2126 | 2127 | 2128 | /***/ }, 2129 | /* 37 */ 2130 | /***/ function(module, exports, __webpack_require__) { 2131 | 2132 | var isVNode = __webpack_require__(14) 2133 | var isVText = __webpack_require__(19) 2134 | var isWidget = __webpack_require__(15) 2135 | var isThunk = __webpack_require__(16) 2136 | 2137 | module.exports = handleThunk 2138 | 2139 | function handleThunk(a, b) { 2140 | var renderedA = a 2141 | var renderedB = b 2142 | 2143 | if (isThunk(b)) { 2144 | renderedB = renderThunk(b, a) 2145 | } 2146 | 2147 | if (isThunk(a)) { 2148 | renderedA = renderThunk(a, null) 2149 | } 2150 | 2151 | return { 2152 | a: renderedA, 2153 | b: renderedB 2154 | } 2155 | } 2156 | 2157 | function renderThunk(thunk, previous) { 2158 | var renderedThunk = thunk.vnode 2159 | 2160 | if (!renderedThunk) { 2161 | renderedThunk = thunk.vnode = thunk.render(previous) 2162 | } 2163 | 2164 | if (!(isVNode(renderedThunk) || 2165 | isVText(renderedThunk) || 2166 | isWidget(renderedThunk))) { 2167 | throw new Error("thunk did not return a valid node"); 2168 | } 2169 | 2170 | return renderedThunk 2171 | } 2172 | 2173 | 2174 | /***/ } 2175 | /******/ ]); --------------------------------------------------------------------------------