[
  {
    "path": ".editorconfig",
    "content": "# editorconfig.org\nroot = true\n\n[*]\nindent_style = space\nindent_size = 4\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".gitignore",
    "content": ".idea/\n.DS_Store\n.monitor\n.*.swp\n.nodemonignore\nreleases\n*.log\n*.err\nfleet.json\npublic/browserify\nbin/*.json\n.bin\nbuild\ncompile\n.lock-wscript\ncoverage\nnode_modules\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    \"asi\": true,\n    \"bitwise\": false,\n    \"camelcase\": true,\n    \"curly\": false,\n    \"eqeqeq\": true,\n    \"eqnull\": true,\n    \"forin\": false,\n    \"immed\": true,\n    \"indent\": 4,\n    \"latedef\": \"nofunc\",\n    \"newcap\": false,\n    \"noarg\": true,\n    \"nonew\": true,\n    \"plusplus\": false,\n    \"proto\": true,\n    \"quotmark\": false,\n    \"regexp\": false,\n    \"undef\": true,\n    \"unused\": true,\n    \"strict\": false,\n    \"trailing\": true,\n    \"noempty\": true,\n    \"maxdepth\": 5,\n    \"maxparams\": 5,\n    \"globals\": {\n        \"console\": true,\n        \"Buffer\": true,\n        \"setTimeout\": true,\n        \"clearTimeout\": true,\n        \"setInterval\": true,\n        \"clearInterval\": true,\n        \"require\": false,\n        \"module\": false,\n        \"exports\": true,\n        \"global\": false,\n        \"process\": true,\n        \"__dirname\": false,\n        \"__filename\": false\n    }\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n- '0.10'\n- '0.12'\nbefore_install:\n- npm install npm -g\nbefore_script:\n- npm install\n- npm install istanbul coveralls\nscript: npm run travis-test\nenv:\n  global:\n  - secure: JTqjyeAoQmKLVH9SzSeIWy02DcY9WAkfIU/w8YotxIsELWbPyZ6seYBEhHiB+JYJ9UeuUgyYhZ144SPm6K8o5w+merMD7zMglr95a/8CJnjMBdPK2/0Rjckz9OcANao5k+Qm+QBBu3keo6dRtKX25g6WrKwOYu8OLz5cradzhLs=\n  - secure: OBCtZZfM5LZyT+fT84Kb7N0PP1JdTQQ3SymZD5Ac+JYK30gCG6UO/o713QjlI5yVG7qwdFlPQOYF2VVf7yw6dUvf6pKj51427b9nOir8Hb9XjWlpo/770dKxlvrNxtQ3kkygAJTU8Fe7Jbk30zJef/Be17C07viiCZs4sHsiZC8=\n"
  },
  {
    "path": ".zuul.yml",
    "content": "ui: tape\nconcurrency: 1\nbrowsers:\n  - name: chrome\n    version: [26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, latest]\n  - name: ie\n    version: 6..latest\n  - name: firefox\n    version: 3..latest\n  - name: iphone\n    version: 4.3..latest\n  - name: ipad\n    version: 4.3..latest\n  - name: android\n    version: 4.0..latest\n  - name: opera\n    version: 11..latest\n  - name: safari\n    version: 5..latest\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Release Notes\n\n## v2.0.0\n\n  Provides fundamental fixes and tests for reordering of keyed nodes.\n\n  Everyone is encouraged to upgrade to v2. The main caveat of this upgrade\n  is that it changes the patch format to encode all of the move data,\n  instead of previously providing the mapping and expecting patch to work\n  out which moves are required. While this might limit options for\n  reordering, on the grounds of performance and debugging it made more\n  sense.\n\n  This is considered a breaking change for that reason. However, for those\n  of you who only consume `create`, `diff`, `patch` and `h`, this will\n  not affect your usage, and upgrading is recommended due to the bugs this\n  new version fixes.\n\n## v1.3.0\n\n  - Add optimization to AttributHook to prevent resetting attributes where\n    new hook instances are used but their values remain the same.\n\n  - Extend the interface of unhook to take the next value from diff.\n\n  - Fix bug where hook is called on unhook-only hooks.\n\n  - Code refactor: diffProps broken out into it's own file\n\n## v1.2.0\n\n  - Correctly sets SVG attributes that are namespaced using a (fixed)\n    attribute hook.\n\n  - Add CSS animation notes from github issue (css-animations.md)\n\n  - A hook with an `unhook` method and no `hook` method is now considered a\n    valid hook.\n\n  - Fixes issue where unhook was not called when a hook property is replaced\n    with a new value\n\n  - Fixes dist script update\n\n  - Update README to note that an instance of `dom-delegator` is required to\n    use the `ev-*` properties.\n\n## v1.1.0 - Element reordering\n\n  - Updates the way in which elements are reordered to increase performance\n    in common use cases.\n\n  - Adds additional SVG display attributes.\n\n# v1.0.0 - Sensible versioning begins\n\n# v0.0.24 - Fix destroy ordering\n\n  - Fixes a bug where widgets cannot be replaced by vnodes due to a bug in the\n    order of destroy patches.\n\n# v0.0.23 - Release notes begin\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2014 Matt-Esch.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# virtual-dom\n\nA JavaScript [DOM model](#dom-model) supporting [element creation](#element-creation), [diff computation](#diff-computation) and [patch operations](#patch-operations) for efficient re-rendering\n\n[![build status][1]][2]\n[![NPM version][3]][4]\n[![Coverage Status][5]][6]\n[![Davis Dependency status][7]][8]\n[![experimental](http://hughsk.github.io/stability-badges/dist/experimental.svg)](http://github.com/hughsk/stability-badges)\n[![Join the chat at https://gitter.im/Matt-Esch/virtual-dom](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Matt-Esch/virtual-dom?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/mattesch.svg)](https://saucelabs.com/u/mattesch)\n\n## Motivation\n\nManual DOM manipulation is messy and keeping track of the previous DOM state is hard. A solution to this problem is to write your code as if you were recreating the entire DOM whenever state changes. Of course, if you actually recreated the entire DOM every time your application state changed, your app would be very slow and your input fields would lose focus.\n\n`virtual-dom` is a collection of modules designed to provide a declarative way of representing the DOM for your app. So instead of updating the DOM when your application state changes, you simply create a virtual tree or `VTree`, which looks like the DOM state that you want. `virtual-dom` will then figure out how to make the DOM look like this efficiently without recreating all of the DOM nodes.\n\n`virtual-dom` allows you to update a view whenever state changes by creating a full `VTree` of the view and then patching the DOM efficiently to look exactly as you described it. This results in keeping manual DOM manipulation and previous state tracking out of your application code, promoting clean and maintainable rendering logic for web applications.\n\n## Example\n\n```javascript\nvar h = require('virtual-dom/h');\nvar diff = require('virtual-dom/diff');\nvar patch = require('virtual-dom/patch');\nvar createElement = require('virtual-dom/create-element');\n\n// 1: Create a function that declares what the DOM should look like\nfunction render(count)  {\n    return h('div', {\n        style: {\n            textAlign: 'center',\n            lineHeight: (100 + count) + 'px',\n            border: '1px solid red',\n            width: (100 + count) + 'px',\n            height: (100 + count) + 'px'\n        }\n    }, [String(count)]);\n}\n\n// 2: Initialise the document\nvar count = 0;      // We need some app data. Here we just store a count.\n\nvar tree = render(count);               // We need an initial tree\nvar rootNode = createElement(tree);     // Create an initial root DOM node ...\ndocument.body.appendChild(rootNode);    // ... and it should be in the document\n\n// 3: Wire up the update logic\nsetInterval(function () {\n      count++;\n\n      var newTree = render(count);\n      var patches = diff(tree, newTree);\n      rootNode = patch(rootNode, patches);\n      tree = newTree;\n}, 1000);\n```\n[View on RequireBin](http://requirebin.com/?gist=5492847b9a9025e64bab)\n\n## Documentation\n\nYou can find the documentation for the seperate components\n  in their READMEs\n\n - For `create-element.js` see the [vdom README](vdom/README.md)\n - For `diff.js` see the [vtree README](vtree/README.md)\n - For `h.js` see the [virtual-hyperscript README](virtual-hyperscript/README.md)\n - For `patch.js` see the [vdom README](vdom/README.md)\n\nFor information about the type signatures of these modules feel\n  free to read the [javascript signature definition](docs.jsig)\n\n## DOM model\n\n`virtual-dom` exposes a set of objects designed for representing DOM nodes. A \"Document Object Model Model\" might seem like a strange term, but it is exactly that. It's a native JavaScript tree structure that represents a native DOM node tree. We call this a **VTree**\n\nWe can create a VTree using the objects directly in a verbose manner, or we can use the more terse virtual-hyperscript.\n\n### Example - creating a VTree using the objects directly\n\n```javascript\nvar VNode = require('virtual-dom/vnode/vnode');\nvar VText = require('virtual-dom/vnode/vtext');\n\nfunction render(data) {\n    return new VNode('div', {\n        className: \"greeting\"\n    }, [\n        new VText(\"Hello \" + String(data.name))\n    ]);\n}\n\nmodule.exports = render;\n```\n\n### Example - creating a VTree using virtual-hyperscript\n\n```javascript\nvar h = require('virtual-dom/h');\n\nfunction render(data) {\n    return h('.greeting', ['Hello ' + data.name]);\n}\n\nmodule.exports = render;\n```\n\nThe DOM model is designed to be efficient to create and read from. The reason why we don't just create a real DOM tree is that creating DOM nodes and reading the node properties is an expensive operation which is what we are trying to avoid. Reading some DOM node properties even causes side effects, so recreating the entire DOM structure with real DOM nodes simply isn't suitable for high performance rendering and it is not easy to reason about either.\n\nA `VTree` is designed to be equivalent to an immutable data structure. While it's not actually immutable, you can reuse the nodes in multiple places and the functions we have exposed that take VTrees as arguments never mutate the trees. We could freeze the objects in the model but don't for efficiency. (The benefits of an immutable-equivalent data structure will be documented in vtree or blog post at some point)\n\n\n\n## Element creation\n\n```haskell\ncreateElement(tree:VTree) -> DOMNode\n```\n\nGiven that we have created a `VTree`, we need some way to translate this into a real DOM tree of some sort. This is provided by `create-element.js`. When rendering for the first time we would pass a complete `VTree` to create-element function to create the equivalent DOM node.\n\n## Diff computation\n\n```haskell\ndiff(previous:VTree, current:VTree) -> PatchObject\n```\n\nThe primary motivation behind virtual-dom is to allow us to write code independent of previous state. So when our application state changes we will generate a new `VTree`. The `diff` function creates a set of DOM patches that, based on the difference between the previous `VTree` and the current `VTree`, will update the previous DOM tree to match the new `VTree`.\n\n## Patch operations\n\n```haskell\npatch(rootNode:DOMNode, patches:PatchObject) -> DOMNode newRootNode\n```\n\nOnce we have computed the set of patches required to apply to the DOM, we need a function that can apply those patches. This is provided by the `patch` function. Given a DOM root node and a set of DOM patches, the `patch` function will update the DOM. After applying the patches to the DOM, the DOM should look like the new `VTree`.\n\n\n## Original motivation\n\nvirtual-dom is heavily inspired by the inner workings of React by facebook. This project originated as a gist of ideas, which [we have linked to provide some background context](https://gist.github.com/Raynos/8414846).\n\n## Tools\n\n* [html2hscript](https://github.com/twilson63/html2hscript) - Parse HTML into hyperscript\n* [html2hscript.herokuapp.com](http://html2hscript.herokuapp.com/) - Online Tool that converts html snippets to hyperscript\n* [html2hyperscript](https://github.com/unframework/html2hyperscript) - Original commandline utility to convert legacy HTML markup into hyperscript\n\n\n[1]: https://secure.travis-ci.org/Matt-Esch/virtual-dom.svg\n[2]: https://travis-ci.org/Matt-Esch/virtual-dom\n[3]: https://badge.fury.io/js/virtual-dom.svg\n[4]: https://badge.fury.io/js/virtual-dom\n[5]: http://img.shields.io/coveralls/Matt-Esch/virtual-dom.svg\n[6]: https://coveralls.io/r/Matt-Esch/virtual-dom\n[7]: https://david-dm.org/Matt-Esch/virtual-dom.svg\n[8]: https://david-dm.org/Matt-Esch/virtual-dom\n"
  },
  {
    "path": "create-element.js",
    "content": "var createElement = require(\"./vdom/create-element.js\")\n\nmodule.exports = createElement\n"
  },
  {
    "path": "diff.js",
    "content": "var diff = require(\"./vtree/diff.js\")\n\nmodule.exports = diff\n"
  },
  {
    "path": "dist/virtual-dom.js",
    "content": "!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.virtualDom=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\nvar createElement = require(\"./vdom/create-element.js\")\n\nmodule.exports = createElement\n\n},{\"./vdom/create-element.js\":15}],2:[function(require,module,exports){\nvar diff = require(\"./vtree/diff.js\")\n\nmodule.exports = diff\n\n},{\"./vtree/diff.js\":35}],3:[function(require,module,exports){\nvar h = require(\"./virtual-hyperscript/index.js\")\n\nmodule.exports = h\n\n},{\"./virtual-hyperscript/index.js\":22}],4:[function(require,module,exports){\nvar diff = require(\"./diff.js\")\r\nvar patch = require(\"./patch.js\")\r\nvar h = require(\"./h.js\")\r\nvar create = require(\"./create-element.js\")\r\nvar VNode = require('./vnode/vnode.js')\r\nvar VText = require('./vnode/vtext.js')\r\n\r\nmodule.exports = {\r\n    diff: diff,\r\n    patch: patch,\r\n    h: h,\r\n    create: create,\r\n    VNode: VNode,\r\n    VText: VText\r\n}\r\n\n},{\"./create-element.js\":1,\"./diff.js\":2,\"./h.js\":3,\"./patch.js\":13,\"./vnode/vnode.js\":31,\"./vnode/vtext.js\":33}],5:[function(require,module,exports){\n/*!\n * Cross-Browser Split 1.1.1\n * Copyright 2007-2012 Steven Levithan <stevenlevithan.com>\n * Available under the MIT License\n * ECMAScript compliant, uniform cross-browser split method\n */\n\n/**\n * Splits a string into an array of strings using a regex or string separator. Matches of the\n * separator are not included in the result array. However, if `separator` is a regex that contains\n * capturing groups, backreferences are spliced into the result each time `separator` is matched.\n * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably\n * cross-browser.\n * @param {String} str String to split.\n * @param {RegExp|String} separator Regex or string to use for separating the string.\n * @param {Number} [limit] Maximum number of items to include in the result array.\n * @returns {Array} Array of substrings.\n * @example\n *\n * // Basic use\n * split('a b c d', ' ');\n * // -> ['a', 'b', 'c', 'd']\n *\n * // With limit\n * split('a b c d', ' ', 2);\n * // -> ['a', 'b']\n *\n * // Backreferences in result array\n * split('..word1 word2..', /([a-z]+)(\\d+)/i);\n * // -> ['..', 'word', '1', ' ', 'word', '2', '..']\n */\nmodule.exports = (function split(undef) {\n\n  var nativeSplit = String.prototype.split,\n    compliantExecNpcg = /()??/.exec(\"\")[1] === undef,\n    // NPCG: nonparticipating capturing group\n    self;\n\n  self = function(str, separator, limit) {\n    // If `separator` is not a regex, use `nativeSplit`\n    if (Object.prototype.toString.call(separator) !== \"[object RegExp]\") {\n      return nativeSplit.call(str, separator, limit);\n    }\n    var output = [],\n      flags = (separator.ignoreCase ? \"i\" : \"\") + (separator.multiline ? \"m\" : \"\") + (separator.extended ? \"x\" : \"\") + // Proposed for ES6\n      (separator.sticky ? \"y\" : \"\"),\n      // Firefox 3+\n      lastLastIndex = 0,\n      // Make `global` and avoid `lastIndex` issues by working with a copy\n      separator = new RegExp(separator.source, flags + \"g\"),\n      separator2, match, lastIndex, lastLength;\n    str += \"\"; // Type-convert\n    if (!compliantExecNpcg) {\n      // Doesn't need flags gy, but they don't hurt\n      separator2 = new RegExp(\"^\" + separator.source + \"$(?!\\\\s)\", flags);\n    }\n    /* Values for `limit`, per the spec:\n     * If undefined: 4294967295 // Math.pow(2, 32) - 1\n     * If 0, Infinity, or NaN: 0\n     * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;\n     * If negative number: 4294967296 - Math.floor(Math.abs(limit))\n     * If other: Type-convert, then use the above rules\n     */\n    limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1\n    limit >>> 0; // ToUint32(limit)\n    while (match = separator.exec(str)) {\n      // `separator.lastIndex` is not reliable cross-browser\n      lastIndex = match.index + match[0].length;\n      if (lastIndex > lastLastIndex) {\n        output.push(str.slice(lastLastIndex, match.index));\n        // Fix browsers whose `exec` methods don't consistently return `undefined` for\n        // nonparticipating capturing groups\n        if (!compliantExecNpcg && match.length > 1) {\n          match[0].replace(separator2, function() {\n            for (var i = 1; i < arguments.length - 2; i++) {\n              if (arguments[i] === undef) {\n                match[i] = undef;\n              }\n            }\n          });\n        }\n        if (match.length > 1 && match.index < str.length) {\n          Array.prototype.push.apply(output, match.slice(1));\n        }\n        lastLength = match[0].length;\n        lastLastIndex = lastIndex;\n        if (output.length >= limit) {\n          break;\n        }\n      }\n      if (separator.lastIndex === match.index) {\n        separator.lastIndex++; // Avoid an infinite loop\n      }\n    }\n    if (lastLastIndex === str.length) {\n      if (lastLength || !separator.test(\"\")) {\n        output.push(\"\");\n      }\n    } else {\n      output.push(str.slice(lastLastIndex));\n    }\n    return output.length > limit ? output.slice(0, limit) : output;\n  };\n\n  return self;\n})();\n\n},{}],6:[function(require,module,exports){\n\n},{}],7:[function(require,module,exports){\n'use strict';\n\nvar OneVersionConstraint = require('individual/one-version');\n\nvar MY_VERSION = '7';\nOneVersionConstraint('ev-store', MY_VERSION);\n\nvar hashKey = '__EV_STORE_KEY@' + MY_VERSION;\n\nmodule.exports = EvStore;\n\nfunction EvStore(elem) {\n    var hash = elem[hashKey];\n\n    if (!hash) {\n        hash = elem[hashKey] = {};\n    }\n\n    return hash;\n}\n\n},{\"individual/one-version\":9}],8:[function(require,module,exports){\n(function (global){\n'use strict';\n\n/*global window, global*/\n\nvar root = typeof window !== 'undefined' ?\n    window : typeof global !== 'undefined' ?\n    global : {};\n\nmodule.exports = Individual;\n\nfunction Individual(key, value) {\n    if (key in root) {\n        return root[key];\n    }\n\n    root[key] = value;\n\n    return value;\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],9:[function(require,module,exports){\n'use strict';\n\nvar Individual = require('./index.js');\n\nmodule.exports = OneVersion;\n\nfunction OneVersion(moduleName, version, defaultValue) {\n    var key = '__INDIVIDUAL_ONE_VERSION_' + moduleName;\n    var enforceKey = key + '_ENFORCE_SINGLETON';\n\n    var versionValue = Individual(enforceKey, version);\n\n    if (versionValue !== version) {\n        throw new Error('Can only have one copy of ' +\n            moduleName + '.\\n' +\n            'You already have version ' + versionValue +\n            ' installed.\\n' +\n            'This means you cannot install version ' + version);\n    }\n\n    return Individual(key, defaultValue);\n}\n\n},{\"./index.js\":8}],10:[function(require,module,exports){\n(function (global){\nvar topLevel = typeof global !== 'undefined' ? global :\n    typeof window !== 'undefined' ? window : {}\nvar minDoc = require('min-document');\n\nif (typeof document !== 'undefined') {\n    module.exports = document;\n} else {\n    var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];\n\n    if (!doccy) {\n        doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;\n    }\n\n    module.exports = doccy;\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"min-document\":6}],11:[function(require,module,exports){\n\"use strict\";\n\nmodule.exports = function isObject(x) {\n\treturn typeof x === \"object\" && x !== null;\n};\n\n},{}],12:[function(require,module,exports){\nvar nativeIsArray = Array.isArray\nvar toString = Object.prototype.toString\n\nmodule.exports = nativeIsArray || isArray\n\nfunction isArray(obj) {\n    return toString.call(obj) === \"[object Array]\"\n}\n\n},{}],13:[function(require,module,exports){\nvar patch = require(\"./vdom/patch.js\")\n\nmodule.exports = patch\n\n},{\"./vdom/patch.js\":18}],14:[function(require,module,exports){\nvar isObject = require(\"is-object\")\nvar isHook = require(\"../vnode/is-vhook.js\")\n\nmodule.exports = applyProperties\n\nfunction applyProperties(node, props, previous) {\n    for (var propName in props) {\n        var propValue = props[propName]\n\n        if (propValue === undefined) {\n            removeProperty(node, propName, propValue, previous);\n        } else if (isHook(propValue)) {\n            removeProperty(node, propName, propValue, previous)\n            if (propValue.hook) {\n                propValue.hook(node,\n                    propName,\n                    previous ? previous[propName] : undefined)\n            }\n        } else {\n            if (isObject(propValue)) {\n                patchObject(node, props, previous, propName, propValue);\n            } else {\n                node[propName] = propValue\n            }\n        }\n    }\n}\n\nfunction removeProperty(node, propName, propValue, previous) {\n    if (previous) {\n        var previousValue = previous[propName]\n\n        if (!isHook(previousValue)) {\n            if (propName === \"attributes\") {\n                for (var attrName in previousValue) {\n                    node.removeAttribute(attrName)\n                }\n            } else if (propName === \"style\") {\n                for (var i in previousValue) {\n                    node.style[i] = \"\"\n                }\n            } else if (typeof previousValue === \"string\") {\n                node[propName] = \"\"\n            } else {\n                node[propName] = null\n            }\n        } else if (previousValue.unhook) {\n            previousValue.unhook(node, propName, propValue)\n        }\n    }\n}\n\nfunction patchObject(node, props, previous, propName, propValue) {\n    var previousValue = previous ? previous[propName] : undefined\n\n    // Set attributes\n    if (propName === \"attributes\") {\n        for (var attrName in propValue) {\n            var attrValue = propValue[attrName]\n\n            if (attrValue === undefined) {\n                node.removeAttribute(attrName)\n            } else {\n                node.setAttribute(attrName, attrValue)\n            }\n        }\n\n        return\n    }\n\n    if(previousValue && isObject(previousValue) &&\n        getPrototype(previousValue) !== getPrototype(propValue)) {\n        node[propName] = propValue\n        return\n    }\n\n    if (!isObject(node[propName])) {\n        node[propName] = {}\n    }\n\n    var replacer = propName === \"style\" ? \"\" : undefined\n\n    for (var k in propValue) {\n        var value = propValue[k]\n        node[propName][k] = (value === undefined) ? replacer : value\n    }\n}\n\nfunction getPrototype(value) {\n    if (Object.getPrototypeOf) {\n        return Object.getPrototypeOf(value)\n    } else if (value.__proto__) {\n        return value.__proto__\n    } else if (value.constructor) {\n        return value.constructor.prototype\n    }\n}\n\n},{\"../vnode/is-vhook.js\":26,\"is-object\":11}],15:[function(require,module,exports){\nvar document = require(\"global/document\")\n\nvar applyProperties = require(\"./apply-properties\")\n\nvar isVNode = require(\"../vnode/is-vnode.js\")\nvar isVText = require(\"../vnode/is-vtext.js\")\nvar isWidget = require(\"../vnode/is-widget.js\")\nvar handleThunk = require(\"../vnode/handle-thunk.js\")\n\nmodule.exports = createElement\n\nfunction createElement(vnode, opts) {\n    var doc = opts ? opts.document || document : document\n    var warn = opts ? opts.warn : null\n\n    vnode = handleThunk(vnode).a\n\n    if (isWidget(vnode)) {\n        return vnode.init()\n    } else if (isVText(vnode)) {\n        return doc.createTextNode(vnode.text)\n    } else if (!isVNode(vnode)) {\n        if (warn) {\n            warn(\"Item is not a valid virtual dom node\", vnode)\n        }\n        return null\n    }\n\n    var node = (vnode.namespace === null) ?\n        doc.createElement(vnode.tagName) :\n        doc.createElementNS(vnode.namespace, vnode.tagName)\n\n    var props = vnode.properties\n    applyProperties(node, props)\n\n    var children = vnode.children\n\n    for (var i = 0; i < children.length; i++) {\n        var childNode = createElement(children[i], opts)\n        if (childNode) {\n            node.appendChild(childNode)\n        }\n    }\n\n    return node\n}\n\n},{\"../vnode/handle-thunk.js\":24,\"../vnode/is-vnode.js\":27,\"../vnode/is-vtext.js\":28,\"../vnode/is-widget.js\":29,\"./apply-properties\":14,\"global/document\":10}],16:[function(require,module,exports){\n// Maps a virtual DOM tree onto a real DOM tree in an efficient manner.\n// We don't want to read all of the DOM nodes in the tree so we use\n// the in-order tree indexing to eliminate recursion down certain branches.\n// We only recurse into a DOM node if we know that it contains a child of\n// interest.\n\nvar noChild = {}\n\nmodule.exports = domIndex\n\nfunction domIndex(rootNode, tree, indices, nodes) {\n    if (!indices || indices.length === 0) {\n        return {}\n    } else {\n        indices.sort(ascending)\n        return recurse(rootNode, tree, indices, nodes, 0)\n    }\n}\n\nfunction recurse(rootNode, tree, indices, nodes, rootIndex) {\n    nodes = nodes || {}\n\n\n    if (rootNode) {\n        if (indexInRange(indices, rootIndex, rootIndex)) {\n            nodes[rootIndex] = rootNode\n        }\n\n        var vChildren = tree.children\n\n        if (vChildren) {\n\n            var childNodes = rootNode.childNodes\n\n            for (var i = 0; i < tree.children.length; i++) {\n                rootIndex += 1\n\n                var vChild = vChildren[i] || noChild\n                var nextIndex = rootIndex + (vChild.count || 0)\n\n                // skip recursion down the tree if there are no nodes down here\n                if (indexInRange(indices, rootIndex, nextIndex)) {\n                    recurse(childNodes[i], vChild, indices, nodes, rootIndex)\n                }\n\n                rootIndex = nextIndex\n            }\n        }\n    }\n\n    return nodes\n}\n\n// Binary search for an index in the interval [left, right]\nfunction indexInRange(indices, left, right) {\n    if (indices.length === 0) {\n        return false\n    }\n\n    var minIndex = 0\n    var maxIndex = indices.length - 1\n    var currentIndex\n    var currentItem\n\n    while (minIndex <= maxIndex) {\n        currentIndex = ((maxIndex + minIndex) / 2) >> 0\n        currentItem = indices[currentIndex]\n\n        if (minIndex === maxIndex) {\n            return currentItem >= left && currentItem <= right\n        } else if (currentItem < left) {\n            minIndex = currentIndex + 1\n        } else  if (currentItem > right) {\n            maxIndex = currentIndex - 1\n        } else {\n            return true\n        }\n    }\n\n    return false;\n}\n\nfunction ascending(a, b) {\n    return a > b ? 1 : -1\n}\n\n},{}],17:[function(require,module,exports){\nvar applyProperties = require(\"./apply-properties\")\n\nvar isWidget = require(\"../vnode/is-widget.js\")\nvar VPatch = require(\"../vnode/vpatch.js\")\n\nvar updateWidget = require(\"./update-widget\")\n\nmodule.exports = applyPatch\n\nfunction applyPatch(vpatch, domNode, renderOptions) {\n    var type = vpatch.type\n    var vNode = vpatch.vNode\n    var patch = vpatch.patch\n\n    switch (type) {\n        case VPatch.REMOVE:\n            return removeNode(domNode, vNode)\n        case VPatch.INSERT:\n            return insertNode(domNode, patch, renderOptions)\n        case VPatch.VTEXT:\n            return stringPatch(domNode, vNode, patch, renderOptions)\n        case VPatch.WIDGET:\n            return widgetPatch(domNode, vNode, patch, renderOptions)\n        case VPatch.VNODE:\n            return vNodePatch(domNode, vNode, patch, renderOptions)\n        case VPatch.ORDER:\n            reorderChildren(domNode, patch)\n            return domNode\n        case VPatch.PROPS:\n            applyProperties(domNode, patch, vNode.properties)\n            return domNode\n        case VPatch.THUNK:\n            return replaceRoot(domNode,\n                renderOptions.patch(domNode, patch, renderOptions))\n        default:\n            return domNode\n    }\n}\n\nfunction removeNode(domNode, vNode) {\n    var parentNode = domNode.parentNode\n\n    if (parentNode) {\n        parentNode.removeChild(domNode)\n    }\n\n    destroyWidget(domNode, vNode);\n\n    return null\n}\n\nfunction insertNode(parentNode, vNode, renderOptions) {\n    var newNode = renderOptions.render(vNode, renderOptions)\n\n    if (parentNode) {\n        parentNode.appendChild(newNode)\n    }\n\n    return parentNode\n}\n\nfunction stringPatch(domNode, leftVNode, vText, renderOptions) {\n    var newNode\n\n    if (domNode.nodeType === 3) {\n        domNode.replaceData(0, domNode.length, vText.text)\n        newNode = domNode\n    } else {\n        var parentNode = domNode.parentNode\n        newNode = renderOptions.render(vText, renderOptions)\n\n        if (parentNode && newNode !== domNode) {\n            parentNode.replaceChild(newNode, domNode)\n        }\n    }\n\n    return newNode\n}\n\nfunction widgetPatch(domNode, leftVNode, widget, renderOptions) {\n    var updating = updateWidget(leftVNode, widget)\n    var newNode\n\n    if (updating) {\n        newNode = widget.update(leftVNode, domNode) || domNode\n    } else {\n        newNode = renderOptions.render(widget, renderOptions)\n    }\n\n    var parentNode = domNode.parentNode\n\n    if (parentNode && newNode !== domNode) {\n        parentNode.replaceChild(newNode, domNode)\n    }\n\n    if (!updating) {\n        destroyWidget(domNode, leftVNode)\n    }\n\n    return newNode\n}\n\nfunction vNodePatch(domNode, leftVNode, vNode, renderOptions) {\n    var parentNode = domNode.parentNode\n    var newNode = renderOptions.render(vNode, renderOptions)\n\n    if (parentNode && newNode !== domNode) {\n        parentNode.replaceChild(newNode, domNode)\n    }\n\n    return newNode\n}\n\nfunction destroyWidget(domNode, w) {\n    if (typeof w.destroy === \"function\" && isWidget(w)) {\n        w.destroy(domNode)\n    }\n}\n\nfunction reorderChildren(domNode, moves) {\n    var childNodes = domNode.childNodes\n    var keyMap = {}\n    var node\n    var remove\n    var insert\n\n    for (var i = 0; i < moves.removes.length; i++) {\n        remove = moves.removes[i]\n        node = childNodes[remove.from]\n        if (remove.key) {\n            keyMap[remove.key] = node\n        }\n        domNode.removeChild(node)\n    }\n\n    var length = childNodes.length\n    for (var j = 0; j < moves.inserts.length; j++) {\n        insert = moves.inserts[j]\n        node = keyMap[insert.key]\n        // this is the weirdest bug i've ever seen in webkit\n        domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to])\n    }\n}\n\nfunction replaceRoot(oldRoot, newRoot) {\n    if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) {\n        oldRoot.parentNode.replaceChild(newRoot, oldRoot)\n    }\n\n    return newRoot;\n}\n\n},{\"../vnode/is-widget.js\":29,\"../vnode/vpatch.js\":32,\"./apply-properties\":14,\"./update-widget\":19}],18:[function(require,module,exports){\nvar document = require(\"global/document\")\nvar isArray = require(\"x-is-array\")\n\nvar render = require(\"./create-element\")\nvar domIndex = require(\"./dom-index\")\nvar patchOp = require(\"./patch-op\")\nmodule.exports = patch\n\nfunction patch(rootNode, patches, renderOptions) {\n    renderOptions = renderOptions || {}\n    renderOptions.patch = renderOptions.patch && renderOptions.patch !== patch\n        ? renderOptions.patch\n        : patchRecursive\n    renderOptions.render = renderOptions.render || render\n\n    return renderOptions.patch(rootNode, patches, renderOptions)\n}\n\nfunction patchRecursive(rootNode, patches, renderOptions) {\n    var indices = patchIndices(patches)\n\n    if (indices.length === 0) {\n        return rootNode\n    }\n\n    var index = domIndex(rootNode, patches.a, indices)\n    var ownerDocument = rootNode.ownerDocument\n\n    if (!renderOptions.document && ownerDocument !== document) {\n        renderOptions.document = ownerDocument\n    }\n\n    for (var i = 0; i < indices.length; i++) {\n        var nodeIndex = indices[i]\n        rootNode = applyPatch(rootNode,\n            index[nodeIndex],\n            patches[nodeIndex],\n            renderOptions)\n    }\n\n    return rootNode\n}\n\nfunction applyPatch(rootNode, domNode, patchList, renderOptions) {\n    if (!domNode) {\n        return rootNode\n    }\n\n    var newNode\n\n    if (isArray(patchList)) {\n        for (var i = 0; i < patchList.length; i++) {\n            newNode = patchOp(patchList[i], domNode, renderOptions)\n\n            if (domNode === rootNode) {\n                rootNode = newNode\n            }\n        }\n    } else {\n        newNode = patchOp(patchList, domNode, renderOptions)\n\n        if (domNode === rootNode) {\n            rootNode = newNode\n        }\n    }\n\n    return rootNode\n}\n\nfunction patchIndices(patches) {\n    var indices = []\n\n    for (var key in patches) {\n        if (key !== \"a\") {\n            indices.push(Number(key))\n        }\n    }\n\n    return indices\n}\n\n},{\"./create-element\":15,\"./dom-index\":16,\"./patch-op\":17,\"global/document\":10,\"x-is-array\":12}],19:[function(require,module,exports){\nvar isWidget = require(\"../vnode/is-widget.js\")\n\nmodule.exports = updateWidget\n\nfunction updateWidget(a, b) {\n    if (isWidget(a) && isWidget(b)) {\n        if (\"name\" in a && \"name\" in b) {\n            return a.id === b.id\n        } else {\n            return a.init === b.init\n        }\n    }\n\n    return false\n}\n\n},{\"../vnode/is-widget.js\":29}],20:[function(require,module,exports){\n'use strict';\n\nvar EvStore = require('ev-store');\n\nmodule.exports = EvHook;\n\nfunction EvHook(value) {\n    if (!(this instanceof EvHook)) {\n        return new EvHook(value);\n    }\n\n    this.value = value;\n}\n\nEvHook.prototype.hook = function (node, propertyName) {\n    var es = EvStore(node);\n    var propName = propertyName.substr(3);\n\n    es[propName] = this.value;\n};\n\nEvHook.prototype.unhook = function(node, propertyName) {\n    var es = EvStore(node);\n    var propName = propertyName.substr(3);\n\n    es[propName] = undefined;\n};\n\n},{\"ev-store\":7}],21:[function(require,module,exports){\n'use strict';\n\nmodule.exports = SoftSetHook;\n\nfunction SoftSetHook(value) {\n    if (!(this instanceof SoftSetHook)) {\n        return new SoftSetHook(value);\n    }\n\n    this.value = value;\n}\n\nSoftSetHook.prototype.hook = function (node, propertyName) {\n    if (node[propertyName] !== this.value) {\n        node[propertyName] = this.value;\n    }\n};\n\n},{}],22:[function(require,module,exports){\n'use strict';\n\nvar isArray = require('x-is-array');\n\nvar VNode = require('../vnode/vnode.js');\nvar VText = require('../vnode/vtext.js');\nvar isVNode = require('../vnode/is-vnode');\nvar isVText = require('../vnode/is-vtext');\nvar isWidget = require('../vnode/is-widget');\nvar isHook = require('../vnode/is-vhook');\nvar isVThunk = require('../vnode/is-thunk');\n\nvar parseTag = require('./parse-tag.js');\nvar softSetHook = require('./hooks/soft-set-hook.js');\nvar evHook = require('./hooks/ev-hook.js');\n\nmodule.exports = h;\n\nfunction h(tagName, properties, children) {\n    var childNodes = [];\n    var tag, props, key, namespace;\n\n    if (!children && isChildren(properties)) {\n        children = properties;\n        props = {};\n    }\n\n    props = props || properties || {};\n    tag = parseTag(tagName, props);\n\n    // support keys\n    if (props.hasOwnProperty('key')) {\n        key = props.key;\n        props.key = undefined;\n    }\n\n    // support namespace\n    if (props.hasOwnProperty('namespace')) {\n        namespace = props.namespace;\n        props.namespace = undefined;\n    }\n\n    // fix cursor bug\n    if (tag === 'INPUT' &&\n        !namespace &&\n        props.hasOwnProperty('value') &&\n        props.value !== undefined &&\n        !isHook(props.value)\n    ) {\n        props.value = softSetHook(props.value);\n    }\n\n    transformProperties(props);\n\n    if (children !== undefined && children !== null) {\n        addChild(children, childNodes, tag, props);\n    }\n\n\n    return new VNode(tag, props, childNodes, key, namespace);\n}\n\nfunction addChild(c, childNodes, tag, props) {\n    if (typeof c === 'string') {\n        childNodes.push(new VText(c));\n    } else if (typeof c === 'number') {\n        childNodes.push(new VText(String(c)));\n    } else if (isChild(c)) {\n        childNodes.push(c);\n    } else if (isArray(c)) {\n        for (var i = 0; i < c.length; i++) {\n            addChild(c[i], childNodes, tag, props);\n        }\n    } else if (c === null || c === undefined) {\n        return;\n    } else {\n        throw UnexpectedVirtualElement({\n            foreignObject: c,\n            parentVnode: {\n                tagName: tag,\n                properties: props\n            }\n        });\n    }\n}\n\nfunction transformProperties(props) {\n    for (var propName in props) {\n        if (props.hasOwnProperty(propName)) {\n            var value = props[propName];\n\n            if (isHook(value)) {\n                continue;\n            }\n\n            if (propName.substr(0, 3) === 'ev-') {\n                // add ev-foo support\n                props[propName] = evHook(value);\n            }\n        }\n    }\n}\n\nfunction isChild(x) {\n    return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x);\n}\n\nfunction isChildren(x) {\n    return typeof x === 'string' || isArray(x) || isChild(x);\n}\n\nfunction UnexpectedVirtualElement(data) {\n    var err = new Error();\n\n    err.type = 'virtual-hyperscript.unexpected.virtual-element';\n    err.message = 'Unexpected virtual child passed to h().\\n' +\n        'Expected a VNode / Vthunk / VWidget / string but:\\n' +\n        'got:\\n' +\n        errorString(data.foreignObject) +\n        '.\\n' +\n        'The parent vnode is:\\n' +\n        errorString(data.parentVnode)\n        '\\n' +\n        'Suggested fix: change your `h(..., [ ... ])` callsite.';\n    err.foreignObject = data.foreignObject;\n    err.parentVnode = data.parentVnode;\n\n    return err;\n}\n\nfunction errorString(obj) {\n    try {\n        return JSON.stringify(obj, null, '    ');\n    } catch (e) {\n        return String(obj);\n    }\n}\n\n},{\"../vnode/is-thunk\":25,\"../vnode/is-vhook\":26,\"../vnode/is-vnode\":27,\"../vnode/is-vtext\":28,\"../vnode/is-widget\":29,\"../vnode/vnode.js\":31,\"../vnode/vtext.js\":33,\"./hooks/ev-hook.js\":20,\"./hooks/soft-set-hook.js\":21,\"./parse-tag.js\":23,\"x-is-array\":12}],23:[function(require,module,exports){\n'use strict';\n\nvar split = require('browser-split');\n\nvar classIdSplit = /([\\.#]?[a-zA-Z0-9\\u007F-\\uFFFF_:-]+)/;\nvar notClassId = /^\\.|#/;\n\nmodule.exports = parseTag;\n\nfunction parseTag(tag, props) {\n    if (!tag) {\n        return 'DIV';\n    }\n\n    var noId = !(props.hasOwnProperty('id'));\n\n    var tagParts = split(tag, classIdSplit);\n    var tagName = null;\n\n    if (notClassId.test(tagParts[1])) {\n        tagName = 'DIV';\n    }\n\n    var classes, part, type, i;\n\n    for (i = 0; i < tagParts.length; i++) {\n        part = tagParts[i];\n\n        if (!part) {\n            continue;\n        }\n\n        type = part.charAt(0);\n\n        if (!tagName) {\n            tagName = part;\n        } else if (type === '.') {\n            classes = classes || [];\n            classes.push(part.substring(1, part.length));\n        } else if (type === '#' && noId) {\n            props.id = part.substring(1, part.length);\n        }\n    }\n\n    if (classes) {\n        if (props.className) {\n            classes.push(props.className);\n        }\n\n        props.className = classes.join(' ');\n    }\n\n    return props.namespace ? tagName : tagName.toUpperCase();\n}\n\n},{\"browser-split\":5}],24:[function(require,module,exports){\nvar isVNode = require(\"./is-vnode\")\nvar isVText = require(\"./is-vtext\")\nvar isWidget = require(\"./is-widget\")\nvar isThunk = require(\"./is-thunk\")\n\nmodule.exports = handleThunk\n\nfunction handleThunk(a, b) {\n    var renderedA = a\n    var renderedB = b\n\n    if (isThunk(b)) {\n        renderedB = renderThunk(b, a)\n    }\n\n    if (isThunk(a)) {\n        renderedA = renderThunk(a, null)\n    }\n\n    return {\n        a: renderedA,\n        b: renderedB\n    }\n}\n\nfunction renderThunk(thunk, previous) {\n    var renderedThunk = thunk.vnode\n\n    if (!renderedThunk) {\n        renderedThunk = thunk.vnode = thunk.render(previous)\n    }\n\n    if (!(isVNode(renderedThunk) ||\n            isVText(renderedThunk) ||\n            isWidget(renderedThunk))) {\n        throw new Error(\"thunk did not return a valid node\");\n    }\n\n    return renderedThunk\n}\n\n},{\"./is-thunk\":25,\"./is-vnode\":27,\"./is-vtext\":28,\"./is-widget\":29}],25:[function(require,module,exports){\nmodule.exports = isThunk\r\n\r\nfunction isThunk(t) {\r\n    return t && t.type === \"Thunk\"\r\n}\r\n\n},{}],26:[function(require,module,exports){\nmodule.exports = isHook\n\nfunction isHook(hook) {\n    return hook &&\n      (typeof hook.hook === \"function\" && !hook.hasOwnProperty(\"hook\") ||\n       typeof hook.unhook === \"function\" && !hook.hasOwnProperty(\"unhook\"))\n}\n\n},{}],27:[function(require,module,exports){\nvar version = require(\"./version\")\n\nmodule.exports = isVirtualNode\n\nfunction isVirtualNode(x) {\n    return x && x.type === \"VirtualNode\" && x.version === version\n}\n\n},{\"./version\":30}],28:[function(require,module,exports){\nvar version = require(\"./version\")\n\nmodule.exports = isVirtualText\n\nfunction isVirtualText(x) {\n    return x && x.type === \"VirtualText\" && x.version === version\n}\n\n},{\"./version\":30}],29:[function(require,module,exports){\nmodule.exports = isWidget\n\nfunction isWidget(w) {\n    return w && w.type === \"Widget\"\n}\n\n},{}],30:[function(require,module,exports){\nmodule.exports = \"2\"\n\n},{}],31:[function(require,module,exports){\nvar version = require(\"./version\")\nvar isVNode = require(\"./is-vnode\")\nvar isWidget = require(\"./is-widget\")\nvar isThunk = require(\"./is-thunk\")\nvar isVHook = require(\"./is-vhook\")\n\nmodule.exports = VirtualNode\n\nvar noProperties = {}\nvar noChildren = []\n\nfunction VirtualNode(tagName, properties, children, key, namespace) {\n    this.tagName = tagName\n    this.properties = properties || noProperties\n    this.children = children || noChildren\n    this.key = key != null ? String(key) : undefined\n    this.namespace = (typeof namespace === \"string\") ? namespace : null\n\n    var count = (children && children.length) || 0\n    var descendants = 0\n    var hasWidgets = false\n    var hasThunks = false\n    var descendantHooks = false\n    var hooks\n\n    for (var propName in properties) {\n        if (properties.hasOwnProperty(propName)) {\n            var property = properties[propName]\n            if (isVHook(property) && property.unhook) {\n                if (!hooks) {\n                    hooks = {}\n                }\n\n                hooks[propName] = property\n            }\n        }\n    }\n\n    for (var i = 0; i < count; i++) {\n        var child = children[i]\n        if (isVNode(child)) {\n            descendants += child.count || 0\n\n            if (!hasWidgets && child.hasWidgets) {\n                hasWidgets = true\n            }\n\n            if (!hasThunks && child.hasThunks) {\n                hasThunks = true\n            }\n\n            if (!descendantHooks && (child.hooks || child.descendantHooks)) {\n                descendantHooks = true\n            }\n        } else if (!hasWidgets && isWidget(child)) {\n            if (typeof child.destroy === \"function\") {\n                hasWidgets = true\n            }\n        } else if (!hasThunks && isThunk(child)) {\n            hasThunks = true;\n        }\n    }\n\n    this.count = count + descendants\n    this.hasWidgets = hasWidgets\n    this.hasThunks = hasThunks\n    this.hooks = hooks\n    this.descendantHooks = descendantHooks\n}\n\nVirtualNode.prototype.version = version\nVirtualNode.prototype.type = \"VirtualNode\"\n\n},{\"./is-thunk\":25,\"./is-vhook\":26,\"./is-vnode\":27,\"./is-widget\":29,\"./version\":30}],32:[function(require,module,exports){\nvar version = require(\"./version\")\n\nVirtualPatch.NONE = 0\nVirtualPatch.VTEXT = 1\nVirtualPatch.VNODE = 2\nVirtualPatch.WIDGET = 3\nVirtualPatch.PROPS = 4\nVirtualPatch.ORDER = 5\nVirtualPatch.INSERT = 6\nVirtualPatch.REMOVE = 7\nVirtualPatch.THUNK = 8\n\nmodule.exports = VirtualPatch\n\nfunction VirtualPatch(type, vNode, patch) {\n    this.type = Number(type)\n    this.vNode = vNode\n    this.patch = patch\n}\n\nVirtualPatch.prototype.version = version\nVirtualPatch.prototype.type = \"VirtualPatch\"\n\n},{\"./version\":30}],33:[function(require,module,exports){\nvar version = require(\"./version\")\n\nmodule.exports = VirtualText\n\nfunction VirtualText(text) {\n    this.text = String(text)\n}\n\nVirtualText.prototype.version = version\nVirtualText.prototype.type = \"VirtualText\"\n\n},{\"./version\":30}],34:[function(require,module,exports){\nvar isObject = require(\"is-object\")\nvar isHook = require(\"../vnode/is-vhook\")\n\nmodule.exports = diffProps\n\nfunction diffProps(a, b) {\n    var diff\n\n    for (var aKey in a) {\n        if (!(aKey in b)) {\n            diff = diff || {}\n            diff[aKey] = undefined\n        }\n\n        var aValue = a[aKey]\n        var bValue = b[aKey]\n\n        if (aValue === bValue) {\n            continue\n        } else if (isObject(aValue) && isObject(bValue)) {\n            if (getPrototype(bValue) !== getPrototype(aValue)) {\n                diff = diff || {}\n                diff[aKey] = bValue\n            } else if (isHook(bValue)) {\n                 diff = diff || {}\n                 diff[aKey] = bValue\n            } else {\n                var objectDiff = diffProps(aValue, bValue)\n                if (objectDiff) {\n                    diff = diff || {}\n                    diff[aKey] = objectDiff\n                }\n            }\n        } else {\n            diff = diff || {}\n            diff[aKey] = bValue\n        }\n    }\n\n    for (var bKey in b) {\n        if (!(bKey in a)) {\n            diff = diff || {}\n            diff[bKey] = b[bKey]\n        }\n    }\n\n    return diff\n}\n\nfunction getPrototype(value) {\n  if (Object.getPrototypeOf) {\n    return Object.getPrototypeOf(value)\n  } else if (value.__proto__) {\n    return value.__proto__\n  } else if (value.constructor) {\n    return value.constructor.prototype\n  }\n}\n\n},{\"../vnode/is-vhook\":26,\"is-object\":11}],35:[function(require,module,exports){\nvar isArray = require(\"x-is-array\")\n\nvar VPatch = require(\"../vnode/vpatch\")\nvar isVNode = require(\"../vnode/is-vnode\")\nvar isVText = require(\"../vnode/is-vtext\")\nvar isWidget = require(\"../vnode/is-widget\")\nvar isThunk = require(\"../vnode/is-thunk\")\nvar handleThunk = require(\"../vnode/handle-thunk\")\n\nvar diffProps = require(\"./diff-props\")\n\nmodule.exports = diff\n\nfunction diff(a, b) {\n    var patch = { a: a }\n    walk(a, b, patch, 0)\n    return patch\n}\n\nfunction walk(a, b, patch, index) {\n    if (a === b) {\n        return\n    }\n\n    var apply = patch[index]\n    var applyClear = false\n\n    if (isThunk(a) || isThunk(b)) {\n        thunks(a, b, patch, index)\n    } else if (b == null) {\n\n        // If a is a widget we will add a remove patch for it\n        // Otherwise any child widgets/hooks must be destroyed.\n        // This prevents adding two remove patches for a widget.\n        if (!isWidget(a)) {\n            clearState(a, patch, index)\n            apply = patch[index]\n        }\n\n        apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b))\n    } else if (isVNode(b)) {\n        if (isVNode(a)) {\n            if (a.tagName === b.tagName &&\n                a.namespace === b.namespace &&\n                a.key === b.key) {\n                var propsPatch = diffProps(a.properties, b.properties)\n                if (propsPatch) {\n                    apply = appendPatch(apply,\n                        new VPatch(VPatch.PROPS, a, propsPatch))\n                }\n                apply = diffChildren(a, b, patch, apply, index)\n            } else {\n                apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))\n                applyClear = true\n            }\n        } else {\n            apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))\n            applyClear = true\n        }\n    } else if (isVText(b)) {\n        if (!isVText(a)) {\n            apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))\n            applyClear = true\n        } else if (a.text !== b.text) {\n            apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))\n        }\n    } else if (isWidget(b)) {\n        if (!isWidget(a)) {\n            applyClear = true\n        }\n\n        apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b))\n    }\n\n    if (apply) {\n        patch[index] = apply\n    }\n\n    if (applyClear) {\n        clearState(a, patch, index)\n    }\n}\n\nfunction diffChildren(a, b, patch, apply, index) {\n    var aChildren = a.children\n    var orderedSet = reorder(aChildren, b.children)\n    var bChildren = orderedSet.children\n\n    var aLen = aChildren.length\n    var bLen = bChildren.length\n    var len = aLen > bLen ? aLen : bLen\n\n    for (var i = 0; i < len; i++) {\n        var leftNode = aChildren[i]\n        var rightNode = bChildren[i]\n        index += 1\n\n        if (!leftNode) {\n            if (rightNode) {\n                // Excess nodes in b need to be added\n                apply = appendPatch(apply,\n                    new VPatch(VPatch.INSERT, null, rightNode))\n            }\n        } else {\n            walk(leftNode, rightNode, patch, index)\n        }\n\n        if (isVNode(leftNode) && leftNode.count) {\n            index += leftNode.count\n        }\n    }\n\n    if (orderedSet.moves) {\n        // Reorder nodes last\n        apply = appendPatch(apply, new VPatch(\n            VPatch.ORDER,\n            a,\n            orderedSet.moves\n        ))\n    }\n\n    return apply\n}\n\nfunction clearState(vNode, patch, index) {\n    // TODO: Make this a single walk, not two\n    unhook(vNode, patch, index)\n    destroyWidgets(vNode, patch, index)\n}\n\n// Patch records for all destroyed widgets must be added because we need\n// a DOM node reference for the destroy function\nfunction destroyWidgets(vNode, patch, index) {\n    if (isWidget(vNode)) {\n        if (typeof vNode.destroy === \"function\") {\n            patch[index] = appendPatch(\n                patch[index],\n                new VPatch(VPatch.REMOVE, vNode, null)\n            )\n        }\n    } else if (isVNode(vNode) && (vNode.hasWidgets || vNode.hasThunks)) {\n        var children = vNode.children\n        var len = children.length\n        for (var i = 0; i < len; i++) {\n            var child = children[i]\n            index += 1\n\n            destroyWidgets(child, patch, index)\n\n            if (isVNode(child) && child.count) {\n                index += child.count\n            }\n        }\n    } else if (isThunk(vNode)) {\n        thunks(vNode, null, patch, index)\n    }\n}\n\n// Create a sub-patch for thunks\nfunction thunks(a, b, patch, index) {\n    var nodes = handleThunk(a, b)\n    var thunkPatch = diff(nodes.a, nodes.b)\n    if (hasPatches(thunkPatch)) {\n        patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch)\n    }\n}\n\nfunction hasPatches(patch) {\n    for (var index in patch) {\n        if (index !== \"a\") {\n            return true\n        }\n    }\n\n    return false\n}\n\n// Execute hooks when two nodes are identical\nfunction unhook(vNode, patch, index) {\n    if (isVNode(vNode)) {\n        if (vNode.hooks) {\n            patch[index] = appendPatch(\n                patch[index],\n                new VPatch(\n                    VPatch.PROPS,\n                    vNode,\n                    undefinedKeys(vNode.hooks)\n                )\n            )\n        }\n\n        if (vNode.descendantHooks || vNode.hasThunks) {\n            var children = vNode.children\n            var len = children.length\n            for (var i = 0; i < len; i++) {\n                var child = children[i]\n                index += 1\n\n                unhook(child, patch, index)\n\n                if (isVNode(child) && child.count) {\n                    index += child.count\n                }\n            }\n        }\n    } else if (isThunk(vNode)) {\n        thunks(vNode, null, patch, index)\n    }\n}\n\nfunction undefinedKeys(obj) {\n    var result = {}\n\n    for (var key in obj) {\n        result[key] = undefined\n    }\n\n    return result\n}\n\n// List diff, naive left to right reordering\nfunction reorder(aChildren, bChildren) {\n    // O(M) time, O(M) memory\n    var bChildIndex = keyIndex(bChildren)\n    var bKeys = bChildIndex.keys\n    var bFree = bChildIndex.free\n\n    if (bFree.length === bChildren.length) {\n        return {\n            children: bChildren,\n            moves: null\n        }\n    }\n\n    // O(N) time, O(N) memory\n    var aChildIndex = keyIndex(aChildren)\n    var aKeys = aChildIndex.keys\n    var aFree = aChildIndex.free\n\n    if (aFree.length === aChildren.length) {\n        return {\n            children: bChildren,\n            moves: null\n        }\n    }\n\n    // O(MAX(N, M)) memory\n    var newChildren = []\n\n    var freeIndex = 0\n    var freeCount = bFree.length\n    var deletedItems = 0\n\n    // Iterate through a and match a node in b\n    // O(N) time,\n    for (var i = 0 ; i < aChildren.length; i++) {\n        var aItem = aChildren[i]\n        var itemIndex\n\n        if (aItem.key) {\n            if (bKeys.hasOwnProperty(aItem.key)) {\n                // Match up the old keys\n                itemIndex = bKeys[aItem.key]\n                newChildren.push(bChildren[itemIndex])\n\n            } else {\n                // Remove old keyed items\n                itemIndex = i - deletedItems++\n                newChildren.push(null)\n            }\n        } else {\n            // Match the item in a with the next free item in b\n            if (freeIndex < freeCount) {\n                itemIndex = bFree[freeIndex++]\n                newChildren.push(bChildren[itemIndex])\n            } else {\n                // There are no free items in b to match with\n                // the free items in a, so the extra free nodes\n                // are deleted.\n                itemIndex = i - deletedItems++\n                newChildren.push(null)\n            }\n        }\n    }\n\n    var lastFreeIndex = freeIndex >= bFree.length ?\n        bChildren.length :\n        bFree[freeIndex]\n\n    // Iterate through b and append any new keys\n    // O(M) time\n    for (var j = 0; j < bChildren.length; j++) {\n        var newItem = bChildren[j]\n\n        if (newItem.key) {\n            if (!aKeys.hasOwnProperty(newItem.key)) {\n                // Add any new keyed items\n                // We are adding new items to the end and then sorting them\n                // in place. In future we should insert new items in place.\n                newChildren.push(newItem)\n            }\n        } else if (j >= lastFreeIndex) {\n            // Add any leftover non-keyed items\n            newChildren.push(newItem)\n        }\n    }\n\n    var simulate = newChildren.slice()\n    var simulateIndex = 0\n    var removes = []\n    var inserts = []\n    var simulateItem\n\n    for (var k = 0; k < bChildren.length;) {\n        var wantedItem = bChildren[k]\n        simulateItem = simulate[simulateIndex]\n\n        // remove items\n        while (simulateItem === null && simulate.length) {\n            removes.push(remove(simulate, simulateIndex, null))\n            simulateItem = simulate[simulateIndex]\n        }\n\n        if (!simulateItem || simulateItem.key !== wantedItem.key) {\n            // if we need a key in this position...\n            if (wantedItem.key) {\n                if (simulateItem && simulateItem.key) {\n                    // if an insert doesn't put this key in place, it needs to move\n                    if (bKeys[simulateItem.key] !== k + 1) {\n                        removes.push(remove(simulate, simulateIndex, simulateItem.key))\n                        simulateItem = simulate[simulateIndex]\n                        // if the remove didn't put the wanted item in place, we need to insert it\n                        if (!simulateItem || simulateItem.key !== wantedItem.key) {\n                            inserts.push({key: wantedItem.key, to: k})\n                        }\n                        // items are matching, so skip ahead\n                        else {\n                            simulateIndex++\n                        }\n                    }\n                    else {\n                        inserts.push({key: wantedItem.key, to: k})\n                    }\n                }\n                else {\n                    inserts.push({key: wantedItem.key, to: k})\n                }\n                k++\n            }\n            // a key in simulate has no matching wanted key, remove it\n            else if (simulateItem && simulateItem.key) {\n                removes.push(remove(simulate, simulateIndex, simulateItem.key))\n            }\n        }\n        else {\n            simulateIndex++\n            k++\n        }\n    }\n\n    // remove all the remaining nodes from simulate\n    while(simulateIndex < simulate.length) {\n        simulateItem = simulate[simulateIndex]\n        removes.push(remove(simulate, simulateIndex, simulateItem && simulateItem.key))\n    }\n\n    // If the only moves we have are deletes then we can just\n    // let the delete patch remove these items.\n    if (removes.length === deletedItems && !inserts.length) {\n        return {\n            children: newChildren,\n            moves: null\n        }\n    }\n\n    return {\n        children: newChildren,\n        moves: {\n            removes: removes,\n            inserts: inserts\n        }\n    }\n}\n\nfunction remove(arr, index, key) {\n    arr.splice(index, 1)\n\n    return {\n        from: index,\n        key: key\n    }\n}\n\nfunction keyIndex(children) {\n    var keys = {}\n    var free = []\n    var length = children.length\n\n    for (var i = 0; i < length; i++) {\n        var child = children[i]\n\n        if (child.key) {\n            keys[child.key] = i\n        } else {\n            free.push(i)\n        }\n    }\n\n    return {\n        keys: keys,     // A hash of key name to index\n        free: free      // An array of unkeyed item indices\n    }\n}\n\nfunction appendPatch(apply, patch) {\n    if (apply) {\n        if (isArray(apply)) {\n            apply.push(patch)\n        } else {\n            apply = [apply, patch]\n        }\n\n        return apply\n    } else {\n        return patch\n    }\n}\n\n},{\"../vnode/handle-thunk\":24,\"../vnode/is-thunk\":25,\"../vnode/is-vnode\":27,\"../vnode/is-vtext\":28,\"../vnode/is-widget\":29,\"../vnode/vpatch\":32,\"./diff-props\":34,\"x-is-array\":12}]},{},[4])(4)\n});"
  },
  {
    "path": "docs/README.md",
    "content": "# virtual-dom documentation\nThis documentation is aimed at people who would like to work with virtual-dom directly, or gain a deeper understanding of how their virtual-dom based framework works. If you would rather be working at a higher level, you may find the [mercury framework](https://github.com/Raynos/mercury) a better place to start.\n\n## Overview\n\nvirtual-dom consists of four main parts:\n\n[vtree](https://github.com/Matt-Esch/virtual-dom/tree/master/vtree) - responsible for diffing two virtual representations DOM nodes  \n[vdom](https://github.com/Matt-Esch/virtual-dom/tree/master/vdom) - responsible for taking the [patch](https://github.com/Matt-Esch/virtual-dom/blob/master/vdom/patch.js) genereated by [vtree/diff](https://github.com/Matt-Esch/virtual-dom/blob/master/vtree/diff.js) and using it to modify the rendered DOM  \n[vnode](https://github.com/Matt-Esch/virtual-dom/tree/master/vnode) - virtual representation of dom elements  \n[virtual-hyperscript](https://github.com/Matt-Esch/virtual-dom/tree/master/virtual-hyperscript) - an interface for generating VNodes from simple data structures\n\nNewcomers should start by reading the VNode and VText documentation, as virtual nodes are central to the operation of virtual-dom. Hooks, Thunks, and Widgets are more advanced features, and you will find both documentation of their interfaces and several examples on their respective pages.\n\n## Contents\n\n[VNode](vnode.md) - A representation of a DOM element\n\n[VText](vtext.md) - A representation of a text node\n\n[Hooks](hooks.md) - The mechanism for executing functions after a new node has been created\n\n[Thunk](thunk.md) - The mechanism for taking control of diffing a specific DOM sub-tree\n\n[Widget](widget.md) - The mechanism for taking control of node patching: DOM Element creation, updating, and removal.\n\n[CSS animations](css-animations.md)\n"
  },
  {
    "path": "docs/css-animations.md",
    "content": "# CSS animations\nBased on a discusison in [question](https://github.com/Matt-Esch/virtual-dom/issues/104#issuecomment-68611995).\n\nYou should be activating the CSS transitions using hooks and nextTick. Here is a basic example of inserting an element through transition:\n```javascript\nItem.render = function(state) {\n  return h('li', {\n    'class' : new ItemInsertHook('item'),\n  }, [\n    h('div.text', state.text), \n    h('button', {\n      'ev-click' : mercury.event(...)\n    }, 'Remove or something...'),\n  ]);\n}\n\nfunction ItemInsertHook(value) {\n  this.value = value;\n}\n\nItemInsertHook.prototype.hook = function(elem, propName) {\n  \n  // Here we want to see if this is a newly created dom element\n  // or an element that was inserted before and is revisited.\n  // The way to check for that in this case is see if the element is \n  // attached to the dom.\n  // Newly created element will not be attached to the dom when hook is executed.\n  \n  if (!document.body.contains(elem)) {\n    elem.setAttribute(propName, this.value + ' inserting');\n\n    nextTick(function () {\n      elem.setAttribute(propName, this.value + '');\n    }.bind(this))\n  }\n}\n\n//Elswhere at the top level of application:\nfunction renderItemsList(state) {\n  return h('ul#item-list', [\n    state.items.map(function(item) {return Item.render(item);})\n  ]);\n}\n```\n\nAnd css:\n```css\nli.item.inserting { opacity : 0.01; }\nli.item { transition: opacity 0.2s ease-in-out; }\nli.item { opacity : 0.99; }\n```\n\nSee full example on requirebin: http://requirebin.com/?gist=250e6e59aa40d5ff0fcc\n\nIn a more complex case it may be necessary to encode animation state in the model. You should know exactly which nodes you wish to animate based on your data, and you should use that data to add a transition hook based on next tick.\n\nYou don't have to do animations with JS, prefer CSS transitions, but you do need to model your expectations properly in your data model and apply transitions to the nodes using that data. Generic transitions that rely on the way in which the DOM is mutated isn't going to work consistently.\n\nFor example, if you want an inserted transition, you might add a wasInserted boolean flag to your model.\n\nOn rendering that item, if wasInserted is true, you add an animation hook which, on next tick, adds a css class like .inserted. You code your CSS transitions against this class.\n\nOn next tick your hook will add the class and the transition will happen. Further to that you will want to clear the wasInserted flag, probably also on next tick.\n\nThere are tons of these flag situations which should not trigger re-render. I think mercury needs to add something like this as a primitive type but that's outside the scope of virtual-dom.\n\nBut as you can see, the animation works because you have recorded the state and necessity for the transition, and did not rely simply on the insertion of the node to trigger that animation.\n"
  },
  {
    "path": "docs/faq.md",
    "content": "# FAQ\n\nThese are frequently asked questions. If you have any questions\nnot on this list, then **please** [open an issue and ask][new-issue].\n\n[new-issue]: https://github.com/Matt-Esch/virtual-dom/issues/new\n\n## How do I do custom rendering\n\nIf you want to embed a custom piece of rendering machinery in\n  the virtual DOM you can use widgets.\n\nA widget is a object with an `init()` and `update()` method and a `type` attribute with the \"Widget\" value.\n\n```js\nfunction GoogleMapWidget(initialPosition) {\n    this.type = 'Widget'\n    this.position = initialPosition\n}\n\nGoogleMapWidget.prototype.init = function () {\n    var elem = document.createElement('div')\n    this.map = GoogleMap(elem)\n    this.map.setPosition(this.position)\n    return elem\n}\n\nGoogleMapWidget.prototype.update = function (prev, elem) {\n    this.map = this.map || prev.map\n    this.map.setPosition(this.position)\n}\n\nh('div', [\n    new GoogleMapWidget({ x: 0, y: 0 })\n])\n```\n\nThe rules for a widget is that the first time it's seen we call\n  `init()`, we expect `init()` to return a DOM element.\n\nThe DOM element you return is yours to keep & mutate, virtual\n  DOM will not touch it or its children. However you should never\n  touch `elem.parentNode` as that does not belong to the widget\n\nThe second method is `update()` if we see a widget and we have\n  the same widget in the previous tree we call `update(prev, elem)`\n  instead. `update()` is a good place to copy over any stateful\n  things from the `prev` widget instance and then to update the\n  state with the current properties by accessing them with `this`\n\nFor another example of a widget see the\n    [canvas demo](examples/canvas.js)\n\n## How do I update custom properties\n\nIf you want to update a custom property on a DOM element, like\n  calling `setAttribute()` or calling `focus()` then you can\n  use a hook\n\n```js\nfunction AttributeHook(value) {\n    this.value = value\n}\n\nAttributeHook.prototype.hook = function (elem, prop) {\n    elem.setAttribute(prop, this.value)\n}\n\nh('div', {\n    class: new AttributeHook('some-class-name')\n})\n```\n\nFor another example of a hook see\n  [TodoMVC focus hook](https://github.com/Raynos/mercury/blob/master/examples/lib/focus-hook.js)\n\n## How do I get life cycle hooks for VNodes\n\n`VNode` only exposes one life cycle mechanism. which is the hook\n  mechanism.\n\n### Hooking into VNode creation\n\nIf you want to do some custom DOM logic immediately once a VNode\n  is created you can add a hook, I normally add them to\n  `ev-foo` properties.\n\n```js\nfunction MyHook(args) {\n  this.args = args\n}\n\nMyHook.prototype.hook = function (elem, propName) {\n  /* do DOM stuff */\n}\n\nh('div', {\n    'ev-myHook': new MyHook(args)\n})\n```\n\n### Hooking into VNode after it's in the DOM\n\nIf you want to a hook to fire after the DOM element has been\n  appended into the DOM you will have to delay the hook manually\n\n```js\nfunction MyHook(args) {\n  this.args = args\n}\n\nMyHook.prototype.hook = function (elem, propName) {\n  setImmediate(function () {\n    // DOM element will be in the real DOM by now\n    // do DOM stuff\n  })\n}\n\nh('div', {\n    'ev-myHook': new MyHook(args)\n})\n```\n\nWe only have one type of hook as maintaining both life cycles\n  separately is very complex when it can simply be done at\n  the user level with a `setImmediate`\n\nWe have the hook fire immediately by default because sometimes\n  you need to run DOM logic BEFORE the element is in the DOM.\n\nFiring the hook when the element is in the DOM makes it\n  impossible to fire it when it's not in the DOM.\n\n"
  },
  {
    "path": "docs/hooks.md",
    "content": "# Hooks\nHooks are functions that execute after turning a VNode into an Element. They are set by passing a VNode any property key with an object that has a function called hook that has not been directly assigned. The simplest way to ensure that a function isn't directly assigned is for it to be a prototype on an object.\n\nWill Work\n```javascript\nvar Hook = function(){}\nHook.prototype.hook = function(node, propertyName, previousValue) { \n  console.log(\"Hello, World\")\n}\ncreateElement(h('div', { \"my-hook\": new Hook() }))\n```\n\nWon't Work\n```javascript\nvar hook = { hook: function(node, propertyName, previousvalue) { console.log(\"Hello, World\") } }\ncreateElement(h('div', { \"my-hook\": hook }))\n```\n\n## Arguments\nYour hook function will be given the following arguments\n\n**node**  \nThe Element generated from the VNode.\n\n```javascript\nvar Hook = function(){}\nHook.prototype.hook = function(node, propertyName, previousValue) {\n  console.log(\"type: \", node.constructor.name)\n}\ncreateElement(h('div', { \"my-hook\": new Hook() }))\n// logs \"type: HTMLDivElement\"\n```\n\n**propertyName**  \nString, key of the property this hook was assigned from.\n\n```javascript\nvar Hook = function(){}\nHook.prototype.hook = function(node, propertyName, previousValue) { \n  console.log(\"name: \" + propertyName)\n}\ncreateElement(h('div', { \"my-hook\": new Hook() }))\n// logs \"name: my-hook\"\n```\n\n**previousValue** *(optional)*  \nIf this node is having just its properties changed during a patch, it will receive the value that was previously assigned to the key. Otherwise, this argument will be undefined.\n\n## Other Examples\n[virtual-hyperscript](https://github.com/Matt-Esch/virtual-dom/tree/master/virtual-hyperscript) uses hooks for several things, including setting up events and returning focus to input elements after a render. You can view these hooks in the [virtual-hyperscript/hooks](https://github.com/Matt-Esch/virtual-dom/tree/master/virtual-hyperscript/hooks) folder.\n"
  },
  {
    "path": "docs/thunk.md",
    "content": "# Thunk\nThunks allow the user to take control of the diff'ing process for a specific dom tree, usually to avoid doing calculations you know are unneeded, such as diff'ing a tree you know hasn't changed.\n\n## Thunk Interface\nA Thunk needs to be an object with two keys\n\n**type**   \nmust be the string \"Thunk\"\n\n**render**   \nFunction that returns a VNode, Widget, or VText.\n\n```javascript\n// Boilerplate Thunk\nvar Thunk = function (){}\nThunk.prototype.type = \"Thunk\"\nThunk.prototype.render = function(previous){}\n```\n\n## Render Method Arguments\nWhen diff is run, the render method is passed a single argument.\n\n**previous**  \nThe previous VNode, Thunk, Widget, or VText that the Thunk is being diffed against\n\n## The Special \"vnode\" Property\nWhen `render` is called by `diff`, it will create a cache of whatever it returns in the key `vnode`. When implementing the Thunk interface, don't define a `vnode` key, as it will be overwritten! You should use the `vnode` property when render is provided with the `previous` argument, and you'd like to return the cached copy to prevent a Thunk from re-rendering. We give an example of this in the ConstantlyThunk implementation below.\n\n## Simple Example\nHere we implement a simple Thunk called ConstantlyThunk. Any instance of ConstantlyThunk that gets diffed with another instance of ConstantlyThunk will return the value of the previous ConstantlyThunk, preventing a patch from being generated.\n\n```javascript\n// Only the first instance of this Thunk will be shown. \n// Once its been rendered, any other instances of ConstantlyThunk that\n// diff with it will return a reference to the cached value that is automatically\n// assigned to the \"vnode\" property\nvar ConstantlyThunk = function(greeting){\n  this.greeting = greeting\n}\nConstantlyThunk.prototype.type = \"Thunk\"\nConstantlyThunk.prototype.render = function(previous) {\n  if (previous && previous.vnode) {\n    return previous.vnode\n  } else {\n    return h('div', [\"Constantly \"+ this.greeting])\n  }\n}\n\nThunk1 = new ConstantlyThunk(\"Thunk!\")\nThunk2 = new ConstantlyThunk(\"I won't be rendered!\")\nthunkElem = createElement(Thunk1)\ndocument.body.appendChild(thunkElem)\n// No new patches are generated\npatches = diff(Thunk1, Thunk2)\n// Nothing will happen\npatch(thunkElem, patches)\n\n```\n\n## Full Example\nHere we implement GenericThunk, a simplified version of Raynos' [immutable-thunk](https://github.com/Raynos/vdom-thunk/blob/master/immutable-thunk.js)\n\nIt takes a rendering function, a comparison function, and a state. When it's being diffed vs. another instance of GenericThunk, it will use the comparison function to look at the new state and old state, and decide if it's ok to update.\n\n```javascript\nvar diff = require(\"virtual-dom\").diff\nvar patch = require(\"virtual-dom\").patch\nvar h = require(\"virtual-dom\").h\nvar createElement = require(\"virtual-dom\").create\n// Our GenericThunk will take 3 arguments\n// renderFn is the function that will generate the VNode\n// cmpFn is the function that will be used to compare state to see if an update is necessary.\n// returns true if the update should re-render, and false if it should use the previous render\n// state is a value that holds the information cmpFn will use to decide whether we should\n// update the Thunk or not\nvar GenericThunk = function(renderFn, cmpFn, state) {\n  this.renderFn = renderFn\n  this.cmpFn = cmpFn\n  this.state = state\n}\n\nGenericThunk.prototype.type = \"Thunk\"\n\nGenericThunk.prototype.render = function(previous) {\n  // The first time the Thunk renders, there will be no previous state\n  var previousState = previous ? previous.state : null\n  // We run the comparison function to see if the state has changed enough\n  // for us to re-render. If it returns truthy, then we call the render\n  // function to give us a new VNode\n  if ((!previousState || !this.state) || this.cmpFn(previousState, this.state)) {\n    return this.renderFn(previous, this)\n  } else {\n    // vnode will be set automatically when a thunk has been created\n    // it contains the VNode, VText, Thunk, or Widget generated by\n    // our render function.\n    return previous.vnode\n  }\n}\n\n// The function we'll pass to GenericThunk to see if the color has changed\n// We return a true value if the colors are different\nvar titleCompare = function(previousState, currentState) {\n  return previousState.color !== currentState.color\n}\n// The function that builds our title when we detect that\n// the color has changed\nvar titleRender = function(previousThunk, currentThunk) {\n  var currentColor = currentThunk.state.color\n  return h(\"h1\", { style: {color: currentColor}}, [\"Hello, I'm a title colored \" + currentColor])\n}\n\nvar GreenColoredThunk = new GenericThunk(titleRender, titleCompare, { color: \"green\"})\nvar BlueColoredThunk = new GenericThunk(titleRender, titleCompare, { color: \"blue\"})\n\nvar currentNode = GreenColoredThunk\nvar rootNode = createElement(currentNode)\n\n// A simple function to diff your thunks, and patch the dom\nvar update = function(nextNode) {\n  var patches = diff(currentNode, nextNode)\n  rootNode = patch(rootNode, patches)\n  currentNode = nextNode\n}\n\ndocument.body.appendChild(rootNode)\n// We schedule a couple updates\n// Our first update will see that our color hasn't changed, and will stop comparing at that point,\n// instead returning a reference to GreenColoredThunk.vnode\nsetTimeout(function() {\n    update(new GenericThunk(titleRender, titleCompare, { color: \"green\" }))\n  },\n  1000)\n\n// In our second update, BlueColoredThunk will see that state.color has changed,\n// and will return a new VNode, generating a patch\nsetTimeout(function() {\n    update(BlueColoredThunk)\n  },\n  2000)\n\n```\n\n## Other Resources\nRaynos has created a library for making Thunks at [vdom-thunk](https://github.com/Raynos/vdom-thunk).\n"
  },
  {
    "path": "docs/vnode.md",
    "content": "# VNode\n\nA VNode is a representation of a dom node. Most end users will probably have their VNodes generated through [virtual-hyperscript](https://github.com/Matt-Esch/virtual-dom/tree/master/virtual-hyperscript), but understanding the VNode interface can be useful.\n\nIn virtual-dom, VNodes are turned from virtual nodes into real nodes with the createElement function. You can read the code at [vdom/create-element](https://github.com/Matt-Esch/virtual-dom/blob/master/vdom/create-element.js)\n\n## Arguments\n\n**tagName**  \nA string, e.g. 'div', 'span', 'article'\n\n**properties** *(optional)*  \nAn object that maps property names to their values, e.g. `{ id: \"foo\", className: \"bar\" }`\n\n**children** *(optional)*  \nAn array of any combination of VNodes, VText, Widgets, or Thunks\n\n**key** *(optional)*  \nAn identifying string used to differentiate this node from others. Used internally by vtree/diff to do node reordering.\n\n**namespace** *(optional*)  \nA string specifying the namespace uri to associate with the element. VNodes created with a namespace will use [Document#createElementNS](https://developer.mozilla.org/en-US/docs/Web/API/document.createElementNS)\n\n### A full example\n```javascript\nvar VNode = require(\"virtual-dom\").VNode\nvar createElement = require(\"virtual-dom\").create\n\nvar Hook = function(){}\nHook.prototype.hook = function(elem, key, previousValue) {\n  console.log(\"Hello from \" + elem.id + \"!\\nMy key was: \" + key)\n}\n\nvar tagName = \"div\"\nvar style = \"width: 100px; height: 100px; background-color: #FF0000;\"\nvar attributes = {\"class\": \"red box\", style: style }\nvar key = \"my-unique-red-box\"\nvar namespace = \"http://www.w3.org/1999/xhtml\"\nvar properties = {\n  attributes: attributes,\n  id: \"my-red-box\",\n  \"a hook can have any property key\": new Hook()\n}\nvar childNode = new VNode(\"div\", {id: \"red-box-child\"})\n\nRedBoxNode = new VNode(tagName, properties, [childNode], key, namespace)\nRedBoxElem = createElement(RedBoxNode)\ndocument.body.appendChild(RedBoxElem)\n\n// Will result in html that looks like\n// <div class=\"red box\" style=\"width: 100px; height: 100px; background-color: #FF0000;\" id=\"my-red-box\">\n//   <div id=\"red-box-child\"></div>\n// </div>\n```\n\n\n### properties\nKeys in properties have several special cases. \n#### properties.attributes\nEverything in the `properties.attributes` object will be set on the rendered dom node using `Element#setAttribute(key, value)`, and removed using `Element#removeAttribute`. Refer to [MDN HTML Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes) for available attributes. \n\n#### Hook Objects\nAny key whose value is an object with an inherited key called \"hook\" is considered a hook. Hooks are used to run functions at render time. Refer to the [hook documentation](hooks.md) for more information.\n\n#### Other Objects\nAny key in `properties` that is an object, but whose value isn't a hook and isn't in the attributes key, will set the rendered elements property to the given object.\n\n```javascript\ncreateElement(new VNode('div', { style: { width: \"100px\", height: \"100px\"}}))\n// When added to the dom, the resulting element will look like <div style=\"width: 100px; height: 100px\"><div>\n```\n\n#### Other Values\nMost attributes can be set using properties. During element creation, keys and values in the `properties.attributes` get set using `Element#setAttribute(key, value)`, whereas keys other than `attributes` present in properties get set using `element[key] = value`.\n\n```javascript\nfoo = new VNode('div', { id: 'foo'})\n// will render the same as\nfoo = new VNode('div', { attributes: { id: 'foo' }})\n```\n\nThis can, however, cause some unexpected behavior, particularly if you are unfamiliar with the differences between setting an element property directly vs. setting it using an attribute. Refer to [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) and [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement) for some common property behaviors.\n\n#### properties.style vs properties.attributes.style\n`properties.style` expects an object, while `properties.attributes.style` expects a string.\n\n```javascript\n// using attributes\nvar redBox = new VNode('div', { attributes: { style: \"width: 100px; height: 100px; background-color: #FF0000;\" }})\n// using a property\nvar anotherRedBox = new VNode('div', { style: { width: \"100px\", height: \"100px\", backgroundColor: \"#FF0000\" }})\n```\n\nWhen using `properties.style`, if the styles have changed since the last render and are being updated, keys that are not in the new style definition will be set to an empty string. This differs from the normal behavior, which sets old object keys to undefined.\n\n#### properties.className vs properties.attributes.class\nSet the class attribute value using `className` key in properties, and the `class` key in attributes.\n\n```javascript\nvar redBox = new VNode('div', { className: \"red box\" })\n// will render the same as\nvar anotherRedBox = new VNode('div', { attributes: { \"class\": \"red box\" }})\n```\n\n#### Custom attributes (data-\\*)\nCustom attributes won't be rendered if set directly in properties. Set them in properties.attributes.\n\n```javascript\nvar doThis = new VNode('div', { attributes: { \"data-example\": \"I will render\" }})\nvar notThis = new VNode('div', { \"data-example\": \"I will not render\" })\n```\n\nAlternately, you can use the [dataset](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.dataset) property to set data-\\* attributes.\n\n```javascript\nnew VNode('div', { attributes: { \"data-greeting\": \"Hello\" }})\nnew VNode('div', { dataset: { greeting: \"Hello\" }})\n// Will both generate <div data-greeting=\"Hello\"></div>\n```\n\n#### ARIA attributes\nLike custom attributes, ARIA attributes are also set in `properties.attributes`.\n\n```javascript\nvar ariaExample = new VNode('div', { attributes: { \"aria-checked\": \"true\" }})\n```\n\nUnlike data-\\* attributes, they cannot be set directly via properties.\n\n#### properties.value, properties.defaultValue, and properties.attributes.value\nIf an input element is reset, its value will be returned to its value set in `properties.attributes.value`. If you've set the value using `properties.value`, this will not happen. However, you may set `properties.defaultValue` to get the desired result.\n"
  },
  {
    "path": "docs/vtext.md",
    "content": "# VText\nVText is a representation of a Text node. \n\nIn virtual-dom, a VText is turned into an actual text node with the `createElement` function. You can read the code at [vdom/create-element](https://github.com/Matt-Esch/virtual-dom/blob/master/vdom/create-element.js)\n\n`createElement` turns a VText into a Text node using [document#createTextNode](https://developer.mozilla.org/en-US/docs/Web/API/document.createTextNode). \n\n## Full Example\n```javascript\nvar createElement = require(\"virtual-dom\").create\nvar VNode = require(\"virtual-dom/vnode/vnode\")\nvar VText = require(\"virtual-dom/vnode/vtext\")\nvar myText = new VText(\"Hello, World\")\n\n// Pass our VText as a child of our VNode\nvar myNode = new VNode(\"div\", { id: \"my-node\" }, [myText])\n\nvar myElem = createElement(myNode)\ndocument.body.appendChild(myElem)\n// Will result in a dom string that looks like <div id=\"my-node\">Hello, World</div>\n```\n\n## Arguments\n**text**  \nThe string you would like the text node to contain.\n\n## HTML Injection\n`document#createTextNode` will defend against HTML injection. You could use the innerHTML property, but it will most likely break virtual dom.\n\n```javascript\nescapedText = new VText('<span>Example</span>')\nescapedNode = new VNode('div', null, [escapedText])\n// Will enter the dom as <div>&lt;span&gt;Example&lt;/span&gt;</div>\n\nunescapedNode = new VNode('div', { innerHTML: \"<span>Example</span>\" })\n// Will enter the dom as <div><span>Example</span></div>\n// You should probably never do this\n```\n"
  },
  {
    "path": "docs/widget.md",
    "content": "# Widget\nWidgets are used to take control of the patching process, allowing the user to create stateful components, control sub-tree rendering, and hook into element removal.\n\n## Widget Interface\n**type**  \nMust be the string \"Widget\"\n\n**init**  \nThe function called when the widget is being created. Should return a DOM Element.\n\n**update**  \nThe function called when the widget is being updated.\n\n**destroy**  \nThe function called when the widget is being removed from the dom.\n\n```javascript\n// Boilerplate widget\nvar Widget = function (){}\nWidget.prototype.type = \"Widget\"\nWidget.prototype.init = function(){}\nWidget.prototype.update = function(previous, domNode){}\nWidget.prototype.destroy = function(domNode){}\n```\n\n### Update Arguments\nThe arguments passed to `Widget#update`\n\n**previous**  \nThe previous Widget\n\n**domNode**  \nThe previous DOM Element associated with this widget\n\n### Destroy Argument\nThe argument passed to `Widget#destroy`\n\n**domNode**  \nThe HTMLElement associated with the widget that will be removed\n\n## Full Example\nThis example demonstrates one way to pass local component state and use `init`, `update`, and `destroy` to create a widget that counts each time it tries to update, only showing the odd numbers.\n\n```javascript\nvar diff = require(\"virtual-dom\").diff\nvar patch = require(\"virtual-dom\").patch\nvar h = require(\"virtual-dom\").h\nvar createElement = require(\"virtual-dom\").create\n\nvar OddCounterWidget = function() {}\nOddCounterWidget.prototype.type = \"Widget\"\nOddCounterWidget.prototype.count = 1\nOddCounterWidget.prototype.init = function() {\n  // With widgets, you can use any method you would like to generate the DOM Elements.\n  // We could get the same result using:\n  // return createElement(h(\"div\", \"Count is: \" + this.count))\n  var divElem = document.createElement(\"div\")\n  var textElem = document.createTextNode(\"Count is: \" + this.count)\n  divElem.appendChild(textElem)\n  return divElem\n}\n\nOddCounterWidget.prototype.update = function(previous, domNode) {\n  this.count = previous.count + 1\n  // Only re-render if the current count is odd\n  if (this.count % 2) {\n    // Returning a new element from widget#update\n    // will replace the previous node\n    return this.init()\n  }\n  return null\n}\n\nOddCounterWidget.prototype.destroy = function(domNode) {\n  // While you can do any cleanup you would like here,\n  // we don't really have to do anything in this case.\n  // Instead, we'll log the current count\n  console.log(this.count)\n}\n\nvar myCounter = new OddCounterWidget()\nvar currentNode = myCounter\nvar rootNode = createElement(currentNode)\n\n// A simple function to diff your widgets, and patch the dom\nvar update = function(nextNode) {\n  var patches = diff(currentNode, nextNode)\n  rootNode = patch(rootNode, patches)\n  currentNode = nextNode\n}\n\ndocument.body.appendChild(rootNode)\nsetInterval(function(){\n  update(new OddCounterWidget())\n}, 1000)\n```\n"
  },
  {
    "path": "docs.jsig",
    "content": "--  A VHook is an object with a hook and unhook method.\n--  A VHook can be used to define your own apply property logic.\n--\n--  When a hook is found in the VProperties object in either\n--      `patch()` or `createElement()`, instead of setting\n--      or unsetting the property we will invoke `hook()` or\n--      `unhook()` respectively so you can define what setting\n--      and unsetting a property means.\ntype VHook : {\n    hook: (node: DOMElement, propertyName: String) => void,\n    unhook: (node: DOMElement, propertyName: String) => void\n}\n\ntype VPropertyName : String\ntype VPropertyValue : String | Boolean | Number\n\n--  A VProperties is a data structure that represents the\n--      set of properties that can be attached to a virtual node\n--\n--  Properties can be many things. The simplest case is a string\n--      property name and string or bool or number property value\n--\n--  You can also have hooks in your properties. You give a\n--      string hook name and a hook value. The hook will then\n--      be invoked as part of `patch()` and `createElement()`\n--      which allows you to set custom properties.\n--\n--  Next up, attributes and style are treated slightly\n--      differently. These keys are expected to have objects\n--      of string keys and string values and will have the\n--      correct `patch()` and `createElement()` logic for\n--      setting attributes and styles.\n--\n--  Finally properties can also have nested arbitrary objects\n--      of some key name to some value that is an object of\n--      string to bool or number or string.\ntype VProperties :\n    Object<propName: VPropertyName, propValue: VPropertyValue> &\n    Object<hookName: String, hook: VHook> &\n    Object<\"attributes\",\n        Object<attrName: String, attrValue: String>> &\n    Object<\"style\",\n        Object<styleName: String, styleValue: String>> &\n    Object<String, Object<\n        nestedPropName: VPropertyName,\n        nestedPropValue: VPropertyValue\n    >\n\n--  A VNode is a data structure that represents a virtual node\n--      in a virtual tree.\n--\n--  A virtual node consists of a tagName, a set of properties\n--      and a list of children. It also has meta data attached,\n--      namely a key and a namespace.\ntype VNode : {\n    tagName: String,\n    properties: VProperties\n    children: Array<VTree>,\n    key: String | undefined,\n    namespace: String | null\n}\n\n--  A VText is a data structure representing a text node in\n--      a virtual tree.\ntype VText : {\n    text: String,\n    type: \"VirtualText\"\n}\n\n--  A Widget is a custom data structure for representing an\n--      object in a virtual tree.\n--\n--  A Widget allows you to fully specify the semantics of\n--      intitialization of the object, updating of the object\n--      and destruction of the object.\n--\n--  A Widget should generally be used for custom, performance\n--      critical code.\ntype Widget : {\n    type: \"Widget\",\n    init: () => DOMElement,\n    update: (previous: Widget, domNode: DOMElement) => void,\n    destroy: (node: DOMElement) => void\n}\n\n--  A Thunk is a custom data structure for representing an\n--      unevaluated node in a virtual tree.\n--\n--  A Thunk allows you to overwrite the semantics of `diff()`\n--      by implementing your own render method that takes the\n--      previous node in the previous virtual tree.\n--\n--  Inside `render()` you can check whether the previous node\n--      is conceptually the same as the current node and return\n--      `previous.vnode` instead of re-computing and recreating\n--      an equivelant vnode.\n--\n--  This allows you to implement caching in the virtual tree\n--      and has significant performance improvements\ntype Thunk : {\n    type: \"Thunk\",\n    vnode: VTree,\n    render: (previous: VTree | null) => VTree\n}\n\n--  A VTree is the union of all the types of nodes that can\n--      exist in a virtual tree.\ntype VTree : VText | VNode | Widget | Thunk\n\n--  A VPatch represents a patch object that is returned from\n--      `diff()`. This patch object can be applied to an\n--      existing DOM element tree.\ntype VPatch := {\n    type: Number,\n    vNode: VNode,\n    patch: Any,\n    type: 'VirtualPatch'\n}\n\nvirtual-dom/create-element : (vnode: VTree, opts: {\n    document?: DOMDocument,\n    warn?: Boolean\n}) => DOMElement | DOMTextNode\n\nvirtual-dom/diff : (left: VTree, right: VTree) => Array<VPatch>\n\nvirtual-dom/h : (\n    tagSelector: String,\n    properties?: {\n        key: String,\n        namespace: String\n    } & VProperties,\n    children?: Array<VTree> | Vtree | textContent: String\n) => VNode\n\nvirtual-dom/patch : (\n    rootNode: DOMElement,\n    patches: Array<VPatch>\n) => newRootNode: DOMElement\n"
  },
  {
    "path": "h.js",
    "content": "var h = require(\"./virtual-hyperscript/index.js\")\n\nmodule.exports = h\n"
  },
  {
    "path": "index.js",
    "content": "var diff = require(\"./diff.js\")\r\nvar patch = require(\"./patch.js\")\r\nvar h = require(\"./h.js\")\r\nvar create = require(\"./create-element.js\")\r\nvar VNode = require('./vnode/vnode.js')\r\nvar VText = require('./vnode/vtext.js')\r\n\r\nmodule.exports = {\r\n    diff: diff,\r\n    patch: patch,\r\n    h: h,\r\n    create: create,\r\n    VNode: VNode,\r\n    VText: VText\r\n}\r\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"virtual-dom\",\n  \"version\": \"2.1.1\",\n  \"description\": \"A batched diff-based DOM rendering strategy\",\n  \"keywords\": [\n    \"virtual\",\n    \"dom\",\n    \"vdom\",\n    \"vtree\",\n    \"diff\",\n    \"patch\",\n    \"browser\"\n  ],\n  \"author\": \"Matt-Esch <matt@mattesch.info>\",\n  \"repository\": \"git://github.com/Matt-Esch/virtual-dom.git\",\n  \"main\": \"index\",\n  \"homepage\": \"https://github.com/Matt-Esch/virtual-dom\",\n  \"contributors\": [\n    {\n      \"name\": \"Matt-Esch\"\n    }\n  ],\n  \"bugs\": {\n    \"url\": \"https://github.com/Matt-Esch/virtual-dom/issues\",\n    \"email\": \"matt@mattesch.info\"\n  },\n  \"dependencies\": {\n    \"browser-split\": \"0.0.1\",\n    \"error\": \"^4.3.0\",\n    \"ev-store\": \"^7.0.0\",\n    \"global\": \"^4.3.0\",\n    \"is-object\": \"^1.0.1\",\n    \"next-tick\": \"^0.2.2\",\n    \"x-is-array\": \"0.1.0\",\n    \"x-is-string\": \"0.1.0\"\n  },\n  \"devDependencies\": {\n    \"browserify\": \"^9.0.7\",\n    \"istanbul\": \"^0.3.13\",\n    \"min-document\": \"^2.14.0\",\n    \"opn\": \"^1.0.1\",\n    \"run-browser\": \"^2.0.2\",\n    \"tap-dot\": \"^1.0.0\",\n    \"tap-spec\": \"^3.0.0\",\n    \"tape\": \"^4.0.0\",\n    \"zuul\": \"^2.1.1\"\n  },\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"test\": \"node ./test/index.js | tap-spec\",\n    \"dot\": \"node ./test/index.js | tap-dot\",\n    \"start\": \"node ./index.js\",\n    \"cover\": \"istanbul cover --report html --print detail ./test/index.js\",\n    \"view-cover\": \"istanbul report html && opn ./coverage/index.html\",\n    \"browser\": \"run-browser test/index.js\",\n    \"phantom\": \"run-browser test/index.js -b | tap-spec\",\n    \"dist\": \"browserify --standalone virtual-dom index.js > dist/virtual-dom.js\",\n    \"travis-test\": \"npm run phantom && npm run cover && istanbul report lcov && ((cat coverage/lcov.info | coveralls) || exit 0)\",\n    \"release\": \"npm run release-patch\",\n    \"release-patch\": \"git checkout master && npm version patch && git push origin master --tags && npm publish\",\n    \"release-minor\": \"git checkout master && npm version minor && git push origin master --tags && npm publish\",\n    \"release-major\": \"git checkout master && npm version major && git push origin master --tags && npm publish\"\n  },\n  \"testling\": {\n    \"files\": \"test/*.js\",\n    \"browsers\": [\n      \"ie/8..latest\",\n      \"firefox/17..latest\",\n      \"firefox/nightly\",\n      \"chrome/22..latest\",\n      \"chrome/canary\",\n      \"opera/12..latest\",\n      \"opera/next\",\n      \"safari/5.1..latest\",\n      \"ipad/6.0..latest\",\n      \"iphone/6.0..latest\",\n      \"android-browser/4.2..latest\"\n    ]\n  }\n}\n"
  },
  {
    "path": "patch.js",
    "content": "var patch = require(\"./vdom/patch.js\")\n\nmodule.exports = patch\n"
  },
  {
    "path": "test/attributes.js",
    "content": "var test = require(\"tape\")\r\n\r\nvar h = require(\"../h.js\")\r\nvar createElement = require(\"../create-element.js\")\r\nvar diff = require(\"../diff.js\")\r\nvar patch = require(\"../patch.js\")\r\n\r\ntest(\"attributes can be set\", function (assert) {\r\n    var leftTree = h(\"div\")\r\n\r\n    var rightTree = h(\"div\",{\r\n        attributes: {\r\n            src: \"test.jpg\"\r\n        }\r\n    })\r\n\r\n    var rootNode = createElement(leftTree)\r\n    var patches = diff(leftTree, rightTree)\r\n\r\n    var newRootNode = patch(rootNode, patches)\r\n\r\n    assert.equal(newRootNode.getAttribute(\"src\"), \"test.jpg\")\r\n    assert.end()\r\n})\r\n\r\ntest(\"individual attributes can be unset\", function (assert) {\r\n    var leftTree = h(\"div\", {\r\n        attributes: {\r\n            a: \"1\",\r\n            b: \"2\",\r\n            c: \"3\"\r\n        }\r\n    })\r\n\r\n    var rightTree = h(\"div\", {\r\n        attributes: {\r\n            a: \"1\",\r\n            c: \"3\"\r\n        }\r\n    })\r\n\r\n    var rootNode = createElement(leftTree)\r\n    var patches = diff(leftTree, rightTree)\r\n\r\n    var newRootNode = patch(rootNode, patches)\r\n\r\n    assert.equal(newRootNode, rootNode)\r\n    assert.equal(newRootNode.getAttribute(\"a\"), \"1\")\r\n    assert.ok(newRootNode.getAttribute(\"b\") == null)\r\n    assert.equal(newRootNode.getAttribute(\"c\"), \"3\")\r\n    assert.end()\r\n})\r\n\r\ntest(\"attributes can be completely unset\", function (assert) {\r\n    var leftTree = h(\"div\", {\r\n        attributes: {\r\n            a: \"1\",\r\n            b: \"2\",\r\n            c: \"3\"\r\n        }\r\n    })\r\n\r\n    var rightTree = h(\"div\")\r\n\r\n    var rootNode = createElement(leftTree)\r\n    var patches = diff(leftTree, rightTree)\r\n\r\n\r\n    var newRootNode = patch(rootNode, patches)\r\n\r\n    assert.equal(newRootNode, rootNode)\r\n    assert.ok(newRootNode.getAttribute(\"a\") == null)\r\n    assert.ok(newRootNode.getAttribute(\"b\") == null)\r\n    assert.ok(newRootNode.getAttribute(\"c\") == null)\r\n    assert.end()\r\n})\r\n"
  },
  {
    "path": "test/hook.js",
    "content": "var test = require(\"tape\")\n\nvar h = require(\"../h.js\")\nvar Node = require(\"../vnode/vnode.js\")\nvar create = require(\"../create-element.js\")\nvar diff = require(\"../diff.js\")\nvar patch = require(\"../patch.js\")\nvar patchCount = require(\"./lib/patch-count.js\")\n\ntest(\"Stateful hooks are added to a hooks object on a node\", function (assert) {\n    function StatefulHook() {}\n    StatefulHook.prototype.hook = function () {}\n    StatefulHook.prototype.unhook = function () {}\n    var statefulValue = new StatefulHook()\n\n    function StatelessHook() {}\n    StatelessHook.prototype.hook = function () {}\n    var statelessValue = new StatelessHook()\n\n    var node = new Node(\"div\", {\n        stateful: statefulValue,\n        stateless: statelessValue,\n        value: \"not a hook\"\n    }, [], null, null)\n\n    assert.equal(node.hooks.stateful, statefulValue)\n    assert.equal(node.hooks.stateless, undefined)\n    assert.equal(node.descendantHooks, false)\n    assert.end()\n})\n\ntest(\"Node child stateless hooks are not identified\", function (assert) {\n    function Prop() {}\n    Prop.prototype.hook = function () {}\n    var propValue = new Prop()\n\n    var node = new Node(\"div\", {\n        \"id\": propValue,\n        \"value\": \"not a hook\"\n    }, [], undefined, undefined)\n\n    var parentNode = new Node(\"div\", {\n        \"id\": \"not a hook\"\n    }, [node], undefined, undefined)\n\n    assert.equal(node.hooks, undefined)\n    assert.equal(parentNode.hooks, undefined)\n    assert.notOk(parentNode.descendantHooks)\n    assert.end()\n})\n\ntest(\"Node child stateful hooks are identified\", function (assert) {\n    function Prop() {}\n    Prop.prototype.hook = function () {}\n    Prop.prototype.unhook = function () {}\n    var propValue = new Prop()\n\n    var node = new Node(\"div\", {\n        \"id\": propValue,\n        \"value\": \"not a hook\"\n    }, [], undefined, undefined)\n\n    var parentNode = new Node(\"div\", {\n        \"id\": \"not a hook\"\n    }, [node], undefined, undefined)\n\n    assert.equal(node.hooks.id, propValue)\n    assert.equal(parentNode.hooks, undefined)\n    assert.ok(parentNode.descendantHooks)\n    assert.end()\n})\n\ntest(\"hooks get called in render\", function (assert) {\n    var counter = 0\n    var vtree = h(\"div\", {\n        \"some-key\": hook(function (elem, prop) {\n            counter++\n            assert.equal(prop, \"some-key\")\n            assert.equal(elem.tagName, \"DIV\")\n\n            elem.className = \"bar\"\n        })\n    })\n\n    var elem = create(vtree)\n    assert.equal(elem.className, \"bar\")\n    assert.equal(counter, 1)\n\n    assert.end()\n})\n\ntest(\"functions are not hooks in render\", function (assert) {\n    var counter = 0\n    var fakeHook = function () {\n        counter++\n    }\n    var vtree = h(\"div\", {\n        \"someProp\": fakeHook\n    })\n\n    var elem = create(vtree)\n    assert.equal(elem.someProp, fakeHook)\n    assert.equal(counter, 0)\n\n    assert.end()\n})\n\ntest(\"hooks get called in patch\", function (assert) {\n    var counter = 0\n    var prev = h(\"div\")\n    var curr = h(\"div\", {\n        \"some-key\": hook(function (elem, prop) {\n            counter++\n            assert.equal(prop, \"some-key\")\n            assert.equal(elem.tagName, \"DIV\")\n\n            elem.className = \"bar\"\n        })\n    })\n\n    var elem = createAndPatch(prev, curr)\n    assert.equal(elem.className, \"bar\")\n    assert.equal(counter, 1)\n\n    assert.end()\n})\n\ntest(\"hooks are called with DOM node, property name, and previous/next value\", function (assert) {\n    function Hook(name) {\n        this.name = name\n        this.hookArgs = []\n        this.unhookArgs = []\n    }\n    Hook.prototype.hook = function() {\n      this.hookArgs.push([].slice.call(arguments, 0))\n    }\n    Hook.prototype.unhook = function() {\n      this.unhookArgs.push([].slice.call(arguments, 0))\n    }\n\n    var hook1 = new Hook('hook1')\n    var hook2 = new Hook('hook2')\n\n    var first = h(\"div\", { id: 'first', hook: hook1 })\n    var second = h(\"div\", { id: 'second', hook: hook2 })\n    var third = h(\"div\")\n\n    var elem = create(first)\n    assert.equal(hook1.hookArgs.length, 1)\n    assert.deepEqual(hook1.hookArgs[0], [elem, 'hook', undefined])\n    assert.equal(hook1.unhookArgs.length, 0)\n\n    var patches = diff(first, second)\n    elem = patch(elem, patches)\n    assert.equal(hook2.hookArgs.length, 1)\n    assert.deepEqual(hook2.hookArgs[0], [elem, 'hook', hook1])\n    assert.equal(hook1.unhookArgs.length, 1)\n    assert.deepEqual(hook1.unhookArgs[0], [elem, 'hook', hook2])\n\n    patches = diff(second, third)\n    elem = patch(elem, patches)\n    assert.equal(hook2.hookArgs.length, 1)\n    assert.equal(hook2.unhookArgs.length, 1)\n    assert.deepEqual(hook2.unhookArgs[0], [elem, 'hook', undefined])\n\n    assert.end()\n})\n\ntest(\"functions are not hooks in render\", function (assert) {\n    var counter = 0\n    var fakeHook = function () {\n        counter++\n    }\n\n    var prev = h(\"div\")\n    var curr = h(\"div\", { someProp: fakeHook })\n\n    var elem = createAndPatch(prev, curr)\n    assert.equal(elem.someProp, fakeHook)\n    assert.equal(counter, 0)\n\n    assert.end()\n})\n\ntest(\"two different hooks\", function (assert) {\n    var counters = { a: 0, b: 0 }\n    var prev = h(\"div\", { propA: hook(function () {\n        counters.a++\n    }) })\n    var curr = h(\"div\", { propB: hook(function () {\n        counters.b++\n    }) })\n\n    var elem = createAndPatch(prev, curr)\n    assert.equal(elem.propA, undefined)\n    assert.equal(elem.propB, null)\n    assert.equal(counters.a, 1)\n    assert.equal(counters.b, 1)\n\n    assert.end()\n})\n\ntest(\"two hooks on same property\", function (assert) {\n    var counters = { a: 0, b: 0 }\n    var prev = h(\"div\", { propA: hook(function () {\n        counters.a++\n    }) })\n    var curr = h(\"div\", { propA: hook(function () {\n        counters.b++\n    }) })\n\n    var elem = createAndPatch(prev, curr)\n    assert.equal(elem.propA, undefined)\n    assert.equal(counters.a, 1)\n    assert.equal(counters.b, 1)\n\n    assert.end()\n})\n\ntest(\"two hooks of same interface\", function (assert) {\n    function Hook(key) {\n        this.key = key\n    }\n    Hook.prototype.hook = function () {\n        counters[this.key]++\n    }\n\n    var counters = { a: 0, b: 0 }\n    var prev = h(\"div\", { propA: new Hook(\"a\") })\n    var curr = h(\"div\", { propA: new Hook(\"b\") })\n\n    var elem = createAndPatch(prev, curr)\n    assert.equal(elem.propA, undefined)\n    assert.equal(counters.a, 1, \"counters.a\")\n    assert.equal(counters.b, 1, \"counters.b\")\n\n    assert.end()\n})\n\ntest(\"hooks are not called on trivial diff\", function (assert) {\n    var counters = {\n        a: 0,\n        b: 0,\n        c: 0\n    }\n\n    var vnode = h(\"div\", {\n        test: hook(function () {\n            counters.a++\n        })\n    }, [\n        h(\"div\", { test: hook(function () { counters.b++ }) }),\n        h(\"div\", { test: hook(function () { counters.c++ }) })\n    ])\n\n    var rootNode = create(vnode)\n    assert.equal(counters.a, 1, \"counters.a\")\n    assert.equal(counters.b, 1, \"counters.b\")\n    assert.equal(counters.c, 1, \"counters.c\")\n\n    var patches = diff(vnode, vnode)\n    assert.equal(patchCount(patches), 0)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n    assert.equal(counters.a, 1, \"counters.a patch\")\n    assert.equal(counters.b, 1, \"counters.b patch\")\n    assert.equal(counters.c, 1, \"counters.c patch\")\n    assert.end()\n})\n\ntest(\"property-replacing diff calls unhook\", function (assert) {\n  unhookCallCount = 0\n\n  function zhook(x) {\n    this.x = x\n  }\n  zhook.prototype.hook = function () {\n    return null\n  }\n\n  zhook.prototype.unhook = function () {\n    unhookCallCount += 1\n  }\n\n  hooker = new zhook('ONE')\n  hooker2 = new zhook('TWO')\n\n  var firstTree = h(\"div\", {roothook: hooker})\n  var secondTree = h(\"div\", {roothook: hooker2})\n  var thirdTree = h(\"span\")\n\n  var rootNode = create(firstTree)\n\n  var firstPatches = diff(firstTree, secondTree)\n  rootNode = patch(rootNode, firstPatches)\n\n\n  var secondPatches = diff(secondTree, thirdTree)\n  rootNode = patch(rootNode, secondPatches)\n\n  assert.strictEqual(unhookCallCount, 2, \"Missing unhook calls\")\n\n  assert.end()\n})\n\ntest(\"unhook-only hook is a valid hook\", function (assert) {\n    var unhookCalled = false;\n\n    function UnhookHook() {}\n\n    UnhookHook.prototype.unhook = function() {\n        unhookCalled = true\n    }\n\n    var hook = new UnhookHook()\n\n    var firstTree = h('div', {hook: hook})\n    var secondTree = h('div', {})\n\n    var rootNode = create(firstTree)\n\n    assert.notOk(unhookCalled)\n\n    var patches = diff(firstTree, secondTree)\n    rootNode = patch(rootNode, patches)\n\n    assert.ok(unhookCalled)\n    assert.end()\n})\n\ntest(\"all hooks are unhooked\", function (assert) {\n    var hookCounts = {}\n    var unhookCounts = {}\n\n    function Hook(value) {\n        if (!(this instanceof Hook)) {\n            return new Hook(value)\n        }\n        this.value = value\n    }\n\n    Hook.prototype.hook = function hook() {\n        var key = this.value\n        if (key in hookCounts) {\n            hookCounts[key]++\n        } else {\n            hookCounts[key] = 1;\n        }\n    }\n\n    Hook.prototype.unhook = function unhook() {\n        var key = this.value;\n        if (key in unhookCounts) {\n            unhookCounts[key]++\n        } else {\n            unhookCounts[key] = 1;\n        }\n    }\n\n    var rootHook = Hook(\"rootHook\")\n    var childHookA = Hook(\"childHookA\")\n    var childHookB = Hook(\"childHookB\")\n    var childHookC = Hook(\"childHookC\")\n    var thunkyRootHook = Hook(\"thunkyRootHook\")\n    var thunkyChildHookA = Hook(\"thunkyChildHookA\")\n    var thunkyChildHookB = Hook(\"thunkyChildHookB\")\n    var thunkyChildHookC = Hook(\"thunkyChildHookC\")\n\n    function Thunky() {}\n\n    Thunky.prototype.render = function () {\n        return h(\"div\", {\n            rootHook: thunkyRootHook\n        }, [\n            h(\"div\", {\n                childHook: thunkyChildHookA\n            }),\n            h(\"div\", {\n                childHook: thunkyChildHookB\n            }),\n            h(\"div\", {\n                childHook: thunkyChildHookC\n            })\n        ])\n    }\n\n    Thunky.prototype.type = \"Thunk\"\n\n\n    var firstTree = h(\"div\", {\n        rootHook: rootHook\n    }, [\n        h(\"div\", {\n            childHook: childHookA\n        }),\n        h(\"div\", {\n            childHook: childHookB\n        }, [\n            new Thunky()\n        ]),\n        h(\"div\", {\n            childHook: childHookC\n        })\n    ])\n\n    var secondTree = h(\"div\", {\n        rootHook: rootHook\n    }, [\n        h(\"div\", {\n            childHook: childHookA\n        }),\n        h(\"div\", {\n            childHook: childHookB\n        }, [\n            new Thunky()\n        ]),\n        h(\"div\", {\n            childHook: childHookC\n        })\n    ])\n\n    var thirdTree = h('span')\n\n    var rootNode = create(firstTree)\n\n    assertHooked();\n\n    var firstPatches = diff(firstTree, secondTree)\n\n    assertHooked();\n\n    assert.strictEqual(patchCount(firstPatches), 0, \"No patches for identical\")\n    rootNode = patch(rootNode, firstPatches)\n\n    assertHooked();\n\n    var secondPatches = diff(secondTree, thirdTree)\n\n    assertHooked();\n\n    // Expect 1 root patch, 3 unhook patches and a thunk patch\n    assert.strictEqual(patchCount(secondPatches), 5, \"Expect unhook patches\")\n\n    rootNode = patch(rootNode, secondPatches)\n\n    assertUnhooked()\n\n    assert.end()\n\n    function assertHooked() {\n        assert.strictEqual(hookCounts.rootHook, 1)\n        assert.strictEqual(hookCounts.childHookA, 1)\n        assert.strictEqual(hookCounts.childHookB, 1)\n        assert.strictEqual(hookCounts.childHookC, 1)\n        assert.strictEqual(hookCounts.thunkyRootHook, 1)\n        assert.strictEqual(hookCounts.thunkyChildHookA, 1)\n        assert.strictEqual(hookCounts.thunkyChildHookB, 1)\n        assert.strictEqual(hookCounts.thunkyChildHookC, 1)\n        assert.strictEqual(unhookCounts.rootHook, undefined)\n        assert.strictEqual(unhookCounts.childHookA, undefined)\n        assert.strictEqual(unhookCounts.childHookB, undefined)\n        assert.strictEqual(unhookCounts.childHookC, undefined)\n        assert.strictEqual(unhookCounts.thunkyRootHook, undefined)\n        assert.strictEqual(unhookCounts.thunkyChildHookA, undefined)\n        assert.strictEqual(unhookCounts.thunkyChildHookB, undefined)\n        assert.strictEqual(unhookCounts.thunkyChildHookC, undefined)\n    }\n\n    function assertUnhooked() {\n        assert.strictEqual(hookCounts.rootHook, 1)\n        assert.strictEqual(hookCounts.childHookA, 1)\n        assert.strictEqual(hookCounts.childHookB, 1)\n        assert.strictEqual(hookCounts.childHookC, 1)\n        assert.strictEqual(hookCounts.thunkyRootHook, 1)\n        assert.strictEqual(hookCounts.thunkyChildHookA, 1)\n        assert.strictEqual(hookCounts.thunkyChildHookB, 1)\n        assert.strictEqual(hookCounts.thunkyChildHookC, 1)\n        assert.strictEqual(unhookCounts.rootHook, 1)\n        assert.strictEqual(unhookCounts.childHookA, 1)\n        assert.strictEqual(unhookCounts.childHookB, 1)\n        assert.strictEqual(unhookCounts.childHookC, 1)\n        assert.strictEqual(unhookCounts.thunkyRootHook, 1)\n        assert.strictEqual(unhookCounts.thunkyChildHookA, 1)\n        assert.strictEqual(unhookCounts.thunkyChildHookB, 1)\n        assert.strictEqual(unhookCounts.thunkyChildHookC, 1)\n    }\n})\n\nfunction createAndPatch(prev, curr) {\n    var elem = create(prev)\n    var patches = diff(prev, curr)\n    elem = patch(elem, patches)\n\n    return elem\n}\n\nfunction Type(fn) {\n    this.fn = fn\n}\n\nType.prototype.hook = function () {\n    this.fn.apply(this, arguments)\n}\n\nfunction hook(fn) {\n    return new Type(fn)\n}\n"
  },
  {
    "path": "test/index.js",
    "content": "require(\"./main.js\")\nrequire(\"./hook.js\")\nrequire(\"./nested-properties.js\")\nrequire(\"./undefined-properties.js\")\nrequire(\"./keys.js\")\nrequire(\"./thunk.js\")\nrequire(\"./style.js\")\nrequire(\"./attributes\")\nrequire(\"./non-string.js\")\n\nrequire(\"../vdom/test/\")\nrequire(\"../vtree/test/\")\nrequire(\"../virtual-hyperscript/test/\")\nrequire(\"../vnode/test/\")\n"
  },
  {
    "path": "test/keys.js",
    "content": "var test = require(\"tape\")\n\nvar h = require(\"../h.js\")\nvar diff = require(\"../diff.js\")\nvar patch = require(\"../patch.js\")\nvar render = require(\"../create-element.js\")\n\nvar patchCount = require(\"./lib/patch-count.js\")\nvar assertEqualDom = require(\"./lib/assert-equal-dom.js\")\nvar nodesFromArray = require(\"./lib/nodes-from-array.js\")\nvar assertChildNodesFromArray = require(\"./lib/assert-childNodes-from-array.js\")\n\nvar VPatch = require(\"../vnode/vpatch.js\")\n\ntest(\"keys get reordered\", function (assert) {\n    var leftNode = nodesFromArray([\"1\", \"2\", \"3\", \"4\", \"test\", \"6\", \"good\", \"7\"])\n    var rightNode = nodesFromArray([\"7\", \"4\", \"3\", \"2\", \"6\", \"test\", \"good\", \"1\"])\n\n    var rootNode = render(leftNode)\n\n    var childNodes = []\n    for (var i = 0; i < rootNode.childNodes.length; i++) {\n        childNodes.push(rootNode.childNodes[i])\n    }\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 1)\n    assertReorderEquals(assert, patches, {\n        removes: [\n            {from: 0, key: '1'},\n            {from: 0, key: '2'},\n            {from: 1, key: '4'},\n            {from: 2, key: '6'},\n            {from: 3, key: '7'}\n        ],\n        inserts: [\n            {to: 0, key: '7'},\n            {to: 1, key: '4'},\n            {to: 3, key: '2'},\n            {to: 4, key: '6'},\n            {to: 7, key: '1'}\n        ]\n    })\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, rootNode.childNodes.length)\n\n    assert.equal(newRoot.childNodes[7], childNodes[0])\n    assert.equal(newRoot.childNodes[3], childNodes[1])\n    assert.equal(newRoot.childNodes[2], childNodes[2])\n    assert.equal(newRoot.childNodes[1], childNodes[3])\n    assert.equal(newRoot.childNodes[5], childNodes[4])\n    assert.equal(newRoot.childNodes[4], childNodes[5])\n    assert.equal(newRoot.childNodes[6], childNodes[6])\n    assert.equal(newRoot.childNodes[0], childNodes[7])\n    assert.end()\n})\n\ntest(\"mix keys without keys\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\", { key: 1 }),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\", { key: 1 })\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 1)\n    assertReorderEquals(assert, patches, {\n        removes: [{from: 0, key: '1'}],\n        inserts: [{to: 7, key: '1'}]\n    })\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, rootNode.childNodes.length)\n\n    assert.equal(newRoot.childNodes[0], childNodes[1])\n    assert.equal(newRoot.childNodes[1], childNodes[2])\n    assert.equal(newRoot.childNodes[2], childNodes[3])\n    assert.equal(newRoot.childNodes[3], childNodes[4])\n    assert.equal(newRoot.childNodes[4], childNodes[5])\n    assert.equal(newRoot.childNodes[5], childNodes[6])\n    assert.equal(newRoot.childNodes[6], childNodes[7])\n    assert.equal(newRoot.childNodes[7], childNodes[0])\n    assert.end()\n})\n\ntest(\"avoid unnecessary reordering\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\"),\n        h(\"div\", { key: 1 }),\n        h(\"div\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\"),\n        h(\"div\", { key: 1 }),\n        h(\"div\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 0)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes[0], childNodes[0])\n    assert.equal(newRoot.childNodes[1], childNodes[1])\n    assert.equal(newRoot.childNodes[2], childNodes[2])\n    assert.end()\n})\n\ntest(\"missing key gets replaced\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\", { key: 1 }),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\"),\n        h(\"div\")\n    ])\n\n    var rootNode = render(leftNode)\n\n    var childNodes = []\n    for (var i = 0; i < rootNode.childNodes.length; i++) {\n        childNodes.push(rootNode.childNodes[i])\n    }\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 1)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, rootNode.childNodes.length)\n\n    assert.notEqual(newRoot.childNodes[0], childNodes[0])\n    assert.equal(newRoot.childNodes[1], childNodes[1])\n    assert.equal(newRoot.childNodes[2], childNodes[2])\n    assert.equal(newRoot.childNodes[3], childNodes[3])\n    assert.equal(newRoot.childNodes[4], childNodes[4])\n    assert.equal(newRoot.childNodes[5], childNodes[5])\n    assert.equal(newRoot.childNodes[6], childNodes[6])\n    assert.equal(newRoot.childNodes[7], childNodes[7])\n    assert.end()\n})\n\ntest(\"widgets can be keyed\", function (assert) {\n    function DivWidget(key, state) {\n        this.key = key\n        this.state = state\n    }\n\n    DivWidget.prototype.init = function () {\n        return render(h(\"div\", this.state))\n    }\n\n    DivWidget.prototype.update = function (rootNode, prev) {\n        if (this.state !== prev.state) {\n            return render(h(\"div\", this.state))\n        }\n    }\n\n    DivWidget.prototype.type = \"Widget\"\n\n    var leftNode = h(\"div\", [\n        new DivWidget(\"1\", \"a\"),\n        new DivWidget(\"2\", \"b\"),\n        new DivWidget(\"3\", \"c\")\n    ])\n\n    var rightNode = h(\"div\", [\n        new DivWidget(\"3\", \"c\"),\n        new DivWidget(\"2\", \"b\"),\n        new DivWidget(\"1\", \"a\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 4)    // 1 reorder and 3 update patches\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, rootNode.childNodes.length)\n\n    assertEqualDom(assert, newRoot.childNodes[0], childNodes[2])\n    assertEqualDom(assert, newRoot.childNodes[1], childNodes[1])\n    assertEqualDom(assert, newRoot.childNodes[2], childNodes[0])\n    assert.end()\n})\n\ntest(\"delete key at the start\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\", { key: \"a\" }, \"a\"),\n        h(\"div\", { key: \"b\" }, \"b\"),\n        h(\"div\", { key: \"c\" }, \"c\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\", { key: \"b\" }, \"b\"),\n        h(\"div\", { key: \"c\" }, \"c\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n    // just a remove patch\n    assert.equal(patchCount(patches), 1)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 2)\n\n    assert.equal(newRoot.childNodes[0], childNodes[1])\n    assert.equal(newRoot.childNodes[1], childNodes[2])\n    assert.end()\n})\n\ntest(\"add key to start\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\", { key: \"b\" }, \"b\"),\n        h(\"div\", { key: \"c\" }, \"c\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\", { key: \"a\" }, \"a\"),\n        h(\"div\", { key: \"b\" }, \"b\"),\n        h(\"div\", { key: \"c\" }, \"c\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 1)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 3)\n\n    assert.equal(newRoot.childNodes[1], childNodes[0])\n    assert.equal(newRoot.childNodes[2], childNodes[1])\n    assert.end()\n})\n\ntest(\"delete key at the end\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\", { key: \"a\" }, \"a\"),\n        h(\"div\", { key: \"b\" }, \"b\"),\n        h(\"div\", { key: \"c\" }, \"c\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\", { key: \"a\" }, \"a\"),\n        h(\"div\", { key: \"b\" }, \"b\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n    // just a remove patch\n    assert.equal(patchCount(patches), 1)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 2)\n\n    assert.equal(newRoot.childNodes[0], childNodes[0])\n    assert.equal(newRoot.childNodes[1], childNodes[1])\n    assert.end()\n})\n\ntest(\"add key to end\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\", { key: \"a\" }, \"a\"),\n        h(\"div\", { key: \"b\" }, \"b\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\", { key: \"a\" }, \"a\"),\n        h(\"div\", { key: \"b\" }, \"b\"),\n        h(\"div\", { key: \"c\" }, \"c\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 1)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 3)\n\n    assert.equal(newRoot.childNodes[0], childNodes[0])\n    assert.equal(newRoot.childNodes[1], childNodes[1])\n    assert.end()\n})\n\ntest(\"add to end and delete from center & reverse\", function (assert) {\n    var leftNode = h(\"div\", [\n        h(\"div\", { key: \"a\", id: \"a\" }, \"a\"),\n        h(\"div\", { key: \"b\", id: \"b\" }, \"b\"),\n        h(\"div\", { key: \"c\", id: \"c\" }, \"c\"),\n        h(\"div\", { key: \"d\", id: \"d\" }, \"d\")\n    ])\n\n    var rightNode = h(\"div\", [\n        h(\"div\", { key: \"e\", id: \"e\" }, \"e\"),\n        h(\"div\", { key: \"d\", id: \"d\" }, \"d\"),\n        h(\"div\", { key: \"c\", id: \"c\" }, \"c\"),\n        h(\"div\", { key: \"a\", id: \"a\" }, \"a\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 2)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 4)\n\n    assert.equal(newRoot.childNodes[1], childNodes[3])\n    assert.equal(newRoot.childNodes[2], childNodes[2])\n    assert.equal(newRoot.childNodes[3], childNodes[0])\n    assert.end()\n})\n\ntest(\"add to front and remove\", function (assert) {\n    var leftNode = h(\"ul\", [\n        h(\"li\", { key: \"c\" }, \"c\"),\n        h(\"li\", { key: \"d\" }, \"d\")\n    ])\n\n    var rightNode = h(\"ul\", [\n        h(\"li\", { key: \"a\" }, \"a\"),\n        h(\"li\", { key: \"b\" }, \"b\"),\n        h(\"li\", { key: \"c\" }, \"c\"),\n        h(\"li\", { key: \"e\" }, \"e\")\n    ])\n\n    var rootNode = render(leftNode)\n    var childNodes = childNodesArray(rootNode)\n\n    var patches = diff(leftNode, rightNode)\n\n    var newRoot = patch(rootNode, patches)\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 4)\n\n    assert.equal(newRoot.childNodes[2], childNodes[0])\n    assert.end()\n})\n\ntest(\"adding multiple widgets\", function (assert) {\n    function FooWidget(foo) {\n        this.foo = foo\n        this.counter = 0\n        this.key = foo\n    }\n\n    FooWidget.prototype.init = function () {\n        return render(h(\"div\", String(this.foo)))\n    }\n\n    FooWidget.prototype.update = function (prev, elem) {\n        this.counter = prev.counter + 1\n        elem.textContent = this.foo + this.counter\n    }\n\n    FooWidget.prototype.type = \"Widget\"\n\n    var firstTree = h(\"div\", [])\n    var rootNode = render(firstTree)\n\n    assert.equal(rootNode.tagName, \"DIV\")\n\n    var secondTree = h(\"div\", [\n        new FooWidget(\"foo\")\n    ])\n    rootNode = patch(rootNode, diff(firstTree, secondTree))\n\n    assert.equal(rootNode.tagName, \"DIV\")\n    assert.equal(rootNode.childNodes.length, 1)\n    assert.equal(rootNode.childNodes[0].tagName, \"DIV\")\n    assert.equal(rootNode.childNodes[0].childNodes[0].data, \"foo\")\n\n    var thirdTree = h(\"div\", [\n        new FooWidget(\"foo\"),\n        new FooWidget(\"bar\")\n    ])\n    rootNode = patch(rootNode, diff(secondTree, thirdTree))\n\n    assert.equal(rootNode.tagName, \"DIV\")\n    assert.equal(rootNode.childNodes.length, 2)\n\n    assert.end()\n})\n\nvar itemHelpers = {\n    item: function (key) {\n        key = key.toString()\n        return h('div', { key: key, id: key }, [\"\" + key])\n    },\n\n    container: function (children) {\n        return h('div', children)\n    },\n\n    itemsInContainer: function () {\n        return {\n            from: function (start) {\n                return {\n                    to: function (end) {\n                        function withPredicate(predicate) {\n                            var items = []\n                            for (var i = start; i <= end; i++) {\n                                if (!predicate(i)) continue\n                                items.push(itemHelpers.item(i))\n                            }\n                            return itemHelpers.container(items)\n                        }\n                        return {\n                            by: function (increment) {\n                                return withPredicate(function (i) {\n                                    return (i - start) % increment === 0\n                                })\n                            },\n                            withPredicate: withPredicate\n                        }\n                    }\n                }\n            }\n        }\n    },\n\n    expectTextOfChild: function (assert, rootNode, childNo, text) {\n        assert.equal(rootNode.childNodes[childNo].id, text)\n    }\n}\n\ntest('3 elements in a container, insert an element after each', function (assert) {\n    var threeItems = itemHelpers.itemsInContainer().from(0).to(4).by(2)\n    var sixItems = itemHelpers.itemsInContainer().from(0).to(5).by(1)\n\n    var rootNode = render(threeItems)\n    rootNode = patch(rootNode, diff(threeItems, sixItems))\n\n    for (var i = 0; i <= 5; i++) {\n        itemHelpers.expectTextOfChild(assert, rootNode, i, i.toString())\n    }\n\n    assert.end()\n})\n\ntest('10 elements in a container, remove every second element', function(assert) {\n    var  fiveItems = itemHelpers.itemsInContainer().from(0).to(9).by(2)\n    var tenItems = itemHelpers.itemsInContainer().from(0).to(9).by(1)\n\n    var rootNode = render(tenItems)\n    var patches = diff(tenItems, fiveItems)\n\n    // 5 remove patches only\n    assert.equal(patchCount(patches), 5)\n\n    rootNode = patch(rootNode, patches)\n\n    for (var i = 0; i < 5; i++) {\n        itemHelpers.expectTextOfChild(assert, rootNode, i, (i * 2).toString())\n    }\n\n    assert.end()\n})\n\ntest('3 elements in a container, add 3 elements after each', function (assert) {\n    var first = itemHelpers.itemsInContainer().from(0).to(11).by(4)\n    var second = itemHelpers.itemsInContainer().from(0).to(11).by(1)\n\n    // Assert indices before\n    assert.strictEqual(first.children.length, 3)\n\n    var rootNode = render(first)\n\n    for (var i = 0; i < 3; i++) {\n        itemHelpers.expectTextOfChild(assert, rootNode, i, (4*i).toString())\n    }\n\n    // Assert indices after\n    assert.strictEqual(second.children.length, 12)\n\n    var newRoot = patch(rootNode, diff(first, second))\n\n    for (var j = 0; j < 12; j++) {\n        itemHelpers.expectTextOfChild(assert, newRoot, j, j.toString())\n    }\n\n    assert.end()\n})\n\ntest('10 in container, add 1 after every 2nd element', function (assert) {\n    function skipEveryThird(i) {\n        return i % 3 === 0 || i % 3 === 1\n    }\n\n    var first = itemHelpers\n        .itemsInContainer()\n        .from(0)\n        .to(14)\n        .withPredicate(skipEveryThird)\n\n    var second = itemHelpers.itemsInContainer().from(0).to(14).by(1)\n\n    // Assert indices before\n    assert.strictEqual(first.children.length, 10)\n\n    var rootNode = render(first)\n    var expectedIndices = [0, 1, 3, 4, 6, 7, 9, 10, 12, 13]\n\n    for (var i = 0; i < 10; i++) {\n        itemHelpers.expectTextOfChild(\n            assert, rootNode, i, expectedIndices[i].toString()\n        )\n    }\n\n    // Assert indices after\n    assert.strictEqual(second.children.length, 15)\n\n    var patches = diff(first, second)\n\n    var newRoot = patch(rootNode, patches)\n\n    for (var j = 0; j < 15; j++) {\n        itemHelpers.expectTextOfChild(assert, newRoot, j, j.toString())\n    }\n\n    assert.end()\n})\n\ntest('move a single element to the end', function (assert) {\n    var start = nodesFromArray([0, 5, 1, 2, 3, 4])\n    var end = nodesFromArray([0, 1, 2, 3, 4, 5])\n\n    var patches = diff(start, end)\n\n    assertReorderEquals(assert, patches, {\n        removes: [{key: '5', from: 1}],\n        inserts: [{key: '5', to: 5}]\n    })\n    assert.end()\n})\n\ntest('move a single element to a later position', function (assert) {\n    var start = nodesFromArray([0, 4, 1, 2, 3, 5])\n    var end = nodesFromArray([0, 1, 2, 3, 4, 5])\n\n    var patches = diff(start, end)\n\n    assertReorderEquals(assert, patches, {\n        removes: [{ key: '4', from: 1 }],\n        inserts: [{ key: '4', to: 4 }]\n    })\n    assert.end()\n})\n\ntest('remove a single element from early in the list', function (assert) {\n    var start = nodesFromArray([0, 1, 2, 3, 4])\n    var end = nodesFromArray([0, 2, 3, 4])\n\n    var patches = diff(start, end)\n\n    var reorderPatch = getReorderPatch(patches)\n    assert.strictEqual(reorderPatch, null)\n    assert.end()\n})\n\ntest('move an element to a position after a removed element', function (assert) {\n    var start = nodesFromArray([0, 1, 2, 3, 4, 5])\n    var end = nodesFromArray([0, 2, 3, 5, 4])\n\n    var patches = diff(start, end)\n\n    assertReorderEquals(assert, patches, {\n        removes: [\n            {from: 1, key: null},\n            {from: 4, key: '5'}\n        ],\n        inserts: [{to: 3, key: '5'}]\n    })\n    assert.end()\n})\n\ntest('mixed keys move from i>0 to i<length-1', function (assert) {\n    var start = nodesFromArray([undefined, undefined, 'key', undefined, undefined, undefined])\n    var end = nodesFromArray([undefined, undefined, undefined, undefined, 'key', undefined])\n\n    var patches = diff(start, end)\n\n    assertReorderEquals(assert, patches, {\n        removes: [{from: 2, key: 'key'}],\n        inserts: [{to: 4, key: 'key'}]\n    })\n    assert.end()\n})\n\n/*\nkeyTest(\n    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42],\n    [41, 3, 34, 36, 1, 40, 39, 7, 37, 14, 23, 26, 15, 6, 25, 24, 19, 8, 9, 22, 29, 27, 38, 35, 11, 20, 33, 31, 17, 32, 4, 28, 12, 2, 10, 0, 42, 21, 5, 16, 30, 18, 13]\n)\n*/\n\nkeyTest(\n    [,8289652839303017,21512342290952802,6586509908083826,,7,8,9,2,5,6,1,,4,2379920135717839,26182894385419786,],\n    [,1,2,3,4,5,6,7,8,9,]\n)\n\nautomateTests({\n    numTests: 1000,\n    minLength: 5,\n    maxLength: 12,\n    minMutations: 15,\n    maxMutations: 20,\n    keyRatio: 0.8,\n    mutations: [addKeyed, addNonKeyed, remove, swap, reverse, move]\n})\n\nfunction addKeyed(list) {\n    list.push(('' + Math.random()).substring(2))\n\n    return list\n}\n\nfunction addNonKeyed(list) {\n    list.push(undefined)\n    return list\n}\n\nfunction remove(list) {\n    var index = Math.floor(Math.random() * list.length)\n\n    list.splice(index, 1)\n\n    return list\n}\n\nfunction swap(list) {\n    var index1 = Math.floor(Math.random() * list.length)\n    var index2 = Math.floor(Math.random() * list.length)\n\n    var item1 = list[index1]\n    list[index1] = list[index2]\n    list[index2] = item1\n\n    return list\n}\n\nfunction reverse(list) {\n    return list.reverse()\n}\n\nfunction move(list) {\n    var from = Math.floor(Math.random() * list.length)\n    var to = Math.floor(Math.random() * list.length)\n\n    list.splice(to, 0, list.splice(from, 1)[0])\n\n    return list\n}\n\nfunction automateTests(options) {\n    options = options || {}\n\n    var numTests = options.numTests || 10\n    var minLength = options.minLength || 5\n    var maxLength = options.maxLength || 10\n    var minMutations = options.minMutations || 3\n    var maxMutations = options.maxMutations || 5\n    var keyRatio = options.keyRatio || 1\n    var mutations = options.mutations || []\n\n    while (numTests--) {\n        var length = Math.ceil(Math.random() * (maxLength - minLength)) + minLength\n        var count = 0\n        var end = []\n\n        do {\n            var isKeyed = Math.random() < keyRatio\n            end[count] = isKeyed ? count : undefined\n        }\n        while (++count < length)\n\n        var start = end.slice()\n\n        if (mutations.length) {\n            var numMutations = Math.ceil(Math.random() * (maxMutations - minMutations)) + minMutations\n            while (numMutations--) {\n                var mutation = mutations[Math.floor(Math.random() * mutations.length)]\n                start = mutation(start)\n            }\n        }\n\n        keyTest(start, end)\n    }\n}\n\nfunction keyTest(itemsA, itemsB) {\n    test(\n        'keyTest([' + itemsA.join() + '], [' + itemsB.join() + '])',\n        assertKeys\n    )\n\n    function assertKeys(assert) {\n        var nodesA = nodesFromArray(itemsA)\n        var nodesB = nodesFromArray(itemsB)\n\n        var patches = diff(nodesA, nodesB)\n\n        var rootNode = render(nodesA)\n        patch(rootNode, patches)\n\n        var childNodes = rootNode.childNodes\n\n        assertChildNodesFromArray(assert, itemsB, childNodes)\n\n\n        assert.end()\n    }\n}\n\nfunction childNodesArray(node) {\n    var childNodes = []\n    for (var i = 0; i < node.childNodes.length; i++) {\n        childNodes.push(node.childNodes[i])\n    }\n    return childNodes\n}\n\nfunction getReorderPatch(patches) {\n    for (var key in patches) {\n        if (key !== \"a\" && patches.hasOwnProperty(key)) {\n            var patch = patches[key]\n            if (patch.type === VPatch.ORDER) {\n                return patch\n            }\n        }\n    }\n\n    return null\n}\n\nfunction assertReorderEquals(assert, patches, expected) {\n    var reorderPatch = getReorderPatch(patches)\n\n    assert.deepEqual(reorderPatch.patch, expected)\n}\n"
  },
  {
    "path": "test/lib/assert-childNodes-from-array.js",
    "content": "module.exports = assertChildNodesFromArray;\n\nfunction assertChildNodesFromArray(assert, items, childNodes) {\n    // ensure that the output has the same number of nodes as required\n    assert.equal(childNodes.length, items.length)\n\n    for (var i = 0; i < items.length; i++) {\n        var key = items[i]\n        assert.equal(childNodes[i].id, key != null ? String(key) : 'no-key-' + i)\n    }\n}\n"
  },
  {
    "path": "test/lib/assert-equal-dom.js",
    "content": "module.exports = assertEqualDom\n\nfunction assertEqualDom(assert, a, b) {\n    assert.ok(areEqual(a, b) && areEqual(b, a), \"Dom structures are equal\")\n}\n\nfunction areEqual(a, b) {\n    for (var key in a) {\n        if (key !== \"parentNode\" &&\n            key !== \"parentElement\" &&\n            key !== \"defaultView\" &&\n            key !== \"ownerElement\" &&\n            key !== \"nextElementSibling\" &&\n            key !== \"nextSibling\" &&\n            key !== \"previousElementSibling\" &&\n            key !== \"previousSibling\" &&\n            key !== \"document\" &&\n            key !== \"window\" &&\n            key !== \"frames\" &&\n            key !== \"top\" &&\n            key !== \"parent\" &&\n            key !== \"self\" &&\n            key !== \"outerHTML\" &&\n            key !== \"innerHTML\" &&\n            key !== \"spellcheck\" &&\n            key !== \"bind\" &&\n            \"\" + parseInt(key, 10) !== key\n        ) {\n            if (key === \"ownerDocument\") {\n                return a[key] === b[key]\n            }\n            if (key === \"style\") {\n                return equalStyle(a[key], b[key])\n            }\n            if (typeof a === \"object\" || typeof a === \"function\") {\n                if (!areEqual(a[key], b[key])) {\n                    return false\n                }\n            } else {\n                if (a !== b) {\n                    return false\n                }\n            }\n        }\n    }\n\n    return true\n}\n\n// CssStyleDeclaration indexes the styles, which could be out of order\n// This is a left sided check. Note that we call equal(a, b) and equal(b, a)\nfunction equalStyle(a, b) {\n    var keys = []\n    for (var key in a) {\n        if (\"\" + parseInt(key, 10) === key) {\n            continue\n        } else {\n            keys.push(key)\n        }\n    }\n\n    keys.sort()\n\n    for (var i = 0; i < keys.length; i++) {\n        if (a[key] !== b[key]) {\n            return false\n        }\n    }\n\n    return true\n}\n"
  },
  {
    "path": "test/lib/nodes-from-array.js",
    "content": "var h = require(\"../../h.js\")\n\nmodule.exports = nodesFromArray\n\nfunction nodesFromArray(array) {\n    var i =0\n    var children = []\n    var key\n    var properties\n\n    for(; i < array.length; i++) {\n        key = array[i]\n\n        if (key != null) {\n            properties = {\n                key: key,\n                id: String(key)\n            }\n        }\n        else {\n            properties = {\n                id: 'no-key-' + i\n            }\n        }\n\n        children.push(h('div', properties, properties.id))\n    }\n\n    return h('div', children)\n}\n"
  },
  {
    "path": "test/lib/patch-count.js",
    "content": "module.exports = patchCount\n\nfunction patchCount(patch) {\n    var count = 0\n\n    for (var key in patch) {\n        if (key !== \"a\" && patch.hasOwnProperty(key)) {\n            count++\n        }\n    }\n\n    return count\n}\n"
  },
  {
    "path": "test/main.js",
    "content": "var test = require(\"tape\")\n\nvar h = require(\"../h.js\")\nvar diff = require(\"../diff.js\")\nvar patch = require(\"../patch.js\")\nvar render = require(\"../create-element.js\")\nvar Node = require(\"../vnode/vnode\")\nvar TextNode = require(\"../vnode/vtext\")\nvar version = require(\"../vnode/version\")\nvar assertEqualDom = require(\"./lib/assert-equal-dom.js\")\nvar patchCount = require(\"./lib/patch-count.js\")\n\n\n\n// VirtualNode tests\ntest(\"Node is a function\", function (assert) {\n    assert.equal(typeof Node, \"function\")\n    assert.end()\n})\n\ntest(\"Node type and version are set\", function (assert) {\n    assert.equal(Node.prototype.type, \"VirtualNode\")\n    assert.deepEqual(Node.prototype.version, version)\n    assert.end()\n})\n\ntest(\"TextNode is a function\", function (assert) {\n    assert.equal(typeof TextNode, \"function\")\n    assert.end()\n})\n\ntest(\"TextNode type and version are set\", function (assert) {\n    assert.equal(TextNode.prototype.type, \"VirtualText\")\n    assert.deepEqual(TextNode.prototype.version, version)\n    assert.end()\n})\n\n// h tests\n\ntest(\"h is a function\", function (assert) {\n    assert.equal(typeof h, \"function\")\n    assert.end()\n})\n\ntest(\"defaults to div node\", function (assert) {\n    var node = h()\n    assertNode(assert, node, \"DIV\")\n    assert.end()\n})\n\ntest(\"can use class selector\", function (assert) {\n    var node = h(\"div.pretty\")\n    assertNode(assert, node, \"DIV\", { className: \"pretty\" })\n    assert.end()\n})\n\ntest(\"can use non-ascii class selector\", function (assert) {\n    var node = h(\"div.ΑΒΓΔΕΖ\")\n    assertNode(assert, node, \"DIV\", { className: \"ΑΒΓΔΕΖ\" })\n    assert.end()\n})\n\ntest(\"class selectors combine with className property\", function (assert) {\n    var node = h(\"div.very\", { className: \"pretty\" })\n    assertNode(assert, node, \"DIV\", { className: \"very pretty\" })\n    assert.end()\n})\n\ntest(\"can use id selector\", function (assert) {\n    var node = h(\"div#important\")\n    assertNode(assert, node, \"DIV\", { id: \"important\" })\n    assert.end()\n})\n\ntest(\"can use non-ascii id selector\", function (assert) {\n    var node = h(\"div#ΑΒΓΔΕΖ\")\n    assertNode(assert, node, \"DIV\", { id: \"ΑΒΓΔΕΖ\" })\n    assert.end()\n})\n\ntest(\"properties id overrides selector id\", function (assert) {\n    var node = h(\"div#very\", { id: \"important\" })\n    assertNode(assert, node, \"DIV\", { id: \"important\" })\n    assert.end()\n})\n\ntest(\"defaults to div when using selectors\", function (assert) {\n    var node1 = h(\"#important\")\n    var node2 = h(\".pretty\")\n    var node3 = h(\"#important.pretty\")\n    var node4 = h(\".pretty#important\")\n\n    assertNode(assert, node1, \"DIV\", { id: \"important\" })\n    assertNode(assert, node2, \"DIV\", { className: \"pretty\" })\n    assertNode(assert, node3, \"DIV\", { id: \"important\", className: \"pretty\" })\n    assertNode(assert, node4, \"DIV\", { id: \"important\", className: \"pretty\" })\n    assert.end()\n})\n\ntest(\"second argument can be children\", function (assert) {\n    var node1 = h(\"#important.pretty\", \"test\")\n    var node2 = h(\"#important.pretty\", [\"test\"])\n    var node3 = h(\"#important.pretty\", h(\"p\", \"testing\"))\n    var node4 = h(\"#important.pretty\", [h(\"p\", \"testing\")])\n\n    var props = { id: \"important\", className: \"pretty\" }\n\n    assertNode(assert, node1, \"DIV\", props, [\"test\"])\n    assertNode(assert, node2, \"DIV\", props, [\"test\"])\n    assertNode(assert, node3, \"DIV\", props, [[\"P\", {}, [\"testing\"]]])\n    assertNode(assert, node4, \"DIV\", props, [[\"P\", {}, [\"testing\"]]])\n    assert.end()\n})\n\ntest(\"third argument can be child or children\", function (assert) {\n    var node1 = h(\"#important.pretty\", { a: \"b\" }, \"test\")\n    var node2 = h(\"#important.pretty\", { a: \"b\" }, [\"test\"])\n    var node3 = h(\"#important.pretty\", { a: \"b\" }, h(\"p\", \"testing\"))\n    var node4 = h(\"#important.pretty\", { a: \"b\" }, [h(\"p\", \"testing\")])\n\n    var props = { a: \"b\", id: \"important\", className: \"pretty\" }\n\n    assertNode(assert, node1, \"DIV\", props, [\"test\"])\n    assertNode(assert, node2, \"DIV\", props, [\"test\"])\n    assertNode(assert, node3, \"DIV\", props, [[\"P\", {}, [\"testing\"]]])\n    assertNode(assert, node4, \"DIV\", props, [[\"P\", {}, [\"testing\"]]])\n    assert.end()\n})\n\nfunction assertNode(assert, node, tagName, properties, children) {\n    properties = properties || {}\n    children = children || []\n\n    assert.ok(node instanceof Node, \"node is a VirtualNode\")\n    assert.equal(node.tagName, tagName, \"tag names are equal\")\n    assert.deepEqual(node.properties, properties, \"propeties are equal\")\n    assert.equal(node.children.length, children.length, \"child count equal\")\n    for (var i = 0; i < children.length; i++) {\n        var child = children[i]\n\n        if (typeof child === \"string\") {\n            assert.equal(node.children[i].text, child)\n        } else {\n            assertNode(assert,\n                node.children[i],\n                child[0],\n                child[1],\n                child[2])\n        }\n    }\n}\n\n\n\n// render tests\ntest(\"render is a function\", function (assert) {\n    assert.equal(typeof h, \"function\")\n    assert.end()\n})\n\ntest(\"render text node\", function (assert) {\n    var vdom = h(\"span\", \"hello\")\n    var dom = render(vdom)\n    assert.equal(dom.tagName, \"SPAN\")\n    assert.notOk(dom.id)\n    assert.notOk(dom.className)\n    assert.equal(dom.childNodes.length, 1)\n    assert.equal(dom.childNodes[0].data, \"hello\")\n    assert.end()\n})\n\ntest(\"render div\", function (assert) {\n    var vdom = h()\n    var dom = render(vdom)\n    assert.notOk(dom.id)\n    assert.notOk(dom.className)\n    assert.equal(dom.tagName, \"DIV\")\n    assert.equal(dom.childNodes.length, 0)\n    assert.end()\n})\n\ntest(\"node id is applied correctly\", function (assert) {\n    var vdom = h(\"#important\")\n    var dom = render(vdom)\n    assert.equal(dom.id, \"important\")\n    assert.notOk(dom.className)\n    assert.equal(dom.tagName, \"DIV\")\n    assert.equal(dom.childNodes.length, 0)\n    assert.end()\n})\n\ntest(\"node class name is applied correctly\", function (assert) {\n    var vdom = h(\".pretty\")\n    var dom = render(vdom)\n    assert.notOk(dom.id)\n    assert.equal(dom.className, \"pretty\")\n    assert.equal(dom.tagName, \"DIV\")\n    assert.equal(dom.childNodes.length, 0)\n    assert.end()\n})\n\ntest(\"mixture of node/classname applied correctly\", function (assert) {\n    var vdom = h(\"#override.very\", { id: \"important\", className: \"pretty\"})\n    var dom = render(vdom)\n    assert.equal(dom.id, \"important\")\n    assert.equal(dom.className, \"very pretty\")\n    assert.equal(dom.tagName, \"DIV\")\n    assert.equal(dom.childNodes.length, 0)\n    assert.end()\n})\n\ntest(\"style object is applied correctly\", function (assert) {\n    var vdom = h(\"#important.pretty\", { style: {\n        border: \"1px solid rgb(0, 0, 0)\",\n        padding: \"2px\"\n    } })\n    var dom = render(vdom)\n    assert.equal(dom.id, \"important\")\n    assert.equal(dom.className, \"pretty\")\n    assert.equal(dom.tagName, \"DIV\")\n    assert.equal(dom.style.border, style(\"border\", \"1px solid rgb(0, 0, 0)\"))\n    assert.equal(dom.style.padding, style(\"padding\", \"2px\"))\n    assert.equal(dom.childNodes.length, 0)\n    assert.end()\n})\n\ntest(\"children are added\", function (assert) {\n    var vdom = h(\"div\", [\n        h(\"div\", [\n            \"just testing\",\n            \"multiple\",\n            h(\"b\", \"nodes\")\n        ]),\n        \"hello\",\n        h(\"span\", \"test\")\n    ])\n\n    var dom = render(vdom)\n\n    assert.equal(dom.childNodes.length, 3)\n\n    var nodes = dom.childNodes\n    assert.equal(nodes.length, 3)\n    assert.equal(nodes[0].tagName, \"DIV\")\n    assert.equal(nodes[1].data, \"hello\")\n    assert.equal(nodes[2].tagName, \"SPAN\")\n\n    var subNodes0 = nodes[0].childNodes\n    assert.equal(subNodes0.length, 3)\n    assert.equal(subNodes0[0].data, \"just testing\")\n    assert.equal(subNodes0[1].data, \"multiple\")\n    assert.equal(subNodes0[2].tagName, \"B\")\n\n    var subNodes0_2 = subNodes0[2].childNodes\n    assert.equal(subNodes0_2.length, 1)\n    assert.equal(subNodes0_2[0].data, \"nodes\")\n\n    var subNodes2 = nodes[2].childNodes\n    assert.equal(subNodes2.length, 1)\n    assert.equal(subNodes2[0].data, \"test\")\n    assert.end()\n})\n\ntest(\"incompatible children are ignored\", function (assert) {\n    var vdom = h(\"#important.pretty\", {\n        style: {\n            \"cssText\": \"color: red;\"\n        }\n    }, [\n        null\n    ])\n    var dom = render(vdom)\n    assert.equal(dom.id, \"important\")\n    assert.equal(dom.className, \"pretty\")\n    assert.equal(dom.tagName, \"DIV\")\n    assert.equal(dom.style.cssText, style(\"cssText\", \"color: red;\"))\n    assert.equal(dom.childNodes.length, 0)\n    assert.end()\n})\n\ntest(\"injected document object is used\", function (assert) {\n    var vdom = h(\"div\", \"hello\")\n    var count = 0\n    var doc = {\n        createElement: function createElement(tagName) {\n            assert.equal(tagName, \"DIV\")\n            count++\n            return { tagName: \"DIV\", appendChild: function (t) {\n                assert.equal(t, \"hello\")\n                count++\n            } }\n        },\n        createTextNode: function createTextNode(text) {\n            assert.equal(text, \"hello\")\n            count++\n            return text\n        }\n    }\n    render(vdom, { document: doc })\n    assert.equal(count, 3)\n    assert.end()\n})\n\ntest(\"injected warning is used\", function (assert) {\n    var badObject = {}\n    var vdom = h(\"#important.pretty\", {\n        style: {\n            cssText: \"color: red;\"\n        }\n    })\n\n    vdom.children = [\n        badObject, null\n    ]\n\n    var i = 0\n    function warn(warning, node) {\n        assert.equal(warning, \"Item is not a valid virtual dom node\")\n\n        if (i === 0) {\n            assert.equal(node, badObject)\n        } else if (i === 1) {\n            assert.equal(node, null)\n        } else {\n            assert.error(\"Too many warnings\")\n        }\n\n        i++\n    }\n\n    var dom = render(vdom, { warn: warn })\n    assert.equal(dom.id, \"important\")\n    assert.equal(dom.className, \"pretty\")\n    assert.equal(dom.tagName, \"DIV\")\n    assert.equal(dom.style.cssText, style(\"cssText\", \"color: red;\"))\n    assert.equal(dom.childNodes.length, 0)\n    assert.equal(i, 2)\n    assert.end()\n})\n\n// Complete patch tests\ntest(\"textnode update test\", function (assert) {\n    var hello = h(\"div\", \"hello\")\n    var goodbye = h(\"div\", \"goodbye\")\n    var rootNode = render(hello)\n    var equalNode = render(goodbye)\n    var patches = diff(hello, goodbye)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\ntest(\"textnode replace test\", function (assert) {\n    var hello = h(\"div\", \"hello\")\n    var goodbye = h(\"div\", [h(\"span\", \"goodbye\")])\n    var rootNode = render(hello)\n    var equalNode = render(goodbye)\n    var patches = diff(hello, goodbye)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\ntest(\"textnode insert test\", function (assert) {\n    var hello = h(\"div\", \"hello\")\n    var again = h(\"span\", [\"hello\", \"again\"])\n    var rootNode = render(hello)\n    var equalNode = render(again)\n    var patches = diff(hello, again)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\ntest(\"textnode remove\", function (assert) {\n    var again = h(\"span\", [\"hello\", \"again\"])\n    var hello = h(\"div\", \"hello\")\n    var rootNode = render(again)\n    var equalNode = render(hello)\n    var patches = diff(again, hello)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\ntest(\"dom node update test\", function (assert) {\n    var hello = h(\"div.hello\", \"hello\")\n    var goodbye = h(\"div.goodbye\", \"goodbye\")\n    var rootNode = render(hello)\n    var equalNode = render(goodbye)\n    var patches = diff(hello, goodbye)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\ntest(\"dom node replace test\", function (assert) {\n    var hello = h(\"div\", \"hello\")\n    var goodbye = h(\"span\", \"goodbye\")\n    var rootNode = render(hello)\n    var equalNode = render(goodbye)\n    var patches = diff(hello, goodbye)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\ntest(\"dom node insert\", function (assert) {\n    var hello = h(\"div\", [h(\"span\", \"hello\")])\n    var again = h(\"div\", [h(\"span\", \"hello\"), h(\"span\", \"again\")])\n    var rootNode = render(hello)\n    var equalNode = render(again)\n    var patches = diff(hello, again)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\ntest(\"dom node remove\", function (assert) {\n    var hello = h(\"div\", [h(\"span\", \"hello\")])\n    var again = h(\"div\", [h(\"span\", \"hello\"), h(\"span\", \"again\")])\n    var rootNode = render(again)\n    var equalNode = render(hello)\n    var patches = diff(again, hello)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.end()\n})\n\n\ntest(\"reuse dom node without breaking\", function (assert) {\n    var hSpan = h(\"span\", \"hello\")\n    var hello = h(\"div\", [hSpan, hSpan, hSpan])\n    var goodbye = h(\"div\", [h(\"span\", \"hello\"), hSpan, h(\"span\", \"goodbye\")])\n    var rootNode = render(hello)\n    var equalNode = render(goodbye)\n    var patches = diff(hello, goodbye)\n    var newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, equalNode)\n\n    // Undo the rendering with new trees\n    hello = h(\"div\", [hSpan, hSpan, hSpan])\n    goodbye = h(\"div\", [h(\"span\", \"hello\"), hSpan, h(\"span\", \"goodbye\")])\n    patches = diff(goodbye, hello)\n    newRoot = patch(rootNode, patches)\n    assertEqualDom(assert, newRoot, rootNode)\n\n    assert.end()\n})\n\ntest(\"Allow empty textnode\", function (assert) {\n    var empty = h(\"span\", \"\")\n    var rootNode = render(empty)\n    assert.equal(rootNode.childNodes.length, 1)\n    assert.equal(rootNode.childNodes[0].data, \"\")\n    assert.end()\n})\n\ntest(\"Can replace vnode with vtext\", function (assert) {\n\n    var leftNode = h(\"div\", h(\"div\"))\n    var rightNode = h(\"div\", \"text\")\n\n    var rootNode = render(leftNode)\n\n    assert.equal(rootNode.childNodes.length, 1)\n    assert.equal(rootNode.childNodes[0].nodeType, 1)\n\n    var patches = diff(leftNode, rightNode)\n\n    var newRoot = patch(rootNode, patches)\n\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 1)\n    assert.equal(newRoot.childNodes[0].nodeType, 3)\n\n    assert.end()\n})\n\n// Widget tests\ntest(\"Widget is initialised on render\", function (assert) {\n    var initCount = 0\n    var testNode = render(h(\"div\"))\n    var Widget = {\n        init: function () {\n            initCount++\n            return testNode\n        },\n        update: function () {\n            initCount = 1000000\n        },\n        type: \"Widget\"\n    }\n\n    var result = render(Widget)\n\n    assert.equal(initCount, 1)\n    assert.equal(result, testNode)\n    assert.end()\n})\n\ntest(\"Nested widget is initialised on render\", function (assert) {\n    var initCount = 0\n    var testNode = render(h(\"div\"))\n    var Widget = {\n        init: function () {\n            initCount++\n            return testNode\n        },\n        update: function () {\n            initCount = 1000000\n        },\n        type: \"Widget\"\n    }\n\n    var vdom = h(\"div\", [\n        h(\"span\", \"text\"),\n        h(\"div.widgetContainer\", [\n            Widget\n        ]),\n        h(\"p\", \"more text\")\n    ])\n\n    var result = render(vdom)\n\n    assert.equal(initCount, 1)\n    assert.equal(result.childNodes[1].childNodes[0], testNode)\n    assert.end()\n})\n\ntest(\"Patch widgets at the root\", function (assert) {\n    var initCount = 0\n    var updateCount = 0\n    var leftState = { a: 1 }\n    var rightState = { a: 2 }\n    var domNode\n\n    function Widget(state) {\n        this.state = state\n        this.vdom = this.render(state)\n    }\n\n    Widget.prototype.init = function () {\n        initCount++\n        return render(this.vdom)\n    }\n\n    Widget.prototype.update = function (leftNode, dom) {\n        updateCount++\n        assert.equal(this.state, rightState)\n        assert.equal(leftNode.state, leftState)\n        assert.equal(dom, domNode)\n        patch(dom, diff(leftNode.vdom, this.vdom))\n    }\n\n    Widget.prototype.render = function (state) {\n        return h(\"div\", \"\" + state.a)\n    }\n\n    Widget.prototype.type = \"Widget\"\n\n    var leftTree = new Widget(leftState)\n    var rightTree = new Widget(rightState)\n    domNode = render(leftTree)\n    assert.equal(initCount, 1, \"initCount after left render\")\n    assert.equal(updateCount, 0, \"updateCount after left render\")\n\n    var patches = diff(leftTree, rightTree)\n    assert.equal(patchCount(patches), 1)\n    assert.equal(initCount, 1, \"initCount after diff\")\n    assert.equal(updateCount, 0, \"updateCount after diff\")\n\n    var newRoot = patch(domNode, patches)\n    assert.equal(initCount, 1, \"initCount after patch\")\n    assert.equal(updateCount, 1, \"updateCount after patch\")\n\n    // The patch should only update sibling value in this use case\n    var expectedNode = render(rightTree)\n    assert.equal(newRoot, domNode)\n    assertEqualDom(assert, newRoot, expectedNode)\n    assert.end()\n})\n\ntest(\"Patch nested widgets\", function (assert) {\n    var initCount = 0\n    var updateCount = 0\n    var leftState = { a: 1 }\n    var rightState = { a: 2 }\n    var domNode\n\n    function Widget(state) {\n        this.state = state\n        this.vdom = this.render(state)\n    }\n\n    Widget.prototype.init = function () {\n        initCount++\n        return render(this.vdom)\n    }\n\n    Widget.prototype.update = function (leftNode, dom) {\n        updateCount++\n        assert.equal(this.state, rightState)\n        assert.equal(leftNode.state, leftState)\n        assert.equal(dom, domNode.childNodes[1].childNodes[0])\n        patch(dom, diff(leftNode.vdom, this.vdom))\n    }\n\n    Widget.prototype.render = function (state) {\n        return h(\"div\", \"\" + state.a)\n    }\n\n    Widget.prototype.type = \"Widget\"\n\n    var leftWidget = new Widget(leftState)\n    var rightWidget = new Widget(rightState)\n\n    var leftTree = h(\"div\", [\n        h(\"span\", \"text\"),\n        h(\"div.widgetContainer\", [\n            leftWidget\n        ]),\n        h(\"p\", \"more text\")\n    ])\n\n    var rightTree = h(\"div\", [\n        h(\"span\", \"text\"),\n        h(\"div.widgetContainer\", [\n            rightWidget\n        ]),\n        h(\"p\", \"more text\")\n    ])\n\n    domNode = render(leftTree)\n    assert.equal(initCount, 1, \"initCount after left render\")\n    assert.equal(updateCount, 0, \"updateCount after left render\")\n\n    var patches = diff(leftTree, rightTree)\n    assert.equal(patchCount(patches), 1)\n    assert.equal(initCount, 1, \"initCount after diff\")\n    assert.equal(updateCount, 0, \"updateCount after diff\")\n\n    var newRoot = patch(domNode, patches)\n    assert.equal(initCount, 1, \"initCount after patch\")\n    assert.equal(updateCount, 1, \"updateCount after patch\")\n\n    // The patch should only update sibling value in this use case\n    var expectedNode = render(rightTree)\n    assert.equal(newRoot, domNode)\n    assertEqualDom(assert, newRoot, expectedNode)\n    assert.end()\n})\n\ntest(\"Can replace stateful widget with vnode\", function (assert) {\n    var statefulWidget  = {\n        init: function () {\n            return render(h(\"div.widget\"))\n        },\n        update: function () {},\n        destroy: function () {},\n        type: \"Widget\"\n    }\n\n    var leftNode = h(\"div\", statefulWidget)\n    var rightNode = h(\"div\", h(\"div.vnode\"))\n\n    var rootNode = render(leftNode)\n\n    assert.equal(rootNode.childNodes.length, 1)\n    assert.equal(rootNode.childNodes[0].className, 'widget')\n\n    var patches = diff(leftNode, rightNode)\n\n    var newRoot = patch(rootNode, patches)\n\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 1)\n    assert.equal(newRoot.childNodes[0].className, 'vnode')\n\n    assert.end()\n})\n\ntest(\"Can replace vnode with stateful widget with vnode\", function (assert) {\n    var statefulWidget  = {\n        init: function () {\n            return render(h(\"div.widget\"))\n        },\n        update: function () {},\n        destroy: function () {},\n        type: \"Widget\"\n    }\n\n    var leftNode = h(\"div\", h(\"div.vnode\"))\n    var rightNode = h(\"div\", statefulWidget)\n\n    var rootNode = render(leftNode)\n\n    assert.equal(rootNode.childNodes.length, 1)\n    assert.equal(rootNode.childNodes[0].className, 'vnode')\n\n    var patches = diff(leftNode, rightNode)\n\n    var newRoot = patch(rootNode, patches)\n\n    assert.equal(newRoot, rootNode)\n\n    assert.equal(newRoot.childNodes.length, 1)\n    assert.equal(newRoot.childNodes[0].className, 'widget')\n\n    assert.end()\n})\n\ntest(\"Ensure children are not rendered more than once\", function (assert) {\n    var initCount = 0\n    var updateCount = 0\n    var rightState = { a: 1 }\n    var domNode\n\n    function Widget(state) {\n        this.state = state\n        this.vdom = this.render(state)\n    }\n\n    Widget.prototype.init = function () {\n        initCount++\n        return render(this.vdom)\n    }\n\n    Widget.prototype.update = function (leftNode, dom) {\n        updateCount++\n        patch(dom, diff(leftNode.vdom, this.vdom))\n    }\n\n    Widget.prototype.render = function (state) {\n        return h(\"div\", \"\" + state.a)\n    }\n\n    Widget.prototype.type = \"Widget\"\n\n    var rightWidget = new Widget(rightState)\n\n    var leftTree = h(\"div.container\", [\n        h(\"div\")\n    ])\n\n    var rightTree = h(\"div.container\", [\n        h(\"section.widgetContainer\", rightWidget)\n    ])\n\n    domNode = render(leftTree)\n    assert.equal(initCount, 0, \"initCount after left render\")\n    assert.equal(updateCount, 0, \"updateCount after left render\")\n\n    var patches = diff(leftTree, rightTree)\n    assert.equal(patchCount(patches), 1)\n    assert.equal(initCount, 0, \"initCount after diff\")\n    assert.equal(updateCount, 0, \"updateCount after diff\")\n\n    var newRoot = patch(domNode, patches)\n    assert.equal(initCount, 1, \"initCount after patch\")\n    assert.equal(updateCount, 0, \"updateCount after patch\")\n\n    // The patch should only update sibling value in this use case\n    var expectedNode = render(rightTree)\n    assert.equal(newRoot, domNode)\n    assertEqualDom(assert, newRoot, expectedNode)\n    assert.end()\n})\n\ntest(\"VNode indicates stateful sibling\", function (assert) {\n    var statefulWidget  = {\n        init: function () {},\n        update: function () {},\n        destroy: function () {},\n        type: \"Widget\"\n    }\n\n    var pureWidget = {\n        init: function () {},\n        update: function () {},\n        type: \"Widget\"\n    }\n\n    var stateful = h(\"div\", [statefulWidget])\n    var pure = h(\"div\", [pureWidget])\n\n    assert.ok(stateful.hasWidgets)\n    assert.notOk(pure.hasWidgets)\n    assert.end()\n})\n\ntest(\"Replacing stateful widget with vnode calls destroy\", function (assert) {\n    var count = 0\n    var statefulWidget  = {\n        init: function () {},\n        update: function () {},\n        destroy: function () {\n            count++\n        },\n        type: \"Widget\"\n    }\n\n    var rootNode = render(h(\"div\"))\n    patch(rootNode, diff(statefulWidget, h(\"div\")))\n    assert.equal(count, 1)\n    assert.end()\n})\n\ntest(\"Replacing stateful widget with stateful widget\", function (assert) {\n    var count = 0\n    var statefulWidget  = {\n        init: function () {},\n        update: function () {},\n        destroy: function () {\n            count++\n        },\n        type: \"Widget\"\n    }\n\n    var newWidget = {\n        init: function () {},\n        update: function () {},\n        destroy: function () {\n            count = 10000000\n        },\n        type: \"Widget\"\n    }\n\n    var rootNode = render(h(\"div\"))\n    var patches = diff(statefulWidget, newWidget)\n    patch(rootNode, patches)\n    assert.equal(count, 1)\n    assert.end()\n})\n\ntest(\"Replacing stateful widget with pure widget\", function (assert) {\n    var count = 0\n    var statefulWidget  = {\n        init: function () {},\n        update: function () {},\n        destroy: function () {\n            count++\n        },\n        type: \"Widget\"\n    }\n\n    var newWidget = {\n        init: function () {},\n        update: function () {},\n        type: \"Widget\"\n    }\n\n    var rootNode = render(h(\"div\"))\n    patch(rootNode, diff(statefulWidget, newWidget))\n    assert.equal(count, 1)\n    assert.end()\n})\n\ntest(\"Removing stateful widget calls destroy\", function (assert) {\n    var count = 0\n    var statefulWidget  = {\n        init: function () {},\n        update: function () {},\n        destroy: function () {\n            count++\n        },\n        type: \"Widget\"\n    }\n\n    var rootNode = render(h(\"div\"))\n    patch(rootNode, diff(statefulWidget, null))\n    assert.equal(count, 1)\n    assert.end()\n})\n\ntest(\"Patching parent destroys stateful sibling\", function (assert) {\n    var count = 0\n    var widgetRoot = render(h(\"span\"))\n    var statefulWidget  = {\n        init: function () {\n            return widgetRoot\n        },\n        update: function () {\n            assert.error()\n        },\n        destroy: function (domNode) {\n            assert.equal(domNode, widgetRoot)\n            count++\n        },\n        type: \"Widget\"\n    }\n\n    var deepTree = h(\"div\", [\n        \"hello\",\n        h(\"span\", \"test\"),\n        h(\"div\", [\n            h(\"article\", [statefulWidget])\n        ]),\n        h(\"div\", [\n            h(\"div\", \"test\")\n        ])\n    ])\n\n    var rootNode\n\n    rootNode = render(deepTree)\n    patch(rootNode, diff(deepTree, null))\n    assert.equal(count, 1)\n\n    rootNode = render(deepTree)\n    patch(rootNode, diff(deepTree, h(\"span\")))\n    assert.equal(count, 2)\n\n    rootNode = render(deepTree)\n    patch(rootNode, diff(deepTree, h(\"div\")))\n    assert.equal(count, 3)\n\n    assert.end()\n})\n\ntest(\"Widget update can replace domNode\", function (assert) {\n    var widgetInit = render(h(\"span.init\"))\n    var widgetUpdate = render(h(\"span.update\"))\n\n    function Widget () {}\n    Widget.prototype.init = function () {\n        return widgetInit\n    }\n    Widget.prototype.update = function () {\n        return widgetUpdate\n    }\n    Widget.prototype.destroy = function () {}\n    Widget.prototype.type = \"Widget\"\n\n    var initTree = h(\"div.init\", [new Widget])\n    var updateTree = h(\"div.update\", [new Widget])\n    var rootNode\n\n    rootNode = render(initTree)\n    assert.equal(rootNode.childNodes[0], widgetInit)\n\n    patch(rootNode, diff(initTree, updateTree))\n\n    assert.equal(rootNode.childNodes[0], widgetUpdate)\n    assert.end()\n})\n\ntest(\"Destroy widget nested in removed thunk\", function (assert) {\n    var count = 0\n    var widgetRoot = render(h(\".widget\"))\n    var statefulWidget  = {\n        init: function () {\n            return widgetRoot\n        },\n        update: function () {\n            assert.error()\n        },\n        destroy: function (domNode) {\n            assert.equal(domNode, widgetRoot)\n            count++\n        },\n        type: \"Widget\"\n    }\n    var vnode = h(\".wrapper\", statefulWidget)\n\n    function Thunk() {}\n\n    Thunk.prototype.render = function () {\n        return vnode\n    }\n\n    Thunk.prototype.type = \"Thunk\"\n\n    var thunkTree = h(\".page\", [\n        h(\".section\", [\n            new Thunk()\n        ])\n    ])\n\n    var empty = h(\".empty\")\n\n    var rootNode = render(thunkTree)\n    patch(rootNode, diff(thunkTree, empty))\n    assert.equal(count, 1)\n\n    assert.end()\n})\n\ntest(\"Create element respects namespace\", function (assert) {\n    if (!supportsNamespace()) {\n        assert.skip(\"browser doesn't support namespaces\");\n        return assert.end();\n    }\n\n    var svgURI = \"http://www.w3.org/2000/svg\"\n    var vnode = new Node(\"svg\", {}, [], null, svgURI)\n    var node = render(vnode)\n\n    assert.equal(node.tagName, \"svg\")\n    assert.equal(node.namespaceURI, svgURI)\n    assert.end()\n})\n\ntest(\"Different namespaces creates a patch\", function (assert) {\n    if (!supportsNamespace()) {\n        assert.skip(\"browser doesn't support namespaces\");\n        return assert.end();\n    }\n\n    var leftNode = new Node(\"div\", {}, [], null, \"testing\")\n    var rightNode = new Node(\"div\", {}, [], null, \"undefined\")\n\n    var rootNode = render(leftNode)\n    assert.equal(rootNode.tagName, \"div\")\n    assert.equal(rootNode.namespaceURI, \"testing\")\n\n    var patches = diff(leftNode, rightNode)\n    assert.equal(patchCount(patches), 1)\n\n    rootNode = patch(rootNode, patches)\n\n    assert.equal(rootNode.tagName, \"div\")\n    assert.equal(rootNode.namespaceURI, \"undefined\")\n\n    assert.end()\n})\n\n// Safely translates style values using the DOM in the browser\nfunction style(name, value) {\n    var node = render(h())\n    node.style[name] = value\n    return node.style[name]\n}\n\n// Determine if namespace is supported by the DOM\nfunction supportsNamespace() {\n    var node = render(h())\n    return 'namespaceURI' in node;\n}\n\n"
  },
  {
    "path": "test/nested-properties.js",
    "content": "var test = require(\"tape\")\n\nvar h = require(\"../h.js\")\nvar diff = require(\"../diff.js\")\nvar patch = require(\"../patch.js\")\nvar render = require(\"../create-element.js\")\nvar assertEqualDom = require(\"./lib/assert-equal-dom.js\")\n\ntest(\"dom node style\", function (assert) {\n    var a = h(\"div\", {\n        style: {\n            border: \"none\",\n            className: \"oops\",\n            display: \"none\"\n        }\n    })\n\n    var b = h(\"div\", {\n        style: {\n            border: \"1px solid #000\",\n            className: \"oops\",\n            display: \"\"\n        }\n    })\n\n    var rootNode = render(a)\n    assert.equal(rootNode.style.border, style(\"border\", \"none\"))\n    assert.equal(rootNode.style.className, style(\"className\", \"oops\"))\n    assert.equal(rootNode.style.display, style(\"display\", \"none\"))\n    var s1 = rootNode.style\n    var equalNode = render(b)\n    assert.equal(equalNode.style.border, style(\"border\", \"1px solid #000\"))\n    assert.equal(equalNode.style.className, style(\"className\", \"oops\"))\n    assert.equal(equalNode.style.display, style(\"display\", \"\"))\n    var newRoot = patch(rootNode, diff(a, b))\n    var s2 = newRoot.style\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.equal(newRoot.style.border, style(\"border\", \"1px solid #000\"))\n    assert.equal(newRoot.style.className, style(\"className\", \"oops\"))\n    assert.equal(newRoot.style.display, style(\"display\", \"\"))\n    assert.equal(s1, s2)\n    assert.end()\n})\n\ntest(\"dom node dataset\", function (assert) {\n    var a = h(\"div\", { dataset: { foo: \"bar\", bar: \"oops\" } })\n    var b = h(\"div\", { dataset: { foo: \"baz\", bar: \"oops\" } })\n    var rootNode = render(a)\n    var d1 = rootNode.dataset\n    assert.equal(rootNode.dataset.foo, \"bar\")\n    assert.equal(rootNode.dataset.bar, \"oops\")\n    var equalNode = render(b)\n    var newRoot = patch(rootNode, diff(a, b))\n    var d2 = newRoot.dataset\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.equal(newRoot.dataset.foo, \"baz\")\n    assert.equal(newRoot.dataset.bar, \"oops\")\n    assert.equal(d1, d2)\n    assert.end()\n})\n\ntest(\"dom node attributes\", function (assert) {\n    var a = h(\"div\", { attributes: { foo: \"bar\", bar: \"oops\" } })\n    var b = h(\"div\", { attributes: { foo: \"baz\", bar: \"oops\" } })\n    var rootNode = render(a)\n    var equalNode = render(b)\n\n    var newRoot = patch(rootNode, diff(a, b))\n\n    assertEqualDom(assert, newRoot, equalNode)\n    assert.equal(newRoot.getAttribute(\"foo\"), \"baz\")\n    assert.equal(newRoot.getAttribute(\"bar\"), \"oops\")\n    assert.end()\n})\n\ntest(\"patch nested properties in right only\", function (assert) {\n    var prev = h(\"div\")\n    var curr = h(\"div\", { style: { display: \"none\" } })\n\n    var elem = createAndPatch(prev, curr)\n\n    assert.equal(elem.style.display, style(\"display\", \"none\"))\n\n    assert.end()\n})\n\ntest(\"null properties\", function (assert) {\n    var prev = h(\"div\", { propA: \"bar\", propC: {} })\n    var curr = h(\"div\", { propB: \"apples\" })\n\n    var elem = createAndPatch(prev, curr)\n\n    assert.equal(elem.propA, \"\")\n    assert.equal(elem.propC, null)\n    assert.equal(elem.propB, \"apples\")\n\n    assert.end()\n})\n\ntest(\"replace object with value\", function (assert) {\n    var prev = h(\"div\", { propA: { foo: \"bar\" } })\n    var curr = h(\"div\", { propA: null })\n\n    var elem = createAndPatch(prev, curr)\n\n    assert.equal(elem.propA, null)\n    assert.end()\n})\n\ntest(\"create object on node for nested properties\", function (assert) {\n    var prev = h(\"div\", { propA: null })\n    var curr = h(\"div\", { propA: { nested: true } })\n\n    var elem = createAndPatch(prev, curr)\n\n    assert.equal(elem.propA.nested, true)\n    assert.end()\n})\n\nfunction createAndPatch(prev, curr) {\n    var elem = render(prev)\n    var patches = diff(prev, curr)\n    return patch(elem, patches)\n}\n\n// Safely translates style values using the DOM in the browser\nfunction style(name, value) {\n    var node = render(h())\n    node.style[name] = value\n    return node.style[name]\n}\n"
  },
  {
    "path": "test/non-string.js",
    "content": "var test = require(\"tape\")\nvar h = require(\"../h.js\")\nvar diff = require(\"../diff.js\")\nvar patch = require(\"../patch.js\")\nvar createElement = require(\"../create-element.js\")\n\ntest(\"coerce numbers to strings in children array\", function (assert) {\n    var leftNode = h(\"div\", [ \"clicked \", 1336, \" times\" ])\n    var rightNode = h(\"div\", [ \"clicked \", 1337, \" times\" ])\n    var rootNode = createElement(leftNode)\n    var newRoot = patch(rootNode, diff(leftNode, rightNode))\n    assert.strictEqual(\n        newRoot.outerHTML || newRoot.toString(),\n        '<div>clicked 1337 times</div>'\n    )\n    assert.end()\n})\n"
  },
  {
    "path": "test/sort.js",
    "content": "//\n// This tests the performance of vtree/diff.\n//\n// This test in it's current configuration will test every array permutation of\n// N numbers from 0, 2, ... N  for N = 1 up to and including N = 9.\n//\n// Furthermore, arrays for N 10, 20, 30, ... 1000 are tested. Since the number\n// of permutations is a factorial problem, we can't test all permutations for\n// these. We generate 100 arrays instead and randomly shuffle them for testing.\n//\n// Each test is timed in a benchmark version of the test which removes the\n// peripheral operations, and each test is also re-run against a validation\n// version, which checks to ensure that the arrays are actually sorted.\n//\n// Essentially this test proves that the sorting algorithm for N 0-based\n// consecutive integers works for ALL permutations up to length 9.\n//\n\nvar PERMUTATION_START = 1;\nvar PERMUTATION_END = 9;\n\nvar SAMPLE_START = 10;\nvar SAMPLE_END = 1000;\nvar SAMPLE_COUNT = 100;\nvar SAMPLE_INTERVAL = 10;\n\nvar nodesFromArray = require('./lib/nodes-from-array.js');\nvar assertChildNodesFromArray = require('./lib/assert-childNodes-from-array.js');\n\nvar diff = require('../vtree/diff');\nvar render = require('../create-element.js');\nvar patch = require('../patch.js');\n\nvar assert = require('assert');\n\nvar document = require('global/document');\n\nvar testlingOutput = document.getElementById('__testling_output');\nif (testlingOutput) {\n    testlingOutput.parentNode.removeChild(testlingOutput);\n}\n\nrunTest();\n// validateOnly();\n// benchmarkOnly();\n\nfunction runTest() {\n    forEachPermutation(PERMUTATION_START, PERMUTATION_END, testArrays);\n    forEachSample(SAMPLE_START, SAMPLE_END, SAMPLE_COUNT, SAMPLE_INTERVAL, testArrays);\n}\n\nfunction testArrays(arrays) {\n    runSort(arrays);\n    runBench(arrays);\n}\n\nfunction validateOnly() {\n    forEachPermutation(PERMUTATION_START, PERMUTATION_END, runSort);\n    forEachSample(SAMPLE_START, SAMPLE_END, SAMPLE_COUNT, SAMPLE_INTERVAL, runSort);\n}\n\nfunction benchmarkOnly() {\n    forEachPermutation(PERMUTATION_START, PERMUTATION_END, runBench);\n    forEachSample(SAMPLE_START, SAMPLE_END, SAMPLE_COUNT, SAMPLE_INTERVAL, runBench);\n}\n\nfunction runBench(permutations) {\n    var count = permutations.length;\n    var arrayLength = permutations[0].goal.length;\n\n    console.log('Benchmarking sort for length ', arrayLength);\n\n    var startTime = Date.now();\n\n    for (var i = 0; i < count; i++) {\n        var item = permutations[i];\n        var goal = nodesFromArray(item.goal);\n        var shuffled = nodesFromArray(item.shuffled);\n\n        var rootNode = render(shuffled);\n        document.body.appendChild(rootNode);\n        var reflow = rootNode.offsetWidth;\n        var patches = diff(shuffled, goal);\n        patch(rootNode, patches);\n        reflow = rootNode.offsetWidth;\n        document.body.removeChild(rootNode);\n    }\n\n    var totalTime = Date.now() - startTime;\n    var average = totalTime / count >> 0\n\n    console.log('All (' + count + ') arrays sorted in', totalTime, 'ms');\n    console.log('An array of length', arrayLength, 'sorts in', average, 'ms');\n}\n\nfunction runSort(permutations) {\n    var count = permutations.length;\n\n    console.log('Testing sort for length ', permutations[0].goal.length);\n\n    for (var i = 0; i < count; i++) {\n        var item = permutations[i];\n        var goal = nodesFromArray(item.goal);\n        var shuffled = nodesFromArray(item.shuffled);\n\n        var rootNode = render(shuffled);\n        var patches = diff(shuffled, goal);\n        patch(rootNode, patches);\n\n        assertChildNodesFromArray(assert, item.goal, rootNode.childNodes);\n    }\n\n    console.log('All permutations sorted correctly');\n}\n\nfunction forEachPermutation(start, end, run) {\n    for (var arrayLength = start; arrayLength <= end; arrayLength++) {\n        var array = createArray(arrayLength);\n\n        console.log('Generating test permutations for length', arrayLength);\n        var permutations = permutator(array);\n\n        run(permutations);\n    }\n}\n\nfunction permutator(inputArr) {\n    var results = [];\n\n    function permute(arr, memo) {\n        memo = memo || [];\n\n        var cur;\n\n        for (var i = 0; i < arr.length; i++) {\n            cur = arr.splice(i, 1);\n            if (arr.length === 0) {\n                results.push({\n                    goal: inputArr,\n                    shuffled: memo.concat(cur)\n                });\n            }\n            permute(arr.slice(), memo.concat(cur));\n            arr.splice(i, 0, cur[0]);\n        }\n\n        return results;\n    }\n\n    return permute(inputArr);\n}\n\nfunction forEachSample(start, end, count, interval, run) {\n    console.log(arguments);\n    for (var i = start; i <= end; i += interval) {\n        var samples = new Array(count);\n\n        console.log(\"Generating\", count, \"sample arrays of length\", i);\n\n        for (var j = 0; j < count; j++) {\n            var goal = createArray(i);\n            samples[j] = {\n                goal: goal,\n                shuffled: shuffle(goal)\n            };\n        }\n\n        run(samples);\n    }\n}\n\nfunction createArray(arrayLength) {\n    var array = new Array(arrayLength);\n\n    for (var numberToAdd = 0; numberToAdd < arrayLength; numberToAdd++) {\n        array[numberToAdd] = numberToAdd;\n    }\n\n    return array;\n}\n\nfunction shuffle(array) {\n    var currentIndex = array.length;\n    var temporaryValue;\n    var randomIndex;\n\n    while (0 !== currentIndex) {\n        randomIndex = Math.floor(Math.random() * currentIndex);\n        currentIndex -= 1;\n\n        temporaryValue = array[currentIndex];\n        array[currentIndex] = array[randomIndex];\n        array[randomIndex] = temporaryValue;\n    }\n\n    return array;\n}\n"
  },
  {
    "path": "test/style.js",
    "content": "var test = require(\"tape\")\r\nvar document = require(\"global/document\")\r\n\r\nvar h = require(\"../h\")\r\nvar diff = require(\"../diff\")\r\nvar patch = require(\"../patch\")\r\nvar render = require(\"../create-element\")\r\n\r\nvar patchCount = require(\"./lib/patch-count\")\r\n\r\n\r\ntest(\"style patches correctly\", function (assert) {\r\n    var leftNode = h(\"div\", {\r\n        style: {\r\n            border: \"1px solid #000\"\r\n        }\r\n    })\r\n\r\n    var rightNode = h(\"div\", {\r\n        style: {\r\n            padding: \"5px\"\r\n        }\r\n    })\r\n\r\n    var patches = diff(leftNode, rightNode)\r\n    assert.equal(patchCount(patches), 1);\r\n\r\n    var rootNode = render(leftNode)\r\n    assert.equal(rootNode.style.border, style(\"border\", \"1px solid #000\"))\r\n\r\n    var newRoot = patch(rootNode, patches)\r\n    assert.equal(rootNode, newRoot)\r\n\r\n    assert.equal(newRoot.style.padding, style(\"padding\", \"5px\"))\r\n    assert.equal(newRoot.style.border, style(\"border\", \"\"))\r\n\r\n    assert.end()\r\n})\r\n\r\nfunction style(name, setValue) {\r\n    var div = document.createElement(\"div\")\r\n    div.style[name] = setValue\r\n    return div.style[name]\r\n}\r\n\r\n"
  },
  {
    "path": "test/thunk.js",
    "content": "var test = require(\"tape\")\r\n\r\nvar isThunk = require(\"../vnode/is-thunk\")\r\nvar isVNode = require(\"../vnode/is-vnode\")\r\nvar VNode = require(\"../vnode/vnode\")\r\nvar diff = require(\"../diff.js\")\r\n\r\nvar patchCount = require(\"./lib/patch-count.js\")\r\n\r\nfunction Thunk(tagName) {\r\n    this.tagName = tagName\r\n}\r\n\r\nThunk.prototype.render = function () {\r\n    return new VNode(this.tagName)\r\n}\r\n\r\nThunk.prototype.type = \"Thunk\"\r\n\r\ntest(\"is thunk\", function (assert) {\r\n    var notThunk = {}\r\n    var thunkLiteral = {\r\n        type: \"Thunk\",\r\n        render: function () {}\r\n    }\r\n\r\n    assert.notOk(isThunk(notThunk))\r\n    assert.ok(isThunk(thunkLiteral))\r\n    assert.ok(isThunk(new Thunk(\"div\")))\r\n    assert.end()\r\n})\r\n\r\ntest(\"null or undefined previous renders thunk\", function (assert) {\r\n    var n = new Thunk(\"first\")\r\n    var u = new Thunk(\"second\")\r\n    var nullPatches = diff(null, n)\r\n    var undefPatches = diff(undefined, u)\r\n\r\n    assert.ok(isVNode(n.vnode))\r\n    assert.ok(isVNode(u.vnode))\r\n    assert.equal(n.vnode.tagName, \"first\")\r\n    assert.equal(u.vnode.tagName, \"second\")\r\n    assert.equal(patchCount(nullPatches), 1)\r\n    assert.equal(patchCount(undefPatches), 1)\r\n    assert.end()\r\n})\r\n\r\ntest(\"previous thunk passed to render\", function (assert) {\r\n    var renderCount = 0\r\n\r\n    var previousThunk = new Thunk(\"div\")\r\n\r\n    var nextThunk = {\r\n        type: \"Thunk\",\r\n        render: function (previous) {\r\n            renderCount++\r\n            assert.equal(previous, previousThunk)\r\n            return new VNode(\"test\")\r\n        }\r\n    }\r\n\r\n    var patches = diff(previousThunk, nextThunk)\r\n\r\n    assert.equal(renderCount, 1)\r\n    assert.equal(patchCount(patches), 1)\r\n    assert.ok(isVNode(nextThunk.vnode))\r\n    assert.equal(nextThunk.vnode.tagName, \"test\")\r\n    assert.end()\r\n})\r\n"
  },
  {
    "path": "test/undefined-properties.js",
    "content": "var test = require(\"tape\")\nvar isObject = require(\"is-object\")\n\nvar h = require(\"../h.js\")\nvar diff = require(\"../diff.js\")\nvar patch = require(\"../patch.js\")\nvar render = require(\"../create-element.js\")\n\ntest(\"undefined props are not set in create-element\", function (assert) {\n    var node = h(\"div\", { special: undefined })\n    var rootNode = render(node)\n    assert.ok(!(\"special\" in rootNode))\n    assert.end()\n})\n\ntest(\"undefined removes all previous styles\", function (assert) {\n    var leftNode = h(\"div\", {\n        style: {\n            display: \"none\",\n            border: \"1px solid #000\"\n        }\n    })\n\n    var rightNode = h(\"div\", {\n        style: undefined\n    })\n\n    var rootNode = createAndPatch(leftNode, rightNode)\n\n    assert.equal(rootNode.style.display, style(\"display\", \"\"))\n    assert.equal(rootNode.style.border, style(\"border\", \"\"))\n    assert.end();\n})\n\ntest(\"undefined style removes individual styles\", function (assert) {\n    var leftNode = h(\"div\", { \"style\": { \"display\": \"none\" }})\n    var rightNode = h(\"div\", { \"style\": undefined })\n\n    var rootNode = createAndPatch(leftNode, rightNode)\n\n    assert.equal(rootNode.style.display, style(\"display\", \"\"))\n    assert.end()\n})\n\ntest(\"undefined ignored for hooks\", function (assert) {\n    function CheckNodeBeforeSet(value) {\n        this.value = value\n    }\n    CheckNodeBeforeSet.prototype.hook = function (rootNode, propName) {\n        var value = this.value\n        if (value !== rootNode[propName]) {\n            rootNode[propName] = value\n        }\n    }\n\n    var leftNode = h(\"input\", { value: new CheckNodeBeforeSet(\"hello\") })\n    var rightNode = h(\"input\", { value: undefined })\n\n    var rootNode = render(leftNode)\n    assert.equal(rootNode.value, \"hello\")\n\n    var newRoot = patch(rootNode, diff(leftNode, rightNode))\n    assert.equal(newRoot.value, \"hello\")\n\n    assert.end()\n})\n\ntest(\"undefined nulls other complex types\", function (assert) {\n    var leftNode = h(\"input\", { special: {} })\n    var rightNode = h(\"input\", { special: null })\n\n    var rootNode = render(leftNode)\n    assert.ok(isObject(rootNode.special))\n\n\n    var newRoot = patch(rootNode, diff(leftNode, rightNode))\n    assert.equal(newRoot.special, null)\n\n    assert.end()\n})\n\ntest(\"null not ignored for value\", function (assert) {\n    var leftNode = h(\"input\", { value: \"hello\" })\n    var rightNode = h(\"input\", { value: null })\n\n    var rootNode = createAndPatch(leftNode, rightNode)\n\n    assert.equal(rootNode.value, property(\"input\", \"value\", null))\n    assert.end()\n})\n\ntest(\"null not ignored for objects\", function (assert) {\n    var leftNode = h(\"div\", { \"test\": { \"complex\": \"object\" }})\n    var rightNode = h(\"div\", { \"test\": null })\n\n    var rootNode = createAndPatch(leftNode, rightNode)\n\n    assert.equal(rootNode.test, null)\n    assert.end()\n})\n\ntest(\"null not ignored for hooks\", function (assert) {\n    function CheckNodeBeforeSet(value) {\n        this.value = value\n    }\n    CheckNodeBeforeSet.prototype.hook = function (rootNode, propName) {\n        var value = this.value\n        if (value !== rootNode[propName]) {\n            rootNode.value = value\n        }\n    }\n\n    var leftNode = h(\"input\", { value: new CheckNodeBeforeSet(\"hello\") })\n    var rightNode = h(\"input\", { value: null })\n\n    var rootNode = render(leftNode)\n    assert.equal(rootNode.value, \"hello\")\n\n    var newRoot = patch(rootNode, diff(leftNode, rightNode))\n    assert.equal(newRoot.value, property(\"input\", \"value\", null))\n\n    assert.end()\n})\n\nfunction createAndPatch(prev, curr) {\n    var elem = render(prev)\n    var patches = diff(prev, curr)\n    return patch(elem, patches)\n}\n\n// Safely translates style values using the DOM in the browser\nfunction style(name, value) {\n    var node = render(h())\n    node.style[name] = value\n    return node.style[name]\n}\n\n// Safely transaltes node property using the DOM in the browser\nfunction property(tag, prop, value) {\n    var node = render(h(tag))\n    node[prop] = value\n    return node[prop]\n}\n"
  },
  {
    "path": "vdom/README.md",
    "content": "# vdom\n\nA DOM render and patch algorithm for vtree\n\n## Motivation\n\nGiven a `vtree` structure representing a DOM structure, we would like to either\nrender the structure to a DOM node using `vdom/create-element` or we would like\nto update the DOM using the results of `vtree/diff` by patching the DOM with\n`vdom/patch`\n\n## Example\n\n```js\nvar h = require(\"virtual-dom/h\")\nvar diff = require(\"virtual-dom/diff\")\n\nvar createElement = require(\"virtual-dom/create-element\")\nvar patch = require(\"virtual-dom/patch\")\n\nvar leftNode = h(\"div\")\nvar rightNode = h(\"text\")\n\n// Render the left node to a DOM node\nvar rootNode = createElement(leftNode)\ndocument.body.appendChild(rootNode)\n\n// Update the DOM with the results of a diff\nvar patches = diff(leftNode, rightNode)\npatch(rootNode, patches)\n```\n\n## Installation\n\n`npm install virtual-dom`\n\n## Contributors\n\n - Matt Esch\n\n## MIT Licenced\n"
  },
  {
    "path": "vdom/apply-properties.js",
    "content": "var isObject = require(\"is-object\")\nvar isHook = require(\"../vnode/is-vhook.js\")\n\nmodule.exports = applyProperties\n\nfunction applyProperties(node, props, previous) {\n    for (var propName in props) {\n        var propValue = props[propName]\n\n        if (propValue === undefined) {\n            removeProperty(node, propName, propValue, previous);\n        } else if (isHook(propValue)) {\n            removeProperty(node, propName, propValue, previous)\n            if (propValue.hook) {\n                propValue.hook(node,\n                    propName,\n                    previous ? previous[propName] : undefined)\n            }\n        } else {\n            if (isObject(propValue)) {\n                patchObject(node, props, previous, propName, propValue);\n            } else {\n                node[propName] = propValue\n            }\n        }\n    }\n}\n\nfunction removeProperty(node, propName, propValue, previous) {\n    if (previous) {\n        var previousValue = previous[propName]\n\n        if (!isHook(previousValue)) {\n            if (propName === \"attributes\") {\n                for (var attrName in previousValue) {\n                    node.removeAttribute(attrName)\n                }\n            } else if (propName === \"style\") {\n                for (var i in previousValue) {\n                    node.style[i] = \"\"\n                }\n            } else if (typeof previousValue === \"string\") {\n                node[propName] = \"\"\n            } else {\n                node[propName] = null\n            }\n        } else if (previousValue.unhook) {\n            previousValue.unhook(node, propName, propValue)\n        }\n    }\n}\n\nfunction patchObject(node, props, previous, propName, propValue) {\n    var previousValue = previous ? previous[propName] : undefined\n\n    // Set attributes\n    if (propName === \"attributes\") {\n        for (var attrName in propValue) {\n            var attrValue = propValue[attrName]\n\n            if (attrValue === undefined) {\n                node.removeAttribute(attrName)\n            } else {\n                node.setAttribute(attrName, attrValue)\n            }\n        }\n\n        return\n    }\n\n    if(previousValue && isObject(previousValue) &&\n        getPrototype(previousValue) !== getPrototype(propValue)) {\n        node[propName] = propValue\n        return\n    }\n\n    if (!isObject(node[propName])) {\n        node[propName] = {}\n    }\n\n    var replacer = propName === \"style\" ? \"\" : undefined\n\n    for (var k in propValue) {\n        var value = propValue[k]\n        node[propName][k] = (value === undefined) ? replacer : value\n    }\n}\n\nfunction getPrototype(value) {\n    if (Object.getPrototypeOf) {\n        return Object.getPrototypeOf(value)\n    } else if (value.__proto__) {\n        return value.__proto__\n    } else if (value.constructor) {\n        return value.constructor.prototype\n    }\n}\n"
  },
  {
    "path": "vdom/create-element.js",
    "content": "var document = require(\"global/document\")\n\nvar applyProperties = require(\"./apply-properties\")\n\nvar isVNode = require(\"../vnode/is-vnode.js\")\nvar isVText = require(\"../vnode/is-vtext.js\")\nvar isWidget = require(\"../vnode/is-widget.js\")\nvar handleThunk = require(\"../vnode/handle-thunk.js\")\n\nmodule.exports = createElement\n\nfunction createElement(vnode, opts) {\n    var doc = opts ? opts.document || document : document\n    var warn = opts ? opts.warn : null\n\n    vnode = handleThunk(vnode).a\n\n    if (isWidget(vnode)) {\n        return vnode.init()\n    } else if (isVText(vnode)) {\n        return doc.createTextNode(vnode.text)\n    } else if (!isVNode(vnode)) {\n        if (warn) {\n            warn(\"Item is not a valid virtual dom node\", vnode)\n        }\n        return null\n    }\n\n    var node = (vnode.namespace === null) ?\n        doc.createElement(vnode.tagName) :\n        doc.createElementNS(vnode.namespace, vnode.tagName)\n\n    var props = vnode.properties\n    applyProperties(node, props)\n\n    var children = vnode.children\n\n    for (var i = 0; i < children.length; i++) {\n        var childNode = createElement(children[i], opts)\n        if (childNode) {\n            node.appendChild(childNode)\n        }\n    }\n\n    return node\n}\n"
  },
  {
    "path": "vdom/dom-index.js",
    "content": "// Maps a virtual DOM tree onto a real DOM tree in an efficient manner.\n// We don't want to read all of the DOM nodes in the tree so we use\n// the in-order tree indexing to eliminate recursion down certain branches.\n// We only recurse into a DOM node if we know that it contains a child of\n// interest.\n\nvar noChild = {}\n\nmodule.exports = domIndex\n\nfunction domIndex(rootNode, tree, indices, nodes) {\n    if (!indices || indices.length === 0) {\n        return {}\n    } else {\n        indices.sort(ascending)\n        return recurse(rootNode, tree, indices, nodes, 0)\n    }\n}\n\nfunction recurse(rootNode, tree, indices, nodes, rootIndex) {\n    nodes = nodes || {}\n\n\n    if (rootNode) {\n        if (indexInRange(indices, rootIndex, rootIndex)) {\n            nodes[rootIndex] = rootNode\n        }\n\n        var vChildren = tree.children\n\n        if (vChildren) {\n\n            var childNodes = rootNode.childNodes\n\n            for (var i = 0; i < tree.children.length; i++) {\n                rootIndex += 1\n\n                var vChild = vChildren[i] || noChild\n                var nextIndex = rootIndex + (vChild.count || 0)\n\n                // skip recursion down the tree if there are no nodes down here\n                if (indexInRange(indices, rootIndex, nextIndex)) {\n                    recurse(childNodes[i], vChild, indices, nodes, rootIndex)\n                }\n\n                rootIndex = nextIndex\n            }\n        }\n    }\n\n    return nodes\n}\n\n// Binary search for an index in the interval [left, right]\nfunction indexInRange(indices, left, right) {\n    if (indices.length === 0) {\n        return false\n    }\n\n    var minIndex = 0\n    var maxIndex = indices.length - 1\n    var currentIndex\n    var currentItem\n\n    while (minIndex <= maxIndex) {\n        currentIndex = ((maxIndex + minIndex) / 2) >> 0\n        currentItem = indices[currentIndex]\n\n        if (minIndex === maxIndex) {\n            return currentItem >= left && currentItem <= right\n        } else if (currentItem < left) {\n            minIndex = currentIndex + 1\n        } else  if (currentItem > right) {\n            maxIndex = currentIndex - 1\n        } else {\n            return true\n        }\n    }\n\n    return false;\n}\n\nfunction ascending(a, b) {\n    return a > b ? 1 : -1\n}\n"
  },
  {
    "path": "vdom/patch-op.js",
    "content": "var applyProperties = require(\"./apply-properties\")\n\nvar isWidget = require(\"../vnode/is-widget.js\")\nvar VPatch = require(\"../vnode/vpatch.js\")\n\nvar updateWidget = require(\"./update-widget\")\n\nmodule.exports = applyPatch\n\nfunction applyPatch(vpatch, domNode, renderOptions) {\n    var type = vpatch.type\n    var vNode = vpatch.vNode\n    var patch = vpatch.patch\n\n    switch (type) {\n        case VPatch.REMOVE:\n            return removeNode(domNode, vNode)\n        case VPatch.INSERT:\n            return insertNode(domNode, patch, renderOptions)\n        case VPatch.VTEXT:\n            return stringPatch(domNode, vNode, patch, renderOptions)\n        case VPatch.WIDGET:\n            return widgetPatch(domNode, vNode, patch, renderOptions)\n        case VPatch.VNODE:\n            return vNodePatch(domNode, vNode, patch, renderOptions)\n        case VPatch.ORDER:\n            reorderChildren(domNode, patch)\n            return domNode\n        case VPatch.PROPS:\n            applyProperties(domNode, patch, vNode.properties)\n            return domNode\n        case VPatch.THUNK:\n            return replaceRoot(domNode,\n                renderOptions.patch(domNode, patch, renderOptions))\n        default:\n            return domNode\n    }\n}\n\nfunction removeNode(domNode, vNode) {\n    var parentNode = domNode.parentNode\n\n    if (parentNode) {\n        parentNode.removeChild(domNode)\n    }\n\n    destroyWidget(domNode, vNode);\n\n    return null\n}\n\nfunction insertNode(parentNode, vNode, renderOptions) {\n    var newNode = renderOptions.render(vNode, renderOptions)\n\n    if (parentNode) {\n        parentNode.appendChild(newNode)\n    }\n\n    return parentNode\n}\n\nfunction stringPatch(domNode, leftVNode, vText, renderOptions) {\n    var newNode\n\n    if (domNode.nodeType === 3) {\n        domNode.replaceData(0, domNode.length, vText.text)\n        newNode = domNode\n    } else {\n        var parentNode = domNode.parentNode\n        newNode = renderOptions.render(vText, renderOptions)\n\n        if (parentNode && newNode !== domNode) {\n            parentNode.replaceChild(newNode, domNode)\n        }\n    }\n\n    return newNode\n}\n\nfunction widgetPatch(domNode, leftVNode, widget, renderOptions) {\n    var updating = updateWidget(leftVNode, widget)\n    var newNode\n\n    if (updating) {\n        newNode = widget.update(leftVNode, domNode) || domNode\n    } else {\n        newNode = renderOptions.render(widget, renderOptions)\n    }\n\n    var parentNode = domNode.parentNode\n\n    if (parentNode && newNode !== domNode) {\n        parentNode.replaceChild(newNode, domNode)\n    }\n\n    if (!updating) {\n        destroyWidget(domNode, leftVNode)\n    }\n\n    return newNode\n}\n\nfunction vNodePatch(domNode, leftVNode, vNode, renderOptions) {\n    var parentNode = domNode.parentNode\n    var newNode = renderOptions.render(vNode, renderOptions)\n\n    if (parentNode && newNode !== domNode) {\n        parentNode.replaceChild(newNode, domNode)\n    }\n\n    return newNode\n}\n\nfunction destroyWidget(domNode, w) {\n    if (typeof w.destroy === \"function\" && isWidget(w)) {\n        w.destroy(domNode)\n    }\n}\n\nfunction reorderChildren(domNode, moves) {\n    var childNodes = domNode.childNodes\n    var keyMap = {}\n    var node\n    var remove\n    var insert\n\n    for (var i = 0; i < moves.removes.length; i++) {\n        remove = moves.removes[i]\n        node = childNodes[remove.from]\n        if (remove.key) {\n            keyMap[remove.key] = node\n        }\n        domNode.removeChild(node)\n    }\n\n    var length = childNodes.length\n    for (var j = 0; j < moves.inserts.length; j++) {\n        insert = moves.inserts[j]\n        node = keyMap[insert.key]\n        // this is the weirdest bug i've ever seen in webkit\n        domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to])\n    }\n}\n\nfunction replaceRoot(oldRoot, newRoot) {\n    if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) {\n        oldRoot.parentNode.replaceChild(newRoot, oldRoot)\n    }\n\n    return newRoot;\n}\n"
  },
  {
    "path": "vdom/patch.js",
    "content": "var document = require(\"global/document\")\nvar isArray = require(\"x-is-array\")\n\nvar render = require(\"./create-element\")\nvar domIndex = require(\"./dom-index\")\nvar patchOp = require(\"./patch-op\")\nmodule.exports = patch\n\nfunction patch(rootNode, patches, renderOptions) {\n    renderOptions = renderOptions || {}\n    renderOptions.patch = renderOptions.patch && renderOptions.patch !== patch\n        ? renderOptions.patch\n        : patchRecursive\n    renderOptions.render = renderOptions.render || render\n\n    return renderOptions.patch(rootNode, patches, renderOptions)\n}\n\nfunction patchRecursive(rootNode, patches, renderOptions) {\n    var indices = patchIndices(patches)\n\n    if (indices.length === 0) {\n        return rootNode\n    }\n\n    var index = domIndex(rootNode, patches.a, indices)\n    var ownerDocument = rootNode.ownerDocument\n\n    if (!renderOptions.document && ownerDocument !== document) {\n        renderOptions.document = ownerDocument\n    }\n\n    for (var i = 0; i < indices.length; i++) {\n        var nodeIndex = indices[i]\n        rootNode = applyPatch(rootNode,\n            index[nodeIndex],\n            patches[nodeIndex],\n            renderOptions)\n    }\n\n    return rootNode\n}\n\nfunction applyPatch(rootNode, domNode, patchList, renderOptions) {\n    if (!domNode) {\n        return rootNode\n    }\n\n    var newNode\n\n    if (isArray(patchList)) {\n        for (var i = 0; i < patchList.length; i++) {\n            newNode = patchOp(patchList[i], domNode, renderOptions)\n\n            if (domNode === rootNode) {\n                rootNode = newNode\n            }\n        }\n    } else {\n        newNode = patchOp(patchList, domNode, renderOptions)\n\n        if (domNode === rootNode) {\n            rootNode = newNode\n        }\n    }\n\n    return rootNode\n}\n\nfunction patchIndices(patches) {\n    var indices = []\n\n    for (var key in patches) {\n        if (key !== \"a\") {\n            indices.push(Number(key))\n        }\n    }\n\n    return indices\n}\n"
  },
  {
    "path": "vdom/test/dom-index.js",
    "content": "var test = require(\"tape\")\r\nvar VNode = require(\"../../vnode/vnode\")\r\nvar VText = require(\"../../vnode/vtext\")\r\nvar diff = require(\"../../vtree/diff\")\r\n\r\nvar createElement = require(\"../create-element\")\r\nvar patch = require(\"../patch\")\r\n\r\ntest(\"indexing over thunk root\", function (assert) {\r\n    var leftThunk = {\r\n        type: \"Thunk\",\r\n        render: function () {\r\n            return new VNode(\"div\", {\r\n                className:\"test\"\r\n            }, [new VText(\"Left\")])\r\n        }\r\n    }\r\n\r\n    var rightThunk = {\r\n        type: \"Thunk\",\r\n        render: function () {\r\n            return new VNode(\"div\", {\r\n                className: \"test\"\r\n            }, [new VText(\"Right\")])\r\n        }\r\n    }\r\n\r\n    var root = createElement(leftThunk)\r\n    var patches = diff(leftThunk, rightThunk)\r\n    var newRoot = patch(root, patches)\r\n\r\n    assert.equal(newRoot.childNodes[0].data, \"Right\")\r\n    assert.end()\r\n})\r\n\r\ntest(\"indexing over thunk child\", function (assert) {\r\n    var leftNode = new VNode(\"div\", {\r\n        className: \"parent-node\"\r\n    }, [\r\n        new VNode(\"div\"),\r\n        new VText(\"test\"),\r\n        {\r\n            type: \"Thunk\",\r\n            render: function () {\r\n                return new VNode(\"div\", {\r\n                    className:\"test\"\r\n                }, [new VText(\"Left\")])\r\n            }\r\n        },\r\n        new VNode(\"div\"),\r\n        new VText(\"test\")\r\n    ])\r\n\r\n    var rightNode = new VNode(\"div\", {\r\n        className: \"parent-node\"\r\n    }, [\r\n        new VNode(\"div\"),\r\n        new VText(\"test\"),\r\n        {\r\n            type: \"Thunk\",\r\n            render: function () {\r\n                return new VNode(\"div\", {\r\n                    className:\"test\"\r\n                }, [new VText(\"Right\")])\r\n            }\r\n        },\r\n        new VNode(\"div\"),\r\n        new VText(\"test\")\r\n    ])\r\n\r\n    var root = createElement(leftNode)\r\n    var patches = diff(leftNode, rightNode)\r\n    patch(root, patches)\r\n    assert.equal(root.childNodes[2].childNodes[0].data, \"Right\")\r\n    assert.end()\r\n})\r\n"
  },
  {
    "path": "vdom/test/index.js",
    "content": "require(\"./dom-index\")\nrequire(\"./patch-index\")\nrequire(\"./patch-op-index\")\n"
  },
  {
    "path": "vdom/test/patch-index.js",
    "content": "var test = require(\"tape\")\nvar VNode = require(\"../../vnode/vnode\")\nvar VText = require(\"../../vnode/vtext\")\nvar diff = require(\"../../vtree/diff\")\n\nvar createElement = require(\"../create-element\")\nvar patch = require(\"../patch\")\n\ntest(\"overrided patch function is correctly used and received correct options\", function (assert) {\n\n    function patchCustom(rootNode, patches, renderOptions) {\n        return {\n            rootNode: rootNode,\n            patches: patches,\n            renderOptions: renderOptions\n        }\n    }\n    function createElementCustom(vnode) {}\n\n    var rootNode = new VNode(\"div\")\n    var patches = {}\n    var renderOptions = { patch: patchCustom, render: createElementCustom }\n\n    var result = patch(rootNode, patches, renderOptions)\n    assert.equal(result.rootNode, rootNode)\n    assert.equal(result.patches, patches)\n    assert.equal(result.renderOptions, renderOptions)\n    assert.end()\n})"
  },
  {
    "path": "vdom/test/patch-op-index.js",
    "content": "var test = require(\"tape\")\nvar VNode = require(\"../../vnode/vnode\")\nvar VText = require(\"../../vnode/vtext\")\nvar diff = require(\"../../vtree/diff\")\nvar document = require(\"global/document\")\n\nvar createElement = require(\"../create-element\")\nvar patch = require(\"../patch\")\n\nvar createElementCustom = function(vnode) {\n    var created = createElement(vnode)\n    created.customCreation = true\n    return created\n}\n\nfunction assertPachedNodeIsMarked(leftNode, rightNode, assert) {\n    var root = createElementCustom(leftNode)\n    var patches = diff(leftNode, rightNode)\n    var newRoot = patch(root, patches, { render: createElementCustom })\n    assert.equal(newRoot.childNodes[0].customCreation, true)\n    assert.end()\n}\n\ntest(\"overrided createElement is used on node insertion\", function (assert) {\n    var leftNode = new VNode(\"div\")\n    var rightNode = new VNode(\"div\", {}, [new VNode(\"div\")])\n\n    assertPachedNodeIsMarked(leftNode, rightNode, assert)\n})\n\ntest(\"overrided createElement is used for patching vnodes\", function (assert) {\n    var leftNode = new VNode(\"div\", {}, [new VNode(\"div\")])\n    var rightNode = new VNode(\"div\", {}, [new VNode(\"span\")])\n\n    assertPachedNodeIsMarked(leftNode, rightNode, assert)\n})\n\ntest(\"overrided createElement is used for patching text nodes\", function (assert) {\n    var leftNode = new VNode(\"div\", {}, [new VNode(\"div\")])\n    var rightNode = new VNode(\"div\", {}, [new VText(\"hello\")])\n\n    assertPachedNodeIsMarked(leftNode, rightNode, assert)\n})\n\ntest(\"overrided createElement is used for patching widget nodes\", function (assert) {\n    var Widget = function (){}\n    Widget.prototype.type = \"Widget\"\n    Widget.prototype.init = function(){ return document.createElement(\"div\") }\n    Widget.prototype.update = function(previous, domNode){ return null }\n    Widget.prototype.destroy = function(domNode){}\n\n    var leftNode = new VNode(\"div\", {}, [new VNode(\"div\")])\n    var rightNode = new VNode(\"div\", {}, [new Widget()])\n\n    assertPachedNodeIsMarked(leftNode, rightNode, assert)\n})\n"
  },
  {
    "path": "vdom/update-widget.js",
    "content": "var isWidget = require(\"../vnode/is-widget.js\")\n\nmodule.exports = updateWidget\n\nfunction updateWidget(a, b) {\n    if (isWidget(a) && isWidget(b)) {\n        if (\"name\" in a && \"name\" in b) {\n            return a.id === b.id\n        } else {\n            return a.init === b.init\n        }\n    }\n\n    return false\n}\n"
  },
  {
    "path": "virtual-hyperscript/README.md",
    "content": "# virtual-hyperscript\n\nA DSL for creating virtual trees\n\n## Example\n\n```js\nvar h = require('virtual-dom/h')\n\nvar tree = h('div.foo#some-id', [\n    h('span', 'some text'),\n    h('input', { type: 'text', value: 'foo' })\n])\n```\n\n## Docs\n\nSee [hyperscript](https://github.com/dominictarr/hyperscript) which has the\n  same interface.\n\nExcept `virtual-hyperscript` returns a virtual DOM tree instead of a DOM\n  element.\n\n### `h(selector, properties, children)`\n\n`h()` takes a selector, an optional properties object and an\n  optional array of children or a child that is a string.\n\nIf you pass it a selector like `span.foo.bar#some-id` it will\n  parse the selector and change the `id` and `className`\n  properties of the `properties` object.\n\nIf you pass it an array of `children` it will have child\n  nodes, normally you want to create children with `h()`.\n\nIf you pass it a string it will create an array containing\n  a single child node that is a text element.\n\n### Special properties in `h()`\n\n#### `key`\n\nIf you call `h` with `h('div', { key: someKey })` it will\n  set a key on the return `VNode`. This `key` is not a normal\n  DOM property but is a virtual-dom optimization hint.\n\nIt basically tells virtual-dom to re-order DOM nodes instead of\n  mutating them.\n\n#### `namespace`\n\nIf you call `h` with `h('div', { namespace: \"http://www.w3.org/2000/svg\" })`\n  it will set the namespace on the returned `VNode`. This\n  `namespace` is not a normal DOM property, instead it will\n  cause `vdom` to create a DOM element with a namespace.\n\n#### `ev-*`\n\n**Note:** You must create an instance of `dom-delegator` for `ev-*` to work.\n\nIf you call `h` with `h('div', { ev-click: function (ev) { } })` it\n  will store the event handler on the dom element. It will not\n  set a property `'ev-foo'` on the DOM element.\n\nThis means that `dom-delegator` will recognise the event handler\n  on that element and correctly call your handler when a click\n  event happens.\n\n## Installation\n\n`npm install virtual-dom`\n\n## Contributors\n\n - Raynos\n - Matt Esch\n\n## MIT Licenced\n"
  },
  {
    "path": "virtual-hyperscript/hooks/attribute-hook.js",
    "content": "'use strict';\n\nmodule.exports = AttributeHook;\n\nfunction AttributeHook(namespace, value) {\n    if (!(this instanceof AttributeHook)) {\n        return new AttributeHook(namespace, value);\n    }\n\n    this.namespace = namespace;\n    this.value = value;\n}\n\nAttributeHook.prototype.hook = function (node, prop, prev) {\n    if (prev && prev.type === 'AttributeHook' &&\n        prev.value === this.value &&\n        prev.namespace === this.namespace) {\n        return;\n    }\n\n    node.setAttributeNS(this.namespace, prop, this.value);\n};\n\nAttributeHook.prototype.unhook = function (node, prop, next) {\n    if (next && next.type === 'AttributeHook' &&\n        next.namespace === this.namespace) {\n        return;\n    }\n\n    var colonPosition = prop.indexOf(':');\n    var localName = colonPosition > -1 ? prop.substr(colonPosition + 1) : prop;\n    node.removeAttributeNS(this.namespace, localName);\n};\n\nAttributeHook.prototype.type = 'AttributeHook';\n"
  },
  {
    "path": "virtual-hyperscript/hooks/ev-hook.js",
    "content": "'use strict';\n\nvar EvStore = require('ev-store');\n\nmodule.exports = EvHook;\n\nfunction EvHook(value) {\n    if (!(this instanceof EvHook)) {\n        return new EvHook(value);\n    }\n\n    this.value = value;\n}\n\nEvHook.prototype.hook = function (node, propertyName) {\n    var es = EvStore(node);\n    var propName = propertyName.substr(3);\n\n    es[propName] = this.value;\n};\n\nEvHook.prototype.unhook = function(node, propertyName) {\n    var es = EvStore(node);\n    var propName = propertyName.substr(3);\n\n    es[propName] = undefined;\n};\n"
  },
  {
    "path": "virtual-hyperscript/hooks/focus-hook.js",
    "content": "'use strict';\n\nvar document = require(\"global/document\");\nvar nextTick = require(\"next-tick\");\n\nmodule.exports = MutableFocusHook;\n\nfunction MutableFocusHook() {\n    if (!(this instanceof MutableFocusHook)) {\n        return new MutableFocusHook();\n    }\n}\n\nMutableFocusHook.prototype.hook = function (node) {\n    nextTick(function () {\n        if (document.activeElement !== node) {\n            node.focus();\n        }\n    });\n};\n"
  },
  {
    "path": "virtual-hyperscript/hooks/soft-set-hook.js",
    "content": "'use strict';\n\nmodule.exports = SoftSetHook;\n\nfunction SoftSetHook(value) {\n    if (!(this instanceof SoftSetHook)) {\n        return new SoftSetHook(value);\n    }\n\n    this.value = value;\n}\n\nSoftSetHook.prototype.hook = function (node, propertyName) {\n    if (node[propertyName] !== this.value) {\n        node[propertyName] = this.value;\n    }\n};\n"
  },
  {
    "path": "virtual-hyperscript/index.js",
    "content": "'use strict';\n\nvar isArray = require('x-is-array');\n\nvar VNode = require('../vnode/vnode.js');\nvar VText = require('../vnode/vtext.js');\nvar isVNode = require('../vnode/is-vnode');\nvar isVText = require('../vnode/is-vtext');\nvar isWidget = require('../vnode/is-widget');\nvar isHook = require('../vnode/is-vhook');\nvar isVThunk = require('../vnode/is-thunk');\n\nvar parseTag = require('./parse-tag.js');\nvar softSetHook = require('./hooks/soft-set-hook.js');\nvar evHook = require('./hooks/ev-hook.js');\n\nmodule.exports = h;\n\nfunction h(tagName, properties, children) {\n    var childNodes = [];\n    var tag, props, key, namespace;\n\n    if (!children && isChildren(properties)) {\n        children = properties;\n        props = {};\n    }\n\n    props = props || properties || {};\n    tag = parseTag(tagName, props);\n\n    // support keys\n    if (props.hasOwnProperty('key')) {\n        key = props.key;\n        props.key = undefined;\n    }\n\n    // support namespace\n    if (props.hasOwnProperty('namespace')) {\n        namespace = props.namespace;\n        props.namespace = undefined;\n    }\n\n    // fix cursor bug\n    if (tag === 'INPUT' &&\n        !namespace &&\n        props.hasOwnProperty('value') &&\n        props.value !== undefined &&\n        !isHook(props.value)\n    ) {\n        if (props.value !== null && typeof props.value !== 'string') {\n            throw UnsupportedValueType({\n                expected: 'String',\n                received: typeof props.value,\n                Vnode: {\n                    tagName: tag,\n                    properties: props\n                }\n            });\n        }\n        props.value = softSetHook(props.value);\n    }\n\n    transformProperties(props);\n\n    if (children !== undefined && children !== null) {\n        addChild(children, childNodes, tag, props);\n    }\n\n\n    return new VNode(tag, props, childNodes, key, namespace);\n}\n\nfunction addChild(c, childNodes, tag, props) {\n    if (typeof c === 'string') {\n        childNodes.push(new VText(c));\n    } else if (typeof c === 'number') {\n        childNodes.push(new VText(String(c)));\n    } else if (isChild(c)) {\n        childNodes.push(c);\n    } else if (isArray(c)) {\n        for (var i = 0; i < c.length; i++) {\n            addChild(c[i], childNodes, tag, props);\n        }\n    } else if (c === null || c === undefined) {\n        return;\n    } else {\n        throw UnexpectedVirtualElement({\n            foreignObject: c,\n            parentVnode: {\n                tagName: tag,\n                properties: props\n            }\n        });\n    }\n}\n\nfunction transformProperties(props) {\n    for (var propName in props) {\n        if (props.hasOwnProperty(propName)) {\n            var value = props[propName];\n\n            if (isHook(value)) {\n                continue;\n            }\n\n            if (propName.substr(0, 3) === 'ev-') {\n                // add ev-foo support\n                props[propName] = evHook(value);\n            }\n        }\n    }\n}\n\nfunction isChild(x) {\n    return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x);\n}\n\nfunction isChildren(x) {\n    return typeof x === 'string' || isArray(x) || isChild(x);\n}\n\nfunction UnexpectedVirtualElement(data) {\n    var err = new Error();\n\n    err.type = 'virtual-hyperscript.unexpected.virtual-element';\n    err.message = 'Unexpected virtual child passed to h().\\n' +\n        'Expected a VNode / Vthunk / VWidget / string but:\\n' +\n        'got:\\n' +\n        errorString(data.foreignObject) +\n        '.\\n' +\n        'The parent vnode is:\\n' +\n        errorString(data.parentVnode)\n        '\\n' +\n        'Suggested fix: change your `h(..., [ ... ])` callsite.';\n    err.foreignObject = data.foreignObject;\n    err.parentVnode = data.parentVnode;\n\n    return err;\n}\n\nfunction UnsupportedValueType(data) {\n    var err = new Error();\n\n    err.type = 'virtual-hyperscript.unsupported.value-type';\n    err.message = 'Unexpected value type for input passed to h().\\n' +\n        'Expected a ' +\n        errorString(data.expected) +\n        ' but got:\\n' +\n        errorString(data.received) +\n        '.\\n' +\n        'The vnode is:\\n' +\n        errorString(data.Vnode)\n        '\\n' +\n        'Suggested fix: Cast the value passed to h() to a string using String(value).';\n    err.Vnode = data.Vnode;\n\n    return err;\n}\n\nfunction errorString(obj) {\n    try {\n        return JSON.stringify(obj, null, '    ');\n    } catch (e) {\n        return String(obj);\n    }\n}\n"
  },
  {
    "path": "virtual-hyperscript/parse-tag.js",
    "content": "'use strict';\n\nvar split = require('browser-split');\n\nvar classIdSplit = /([\\.#]?[a-zA-Z0-9\\u007F-\\uFFFF_:-]+)/;\nvar notClassId = /^\\.|#/;\n\nmodule.exports = parseTag;\n\nfunction parseTag(tag, props) {\n    if (!tag) {\n        return 'DIV';\n    }\n\n    var noId = !(props.hasOwnProperty('id'));\n\n    var tagParts = split(tag, classIdSplit);\n    var tagName = null;\n\n    if (notClassId.test(tagParts[1])) {\n        tagName = 'DIV';\n    }\n\n    var classes, part, type, i;\n\n    for (i = 0; i < tagParts.length; i++) {\n        part = tagParts[i];\n\n        if (!part) {\n            continue;\n        }\n\n        type = part.charAt(0);\n\n        if (!tagName) {\n            tagName = part;\n        } else if (type === '.') {\n            classes = classes || [];\n            classes.push(part.substring(1, part.length));\n        } else if (type === '#' && noId) {\n            props.id = part.substring(1, part.length);\n        }\n    }\n\n    if (classes) {\n        if (props.className) {\n            classes.push(props.className);\n        }\n\n        props.className = classes.join(' ');\n    }\n\n    return props.namespace ? tagName : tagName.toUpperCase();\n}\n"
  },
  {
    "path": "virtual-hyperscript/svg-attribute-namespace.js",
    "content": "'use strict';\n\nvar DEFAULT_NAMESPACE = null;\nvar EV_NAMESPACE = 'http://www.w3.org/2001/xml-events';\nvar XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';\nvar XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';\n\n// http://www.w3.org/TR/SVGTiny12/attributeTable.html\n// http://www.w3.org/TR/SVG/attindex.html\nvar SVG_PROPERTIES = {\n    'about': DEFAULT_NAMESPACE,\n    'accent-height': DEFAULT_NAMESPACE,\n    'accumulate': DEFAULT_NAMESPACE,\n    'additive': DEFAULT_NAMESPACE,\n    'alignment-baseline': DEFAULT_NAMESPACE,\n    'alphabetic': DEFAULT_NAMESPACE,\n    'amplitude': DEFAULT_NAMESPACE,\n    'arabic-form': DEFAULT_NAMESPACE,\n    'ascent': DEFAULT_NAMESPACE,\n    'attributeName': DEFAULT_NAMESPACE,\n    'attributeType': DEFAULT_NAMESPACE,\n    'azimuth': DEFAULT_NAMESPACE,\n    'bandwidth': DEFAULT_NAMESPACE,\n    'baseFrequency': DEFAULT_NAMESPACE,\n    'baseProfile': DEFAULT_NAMESPACE,\n    'baseline-shift': DEFAULT_NAMESPACE,\n    'bbox': DEFAULT_NAMESPACE,\n    'begin': DEFAULT_NAMESPACE,\n    'bias': DEFAULT_NAMESPACE,\n    'by': DEFAULT_NAMESPACE,\n    'calcMode': DEFAULT_NAMESPACE,\n    'cap-height': DEFAULT_NAMESPACE,\n    'class': DEFAULT_NAMESPACE,\n    'clip': DEFAULT_NAMESPACE,\n    'clip-path': DEFAULT_NAMESPACE,\n    'clip-rule': DEFAULT_NAMESPACE,\n    'clipPathUnits': DEFAULT_NAMESPACE,\n    'color': DEFAULT_NAMESPACE,\n    'color-interpolation': DEFAULT_NAMESPACE,\n    'color-interpolation-filters': DEFAULT_NAMESPACE,\n    'color-profile': DEFAULT_NAMESPACE,\n    'color-rendering': DEFAULT_NAMESPACE,\n    'content': DEFAULT_NAMESPACE,\n    'contentScriptType': DEFAULT_NAMESPACE,\n    'contentStyleType': DEFAULT_NAMESPACE,\n    'cursor': DEFAULT_NAMESPACE,\n    'cx': DEFAULT_NAMESPACE,\n    'cy': DEFAULT_NAMESPACE,\n    'd': DEFAULT_NAMESPACE,\n    'datatype': DEFAULT_NAMESPACE,\n    'defaultAction': DEFAULT_NAMESPACE,\n    'descent': DEFAULT_NAMESPACE,\n    'diffuseConstant': DEFAULT_NAMESPACE,\n    'direction': DEFAULT_NAMESPACE,\n    'display': DEFAULT_NAMESPACE,\n    'divisor': DEFAULT_NAMESPACE,\n    'dominant-baseline': DEFAULT_NAMESPACE,\n    'dur': DEFAULT_NAMESPACE,\n    'dx': DEFAULT_NAMESPACE,\n    'dy': DEFAULT_NAMESPACE,\n    'edgeMode': DEFAULT_NAMESPACE,\n    'editable': DEFAULT_NAMESPACE,\n    'elevation': DEFAULT_NAMESPACE,\n    'enable-background': DEFAULT_NAMESPACE,\n    'end': DEFAULT_NAMESPACE,\n    'ev:event': EV_NAMESPACE,\n    'event': DEFAULT_NAMESPACE,\n    'exponent': DEFAULT_NAMESPACE,\n    'externalResourcesRequired': DEFAULT_NAMESPACE,\n    'fill': DEFAULT_NAMESPACE,\n    'fill-opacity': DEFAULT_NAMESPACE,\n    'fill-rule': DEFAULT_NAMESPACE,\n    'filter': DEFAULT_NAMESPACE,\n    'filterRes': DEFAULT_NAMESPACE,\n    'filterUnits': DEFAULT_NAMESPACE,\n    'flood-color': DEFAULT_NAMESPACE,\n    'flood-opacity': DEFAULT_NAMESPACE,\n    'focusHighlight': DEFAULT_NAMESPACE,\n    'focusable': DEFAULT_NAMESPACE,\n    'font-family': DEFAULT_NAMESPACE,\n    'font-size': DEFAULT_NAMESPACE,\n    'font-size-adjust': DEFAULT_NAMESPACE,\n    'font-stretch': DEFAULT_NAMESPACE,\n    'font-style': DEFAULT_NAMESPACE,\n    'font-variant': DEFAULT_NAMESPACE,\n    'font-weight': DEFAULT_NAMESPACE,\n    'format': DEFAULT_NAMESPACE,\n    'from': DEFAULT_NAMESPACE,\n    'fx': DEFAULT_NAMESPACE,\n    'fy': DEFAULT_NAMESPACE,\n    'g1': DEFAULT_NAMESPACE,\n    'g2': DEFAULT_NAMESPACE,\n    'glyph-name': DEFAULT_NAMESPACE,\n    'glyph-orientation-horizontal': DEFAULT_NAMESPACE,\n    'glyph-orientation-vertical': DEFAULT_NAMESPACE,\n    'glyphRef': DEFAULT_NAMESPACE,\n    'gradientTransform': DEFAULT_NAMESPACE,\n    'gradientUnits': DEFAULT_NAMESPACE,\n    'handler': DEFAULT_NAMESPACE,\n    'hanging': DEFAULT_NAMESPACE,\n    'height': DEFAULT_NAMESPACE,\n    'horiz-adv-x': DEFAULT_NAMESPACE,\n    'horiz-origin-x': DEFAULT_NAMESPACE,\n    'horiz-origin-y': DEFAULT_NAMESPACE,\n    'id': DEFAULT_NAMESPACE,\n    'ideographic': DEFAULT_NAMESPACE,\n    'image-rendering': DEFAULT_NAMESPACE,\n    'in': DEFAULT_NAMESPACE,\n    'in2': DEFAULT_NAMESPACE,\n    'initialVisibility': DEFAULT_NAMESPACE,\n    'intercept': DEFAULT_NAMESPACE,\n    'k': DEFAULT_NAMESPACE,\n    'k1': DEFAULT_NAMESPACE,\n    'k2': DEFAULT_NAMESPACE,\n    'k3': DEFAULT_NAMESPACE,\n    'k4': DEFAULT_NAMESPACE,\n    'kernelMatrix': DEFAULT_NAMESPACE,\n    'kernelUnitLength': DEFAULT_NAMESPACE,\n    'kerning': DEFAULT_NAMESPACE,\n    'keyPoints': DEFAULT_NAMESPACE,\n    'keySplines': DEFAULT_NAMESPACE,\n    'keyTimes': DEFAULT_NAMESPACE,\n    'lang': DEFAULT_NAMESPACE,\n    'lengthAdjust': DEFAULT_NAMESPACE,\n    'letter-spacing': DEFAULT_NAMESPACE,\n    'lighting-color': DEFAULT_NAMESPACE,\n    'limitingConeAngle': DEFAULT_NAMESPACE,\n    'local': DEFAULT_NAMESPACE,\n    'marker-end': DEFAULT_NAMESPACE,\n    'marker-mid': DEFAULT_NAMESPACE,\n    'marker-start': DEFAULT_NAMESPACE,\n    'markerHeight': DEFAULT_NAMESPACE,\n    'markerUnits': DEFAULT_NAMESPACE,\n    'markerWidth': DEFAULT_NAMESPACE,\n    'mask': DEFAULT_NAMESPACE,\n    'maskContentUnits': DEFAULT_NAMESPACE,\n    'maskUnits': DEFAULT_NAMESPACE,\n    'mathematical': DEFAULT_NAMESPACE,\n    'max': DEFAULT_NAMESPACE,\n    'media': DEFAULT_NAMESPACE,\n    'mediaCharacterEncoding': DEFAULT_NAMESPACE,\n    'mediaContentEncodings': DEFAULT_NAMESPACE,\n    'mediaSize': DEFAULT_NAMESPACE,\n    'mediaTime': DEFAULT_NAMESPACE,\n    'method': DEFAULT_NAMESPACE,\n    'min': DEFAULT_NAMESPACE,\n    'mode': DEFAULT_NAMESPACE,\n    'name': DEFAULT_NAMESPACE,\n    'nav-down': DEFAULT_NAMESPACE,\n    'nav-down-left': DEFAULT_NAMESPACE,\n    'nav-down-right': DEFAULT_NAMESPACE,\n    'nav-left': DEFAULT_NAMESPACE,\n    'nav-next': DEFAULT_NAMESPACE,\n    'nav-prev': DEFAULT_NAMESPACE,\n    'nav-right': DEFAULT_NAMESPACE,\n    'nav-up': DEFAULT_NAMESPACE,\n    'nav-up-left': DEFAULT_NAMESPACE,\n    'nav-up-right': DEFAULT_NAMESPACE,\n    'numOctaves': DEFAULT_NAMESPACE,\n    'observer': DEFAULT_NAMESPACE,\n    'offset': DEFAULT_NAMESPACE,\n    'opacity': DEFAULT_NAMESPACE,\n    'operator': DEFAULT_NAMESPACE,\n    'order': DEFAULT_NAMESPACE,\n    'orient': DEFAULT_NAMESPACE,\n    'orientation': DEFAULT_NAMESPACE,\n    'origin': DEFAULT_NAMESPACE,\n    'overflow': DEFAULT_NAMESPACE,\n    'overlay': DEFAULT_NAMESPACE,\n    'overline-position': DEFAULT_NAMESPACE,\n    'overline-thickness': DEFAULT_NAMESPACE,\n    'panose-1': DEFAULT_NAMESPACE,\n    'path': DEFAULT_NAMESPACE,\n    'pathLength': DEFAULT_NAMESPACE,\n    'patternContentUnits': DEFAULT_NAMESPACE,\n    'patternTransform': DEFAULT_NAMESPACE,\n    'patternUnits': DEFAULT_NAMESPACE,\n    'phase': DEFAULT_NAMESPACE,\n    'playbackOrder': DEFAULT_NAMESPACE,\n    'pointer-events': DEFAULT_NAMESPACE,\n    'points': DEFAULT_NAMESPACE,\n    'pointsAtX': DEFAULT_NAMESPACE,\n    'pointsAtY': DEFAULT_NAMESPACE,\n    'pointsAtZ': DEFAULT_NAMESPACE,\n    'preserveAlpha': DEFAULT_NAMESPACE,\n    'preserveAspectRatio': DEFAULT_NAMESPACE,\n    'primitiveUnits': DEFAULT_NAMESPACE,\n    'propagate': DEFAULT_NAMESPACE,\n    'property': DEFAULT_NAMESPACE,\n    'r': DEFAULT_NAMESPACE,\n    'radius': DEFAULT_NAMESPACE,\n    'refX': DEFAULT_NAMESPACE,\n    'refY': DEFAULT_NAMESPACE,\n    'rel': DEFAULT_NAMESPACE,\n    'rendering-intent': DEFAULT_NAMESPACE,\n    'repeatCount': DEFAULT_NAMESPACE,\n    'repeatDur': DEFAULT_NAMESPACE,\n    'requiredExtensions': DEFAULT_NAMESPACE,\n    'requiredFeatures': DEFAULT_NAMESPACE,\n    'requiredFonts': DEFAULT_NAMESPACE,\n    'requiredFormats': DEFAULT_NAMESPACE,\n    'resource': DEFAULT_NAMESPACE,\n    'restart': DEFAULT_NAMESPACE,\n    'result': DEFAULT_NAMESPACE,\n    'rev': DEFAULT_NAMESPACE,\n    'role': DEFAULT_NAMESPACE,\n    'rotate': DEFAULT_NAMESPACE,\n    'rx': DEFAULT_NAMESPACE,\n    'ry': DEFAULT_NAMESPACE,\n    'scale': DEFAULT_NAMESPACE,\n    'seed': DEFAULT_NAMESPACE,\n    'shape-rendering': DEFAULT_NAMESPACE,\n    'slope': DEFAULT_NAMESPACE,\n    'snapshotTime': DEFAULT_NAMESPACE,\n    'spacing': DEFAULT_NAMESPACE,\n    'specularConstant': DEFAULT_NAMESPACE,\n    'specularExponent': DEFAULT_NAMESPACE,\n    'spreadMethod': DEFAULT_NAMESPACE,\n    'startOffset': DEFAULT_NAMESPACE,\n    'stdDeviation': DEFAULT_NAMESPACE,\n    'stemh': DEFAULT_NAMESPACE,\n    'stemv': DEFAULT_NAMESPACE,\n    'stitchTiles': DEFAULT_NAMESPACE,\n    'stop-color': DEFAULT_NAMESPACE,\n    'stop-opacity': DEFAULT_NAMESPACE,\n    'strikethrough-position': DEFAULT_NAMESPACE,\n    'strikethrough-thickness': DEFAULT_NAMESPACE,\n    'string': DEFAULT_NAMESPACE,\n    'stroke': DEFAULT_NAMESPACE,\n    'stroke-dasharray': DEFAULT_NAMESPACE,\n    'stroke-dashoffset': DEFAULT_NAMESPACE,\n    'stroke-linecap': DEFAULT_NAMESPACE,\n    'stroke-linejoin': DEFAULT_NAMESPACE,\n    'stroke-miterlimit': DEFAULT_NAMESPACE,\n    'stroke-opacity': DEFAULT_NAMESPACE,\n    'stroke-width': DEFAULT_NAMESPACE,\n    'surfaceScale': DEFAULT_NAMESPACE,\n    'syncBehavior': DEFAULT_NAMESPACE,\n    'syncBehaviorDefault': DEFAULT_NAMESPACE,\n    'syncMaster': DEFAULT_NAMESPACE,\n    'syncTolerance': DEFAULT_NAMESPACE,\n    'syncToleranceDefault': DEFAULT_NAMESPACE,\n    'systemLanguage': DEFAULT_NAMESPACE,\n    'tableValues': DEFAULT_NAMESPACE,\n    'target': DEFAULT_NAMESPACE,\n    'targetX': DEFAULT_NAMESPACE,\n    'targetY': DEFAULT_NAMESPACE,\n    'text-anchor': DEFAULT_NAMESPACE,\n    'text-decoration': DEFAULT_NAMESPACE,\n    'text-rendering': DEFAULT_NAMESPACE,\n    'textLength': DEFAULT_NAMESPACE,\n    'timelineBegin': DEFAULT_NAMESPACE,\n    'title': DEFAULT_NAMESPACE,\n    'to': DEFAULT_NAMESPACE,\n    'transform': DEFAULT_NAMESPACE,\n    'transformBehavior': DEFAULT_NAMESPACE,\n    'type': DEFAULT_NAMESPACE,\n    'typeof': DEFAULT_NAMESPACE,\n    'u1': DEFAULT_NAMESPACE,\n    'u2': DEFAULT_NAMESPACE,\n    'underline-position': DEFAULT_NAMESPACE,\n    'underline-thickness': DEFAULT_NAMESPACE,\n    'unicode': DEFAULT_NAMESPACE,\n    'unicode-bidi': DEFAULT_NAMESPACE,\n    'unicode-range': DEFAULT_NAMESPACE,\n    'units-per-em': DEFAULT_NAMESPACE,\n    'v-alphabetic': DEFAULT_NAMESPACE,\n    'v-hanging': DEFAULT_NAMESPACE,\n    'v-ideographic': DEFAULT_NAMESPACE,\n    'v-mathematical': DEFAULT_NAMESPACE,\n    'values': DEFAULT_NAMESPACE,\n    'version': DEFAULT_NAMESPACE,\n    'vert-adv-y': DEFAULT_NAMESPACE,\n    'vert-origin-x': DEFAULT_NAMESPACE,\n    'vert-origin-y': DEFAULT_NAMESPACE,\n    'viewBox': DEFAULT_NAMESPACE,\n    'viewTarget': DEFAULT_NAMESPACE,\n    'visibility': DEFAULT_NAMESPACE,\n    'width': DEFAULT_NAMESPACE,\n    'widths': DEFAULT_NAMESPACE,\n    'word-spacing': DEFAULT_NAMESPACE,\n    'writing-mode': DEFAULT_NAMESPACE,\n    'x': DEFAULT_NAMESPACE,\n    'x-height': DEFAULT_NAMESPACE,\n    'x1': DEFAULT_NAMESPACE,\n    'x2': DEFAULT_NAMESPACE,\n    'xChannelSelector': DEFAULT_NAMESPACE,\n    'xlink:actuate': XLINK_NAMESPACE,\n    'xlink:arcrole': XLINK_NAMESPACE,\n    'xlink:href': XLINK_NAMESPACE,\n    'xlink:role': XLINK_NAMESPACE,\n    'xlink:show': XLINK_NAMESPACE,\n    'xlink:title': XLINK_NAMESPACE,\n    'xlink:type': XLINK_NAMESPACE,\n    'xml:base': XML_NAMESPACE,\n    'xml:id': XML_NAMESPACE,\n    'xml:lang': XML_NAMESPACE,\n    'xml:space': XML_NAMESPACE,\n    'y': DEFAULT_NAMESPACE,\n    'y1': DEFAULT_NAMESPACE,\n    'y2': DEFAULT_NAMESPACE,\n    'yChannelSelector': DEFAULT_NAMESPACE,\n    'z': DEFAULT_NAMESPACE,\n    'zoomAndPan': DEFAULT_NAMESPACE\n};\n\nmodule.exports = SVGAttributeNamespace;\n\nfunction SVGAttributeNamespace(value) {\n  if (SVG_PROPERTIES.hasOwnProperty(value)) {\n    return SVG_PROPERTIES[value];\n  }\n}\n"
  },
  {
    "path": "virtual-hyperscript/svg.js",
    "content": "'use strict';\n\nvar isArray = require('x-is-array');\n\nvar h = require('./index.js');\n\n\nvar SVGAttributeNamespace = require('./svg-attribute-namespace');\nvar attributeHook = require('./hooks/attribute-hook');\n\nvar SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\nmodule.exports = svg;\n\nfunction svg(tagName, properties, children) {\n    if (!children && isChildren(properties)) {\n        children = properties;\n        properties = {};\n    }\n\n    properties = properties || {};\n\n    // set namespace for svg\n    properties.namespace = SVG_NAMESPACE;\n\n    var attributes = properties.attributes || (properties.attributes = {});\n\n    for (var key in properties) {\n        if (!properties.hasOwnProperty(key)) {\n            continue;\n        }\n\n        var namespace = SVGAttributeNamespace(key);\n\n        if (namespace === undefined) { // not a svg attribute\n            continue;\n        }\n\n        var value = properties[key];\n\n        if (typeof value !== 'string' &&\n            typeof value !== 'number' &&\n            typeof value !== 'boolean'\n        ) {\n            continue;\n        }\n\n        if (namespace !== null) { // namespaced attribute\n            properties[key] = attributeHook(namespace, value);\n            continue;\n        }\n\n        attributes[key] = value\n        properties[key] = undefined\n    }\n\n    return h(tagName, properties, children);\n}\n\nfunction isChildren(x) {\n    return typeof x === 'string' || isArray(x);\n}\n"
  },
  {
    "path": "virtual-hyperscript/test/attribute-hook.js",
    "content": "var test = require(\"tape\")\nvar doc = require(\"global/document\")\n\nvar attributeHook = require(\"../hooks/attribute-hook.js\")\nvar h = require(\"../index.js\")\nvar createElement = require(\"../../vdom/create-element\")\nvar patch = require(\"../../vdom/patch\")\nvar diff = require(\"../../vtree/diff\")\n\ntest(\"sets and removes namespaced attribute\", function (assert) {\n    var namespace = 'http://ns.com/my'\n\n    var hook1 = attributeHook(namespace, 'first value')\n    var hook2 = attributeHook(namespace, 'first value')\n    var hook3 = attributeHook(namespace, 'second value')\n\n    var first = h('div', {'myns:myattr': hook1})\n    var second = h('div', {'myns:myattr': hook2})\n    var third = h('div', {'myns:myattr': hook3})\n    var fourth = h('div', {})\n\n    var elem = createElement(first)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), 'first value')\n\n    var patches = diff(first, second)\n    patch(elem, patches)\n    // The value shouldn't change.\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), 'first value')\n\n    patches = diff(second, third)\n    patch(elem, patches)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), 'second value')\n\n    patches = diff(third, fourth)\n    patch(elem, patches)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), blankAttributeNS())\n\n    assert.end()\n})\n\ntest(\"sets the attribute if previous value was not an AttributeHook\", function (assert) {\n    var namespace = 'http://ns.com/my'\n\n    var OtherHook = function(namespace, value) {\n        this.namespace = namespace\n        this.value = value\n    }\n    OtherHook.prototype.hook = function() {}\n\n    var hook1 = new OtherHook(namespace, 'the value')\n    var hook2 = attributeHook(namespace, 'the value')\n\n    var first = h('div', {'myns:myattr': hook1})\n    var second = h('div', {'myns:myattr': hook2})\n\n    var elem = createElement(first)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), blankAttributeNS())\n\n    patches = diff(first, second)\n    patch(elem, patches)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), 'the value')\n\n    assert.end()\n})\n\ntest(\"sets the attribute if previous value uses a different namespace\", function (assert) {\n    var namespace = 'http://ns.com/my'\n\n    var hook1 = attributeHook('http://other.ns/', 'the value')\n    var hook2 = attributeHook(namespace, 'the value')\n\n    var first = h('div', {'myns:myattr': hook1})\n    var second = h('div', {'myns:myattr': hook2})\n\n    var elem = createElement(first)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), blankAttributeNS())\n\n    patches = diff(first, second)\n    patch(elem, patches)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), 'the value')\n\n    assert.end()\n})\n\ntest(\"removes the attribute if next value is not an AttributeHook\", function (assert) {\n    var namespace = 'http://ns.com/my'\n\n    var OtherHook = function(namespace, value) {\n        this.namespace = namespace\n        this.value = value\n    }\n    OtherHook.prototype.hook = function() {}\n\n    var hook1 = attributeHook(namespace, 'the value')\n    var hook2 = new OtherHook(namespace, 'the value')\n\n    var first = h('div', {'myns:myattr': hook1})\n    var second = h('div', {'myns:myattr': hook2})\n\n    var elem = createElement(first)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), 'the value')\n\n    patches = diff(first, second)\n    patch(elem, patches)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), blankAttributeNS())\n\n    assert.end()\n})\n\ntest(\"removes the attribute if next value uses a different namespace\", function (assert) {\n    var namespace = 'http://ns.com/my'\n\n    var hook1 = attributeHook(namespace, 'the value')\n    var hook2 = attributeHook('http://other.ns/', 'the value')\n\n    var first = h('div', {'myns:myattr': hook1})\n    var second = h('div', {'myns:myattr': hook2})\n\n    var elem = createElement(first)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), 'the value')\n\n    patches = diff(first, second)\n    patch(elem, patches)\n    assert.equal(elem.getAttributeNS(namespace, 'myattr'), blankAttributeNS())\n\n    assert.end()\n})\n\nfunction blankAttributeNS() {\n    // Most browsers conform to the latest version of the DOM spec,\n    // which requires `getAttributeNS` to return `null` when the attribute\n    // doesn't exist, but some browsers (including phantomjs) implement the\n    // old version of the spec and return an empty string instead, see:\n    // https://developer.mozilla.org/en-US/docs/Web/API/element.getAttributeNS#Return_value\n    var div = doc.createElement(\"div\")\n    return div.getAttributeNS(null, \"foo\")\n}\n"
  },
  {
    "path": "virtual-hyperscript/test/ev-hook.js",
    "content": "var test = require(\"tape\")\nvar EvStore = require(\"ev-store\")\n\nvar h = require(\"../index.js\")\nvar createElement = require(\"../../vdom/create-element\")\nvar patch = require(\"../../vdom/patch\")\nvar diff = require(\"../../vtree/diff\")\n\ntest(\"h with events\", function (assert) {\n    function one() {}\n\n    var left = h(\".foo\", {\n        \"ev-click\": one\n    })\n\n    var right = h(\".bar\", {})\n\n    var elem = createElement(left)\n\n    var ds1 = EvStore(elem)\n    assert.ok(ds1)\n    assert.equal(ds1.click, one)\n\n    var patches = diff(left, right)\n\n    patch(elem, patches)\n\n    var ds2 = EvStore(elem)\n    assert.ok(ds2)\n    assert.equal(ds1, ds2)\n    assert.equal(ds2.click, undefined)\n\n    assert.end()\n})\n"
  },
  {
    "path": "virtual-hyperscript/test/h.js",
    "content": "var test = require(\"tape\")\nvar EvStore = require('ev-store')\n\nvar h = require(\"../index\")\n\ntest(\"h is a function\", function (assert) {\n    assert.equal(typeof h, \"function\")\n    assert.end()\n})\n\ntest(\"h returns a vnode\", function (assert) {\n    assert.equal(h(\"div\").tagName, \"DIV\")\n\n    assert.end()\n})\n\ntest(\"h defaults tagName to uppercase\", function (assert) {\n    assert.equal(h(\"\").tagName, \"DIV\")\n    assert.equal(h(\"div\").tagName, \"DIV\")\n    assert.end()\n})\n\ntest(\"h preserves tagName case if namespace is given\", function (assert) {\n    assert.equal(h(\"test\", { namespace: \"http://www.w3.org/XML/1998/namespace\" }).tagName, \"test\")\n    assert.end()\n})\n\ntest(\"h has props\", function (assert) {\n    assert.equal(h(\"div\", {\n        foo: \"bar\"\n    }).properties.foo, \"bar\")\n\n    assert.end()\n})\n\ntest(\"h with text\", function (assert) {\n    var node = h(\"div\", \"text\")\n\n    assert.equal(node.children[0].text, \"text\")\n\n    assert.end()\n})\n\ntest(\"h with key\", function (assert) {\n    var node = h(\"div\", { key: \"bar\" })\n\n    assert.equal(node.key, \"bar\")\n\n    assert.end()\n})\n\n\ntest(\"h with ev-\", function (assert) {\n    var node = h(\"div\", { \"ev-foo\": \"bar\" })\n\n    assert.ok(node.properties[\"ev-foo\"])\n\n    var hook = node.properties[\"ev-foo\"]\n    var elem = {}\n    hook.hook(elem, \"ev-foo\")\n    assert.equal(EvStore(elem).foo, \"bar\")\n\n    assert.end()\n})\n\ntest(\"input.value soft hook\", function (assert) {\n    var node = h(\"input\", { value: \"text\" })\n\n    assert.equal(typeof node.properties.value, \"object\")\n    var elem = {}\n    node.properties.value.hook(elem, \"value\")\n\n    assert.equal(elem.value, \"text\")\n\n    assert.end()\n})\n\ntest(\"input.value must be string\", function (assert) {\n    assert.throws(function() {\n        var node = h(\"input\", { value: 1234 })\n    });\n\n    assert.throws(function() {\n        var node = h(\"input\", { value: {} })\n    });\n\n    assert.end()\n})\n\ntest(\"h with child\", function (assert) {\n    var node = h(\"div\", h(\"span\"))\n\n    assert.equal(node.children[0].tagName, \"SPAN\")\n\n    assert.end()\n})\n\ntest(\"h with children\", function (assert) {\n    var node = h(\"div\", [h(\"span\")])\n\n    assert.equal(node.children[0].tagName, \"SPAN\")\n\n    assert.end()\n})\n\ntest(\"h with null\", function (assert) {\n    var node = h(\"div\", null)\n    var node2 = h(\"div\", [null])\n\n    assert.equal(node.children.length, 0)\n    assert.equal(node2.children.length, 0)\n\n    assert.end()\n})\n\ntest(\"h with undefined\", function (assert) {\n    var node = h(\"div\", undefined)\n    var node2 = h(\"div\", [undefined])\n\n    assert.equal(node.children.length, 0)\n    assert.equal(node2.children.length, 0)\n\n    assert.end()\n})\n\ntest(\"h with foreign object\", function (assert) {\n    var errorSingleChild\n\n    try {\n        h(\"div\", null, { foreign: \"object\" })\n    } catch (e) {\n        errorSingleChild = e\n    }\n\n    var errorChildren\n\n    try {\n        h(\"div\", [{ foreign: \"object\" }])\n    } catch (e) {\n        errorChildren = e\n    }\n\n    assert.ok(errorSingleChild);\n    assert.ok(/Unexpected virtual child/.test(errorSingleChild.message))\n\n    assert.ok(errorChildren);\n    assert.ok(/Unexpected virtual child/.test(errorChildren.message))\n\n    assert.end()\n})\n\ntest(\"h with class\", function (assert) {\n    var node = h(\".foo\")\n\n    assert.equal(node.properties.className, \"foo\")\n\n    assert.end()\n})\n\ntest(\"h with id\", function (assert) {\n    var node = h(\"#foo\")\n\n    assert.equal(node.properties.id, \"foo\")\n\n    assert.end()\n})\n\ntest(\"h with empty string\", function (assert) {\n    var node = h(\"\")\n\n    assert.equal(node.tagName, \"DIV\")\n\n    assert.end()\n})\n\ntest(\"h with two classes\", function (assert) {\n    var node = h(\".foo\", { className: \"bar\" })\n\n    assert.equal(node.properties.className, \"foo bar\")\n\n    assert.end()\n})\n\ntest(\"h with two ids\", function (assert) {\n    var node = h(\"#foo\", { id: \"bar\" })\n\n    assert.equal(node.properties.id, \"bar\")\n\n    assert.end()\n})\n"
  },
  {
    "path": "virtual-hyperscript/test/index.js",
    "content": "require(\"./h.js\")\nrequire(\"./svg.js\")\nrequire(\"./ev-hook.js\")\nrequire(\"./attribute-hook.js\")\n"
  },
  {
    "path": "virtual-hyperscript/test/svg.js",
    "content": "var test = require(\"tape\")\nvar doc = require(\"global/document\")\n\nvar svg = require(\"../svg\")\nvar attributeHook = require(\"../hooks/attribute-hook\")\n\ntest(\"svg returns a vnode\", function (assert) {\n    assert.equal(svg(\"circle\").tagName, \"circle\")\n    assert.equal(svg(\"circle\").namespace, \"http://www.w3.org/2000/svg\")\n\n    assert.end()\n})\n\ntest(\"svg with text\", function (assert) {\n    var node = svg(\"circle\", \"dat text\")\n\n    assert.equal(node.children[0].text, \"dat text\")\n\n    assert.end()\n})\n\ntest(\"svg with properties\", function (assert) {\n    var node = svg(\"circle\", { width: \"40px\" })\n\n    assert.strictEqual(node.properties.attributes.width, \"40px\")\n\n    assert.end()\n})\n\ntest(\"svg properties are set\", function (assert) {\n    var node = svg(\"circle.test\", {\n        style: {\n            border: \"1px solid #000\"\n        },\n        width: \"40px\"\n    })\n\n    assert.strictEqual(node.properties.attributes.width, \"40px\")\n    assert.strictEqual(node.properties.width, undefined)\n    assert.strictEqual(\n        node.properties.style.border,\n        safeStyle(\"boder\", \"1px solid #000\")\n    )\n\n    assert.end()\n})\n\ntest(\"namespaced attributes are set with correct namespace\", function(assert) {\n    var node = svg(\"image\", {\n        \"xlink:href\": \"http://example.com/image.png\",\n        \"xml:space\": \"preserve\",\n     })\n\n    assert.strictEqual(node.properties.attributes[\"xlink:href\"], undefined)\n    assert.strictEqual(node.hooks[\"xlink:href\"].constructor, attributeHook)\n    assert.strictEqual(node.hooks[\"xlink:href\"].value, \"http://example.com/image.png\")\n    assert.strictEqual(node.hooks[\"xlink:href\"].namespace, \"http://www.w3.org/1999/xlink\")\n\n    assert.strictEqual(node.properties.attributes[\"xml:space\"], undefined)\n    assert.strictEqual(node.hooks[\"xml:space\"].constructor, attributeHook)\n    assert.strictEqual(node.hooks[\"xml:space\"].value, \"preserve\")\n    assert.strictEqual(node.hooks[\"xml:space\"].namespace, \"http://www.w3.org/XML/1998/namespace\")\n\n    assert.end()\n})\n\nfunction safeStyle(property, value) {\n    var div = doc.createElement(\"div\")\n    div.style[property] = value\n    return div.style[property]\n}\n"
  },
  {
    "path": "vnode/handle-thunk.js",
    "content": "var isVNode = require(\"./is-vnode\")\nvar isVText = require(\"./is-vtext\")\nvar isWidget = require(\"./is-widget\")\nvar isThunk = require(\"./is-thunk\")\n\nmodule.exports = handleThunk\n\nfunction handleThunk(a, b) {\n    var renderedA = a\n    var renderedB = b\n\n    if (isThunk(b)) {\n        renderedB = renderThunk(b, a)\n    }\n\n    if (isThunk(a)) {\n        renderedA = renderThunk(a, null)\n    }\n\n    return {\n        a: renderedA,\n        b: renderedB\n    }\n}\n\nfunction renderThunk(thunk, previous) {\n    var renderedThunk = thunk.vnode\n\n    if (!renderedThunk) {\n        renderedThunk = thunk.vnode = thunk.render(previous)\n    }\n\n    if (!(isVNode(renderedThunk) ||\n            isVText(renderedThunk) ||\n            isWidget(renderedThunk))) {\n        throw new Error(\"thunk did not return a valid node\");\n    }\n\n    return renderedThunk\n}\n"
  },
  {
    "path": "vnode/is-thunk.js",
    "content": "module.exports = isThunk\r\n\r\nfunction isThunk(t) {\r\n    return t && t.type === \"Thunk\"\r\n}\r\n"
  },
  {
    "path": "vnode/is-vhook.js",
    "content": "module.exports = isHook\n\nfunction isHook(hook) {\n    return hook &&\n      (typeof hook.hook === \"function\" && !hook.hasOwnProperty(\"hook\") ||\n       typeof hook.unhook === \"function\" && !hook.hasOwnProperty(\"unhook\"))\n}\n"
  },
  {
    "path": "vnode/is-vnode.js",
    "content": "var version = require(\"./version\")\n\nmodule.exports = isVirtualNode\n\nfunction isVirtualNode(x) {\n    return x && x.type === \"VirtualNode\" && x.version === version\n}\n"
  },
  {
    "path": "vnode/is-vtext.js",
    "content": "var version = require(\"./version\")\n\nmodule.exports = isVirtualText\n\nfunction isVirtualText(x) {\n    return x && x.type === \"VirtualText\" && x.version === version\n}\n"
  },
  {
    "path": "vnode/is-widget.js",
    "content": "module.exports = isWidget\n\nfunction isWidget(w) {\n    return w && w.type === \"Widget\"\n}\n"
  },
  {
    "path": "vnode/test/handle-thunk.js",
    "content": "var test = require(\"tape\")\n\nvar handleThunk = require(\"../handle-thunk\")\nvar VNode = require(\"../vnode\")\nvar VText = require(\"../vtext\")\n\ntest(\"render a new thunk to vnode\", function (assert) {\n    var aNode = {\n        render: function (previous) {\n            assert.error(\"Render should not be called for cached thunk\")\n        },\n        type: \"Thunk\"\n    }\n\n    aNode.vnode = new VNode(\"div\")\n\n    var renderedBNode = new VNode(\"div\")\n\n    var bNode = {\n        render: function (previous) {\n            assert.equal(previous, aNode)\n            return renderedBNode\n        },\n        type: \"Thunk\"\n    }\n\n    var result = handleThunk(aNode, bNode)\n\n    assert.equal(result.a, aNode.vnode)\n    assert.equal(result.b, renderedBNode)\n    assert.equal(bNode.vnode, renderedBNode)\n    assert.end()\n})\n\ntest(\"render a new thunk to vtext\", function (assert) {\n    var aNode = {\n        render: function (previous) {\n            assert.error(\"Render should not be called for cached thunk\")\n        },\n        type: \"Thunk\"\n    }\n\n    aNode.vnode = new VNode(\"div\")\n\n    var renderedBNode = new VText(\"text\")\n\n    var bNode = {\n        render: function (previous) {\n            assert.equal(previous, aNode)\n            return renderedBNode\n        },\n        type: \"Thunk\"\n    }\n\n    var result = handleThunk(aNode, bNode)\n\n    assert.equal(result.a, aNode.vnode)\n    assert.equal(result.b, renderedBNode)\n    assert.equal(bNode.vnode, renderedBNode)\n    assert.end()\n})\n\ntest(\"render a new thunk to a widget\", function (assert) {\n    var aNode = {\n        render: function (previous) {\n            assert.error(\"Render should not be called for cached thunk\")\n        },\n        type: \"Thunk\"\n    }\n\n    aNode.vnode = new VNode(\"div\")\n\n    var renderedBNode = { type: \"Widget\" }\n\n    var bNode = {\n        render: function (previous) {\n            assert.equal(previous, aNode)\n            return renderedBNode\n        },\n        type: \"Thunk\"\n    }\n\n    var result = handleThunk(aNode, bNode)\n\n    assert.equal(result.a, aNode.vnode)\n    assert.equal(result.b, renderedBNode)\n    assert.equal(bNode.vnode, renderedBNode)\n    assert.end()\n})\n\ntest(\"render current thunk to a thunk throws exception\", function (assert) {\n    var aNode = {\n        render: function (previous) {\n            assert.error(\"Render should not be called for cached thunk\")\n        },\n        type: \"Thunk\"\n    }\n\n    aNode.vnode = new VNode(\"div\")\n\n    var bNode = {\n        render: function (previous) {\n            assert.equal(previous, aNode)\n            return { type: \"Thunk\" }\n        },\n        type: \"Thunk\"\n    }\n\n    var result\n\n    try {\n        handleThunk(aNode, bNode)\n    } catch (e) {\n        result = e\n    }\n\n    assert.equal(result.message, \"thunk did not return a valid node\")\n    assert.end()\n})\n\ntest(\"render previous thunk to a thunk throws exception\", function (assert) {\n    var aNode = {\n        render: function (previous) {\n            assert.equal(previous, null)\n            return { type: \"Thunk\" }\n        },\n        type: \"Thunk\"\n    }\n\n    var renderedBNode = new VNode(\"div\")\n\n    var bNode = {\n        render: function (previous) {\n            assert.equal(previous, aNode)\n            return renderedBNode\n        },\n        type: \"Thunk\"\n    }\n\n    var result\n\n    try {\n        handleThunk(aNode, bNode)\n    } catch (e) {\n        result = e\n    }\n\n    assert.equal(result.message, \"thunk did not return a valid node\")\n    assert.end()\n})\n\ntest(\"normal nodes are returned\", function (assert) {\n    var aNode = new VNode('div')\n    var bNode = new VNode('div')\n\n    var result = handleThunk(aNode, bNode)\n\n    assert.equal(result.a, aNode)\n    assert.equal(result.b, bNode)\n    assert.end()\n})\n\n"
  },
  {
    "path": "vnode/test/index.js",
    "content": "require('./handle-thunk.js')\n"
  },
  {
    "path": "vnode/version.js",
    "content": "module.exports = \"2\"\n"
  },
  {
    "path": "vnode/vnode.js",
    "content": "var version = require(\"./version\")\nvar isVNode = require(\"./is-vnode\")\nvar isWidget = require(\"./is-widget\")\nvar isThunk = require(\"./is-thunk\")\nvar isVHook = require(\"./is-vhook\")\n\nmodule.exports = VirtualNode\n\nvar noProperties = {}\nvar noChildren = []\n\nfunction VirtualNode(tagName, properties, children, key, namespace) {\n    this.tagName = tagName\n    this.properties = properties || noProperties\n    this.children = children || noChildren\n    this.key = key != null ? String(key) : undefined\n    this.namespace = (typeof namespace === \"string\") ? namespace : null\n\n    var count = (children && children.length) || 0\n    var descendants = 0\n    var hasWidgets = false\n    var hasThunks = false\n    var descendantHooks = false\n    var hooks\n\n    for (var propName in properties) {\n        if (properties.hasOwnProperty(propName)) {\n            var property = properties[propName]\n            if (isVHook(property) && property.unhook) {\n                if (!hooks) {\n                    hooks = {}\n                }\n\n                hooks[propName] = property\n            }\n        }\n    }\n\n    for (var i = 0; i < count; i++) {\n        var child = children[i]\n        if (isVNode(child)) {\n            descendants += child.count || 0\n\n            if (!hasWidgets && child.hasWidgets) {\n                hasWidgets = true\n            }\n\n            if (!hasThunks && child.hasThunks) {\n                hasThunks = true\n            }\n\n            if (!descendantHooks && (child.hooks || child.descendantHooks)) {\n                descendantHooks = true\n            }\n        } else if (!hasWidgets && isWidget(child)) {\n            if (typeof child.destroy === \"function\") {\n                hasWidgets = true\n            }\n        } else if (!hasThunks && isThunk(child)) {\n            hasThunks = true;\n        }\n    }\n\n    this.count = count + descendants\n    this.hasWidgets = hasWidgets\n    this.hasThunks = hasThunks\n    this.hooks = hooks\n    this.descendantHooks = descendantHooks\n}\n\nVirtualNode.prototype.version = version\nVirtualNode.prototype.type = \"VirtualNode\"\n"
  },
  {
    "path": "vnode/vpatch.js",
    "content": "var version = require(\"./version\")\n\nVirtualPatch.NONE = 0\nVirtualPatch.VTEXT = 1\nVirtualPatch.VNODE = 2\nVirtualPatch.WIDGET = 3\nVirtualPatch.PROPS = 4\nVirtualPatch.ORDER = 5\nVirtualPatch.INSERT = 6\nVirtualPatch.REMOVE = 7\nVirtualPatch.THUNK = 8\n\nmodule.exports = VirtualPatch\n\nfunction VirtualPatch(type, vNode, patch) {\n    this.type = Number(type)\n    this.vNode = vNode\n    this.patch = patch\n}\n\nVirtualPatch.prototype.version = version\nVirtualPatch.prototype.type = \"VirtualPatch\"\n"
  },
  {
    "path": "vnode/vtext.js",
    "content": "var version = require(\"./version\")\n\nmodule.exports = VirtualText\n\nfunction VirtualText(text) {\n    this.text = String(text)\n}\n\nVirtualText.prototype.version = version\nVirtualText.prototype.type = \"VirtualText\"\n"
  },
  {
    "path": "vtree/README.md",
    "content": "# vtree\n\nA realtime tree diffing algorithm\n\n## Motivation\n\n`vtree` currently exists as part of `virtual-dom`. It is used for imitating\ndiff operations between two `vnode` structures that imitate the structure of\nthe active DOM node structure in the browser.\n\n## Example\n\n```js\nvar h = require(\"virtual-dom/h\")\nvar diff = require(\"virtual-dom/diff\")\n\nvar leftNode = h(\"div\")\nvar rightNode = h(\"text\")\n\nvar patches = diff(leftNode, rightNode)\n/*\n  -> {\n    a: leftNode,\n    0: vpatch<REPLACE>(rightNode) // a replace operation for the first node\n  }\n*/\n```\n\n## Installation\n\n`npm install virtual-dom`\n\n## Contributors\n\n - Matt Esch\n\n## MIT Licenced\n"
  },
  {
    "path": "vtree/diff-props.js",
    "content": "var isObject = require(\"is-object\")\nvar isHook = require(\"../vnode/is-vhook\")\n\nmodule.exports = diffProps\n\nfunction diffProps(a, b) {\n    var diff\n\n    for (var aKey in a) {\n        if (!(aKey in b)) {\n            diff = diff || {}\n            diff[aKey] = undefined\n        }\n\n        var aValue = a[aKey]\n        var bValue = b[aKey]\n\n        if (aValue === bValue) {\n            continue\n        } else if (isObject(aValue) && isObject(bValue)) {\n            if (getPrototype(bValue) !== getPrototype(aValue)) {\n                diff = diff || {}\n                diff[aKey] = bValue\n            } else if (isHook(bValue)) {\n                 diff = diff || {}\n                 diff[aKey] = bValue\n            } else {\n                var objectDiff = diffProps(aValue, bValue)\n                if (objectDiff) {\n                    diff = diff || {}\n                    diff[aKey] = objectDiff\n                }\n            }\n        } else {\n            diff = diff || {}\n            diff[aKey] = bValue\n        }\n    }\n\n    for (var bKey in b) {\n        if (!(bKey in a)) {\n            diff = diff || {}\n            diff[bKey] = b[bKey]\n        }\n    }\n\n    return diff\n}\n\nfunction getPrototype(value) {\n  if (Object.getPrototypeOf) {\n    return Object.getPrototypeOf(value)\n  } else if (value.__proto__) {\n    return value.__proto__\n  } else if (value.constructor) {\n    return value.constructor.prototype\n  }\n}\n"
  },
  {
    "path": "vtree/diff.js",
    "content": "var isArray = require(\"x-is-array\")\n\nvar VPatch = require(\"../vnode/vpatch\")\nvar isVNode = require(\"../vnode/is-vnode\")\nvar isVText = require(\"../vnode/is-vtext\")\nvar isWidget = require(\"../vnode/is-widget\")\nvar isThunk = require(\"../vnode/is-thunk\")\nvar handleThunk = require(\"../vnode/handle-thunk\")\n\nvar diffProps = require(\"./diff-props\")\n\nmodule.exports = diff\n\nfunction diff(a, b) {\n    var patch = { a: a }\n    walk(a, b, patch, 0)\n    return patch\n}\n\nfunction walk(a, b, patch, index) {\n    if (a === b) {\n        return\n    }\n\n    var apply = patch[index]\n    var applyClear = false\n\n    if (isThunk(a) || isThunk(b)) {\n        thunks(a, b, patch, index)\n    } else if (b == null) {\n\n        // If a is a widget we will add a remove patch for it\n        // Otherwise any child widgets/hooks must be destroyed.\n        // This prevents adding two remove patches for a widget.\n        if (!isWidget(a)) {\n            clearState(a, patch, index)\n            apply = patch[index]\n        }\n\n        apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b))\n    } else if (isVNode(b)) {\n        if (isVNode(a)) {\n            if (a.tagName === b.tagName &&\n                a.namespace === b.namespace &&\n                a.key === b.key) {\n                var propsPatch = diffProps(a.properties, b.properties)\n                if (propsPatch) {\n                    apply = appendPatch(apply,\n                        new VPatch(VPatch.PROPS, a, propsPatch))\n                }\n                apply = diffChildren(a, b, patch, apply, index)\n            } else {\n                apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))\n                applyClear = true\n            }\n        } else {\n            apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))\n            applyClear = true\n        }\n    } else if (isVText(b)) {\n        if (!isVText(a)) {\n            apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))\n            applyClear = true\n        } else if (a.text !== b.text) {\n            apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))\n        }\n    } else if (isWidget(b)) {\n        if (!isWidget(a)) {\n            applyClear = true\n        }\n\n        apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b))\n    }\n\n    if (apply) {\n        patch[index] = apply\n    }\n\n    if (applyClear) {\n        clearState(a, patch, index)\n    }\n}\n\nfunction diffChildren(a, b, patch, apply, index) {\n    var aChildren = a.children\n    var orderedSet = reorder(aChildren, b.children)\n    var bChildren = orderedSet.children\n\n    var aLen = aChildren.length\n    var bLen = bChildren.length\n    var len = aLen > bLen ? aLen : bLen\n\n    for (var i = 0; i < len; i++) {\n        var leftNode = aChildren[i]\n        var rightNode = bChildren[i]\n        index += 1\n\n        if (!leftNode) {\n            if (rightNode) {\n                // Excess nodes in b need to be added\n                apply = appendPatch(apply,\n                    new VPatch(VPatch.INSERT, null, rightNode))\n            }\n        } else {\n            walk(leftNode, rightNode, patch, index)\n        }\n\n        if (isVNode(leftNode) && leftNode.count) {\n            index += leftNode.count\n        }\n    }\n\n    if (orderedSet.moves) {\n        // Reorder nodes last\n        apply = appendPatch(apply, new VPatch(\n            VPatch.ORDER,\n            a,\n            orderedSet.moves\n        ))\n    }\n\n    return apply\n}\n\nfunction clearState(vNode, patch, index) {\n    // TODO: Make this a single walk, not two\n    unhook(vNode, patch, index)\n    destroyWidgets(vNode, patch, index)\n}\n\n// Patch records for all destroyed widgets must be added because we need\n// a DOM node reference for the destroy function\nfunction destroyWidgets(vNode, patch, index) {\n    if (isWidget(vNode)) {\n        if (typeof vNode.destroy === \"function\") {\n            patch[index] = appendPatch(\n                patch[index],\n                new VPatch(VPatch.REMOVE, vNode, null)\n            )\n        }\n    } else if (isVNode(vNode) && (vNode.hasWidgets || vNode.hasThunks)) {\n        var children = vNode.children\n        var len = children.length\n        for (var i = 0; i < len; i++) {\n            var child = children[i]\n            index += 1\n\n            destroyWidgets(child, patch, index)\n\n            if (isVNode(child) && child.count) {\n                index += child.count\n            }\n        }\n    } else if (isThunk(vNode)) {\n        thunks(vNode, null, patch, index)\n    }\n}\n\n// Create a sub-patch for thunks\nfunction thunks(a, b, patch, index) {\n    var nodes = handleThunk(a, b)\n    var thunkPatch = diff(nodes.a, nodes.b)\n    if (hasPatches(thunkPatch)) {\n        patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch)\n    }\n}\n\nfunction hasPatches(patch) {\n    for (var index in patch) {\n        if (index !== \"a\") {\n            return true\n        }\n    }\n\n    return false\n}\n\n// Execute hooks when two nodes are identical\nfunction unhook(vNode, patch, index) {\n    if (isVNode(vNode)) {\n        if (vNode.hooks) {\n            patch[index] = appendPatch(\n                patch[index],\n                new VPatch(\n                    VPatch.PROPS,\n                    vNode,\n                    undefinedKeys(vNode.hooks)\n                )\n            )\n        }\n\n        if (vNode.descendantHooks || vNode.hasThunks) {\n            var children = vNode.children\n            var len = children.length\n            for (var i = 0; i < len; i++) {\n                var child = children[i]\n                index += 1\n\n                unhook(child, patch, index)\n\n                if (isVNode(child) && child.count) {\n                    index += child.count\n                }\n            }\n        }\n    } else if (isThunk(vNode)) {\n        thunks(vNode, null, patch, index)\n    }\n}\n\nfunction undefinedKeys(obj) {\n    var result = {}\n\n    for (var key in obj) {\n        result[key] = undefined\n    }\n\n    return result\n}\n\n// List diff, naive left to right reordering\nfunction reorder(aChildren, bChildren) {\n    // O(M) time, O(M) memory\n    var bChildIndex = keyIndex(bChildren)\n    var bKeys = bChildIndex.keys\n    var bFree = bChildIndex.free\n\n    if (bFree.length === bChildren.length) {\n        return {\n            children: bChildren,\n            moves: null\n        }\n    }\n\n    // O(N) time, O(N) memory\n    var aChildIndex = keyIndex(aChildren)\n    var aKeys = aChildIndex.keys\n    var aFree = aChildIndex.free\n\n    if (aFree.length === aChildren.length) {\n        return {\n            children: bChildren,\n            moves: null\n        }\n    }\n\n    // O(MAX(N, M)) memory\n    var newChildren = []\n\n    var freeIndex = 0\n    var freeCount = bFree.length\n    var deletedItems = 0\n\n    // Iterate through a and match a node in b\n    // O(N) time,\n    for (var i = 0 ; i < aChildren.length; i++) {\n        var aItem = aChildren[i]\n        var itemIndex\n\n        if (aItem.key) {\n            if (bKeys.hasOwnProperty(aItem.key)) {\n                // Match up the old keys\n                itemIndex = bKeys[aItem.key]\n                newChildren.push(bChildren[itemIndex])\n\n            } else {\n                // Remove old keyed items\n                itemIndex = i - deletedItems++\n                newChildren.push(null)\n            }\n        } else {\n            // Match the item in a with the next free item in b\n            if (freeIndex < freeCount) {\n                itemIndex = bFree[freeIndex++]\n                newChildren.push(bChildren[itemIndex])\n            } else {\n                // There are no free items in b to match with\n                // the free items in a, so the extra free nodes\n                // are deleted.\n                itemIndex = i - deletedItems++\n                newChildren.push(null)\n            }\n        }\n    }\n\n    var lastFreeIndex = freeIndex >= bFree.length ?\n        bChildren.length :\n        bFree[freeIndex]\n\n    // Iterate through b and append any new keys\n    // O(M) time\n    for (var j = 0; j < bChildren.length; j++) {\n        var newItem = bChildren[j]\n\n        if (newItem.key) {\n            if (!aKeys.hasOwnProperty(newItem.key)) {\n                // Add any new keyed items\n                // We are adding new items to the end and then sorting them\n                // in place. In future we should insert new items in place.\n                newChildren.push(newItem)\n            }\n        } else if (j >= lastFreeIndex) {\n            // Add any leftover non-keyed items\n            newChildren.push(newItem)\n        }\n    }\n\n    var simulate = newChildren.slice()\n    var simulateIndex = 0\n    var removes = []\n    var inserts = []\n    var simulateItem\n\n    for (var k = 0; k < bChildren.length;) {\n        var wantedItem = bChildren[k]\n        simulateItem = simulate[simulateIndex]\n\n        // remove items\n        while (simulateItem === null && simulate.length) {\n            removes.push(remove(simulate, simulateIndex, null))\n            simulateItem = simulate[simulateIndex]\n        }\n\n        if (!simulateItem || simulateItem.key !== wantedItem.key) {\n            // if we need a key in this position...\n            if (wantedItem.key) {\n                if (simulateItem && simulateItem.key) {\n                    // if an insert doesn't put this key in place, it needs to move\n                    if (bKeys[simulateItem.key] !== k + 1) {\n                        removes.push(remove(simulate, simulateIndex, simulateItem.key))\n                        simulateItem = simulate[simulateIndex]\n                        // if the remove didn't put the wanted item in place, we need to insert it\n                        if (!simulateItem || simulateItem.key !== wantedItem.key) {\n                            inserts.push({key: wantedItem.key, to: k})\n                        }\n                        // items are matching, so skip ahead\n                        else {\n                            simulateIndex++\n                        }\n                    }\n                    else {\n                        inserts.push({key: wantedItem.key, to: k})\n                    }\n                }\n                else {\n                    inserts.push({key: wantedItem.key, to: k})\n                }\n                k++\n            }\n            // a key in simulate has no matching wanted key, remove it\n            else if (simulateItem && simulateItem.key) {\n                removes.push(remove(simulate, simulateIndex, simulateItem.key))\n            }\n        }\n        else {\n            simulateIndex++\n            k++\n        }\n    }\n\n    // remove all the remaining nodes from simulate\n    while(simulateIndex < simulate.length) {\n        simulateItem = simulate[simulateIndex]\n        removes.push(remove(simulate, simulateIndex, simulateItem && simulateItem.key))\n    }\n\n    // If the only moves we have are deletes then we can just\n    // let the delete patch remove these items.\n    if (removes.length === deletedItems && !inserts.length) {\n        return {\n            children: newChildren,\n            moves: null\n        }\n    }\n\n    return {\n        children: newChildren,\n        moves: {\n            removes: removes,\n            inserts: inserts\n        }\n    }\n}\n\nfunction remove(arr, index, key) {\n    arr.splice(index, 1)\n\n    return {\n        from: index,\n        key: key\n    }\n}\n\nfunction keyIndex(children) {\n    var keys = {}\n    var free = []\n    var length = children.length\n\n    for (var i = 0; i < length; i++) {\n        var child = children[i]\n\n        if (child.key) {\n            keys[child.key] = i\n        } else {\n            free.push(i)\n        }\n    }\n\n    return {\n        keys: keys,     // A hash of key name to index\n        free: free      // An array of unkeyed item indices\n    }\n}\n\nfunction appendPatch(apply, patch) {\n    if (apply) {\n        if (isArray(apply)) {\n            apply.push(patch)\n        } else {\n            apply = [apply, patch]\n        }\n\n        return apply\n    } else {\n        return patch\n    }\n}\n"
  },
  {
    "path": "vtree/test/diff-props.js",
    "content": "var test = require(\"tape\")\r\nvar diffProps = require(\"../diff-props\")\r\n\r\ntest(\"add attributes to empty attributes\", function (assert) {\r\n    var propsA = {\r\n      attributes : {}\r\n    }\r\n    var propsB = {\r\n        attributes : {\r\n            class : \"standard\",\r\n            \"e-text\" : \"custom\"\r\n        }\r\n    }\r\n\r\n    var diff = diffProps(propsA,propsB)\r\n    assert.equal(diff.attributes.class, \"standard\")\r\n    assert.equal(diff.attributes[\"e-text\"], \"custom\")\r\n\r\n    assert.end()\r\n})\r\n"
  },
  {
    "path": "vtree/test/index.js",
    "content": "require(\"./diff-props\")\n"
  }
]