[
  {
    "path": ".gitattributes",
    "content": "dist/* -diff"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\ncoverage\n*.log"
  },
  {
    "path": ".travis.yml",
    "content": "sudo: false\nlanguage: node_js\nnode_js:\n  - \"stable\"\n\nafter_script: NODE_ENV=test istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
  },
  {
    "path": "README.md",
    "content": "# Ripple Fullstack\n\nOn the server:\n\n**`index.js`**\n```js\nconst ripple = require('rijs')({ dir: __dirname })\n```\n\nOn the client: \n\n**`pages/index.html`**\n```html\n<script src=\"/ripple.js\"></script>\n```\n\nRun it:\n\n```\n$ node index.js\n```\n\nThis starts up a server on a random port and statically serves your `/pages` directory. You can also specify a `port` to always use, or pass an existing HTTP `server` (e.g. from express). \n\nClients will then just be streamed the fine-grained resources they are using (i.e. everything is lazy loaded, no bundling, no over-fetching). \n\nRipple keeps clients/servers in sync by replicating an immutable log of actions in the background, and subsequently the view - or other modules - which are reactively updated when the local store is updated.\n\nThat's it! No boilerplate necessary, no build pipeline, no special transpilation, no magical CLI.\n\nThe basic API is:\n\n```js\nripple(name)        // getter\nripple(name, body)  // setter\nripple.on('change', (name, change) => { .. })\n```\n\n&nbsp; \n## Components\n\nLet's add a (Web) Component to the page:\n\n**`index.html`**\n```diff\n<script src=\"/ripple.js\"></script>\n+ <my-app></my-app>\n```\n\nLet's define the component:\n\n**`resources/my-app.js:`**\n\n```js\nexport default () => ()\n```\n\nRipple is agnostic to _how_ you write your components, they should just be idempotent: a single render function. \n\nThis is fine:\n\n**`resources/my-app.js:`**\n\n```js\nexport default (node, data) => node.innerHTML = 'Hello World!'\n```\n\nOr using some DOM-diff helper:\n\n**`resources/my-app.js:`**\n\n```js\nexport default (node, data) => jsx(node)`<h1>Hello World</h1>`\n```\n\nOr using [once](https://github.com/utilise/once#once)/D3 joins:\n\n**`resources/my-app.js:`**\n\n```js\nexport default (node, data) => {\n  once(node)\n    ('h1', 1)\n      .text('Hello World')\n})\n```\n\nFor more info about writing idempotent components, see [this spec](https://github.com/pemrouz/vanilla).\n\n&nbsp;\n## State/Data\n\nThe first parameter of the component is the node to update. \n\nThe second parameter contains all the state and data the component needs to render:\n\n```js\nexport default function component(node, data){ ... }\n```\n\n* You can inject data resources by adding the name of the resources to the data attribute:\n\n    ```html\n    <my-shop data=\"stock\">\n    ```\n\n    ```js\n    export default function shop({ stock }){ ... }\n    ```\n\n    Declaring the data needed on a component is used to reactively rerender it when the data changes. \n\n    Alternatively, you can use `ripple.pull` directly to retrieve a resource, which has similar semantics to [dynamic `import()`](https://github.com/tc39/proposal-dynamic-import) (i.e. resolves from local cache or returns a single promise):\n\n    ```js\n    const dependency = await pull('dependency')\n    ```\n\n* The other option is to explicitly pass down data to the component from the parent:\n\n    ```js\n    once(node)\n      ('my-shop', { stock })\n    ```\n\n    The helper function will set the state and redraw, so redrawing a parent will redraw it's children. If you want to do it yourself:\n\n    ```js\n    element.state = { stock }\n    element.draw()\n    ```\n\n&nbsp;\n## Defaults\n\nYou can set defaults using the ES6 syntax:\n\n```js\nexport default function shop({ stock = [] }){ ... }\n```\n\nIf you need to persist defaults on the component's state object, you can use a small [helper function](https://github.com/utilise/utilise#--defaults):\n\n```js\nexport default function shop(state){ \n  const stock = defaults(state, 'stock', [])\n}\n```\n\n&nbsp;\n## Updates\n\n#### Local state\n\nWhenever you need to update local state, just change the `state` and invoke a redraw (like a game loop):\n\n```js\nexport default function abacus(node, state){ \n  const o = once(node)\n      , { counter = 0 } = state\n\n  o('span', 1)\n    .text(counter)\n\n  o('button', 1)\n    .text('increment')\n    .on('click.increment' d => {\n      state.counter++\n      o.draw()\n    })\n}\n```\n\n#### Global state\n\nWhenever you need to update global state, you can simply compute the new value and register it again which will trigger an update:\n\n```js\nripple('stock', {\n  apples: 10\n, oranges: 20\n, pomegranates: 30\n})\n```\n\nOr if you just want to change a part of the resource, use a [functional operator](https://github.com/utilise/utilise#--set) to apply a finer-grained diff and trigger an update:\n\n```js\nupdate('pomegranates', 20)(ripple('stock'))\n// same as: set({ type: 'update', key: 'pomegranate', value: 20 })(ripple('stock'))\n```\n\nUsing logs of atomic diffs combines the benefits of immutability with a saner way to synchronise state across a distributed environment.\n\nComponents are rAF batched by default. You can access the list of all relevant changes since the last render in your component via `node.changes` to make it more performant if necessary.\n\n&nbsp;\n## Events\n\nDispatch an event on the root element to communicate changes to parents (`node.dispatchEvent`).\n\n&nbsp;\n## Routing\n\nRouting is handled by your top-level component: Simply parse the URL to determine what children to render and invoke a redraw of your application when the route has changed: \n\n```js\nexport function app(node, data){\n  const o = once(node)\n      , { pathname } = location\n\n  o('page-dashboard', pathname == '/dashboard')\n  o('page-login', pathname == '/login')\n \n  once(window)\n    .on('popstate.nav', d => o.draw())\n}\n```\n\nThis solution is not tied to any library, and you may not need one at all. \n\nFor advanced uses cases, checkout [decouter](https://github.com/pemrouz/decouter).\n\n&nbsp;\n## Styling\n\nYou can author your stylesheets assuming they are completely isolated, using the Web Component syntax (`:host` etc).\n\nThey will either be inserted in the shadow root of the element, or scoped and added to the head if there is no shadow.\n\nBy default, the CSS resource `component-name.css` will be automatically applied to the component `component-name`.\n\nBut you can apply multiple stylesheets to a component too: just extend the `css` attribute. \n\n&nbsp;\n## Folder Convention\n\nAll files in your `/resources` folder will be automatically registered (except tests etc). You can organise it as you like, but I recommend using the convention: a folder for each component (to co-locate JS, CSS and tests), and a `data` folder for the resources that make up your domain model.\n\n```\nresources\n├── data\n│   ├── stock.js\n│   ├── order.js\n│   └── ...\n├── my-app\n│   ├── my-app.js\n│   ├── my-app.css\n│   └── test.js\n├── another-component\n│   ├── another-component.js\n│   ├── another-component.css\n│   └── test.js\n└── ...\n```\n\nHot reloading works out of the box. Any changes to these files will be instantly reflected everywhere.\n\n&nbsp;\n## Loading Resources\n\nYou can also get/set resources yourselves imperatively:\n\n```js\nripple(name)       // getter\nripple(name, body) // setter\n```\n\nOr for example import resources from other packages:\n\n```js\nripple\n  .resource(require('external-module-1'))\n  .resource(require('external-module-2'))\n  .resource(require('external-module-3'))\n```\n\nYou can also create resources that proxy to [fero](https://github.com/pemrouz/fero)) services too.\n\n&nbsp;\n## Offline\n\nResources are currently cached in `localStorage`. \n\nThis means even _before_ any network interaction, your application renders the last-known-good-state for a superfast startup. \n\nThen as resources are streamed in, the relevant parts of the application are updated.\n\nNote: Caching of resources will be improved by using ServiceWorkers under the hood instead soon ([#27](https://github.com/rijs/fullstack/issues/27))\n\n&nbsp;\n## Render Middleware\n\nBy default the draw function just invokes the function on an element. You can extend this without any framework hooks using the explicit decorator pattern:\n\n```js\n// in component\nexport default function component(node, data){\n  middleware(node, data)\n}\n\n// around component\nexport default middleware(function component(node, data){\n  \n})\n\n// for all components\nripple.draw = middleware(ripple.draw)\n```\n\nA few useful middleware included in this build are:\n\n### Needs\n\n[This middleware](https://github.com/rijs/needs#ripple--needs) reads the `needs` header and applies the attributes onto the element. The component does not render until all dependencies are available. This is useful when a component needs to define its own dependencies. You can also supply a function to dynamically calculate the required resources.\n\n```js\nexport default {\n  name: 'my-component'\n, body: function(){}\n, headers: { needs: '[css=..][data=..]' }\n}\n```\n\n### Shadow\n\nIf supported by the browser, a shadow root will be created for each component. The component will render into the shadow DOM rather than the light DOM.\n\n\n### Perf (Optional)\n\nThis one is not included by default, but you can use this to log out the time each component takes to render.\n\nOther debugging tips: \n\n* Check `ripple.resources` for a snapshot of your application. Resources are in the [tuple format](https://github.com/rijs/core#ripple--core) `{ name, body, headers }`.\n\n* Check `$0.state` on an element to see the state object it was last rendered with or manipulate it.\n\n&nbsp;\n## Sync\n\nYou can define a `from` function in the resource headers which will process requests from the client:\n\n```js\nconst from = (req, res) => \n  req.data.type == 'REGISTER' ? register(req, res)\n: req.data.type == 'FORGOT'   ? forgot(req, res)\n: req.data.type == 'LOGOUT'   ? logout(req, res)\n: req.data.type == 'RESET'    ? reset(req, res)\n: req.data.type == 'LOGIN'    ? login(req, res)\n                              : false\n\nmodule.exports = { \n  name: 'users'\n, body: {}\n, headers: { from } \n}\n```\n\nThis can return a single value, a promise or a stream. On the client you make requests with `ripple.send(name, type, value)`. This returns an awaitable [stream](https://github.com/utilise/emitterify/#emitterify).\n\nYou can also use the `.subscribe` API to subscribe to all or part of a resource. The key can be arbitrarily deep, and multiple keys will be merged into a single object. \n\n```js\nripple.subscribe(name, key)\nripple.subscribe(name, [keys])\n```\n\nSubscriptions are automatically deduplicated are ref-counted, so components can indepedently subscribe to the data they need without worrying about this.\n\nNote that you can also use `ripple.get` instead of subscribe if you just want to get a single value and then automatically unsubscribe.\n\n&nbsp;\n## Ripple Minimal\n\nIf you have don't have backend for your frontend, checkout [rijs/minimal](https://github.com/rijs/minimal) which is a client-side only build of Ripple.\n\nYou can also adjust your own framework by [adding/removing modules](https://github.com/rijs/minimal/blob/master/src/index.js#L1-L11).\n\n&nbsp;\n## Docs\n\nSee [rijs/docs](https://github.com/rijs/docs) for more guides, index of modules, API reference, etc\n"
  },
  {
    "path": "client/ripple.bundle.js",
    "content": "var rijs = (function () {\n\t'use strict';\n\n\tfunction commonjsRequire () {\n\t\tthrow new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs');\n\t}\n\n\tfunction createCommonjsModule(fn, module) {\n\t\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n\t}\n\n\tvar client = typeof window != 'undefined';\n\n\tvar client$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: client,\n\t\t__moduleExports: client\n\t});\n\n\tvar promise_1 = promise;\n\n\tfunction promise() {\n\t  var resolve\n\t    , reject\n\t    , p = new Promise(function(res, rej){ \n\t        resolve = res, reject = rej;\n\t      });\n\n\t  arguments.length && resolve(arguments[0]);\n\t  p.resolve = resolve;\n\t  p.reject  = reject;\n\t  return p\n\t}\n\n\tvar promise$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: promise_1,\n\t\t__moduleExports: promise_1\n\t});\n\n\tvar flatten = function flatten(p,v){ \n\t  if (v instanceof Array) { v = v.reduce(flatten, []); }\n\t  return (p = p || []), p.concat(v) \n\t};\n\n\tvar flatten$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: flatten,\n\t\t__moduleExports: flatten\n\t});\n\n\tvar has = function has(o, k) {\n\t  return k in o\n\t};\n\n\tvar has$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: has,\n\t\t__moduleExports: has\n\t});\n\n\tvar has$2 = ( has$1 && has ) || has$1;\n\n\tvar def = function def(o, p, v, w){\n\t  if (o.host && o.host.nodeName) { o = o.host; }\n\t  if (p.name) { v = p, p = p.name; }\n\t  !has$2(o, p) && Object.defineProperty(o, p, { value: v, writable: w });\n\t  return o[p]\n\t};\n\n\tvar def$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: def,\n\t\t__moduleExports: def\n\t});\n\n\tvar promise$2 = ( promise$1 && promise_1 ) || promise$1;\n\n\tvar flatten$2 = ( flatten$1 && flatten ) || flatten$1;\n\n\tvar def$2 = ( def$1 && def ) || def$1;\n\n\tvar noop = function(){};\n\n\tvar emitterify = function emitterify(body, hooks) {\n\t  body = body || {};\n\t  hooks = hooks || {};\n\t  def$2(body, 'emit', emit, 1);\n\t  def$2(body, 'once', once, 1);\n\t  def$2(body, 'off', off, 1);\n\t  def$2(body, 'on', on, 1);\n\t  body.on['*'] = body.on['*'] || [];\n\t  return body\n\n\t  function emit(type, pm, filter) {\n\t    var li = body.on[type.split('.')[0]] || []\n\t      , results = [];\n\n\t    for (var i = 0; i < li.length; i++)\n\t      { if (!li[i].ns || !filter || filter(li[i].ns))\n\t        { results.push(call(li[i].isOnce ? li.splice(i--, 1)[0] : li[i], pm)); } }\n\n\t    for (var i = 0; i < body.on['*'].length; i++)\n\t      { results.push(call(body.on['*'][i], [type, pm])); }\n\n\t    return results.reduce(flatten$2, [])\n\t  }\n\n\t  function call(cb, pm){\n\t    return cb.next             ? cb.next(pm) \n\t         : pm instanceof Array ? cb.apply(body, pm) \n\t                               : cb.call(body, pm) \n\t  }\n\n\t  function on(type, opts, isOnce) {\n\t    var id = type.split('.')[0]\n\t      , ns = type.split('.')[1]\n\t      , li = body.on[id] = body.on[id] || []\n\t      , cb = typeof opts == 'function' ? opts : 0;\n\n\t    return !cb &&  ns ? (cb = body.on[id]['$'+ns]) ? cb : push(observable(body, opts))\n\t         : !cb && !ns ? push(observable(body, opts))\n\t         :  cb &&  ns ? push((remove(li, body.on[id]['$'+ns] || -1), cb))\n\t         :  cb && !ns ? push(cb)\n\t                      : false\n\n\t    function push(cb){\n\t      cb.isOnce = isOnce;\n\t      cb.type = id;\n\t      if (ns) { body.on[id]['$'+(cb.ns = ns)] = cb; }\n\t      li.push(cb)\n\t      ;(hooks.on || noop)(cb);\n\t      return cb.next ? cb : body\n\t    }\n\t  }\n\n\t  function once(type, callback){\n\t    return body.on(type, callback, true)\n\t  }\n\n\t  function remove(li, cb) {\n\t    var i = li.length;\n\t    while (~--i) \n\t      { if (cb == li[i] || cb == li[i].fn || !cb)\n\t        { (hooks.off || noop)(li.splice(i, 1)[0]); } }\n\t  }\n\n\t  function off(type, cb) {\n\t    remove((body.on[type] || []), cb);\n\t    if (cb && cb.ns) { delete body.on[type]['$'+cb.ns]; }\n\t    return body\n\t  }\n\n\t  function observable(parent, opts) {\n\t    opts = opts || {};\n\t    var o = emitterify(opts.base || promise$2());\n\t    o.i = 0;\n\t    o.li = [];\n\t    o.fn = opts.fn;\n\t    o.parent = parent;\n\t    o.source = opts.fn ? o.parent.source : o;\n\t    \n\t    o.on('stop', function(reason){\n\t      o.type\n\t        ? o.parent.off(o.type, o)\n\t        : o.parent.off(o);\n\t      return o.reason = reason\n\t    });\n\n\t    o.each = function(fn) {\n\t      var n = fn.next ? fn : observable(o, { fn: fn });\n\t      o.li.push(n);\n\t      return n\n\t    };\n\n\t    o.pipe = function(fn) {\n\t      return fn(o)\n\t    };\n\n\t    o.map = function(fn){\n\t      return o.each(function(d, i, n){ return n.next(fn(d, i, n)) })\n\t    };\n\n\t    o.filter = function(fn){\n\t      return o.each(function(d, i, n){ return fn(d, i, n) && n.next(d) })\n\t    };\n\n\t    o.reduce = function(fn, acc) {\n\t      return o.each(function(d, i, n){ return n.next(acc = fn(acc, d, i, n)) })\n\t    };\n\n\t    o.unpromise = function(){ \n\t      var n = observable(o, { base: {}, fn: function(d){ return n.next(d) } });\n\t      o.li.push(n);\n\t      return n\n\t    };\n\n\t    o.next = function(value) {\n\t      o.resolve && o.resolve(value);\n\t      return o.li.length \n\t           ? o.li.map(function(n){ return n.fn(value, n.i++, n) })\n\t           : value\n\t    };\n\n\t    o.until = function(stop){\n\t      return stop.each ? stop.each(o.stop) // TODO: check clean up on stop too\n\t           : stop.then ? stop.then(o.stop)\n\t           : stop.call ? o.filter(stop).map(o.stop)\n\t                       : 0\n\t    };\n\n\t    o.off = function(fn){\n\t      return remove(o.li, fn), o\n\t    };\n\n\t    o.start = function(){\n\t      o.source.emit('start');\n\t      return o\n\t    };\n\n\t    o.stop = function(reason){\n\t      return o.source.emit('stop', reason)\n\t    };\n\n\t    o[Symbol.asyncIterator] = function(){ \n\t      return { \n\t        next: function(){ \n\t          return o.wait = new Promise(function(resolve){\n\t            o.wait = true;\n\t            o.map(function(d, i, n){\n\t              delete o.wait;\n\t              o.off(n);\n\t              resolve({ value: d, done: false });\n\t            });\n\t            o.emit('pull', o);\n\t          })\n\t        }\n\t      }\n\t    };\n\n\t    return o\n\t  }\n\t};\n\n\tvar emitterify$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: emitterify,\n\t\t__moduleExports: emitterify\n\t});\n\n\tvar is_1 = is;\n\tis.fn      = isFunction;\n\tis.str     = isString;\n\tis.num     = isNumber;\n\tis.obj     = isObject;\n\tis.lit     = isLiteral;\n\tis.bol     = isBoolean;\n\tis.truthy  = isTruthy;\n\tis.falsy   = isFalsy;\n\tis.arr     = isArray;\n\tis.null    = isNull;\n\tis.def     = isDef;\n\tis.in      = isIn;\n\tis.promise = isPromise;\n\tis.stream  = isStream;\n\n\tfunction is(v){\n\t  return function(d){\n\t    return d == v\n\t  }\n\t}\n\n\tfunction isFunction(d) {\n\t  return typeof d == 'function'\n\t}\n\n\tfunction isBoolean(d) {\n\t  return typeof d == 'boolean'\n\t}\n\n\tfunction isString(d) {\n\t  return typeof d == 'string'\n\t}\n\n\tfunction isNumber(d) {\n\t  return typeof d == 'number'\n\t}\n\n\tfunction isObject(d) {\n\t  return typeof d == 'object'\n\t}\n\n\tfunction isLiteral(d) {\n\t  return d.constructor == Object\n\t}\n\n\tfunction isTruthy(d) {\n\t  return !!d == true\n\t}\n\n\tfunction isFalsy(d) {\n\t  return !!d == false\n\t}\n\n\tfunction isArray(d) {\n\t  return d instanceof Array\n\t}\n\n\tfunction isNull(d) {\n\t  return d === null\n\t}\n\n\tfunction isDef(d) {\n\t  return typeof d !== 'undefined'\n\t}\n\n\tfunction isPromise(d) {\n\t  return d instanceof Promise\n\t}\n\n\tfunction isStream(d) {\n\t  return !!(d && d.next)\n\t}\n\n\tfunction isIn(set) {\n\t  return function(d){\n\t    return !set ? false  \n\t         : set.indexOf ? ~set.indexOf(d)\n\t         : d in set\n\t  }\n\t}\n\n\tvar is$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: is_1,\n\t\t__moduleExports: is_1\n\t});\n\n\tvar client$2 = ( client$1 && client ) || client$1;\n\n\tvar is$2 = ( is$1 && is_1 ) || is$1;\n\n\tvar colorfill_1 = colorfill();\n\n\tfunction colorfill(){\n\t  /* istanbul ignore next */\n\t  ['red', 'green', 'bold', 'grey', 'strip'].forEach(function(color) {\n\t    !is$2.str(String.prototype[color]) && Object.defineProperty(String.prototype, color, {\n\t      get: function() {\n\t        return String(this)\n\t      } \n\t    });\n\t  });\n\t}\n\n\tvar identity = function identity(d) {\n\t  return d\n\t};\n\n\tvar identity$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: identity,\n\t\t__moduleExports: identity\n\t});\n\n\tvar wrap = function wrap(d){\n\t  return function(){\n\t    return d\n\t  }\n\t};\n\n\tvar wrap$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: wrap,\n\t\t__moduleExports: wrap\n\t});\n\n\tvar keys = function keys(o) { \n\t  return Object.keys(is$2.obj(o) || is$2.fn(o) ? o : {})\n\t};\n\n\tvar keys$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: keys,\n\t\t__moduleExports: keys\n\t});\n\n\tvar str = function str(d){\n\t  return d === 0 ? '0'\n\t       : !d ? ''\n\t       : is$2.fn(d) ? '' + d\n\t       : is$2.obj(d) ? JSON.stringify(d)\n\t       : String(d)\n\t};\n\n\tvar str$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: str,\n\t\t__moduleExports: str\n\t});\n\n\tvar wrap$2 = ( wrap$1 && wrap ) || wrap$1;\n\n\tvar keys$2 = ( keys$1 && keys ) || keys$1;\n\n\tvar str$2 = ( str$1 && str ) || str$1;\n\n\tvar key = function key(k, v){ \n\t  var set = arguments.length > 1\n\t    , keys = is$2.fn(k) ? [] : str$2(k).split('.').filter(Boolean)\n\t    , root = keys.shift();\n\n\t  return function deep(o, i){\n\t    var masked = {};\n\t    \n\t    return !o ? undefined \n\t         : !is$2.num(k) && !k ? (set ? replace(o, v) : o)\n\t         : is$2.arr(k) ? (k.map(copy), masked)\n\t         : o[k] || !keys.length ? (set ? ((o[k] = is$2.fn(v) ? v(o[k], i) : v), o)\n\t                                       :  (is$2.fn(k) ? k(o) : o[k]))\n\t                                : (set ? (key(keys.join('.'), v)(o[root] ? o[root] : (o[root] = {})), o)\n\t                                       :  key(keys.join('.'))(o[root]))\n\n\t    function copy(k){\n\t      var val = key(k)(o);\n\t      val = is$2.fn(v)       ? v(val) \n\t          : val == undefined ? v\n\t                           : val;\n\t    if (val != undefined) \n\t        { key(k, is$2.fn(val) ? wrap$2(val) : val)(masked); }\n\t    }\n\n\t    function replace(o, v) {\n\t      keys$2(o).map(function(k){ delete o[k]; });\n\t      keys$2(v).map(function(k){ o[k] = v[k]; });\n\t      return o\n\t    }\n\t  }\n\t};\n\n\tvar key$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: key,\n\t\t__moduleExports: key\n\t});\n\n\tvar key$2 = ( key$1 && key ) || key$1;\n\n\tvar header = function header(header$1, value) {\n\t  var getter = arguments.length == 1;\n\t  return function(d){ \n\t    return !d || !d.headers ? null\n\t         : getter ? key$2(header$1)(d.headers)\n\t                  : key$2(header$1)(d.headers) == value\n\t  }\n\t};\n\n\tvar header$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: header,\n\t\t__moduleExports: header\n\t});\n\n\tvar datum = function datum(node){\n\t  return node.__data__\n\t};\n\n\tvar datum$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: datum,\n\t\t__moduleExports: datum\n\t});\n\n\tvar datum$2 = ( datum$1 && datum ) || datum$1;\n\n\tvar from_1 = from;\n\tfrom.parent = fromParent;\n\n\tfunction from(o){\n\t  return function(k){\n\t    return key$2(k)(o)\n\t  }\n\t}\n\n\tfunction fromParent(k){\n\t  return datum$2(this.parentNode)[k]\n\t}\n\n\tvar from$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: from_1,\n\t\t__moduleExports: from_1\n\t});\n\n\tvar from$2 = ( from$1 && from_1 ) || from$1;\n\n\tvar values = function values(o) {\n\t  return !o ? [] : keys$2(o).map(from$2(o))\n\t};\n\n\tvar values$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: values,\n\t\t__moduleExports: values\n\t});\n\n\tvar to = { \n\t  arr: toArray\n\t, obj: toObject\n\t};\n\n\tfunction toArray(d){\n\t  return Array.prototype.slice.call(d, 0)\n\t}\n\n\tfunction toObject(d) {\n\t  var by = 'id'\n\t    ;\n\n\t  return arguments.length == 1 \n\t    ? (by = d, reduce)\n\t    : reduce.apply(this, arguments)\n\n\t  function reduce(p,v,i){\n\t    if (i === 0) { p = {}; }\n\t    p[is$2.fn(by) ? by(v, i) : v[by]] = v;\n\t    return p\n\t  }\n\t}\n\tvar to_1 = to.arr;\n\tvar to_2 = to.obj;\n\n\tvar to$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: to,\n\t\t__moduleExports: to,\n\t\tarr: to_1,\n\t\tobj: to_2\n\t});\n\n\tvar to$2 = ( to$1 && to ) || to$1;\n\n\tvar za = function az() {\n\t  return compare(to$2.arr(arguments))\n\t};\n\n\tfunction compare(keys){ \n\t  return function(a, b){\n\t    if (!keys.length) { return 0 }\n\t    var k = keys[0]\n\t      , ka = key$2(k)(a) || ''\n\t      , kb = key$2(k)(b) || '';\n\n\t    return ka < kb ?  1 \n\t         : ka > kb ? -1 \n\t         : compare(keys.slice(1))(a, b)\n\t  }\n\t}\n\n\tvar za$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: za,\n\t\t__moduleExports: za\n\t});\n\n\tvar includes = function includes(pattern){\n\t  return function(d){\n\t    return d && d.indexOf && ~d.indexOf(pattern)\n\t  }\n\t};\n\n\tvar includes$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: includes,\n\t\t__moduleExports: includes\n\t});\n\n\tvar includes$2 = ( includes$1 && includes ) || includes$1;\n\n\tvar text = {\n\t  header: 'text/plain'\n\t, check: function check(res){ return !includes$2('.html')(res.name) && !includes$2('.css')(res.name) && is$2.str(res.body) }\n\t};\n\tvar text_1 = text.header;\n\tvar text_2 = text.check;\n\n\tvar text$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: text,\n\t\t__moduleExports: text,\n\t\theader: text_1,\n\t\tcheck: text_2\n\t});\n\n\tvar owner = client$2 ? /* istanbul ignore next */ window : global;\n\n\tvar owner$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: owner,\n\t\t__moduleExports: owner\n\t});\n\n\tvar owner$2 = ( owner$1 && owner ) || owner$1;\n\n\tvar err = function err(ns){\n\t  return function(d){\n\t    if (!owner$2.console || !console.error.apply) { return d; }\n\t    is$2.arr(arguments[2]) && (arguments[2] = arguments[2].length);\n\t    var args = to$2.arr(arguments)\n\t      , prefix = '[err][' + (new Date()).toISOString() + ']' + ns;\n\n\t    args.unshift(prefix.red ? prefix.red : prefix);\n\t    return console.error.apply(console, args), d\n\t  }\n\t};\n\n\tvar err$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: err,\n\t\t__moduleExports: err\n\t});\n\n\tvar log = function log(ns){\n\t  return function(d){\n\t    if (!owner$2.console || !console.log.apply) { return d; }\n\t    is$2.arr(arguments[2]) && (arguments[2] = arguments[2].length);\n\t    var args = to$2.arr(arguments)\n\t      , prefix = '[log][' + (new Date()).toISOString() + ']' + ns;\n\n\t    args.unshift(prefix.grey ? prefix.grey : prefix);\n\t    return console.log.apply(console, args), d\n\t  }\n\t};\n\n\tvar log$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: log,\n\t\t__moduleExports: log\n\t});\n\n\tvar split = function split(delimiter){\n\t  return function(d){\n\t    return d.split(delimiter)\n\t  }\n\t};\n\n\tvar split$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: split,\n\t\t__moduleExports: split\n\t});\n\n\tvar split$2 = ( split$1 && split ) || split$1;\n\n\tvar identity$2 = ( identity$1 && identity ) || identity$1;\n\n\tvar DEBUG = strip((client$2 ? (owner$2.location.search.match(/debug=(.*?)(&|$)/) || [])[1] : key$2('process.env.DEBUG')(owner$2)) || '')\n\t  , whitelist = DEBUG.split(',').map(split$2('/'));\n\n\tvar deb = function deb(ns){\n\t  return DEBUG == '*' || whitelist.some(matches(ns)) ? out : identity$2\n\n\t  function out(d){\n\t    if (!owner$2.console || !console.log.apply) { return d; }\n\t    is$2.arr(arguments[2]) && (arguments[2] = arguments[2].length);\n\t    var args = to$2.arr(arguments)\n\t      , prefix = '[deb][' + (new Date()).toISOString() + ']' + ns;\n\n\t    args.unshift(prefix.grey ? prefix.grey : prefix);\n\t    return console.log.apply(console, args), d\n\t  }\n\t};\n\n\tfunction matches(ns) {\n\t  ns = strip(ns).split('/');\n\t  return function(arr){\n\t    return arr.length == 1 ? arr[0] == ns[0]\n\t         : arr.length == 2 ? arr[0] == ns[0] && arr[1] == ns[1]\n\t                           : false \n\t  }\n\t}\n\n\tfunction strip(str) {\n\t  return str.replace(/(\\[|\\])/g, '')\n\t}\n\n\tvar deb$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: deb,\n\t\t__moduleExports: deb\n\t});\n\n\tvar emitterify$2 = ( emitterify$1 && emitterify ) || emitterify$1;\n\n\tvar header$2 = ( header$1 && header ) || header$1;\n\n\tvar values$2 = ( values$1 && values ) || values$1;\n\n\tvar za$2 = ( za$1 && za ) || za$1;\n\n\tvar text$2 = ( text$1 && text ) || text$1;\n\n\tvar require$$0$1 = ( err$1 && err ) || err$1;\n\n\tvar require$$0$2 = ( log$1 && log ) || log$1;\n\n\tvar require$$2 = ( deb$1 && deb ) || deb$1;\n\n\t// -------------------------------------------\n\t// API: Gets or sets a resource\n\t// -------------------------------------------\n\t// ripple('name')     - returns the resource body if it exists\n\t// ripple('name')     - creates & returns resource if it doesn't exist\n\t// ripple('name', {}) - creates & returns resource, with specified name and body\n\t// ripple({ ... })    - creates & returns resource, with specified name, body and headers\n\t// ripple.resources   - returns raw resources\n\t// ripple.register    - alias for ripple\n\t// ripple.on          - event listener for changes - all resources\n\t// ripple('name').on  - event listener for changes - resource-specific\n\n\tvar rijs_core = function core(ref){\n\t  if ( ref === void 0 ) ref = {};\n\t  var aliases = ref.aliases; if ( aliases === void 0 ) aliases = {};\n\n\t  log$2('creating');\n\n\t  ripple.resources = {};\n\t  ripple.link      = link(ripple);\n\t  ripple.register  = ripple;\n\t  ripple.types     = types();\n\t  return linkify(emitterify$2(ripple), aliases)\n\n\t  function ripple(name, body, headers){\n\t    return !name                                            ? ripple\n\t         : is$2.arr(name)                                     ? name.map(ripple)\n\t         : is$2.promise(name)                                 ? name.then(ripple).catch(err$2)\n\t         : is$2.obj(name) && !name.name                       ? ripple(values$2(name))\n\t         : is$2.fn(name)  &&  name.resources                  ? ripple(values$2(name.resources))\n\t         : is$2.str(name) && !body &&  ripple.resources[name] ? ripple.resources[name].body\n\t         : is$2.str(name) && !body && !ripple.resources[name] ? undefined\n\t         : is$2.str(name) &&  body                            ? register(ripple)({ name: name, body: body, headers: headers })\n\t         : is$2.obj(name)                                     ? register(ripple)(name)\n\t         : (err$2('could not find or create resource', name), false)\n\t  }\n\t};\n\n\tvar register = function (ripple) { return function (ref) {\n\t  var name = ref.name;\n\t  var body = ref.body;\n\t  var headers = ref.headers; if ( headers === void 0 ) headers = {};\n\n\t  name = ripple.aliases.src[name] || name;\n\t  if (is$2.promise(body)) { return body.then(function (body) { return register(ripple)({ name: name, body: body, headers: headers }); }).catch(err$2) }\n\t  deb$2('registering', name);\n\t  var res = normalise(ripple)({ name: name, body: body, headers: headers });\n\n\t  if (!res) { return err$2('failed to register', name), false }\n\t  ripple.resources[name] = res;\n\t  ripple.emit('change', [name, { \n\t    type: 'update'\n\t  , value: res.body\n\t  , time: now(res)\n\t  }]);\n\n\t  return ripple.resources[name].body\n\t}; };\n\n\tvar normalise = function (ripple) { return function (res) {\n\t  if (!header$2('content-type')(res)) { values$2(ripple.types).sort(za$2('priority')).some(contentType(res)); }\n\t  if (!header$2('content-type')(res)) { return err$2('could not understand resource', res), false }\n\t  return parse(ripple)(res)\n\t}; };\n\n\tvar parse = function (ripple) { return function (res) {\n\t  var type = header$2('content-type')(res);\n\t  if (!ripple.types[type]) { return err$2('could not understand type', type), false }\n\t  return (ripple.types[type].parse || identity$2)(res)\n\t}; };\n\n\tvar contentType = function (res) { return function (type) { return type.check(res) && (res.headers['content-type'] = type.header); }; };\n\n\tvar types = function () { return [text$2].reduce(to$2.obj('header'), 1); };\n\n\tvar linkify = function (ripple, aliases) {\n\t  ripple.aliases = { dst: {}, src: {} };\n\t  for (var name in aliases)\n\t    { ripple.link(aliases[name], name); }\n\t  return ripple\n\t};\n\n\tvar link = function (ripple) { return function (from, to) {\n\t  ripple.aliases.src[from] = to;\n\t  ripple.aliases.dst[to] = from;\n\t  Object.defineProperty(ripple.resources, from, { \n\t    get: function get(){ return ripple.resources[to] } \n\t  , set: function set(value){ ripple.resources[to] = value; } \n\t  });\n\t}; };\n\n\tvar err$2 = require$$0$1('[ri/core]')\n\t    , log$2 = require$$0$2('[ri/core]')\n\t    , deb$2 = require$$2('[ri/core]')\n\t    , now = function (d, t) { return (t = key$2('body.log.length')(d), is$2.num(t) ? t - 1 : t); };\n\n\tvar rijs_core$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: rijs_core,\n\t\t__moduleExports: rijs_core\n\t});\n\n\t// -------------------------------------------\n\t// Exposes a convenient global instance \n\t// -------------------------------------------\n\tvar rijs_singleton = function singleton(ripple){\n\t  log$3('creating');\n\t  if (!owner$2.ripple) { owner$2.ripple = ripple; }\n\t  return ripple\n\t};\n\n\tvar log$3 = require$$0$2('[ri/singleton]');\n\n\tvar rijs_singleton$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: rijs_singleton,\n\t\t__moduleExports: rijs_singleton\n\t});\n\n\tvar copy = function copy(from, to){ \n\t  return function(d){ \n\t    return to[d] = from[d], d\n\t  }\n\t};\n\n\tvar copy$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: copy,\n\t\t__moduleExports: copy\n\t});\n\n\tvar copy$2 = ( copy$1 && copy ) || copy$1;\n\n\tvar overwrite = function overwrite(to){ \n\t  return function(from){\n\t    keys$2(from)\n\t      .map(copy$2(from, to));\n\t        \n\t    return to\n\t  }\n\t};\n\n\tvar overwrite$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: overwrite,\n\t\t__moduleExports: overwrite\n\t});\n\n\tvar not = function not(fn){\n\t  return function(){\n\t    return !fn.apply(this, arguments)\n\t  }\n\t};\n\n\tvar not$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: not,\n\t\t__moduleExports: not\n\t});\n\n\tvar not$2 = ( not$1 && not ) || not$1;\n\n\tvar extend = function extend(to){ \n\t  return function(from){\n\t    keys$2(from)\n\t      .filter(not$2(is$2.in(to)))\n\t      .map(copy$2(from, to));\n\n\t    return to\n\t  }\n\t};\n\n\tvar extend$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: extend,\n\t\t__moduleExports: extend\n\t});\n\n\tvar merge_1 = merge;\n\n\tfunction merge(to){ \n\t  return function(from){\n\t    for (x in from) \n\t      { is$2.obj(from[x]) && is$2.obj(to[x])\n\t        ? merge(to[x])(from[x])\n\t        : (to[x] = from[x]); }\n\t    return to\n\t  }\n\t}\n\n\tvar merge$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: merge_1,\n\t\t__moduleExports: merge_1\n\t});\n\n\tvar attr = function attr(name, value) {\n\t  var args = arguments.length;\n\t  \n\t  return !is$2.str(name) && args == 2 ? attr(arguments[1]).call(this, arguments[0])\n\t       : !is$2.str(name) && args == 3 ? attr(arguments[1], arguments[2]).call(this, arguments[0])\n\t       :  function(el){\n\t            var ctx = this || {};\n\t            el = ctx.nodeName || is$2.fn(ctx.node) ? ctx : el;\n\t            el = el.node ? el.node() : el;\n\t            el = el.host || el;\n\n\t            return args > 1 && value === false ? el.removeAttribute(name)\n\t                 : args > 1                    ? (el.setAttribute(name, value), value)\n\t                 : el.attributes.getNamedItem(name) \n\t                && el.attributes.getNamedItem(name).value\n\t          } \n\t};\n\n\tvar attr$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: attr,\n\t\t__moduleExports: attr\n\t});\n\n\tvar act = { add: add, update: update, remove: remove }\n\t  , str$3 = JSON.stringify\n\t  , parse$1 = JSON.parse;\n\n\tvar set = function set(d, skipEmit) {\n\t  return function(o, existing, max) {\n\t    if (!is$2.obj(o) && !is$2.fn(o))\n\t      { return o }\n\n\t    if (!is$2.obj(d)) { \n\t      var log = existing || o.log || []\n\t        , root = o;\n\n\t      if (!is$2.def(max)) { max = log.max || 0; }\n\t      if (!max)    { log = []; }\n\t      if (max < 0) { log = log.concat(null); }\n\t      if (max > 0) {\n\t        var s = str$3(o);\n\t        root = parse$1(s); \n\t        log = log.concat({ type: 'update', value: parse$1(s), time: log.length });\n\t      } \n\n\t      def$2(log, 'max', max);\n\t      \n\t      root.log \n\t        ? (root.log = log)\n\t        : def$2(emitterify$2(root, null), 'log', log, 1);\n\n\t      return root\n\t    }\n\n\t    if (is$2.def(d.key)) {\n\t      if (!apply(o, d.type, (d.key = '' + d.key).split('.').filter(Boolean), d.value))\n\t        { return false }\n\t    } else\n\t      { return false }\n\n\t    if (o.log && o.log.max) \n\t      { o.log.push((d.time = o.log.length, o.log.max > 0 ? d : null)); }\n\n\t    if (!skipEmit && o.emit)\n\t      { o.emit('change', d); }\n\n\t    return o\n\t  }\n\t};\n\n\tfunction apply(body, type, path, value) {\n\t  var next = path.shift();\n\n\t  if (!act[type]) \n\t    { return false }\n\t  if (path.length) { \n\t    if (!(next in body)) \n\t      { if (type == 'remove') { return true }\n\t      else { body[next] = {}; } }\n\t    return apply(body[next], type, path, value)\n\t  }\n\t  else {\n\t    return !act[type](body, next, value)\n\t  }\n\t}\n\n\tfunction add(o, k, v) {\n\t  is$2.arr(o) \n\t    ? o.splice(k, 0, v) \n\t    : (o[k] = v);\n\t}\n\n\tfunction update(o, k, v) {\n\t  if (!is$2.num(k) && !k) {\n\t    if (!is$2.obj(v)) { return true }\n\t    for (var x in o) { delete o[x]; }\n\t    for (var x in v) { o[x] = v[x]; }\n\t  } else \n\t    { o[k] = v; } \n\t}\n\n\tfunction remove(o, k, v) { \n\t  is$2.arr(o) \n\t    ? o.splice(k, 1)\n\t    : delete o[k];\n\t}\n\n\tvar set$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: set,\n\t\t__moduleExports: set\n\t});\n\n\tvar overwrite$2 = ( overwrite$1 && overwrite ) || overwrite$1;\n\n\tvar extend$2 = ( extend$1 && extend ) || extend$1;\n\n\tvar merge$2 = ( merge$1 && merge_1 ) || merge$1;\n\n\tvar attr$2 = ( attr$1 && attr ) || attr$1;\n\n\tvar set$2 = ( set$1 && set ) || set$1;\n\n\t// -------------------------------------------\n\t// Adds support for data resources\n\t// -------------------------------------------\n\tvar rijs_data = function data(ripple){\n\t  log$4('creating');\n\t  ripple\n\t    .on('change.data')\n\t    .filter(function (ref) {\n\t      var name = ref[0];\n\t      var change = ref[1];\n\n\t      return header$2('content-type', 'application/data')(ripple.resources[name]);\n\t  })\n\t    .filter(function (ref) {\n\t      var name = ref[0];\n\t      var change = ref[1];\n\n\t      return change && change.key;\n\t  })\n\t    .map(function (ref) {\n\t      var name = ref[0];\n\t      var change = ref[1];\n\n\t      return ripple\n\t      .resources[name]\n\t      .body\n\t      .emit('change', (change || null), not$2(is$2.in(['bubble'])));\n\t  });\n\n\t  ripple.types['application/data'] = {\n\t    header: 'application/data'\n\t  , ext: '*.data.js'\n\t  , selector: function (res) { return (\"[data~=\\\"\" + (res.name) + \"\\\"]\"); }\n\t  , extract: function (el) { return (attr$2(\"data\")(el) || '').split(' '); }\n\t  , check: function (res) { return is$2.obj(res.body); }\n\t  , load: function load(res) {\n\t      var exported = commonjsRequire(res.headers.path);\n\t      exported = exported.default || exported;\n\t      exported = is$2.fn(exported) ? exported(ripple) : exported;\n\t      res.headers['content-type'] = this.header;\n\t      ripple(merge$2(res)(exported));\n\t      return ripple.resources[res.name]\n\t    }\n\t  , parse: function parse(res){ \n\t      var existing = ripple.resources[res.name] || {};\n\n\t      extend$2(res.headers)(existing.headers);\n\t      res.body = set$2()(\n\t        res.body || []\n\t      , existing.body && existing.body.log\n\t      , is$2.num(res.headers.log) ? res.headers.log : -1\n\t      );\n\t      overwrite$2(res.body.on)(listeners(existing));\n\t      res.body.on('change.bubble', function (change) {\n\t        ripple.emit('change', ripple.change = [res.name, change], not$2(is$2.in(['data'])));\n\t        delete ripple.change;\n\t      });\n\n\t      if (res.headers.loaded && !res.headers.loading)\n\t        { res.headers.loading = Promise.resolve(res.headers.loaded(ripple, res))\n\t          .then(function () { \n\t            delete res.headers.loading;\n\t            return res\n\t          }); }\n\n\t      return res\n\t    }\n\t  };\n\n\t  return ripple\n\t};\n\n\tvar log$4 = require$$0$2('[ri/types/data]')\n\t    , listeners = key$2('body.on');\n\n\tvar rijs_data$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: rijs_data,\n\t\t__moduleExports: rijs_data\n\t});\n\n\tvar djbx = function (str) {\n\t  var hash = 5381\n\t    , i = str.length;\n\n\t  while (i)\n\t    { hash = (hash * 33) ^ str.charCodeAt(--i); }\n\n\t  return hash >>> 0\n\t};\n\n\tvar djbx$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: djbx,\n\t\t__moduleExports: djbx\n\t});\n\n\tvar hash = ( djbx$1 && djbx ) || djbx$1;\n\n\tvar client_1 = function(ripple) {\n\t    return log$5(\"creating\"), ripple.types[\"text/css\"] = {\n\t        header: \"text/css\",\n\t        ext: \"*.css\",\n\t        selector: function (res) { return (\"[css~=\\\"\" + (res.name) + \"\\\"]\"); },\n\t        extract: function (el) { return (attr$2(\"css\")(el) || \"\").split(\" \"); },\n\t        check: function (res) { return includes$2(\".css\")(res.name); },\n\t        shortname: function (path) { return basename(path); },\n\t        load: !1,\n\t        parse: function (res) { return (res.headers.hash = res.headers.hash || hash(res.body), res); }\n\t    }, ripple;\n\t};\n\n\tvar log$5 = require$$0$2(\"[ri/types/css]\");\n\n\tvar basename;\n\n\tvar client$3 = /*#__PURE__*/Object.freeze({\n\t\tdefault: client_1,\n\t\t__moduleExports: client_1\n\t});\n\n\tvar lo = function lo(d){\n\t  return (d || '').toLowerCase()\n\t};\n\n\tvar lo$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: lo,\n\t\t__moduleExports: lo\n\t});\n\n\tvar lo$2 = ( lo$1 && lo ) || lo$1;\n\n\tvar client_1$1 = function(ripple, ref) {\n\t    if ( ref === void 0 ) ref = {};\n\t    var dir = ref.dir; if ( dir === void 0 ) dir = \".\";\n\n\t    return log$6(\"creating\"), ripple.require = (function (res) { return function (module) {\n\t        if (module in res.headers.dependencies && ripple.resources[res.headers.dependencies[module]]) { return ripple(res.headers.dependencies[module]); }\n\t        throw new Error((\"Cannot find module: \" + module + \" for \" + (res.name)));\n\t    }; }), ripple.types[\"application/javascript\"] = {\n\t        header: header$3,\n\t        selector: function (res) { return ((res.name) + \",[is~=\\\"\" + (res.name) + \"\\\"]\"); },\n\t        extract: function (el) { return (attr$2(\"is\")(el) || \"\").split(\" \").concat(lo$2(el.nodeName)); },\n\t        ext: \"*.js\",\n\t        shortname: function (path) { return basename$1(path).split(\".\").slice(0, -1).join(\".\"); },\n\t        check: function (res) { return is$2.fn(res.body); },\n\t        load: !1,\n\t        parse: function (res) {\n\t            if (\"cjs\" == res.headers.format) {\n\t                var m = {\n\t                    exports: {}\n\t                };\n\t                res.body(m, m.exports, ripple.require(res), {\n\t                    env: {}\n\t                }), res.body = m.exports;\n\t            }\n\t            return res;\n\t        }\n\t    }, ripple;\n\t};\n\n\tvar log$6 = require$$0$2(\"[ri/types/fn]\"), header$3 = \"application/javascript\";\n\n\tvar basename$1;\n\n\tvar client$4 = /*#__PURE__*/Object.freeze({\n\t\tdefault: client_1$1,\n\t\t__moduleExports: client_1$1\n\t});\n\n\tvar nanosocket = function(url){\n\t  if ( url === void 0 ) url = location.href.replace('http', 'ws');\n\n\t  var io = emitterify$2({ attempt: 0 });\n\t  io.ready = io.once('connected');\n\t  io.connect = connect(io, url);\n\t  io.connect(); \n\t  io.send = function (data) { return io.ready.then(function (socket) { return socket.send(data); }); };\n\t  return io\n\t};\n\n\tvar min = Math.min;\n\tvar pow = Math.pow;\n\n\tvar connect = function (io, url) { return function () {\n\t  var WebSocket = window.WebSocket;\n\t  var location = window.location;\n\t  var setTimeout = window.setTimeout;\n\t  var socket = new WebSocket(url);\n\t  socket.onopen = function (d) { return io.emit('connected', socket); };\n\t  socket.onmessage = function (d) { return io.emit('recv', d.data); };\n\t  socket.onclose = function (d) { \n\t    io.ready = io.once('connected');\n\t    io.emit('disconnected');\n\t    setTimeout(io.connect, backoff(++io.attempt));\n\t  };\n\t}; };\n\n\tvar backoff = function (attempt, base, cap) {\n\t    if ( base === void 0 ) base = 100;\n\t    if ( cap === void 0 ) cap = 10000;\n\n\t    return min(cap, base * pow(2, attempt));\n\t};\n\n\tvar nanosocket$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: nanosocket,\n\t\t__moduleExports: nanosocket\n\t});\n\n\tvar require$$0$3 = ( nanosocket$1 && nanosocket ) || nanosocket$1;\n\n\tvar client$5 = function(ref){\n\t  if ( ref === void 0 ) ref = {};\n\t  var socket = ref.socket; if ( socket === void 0 ) socket = require$$0$3();\n\n\t  socket.id = 0;\n\n\t  var server = emitterify$2({ \n\t    socket: socket\n\t  , send: send(socket)\n\t  , get subscriptions(){\n\t      return values$2(socket.on)\n\t        .map(function (d) { return d && d[0]; })\n\t        .filter(function (d) { return d && d.type && d.type[0] == '$'; })\n\t    }\n\t  });\n\t  \n\t  socket\n\t    .once('disconnected')\n\t    .map(function (d) { return socket\n\t      .on('connected')\n\t      .map(reconnect(server)); }\n\t    );\n\n\t  socket\n\t    .on('recv')\n\t    .map(deserialise)\n\t    .each(function (ref) {\n\t      var id = ref.id;\n\t      var data = ref.data;\n\n\t      // TODO: check/warn if no sub\n\t      var sink = socket.on[(\"$\" + id)] && socket.on[(\"$\" + id)][0];\n\n\t      data.exec ? data.exec(sink, data.value)\n\t    : !id       ? server.emit('recv', data)\n\t                : socket.emit((\"$\" + id), data);\n\t    });\n\n\t  return server\n\t};\n\n\tvar deserialise = function (input) { return (new Function((\"return \" + input)))(); };\n\n\tvar reconnect = function (server) { return function () { return server.subscriptions\n\t  .map(function (ref) {\n\t    var subscription = ref.subscription;\n\n\t    return server.socket.send(subscription);\n\t  }); }; };\n\n\n\t    \n\tvar send = function (socket, type) { return function (data, meta) {\n\t  if (data instanceof window.Blob) \n\t    { return binary(socket, data, meta) }\n\n\t  var id = str$2(++socket.id)\n\t      , output = socket.on((\"$\" + id))\n\t      , next = function (data, count) {\n\t        if ( count === void 0 ) count = 0;\n\n\t        return socket\n\t          .send(output.source.subscription = str$2({ id: id, data: data, type: type }))\n\t          .then(function (d) { return output.emit('sent', { id: id, count: count }); });\n\t  };\n\n\t  data.next \n\t    ? data.map(next).source.emit('start')\n\t    : next(data);\n\n\t  output\n\t    .source\n\t    .once('stop')\n\t    .filter(function (reason) { return reason != 'CLOSED'; })\n\t    .map(function (d) { return send(socket, 'UNSUBSCRIBE')(id)\n\t      // TODO: also force stop on close of server created sub (?)\n\t      .filter(function (d, i, n) { return n.source.emit('stop', 'CLOSED'); }); }\n\t    );\n\n\t  return output\n\t}; };\n\n\tvar binary = function (socket, blob, meta, start, blockSize) {\n\t  if ( start === void 0 ) start = 0;\n\t  if ( blockSize === void 0 ) blockSize = 1024;\n\n\t  var output = emitterify$2().on('recv')\n\t      , next = function (id) { return function () { return start >= blob.size \n\t            ? output.emit('sent', { id: id })\n\t            : ( socket.send(blob.slice(start, start += blockSize))\n\t              , window.setTimeout(next(id))\n\t              ); }; };\n\n\t  send(socket, 'BINARY')({ size: blob.size, meta: meta })\n\t    .on('sent', function (ref) {\n\t      var id = ref.id;\n\n\t      return next(id)();\n\t  })\n\t    .on('progress', function (received) { return output.emit('progress', { received: received, total: blob.size }); })\n\t    .map(output.next)\n\t    .source\n\t    .until(output.once('stop'));\n\n\t  return output\n\t};\n\n\tvar client$6 = /*#__PURE__*/Object.freeze({\n\t\tdefault: client$5,\n\t\t__moduleExports: client$5\n\t});\n\n\tvar time = function time(ms, fn) {\n\t  return arguments.length === 1 \n\t       ? setTimeout(ms)\n\t       : setTimeout(fn, ms)\n\t};\n\n\tvar time$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: time,\n\t\t__moduleExports: time\n\t});\n\n\tvar require$$0$4 = ( client$6 && client$5 ) || client$6;\n\n\tvar time$2 = ( time$1 && time ) || time$1;\n\n\tvar client$7 = function sync(\n\t  ripple\n\t, ref\n\t, ref$1\n\t){\n\t  if ( ref === void 0 ) ref = {};\n\t  if ( ref$1 === void 0 ) ref$1 = {};\n\t  var xrs = ref$1.xrs; if ( xrs === void 0 ) xrs = require$$0$4;\n\n\t  ripple.server = xrs();\n\t  ripple.send = send$1(ripple);\n\t  ripple.subscribe = subscribe(ripple);\n\t  ripple.subscriptions = {};\n\t  ripple.get = get(ripple);\n\t  ripple.upload = upload(ripple);\n\t  ripple.upload.id = 0;\n\n\t  // TODO: other than cache pushes? ans: use server.type\n\t  ripple\n\t    .server\n\t    .on('recv')\n\t    .map(function (data, i, n) { return cache(ripple)(data, i, n); });\n\n\t  return ripple\n\t};\n\n\tvar send$1 = function (ref) {\n\t  var server = ref.server;\n\n\t  return function (name, type, value) { return name instanceof Blob ? server.send(name, type)\n\t: is$2.obj(name)         ? server.send(name)\n\t                       : server.send({ name: name, type: type, value: value }); };\n\t};\n\n\tvar get = function (ripple) { return function (name, k) { return ripple\n\t  .subscribe(name, k)\n\t  .filter(function (d, i, n) { return n.source.emit('stop'); })\n\t  .start(); }; };\n\n\tvar cache = function (ripple, n, k) { return function (change) {\n\t  // if (name && change.name && name != change.name) ripple.link(name, change.name)\n\t  var name = change.name = change.name || n;\n\t  if (!change.type) { change.type = 'update'; }\n\t  if (is$2.def(k)) { change.key = k + \".\" + (str$2(change.key)); }\n\t  !change.key && change.type == 'update'\n\t    ? ripple(body(change))\n\t    : set$2(change)(ripple.resources[name] ? ripple(name) : ripple(name, {}));\n\n\t  ripple.change = change;\n\t  \n\t  return key$2(k)(ripple(name))\n\t}; };\n\n\tvar subscribe = function (ripple) { return function (name, k) {\n\t  if (is$2.arr(name)) { return merge$3(name.map(function (n) { return ripple.subscribe(n, k); }))\n\t    .map(function (d) { return name.reduce(function (p, v, i) { return (p[v] = d[i], p); }, {}); }) }\n\n\t  ripple.subscriptions[name] = ripple.subscriptions[name] || {};\n\t  if (is$2.arr(k)) { return merge$3(k.map(function (k) { return ripple.subscribe(name, k); }))\n\t    .map(function (d) { return key$2(k)(ripple(name)); }) }\n\t  var output = emitterify$2().on('subscription');\n\n\t  output\n\t    .on('stop')\n\t    .each(function (d, i, n) {\n\t      raw.subs.splice(raw.subs.indexOf(output), 1);\n\t      time$2(1000, function () { \n\t        if (raw.subs.length) { return }\n\t        raw.source.emit('stop');\n\t        ripple.subscriptions[name][k] = undefined;\n\t        output.emit('end');\n\t      });\n\t    });\n\n\t  if (ripple.subscriptions[name][k])\n\t    { output\n\t      .on('start')\n\t      .map(function () { return key$2(k)(ripple(name)); })\n\t      .filter(is$2.def)\n\t      .map(function (initial) { return output.next(initial); }); }\n\n\t  var raw = ripple.subscriptions[name][k] = ripple.subscriptions[name][k] || ripple\n\t    .send(name, 'SUBSCRIBE', k)\n\t    .map(cache(ripple, name, k))\n\t    .each(function (value) {\n\t      raw.subs.map(function (o) { return o.next(value); });\n\t      delete ripple.change;\n\t    });\n\n\t  raw.subs = raw.subs || [];\n\t  raw.subs.push(output);\n\t  \n\t  return output\n\t}; };\n\n\tvar upload = function (ripple) { return function (name, form) {\n\t  var index = ++ripple.upload.id\n\t    , fields = {}\n\t    , size = 0\n\t    , next = function () {\n\t        if (!files.length) { return true }\n\t        var ref = files.shift();\n\t        var field = ref.field;\n\t        var filename = ref.filename;\n\t        var i = ref.i;\n\t        var blob = ref.blob;\n\t        return ripple\n\t          .send(blob, { filename: filename, field: field, i: i, index: index })\n\t          .on('progress', function (ref) {\n\t            var received = ref.received;\n\t            var total = ref.total;\n\n\t            return output.emit('progress', {\n\t            total: size\n\t          , received: \n\t              size\n\t            - (blob.size - received)\n\t            - files.reduce(function (acc, d) { return (acc += d.blob.size); }, 0)\n\t          });\n\t        })\n\t          .then(next)\n\t      };\n\n\t  var files = keys$2(form)\n\t    .map(function (field) { return (fields[field] = form[field], field); })\n\t    .filter(function (field) { return form[field] instanceof FileList; })\n\t    .map(function (field) { \n\t      fields[field] = [];\n\t      return to$2.arr(form[field])\n\t        .map(function (f) { return (size += f.size, f); })\n\t        .map(function (f, i) { return ({ field: field, filename: f.name, i: i, blob: f, sent: 0 }); })\n\t    })\n\t    .reduce(flatten$2, []);\n\n\t  var output = ripple.send({ \n\t    files: files.length\n\t  , type: 'PREUPLOAD'\n\t  , fields: fields\n\t  , index: index\n\t  , size: size \n\t  , name: name\n\t  }).once('sent', next);\n\n\t  return output\n\t}; };\n\n\tvar body = function (ref) {\n\t  var name = ref.name;\n\t  var value = ref.value;\n\t  var headers = ref.headers;\n\n\t  return ({ name: name, headers: headers, body: value });\n\t};\n\n\t// TODO: factor out\n\tvar merge$3 = function (streams) {\n\t  var output = emitterify$2().on('merged');\n\t  output.streams = streams;\n\n\t  streams.map(function (stream, i) { return stream.each(function (value) {\n\t      stream.latest = value;\n\t      var latest = streams.map(function (d) { return d.latest; });\n\t      if (latest.every(is$2.def)) { output.next(latest); }\n\t    }); }\n\t  );\n\n\t  output\n\t    .once('start')\n\t    .map(function (d) { return streams.map(function ($) { return $.source.emit('start'); }); });\n\n\t  output\n\t    .once('stop')\n\t    .map(function (d) { return streams.map(function ($) { return $.source.emit('stop'); }); });\n\n\t  return output\n\t};\n\n\tvar client$8 = /*#__PURE__*/Object.freeze({\n\t\tdefault: client$7,\n\t\t__moduleExports: client$7\n\t});\n\n\tvar ready = function ready(fn){\n\t  return document.body ? fn() : document.addEventListener('DOMContentLoaded', fn.bind(this))\n\t};\n\n\tvar ready$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: ready,\n\t\t__moduleExports: ready\n\t});\n\n\tvar _class = function (definition) { return assign$1(\n\t   definition.class               ? definition.class\n\t: !definition.prototype           ? classed(definition)\n\t:  definition.prototype.render    ? definition\n\t:  definition.prototype.connected ? definition\n\t                                  : classed(definition)\n\t); };\n\n\tvar assign$1 = Object.assign;\n\n\tvar classed = function (render) { return render.class = render.class || class { \n\t  render(){ render.apply(this, arguments); } \n\t}; };\n\n\tvar _class$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: _class,\n\t\t__moduleExports: _class\n\t});\n\n\tvar event = function event(node, index) {\n\t  node = node.host && node.host.nodeName ? node.host : node;\n\t  if (node.on) { return }\n\t  node.listeners = {};\n\n\t  var on = function (o) {\n\t    var type = o.type.split('.').shift();\n\t    if (!node.listeners[type])\n\t      { node.addEventListener(type, node.listeners[type] = \n\t        function (event) { return (!event.detail || !event.detail.emitted ? emit(type, event) : 0); }\n\t      ); }\n\t  };\n\n\t  var off = function (o) {\n\t    if (!node.on[o.type].length) {\n\t      node.removeEventListener(o.type, node.listeners[o.type]);\n\t      delete node.listeners[o.type];\n\t    }\n\t  };\n\n\t  emitterify$2(node, { on: on, off: off });\n\t  var emit = node.emit;\n\n\t  node.emit = function(type, params){\n\t    var detail = { params: params, emitted: true }\n\t        , event = new CustomEvent(type, { detail: detail, bubbles: false, cancelable: true });\n\t    node.dispatchEvent(event);\n\t    return emit(type, event)\n\t  };\n\t};\n\n\tvar event$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: event,\n\t\t__moduleExports: event\n\t});\n\n\tvar classed$1 = ( _class$1 && _class ) || _class$1;\n\n\tvar event$2 = ( event$1 && event ) || event$1;\n\n\tvar noop$1 = function () {}\n\t    , HTMLElement = client$2 && window.HTMLElement || class {}\n\t    , registry = client$2 && window.customElements || {};\n\n\tvar define = function define(name, component) {\n\t  if (arguments.length == 1) { component = name, name = \"anon-\" + (registry.anon++); }\n\t  if (component.wrapper) { return component.wrapper }\n\t  if (!name.includes('-')) { return; }\n\t  if (!client$2) { return wrap$3(classed$1(component)) }\n\t  var wrapped = registry.get(name);\n\n\t  if (wrapped) {\n\t    if (wrapped.class == classed$1(component)) { return wrapped }\n\t    wrapped.class = classed$1(component);\n\t    var instances = Array.from(document.querySelectorAll(name));\n\t    instances.map(function (node) {\n\t      node.disconnectedCallback();\n\t      node.methods.map(function (method) { delete node[method]; });\n\t      node.connectedCallback();\n\t    });\n\t  } else {\n\t    registry.define(name, wrapped = wrap$3(classed$1(component)));\n\t  }\n\n\t  return wrapped\n\t};\n\n\tvar wrap$3 = function (component) {\n\t  component.wrapper = component.wrapper || class extends HTMLElement {\n\t    connectedCallback(){\n\t      var this$1 = this;\n\t \n\t      var ref = component.wrapper.class;\n\t      var prototype = ref.prototype;\n\t      event$2(this);\n\t      this.state = this.state || {};\n\t      this.methods = Object\n\t        .getOwnPropertyNames(prototype)\n\t        .filter(function (method) { return !(method in disallowed); })\n\t        .map(function (method) { return ((this$1[method] = prototype[method].bind(this$1)), method); });\n\n\t      return Promise.resolve((this.connected || noop$1).call(this, this, this.state))\n\t        .then(function (d) {\n\t          this$1.initialised = true;\n\t          this$1.render();\n\t        })\n\t    }\n\n\t    render(){\n\t      var ref = component.wrapper.class;\n\t      var prototype = ref.prototype;\n\t      if (!this.initialised) { return }\n\t      return prototype.render.call(this, this, this.state)\n\t    }\n\n\t    disconnectedCallback(){\n\t      (this.disconnected || noop$1).call(this, this, this.state);\n\t      this.dispatchEvent(new CustomEvent('disconnected')); \n\t      this.initialised = false;\n\t    }\n\t  };\n\n\t  component.wrapper.class = component;\n\t  return component.wrapper\n\t};\n\n\tvar disallowed = { length: 1, prototype: 1, name: 1, render: 1 };\n\n\tregistry.anon = registry.anon || 1;\n\n\tvar define$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: define,\n\t\t__moduleExports: define\n\t});\n\n\tvar ready$2 = ( ready$1 && ready ) || ready$1;\n\n\tvar define$2 = ( define$1 && define ) || define$1;\n\n\tvar rijs_components = function components(ripple){\n\t  if (!client$2) { return ripple }\n\t  log$7('creating');\n\n\t  // if no render is defined on a component, load up definition\n\t  Node.prototype.render = function(){\n\t    var name = this.nodeName.toLowerCase();\n\t    if (name.includes('-')) \n\t      { return this.fn$ = this.fn$ || ripple\n\t        .subscribe(name)\n\t        .map(function (component) { return define$2(name, component); }) }\n\t        // TODO: test this works well across all instances\n\t        // .until(new Promise(resolve => this.addEventListener('disconnected', () => {\n\t        //   if (!this.isConnected) resolve()\n\t        // })))\n\t  };\n\t  \n\t  // this is for backwards compatibility\n\t  Node.prototype.draw = function(){ \n\t    this.render(); \n\t  };\n\n\t  ready$2(function () { return Array.from(document.querySelectorAll('*'))\n\t    .filter(function (d) { return d.nodeName.includes('-'); })\n\t    .map(function (node) { return node.render(); }); }\n\t  );\n\n\t  return ripple\n\t};\n\n\tvar log$7 = require$$0$2('[ri/components]');\n\n\tvar rijs_components$1 = /*#__PURE__*/Object.freeze({\n\t\tdefault: rijs_components,\n\t\t__moduleExports: rijs_components\n\t});\n\n\tvar require$$0$5 = ( rijs_core$1 && rijs_core ) || rijs_core$1;\n\n\tvar require$$1 = ( rijs_singleton$1 && rijs_singleton ) || rijs_singleton$1;\n\n\tvar require$$2$1 = ( rijs_data$1 && rijs_data ) || rijs_data$1;\n\n\tvar require$$3 = ( client$3 && client_1 ) || client$3;\n\n\tvar require$$4 = ( client$4 && client_1$1 ) || client$4;\n\n\tvar require$$5 = ( client$8 && client$7 ) || client$8;\n\n\tvar require$$6 = ( rijs_components$1 && rijs_components ) || rijs_components$1;\n\n\tvar ripple = createCommonjsModule(function (module) {\n\tfunction create(opts) {\n\t    var ripple = require$$0$5(opts);\n\t    return require$$1(ripple, opts), require$$2$1(ripple, opts), \n\t    require$$3(ripple, opts), require$$4(ripple, opts), require$$5(ripple, opts), \n\t    require$$6(ripple, opts), ripple;\n\t}\n\n\t!window.ripple && create(), module.exports = create;\n\t});\n\n\treturn ripple;\n\n}());\n"
  },
  {
    "path": "client/ripple.js",
    "content": "const client = require(\"utilise/client\");\n\nfunction create(opts) {\n    const ripple = require(\"rijs.core\")(opts);\n    return require(\"rijs.singleton\")(ripple, opts), require(\"rijs.data\")(ripple, opts), \n    require(\"rijs.css\")(ripple, opts), require(\"rijs.fn\")(ripple, opts), require(\"rijs.sync\")(ripple, opts), \n    require(\"rijs.components\")(ripple, opts), ripple;\n}\n\n!window.ripple && create(), module.exports = create;\n"
  },
  {
    "path": "index.js",
    "content": "const client = require('utilise/client')\n    \nif (client) !window.ripple && create()\n\nmodule.exports = create\n\nfunction create(opts){\n  const ripple = require('rijs.core')(opts)\n  require('rijs.singleton')(ripple, opts)\n  require('rijs.data')(ripple, opts)\n  require('rijs.css')(ripple, opts)\n  require('rijs.fn')(ripple, opts)\n  require('rijs.sync')(ripple, opts)\n  require('rijs.components')(ripple, opts)\n\n  if (!client) {\n    const { dirname, resolve } = require('path')\n    opts.dir = opts.dir || dirname(module.parent.filename)\n    opts.serve = resolve(__dirname, 'client')\n    require('rijs.sessions')(ripple, opts)\n    require('rijs.serve')(ripple, opts)\n    require('rijs.pages')(ripple, opts)\n    require('rijs.resdir')(ripple, opts)\n  }\n  \n  return ripple\n}"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"rijs\",\n  \"version\": \"0.9.1\",\n  \"main\": \".\",\n  \"author\": \"Pedram Emrouznejad (https://github.com/pemrouz)\",\n  \"license\": \"pemrouz.mit-license.org\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/rijs/fullstack.git\"\n  },\n  \"scripts\": {\n    \"clean\": \"rm -rf ./client/ripple.*\",\n    \"build\": \"npm run clean && npm run client && npm run rollup && npm run minify && npm run gzip\",\n    \"client\": \"uglifyjs index.js -b -d client=true -c > ./client/ripple.js\",\n    \"rollup\": \"rollup -c\",\n    \"minify\": \"uglifyjs ./client/ripple.bundle.js -m -c keep_fargs=false > ./client/ripple.min.js\",\n    \"gzip\": \"gzip -c ./client/ripple.min.js > ./client/ripple.min.js.gz\",\n    \"version\": \"npm run build && git add -A\",\n    \"postversion\": \"git push && git push --tags\",\n    \"test\": \"tap ./tests/*.js\"\n  },\n  \"dependencies\": {\n    \"rijs.components\": \"*\",\n    \"rijs.core\": \"*\",\n    \"rijs.css\": \"*\",\n    \"rijs.data\": \"*\",\n    \"rijs.fn\": \"*\",\n    \"rijs.pages\": \"*\",\n    \"rijs.resdir\": \"*\",\n    \"rijs.serve\": \"*\",\n    \"rijs.sessions\": \"*\",\n    \"rijs.singleton\": \"*\",\n    \"rijs.sync\": \"*\",\n    \"utilise\": \"*\"\n  },\n  \"devDependencies\": {\n    \"puppeteer\": \"^1.3.0\",\n    \"rollup\": \"^0.58.0\",\n    \"rollup-plugin-async\": \"*\",\n    \"rollup-plugin-buble\": \"*\",\n    \"rollup-plugin-commonjs\": \"*\",\n    \"rollup-plugin-node-resolve\": \"*\",\n    \"rollup-plugin-nodent\": \"*\",\n    \"tap\": \"^10.7.3\",\n    \"uglify-es\": \"^3.3.10\"\n  }\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import nodeResolve from 'rollup-plugin-node-resolve';\nimport commonjs from 'rollup-plugin-commonjs';\nimport async from 'rollup-plugin-async';\nimport buble from 'rollup-plugin-buble'\n\nexport default {\n  input: 'client/ripple.js'\n, output: { \n    file: 'client/ripple.bundle.js' \n  , format: 'iife'\n  } \n, name: 'rijs'\n, plugins: [\n    nodeResolve({ browser: true })\n  , commonjs({ ignoreGlobal: true })\n  , async()\n  , buble({ \n      transforms: { \n        generator: false\n      , classes: false \n      }\n    })\n  ]\n}"
  },
  {
    "path": "rollup.pure.config.js",
    "content": "import nodeResolve from 'rollup-plugin-node-resolve'\nimport commonjs from 'rollup-plugin-commonjs'\nimport replace from 'rollup-plugin-replace'\nimport buble from 'rollup-plugin-buble'\n\nexport default {\n  input: 'index.js'\n, output: {\n    file: 'ripple.pure.js'\n  , format: 'iife'\n  }\n, name: 'rijs'\n, plugins: [\n    replace({\n      delimiters: ['','']\n    , values: {\n        \"require('utilise/emitterify')\": \"window.emitterify\"\n      , \"require('utilise/overwrite')\": \"window.overwrite\"\n      , \"require('utilise/colorfill')\": \"window.colorfill\"\n      , \"require('utilise/includes')\": \"window.includes\"\n      , \"require('utilise/identity')\": \"window.identity\"\n      , \"require('utilise/debounce')\": \"window.debounce\"\n      , \"require('utilise/flatten')\": \"window.flatten\"\n      , \"require('utilise/replace')\": \"window.replace\"\n      , \"require('utilise/header')\": \"window.header\"\n      , \"require('utilise/extend')\": \"window.extend\"\n      , \"require('utilise/append')\": \"window.append\"\n      , \"require('utilise/values')\": \"window.values\"\n      , \"require('utilise/ready')\": \"window.ready\"\n      , \"require('utilise/proxy')\": \"window.proxy\"\n      , \"require('utilise/split')\": \"window.split\"\n      , \"require('utilise/clone')\": \"window.clone\"\n      , \"require('utilise/group')\": \"window.group\"\n      , \"require('utilise/parse')\": \"window.parse\"\n      , \"require('utilise/attr')\": \"window.attr\"\n      , \"require('utilise/keys')\": \"window.keys\"\n      , \"require('utilise/time')\": \"window.time\"\n      , \"require('utilise/noop')\": \"window.noop\"\n      , \"require('utilise/from')\": \"window.from\"\n      , \"require('utilise/all')\": \"window.all\"\n      , \"require('utilise/raw')\": \"window.raw\"\n      , \"require('utilise/log')\": \"window.log\"\n      , \"require('utilise/not')\": \"window.not\"\n      , \"require('utilise/key')\": \"window.key\"\n      , \"require('utilise/set')\": \"window.set\"\n      , \"require('utilise/err')\": \"window.err\"\n      , \"require('utilise/str')\": \"window.str\"\n      , \"require('utilise/is')\": \"window.is\"\n      , \"require('utilise/by')\": \"window.by\"\n      , \"require('utilise/el')\": \"window.el\"\n      , \"require('utilise/to')\": \"window.to\"\n      , \"require('utilise/lo')\": \"window.lo\"\n      , \"require('utilise/fn')\": \"window.fn\"\n      , \"require('utilise/za')\": \"window.za\"\n      , \"require('utilise/owner')\": \"window\"\n      , \"require('utilise/client')\": \"true\"\n\n      , \"require('rijs.sessions')\": \"d => d\"\n      , \"require('rijs.resdir')\": \"d => d\"\n      , \"require('rijs.pages')\": \"d => d\"\n      , \"require('rijs.serve')\": \"d => d\"\n      }\n    })\n  , nodeResolve({ browser: true })\n  , commonjs({ ignoreGlobal: true })\n  , buble()\n  ]\n}"
  },
  {
    "path": "tests/basic.test.js",
    "content": "(async () => {\n  const puppeteer = require('puppeteer')\n      , browser = await puppeteer.launch({ headless: process.env.HEADLESS !== 'false' })\n      , { test } = require('tap')    \n\n  await test('define, use component on page, with stylesheet, hot reload', async ({ plan, same }) => {\n    plan(2)\n    const { ripple, page } = await startup()\n\n    // register component and css\n    ripple\n      .resource('web-component', node => node.innerHTML = 'foo')\n\n    // append to page\n    await page.evaluate(() => {\n      foo = document.createElement('web-component')\n      document.body.appendChild(foo)\n      foo.render()\n    })\n\n    // check rendered\n    await page.waitFor('web-component')\n    same('foo', await page.evaluate(() => foo.innerHTML))\n\n    // register new version of component\n    ripple('web-component', node => node.innerHTML = 'boo')\n    same('boo', await page.evaluate(() => foo.innerHTML))\n\n    await page.close()\n  })\n\n  await test('auto load components, with dependencies', async ({ plan, same }) => {\n    plan(1)\n    const { ripple, page } = await startup(`<auto-loaded-component id=\"component\"></auto-loaded-component>`)\n\n    // check rendered\n    await page.waitFor(() => component.innerHTML == 'foo')\n    same(['./resources/utils/foo.js', 'auto-loaded-component'], await page.evaluate(() => Object.keys(ripple.resources)))\n    \n    await page.close()\n  })\n\n  await browser.close()\n  process.exit(0)\n\n  async function startup(body = ''){\n    const ripple = require('..')({ port: 0, dir: __dirname })\n    ripple.server.express.use((req, res) => res.send(`\n      <script src=\"/ripple.min.js\"></script>\n      <body>${body}</body> \n    `))\n\n    await ripple.server.once('listening')\n\n    const page = await browser.newPage()\n\n    await page.goto(`http://localhost:${ripple.server.port}`)\n\n    if (process.env.DEBUG == 'true')\n      page.on('console', (...args) => console.log('(CLIENT):', ...args))\n\n    return { ripple, page }\n  }\n})()"
  },
  {
    "path": "tests/resources/_components/x-foo.css",
    "content": ":host { background: red }"
  },
  {
    "path": "tests/resources/_components/x-foo.js",
    "content": "const define = require('@compone/define')\n    , style = require('@compone/style')\n\nmodule.exports = define('x-foo', async (node, state) => {\n  await style(node, await ripple.get('x-foo.css'))\n\n  node.innerHTML = await ripple.get('some-data')\n})"
  },
  {
    "path": "tests/resources/components/auto-loaded-component.js",
    "content": "const foo = require('../utils/foo')\n\nmodule.exports = node => (node.innerHTML = foo)"
  },
  {
    "path": "tests/resources/utils/foo.js",
    "content": "module.exports = 'foo'"
  }
]