[
  {
    "path": ".dockerignore",
    "content": "node_modules\nradata\nstats.radata\n.git\n.gitignore\n*.md\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: amark\npatreon: gunDB\nopen_collective: gun\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: ci\n\non:\n  push:\n  pull_request:\n\njobs:\n  test:\n    strategy:\n      matrix:\n        node-version: [14.x]\n        os: [ubuntu-latest]\n    runs-on: ${{ matrix.os }}\n    steps:\n      # checkout the code\n      - name: Checkout\n        uses: actions/checkout@v4  # Updated to v4 (latest as of 2025)\n\n      # verify the version in package.json matches the release tag\n      - name: Version\n        uses: tcurdt/action-verify-version-npm@master  # No version update as it's using @master\n\n      # setup the node version\n      - name: Setup Node ${{ matrix.node-version }}\n        uses: actions/setup-node@v4  # Updated to v4 (latest as of 2025)\n        with:\n          node-version: ${{ matrix.node-version }}\n\n      # cache node_modules if we can\n      - name: Cache\n        id: cache-modules\n        uses: actions/cache@v4  # Updated to v4 (latest as of 2025)\n        with:\n          path: node_modules\n          key: ${{ matrix.node-version }}-${{ runner.os }}-build-${{ hashFiles('package.json') }}\n\n      # otherwise run install\n      - name: Install\n        if: steps.cache-modules.outputs.cache-hit != 'true'\n        run: npm install\n\n      # run tests\n      - name: Test\n        run: npm test\n\n  # create github release\n  release:\n    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')\n    needs: [test]\n    runs-on: ubuntu-latest\n    steps:\n      # create github release (which triggers the release workflows)\n      - name: Release\n        uses: softprops/action-gh-release@v2  # Updated to v2 (latest stable version as of 2025)\n        # env:\n        #   GITHUB_TOKEN: ${{ secrets.PAT }}\n\n#   # publish latest master or release to dockerhub\n#   dockerhub:\n#     if: github.event_name == 'push'\n#     needs: [test]\n#     runs-on: ubuntu-latest\n#     env:\n#       image: ${{ secrets.DOCKERHUB_USERNAME }}/gun\n#     steps:\n#\n#     - name: Checkout\n#       uses: actions/checkout@v4  # Updated to v4\n#\n#     - name: Login\n#       env:\n#         DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}\n#         DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}\n#       run: echo -n ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin\n#\n#     - name: Build\n#       run: |\n#         echo \"SHA=$GITHUB_SHA\"\n#         docker build --build-arg SHA=$GITHUB_SHA \\\n#           BUILD_DATE=$(date +'%Y-%m-%dT%H:%M:%S') \\\n#           VCS_REF=${GITHUB_REF} \\\n#           VCS_URL=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} \\\n#           VERSION=${GITHUB_REF##*/} \\\n#           SHA=$GITHUB_SHA \\\n#           --label \"SHA=$GITHUB_SHA\" \\\n#           --tag ${{ env.image }}:${GITHUB_REF##*/} \\\n#           --tag ${{ env.image }}:latest \\\n#           .\n#\n#     - name: Push\n#       run: docker push ${{ env.image }}\n\n  # publish release to npm\n  npm:\n    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')\n    needs: [test]\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4  # Updated to v4\n\n      - name: Publish\n        env:\n          NPM_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}\n        run: |\n          npm config set //registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN\n          npm install\n          npm publish --access=public\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\r\nnpm-debug.log\r\nyarn.lock\r\n*data.json\r\n*data*\r\n*.db\r\n.idea/\r\n*.bak\r\n*.new\r\n*.log\r\nv8.json\r\n*.DS_store\r\nisolate*.log\r\n.esm-cache\r\n.sessionStorage\r\n.localStorage\r\n/types/**/*.ts\r\n!/types/**/*.d.ts\r\n!/types/**/*.test-d.ts\r\n/gun.ts\r\n/temp/"
  },
  {
    "path": ".npmignore",
    "content": "*.ts\n/temp/\n!*.d.ts\n*.radata\nisolate-*\n"
  },
  {
    "path": ".prettierignore",
    "content": "*"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nbranches:\n  except:\n    - debug\n    - manhattan\nnode_js:\n  - 10\ncache:\n  directories:\n    - node_modules\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# CHANGELOG\n\n## 0.2020.x\n\n`>0.2020.520` may break in-process `gun1` `gun2` message passing. Check `test/common.js` \"Check multi instance message passing\" for a hint and/or complain on community chat. \n\n - No breaking changes to core API.\n - Storage adapter `put` event breaking change (temporary?), RAD is official now and storage adapters should be RAD plugins instead of GUN adapters.\n - GUN soul format changed from being a random UUID to being a more predictable graph path (of where initially created) to support even better offline behavior. This means `null`ing & replacing an object will not create a new but re-merge.\n - Pretty much all internal GUN utility will be deleted, these are mostly undocumented but will affect some people - they will still be available as a separate file but deprecated.\n - As the DHT gets implemented, your relay peers may automatically connect to it, so do not assume your peer is standalone. `Gun({axe: false` should help prevent this but loses you most scaling properties.\n - The 2019 -> 2020 \"changes\" are happening gradually, based on experimental in-production tests.\n - As always, **most important** is to ask in the [community chat](http://chat.gun.eco) if you have any issues, and to keep up to date with changes.\n\n## 0.2019.x\n\nSome RAD & SEA data format changes, but with as much backward compatibility as possible, tho ideally should be dropped.\n\n## 0.9.x\n\nNo breaking changes, but the new Radix Storage Engine (RSE) has been finally integrated and works with S3 as a backup.\n\n// Edit: commentary removed.\n\n## 0.8.x\n\nAdapter interfaces have changed from `Gun.on('event', cb)` to `gun.on('event', cb)`, this will force adapters to be instance specific.\n\n`.path()` and `.not()` have been officially removed from the core bundle, you can bundle them yourself at `lib/path.js` and `lib/not.js` if you still need them.\n\n## 0.7.x\n\nSmall breaking change to `.val(cb)`:\n\nPreviously `.val(cb)` would ONLY be called when data exists, like `.on(cb)`.\n\nHowever, due to popular demand, people wanted `.val(cb)` to also get called for `.not(cb)` rather than (before) it would \"wait\" until data arrived.\n\nNOTE: For dynamic paths, `.val(cb)` will still wait, like:\n\n`gun.get('users').map().val(cb)` because the behavior of the `map()` is simply to not fire anything down the chain unless items are found.\n\n## 0.6.x\n\nIntroduced experimental features, chaining `.val()` (no callback) and `.map(cb)` behaving as a map/reduce function.\n\nIt also upgraded the socket adapters and did end-to-end load testing and correctness testing.\n\n## 0.5.9\n\nGUN 0.3 -> 0.4 -> 0.5 Migration Guide:\n`gun.back` -> `gun.back()`;\n`gun.get(key, cb)` -> cb(err, data) -> cb(at) at.err, at.put;\n`gun.map(cb)` -> `gun.map().on(cb)`;\n`gun.init` -> deprecated;\n`gun.put(data, cb)` -> cb(err, ok) -> cb(ack) ack.err, ack.ok;\n`gun.get(key)` global/absolute -> `gun.back(-1).get(key)`;\n`gun.key(key)` -> temporarily broken;\n\n## 0.3.7\n\n - Catch localStorage errors.\n\n## 0.3.6\n\n - Fixed S3 typo.\n\n## 0.3.5\n\n - Fixed server push.\n\n## 0.3.4\n\n - Breaking Change! `list.set(item)` returns the item's chain now, not the list chain.\n - Client and Server GUN servers are now more up to spec, trimmed excess HTTP/REST header data.\n - Gun.is.lex added.\n\n## 0.3.3\n\n- You can now link nodes natively, `gun.get('mark').path('owner').put(gun.get('cat'))`!\n- Sets (or tables, collections, lists) are now easily done with `gun.get('users').set(gun.get('person/mark'))`.\n\n## 0.3.2\n\nBug fixes.\n\n## 0.3.1\n\nBug fixes.\n\n## 0.3\n\nMigration Guide! Migrate by changing `.attach(` to `.wsp(` on your server if you have one with gun. Remove `.set()` (delete it), and change `.set($DATA)` (where you call set with something) to `.path('I' + Date.now() + 'R' + Gun.text.random(5)).put($DATA)`. If you have NodeJS style callbacks in your `.get` (which documentation previously recommended that you shouldn't) they previous took `err, graph` and now they take `err, node` (which means now using callback style is fine to use). Inside of `.not()` no longer use `return` or `this`, instead (probably) use `gun` and no `return`. If you are a module developer, use `opt.wire` now instead of `opt.hooks` and message Mark since he needs to talk to you since the wire protocol has changed.\n\n- Server side default `.wsp()` renamed from `.attach()`.\n- `.set()` deprecated because it did a bunch of random inconsistent things. Its useful behavior has now become implicit (see below) or can be done explicitly.\n- `.not()` it was previously common to `return` the chain inside of .not, beware that if you have code like `gun.get(key).not(function(){ return this.put({}).key(key) }).val()` cause `.val()` to be triggered twice (this is intentional, because it funnels two separate chains together) which previously didn't happen. To fix this, just don't return the chain.\n- `.put()` and `.path()` do implicit `.init()` by default, turn on explicit behavior with `Gun({init: true})`.\n- `.get(soul, cb)` cb is called back with `err, node` rather than `err, graph`.\n- Options `opt.wire` renamed from `opt.hooks`.\n- `.val()` when called empty automatically cleanly logs for convenience purposes.\n- `.init()` added.\n- `Gun.is.val` renamed from `Gun.is.value`.\n- `Gun.is.rel` renamed from `Gun.is.soul`.\n- `Gun.is.node.soul` renamed from `Gun.is.soul.on`.\n- `Gun.union.ify` renamed from `Gun.union.pseudo`.\n- `Gun.union.HAM` renamed from `Gun.HAM`.\n- `Gun.HAM` is now the actual HAM function for conflict resolution.\n- `Gun._.state` renamed from `Gun._.HAM`.\n- Maximum Callstack Exceeded is less problematic now, unless you intentionally choke the thread. #95\n- Putting a regex or Date or NaN is actually detected and causes an error now while before it was silent. #122 #123\n- `.on()` gets called when a key is later newly made while before it did not. #116\n- `.val()` should not ever get called with a relation alone (internals should resolve it), this is fixed. #132\n"
  },
  {
    "path": "Dockerfile",
    "content": "# install packages\nFROM node:lts-alpine as builder\nRUN mkdir /work\nWORKDIR /work\nRUN apk add --no-cache alpine-sdk python3\nCOPY package*.json ./\nRUN mkdir -p node_modules\nRUN npm ci --only=production\n\n# fresh image without dev packages\nFROM node:lts-alpine\n# build-time metadata as defined at http://label-schema.org\nARG BUILD_DATE\nARG VCS_REF\nARG VCS_URL\nARG VERSION\nLABEL org.label-schema.build-date=$BUILD_DATE \\\n  org.label-schema.name=\"Gun - Offline First, Javascript Graph Database\" \\\n  org.label-schema.url=\"http://gun.js.org\" \\\n  org.label-schema.vcs-ref=$VCS_REF \\\n  org.label-schema.vcs-url=$VCS_URL \\\n  org.label-schema.vendor=\"The Gun Database Team\" \\\n  org.label-schema.version=$VERSION \\\n  org.label-schema.schema-version=\"1.0\"\nARG SHA\nRUN mkdir /work\nWORKDIR /work\nCOPY --from=builder /work/node_modules ./node_modules\nRUN npm rebuild -q\nADD . .\nRUN echo \"{ \\\"sha\\\": \\\"$SHA\\\" }\" > version.json\nRUN cat version.json\nEXPOSE 8080\nEXPOSE 8765\nCMD [\"npm\",\"start\"]\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Copyright (c) 2015 Mark Nadal\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\n---\n\nCopyright (c) 2015 Mark Nadal\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgement in the product documentation would be\n   appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n   misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution.\n\n---\n\nCopyright 2015 Mark Nadal\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "Procfile",
    "content": "web: node --inspect examples/http.js"
  },
  {
    "path": "README.md",
    "content": "<p id=\"readme\"><a href=\"https://gun.eco/\"><img width=\"40%\" src=\"https://cldup.com/TEy9yGh45l.svg\"/></a><img width=\"50%\" align=\"right\" vspace=\"25\" src=\"https://gun.eco/see/demo.gif\"/></p>\r\n\r\n[![](https://data.jsdelivr.com/v1/package/npm/gun/badge)](https://www.jsdelivr.com/package/npm/gun)\r\n![Build](https://github.com/amark/gun/actions/workflows/ci.yml/badge.svg)\r\n[![Gitter](https://img.shields.io/gitter/room/amark/gun.js.svg)](http://chat.gun.eco)\r\n\r\n**GUN** is an [ecosystem](https://gun.eco/docs/Ecosystem) of **tools** that let you build [community run](https://www.nbcnews.com/tech/tech-news/these-technologists-think-internet-broken-so-they-re-building-another-n1030136) and [encrypted applications](https://gun.eco/docs/Cartoon-Cryptography) - like an Open Source Firebase or a Decentralized Dropbox.\r\n\r\nThe [Internet Archive](https://news.ycombinator.com/item?id=17685682) and [100s of other apps](https://github.com/amark/gun/wiki/awesome-gun) run GUN in-production.\r\n\r\n + Multiplayer by default with realtime p2p state synchronization!\r\n + Graph data lets you use key/value, tables, documents, videos, & more!\r\n + Local-first, offline, and decentralized with end-to-end encryption.\r\n\r\nDecentralized alternatives to [Zoom](https://www.zdnet.com/article/era-hatches-meething-an-open-source-browser-based-video-conferencing-system/), [Reddit](https://notabug.io/t/whatever/comments/36588a16b9008da4e3f15663c2225e949eca4a15/gpu-bot-test), [Instagram](https://iris.to/), [Slack](https://iris.to/), [YouTube](https://d.tube/), [Stripe](https://twitter.com/marknadal/status/1422717427427647489), [Wikipedia](https://news.ycombinator.com/item?id=17685682), Facebook [Horizon](https://twitter.com/marknadal/status/1424476179189305347) and more have already pushed terabytes of daily P2P traffic on GUN. We are a [friendly community](http://chat.gun.eco/) creating a [free fun future for freedom](https://youtu.be/1HJdrBk3BlE):\r\n\r\n<table>\r\n<tr>\r\n<a href=\"https://youtu.be/s_m16-w6bBI\"><img width=\"31%\" src=\"https://gun.eco/see/3dvr.gif\" title=\"3D VR\"/></a>\r\n<a href=\"https://github.com/cstefanache/cstefanache.github.io/blob/06697003449e4fc531fd32ee068bab532976f47b/_posts/2016-08-02-gun-db-artificial-knowledge-sharing.md\"><img width=\"31%\" src=\"https://gun.eco/see/aiml.gif\" title=\"AI/ML\"/></a>\r\n<a href=\"http://gps.gunDB.io/\"><img width=\"31%\" src=\"https://gun.eco/see/gps.gif\" title=\"GPS\"/></a>\r\n</tr>\r\n<tr>\r\n<a href=\"https://github.com/lmangani/gun-scape#gun-scape\"><img width=\"31%\" src=\"https://gun.eco/see/dataviz.gif\" title=\"Data Viz\"/></a>\r\n<a href=\"https://github.com/amark/gun/wiki/Auth\"><img width=\"31%\" src=\"https://gun.eco/see/p2p.gif\" title=\"P2P\"/></a>\r\n<a href=\"https://github.com/Stefdv/gun-ui-lcd#okay-what-about-gundb-\"><img width=\"31%\" src=\"https://gun.eco/see/iot.gif\" title=\"IoT\"/></a>\r\n</tr>\r\n<tr>\r\n<a href=\"http://chat.gun.eco\"><img width=\"31%\" src=\"https://gun.eco/see/vr-world.gif\" title=\"VR World\"/></a>\r\n<a href=\"https://youtu.be/1ASrmQ-CwX4\"><img width=\"31%\" src=\"https://gun.eco/see/ar.gif\" title=\"AR\"/></a>\r\n<a href=\"https://meething.space/\"><img width=\"31%\" src=\"https://gun.eco/see/video-conf.gif\" title=\"Video Confernece\"/></a>\r\n</tr>\r\n</table>\r\n\r\n## Quickstart\r\n\r\nGUN is *super easy* to get started with:\r\n\r\n - Try the [interactive tutorial](https://gun.eco/docs/Todo-Dapp) in the browser (**5min** ~ average developer).\r\n - Or `npm install gun` and run the examples with `cd node_modules/gun && npm start` (**5min** ~ average developer).\r\n\r\n> **Note:** If you don't have [node](http://nodejs.org/) or [npm](https://www.npmjs.com/), read [this](https://github.com/amark/gun/blob/master/examples/install.sh) first.\r\n> If the `npm` command line didn't work, you may need to `mkdir node_modules` first or use `sudo`.\r\n\r\n- An online demo of the examples are available here: http://try.axe.eco/\r\n- Or write a quick app: ([try now in a playground](https://jsbin.com/kadobamevo/edit?js,console))\r\n```html\r\n<script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\r\n<script>\r\n// import GUN from 'gun'; // in ESM\r\n// GUN = require('gun'); // in NodeJS\r\n// GUN = require('gun/gun'); // in React\r\ngun = GUN();\r\n\r\ngun.get('mark').put({\r\n  name: \"Mark\",\r\n  email: \"mark@gun.eco\",\r\n});\r\n\r\ngun.get('mark').on((data, key) => {\r\n  console.log(\"realtime updates:\", data);\r\n});\r\n\r\nsetInterval(() => { gun.get('mark').get('live').put(Math.random()) }, 9);\r\n</script>\r\n```\r\n- Or try something **mind blowing**, like saving circular references to a table of documents! ([play](http://jsbin.com/wefozepume/edit?js,console))\r\n```javascript\r\ncat = {name: \"Fluffy\", species: \"kitty\"};\r\nmark = {boss: cat};\r\ncat.slave = mark;\r\n\r\n// partial updates merge with existing data!\r\ngun.get('mark').put(mark);\r\n\r\n// access the data as if it is a document.\r\ngun.get('mark').get('boss').get('name').once(function(data, key){\r\n  // `once` grabs the data once, no subscriptions.\r\n  console.log(\"Mark's boss is\", data);\r\n});\r\n\r\n// traverse a graph of circular references!\r\ngun.get('mark').get('boss').get('slave').once(function(data, key){\r\n  console.log(\"Mark is the cat's slave!\", data);\r\n});\r\n\r\n// add both of them to a table!\r\ngun.get('list').set(gun.get('mark').get('boss'));\r\ngun.get('list').set(gun.get('mark'));\r\n\r\n// grab each item once from the table, continuously:\r\ngun.get('list').map().once(function(data, key){\r\n  console.log(\"Item:\", data);\r\n});\r\n\r\n// live update the table!\r\ngun.get('list').set({type: \"cucumber\", goal: \"jumping cat\"});\r\n```\r\n\r\nWant to keep building more? **Jump to [THE DOCUMENTATION](#documentation)!**\r\n\r\n# About\r\nFirst & foremost, GUN is **a community of the nicest and most helpful people** out there. So [I want to invite you](http://chat.gun.eco) to come tell us about what **you** are working on & wanting to build (new or old school alike! Just be nice as well.) and ask us your questions directly. :)\r\n\r\n<p align=\"center\"><a href=\"https://www.youtube.com/watch?v=oTQXzhm8w_8\"><img width=\"250\" src=\"https://img.youtube.com/vi/oTQXzhm8w_8/0.jpg\"><br/>Watch the 100 second intro!</a></p>\r\n\r\nThe GUN ecosystem stack is a collection of independent and modular tools covering everything from [CRDT](https://crdt.tech/) [conflict resolution](https://gun.eco/distributed/matters.html), [cryptographic security](https://gun.eco/docs/Cartoon-Cryptography) & [encryption](https://gun.eco/docs/SEA), [radix storage serialization](https://gun.eco/docs/RAD), [mesh networking](https://gun.eco/docs/DAM) & [routing algorithms](https://gun.eco/docs/Routing), to distributed systems [correctness & load testing](https://github.com/gundb/panic-server), CPU scheduled [JSON parser](https://github.com/amark/gun/blob/master/lib/yson.js) to prevent UI lag, and more!\r\n\r\n<div><img width=\"48%\" src=\"https://gun.eco/see/stack.png\"/>\r\n<img width=\"48%\" align=\"right\" src=\"https://gun.eco/see/layers.png\"/></div>\r\n\r\nOn that note, let's get some official shout outs covered first:\r\n\r\n### Support\r\n\r\n<p align=\"center\">\r\nThanks to:\r\n\r\n<table>\r\n<tr>\r\n<td vlign=\"center\"><a href=\"https://mozilla.org/builders\"><img height=\"100\" src=\"https://user-images.githubusercontent.com/1423657/81992335-85346480-9643-11ea-8754-8275e98e06bc.png\"></a></td>\r\n<td vlign=\"center\"><a href=\"http://unstoppabledomains.com/\"><img src=\"https://gun.eco/img/unstoppable.png\"></a></td>\r\n<td vlign=\"center\"><a href=\"https://mask.io/\"><img src=\"https://dimensiondev.github.io/Mask-VI/assets/Logo/MB--Logo--CombH-Circle--Blue.svg\" width=\"250\"></a></td>\r\n</tr>\r\n<tr>\r\n<td vlign=\"center\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"https://www.ajar.org/\"><img src=\"https://www.ajar.org/logo.png\" height=\"120\"></a></td>\r\n<td vlign=\"center\"><a href=\"https://wallie.io/\"><img src=\"https://raw.githubusercontent.com/gundb/gun-site/master/img/wallie.png\" width=\"250\"></a></td>\r\n<td vlign=\"center\">&nbsp;&nbsp;<a href=\"https://ghostdrive.com/\"><img src=\"https://gun.eco/img/ghostdrive.png\" height=\"120\"></a></td>\r\n</tr>\r\n</table>\r\n\r\n<a href=\"https://github.com/robertheessels\">Robert Heessels</a>,\r\n<a href=\"http://qxip.net/\">Lorenzo Mangani</a>,\r\n<a href=\"https://nlnet.nl/\">NLnet Foundation</a>,\r\n<a href=\"http://github.com/samliu\">Sam Liu</a>,\r\n<a href=\"http://github.com/ddombrow\">Daniel Dombrowsky</a>,\r\n<a href=\"http://github.com/vincentwoo\">Vincent Woo</a>,\r\n<a href=\"http://github.com/coolaj86\">AJ ONeal</a>,\r\n<a href=\"http://github.com/ottman\">Bill Ottman</a>,\r\n<a href=\"http://github.com/mikewlange\">Mike Lange</a>,\r\n<a href=\"http://github.com/ctrlplusb\">Sean Matheson</a>,\r\n<a href=\"http://github.com/alanmimms\">Alan Mimms</a>,\r\n<a href=\"https://github.com/dfreire\">Dário Freire</a>,\r\n<a href=\"http://github.com/velua\">John Williamson</a>,\r\n<a href=\"http://github.com/finwo\">Robin Bron</a>,\r\n<a href=\"http://github.com/ElieMakhoul\">Elie Makhoul</a>,\r\n<a href=\"http://github.com/mikestaub\">Mike Staub</a>,\r\n<a href=\"http://github.com/bmatusiak\">Bradley Matusiak</a>,\r\n<a href=\"https://github.com/sjuxax\">Jeff Cook</a>,\r\n<a href=\"https://github.com/nmauersberg\">Nico</a>,\r\n<a href=\"https://github.com/ajartille\">Aaron Artille</a>,\r\n<a href=\"https://github.com/timjrobinson\">Tim Robinson</a>,\r\n<a href=\"https://github.com/hibas123\">Fabian Stamm</a>,\r\n<a href=\"https://twitter.com/mikestaub\">Mike Staub</a>,\r\n<a href=\"https://hunterowens.com/\">Hunter Owens</a>,\r\n<a href=\"https://github.com/JacobMillner\">Jacob Millner</a>,\r\n<a href=\"https://github.com/b-lack\">Gerrit Balindt</a>,\r\n<a href=\"https://github.com/gabriellemon\">Gabriel Lemon</a>,\r\n<a href=\"https://github.com/murageyun\">Murage Martin</a>,\r\n<a href=\"https://github.com/octalmage\">Jason Stallings</a>\r\n</p>\r\n\r\n - Join others in sponsoring code: https://www.patreon.com/gunDB !\r\n - Ask questions: http://stackoverflow.com/questions/tagged/gun ?\r\n - Found a bug? Report at: https://github.com/amark/gun/issues ;\r\n - **Need help**? Chat with us: http://chat.gun.eco .\r\n\r\n### History\r\n\r\n[GUN](https://gun.eco) was created by [Mark Nadal](https://twitter.com/marknadal) in 2014 after he had spent 4 years trying to get his collaborative web app to scale up with traditional databases.\r\n\r\n<img width=\"250px\" src=\"https://gun.eco/see/problem.png\" align=\"left\" title=\"pain point\" style=\"margin: 0 1em 1em 0\"> After he realized [Master-Slave database architecture causes one big bottleneck](https://gun.eco/distributed/matters.html), he (as a complete newbie outsider) naively decided **to question the status quo** and shake things up with controversial, heretical, and contrarian experiments:\r\n\r\n**The NoDB** - no master, no servers, no \"single source of truth\", not built with a real programming language or real hardware, no DevOps, no locking, not *just* SQL or NoSQL but both (**all** - graphs, documents, tables, key/value).\r\n\r\nThe goal was to build a P2P database that could survive living inside **any** browser, and could correctly sync data between **any** device after assuming **any** offline-first activity.\r\n\r\n<img src=\"https://gun.eco/see/compare.png\" title=\"comparison table\">\r\n\r\nTechnically, **GUN is a graph synchronization protocol** with a *lightweight embedded engine*, capable of doing *[20M+ API ops/sec](https://gun.eco/docs/Performance)* in **just ~9KB gzipped size**.\r\n\r\n## Documentation\r\n\r\n<table>\r\n  <tr>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/API\">API reference</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/Todo-Dapp\">Tutorials</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://github.com/amark/gun/tree/master/examples\">Examples</a></h3></td>\r\n  </tr>\r\n  <tr>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://github.com/brysgo/graphql-gun\">GraphQL</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://github.com/PenguinMan98/electrontest\">Electron</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/React-Native\">React & Native</a></h3></td>\r\n  </tr>\r\n  <tr>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://github.com/sjones6/vue-gun\">Vue</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/Svelte\">Svelte</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://github.com/Stefdv/gun-ui-lcd#syncing\">Webcomponents</a></h3></td>\r\n  </tr>\r\n  <tr>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/CAP-Theorem\">CAP Theorem Tradeoffs</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/distributed/matters.html\">How Data Sync Works</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/Porting-GUN\">How GUN is Built</a></h3></td>\r\n  </tr>\r\n  <tr>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/Auth\">Crypto Auth</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://github.com/amark/gun/wiki/Awesome-GUN\">Modules</a></h3></td>\r\n    <td style=\"border: 0;\"><h3><a href=\"https://gun.eco/docs/Roadmap\">Roadmap</a></h3></td>\r\n  </tr>\r\n</table>\r\n\r\nThis would not be possible without **community contributors**, big shout out to:\r\n\r\n**[ajmeyghani](https://github.com/ajmeyghani) ([Learn GUN Basics with Diagrams](https://medium.com/@ajmeyghani/gundb-a-graph-database-in-javascript-3860a08d873c))**; **[anywhichway](https://github.com/anywhichway) ([Block Storage](https://github.com/anywhichway/gun-block))**; **[beebase](https://github.com/beebase) ([Quasar](https://github.com/beebase/gun-vuex-quasar))**; **[BrockAtkinson](https://github.com/BrockAtkinson) ([brunch config](https://github.com/BrockAtkinson/brunch-gun))**; **[Brysgo](https://github.com/brysgo) ([GraphQL](https://github.com/brysgo/graphql-gun))**; **[d3x0r](https://github.com/d3x0r) ([SQLite](https://github.com/d3x0r/gun-db))**; **[forrestjt](https://github.com/forrestjt) ([file.js](https://github.com/amark/gun/blob/master/lib/file.js))**; **[hillct](https://github.com/hillct) (Docker)**; **[JosePedroDias](https://github.com/josepedrodias) ([graph visualizer](http://acor.sl.pt:9966))**; **[JuniperChicago](https://github.com/JuniperChicago) ([cycle.js bindings](https://github.com/JuniperChicago/cycle-gun))**; **[jveres](https://github.com/jveres) ([todoMVC](https://github.com/jveres/todomvc))**; **[kristianmandrup](https://github.com/kristianmandrup) ([edge](https://github.com/kristianmandrup/gun-edge))**; **[Lightnet](https://github.com/Lightnet)** ([Awesome Vue User Examples](https://glitch.com/edit/#!/jsvuegunui?path=README.md:1:0) & [User Kitchen Sink Playground](https://gdb-auth-vue-node.glitch.me/)); **[lmangani](https://github.com/lmangani) ([Cytoscape Visualizer](https://github.com/lmangani/gun-scape), [Cassandra](https://github.com/lmangani/gun-cassandra), [Fastify](https://github.com/lmangani/fastify-gundb), [LetsEncrypt](https://github.com/lmangani/polyGun-letsencrypt))**; **[mhelander](https://github.com/mhelander) ([SEA](https://github.com/amark/gun/blob/master/sea.js))**; [omarzion](https://github.com/omarzion) ([Sticky Note App](https://github.com/omarzion/stickies)); [PsychoLlama](https://github.com/PsychoLlama) ([LevelDB](https://github.com/PsychoLlama/gun-level)); **[RangerMauve](https://github.com/RangerMauve) ([schema](https://github.com/gundb/gun-schema))**; **[robertheessels](https://github.com/swifty) ([gun-p2p-auth](https://github.com/swifty/gun-p2p-auth))**; **[rogowski](https://github.com/rogowski) (AXE)**; [sbeleidy](https://github.com/sbeleidy); **[sbiaudet](https://github.com/sbiaudet) ([C# Port](https://github.com/sbiaudet/cs-gun))**; **[Sean Matheson](https://github.com/ctrlplusb) ([Observable/RxJS/Most.js bindings](https://github.com/ctrlplusb/gun-most))**; **[Shadyzpop](https://github.com/Shadyzpop) ([React Native example](https://github.com/amark/gun/tree/master/examples/react-native))**; **[sjones6](https://github.com/sjones6) ([Flint](https://github.com/sjones6/gun-flint))**; RIP **[Stefdv](https://github.com/stefdv) (Polymer/web components)**; **[zrrrzzt](https://github.com/zrrrzzt) ([JWT Auth](https://gist.github.com/zrrrzzt/6f88dc3cedee4ee18588236756d2cfce))**; **[xmonader](https://github.com/xmonader) ([Python Port](https://github.com/xmonader/pygundb))**; \r\n\r\nI am missing many others, apologies, will be adding them soon! This list is infinitely old & way out of date, if you want to be listed in it please make a PR! :)\r\n\r\n## Testing\r\n\r\nYou will need to `npm install -g mocha` first. Then in the gun root folder run `npm test`. Tests will trigger persistent writes to the DB, so subsequent runs of the test will fail. You must clear the DB before running the tests again. This can be done by running `rm -rf *data*` command in the project directory.\r\n\r\n## Shims\r\n\r\n > These are only needed for NodeJS & React Native, they shim the native Browser WebCrypto API.\r\n\r\nIf you want to use [SEA](https://gun.eco/docs/SEA) for `User` auth and security, you will need to install:\r\n\r\n`npm install @peculiar/webcrypto --save`\r\n\r\nPlease see [our React Native docs](https://gun.eco/docs/React-Native) for installation instructions!\r\n\r\nThen you can require [SEA](https://gun.eco/docs/SEA) without an error:\r\n\r\n```javascript\r\nGUN = require('gun/gun');\r\nSEA = require('gun/sea');\r\n```\r\n\r\n## Deploy\r\n\r\n > Note: The default examples that get auto-deployed on `npm start` CDN-ify all GUN files, modules, & storage.\r\n \r\n > Note: Moving forward, AXE will start to automatically cluster your peer into a shared DHT. You may want to disable this to run an isolated network.\r\n \r\n > Note: When deploying a web application using GUN on a cloud provider, you may have to set `CI=false` in your `.env`. This prevents GUN-specific warnings from being treated as errors when deploying your app. You may also resolve this by modifying your webpack config to not try to build the GUN dependencies.\r\n\r\nTo quickly spin up a GUN relay peer for your development team, utilize [Heroku](http://heroku.com), [Docker](http://docker.com), or any others listed below. Or some variant thereof [Dokku](http://dokku.viewdocs.io/dokku/), K8s, etc. ! Or use all of them so your relays are decentralized too!\r\n\r\n### Linux\r\n\r\n`SSH` into the home directory of a clean OS install with `sudo` ability. Set any environment variables you need (see below), then do:\r\n\r\n```bash\r\ncurl -o- https://raw.githubusercontent.com/amark/gun/master/examples/install.sh | bash\r\n```\r\n\r\n > Read [install.sh](https://github.com/amark/gun/blob/master/examples/install.sh) first!\r\n > If `curl` is not found, *copy&paste* the contents of install.sh into your ssh.\r\n\r\nYou can now safely `CTRL+A+D` to escape without stopping the peer. To stop everything `killall screen` or `killall node`.\r\n\r\nEnvironment variables may need to be set like `export HTTPS_CERT=~/cert.pem HTTPS_KEY=~/key.pem PORT=443`. You can also look at a sample [nginx](https://gun.eco/docs/nginx) config. For production deployments, you probably will want to use something like `pm2` or better to keep the peer alive after machine reboots.\r\n\r\n### [Dome](https://www.trydome.io/)\r\n[Deploy GUN in one-click](https://app.trydome.io/signup?package=gun) with [Dome](https://trydome.io) and receive a free trial:\r\n\r\n[![Deploy to Dome](https://trydome.io/button.svg)](https://app.trydome.io/signup?package=gun)\r\n\r\n### [Heroku](https://www.heroku.com/)\r\n\r\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/amark/gun)\r\n\r\n > Heroku deletes your data every 15 minutes, one way to fix this is by adding [cheap storage](https://gun.eco/docs/Using-Amazon-S3-for-Storage).\r\n\r\nOr:\r\n\r\n```bash\r\ngit clone https://github.com/amark/gun.git\r\ncd gun\r\nheroku create\r\ngit push -f heroku HEAD:master\r\n```\r\n\r\nThen visit the URL in the output of the 'heroku create' step, in a browser. Make sure to set any environment config vars in the settings tab.\r\n\r\n### [Zeet.co](https://www.zeet.co/)\r\n\r\n[![Deploy](https://deploy.zeet.co/gun.svg)](https://deploy.zeet.co/?url=https://github.com/amark/gun)\r\n\r\nThen visit the URL in the output of the 'now --npm' step, in your browser.\r\n\r\n### [Docker](https://www.docker.com/)\r\n\r\n > Warning: Docker image is community contributed and may be old with missing security updates, please check version numbers to compare.\r\n\r\n[![Docker Automated build](https://img.shields.io/docker/automated/gundb/gun.svg)](https://hub.docker.com/r/gundb/gun/) [![](https://images.microbadger.com/badges/image/gundb/gun.svg)](https://microbadger.com/images/gundb/gun \"Get your own image badge on microbadger.com\") [![Docker Pulls](https://img.shields.io/docker/pulls/gundb/gun.svg)](https://hub.docker.com/r/gundb/gun/) [![Docker Stars](https://img.shields.io/docker/stars/gundb/gun.svg)](https://hub.docker.com/r/gundb/gun/)\r\n\r\nPull from the [Docker Hub](https://hub.docker.com/r/gundb/gun/) [![](https://images.microbadger.com/badges/commit/gundb/gun.svg)](https://microbadger.com/images/gundb/gun). Or:\r\n\r\n```bash\r\ndocker run -p 8765:8765 gundb/gun\r\n```\r\n\r\nOr build the [Docker](https://docs.docker.com/engine/installation/) image locally:\r\n\r\n```bash\r\ngit clone https://github.com/amark/gun.git\r\ncd gun\r\ndocker build -t myrepo/gundb:v1 .\r\ndocker run -p 8765:8765 myrepo/gundb:v1\r\n```\r\n\r\nOr, if you prefer your Docker image with metadata labels (Linux/Mac only):\r\n\r\n```bash\r\nnpm run docker\r\ndocker run -p 8765:8765 username/gun:git\r\n```\r\n\r\nThen visit [http://localhost:8765](http://localhost:8765) in your browser.\r\n\r\n## License\r\n\r\nDesigned with ♥ by Mark Nadal, the GUN team, and many amazing contributors.\r\n\r\nOpenly licensed under [Zlib / MIT / Apache 2.0](https://github.com/amark/gun/blob/master/LICENSE.md).\r\n\r\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Famark%2Fgun.svg?size=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Famark%2Fgun?ref=badge_large)\r\n\r\n[YouTube](https://www.youtube.com/channel/UCQAtpf-zi9Pp4__2nToOM8g) . [Twitter](https://twitter.com/marknadal)\r\n"
  },
  {
    "path": "RELEASE.md",
    "content": "Every push or pull request will\n\n - run the tests\n\nEvery push to master will\n\n - run the tests\n - publish the latest docker image to dockerhub\n\nCreating a tag that starts with `v` will\n\n - create a new github release\n - publish the release to npm\n - publish the release to dockerhub\n\nCreating a release from the github web interface will\n\n - publish the release to npm\n - publish the release to dockerhub\n\nCreating the release for version `0.2021.001` from the command line works as follows\n\n    git tag v0.2021.001\n    git push --tags\n\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Introduction\n\nSecurity is our top priority. We are committed to ensuring that our project is as secure as possible for everyone who uses it. This document outlines our security policy and procedures for dealing with security issues.\n\n## Supported Versions\n\nWe provide security updates for the following versions of our project:\n\n| Version | Supported          |\n| ------- | ------------------ |\n| 0.2020.x| :white_check_mark: |\n| < 0.2020| :x:                |\n\n## Reporting a Vulnerability\n\nIf you discover a vulnerability, we would like to know about it so we can take steps to address it as quickly as possible.\n\n### Report Format\n\nWhen reporting vulnerabilities, please include the following details:\n\n- Description of the vulnerability\n- Steps to reproduce the issue\n- Potential impact if left unaddressed\n- Suggested mitigation or resolution if any\n\n### Response Time\n\nWe aim to confirm the receipt of your vulnerability report within 48 hours. Depending on the severity and complexity of the issue, we strive to investigate the issue and provide an initial response within a week.\n\n### Disclosure Policy\n\nIf the vulnerability is confirmed, we will work on a fix and plan a release. We ask that you do not publicly disclose the issue until it has been addressed by us.\n\n## Security Practices\n\nWe follow industry-standard security practices, including regular audits of the services and features we provide, to maintain the trust of our users.\n\n## Security Updates\n\nWe will communicate any security updates through our standard communication channels, including our project's release notes and official website.\n\n## Conclusion\n\nWe greatly value the work of security researchers and believe that responsible disclosure of vulnerabilities is a valuable contribution to the security of the Internet. We encourage users to contribute to the security of our project by reporting any security-related issues to us."
  },
  {
    "path": "app.json",
    "content": "{\n  \"name\": \"gun-server\",\n  \"website\": \"http://gun.eco/\",\n  \"repository\": \"https://github.com/amark/gun\",\n  \"logo\": \"https://avatars3.githubusercontent.com/u/8811914\",\n  \"keywords\": [\"node\", \"gun\", \"gunDB\", \"database\",\"graph\",\"offline-first\"],\n  \"description\": \"Javascript, Offline-First Javascript Graph Database Server Peer\",\n  \"env\": {\n    \"NPM_CONFIG_PRODUCTION\": {\n      \"description\": \"If you do not want default features, set to \\\"true\\\".\",\n      \"value\": \"false\"\n    },\n    \"PEERS\": {\n      \"description\": \"Comma-separated list of peer urls to connect to\",\n      \"required\": false\n    }\n  }\n}\n"
  },
  {
    "path": "as.js",
    "content": ";(function(){\n\tfunction as(el, gun, cb, opt){\n\t\tel = $(el);\n\t\tif(gun === as.gui && as.el && as.el.is(el)){ return }\n\n\t\topt = opt || {};\n\t\topt.match = opt.match || '{{ ';\n\t\topt.end = opt.end || ' }}';\n\t\t;(function(){ // experimental\n\t\t\tfunction nest(t, s,e, r, i,tmp,u){\n\t\t\t\tif(r && !r.length){ return t||'' }\n\t\t\t\tif(!t){ return [] }\n\t\t\t\te = e || s;\n\t\t\t\ti = t.indexOf(s, i||0);\n\t\t\t\tif(0 > i){ return [] }\n\t\t\t\ttmp = t.indexOf(e, i+1);\n\t\t\t\tif(!r){ return [t.slice(i+s.length, tmp)].concat(nest(t, s,e, r, tmp,tmp,u)) }\n\t\t\t\treturn t.slice(0,i)+r[0]+nest(t.slice(tmp+e.length), s,e, r.slice(1), 0,tmp,u);\n\t\t\t}\n\n\t\t\t/* experimental */\n\t\t\tfunction template(tag, attr){\n\t\t\t\tvar html = (tag = $(tag))[0].outerHTML, sub, tmp;\n\t\t\t\tif(html && (0 > html.indexOf(opt.match))){ return }\n\t\t\t\tif(!attr){\n\t\t\t\t\t$.each(tag[0].attributes, function(i,v){\n\t\t\t\t\t\tif(!v){ return }\n\t\t\t\t\t\tif(!nest(v.value, opt.match, opt.end).length){ return }\n\t\t\t\t\t\ttemplate(tag, v.name)\n\t\t\t\t\t});\n\t\t\t\t\tif((sub = tag.children()).length){\n\t\t\t\t\t\treturn sub.each(function(){ template(this) });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar data = [], plate = attr? tag.attr(attr) : tag.html();\n\t\t\t\ttmp = nest(plate, opt.match, opt.end);\n\t\t\t\tif(!tmp.length){ return }\n\t\t\t\t$.each(tmp, function(pos, match){\n\t\t\t\t\tvar expr = match.split(' ');\n\t\t\t\t\tvar path = (expr[0]).split('.');\n\t\t\t\t\tif(expr = expr.slice(1).join(' ')){\n\t\t\t\t\t\texpr = new Function(\"_\", \"b\", \"return (_)\" + expr);\n\t\t\t\t\t}\n\t\t\t\t\tvar val = (expr && expr('')) || '';\n\t\t\t\t\tdata.push(val);\n\t\t\t\t\tif(!attr){ tag.text(val) }\n\n\t\t\t\t\tvar ref = gun, sup = [], tmp;\n\t\t\t\t\tif(tmp = tag.attr('name')){ sup.push(tmp) }\n\t\t\t\t\ttag.parents(\"[name]\").each(function(){\n\t\t\t\t\t\tsup.push($(this).attr('name'));\n\t\t\t\t\t});\n\t\t\t\t\t$.each(path = sup.reverse().concat(path), function(i,v){\n\t\t\t\t\t\tref = ref.get(v);\n\t\t\t\t\t});\n\t\t\t\t\tref.on(function(v){\n\t\t\t\t\t\tv = data[pos] = expr? expr(v) : v;\n\t\t\t\t\t\tvar tmp = nest(plate, opt.match, opt.end, data);\n\t\t\t\t\t\tif(attr){\n\t\t\t\t\t\t\ttag.attr(attr, tmp);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttag.text(tmp);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t\ttemplate(el);\n\n\t\t}());\n\n\t\tas.gui = gun;\n\t\tas.el = el;\n\t\tif(el.data('as')){\n\t\t\tel.html(el.data('as').fresh);\n\t\t} else {\n\t\t\tel.data('as', {\n\t\t\t\tfresh: el.html()\n\t\t\t})\n\t\t}\n\t\tel.find(\"[name]\").each(function(){\n\t\t\tif($(this).find(\"[name]\").length){ return }\n\t\t\tvar name = $(this),\n\t\t\t\tparents = name.parents(\"[name]\"),\n\t\t\t\tpath = [],\n\t\t\t\tref = gun;\n\n\t\t\tpath.push(name.attr('name'));\n\t\t\tparents.each(function(){\n\t\t\t\tpath.push($(this).attr('name'));\n\t\t\t});\n\t\t\tpath = path.reverse();\n\n\t\t\tpath.forEach(function(key){\n\t\t\t\tif('#' === key){\n\t\t\t\t\tref = ref.map()\n\t\t\t\t} else {\n\t\t\t\t\tref = ref.get(key);\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tvar many = path.slice().reverse().indexOf('#'), model;\n\t\t\tmany = (0 < ++many)? many : false;\n\t\t\tif(many){\n\t\t\t\tmodel = name.closest(\"[name='#']\");\n\t\t\t\tmodel = model.data('model') || model.data('model', {$: model.clone(), on: model.parent(), has: {}}).hide().data('model');\n\t\t\t} \n\n\t\t\tref.get(function(at){\n\t\t\t\tvar data = at.put, key = at.get, gui = at.gun || at.$, ui = name, back;\n\t\t\t\tif(model){\n\t\t\t\t\tui = model.has[(gui._).id];\n\t\t\t\t\tif(!ui){\n\t\t\t\t\t\tback = gui.back(many - 1);\n\t\t\t\t\t\tui = model.has[(back._).id];\n\t\t\t\t\t\tif(!ui){\n\t\t\t\t\t\t\tif(!(back._).get){ return }\n\t\t\t\t\t\t\tui = (model.has[(back._).id] = model.$.clone(true).prependTo(model.on));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tui = ui.find(\"[name='\"+key+\"']\").first();\n\t\t\t\t\t\tmodel.has[(gui._).id] = ui;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tui.data('gun', gui);\n\t\t\t\tif(ui.data('was') === data){ return }\n\t\t\t\tif(many && ui.is('.sort')){\n\t\t\t\t\tvar up = ui.closest(\"[name='#']\");\n\t\t\t\t\tvar tmp = as.sort(data, up.parent().children().last());\n\t\t\t\t\ttmp? up.insertAfter(tmp) : up.prependTo(up.parent());\n\t\t\t\t}\n\t\t\t\tif(as.lock === gui){ return }\n\t\t\t\tif(!(data && data instanceof Object)){\n\t\t\t\t\t(ui[0] && u === ui[0].value)? ui.text(data) : ui.val(data);\n\t\t\t\t}\n\t\t\t\tui.data('was', data);\n\t\t\t\tif(cb){\n\t\t\t\t\tcb(data, key, ui);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\tas.wait = function(cb, wait, to){\n\t\treturn function(a,b,c){\n\t\t\tvar me = as.typing = this;\n\t\t\tclearTimeout(to);\n\t\t\tto = setTimeout(function(){\n\t\t\t\tcb.call(me, a,b,c);\n\t\t\t\tas.typing = me = false;\n\t\t\t}, wait || 200);\n\t\t}\n\t}\n\tas.sort = function sort(num, li){ return parseFloat(num) >= parseFloat($(li).find('.sort').text() || -Infinity)? li : sort(num, li.prev()) }\n\t$(document).on('keyup', 'input, textarea, [contenteditable]', as.wait(function(){\n\t\tvar el = $(this);\n\t\tvar data = (el[0] && u === el[0].value)? el.text() : el.val();\n\t\tvar g = el.data('gun');\n\t\tif(!g){ return }\n\t\tas.lock = g;\n\t\tg.put(data);\n\t}, 99));\n\t//$(document).on('submit', 'form', function(e){ e.preventDefault() });\n\tvar u;\n\twindow.as = as;\n\t$.as = as;\n}());\n\n;(function(){\n\t$(document).on('click', 'a, button', function(e){\n\t\tvar tmp = $(this).attr('href') || '';\n\t\tif(0 === tmp.indexOf('http')){ return }\n\t\te.preventDefault();\n\t\tr(tmp);\n\t});\n\tfunction r(href){\n\t\tif(!href){ return }\n\t\tif(href[0] == '#'){ href = href.slice(1) }\n\t\tvar h = href.split('/')[0];\n\t\t$('.page').hide();\n\t\t$('#' + h).show();\n\t\tif(r.on === h){ return }\n\t\tlocation.hash = href;\n\t\t(r.page[h] || {on:function(){}}).on();\n\t\tr.on = h;\n\t\treturn r;\n\t};\n\tr.page = function(h, cb){\n\t\tr.page[h] = r.page[h] || {on: cb};\n\t\treturn r;\n\t}\n\tr.render = function(id, model, onto, data){\n\t\tvar $data = $(\n\t\t\t$('#' + id).get(0) ||\n\t\t\t$('.model').find(model).clone(true).attr('id', id).appendTo(onto)\n\t\t);\n\t\t$.each(data, function(field, val){\n\t\t\tif($.isPlainObject(val)){ return }\n\t\t\t$data.find(\"[name='\" + field + \"']\").val(val).text(val);\n\t\t});\n\t\treturn $data;\n\t}\n\twindow.onhashchange = function(){ r(location.hash.slice(1)) };\n\t$.as && ($.as.route = r);\n\tif(window.as){\n\t\tas.route = r;\n\t} else {\n\t\t$.route = r;\n\t}\n}());\n\n;$(function(){\n\t$('.page').not(':first').hide();\n\t$.as.route(location.hash.slice(1));\n\t$(JOY.start = JOY.start || function(){ $.as(document, gun, null, JOY.opt) });\n\n\tif($('body').attr('peers')){ (console.warn || console.log)('Warning: Please upgrade <body peers=\"\"> to https://github.com/eraeco/joydb#peers !') }\n\n});\n;(function(){ // need to isolate into separate module!\n\tvar joy = window.JOY = function(){};\n\tjoy.auth = function(a,b,cb,o){\n\t\tif(!o){ o = cb ; cb = 0 }\n\t\tif(o === true){\n\t\t\tgun.user().create(a, b);\n\t\t\treturn;\n\t\t}\n\t\tgun.user().auth(a,b, cb,o);\n\t}\n\n\tvar opt = joy.opt = window.CONFIG || {}, peers;\n\t$('link[type=peer]').each(function(){ (peers || (peers = [])).push($(this).attr('href')) });\n\t!window.gun && (opt.peers = opt.peers || peers || (function(){\n\t\t(console.warn || console.log)('Warning: No peer provided, defaulting to DEMO peer. Do not run in production, or your data will be regularly wiped, reset, or deleted. For more info, check https://github.com/eraeco/joydb#peers !');\n\t\treturn ['https://gunjs.herokuapp.com/gun'];\n\t}()));\n\twindow.gun = window.gun || Gun(opt);\n\n\tgun.on('auth', function(ack){\n\t\tconsole.log(\"Your namespace is publicly available at\", ack.soul);\n\t});\n}());"
  },
  {
    "path": "axe.js",
    "content": ";(function(){\n\n\tvar sT = setTimeout || {}, u;\n  if(typeof window !== ''+u){ sT.window = window }\n\tvar AXE = (sT.window||'').AXE || function(){};\n  if(AXE.window = sT.window){ AXE.window.AXE = AXE }\n\n\tvar Gun = (AXE.window||'').GUN || require('./gun');\n\t(Gun.AXE = AXE).GUN = AXE.Gun = Gun;\n\n  //if(!Gun.window){ try{ require('./lib/axe') }catch(e){} }\n  if(!Gun.window){ require('./lib/axe') }\n\n\tGun.on('opt', function(at){ start(at) ; this.to.next(at) }); // make sure to call the \"next\" middleware adapter.\n\n\tfunction start(root){\n\t\tif(root.axe){ return }\n\t\tvar opt = root.opt, peers = opt.peers;\n\t\tif(false === opt.axe){ return }\n\t\tif(!Gun.window){ return } // handled by ^ lib/axe.js\n\t\tvar w = Gun.window, lS = w.localStorage || opt.localStorage || {}, loc = w.location || opt.location || {}, nav = w.navigator || opt.navigator || {};\n\t\tvar axe = root.axe = {}, tmp, id;\n\t\tvar mesh = opt.mesh = opt.mesh || Gun.Mesh(root); // DAM!\n\n\t\ttmp = peers[id = loc.origin + '/gun'] = peers[id] || {};\n\t\ttmp.id = tmp.url = id; tmp.retry = tmp.retry || 0;\n\t\ttmp = peers[id = 'http://localhost:8765/gun'] = peers[id] || {};\n\t\ttmp.id = tmp.url = id; tmp.retry = tmp.retry || 0;\n\t\tGun.log.once(\"AXE\", \"AXE enabled: Trying to find network via (1) local peer (2) last used peers (3) a URL parameter, and last (4) hard coded peers.\");\n\t\tGun.log.once(\"AXEWarn\", \"Warning: AXE is in alpha, use only for testing!\");\n\t\tvar last = lS.peers || ''; if(last){ last += ' ' }\n\t\tlast += ((loc.search||'').split('peers=')[1]||'').split('&')[0];\n\n\t\troot.on('bye', function(peer){\n\t\t\tthis.to.next(peer);\n\t\t\tif(!peer.url){ return } // ignore WebRTC disconnects for now.\n\t\t\tif(!nav.onLine){ peer.retry = 1 }\n\t\t\tif(peer.retry){ return }\n\t\t\tif(axe.fall){ delete axe.fall[peer.url || peer.id] }\n\t\t\t(function next(){\n\t\t\t\tif(!axe.fall){ setTimeout(next, 9); return } // not found yet\n\t\t\t\tvar fall = Object.keys(axe.fall||''), one = fall[(Math.random()*fall.length) >> 0];\n\t\t\t\tif(!fall.length){ lS.peers = ''; one = 'https://gunjs.herokuapp.com/gun' } // out of peers\n\t\t\t\tif(peers[one]){ next(); return } // already choose\n\t\t\t\tmesh.hi(one);\n\t\t\t}());\n\t\t});\n\n\t\troot.on('hi', function(peer){ // TEMPORARY! Try to connect all peers.\n\t\t\tthis.to.next(peer);\n\t\t\tif(!peer.url){ return } // ignore WebRTC disconnects for now.\n\t\t\treturn; // DO NOT COMMIT THIS FEATURE YET! KEEP TESTING NETWORK PERFORMANCE FIRST!\n\t\t\t(function next(){\n\t\t\t\tif(!peer.wire){ return }\n\t\t\t\tif(!axe.fall){ setTimeout(next, 9); return } // not found yet\n\t\t\t\tvar one = (next.fall = next.fall || Object.keys(axe.fall||'')).pop();\n\t\t\t\tif(!one){ return }\n\t\t\t\tsetTimeout(next, 99);\n\t\t\t\tmesh.say({dam: 'opt', opt: {peers: one}}, peer);\n\t\t\t}());\n\t\t});\n\n\t\tfunction found(text){\n\n\t\t\taxe.fall = {};\n\t\t\t((text||'').match(/https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)/ig)||[]).forEach(function(url){\n\t\t\t\taxe.fall[url] = {url: url, id: url, retry: 0}; // RETRY\n\t\t\t});\n\t\t\t\n\t\t\treturn;\n\n\t\t\t// TODO: Finish porting below? Maybe not.\n\n\t\t\tObject.keys(last.peers||'').forEach(function(key){\n\t\t\t\ttmp = peers[id = key] = peers[id] || {};\n\t\t\t\ttmp.id = tmp.url = id;\n\t\t\t});\n\t\t\ttmp = peers[id = 'https://guntest.herokuapp.com/gun'] = peers[id] || {};\n\t\t\ttmp.id = tmp.url = id;\n\n\t\t\tvar mesh = opt.mesh = opt.mesh || Gun.Mesh(root); // DAM!\n\t\t\tmesh.way = function(msg){\n\t\t\t\tif(root.$ === msg.$ || (msg._||'').via){\n\t\t\t\t\tmesh.say(msg, opt.peers);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar at = (msg.$||'')._;\n\t\t\t\tif(!at){ mesh.say(msg, opt.peers); return }\n\t\t\t\tif(msg.get){\n\t\t\t\t\tif(at.axe){ return } // don't ask for it again!\n\t\t\t\t\tat.axe = {};\n\t\t\t\t}\n\t\t\t\tmesh.say(msg, opt.peers);\n\t\t\t}\n\t\t}\n\n\t\tif(last){ found(last); return }\n\t\ttry{ fetch(((loc.search||'').split('axe=')[1]||'').split('&')[0] || loc.axe || 'https://raw.githubusercontent.com/wiki/amark/gun/volunteer.dht.md').then(function(res){\n\t  \treturn res.text()\n\t  }).then(function(text){\n\t  \tfound(lS.peers = text);\n\t  }).catch(function(){\n\t  \tfound(); // nothing\n\t  })}catch(e){found()}\n\t}\n\n\tvar empty = {}, yes = true;\n  try{ if(typeof module != ''+u){ module.exports = AXE } }catch(e){}\n}());"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"gun\",\n  \"main\": \"gun.js\",\n  \"version\": \"0.1.5\",\n  \"homepage\": \"http://gunDB.io\",\n  \"authors\": [\n    { \"name\": \"Mark Nadal\",     \"email\": \"mark@accelsor.com\"    },\n    { \"name\": \"Alex LaFroscia\", \"email\": \"alex@lafroscia.com\"   }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/amark/gun\"\n  },\n  \"description\": \"A distributed, embedded, graph database engine.\",\n  \"moduleType\": [\n    \"globals\"\n  ],\n  \"keywords\": [\n    \"graph\",\n    \"database\",\n    \"gun\",\n    \"gundb\",\n    \"nodb\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ]\n}\n"
  },
  {
    "path": "browser.js",
    "content": "// if(!(typeof navigator == \"undefined\") && navigator.product == \"ReactNative\"){\r\n//     require(\"./lib/mobile.js\");\r\n// }\r\nmodule.exports = require('./gun.js');\r\n"
  },
  {
    "path": "examples/.gitignore",
    "content": "node_modules/*\r\nnpm-debug.log\r\n*data.json\r\n"
  },
  {
    "path": "examples/Main.js",
    "content": "import { render } from './iris/js/lib/preact.js';\nimport { Router, route } from './iris/js/lib/preact-router.es.js';\nimport { createHashHistory } from './iris/js/lib/history.production.min.js';\nimport { Component } from './iris/js/lib/preact.js';\nimport { Link } from './iris/js/lib/preact.match.js';\n\nimport Helpers from './iris/js/Helpers.js';\nimport { html } from './iris/js/Helpers.js';\nimport QRScanner from './iris/js/QRScanner.js';\nimport PeerManager from './iris/js/PeerManager.js';\nimport Session from './iris/js/Session.js';\nimport { translate as t } from './iris/js/Translation.js';\n\nimport Settings from './iris/js/views/Settings.js';\nimport LogoutConfirmation from './iris/js/views/LogoutConfirmation.js';\nimport Chat from './iris/js/views/Chat.js';\nimport Store from './iris/js/views/Store.js';\nimport Checkout from './iris/js/views/Checkout.js';\nimport Product from './iris/js/views/Product.js';\nimport Login from './iris/js/views/Login.js';\nimport Profile from './iris/js/views/Profile.js';\nimport Group from './iris/js/views/Group.js';\nimport Message from './iris/js/views/Message.js';\nimport Follows from './iris/js/views/Follows.js';\nimport Feed from './iris/js/views/Feed.js';\nimport About from './iris/js/views/About.js';\nimport Explorer from './iris/js/views/Explorer.js';\nimport Contacts from './iris/js/views/Contacts.js';\nimport Torrent from './iris/js/views/Torrent.js';\n\nimport VideoCall from './iris/js/components/VideoCall.js';\nimport Identicon from './iris/js/components/Identicon.js';\nimport MediaPlayer from './iris/js/components/MediaPlayer.js';\nimport Footer from './iris/js/components/Footer.js';\nimport State from './iris/js/State.js';\nimport Icons from './iris/js/Icons.js';\n\nconst userAgent = navigator.userAgent.toLowerCase();\nconst isElectron = (userAgent.indexOf(' electron/') > -1);\nif (!isElectron && ('serviceWorker' in navigator)) {\n  window.addEventListener('load', function() {\n    navigator.serviceWorker.register('iris/serviceworker.js')\n    .catch(function(err) {\n      // registration failed :(\n      console.log('ServiceWorker registration failed: ', err);\n    });\n  });\n}\n\nState.init();\nSession.init({autologin: true});\nPeerManager.init();\n\nHelpers.checkColorScheme();\n\nconst APPLICATIONS = [ // TODO: move editable shortcuts to State.local gun\n  {url: '/', text: t('home'), icon: Icons.home},\n  {url: '/feed', text: t('feed'), icon: Icons.feed},\n  {url: '/media', text: t('media'), icon: Icons.play},\n  {url: '/settings', text: t('settings'), icon: Icons.settings},\n  {url: '/store', text: t('store'), icon: Icons.store},\n  {url: '/explorer', text: t('explorer'), icon: Icons.folder},\n  {url: '/chat', text: t('messages'), icon: Icons.chat},\n  // {url: '/store', text: t('store'), icon: Icons.store}, // restore when it works!\n  {},\n  {url: '../stats.html', text: 'Gun node stats'},\n  {url: '../iris/index.html', text: 'Iris', icon: html`<img src=\"iris/img/icon128.png\" width=24/>`},\n  {url: '../infinite-scroll/index.html', text: 'Infinite scroll'},\n  {url: '../chat/index.html', text: 'Chat'},\n  {url: '../game/space.html', text: 'Space'},\n  {},\n  {url: 'https://gun.eco/docs/', text: 'Gun documentation'},\n  {url: 'https://examples.iris.to/components/', text: 'Iris web components'}\n];\n\nconst HomeView = () => {\n  return html`\n  <div class=\"main-view\">\n    <div class=\"centered-container public-messages-view\">\n      <h1>Hello, world!</h1>\n      <p>Here you can find sample applications and utilities for <a href=\"https://github.com/amark/gun\">GUN</a>.</p>\n      <p>If you need any help, please feel free to join the GUN community chat: <a href=\"http://chat.gun.eco\">http://chat.gun.eco</a></p>\n      <a href=\"/explorer\" class=\"msg\"><div class=\"msg-content\">\n        <b>Explorer</b>\n        <p>Explore the data saved on the GUN database. Open to the side while using an application and see the data change in real-time.</p>\n      </div></a>\n      <a class=\"msg\" href=\"game/space.html\"><div class=\"msg-content\">\n        <div class=\"img-container\"><img src=\"iris/img/space-game.jpg\"/></div>\n        <b>Space</b>\n        <p>Spaceflight game. Open in 2 or more browser windows.</p>\n      </div></a>\n      <a class=\"msg\" href=\"/iris/index.html\"><div class=\"msg-content\">\n        <div class=\"img-container\"><img src=\"iris/img/screenshot.png\"/></div>\n        <b>Iris</b>\n        <p>Decentralized Twitter/Instagram. Provides modular components that can be reused in other applications (including this one).</p>\n      </div></a>\n      <a native class=\"msg\" href=\"/chat/index.html\"><div class=\"msg-content\">\n        <div class=\"img-container\"><img src=\"iris/img/gun-chat.jpg\"/></div>\n        <b>Chat</b>\n        <p>Shoutbox!</p>\n      </div></a>\n    </div>\n  </div>\n  `;\n};\n\nclass MenuView extends Component {\n  componentDidMount() {\n    State.local.get('showMenu').on(showMenu => this.setState({showMenu}));\n  }\n\n  render() {\n    const pub = Session.getPubKey();\n    return html`\n      <div class=\"application-list ${this.state.showMenu ? 'menu-visible-xs' : ''}\">\n        <a href=\"/profile/${pub}\">\n          <span class=\"icon\"><${Identicon} str=${pub} width=40/></span>\n          <span class=\"text\" style=\"font-size: 1.2em;border:0;margin-left: 7px;\"><iris-text user=\"${pub}\" path=\"profile/name\" editable=\"false\"/></span>\n        </a>\n        <br/><br/>\n        ${APPLICATIONS.map(a => {\n          if (a.url) {\n            return html`\n              <a href=${a.url}>\n                <span class=\"icon\">${a.icon || Icons.circle}</span>\n                <span class=\"text\">${a.text}</span>\n              </a>`;\n          } else {\n            return html`<br/><br/>`;\n          }\n        })}\n      </div>\n    `;\n  }\n};\n\nclass Main extends Component {\n  constructor() {\n    super();\n    this.showMenu = false;\n  }\n\n  componentDidMount() {\n    State.local.get('loggedIn').on(loggedIn => this.setState({loggedIn}));\n  }\n\n  handleRoute(e) {\n    let activeRoute = e.url;\n    if (!activeRoute && window.location.hash) {\n      return route(window.location.hash.replace('#', '')); // bubblegum fix back navigation\n    }\n    document.title = 'Iris';\n    if (activeRoute && activeRoute.length > 1) { document.title += ' - ' + Helpers.capitalize(activeRoute.replace('/', '')); }\n    State.local.get('activeRoute').put(activeRoute);\n    QRScanner.cleanupScanner();\n  }\n\n  onClickOverlay() {\n    if (this.state.showMenu) {\n      this.setState({showMenu: false});\n    }\n  }\n\n  toggleMenu(show) {\n    this.setState({showMenu: typeof show === 'undefined' ? !this.state.showMenu : show});\n  }\n\n  render() {\n    const content = this.state.loggedIn ? html`\n      <div class=\"visible-xs-flex\" style=\"border-bottom:var(--sidebar-border-right)\">\n        <svg onClick=${() => State.local.get('showMenu').put(this.showMenu = !this.showMenu)} style=\"padding: 5px;cursor:pointer;\" viewBox=\"0 -53 384 384\" width=\"40px\"><path d=\"m368 154.667969h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0\"/><path d=\"m368 32h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0\"/><path d=\"m368 277.332031h-352c-8.832031 0-16-7.167969-16-16s7.167969-16 16-16h352c8.832031 0 16 7.167969 16 16s-7.167969 16-16 16zm0 0\"/></svg>\n      </div>\n      <section class=\"main\" style=\"flex-direction: row;\">\n        <${MenuView}/>\n        <div style=\"flex: 3; display: flex\">\n          <${Router} history=${createHashHistory()} onChange=${e => this.handleRoute(e)}>\n            <${HomeView} path=\"/\"/>\n            <${Feed} path=\"/feed\"/>\n            <${Feed} path=\"/search/:term?/:type?\"/>\n            <${Feed} path=\"/media\" index=\"media\"/>\n            <${Login} path=\"/login\"/>\n            <${Chat} path=\"/chat/:id?\"/>\n            <${Message} path=\"/post/:hash\"/>\n            <${Torrent} path=\"/torrent/:id\"/>\n            <${About} path=\"/about\"/>\n            <${Settings} path=\"/settings\"/>\n            <${LogoutConfirmation} path=\"/logout\"/>\n            <${Profile} path=\"/profile/:id?\" tab=\"profile\"/>\n            <${Profile} path=\"/replies/:id?\" tab=\"replies\"/>\n            <${Profile} path=\"/likes/:id?\" tab=\"likes\"/>\n            <${Profile} path=\"/media/:id\" tab=\"media\"/>\n            <${Group} path=\"/group/:id?\"/>\n            <${Store} path=\"/store/:store?\"/>\n            <${Checkout} path=\"/checkout/:store?\"/>\n            <${Product} path=\"/product/:product/:store\"/>\n            <${Product} path=\"/product/new\" store=Session.getPubKey()/>\n            <${Explorer} path=\"/explorer/:node\"/>\n            <${Explorer} path=\"/explorer\"/>\n            <${Follows} path=\"/follows/:id\"/>\n            <${Follows} followers=${true} path=\"/followers/:id\"/>\n            <${Contacts} path=\"/contacts\"/>\n          </${Router}>\n        </div>\n      </section>\n      <${VideoCall}/>\n    ` : '';\n    return html`\n      <div id=\"main-content\">\n        ${content}\n      </div>\n    `;\n  }\n}\n\nrender(html`<${Main}/>`, document.body);\n\n$('body').css('opacity', 1); // use opacity because setting focus on display: none elements fails\n"
  },
  {
    "path": "examples/angular/.angular-cli.json",
    "content": "{\n  \"$schema\": \"./node_modules/@angular/cli/lib/config/schema.json\",\n  \"project\": {\n    \"name\": \"angular\"\n  },\n  \"apps\": [\n    {\n      \"root\": \"src\",\n      \"outDir\": \"dist\",\n      \"assets\": [\n        \"assets\",\n        \"favicon.ico\"\n      ],\n      \"index\": \"index.html\",\n      \"main\": \"main.ts\",\n      \"polyfills\": \"polyfills.ts\",\n      \"test\": \"test.ts\",\n      \"tsconfig\": \"tsconfig.app.json\",\n      \"testTsconfig\": \"tsconfig.spec.json\",\n      \"prefix\": \"app\",\n      \"styles\": [\n        \"styles.css\"\n      ],\n      \"scripts\": [],\n      \"environmentSource\": \"environments/environment.ts\",\n      \"environments\": {\n        \"dev\": \"environments/environment.ts\",\n        \"prod\": \"environments/environment.prod.ts\"\n      }\n    }\n  ],\n  \"e2e\": {\n    \"protractor\": {\n      \"config\": \"./protractor.conf.js\"\n    }\n  },\n  \"lint\": [\n    {\n      \"project\": \"src/tsconfig.app.json\",\n      \"exclude\": \"**/node_modules/**\"\n    },\n    {\n      \"project\": \"src/tsconfig.spec.json\"\n    },\n    {\n      \"project\": \"e2e/tsconfig.e2e.json\"\n    }\n  ],\n  \"test\": {\n    \"karma\": {\n      \"config\": \"./karma.conf.js\"\n    }\n  },\n  \"defaults\": {\n    \"styleExt\": \"css\",\n    \"component\": {}\n  }\n}\n"
  },
  {
    "path": "examples/angular/.editorconfig",
    "content": "# Editor configuration, see http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.md]\nmax_line_length = off\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": "examples/angular/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# compiled output\n/dist\n/tmp\n/out-tsc\n\n# dependencies\n/node_modules\n\n# IDEs and editors\n/.idea\n.project\n.classpath\n.c9/\n*.launch\n.settings/\n*.sublime-workspace\n\n# IDE - VSCode\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n\n# misc\n/.sass-cache\n/connect.lock\n/coverage\n/libpeerconnection.log\nnpm-debug.log\ntestem.log\n/typings\n\n# e2e\n/e2e/*.js\n/e2e/*.map\n\n# System Files\n.DS_Store\nThumbs.db\n"
  },
  {
    "path": "examples/angular/README.md",
    "content": "# Angular\n\nThis project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0.\n\n## Development server\n\nRun `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.\n\n## Code scaffolding\n\nRun `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.\n\n## Build\n\nRun `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.\n\n## Running unit tests\n\nRun `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).\n\n## Running end-to-end tests\n\nRun `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).\nBefore running the tests make sure you are serving the app via `ng serve`.\n\n## Further help\n\nTo get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).\n"
  },
  {
    "path": "examples/angular/e2e/app.e2e-spec.ts",
    "content": "import { AngularPage } from './app.po';\n\ndescribe('angular App', () => {\n  let page: AngularPage;\n\n  beforeEach(() => {\n    page = new AngularPage();\n  });\n\n  it('should display message saying app works', () => {\n    page.navigateTo();\n    expect(page.getParagraphText()).toEqual('app works!');\n  });\n});\n"
  },
  {
    "path": "examples/angular/e2e/app.po.ts",
    "content": "import { browser, element, by } from 'protractor';\n\nexport class AngularPage {\n  navigateTo() {\n    return browser.get('/');\n  }\n\n  getParagraphText() {\n    return element(by.css('app-root h1')).getText();\n  }\n}\n"
  },
  {
    "path": "examples/angular/e2e/tsconfig.e2e.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../out-tsc/e2e\",\n    \"module\": \"commonjs\",\n    \"target\": \"es5\",\n    \"types\":[\n      \"jasmine\",\n      \"node\"\n    ]\n  }\n}\n"
  },
  {
    "path": "examples/angular/example_package.json",
    "content": "{\n  \"name\": \"angular\",\n  \"version\": \"0.0.0\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"ng\": \"ng\",\n    \"start\": \"ng serve\",\n    \"build\": \"ng build\",\n    \"test\": \"ng test\",\n    \"lint\": \"ng lint\",\n    \"e2e\": \"ng e2e\"\n  },\n  \"private\": true,\n  \"dependencies\": {\n    \"@angular/common\": \"^4.1.0\",\n    \"@angular/compiler\": \"^4.1.0\",\n    \"@angular/core\": \"^4.1.0\",\n    \"@angular/forms\": \"^4.1.0\",\n    \"@angular/http\": \"^4.1.0\",\n    \"@angular/platform-browser\": \"^4.1.0\",\n    \"@angular/platform-browser-dynamic\": \"^4.1.0\",\n    \"@angular/router\": \"^4.1.0\",\n    \"core-js\": \"^2.4.1\",\n    \"express-http-proxy\": \"^1.0.1\",\n    \"gun\": \"https://github.com/amark/gun.git#master\",\n    \"ngx-pipes\": \"^2.0.5\",\n    \"rxjs\": \"^5.3.0\",\n    \"underscore\": \"^1.8.3\",\n    \"zone.js\": \"^0.8.9\"\n  },\n  \"devDependencies\": {\n    \"@angular/cli\": \"1.0.0\",\n    \"@angular/compiler-cli\": \"^4.1.0\",\n    \"@types/jasmine\": \"2.5.38\",\n    \"@types/node\": \"~6.0.60\",\n    \"@types/underscore\": \"^1.8.0\",\n    \"codelyzer\": \"^2.1.1\",\n    \"jasmine-core\": \"^2.6.1\",\n    \"jasmine-spec-reporter\": \"^4.0.0\",\n    \"karma\": \"^1.6.0\",\n    \"karma-chrome-launcher\": \"~2.0.0\",\n    \"karma-cli\": \"~1.0.1\",\n    \"karma-coverage-istanbul-reporter\": \"^1.2.0\",\n    \"karma-jasmine\": \"~1.1.0\",\n    \"karma-jasmine-html-reporter\": \"^0.2.2\",\n    \"protractor\": \"~5.1.0\",\n    \"ts-node\": \"^3.0.2\",\n    \"tslint\": \"~4.5.0\",\n    \"typescript\": \"^2.3.2\"\n  }\n}\n"
  },
  {
    "path": "examples/angular/karma.conf.js",
    "content": "// Karma configuration file, see link for more information\n// https://karma-runner.github.io/0.13/config/configuration-file.html\n\nmodule.exports = function (config) {\n  config.set({\n    basePath: '',\n    frameworks: ['jasmine', '@angular/cli'],\n    plugins: [\n      require('karma-jasmine'),\n      require('karma-chrome-launcher'),\n      require('karma-jasmine-html-reporter'),\n      require('karma-coverage-istanbul-reporter'),\n      require('@angular/cli/plugins/karma')\n    ],\n    client:{\n      clearContext: false // leave Jasmine Spec Runner output visible in browser\n    },\n    files: [\n      { pattern: './src/test.ts', watched: false }\n    ],\n    preprocessors: {\n      './src/test.ts': ['@angular/cli']\n    },\n    mime: {\n      'text/x-typescript': ['ts','tsx']\n    },\n    coverageIstanbulReporter: {\n      reports: [ 'html', 'lcovonly' ],\n      fixWebpackSourcePaths: true\n    },\n    angularCli: {\n      environment: 'dev'\n    },\n    reporters: config.angularCli && config.angularCli.codeCoverage\n              ? ['progress', 'coverage-istanbul']\n              : ['progress', 'kjhtml'],\n    port: 9876,\n    colors: true,\n    logLevel: config.LOG_INFO,\n    autoWatch: true,\n    browsers: ['Chrome'],\n    singleRun: false\n  });\n};\n"
  },
  {
    "path": "examples/angular/protractor.conf.js",
    "content": "// Protractor configuration file, see link for more information\n// https://github.com/angular/protractor/blob/master/lib/config.ts\n\nconst { SpecReporter } = require('jasmine-spec-reporter');\n\nexports.config = {\n  allScriptsTimeout: 11000,\n  specs: [\n    './e2e/**/*.e2e-spec.ts'\n  ],\n  capabilities: {\n    'browserName': 'chrome'\n  },\n  directConnect: true,\n  baseUrl: 'http://localhost:4200/',\n  framework: 'jasmine',\n  jasmineNodeOpts: {\n    showColors: true,\n    defaultTimeoutInterval: 30000,\n    print: function() {}\n  },\n  beforeLaunch: function() {\n    require('ts-node').register({\n      project: 'e2e/tsconfig.e2e.json'\n    });\n  },\n  onPrepare() {\n    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));\n  }\n};\n"
  },
  {
    "path": "examples/angular/server.js",
    "content": "var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8765;\nvar host = process.env.OPENSHIFT_NODEJS_HOST || process.env.VCAP_APP_HOST || process.env.HOST || 'localhost';\n\nvar express = require('express');\nvar proxy = require('express-http-proxy');\nvar http = require('http');\nvar app = express();\nvar server = http.createServer(app);\n\nvar Gun = require('gun');\nvar gun = Gun({\n\tfile: 'data.json',\n\tweb: server\n});\n\napp.use(Gun.serve);\napp.use(proxy(host + ':4200'));\nserver.listen(port);\n\nconsole.log('Server started on port ' + port + ' with /gun');\n"
  },
  {
    "path": "examples/angular/src/app/app.component.css",
    "content": "html, body { font-size: 14pt; padding: 10px 2.5%;}\n.hide { display: none; }\nform .who { width: 10%; }\nform .what { width: 80%; }\nul { list-style: none; padding: 0; }\nul .when {color: #555; font-size: 12pt; float: right; display: none; }\nli:hover .when {display: inline;}\n"
  },
  {
    "path": "examples/angular/src/app/app.component.html",
    "content": "<div>\n\n  <form (ngSubmit)=\"add()\">\n    <input type=\"text\" [(ngModel)]=\"newTodo\" name=\"newTodo\" placeholder=\"New TODO\">\n    <button type=\"submit\" *ngIf=\"newTodo\" [disabled]=\"newTodo?.trim().length === 0\">Add</button>\n  </form>\n  <br />\n  <ul>\n    <li *ngFor=\"let todo of todos$ | async | pairs\" (click)=\"delete(todo[0])\">{{todo[1]}}</li>\n  </ul>\n  <button (click)=\"sub()\" *ngIf=\"!todosSub\">Log in console</button>\n  <button (click)=\"unsub()\" *ngIf=\"!!todosSub\">Stop logging</button>\n</div>\n"
  },
  {
    "path": "examples/angular/src/app/app.component.spec.ts",
    "content": "import { TestBed, async } from '@angular/core/testing';\n\nimport { AppComponent } from './app.component';\n\ndescribe('AppComponent', () => {\n  beforeEach(async(() => {\n    TestBed.configureTestingModule({\n      declarations: [\n        AppComponent\n      ],\n    }).compileComponents();\n  }));\n\n  it('should create the app', async(() => {\n    const fixture = TestBed.createComponent(AppComponent);\n    const app = fixture.debugElement.componentInstance;\n    expect(app).toBeTruthy();\n  }));\n\n  it(`should have as title 'app works!'`, async(() => {\n    const fixture = TestBed.createComponent(AppComponent);\n    const app = fixture.debugElement.componentInstance;\n    expect(app.title).toEqual('app works!');\n  }));\n\n  it('should render title in a h1 tag', async(() => {\n    const fixture = TestBed.createComponent(AppComponent);\n    fixture.detectChanges();\n    const compiled = fixture.debugElement.nativeElement;\n    expect(compiled.querySelector('h1').textContent).toContain('app works!');\n  }));\n});\n"
  },
  {
    "path": "examples/angular/src/app/app.component.ts",
    "content": "import { Component, OnInit } from '@angular/core';\nimport { Observable } from 'rxjs/Observable';\nimport { Subscription } from 'rxjs/Subscription';\nimport Gun from 'gun/gun';\n\nimport { GunDb } from 'app/gun.service';\nimport { on$ } from 'app/gun.helper';\n\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html',\n  styleUrls: ['./app.component.css']\n})\nexport class AppComponent implements OnInit {\n  newTodo = '';\n\n  todos = this.db.gun.get('todos');\n  todos$: Observable<string[]> = on$(this.todos);\n\n  todosSub: Subscription;\n\n  constructor(private db: GunDb) { }\n\n  ngOnInit() { }\n\n  add() {\n    if (this.newTodo) {\n      this.todos.get(Gun.text.random()).put(this.newTodo);\n      this.newTodo = '';\n    }\n  }\n\n  delete(key: string) {\n    this.todos.get(key).put(null);\n  }\n\n  sub() {\n    this.todosSub = this.todos$.subscribe(v => console.log(v));\n  }\n\n  unsub() {\n    this.todosSub.unsubscribe();\n  }\n}\n"
  },
  {
    "path": "examples/angular/src/app/app.module.ts",
    "content": "import { BrowserModule } from '@angular/platform-browser';\nimport { NgModule, Injectable } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { HttpModule } from '@angular/http';\nimport { Observable } from 'rxjs/Observable';\nimport { NgPipesModule } from 'ngx-pipes';\n\nimport { AppComponent } from './app.component';\nimport { GunDb } from 'app/gun.service';\n\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    BrowserModule,\n    FormsModule,\n    HttpModule,\n    NgPipesModule\n  ],\n  providers: [GunDb],\n  bootstrap: [AppComponent]\n})\nexport class AppModule { }\n"
  },
  {
    "path": "examples/angular/src/app/gun.helper.ts",
    "content": "import { Observable } from 'rxjs/Observable';\nimport { Gun } from 'gun/gun';\nimport { pick } from 'underscore';\n\nexport function on$(node, cleanup = true): Observable<any> {\n    return Observable.fromEventPattern(\n        h => {\n            // there is no way to off() an on() until at least one value is triggered\n            // so that we can access the event listener to off() it\n            const signal = { stop: false };\n            node.on((data, key, at, ev) => {\n                if (signal.stop) {\n                    ev.off();\n                } else {\n                    // modifying data directly does not seem to work...\n                    h(cleanup ? pick(data, (v, k, o) => v !== null && k !== '_') : data);\n                }\n            });\n            return signal;\n        },\n        (h, signal) => { signal.stop = true; }\n    );\n}\n\nexport function val$(node): Observable<any> {\n    return new Observable(o => node.val(v => {\n        o.next(v);\n        o.complete();\n    }));\n}\n"
  },
  {
    "path": "examples/angular/src/app/gun.service.ts",
    "content": "import { NgModule, Injectable } from '@angular/core';\nimport Gun from 'gun/gun';\n\n@Injectable()\nexport class GunDb {\n    readonly gun = Gun(location.origin + '/gun');\n}\n"
  },
  {
    "path": "examples/angular/src/assets/.gitkeep",
    "content": ""
  },
  {
    "path": "examples/angular/src/environments/environment.prod.ts",
    "content": "export const environment = {\n  production: true\n};\n"
  },
  {
    "path": "examples/angular/src/environments/environment.ts",
    "content": "// The file contents for the current environment will overwrite these during build.\n// The build system defaults to the dev environment which uses `environment.ts`, but if you do\n// `ng build --env=prod` then `environment.prod.ts` will be used instead.\n// The list of which env maps to which file can be found in `.angular-cli.json`.\n\nexport const environment = {\n  production: false\n};\n"
  },
  {
    "path": "examples/angular/src/index.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n  <title>Angular</title>\n  <base href=\"/\">\n\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <link rel=\"icon\" type=\"image/x-icon\" href=\"favicon.ico\">\n</head>\n<body>\n  <app-root>Loading...</app-root>\n</body>\n</html>\n"
  },
  {
    "path": "examples/angular/src/main.ts",
    "content": "import { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nimport 'rxjs/add/operator/startWith';\nimport 'rxjs/add/operator/map';\n\nimport 'rxjs/add/observable/fromEventPattern';\n\nif (environment.production) {\n  enableProdMode();\n}\n\nplatformBrowserDynamic().bootstrapModule(AppModule);\n"
  },
  {
    "path": "examples/angular/src/polyfills.ts",
    "content": "/**\n * This file includes polyfills needed by Angular and is loaded before the app.\n * You can add your own extra polyfills to this file.\n *\n * This file is divided into 2 sections:\n *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.\n *   2. Application imports. Files imported after ZoneJS that should be loaded before your main\n *      file.\n *\n * The current setup is for so-called \"evergreen\" browsers; the last versions of browsers that\n * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),\n * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.\n *\n * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html\n */\n\n/***************************************************************************************************\n * BROWSER POLYFILLS\n */\n\n/** IE9, IE10 and IE11 requires all of the following polyfills. **/\n// import 'core-js/es6/symbol';\n// import 'core-js/es6/object';\n// import 'core-js/es6/function';\n// import 'core-js/es6/parse-int';\n// import 'core-js/es6/parse-float';\n// import 'core-js/es6/number';\n// import 'core-js/es6/math';\n// import 'core-js/es6/string';\n// import 'core-js/es6/date';\n// import 'core-js/es6/array';\n// import 'core-js/es6/regexp';\n// import 'core-js/es6/map';\n// import 'core-js/es6/set';\n\n/** IE10 and IE11 requires the following for NgClass support on SVG elements */\n// import 'classlist.js';  // Run `npm install --save classlist.js`.\n\n/** IE10 and IE11 requires the following to support `@angular/animation`. */\n// import 'web-animations-js';  // Run `npm install --save web-animations-js`.\n\n\n/** Evergreen browsers require these. **/\nimport 'core-js/es6/reflect';\nimport 'core-js/es7/reflect';\n\n\n/** ALL Firefox browsers require the following to support `@angular/animation`. **/\n// import 'web-animations-js';  // Run `npm install --save web-animations-js`.\n\n\n\n/***************************************************************************************************\n * Zone JS is required by Angular itself.\n */\nimport 'zone.js/dist/zone';  // Included with Angular CLI.\n\n\n\n/***************************************************************************************************\n * APPLICATION IMPORTS\n */\n\n/**\n * Date, currency, decimal and percent pipes.\n * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10\n */\n// import 'intl';  // Run `npm install --save intl`.\n"
  },
  {
    "path": "examples/angular/src/styles.css",
    "content": "/* You can add global styles to this file, and also import other style files */\n"
  },
  {
    "path": "examples/angular/src/test.ts",
    "content": "// This file is required by karma.conf.js and loads recursively all the .spec and framework files\n\nimport 'zone.js/dist/long-stack-trace-zone';\nimport 'zone.js/dist/proxy.js';\nimport 'zone.js/dist/sync-test';\nimport 'zone.js/dist/jasmine-patch';\nimport 'zone.js/dist/async-test';\nimport 'zone.js/dist/fake-async-test';\nimport { getTestBed } from '@angular/core/testing';\nimport {\n  BrowserDynamicTestingModule,\n  platformBrowserDynamicTesting\n} from '@angular/platform-browser-dynamic/testing';\n\n// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.\ndeclare var __karma__: any;\ndeclare var require: any;\n\n// Prevent Karma from running prematurely.\n__karma__.loaded = function () {};\n\n// First, initialize the Angular testing environment.\ngetTestBed().initTestEnvironment(\n  BrowserDynamicTestingModule,\n  platformBrowserDynamicTesting()\n);\n// Then we find all the tests.\nconst context = require.context('./', true, /\\.spec\\.ts$/);\n// And load the modules.\ncontext.keys().map(context);\n// Finally, start Karma to run the tests.\n__karma__.start();\n"
  },
  {
    "path": "examples/angular/src/tsconfig.app.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../out-tsc/app\",\n    \"module\": \"es2015\",\n    \"baseUrl\": \"\",\n    \"types\": []\n  },\n  \"exclude\": [\n    \"test.ts\",\n    \"**/*.spec.ts\"\n  ]\n}\n"
  },
  {
    "path": "examples/angular/src/tsconfig.spec.json",
    "content": "{\n  \"extends\": \"../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../out-tsc/spec\",\n    \"module\": \"commonjs\",\n    \"target\": \"es5\",\n    \"baseUrl\": \"\",\n    \"types\": [\n      \"jasmine\",\n      \"node\"\n    ]\n  },\n  \"files\": [\n    \"test.ts\"\n  ],\n  \"include\": [\n    \"**/*.spec.ts\",\n    \"**/*.d.ts\"\n  ]\n}\n"
  },
  {
    "path": "examples/angular/src/typings.d.ts",
    "content": "/* SystemJS module definition */\ndeclare var module: NodeModule;\ninterface NodeModule {\n  id: string;\n}\n"
  },
  {
    "path": "examples/angular/tsconfig.json",
    "content": "{\n  \"compileOnSave\": false,\n  \"compilerOptions\": {\n    \"outDir\": \"./dist/out-tsc\",\n    \"baseUrl\": \"src\",\n    \"sourceMap\": true,\n    \"declaration\": false,\n    \"moduleResolution\": \"node\",\n    \"emitDecoratorMetadata\": true,\n    \"experimentalDecorators\": true,\n    \"target\": \"es5\",\n    \"typeRoots\": [\n      \"node_modules/@types\"\n    ],\n    \"lib\": [\n      \"es2016\",\n      \"dom\"\n    ]\n  }\n}\n"
  },
  {
    "path": "examples/angular/tslint.json",
    "content": "{\n  \"rulesDirectory\": [\n    \"node_modules/codelyzer\"\n  ],\n  \"rules\": {\n    \"callable-types\": true,\n    \"class-name\": true,\n    \"comment-format\": [\n      true,\n      \"check-space\"\n    ],\n    \"curly\": true,\n    \"eofline\": true,\n    \"forin\": true,\n    \"import-blacklist\": [true, \"rxjs\"],\n    \"import-spacing\": true,\n    \"indent\": [\n      true,\n      \"spaces\"\n    ],\n    \"interface-over-type-literal\": true,\n    \"label-position\": true,\n    \"max-line-length\": [\n      true,\n      140\n    ],\n    \"member-access\": false,\n    \"member-ordering\": [\n      true,\n      \"static-before-instance\",\n      \"variables-before-functions\"\n    ],\n    \"no-arg\": true,\n    \"no-bitwise\": true,\n    \"no-console\": [\n      true,\n      \"debug\",\n      \"info\",\n      \"time\",\n      \"timeEnd\",\n      \"trace\"\n    ],\n    \"no-construct\": true,\n    \"no-debugger\": true,\n    \"no-duplicate-variable\": true,\n    \"no-empty\": false,\n    \"no-empty-interface\": true,\n    \"no-eval\": true,\n    \"no-inferrable-types\": [true, \"ignore-params\"],\n    \"no-shadowed-variable\": true,\n    \"no-string-literal\": false,\n    \"no-string-throw\": true,\n    \"no-switch-case-fall-through\": true,\n    \"no-trailing-whitespace\": true,\n    \"no-unused-expression\": true,\n    \"no-use-before-declare\": true,\n    \"no-var-keyword\": true,\n    \"object-literal-sort-keys\": false,\n    \"one-line\": [\n      true,\n      \"check-open-brace\",\n      \"check-catch\",\n      \"check-else\",\n      \"check-whitespace\"\n    ],\n    \"prefer-const\": true,\n    \"quotemark\": [\n      true,\n      \"single\"\n    ],\n    \"radix\": true,\n    \"semicolon\": [\n      \"always\"\n    ],\n    \"triple-equals\": [\n      true,\n      \"allow-null-check\"\n    ],\n    \"typedef-whitespace\": [\n      true,\n      {\n        \"call-signature\": \"nospace\",\n        \"index-signature\": \"nospace\",\n        \"parameter\": \"nospace\",\n        \"property-declaration\": \"nospace\",\n        \"variable-declaration\": \"nospace\"\n      }\n    ],\n    \"typeof-compare\": true,\n    \"unified-signatures\": true,\n    \"variable-name\": false,\n    \"whitespace\": [\n      true,\n      \"check-branch\",\n      \"check-decl\",\n      \"check-operator\",\n      \"check-separator\",\n      \"check-type\"\n    ],\n\n    \"directive-selector\": [true, \"attribute\", \"app\", \"camelCase\"],\n    \"component-selector\": [true, \"element\", \"app\", \"kebab-case\"],\n    \"use-input-property-decorator\": true,\n    \"use-output-property-decorator\": true,\n    \"use-host-property-decorator\": true,\n    \"no-input-rename\": true,\n    \"no-output-rename\": true,\n    \"use-life-cycle-interface\": true,\n    \"use-pipe-transform-interface\": true,\n    \"component-class-suffix\": true,\n    \"directive-class-suffix\": true,\n    \"no-access-missing-member\": true,\n    \"templates-use-public\": true,\n    \"invoke-injectable\": true\n  }\n}\n"
  },
  {
    "path": "examples/axe.html",
    "content": "<!DOCTYPE HTML>\n<html>\n\n<head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1.0\" />\n  <title>Testing AXE</title>\n</head>\n\n<body>\n<h3 id=\"pid\"></h3>\n  <script src=\"../gun.js\"></script>\n  <script src=\"../axe.js\"></script>\n  <script src=\"../lib/radix.js\"></script>\n  <script src=\"../lib/webrtc.js\"></script>\n  <!-- <script src=\"../sea.js\"></script> -->\n  <script>\n  var pid = location.hash.slice(1);\n\n  var opt = ({\n    peers: [`${location.origin}/gun`]\n  });\n\n  if (pid) { opt.pid = pid; }\n\n  Gun.on('opt', function(ctx) {\n    this.to.next(ctx);\n    ctx.on('hi', function(opt) {\n//       console.log('HI!! PEER', new Date(), opt.pid);\n        setTimeout(function() {\n            document.getElementById('pid').innerHTML = gun._.opt.pid;\n        });\n    });\n//     if (pid) {\n//     ctx.on('out', function(msg) {\n//       msg.pid = pid;\n//       this.to.next(msg);\n//     });\n//     }\n  });\n\n  var gun = Gun(opt);\n  //var user = gun.user();\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/basic/chat.html",
    "content": "<!DOCTYPE html>\n<ul id='list'></ul>\n<form id='form'>\n  <input id='who' placeholder='name'>\n  <input id='what' placeholder='say'>\n  <input type='submit' value='send'>\n</form>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/axe.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/emojione@4.0.0/lib/js/emojione.min.js\"></script>\n<script>\ngun = GUN(), chat = gun.get(\"note\" + location.hash.replace('#','/')), view = document;\nform.onsubmit = (eve) => { chat.set(who.value+': '+what.value), eve.preventDefault(what.value = \"\") }\nchat.map().on(function show(data, id){\n  (view.line = view.getElementById(id) || view.createElement(\"li\")).id = id;\n  list.appendChild(view.line).innerText = emojione.shortnameToUnicode(data);\n  window.scroll(0, list.offsetHeight);\n  (list.beep = new SpeechSynthesisUtterance()).text = \"new\";\n  list.beep.rate = 10, list.beep.pitch = 2, window.speechSynthesis.speak(list.beep);\n});\n</script>"
  },
  {
    "path": "examples/basic/emoji.html",
    "content": "<!DOCTYPE html>\n<p>Moved to <a href=\"./chat.html\">./chat.html</a>!</p>"
  },
  {
    "path": "examples/basic/meet.html",
    "content": "<!DOCTYPE html>\n\n<center>must press play or unmute on new videos to accept meeting</center>\n<center id=\"videos\">\n<video id=\"me\" width=\"100%\" controls autoplay playsinline muted></video>\n</center>\n<center>Stream <select id=\"select\"><option id=\"from\">from</option></select></center>\n\n<script src=\"../jquery.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/sea.js\"></script>\n<script src=\"../../../gun/lib/webrtc.js\"></script>\n\n<script>;(async function(){\nstreams = {}, gun = Gun(location.origin + '/gun'); //gun = GUN();\nmesh = gun.back('opt.mesh');\n\n(await (me.stream = navigator.mediaDevices).enumerateDevices()).forEach((device,i) => {\n  if('videoinput' !== device.kind){ return }\n  var opt = $(from).clone().prependTo('select').get(0);\n  $(opt).text(opt.id = device.label || 'Camera '+i);\n  opt.value = device.deviceId;\n});\n\n$('select').on('change', async eve => { $(from).text('Off'); // update label\n  if('Off' == select.value){ return me.srcObject.getTracks()[0].stop() }\n  mesh.hi(me.srcObject = await me.stream.getUserMedia({ audio: true,\n    video: (select.value && {deviceId: {exact: select.value}}) || {facingMode: \"environment\"}\n  }));\n});\n\ngun.on('rtc', async function(eve){ var ui, src;\n  console.log(\"?RTC?\", eve.peer && eve.peer.connectionState, eve);\n  if(!(src = eve.streams)){ return }\n  ui = $('#v'+(src=src[0]).id).get(0) || $(me).clone().attr('id', 'v'+src.id).prependTo('#videos').get(0); // reuse or create video element\n  ui.srcObject = src;\n});\n}());</script>"
  },
  {
    "path": "examples/basic/note.html",
    "content": "<!DOCTYPE html>\n<style>html, body, textarea { width: 100%; height: 100%; padding: 0; margin: 0; }</style>\n<textarea id=\"view\" placeholder=\"write here...\"></textarea>\n<script src=\"../../../gun/gun.js\"></script><script>\n\tgun = GUN(location.origin + '/gun');\n\tnote = gun.get('note').get(location.hash.replace('#','')||1);\n\tview.oninput = () => { note.put(view.value) };\n\tnote.on((data) => { view.value = data });\n</script>"
  },
  {
    "path": "examples/basic/paste.html",
    "content": "<!DOCTYPE html>\n<p>Moved to <a href=\"./note.html\">./note.html</a>!</p>"
  },
  {
    "path": "examples/basic/poll.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width\">\n\n\t<script src=\"../jquery.js\"></script>\n\t<script src=\"../../../gun/gun.js\"></script>\n\t<script src=\"../../../gun/sea.js\"></script>\n\t<!-- script src=\"../../../gun/axe.js\"></script -->\n\t<script> // main init!\n\tvar app = {\n\t\tview: $, // replace with not jquery!\n\t\tdata: GUN('http://localhost:8765/gun'), // peer-to-peer database!\n\t};\n\tapp.user = app.data.user().recall({sessionStorage: true});\n\t</script>\n\n</head>\n<body>\n\n<div id=\"login\" class=\"center pad\">\n\t<style>\n\t#login input {\n\t\tmax-width: 6em;\n\t}\n\t</style>\n\t<form id=\"sign\" onsubmit=\"app.login(event)\">\n\t  <input id=\"alias\" placeholder=\"username\" class=\"jot rim\">\n\t  <input id=\"pass\" type=\"password\" placeholder=\"passphrase\" class=\"jot rim\">\n\t  <input id=\"in\" type=\"submit\" value=\"sign in\" class=\"green whitet act gap sap rim\">\n\t  <input id=\"up\" type=\"button\" value=\"sign up\" onclick=\"app.register()\" class=\"act gap sap rim\">\n\t</form>\n\t<script>\n\tapp.login = function(eve){\n\t\tif(app.error(eve)){ return }\n\t  app.data.user().auth(\n\t  \tapp.view('#alias').val(),\n\t  \tapp.view('#pass').val(),\n\t  \tapp.error\n\t  );\n\t};\n\n\tapp.register = function(eve){\n\t  app.data.user().create(\n\t  \tapp.view('#alias').val(),\n\t  \tapp.view('#pass').val(),\n\t  \tapp.login\n\t  );\n\t};\n\n\tapp.data.on('auth', function(eve){\n\t  app.view('#sign').hide(); // hide login form upon logging in.\n\t});\n\t</script>\n</div>\n\n<div id=\"poll\" class=\"pad\">\n\t<style>\n\t#poll {\n\t\tdisplay: flex;\n\t\tflex-wrap: wrap;\n\t}\n\t#poll div {\n\t\tmargin: 1%;\n\t\twidth: 100%;\n\t}\n\t</style>\n\t<script>\n\t(window.onhashchange = async function(){\n\t\tapp.poll = app.data.get(location.hash.slice(1));\n\t\tapp.poll.map().on(function(data, id){\n\t\t\tapp.render(id = 'p'+String.hash(id), '.q', '#poll', data).css({order: data.how}).data('as',{$:this});\n\t\t\tconsole.log(\"poll?\", id, data);\n\t\t});\n\t})();\n\tapp.render = function(id, model, onto, data){\n\t\tvar ui = $(\n\t\t\t$('#'+id).get(0) ||\n\t\t\t$('.model').find(model).clone(true).attr('id', id).appendTo(onto)\n\t\t);\n\t\t$.each(data, function(field, val){\n\t\t\tif($.isPlainObject(val)){ return }\n\t\t\tui.find(\"[name='\" + field + \"']\").val(val).text(val);\n\t\t});\n\t\treturn ui;\n\t}\n\t</script>\n\t<div class=\"model\">\n\t\t<div class=\"q\">\n\t\t\t<span name=\"what\"></span>\n\t\t</div>\n\t</div>\n</div>\n\n<div id=\"make\" class=\"pad\">\n\t<style>\n\t#make #add {\n\t\tborder-radius: 100%;\n    width: 2em;\n    height: 2em;\n    line-height: 0em;\n    padding: 0;\n    margin: 0;\n    text-align: center;\n\t}\n\t</style>\n\t<button id=\"add\" onclick=\"app.add()\" class=\"green whitet act\">+</button>\n\t<span class=\"hint\">add new title, text, question...</span>\n\t<script>\n\tapp.add = async function(){\n\t\tif(app.error(app.user)){ return }\n\t\tvar tmp = await (app.poll = app.poll || app.data.get(location.hash.slice(1)));\n\t\tif(!tmp){ app.poll = app.user.get('poll').set({}) }\n\t\tapp.poll.set({how: tmp = Object.keys(tmp||'').length || 1, what: \"Question \" + tmp });\n\t\tif(!location.hash){ location.hash = (await app.poll)._['#'] }\n\t}\n</script>\n</div>\n\n<span id=\"error\">\n\t<span id=\"err\"></span>\n\t<script>\n\tapp.error = function(eve){\n\t\tapp.view('#err').text('').hide();\n\t\tif(!eve){ return }\n\t\tif(eve.preventDefault){\n\t\t\teve.preventDefault();\n\t\t\treturn;\n\t\t}\n\t\tif(eve._ && !eve.is){ eve = {err: \"Not signed in!\"} }\n\t\tif(!eve.err){ return }\n\t\tapp.view('#err').text(eve.err).show();\n\t\treturn true;\n\t}\n\t</script>\n</span>\n\n<style>\n#error { position: fixed; top: 0; width: 100%; text-align: center; background: white; }\n</style>\n<link rel=\"stylesheet\" href=\"../style.css\"/>\n<style>\n@import url('https://fonts.googleapis.com/css?family=Oxygen');\nhtml, body { font-family: \"Oxygen\", sans-serif; }\n</style>\n</body>\n</html>"
  },
  {
    "path": "examples/basic/post.html",
    "content": "<!DOCTYPE html>\n\n<h1>Posts</h1>\n\n<form id=\"sign\">\n  <input id=\"alias\" placeholder=\"username\">\n  <input id=\"pass\" type=\"password\" placeholder=\"passphrase\">\n  <input id=\"in\" type=\"submit\" value=\"sign in\">\n  <input id=\"up\" type=\"button\" value=\"sign up\">\n</form>\n\n<form id=\"said\">\n  <input id=\"say\" placeholder=\"write here...\">\n  <input id=\"speak\" type=\"submit\" value=\"say\">\n</form>\n\n<ul></ul>\n\n<script src=\"../jquery.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/sea.js\"></script>\n<script src=\"../../../gun/axe.js\"></script>\n\n<script>\ngun = GUN(), user = gun.user().recall({sessionStorage: true});\n\n$('#sign').on('submit', login);\n$('#up').on('click', () => { user.create($('#alias').val(), $('#pass').val(), login) });\nfunction login(eve){\n  eve.preventDefault();\n  user.auth($('#alias').val(), $('#pass').val());\n};\n\ngun.on('auth', () => { $('#sign').hide(), user.get('said').map().on(show) });\nfunction show(data, id){\n  return ($('#' + id).get(0) || $('<li>').attr('id', id).prependTo('ul')).text(data);\n};\n\n$('#said').on('submit', (eve) => {\n  eve.preventDefault();\n  if(!user.is){ return }\n  user.get('said').set($('#say').val());\n  $('#say').val(\"\");\n});\n</script>"
  },
  {
    "path": "examples/basic/private.html",
    "content": "<!DOCTYPE html>\n<style>\n  html, body {\n    background: rgb(245, 245, 245);\n    margin: 0;\n    padding: 0;\n  }\n  div {\n    position: relative;\n    overflow: hidden;\n  }\n  #top {\n    background: #283e4a;\n    height: 52px;\n    width: 100%;\n  }\n  .box {\n    border-radius: 3px;\n    box-shadow: 0px 0px 3px #777;\n    background: white;\n    max-width: 36em;\n    margin: 0 auto;\n    min-height: 10em;\n    margin-bottom: 0.5em;\n  }\n  .color {\n    background: #2977b5;\n    height: 7em;\n    width: 100%;\n  }\n  .pad {\n    margin: 1em;\n  }\n  .none { display: none; }\n  input {\n    font-size: 1em;\n    margin: 0.1em;\n  }\n</style>\n<div id=\"top\">\n  <center>\n    <input id=\"search\" placeholder=\"search by pub or DID\">\n  </center>\n</div>\n\n<div class=\"box\">\n  <div class=\"color\"></div>\n  <div class=\"pad\">\n    <form id=\"sign\">\n      <h1>Login</h1>\n      <input id=\"alias\" placeholder=\"username\">\n      <input id=\"pass\" type=\"password\" placeholder=\"passphrase\">\n      <input id=\"in\" type=\"submit\" value=\"sign in\">\n      <input id=\"up\" type=\"button\" value=\"sign up\">\n    </form>\n\n\n    <form id=\"profile\" class=\"none\">\n      <h1>Profile</h1>\n      <p>Data is privately encrypted by default. \"+\" to grant access, \"x\" to revoke access.</p>\n      <input id=\"name\" placeholder=\"name\"> <button>+</button><br/>\n      <input id=\"born\" placeholder=\"born\"> <button>+</button><br/>\n      <input id=\"edu\" placeholder=\"education\"> <button>+</button><br/>\n      <input id=\"skills\" placeholder=\"skills\"> <button>+</button><br/>\n    </form>\n  </div>\n</div>\n\n<div class=\"box\"><div class=\"pad\">\n  Public Key: <input id=\"pub\">\n</div></div>\n\n<script src=\"../jquery.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/sea.js\"></script>\n\n<script>\n\n// extend SEA functions to base64 encode encrypted data\n// workaround for https://github.com/amark/gun/issues/783\n\n(() => {\n  const _encrypt = SEA.encrypt;\n  SEA.encrypt = function(...args) {\n    return _encrypt.apply(this, args).then(enc => btoa(JSON.stringify(enc)));\n  }\n\n  const _decrypt = SEA.decrypt;\n  SEA.decrypt = function(data, ...args) {\n    try     { data = JSON.parse(atob(data)); }\n    finally { return _decrypt.apply(this, [data, ...args]); }\n  }\n})();\n\n// override User functions to fix several issues\n// see https://github.com/amark/gun/issues/808\n\nSEA.Gun.User.prototype.grant = function grant(to, cb) {\n  const gun  = this;       const user = gun.back(-1).user();\n  const pair = user._.sea; let   path = '';\n\n  gun.back(at => { if (at.has) { path += at.get; } });\n\n  (async () => {\n    let enc, sec;\n\n    if (sec = await user.get('trust').get(pair.pub).get(path).then()) {\n      sec = await SEA.decrypt(sec, pair);\n\n    } else {\n      sec = SEA.random(24).toString();\n      enc = await SEA.encrypt(sec, pair);\n\n      user.get('trust').get(pair.pub).get(path).put(enc);\n    }\n\n    let pub  = to.get('pub') .then();\n    let epub = to.get('epub').then();\n\n    pub = await pub; epub = await epub;\n\n    const dh = await SEA.secret (epub, pair);\n    enc      = await SEA.encrypt(sec,  dh);\n\n    // if pub is not already in trust, first put an empty node\n    // workaround for https://github.com/amark/gun/issues/844\n\n    if (!await user.get('trust').get(pub).then()) {\n      await user.get('trust').get(pub).get(path).put({}).then();\n    }\n\n    user.get('trust').get(pub).get(path).put(enc, cb);\n  })();\n\n  return gun;\n}\n\nSEA.Gun.User.prototype.secret = function(data, cb) {\n  const gun  = this;       const user = gun.back(-1).user();\n  const pair = user._.sea; let   path = '';\n\n  gun.back(at => { if (at.has) { path += at.get; } });\n\n  (async () => {\n    let enc, sec;\n\n    if (sec = await user.get('trust').get(pair.pub).get(path).then()) {\n      sec = await SEA.decrypt(sec, pair);\n\n    } else {\n      sec = SEA.random(24).toString();\n      enc = await SEA.encrypt(sec, pair);\n\n      user.get('trust').get(pair.pub).get(path).put(enc);\n    }\n\n    enc = await SEA.encrypt(data, sec);\n    gun.put(enc, cb);\n  })();\n\n  return gun;\n}\n\nvar gun = Gun('http://localhost:8765/gun');\nvar user = gun.user();\nvar LI = {};\n\nuser.recall({sessionStorage: true});\n\n$('#up').on('click', function(e){\n\tuser.create($('#alias').val(), $('#pass').val());\n});\n\n$('#sign').on('submit', function(e){\n\te.preventDefault();\n\tuser.auth($('#alias').val(), $('#pass').val());\n});\n\ngun.on('auth', function(){\n  $('#sign').hide();\n\t$('#profile').show();\n  var pub = user._.sea.pub;\n  $('#pub').val(pub);\n  return;\n  $(\"#search\").val(pub).trigger('blur');\n});\n\n$('#profile input').on('keyup', function(e){\n  if(!user.is){ return }\n  var id = LI.busy = $(this).attr('id');\n  user.get('profile').get(id).secret($(this).val());\n}).on('blur', function(){ LI.busy = false })\n\n$('#profile button').on('click', async function(e){\n  e.preventDefault();\n\tif(!user.is){ return }\n  var b = $(this);\n  var id = b.prev().attr('id');\n  var pub = prompt(\"What is the Public Key or DID you want to give read access to?\");\n  var to = gun.user(pub);\n  var who = await to.get('alias').then();\n  if(!confirm(\"You want to give access to \" + who + \"?\")){ return }\n  user.get('profile').get(id).grant(to);\n});\n\n$('#search').on('blur', function(e){\n  var s = LI.search = $(this).val();\n  var find = gun.user(s);\n  find.get('profile').on(function(data, key, at, ev){\n    if(s !== LI.search){\n      ev.off();\n      return;\n    }\n\n    Gun.node.is(data, async (enc, id) => {\n      if (id === LI.busy) { return; }\n\n      const pair = user._.sea;\n      let key, val;\n\n      if (key =\n        await find.get('trust').get(pair.pub).get(id + 'profile').then()) {\n        const mix = await Gun.SEA.secret(await find.get('epub').then(), pair);\n\n        key = await Gun.SEA.decrypt(key, mix);\n        val = await Gun.SEA.decrypt(enc, key);\n\n        // decode encrypted data to show 'SEA{...}'\n      } else { val = JSON.parse(atob(enc)); }\n\n      $('#' + id).val(val);\n    });\n  });\n});\n</script>"
  },
  {
    "path": "examples/basic/schedule.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\n  <link href='https://fonts.googleapis.com/css?family=Poiret+One' rel='stylesheet' type='text/css'>\n</head>\n<body>\n  \n<h1><button id=\"left\">&larr;</button> <span id=\"date\"></span> Schedule <button id=\"right\">&rarr;</button></h1>\n\n<form id=\"add\">\n  <style>input[type=\"number\"]{ width: 4em; }</style>\n  <input id=\"what\" placeholder=\"What?\">\n  <input id=\"where\" placeholder=\"Where?\">\n  <input type=\"number\" id=\"hour\"><script>hour.value = new Date().getHours() % 12 || 12</script> :\n  <input type=\"number\" id=\"min\" value=\"0\">\n  <select id=\"ampm\">\n    <option value=\"\">am</option>\n    <option value=\"1\">pm</option>\n    <script>ampm.children[new Date().getHours() < 12? 0 : 1].selected='selected'</script>\n  </select>\n  <input id=\"id\" type=\"hidden\">\n  <input id=\"go\" type=\"submit\" value=\"add\">\n  <div id=\"err\"></div>\n</form>\n\n<style>\n  .none { display: none; }\n  p, ul, li { list-style-type: none; margin: 0; padding: 0; }\n</style>\n\n<ul></ul>\n\n<div class=\"model none\">\n  <li>\n    <b class=\"when\"></b>\n    <span class=\"what\"></span>\n    <u class=\"where\"></u>\n    <span class=\"sort none\">0</span>\n    <button class=\"edit\"><</button>\n  </li>\n</div>\n\n<script src=\"../jquery.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/nts.js\"></script>\n<script src=\"../../../gun/lib/webrtc.js\"></script>\n\n<script>\nvar name = 'schedule/' + location.hash.slice(1);\nvar gun = Gun(location.origin + '/gun');\n//var gun = Gun('http://localhost:8765/gun');\n//var gun = Gun();\n\n$('#add').on('submit', function(event){\n  event.preventDefault();\n  event = {};\n  if(!schedule.on){ return err.innerText = \"No date!\" }\n  event.when = new Date(schedule.on.getFullYear(), schedule.on.getMonth(), schedule.on.getDate(), hour.value % 12 + (ampm.value? 12 : 0), min.value).getTime();\n  if(!(event.what = what.value)){ return err.innerText = \"No description!\" }\n  if(!(event.where = where.value)){ return err.innerText = \"No location!\" }\n  var day = gun.get(name+now(event.when));\n  day.get(id.value || String.random(9)).put(event);\n  what.value = where.value = id.value = err.innerText = '';\n  go.value = 'add';\n  schedule(event.when);\n});\n\nfunction schedule(ms){\n  var day = new Date(ms);\n  if(schedule.on && schedule.on.toLocaleDateString() === day.toLocaleDateString()){ return } schedule.on = day;\n  $('#date').text(day.getFullYear()+' '+ day.toString().split(' ')[1] +' '+day.getDate());\n  day = gun.get(name+now(ms));\n  $('ul').empty();\n  day.map().on(UI);\n}\nschedule(+new Date());\n\n$('#left').on('click', function(){ schedule(+new Date(schedule.on.getFullYear(), schedule.on.getMonth(), schedule.on.getDate() - 1)) });\n$('#right').on('click', function(){ schedule(+new Date(schedule.on.getFullYear(), schedule.on.getMonth(), schedule.on.getDate() + 1)) });\n\nfunction UI(event, id){\n  if(!event){ return }\n  var when = new Date(event.when);\n  if(schedule.on && when.toLocaleDateString() !== schedule.on.toLocaleDateString()){ return }\n  var ul = $('ul')\n  var li = $(\"#cal-\" + id)[0]; // grab if exists\n  if(!li){\n    li = $('.model li').clone(true) // else create it\n      .attr('id', 'cal-' + id);\n  } \n  li = (UI.last = sort(event.when, ul.children('li').last())[0])? $(li).insertAfter(UI.last) : $(li).prependTo(ul);\n  li.find('.what').text(event.what);\n  li.find('.where').text(event.where);\n  li.find('.sort').text(event.when);\n  li.find('.edit').val(id);\n\n  var time = when.toLocaleTimeString();\n  li.find('.when').text(time.split(':').slice(0,2).join(':') + time.slice(-2));\n};\n\n$(document).on('click', '.edit', function(){\n  go.value = 'update';\n  id.value = this.value;\n  what.value = $(this).parent().find('.what').text();\n  where.value = $(this).parent().find('.where').text();\n  var when = new Date(parseFloat($(this).parent().find('.sort').text()));\n  hour.value = when.getHours() % 12 || 12;\n  min.value = when.getMinutes();\n  ampm.value = when.getHours() < 12? '' : 1;\n  what.focus();\n});\n\nfunction now(t){\n  return new Date(t || Gun.state()).toLocaleDateString().split('/').reverse().join('/')\n}\n\nfunction sort(num, li){ return parseFloat(num) >= parseFloat($(li).find('.sort').text() || -Infinity)? li : sort(num, li.prev()) }\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/basic/screen.html",
    "content": "<!DOCTYPE html>\n\n<video id=\"video\" width=\"100%\"></video>\n<center>\n  <button id=\"record\">Record</button>\n  <button id=\"play\">Play</button>\n</center>\n\n<script src=\"../jquery.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n\n<script>\nvar gun = Gun(location.origin + '/gun');\nvar record = {recorder: null, recording: false};\n\n$('#record').on('click', ()=>{\n  if(!record.ing){ return record.stream() }\n  $('#record').text(\"Record\");\n  if(record.ing.stop){ record.ing.stop() }\n  record.ing = false;\n})\n\nrecord.stream = function(){\n  navigator.mediaDevices.getDisplayMedia({ video: true }).then(stream => {\n    var chunks = []; // we have a stream, we can record it\n    record.ing = new MediaRecorder(stream);\n    record.ing.ondataavailable = eve => chunks.push(eve.data);\n    record.ing.onstop = eve => record.save(new Blob(chunks));\n    record.ing.start()\n    $('#record').text(\"End\");\n  }, err => { console.log(err) });\n}\n\nrecord.save = function(data){\n  record.file = record.file || new FileReader();\n  record.file.readAsDataURL(data); \n  record.file.onloadend = function(){\n    var b64 = record.file.result;\n    b64 = \"data:video/webm\" + b64.slice(b64.indexOf(';'));\n    gun.get('test').get('screen').put(b64);\n  }\n}\n\n$('#play').on('click', ()=>{\n  if(record.playing){\n    $('#play').text(\"Play\")\n    $('#video').get(0).stop();\n    record.playing = false;\n    return;\n  }\n  $('#play').text(\"Stop\");\n  record.playing = true;\n  gun.get('test').get('screen').once((data)=>{\n    if(!data){ return }\n    $('#video').get(0).src = data;\n    $('#video').get(0).play()\n  })\n})\n</script>"
  },
  {
    "path": "examples/basic/stream.html",
    "content": "<!DOCTYPE html>\n\n<center>\n  <img id=\"img\" width=\"100%\"><br/>\n  Stream <select id=\"select\"><option id=\"from\">from</option></select>\n  add <input id=\"pass\" placeholder=\"password\" type=\"password\">\n  resolution <input id=\"res\" value=\"240\" step=\"32\" max=\"1080\" type=\"number\" style=\"width:3em;\">\n  or <input id=\"upload\" type=\"file\">\n</center>\n<video id=\"video\" width=\"100%\" controls autoplay style=\"display: none;\"></video>\n<canvas id=\"canvas\" width=\"0\" style=\"display: none;\"></canvas>\n\n<script src=\"../jquery.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/sea.js\"></script>\n<script src=\"../../../gun/lib/webrtc.js\"></script>\n\n<script>;(async function(){\ngun = Gun(location.origin + '/gun'); //gun = GUN();\n\nstream = canvas.getContext('2d'), stream.from = navigator.mediaDevices;\n\n(await stream.from.enumerateDevices()).forEach((device,i) => {\n  if('videoinput' !== device.kind){ return }\n  var opt = $(from).clone().prependTo('select').get(0);\n  $(opt).text(opt.id = device.label || 'Camera '+i);\n  opt.value = device.deviceId;\n});\n\n$('select').on('change', async eve => { $(from).text('Off'); // update label\n  if('Off' == select.value){ return video.srcObject.getTracks()[0].stop() }\n  video.srcObject = await stream.from.getUserMedia({ audio: false,\n    video: (select.value && {deviceId: {exact: select.value}}) || {facingMode: \"environment\"}\n  });\n});\n$('#upload').on('change', async eve => { console.log(\"Check ./upload.html\") })\n\nsetInterval(async tmp => {\n  if(!(video.srcObject||'').active){ return }\n  var size = parseInt(res.value);\n  stream.drawImage(video, 0,0,\n    canvas.width = size || video.videoWidth * 0.1,\n    canvas.height = (size * (video.videoHeight/video.videoWidth)) || video.videoHeight * 0.1\n  );\n  var b64 = canvas.toDataURL('image/jpeg');\n  if(pass.value){ b64 = await SEA.encrypt(b64, pass.value) }\n  gun.get('test').get('video').put(b64);\n}, 99);\n\ngun.get('test').get('video').on(async data => {\n  if(pass.value){ data = await SEA.decrypt(data, pass.value) }\n  img.src = data; // Beware: Some browsers memory leak fast src updates.\n});\n\n// === AUDIO STREAMING WITH FADE-IN/OUT ===\nconst audioCtx = new (window.AudioContext || window.webkitAudioContext)();\nconst mic = await stream.from.getUserMedia({ audio: true });\nconst src = audioCtx.createMediaStreamSource(mic);\nconst proc = audioCtx.createScriptProcessor(2048, 1, 1);\n\nsrc.connect(proc);\nproc.connect(audioCtx.destination);\n\nproc.onaudioprocess = async e => {\n  const input = e.inputBuffer.getChannelData(0);\n  const output = new Float32Array(input.length);\n  const fade = 128;\n\n  for (let i = 0; i < fade; i++) {\n    output[i] = input[i] * (i / fade); // fade in\n  }\n  for (let i = fade; i < input.length - fade; i++) {\n    output[i] = input[i]; // middle\n  }\n  for (let i = input.length - fade; i < input.length; i++) {\n    output[i] = input[i] * ((input.length - i) / fade); // fade out\n  }\n\n  const int16 = new Int16Array(output.length);\n  for (let i = 0; i < output.length; i++) {\n    int16[i] = Math.max(-32768, Math.min(32767, output[i] * 32768));\n  }\n\n  let b64 = btoa(String.fromCharCode(...new Uint8Array(int16.buffer)));\n  if(pass.value){ b64 = await SEA.encrypt(b64, pass.value) }\n  gun.get('test').get('audio').put(b64);\n};\n\ngun.get('test').get('audio').on(async data => {\n  if(!data) return;\n  if(pass.value){ data = await SEA.decrypt(data, pass.value) }\n  const bin = atob(data);\n  const bytes = new Uint8Array(bin.length);\n  for(let i=0; i<bin.length; i++){ bytes[i] = bin.charCodeAt(i) }\n  const buf = audioCtx.createBuffer(1, bytes.length / 2, 44100);\n  const chan = buf.getChannelData(0);\n  for(let i=0; i<chan.length; i++){\n    const s = (bytes[i*2+1] << 8) | bytes[i*2];\n    chan[i] = (s > 32767 ? s - 65536 : s) / 32768;\n  }\n  const player = audioCtx.createBufferSource();\n  player.buffer = buf;\n  player.connect(audioCtx.destination);\n  player.start();\n});\n\n}());</script>\n"
  },
  {
    "path": "examples/basic/tables.html",
    "content": "<!DOCTYPE html>\n\n<h1>Tables</h1>\n\n<form id=\"sign\">\n  <input id=\"alias\" placeholder=\"username\">\n  <input id=\"pass\" type=\"password\" placeholder=\"passphrase\">\n  <input id=\"in\" type=\"submit\" value=\"sign in\">\n  <input id=\"up\" type=\"button\" value=\"sign up\">\n</form>\n\n<button id=\"tadd\">+ table</button>\n<ul></ul><br/>\n\n<div id=\"table\"></div>\n<button id=\"radd\">+ row</button>\n<button id=\"cadd\">+ col</button>\n\n<style>\ndiv {\n  position: relative;\n  overflow: hidden;\n}\n.cell {\n  width: 5em;\n  height: 5em;\n  border: 1px solid black;\n  float: left;\n}\n.item {\n  float: left;\n  min-width: 5em;\n}\n</style>\n<div class=\"model\" style=\"display: none;\">\n  <div class=\"item\"></div>\n  <div class=\"cell\"></div>\n  <div class=\"row\"></div>\n</div>\n\n<script src=\"https://cdn.jsdelivr.net/npm/gun/examples/jquery.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/gun/sea.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/gun/lib/open.js\"></script>\n\n<script>\n//var gun = Gun(['http://localhost:8080/gun']);\nvar gun = Gun();\nvar user = gun.user();\n\n$('#up').on('click', function(e){\n\tuser.create($('#alias').val(), $('#pass').val());\n});\n\n$('#sign').on('submit', function(e){\n\te.preventDefault();\n\tuser.auth($('#alias').val(), $('#pass').val());\n});\n\nuser.recall({sessionStorage: true});\n\ngun.on('auth', function(){\n\t$('#sign').hide();\n\tuser.get('tables').map().once(list);\n});\n\n$('#tadd').on('click', function(e){\n  if(!user.is){ return alert(\"login first\") }\n  var cell = user.get('cells').set({what: \"Edit me!\", sort: 1});\n  var row = user.get('rows').set({sort: 1});\n  row.get('cells').set(cell);\n  var name = prompt(\"What do you want to call this table?\")\n  var table = user.get('tables').set({name: name});\n  table.get('rows').set(row);\n  choose(table);\n});\n\n$(document).on('click', '.item', function(){\n  choose($(this).data('$'));\n});\n\nfunction choose(table){\n  choose.table = table;\n  table.open(render);\n}\n\nfunction render(data){\n  console.log(data);\n  $('#table').empty(); // BAD! Write DOM-diffing!\n  Gun.obj.map(data.rows, function(row, id){\n    var $r = grab(id, '.model .row', '#table');\n    Gun.obj.map(row.cells, function(cell, id){\n      var $c = grab(id, '.model .cell', $r);\n      $c.text(cell.what);\n    });\n  });\n}\n\n$(document).on('click', '.cell', function(e){\n  var id = $(this).data('id'), ref = gun.get(id);\n  var what = prompt(\"What should be in this cell?\");\n  ref.get('what').put(what);\n});\n\n$('#radd').on('click', function(){\n  if(!user.is){ return alert(\"login first\") }\n  choose.table.get('rows').set();\n\n  var cell = user.get('cells').set({what: \"Edit me!\", sort: 1});\n  var row = user.get('rows').set({sort: 1});\n  row.get('cells').set(cell);\n  choose.table.get('rows').set(row);\n});\n\n$('#cadd').on('click', function(){\n  if(!user.is){ return alert(\"login first\") }\n  choose.table.get('rows').map().once(function(){\n    var cell = user.get('cells').set({what: \"Edit me!\", sort: 1});\n    this.get('cells').set(cell);\n  });\n});\n\nfunction grab(id, $model, $to){\n  var did = btoa(id).replace(/[\\+\\-\\=\\.]/ig,'');\n  return $('#' + did).get(0) || $($model).clone(true, true).attr('id', did).appendTo($to).data('id', id);\n};\n\nfunction list(table, id, $model, $to){\n  var li = grab(id, '.model .item', 'ul');\n  $(li).text(table.name).data('$', this);\n};\n</script>"
  },
  {
    "path": "examples/basic/upload.html",
    "content": "<!DOCTYPE html>\n\n<div class=\"model\" style=\"display: none;\">\n  <video width=\"100%\" controls autoplay></video>\n  <audio width=\"100%\" controls autoplay></audio>\n  <img style=\"max-width: 100%;\">\n</div>\n<center>\n  <p>Drag & drop videos, songs, or images! <input id=\"upload\" type=\"file\" multiple></p>\n</center>\n\n<script src=\"../../../gun/lib/yson.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/lib/dom.js\"></script>\n<script src=\"../../../gun/lib/upload.js\"></script>\n\n<script>\ngun = GUN(location.origin + '/gun');\n\n$('html, #upload').upload(function resize(eve, up){\n  if(up){ return up.shrink(eve, resize, 1024) }\n  var b64 = (eve.base64 || ((eve.event || eve).target || eve).result || eve); // which one? try all!\n  gun.get('test').get((eve.id+(new Date).getUTCSeconds()) % 60).put(b64); // limit uploads to 1 of 60 slots.\n});\n\ngun.get('test').map().once(function(data){\n  if(\"string\" != typeof data){ return }\n  var type = data.split(';')[0], ui;\n  if(type.indexOf('image') + 1){ ui = $(\"img\").get(0) }\n  if(type.indexOf('video') + 1){ ui = $('video').get(0) }\n  if(type.indexOf('audio') + 1){ ui = $('audio').get(0) }\n  if(!ui){ return }\n  $(ui).clone().prependTo('center').get(0).src = data;\n});\n</script>"
  },
  {
    "path": "examples/basic/user.html",
    "content": "<!DOCTYPE html>\n<p>Moved to <a href=\"./post.html\">./post.html</a>!</p>"
  },
  {
    "path": "examples/basic/video.html",
    "content": "<!DOCTYPE html>\n\n<video id=\"video\" width=\"100%\" controls autoplay></video>\n<center>\n  <input id=\"pass\" placeholder=\"password\">\n  Record <button class=\"record\">Camera</button> or <button class=\"record\">Screen</button>\n</center>\n\n<script src=\"../jquery.js\"></script>\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/sea.js\"></script>\n\n<script>\nvar gun = Gun(location.origin + '/gun');\n\ngun.get('test').get('video').on(async function(data){\n  if($('#pass').val()){ data = await SEA.decrypt(data, $('#pass').val()) }\n  $('#video').get(0).src = data;\n})\n\n$('.record').on('click', function(){\n  if(record.ing){\n    if(record.ing.stop){ record.ing.stop() }\n    $(this).text(record.type);\n    record.ing = false;\n    return;\n  }\n  record(record.type = $(this).text());\n  $(this).text(\"End\");\n})\n\nfunction record(type){\n  if('Camera' === type){\n    navigator.getMedia({ video: true, audio: true }, load, error);\n  }\n  if('Screen' === type){\n    navigator.mediaDevices.getDisplayMedia({ video: true, audio: true }).then(load, error);\n  }\n  function load(media){\n    var chunks = [];\n    record.ing = new MediaRecorder(media);\n    record.ing.ondataavailable = function(eve){ chunks.push(eve.data) }\n    record.ing.onstop = function(eve){record.save(new Blob(chunks)) }\n    record.ing.start();\n  }\n  function error(err){ console.log(err) }\n}\n\nrecord.save = function(data){\n  record.file = record.file || new FileReader();\n  record.file.readAsDataURL(data); \n  record.file.onloadend = async function(){\n    var b64 = record.file.result, pass;\n    b64 = $('#video').get(0).src = \"data:video/webm\" + b64.slice(b64.indexOf(';'));\n    if($('#pass').val()){ b64 = await SEA.encrypt(b64, $('#pass').val()) }\n    gun.get('test').get('video').put(b64);\n  }\n}\n\nnavigator.getMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia\n  || navigator.mozGetUserMedia || navigator.msGetUserMedia);\n</script>"
  },
  {
    "path": "examples/chat/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <title>Converse</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\">\n  <link href='https://fonts.googleapis.com/css?family=Poiret+One' rel='stylesheet' type='text/css'>\n  <style>\n    .chat__heading {\n      position: fixed;\n      text-align: center;\n      z-index: 1;\n      width: 100%;\n      margin-top: 0;\n      margin-bottom: 0;\n    }\n\n    .chat__form-container {\n      display: flex;\n      justify-content: center;\n      width: 100%;\n      padding: 10px 20px;\n      position: fixed;\n      z-index: 1;\n      bottom: 0;\n    }\n\n    .chat__form {\n      display: flex;\n      justify-content: center;\n      height: 50px;\n      background-color: white;\n      border: 2px solid white;\n      max-width: 900px;\n      width: 100%;\n      border-radius: 5px;\n    }\n\n    .chat__name-input {\n      flex: 1;\n      padding: 10px;\n    }\n\n    .chat__message-input {\n      flex: 5;\n      padding: 10px;\n    }\n\n    .chat__submit {\n      padding: 10px;\n      color: white;\n      border-radius: 5px;\n    }\n\n    .chat__submit:hover::after {\n      background-color: rgba(0,0,0,0.2);\n    }\n\n    .chat__submit:focus::after {\n      background-color: rgba(0,0,0,0.2);\n    }\n\n    .chat__submit::after {\n      content: '';\n      position: absolute;\n      width: 100%;\n      height: 100%;\n      left: 0;\n      top: 0;\n      border-radius: 5px;\n      transition: background-color 0.3s;\n      background-color: rgba(0,0,0,0);\n    }\n\n    .chat__message-list {\n      display: flex;\n      flex-direction: column;\n      align-items: center;\n      flex: 1;\n      overflow-y: auto;\n      padding: 60px 20px;\n      width: 100%;\n      background-color: rgba(0, 0, 0, 0.2);\n      min-height: 100vh;\n    }\n\n    .chat__message {\n      display: flex;\n      flex-wrap: wrap;\n      margin-bottom: 10px;\n      padding: 10px;\n      border-radius: 5px;\n      width: 100%;\n      position: relative;\n      max-width: 900px;\n    }\n\n    .chat__name {\n      margin-right: 20px;\n    }\n\n    .chat__when {\n      position: absolute;\n      top: 0;\n      right: 2em;\n      padding: 10px;\n      background: rgba(100%, 100%, 100%, 0.9);\n      opacity: 0;\n      border-radius: 5px;\n    }\n\n    .chat__message:hover .chat__when {\n      opacity: 1;\n      right: 0em;\n    }\n\n    @media (max-width: 567px) {\n      .chat__heading {\n        font-size: 30px;\n      }\n    }\n  </style>\n</head>\n\n<body>\n  <div class=\"chat hue2 page\">\n    <h2 id='title' class=\"chat__heading hue2 whitet\">Have a Conversation...</h2>\n    <ul class=\"chat__message-list\">\n      <li class=\"none\"></li>\n    </ul>\n\n    <div class=\"chat__form-container hue2\">\n      <form class=\"chat__form\">\n        <label for=\"name-input\" class=\"visually-hidden\">Name</label>\n        <input id=\"name-input\" class=\"chat__name-input\" placeholder=\"Name\"></input>\n        <label for=\"message-input\" class=\"visually-hidden\">Message</label>\n        <input id=\"message-input\" class=\"chat__message-input\" placeholder=\"Write a message...\"></input>\n        <button class=\"chat__submit say hue2\">say</button>\n      </form>\n    </div>\n\n    <div class=\"model\">\n      <li class=\"chat__message white huet2 box\">\n        <b class=\"chat__name\"></b>\n        <p class=\"chat__message-text\"></p>\n        <span class=\"sort none\">0</span>\n        <div class=\"chat__when\"></div>\n      </li>\n    </div>\n  </div>\n\n  <script src=\"/jquery.js\"></script>\n  <script src=\"/gun.js\"></script>\n  <script src=\"/gun/nts.js\"></script>\n  <script>\n    var gun = Gun(location.origin + '/gun');\n    var chat = gun.get('converse/' + location.hash.slice(1));\n\n    $(\".chat__submit\").on('click', submit);\n    $(\".chat_form\").on('keydown', enter);\n    function enter(e) {\n      if (e.which !== 13) { return }\n      submit(e);\n    }\n    function submit(e) {\n      e.preventDefault();\n\n      var msg = { when: Gun.state() };\n\n      msg.who = $('.chat__name-input').val();\n      if (!msg.who) {\n        msg.who = 'user' + String.random(3);\n        $('.chat__name-input').val(msg.who);\n      }\n\n      msg.what = $('.chat__message-input').val();\n      if (!msg.what) { return }\n\n      chat.set(msg);\n      $('.chat__message-input').val('').focus();\n    }\n\n    chat.map().once(function (msg, id) {\n      if (!msg) { return }\n      var messageList = $('.chat__message-list');\n      var last = sort(msg.when, messageList.children('li').last());\n\n      var li = $(\"#msg-\" + id)[0]; // grab if exists\n      if (!li) {\n        li = $('.model li').clone(true) // else create it\n          .attr('id', 'msg-' + id)\n          .insertAfter(last);\n      }\n\n      // bind the message data into the UI\n      li = $(li);\n      li.find('.chat__name').text(msg.who);\n      li.find('.chat__message-text').text(msg.what);\n      li.find('.sort').text(msg.when);\n\n      var time = new Date(msg.when);\n      li.find('.chat__when').text(time.toDateString() + ', ' + time.toLocaleTimeString());\n\n      $('html, body').stop(true, true)\n        .animate({ scrollTop: messageList.height() });\n    });\n\n    function sort(num, li) { return parseFloat(num) >= parseFloat($(li).find('.sort').text() || -Infinity) ? li : sort(num, li.prev()) }\n  </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/chat/user.html",
    "content": "<script src=\"/gun.js\"></script>\n<!--\n<script src=\"/gun/lib/cryptomodules.js\" type=\"text/javascript\"></script>\n<script src=\"/gun/sea.js\"></script>\n-->\n<script>\n\tvar gun = Gun(location.origin+'/gun');\n\tvar user = gun.user && gun.user();\n\tif(user){\n\t\t// 1st: call create. 2nd call auth. After that, call recall\n\t\t// user.create('dude', 'my secret').then(function(ack) { console.log('created ack:', ack) });\n\t\t// user.recall().then(function(ack){\n\t\t// \tif (!ack || !ack.sea){\n\t\t// \t\tconsole.log('user.recall not bootstrapping...');\n\t\t// \t\tuser.auth('dude', 'my secret', {pin: 'PIN'}).then(function(user) { console.log('authenticated user:', user) });\n\t\t// \t\t// user.auth('dude', 'my secret', {pin: 'PIN', newpass: 'my new secret'}).then(function(user) { console.log('authenticated user:', user) });\n\t\t// \t} else {\n\t\t// \t\tconsole.log('user.recall authenticated user:', ack.alias);\n\t\t// \t}\n\t\t// });\n\t}\n</script>"
  },
  {
    "path": "examples/contact/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../style.css\">\n\t</head>\n\t<body>\n\t\t<div id=\"sign\" class=\"hue page\">\n\t\t\t<style>\n\t\t\t\tinput, button {\n\t\t\t\t\tmargin: 1em 0;\n\t\t\t\t\tpadding: 1em;\n\t\t\t\t}\n\t\t\t\t.or {\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\twidth: 15%;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<form id=\"inup\" class=\"sign pad center\">\n\t\t\t\t<div class=\"loud\">Welcome,</div>\n\t\t\t\t<div class=\"mid row col\">\n\t\t\t\t\t<input name=\"alias\" class=\"huet jot sap\" placeholder=\"alias\">\n\t\t\t\t\tEnter your public username.\n\t\t\t\t</div>\n\t\t\t\t<div class=\"mid row col\">\n\t\t\t\t\t<input name=\"pass\" class=\"huet jot sap\" type=\"password\" placeholder=\"passphrase\">\n\t\t\t\t\tAnd a long private passphrase.\n\t\t\t\t</div>\n\t\t\t\t<div class=\"mid row col go\">\n\t\t\t\t\t<button class=\"huet sap act symbol\">sign in</button>\n\t\t\t\t\t<div class=\"or\">or</div>\n\t\t\t\t\t<button class=\"huet sap act symbol\">sign up</button>\n\t\t\t\t</div>\n\t\t\t\t<a href=\"info\">more info</a>\n\t\t\t</form>\n\t\t</div id=\"sign\">\n\t\t\n\t\t<div id=\"people\" class=\"hue2 page\">\n\t\t\t<ul name=\"users\" class=\"pad\">\n\t\t\t\t<h3>Here is a list of people:</h3>\n\t\t\t\t<li name=\"#\">\n\t\t\t\t\t<!-- <h3 name=\".\"></h3> -->\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<a href=\"person\" name=\"#\" class=\"whitet act\">\n\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t<span name=\"who\">\n\t\t\t\t\t\t\t\t\t<b name=\"name\"></b>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<i>~</i><i name=\"alias\" class=\"sort\"></i>\n\t\t\t\t\t\t\t\t<input name=\"pub\">\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</ul>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div id=\"people\">\n\t\t\n\t\t<div id=\"converse\" class=\"page\">\n\t\t\t<ul>\n\t\t\t</ul>\n\t\t\t<div class=\"model\">\n\t\t\t\t<li class=\"msg\">\n\t\t\t\t\t<span name=\"fro\">Alias</span>: <span name=\"what\"></span>\n\t\t\t\t</li>\n\t\t\t</div>\n\t\t\t<form>\n\t\t\t\t<input placeholder=\"to\" name=\"to\">\n\t\t\t\t<textarea name=\"what\"></textarea>\n\t\t\t\t<input type=\"submit\" value=\"submit\">\n\t\t\t\t<div class=\"status\"></div>\n\t\t\t</form>\n\t\t</div id=\"converse\">\n\t\t\n\t\t<div id=\"person\" class=\"hue3 page\">\n\t\t\t<style>\n\t\t\t\t#person .back {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\ttop: 0.3em;\n\t\t\t\t\tleft: 0.5em;\n\t\t\t\t\twidth: 2em;\n\t\t\t\t\theight: 2em;\n\t\t\t\t\tz-index: 99999;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<a href=\"people\" class=\"whitet act back\">&#8592</a>\n\t\t\t<div class=\"pad\">\n\t\t\t\t<div name=\"who\">\n\t\t\t\t\t<!-- img src=\"\" -->\n\t\t\t\t\t<h2 name=\"name\" contenteditable=\"true\">Name</h2>\n\t\t\t\t\t<i name=\"born\"></i>\n\t\t\t\t\t<span name=\"bio\" contenteditable=\"true\">bio</span>\n\t\t\t\t\t<form id=\"say\" class=\"center none\">\n\t\t\t\t\t\t<input class=\"jot\" placeholder=\"Say something!\" style=\"width: 80%;\">\n\t\t\t\t\t\t<input type=\"submit\" id=\"speak\" class=\"huet2 sap act symbol\" style=\"min-width: 5em; width: 10%;\" value=\"speak\">\n\t\t\t\t\t</form>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<ul name=\"said\">\n\t\t\t\t\t\t\t<li name=\"#\" class=\"sit sort shade rim\"><div name=\"what\" class=\"rim\"></div></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<input name=\"pub\">\n\t\t\t</div>\n\t\t</div id=\"person\">\n\n\t\t<div id=\"info\" class=\"page\">\n\t\t\t<p>A mysterious new example app has appeared! It is not finished/ready yet.</p>\n\t\t</div id=\"info\">\n\t\t\n\t\t<div id=\"tell\" class=\"center\">\n\t\t\t<style>\n\t\t\t\t#tell {\n\t\t\t\t\tposition: fixed;\n\t\t\t\t\ttop: 0;\n\t\t\t\t\tleft: 0;\n\t\t\t\t\tright: 0;\n\t\t\t\t\theight: 0;\n\t\t\t\t\toverflow: visible;\n\t\t\t\t}\n\t\t\t\t#tell p {\n\t\t\t\t\ttop: -2em;\n\t\t\t\t\twidth: 50%;\n\t\t\t\t\tborder: solid #222 0.2em;\n\t\t\t\t\tborder-top: none;\n\t\t\t\t\tpadding: 1%;\n\t\t\t\t\topacity: 0;\n\t\t\t\t\tvisibility: hidden;\n\t\t\t\t\ttransition: visibility 2s, all 1s ease-in;\n\t\t\t\t}\n\t\t\t\t#tell .notify {\n\t\t\t\t\ttop: 0em;\n\t\t\t\t\topacity: 0.8;\n\t\t\t\t\tvisibility: visible;\n\t\t\t\t\ttransition: visibility 0s, all 0.25s ease-out;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<p class=\"mid black\">Hello world!</p>\n\t\t</div>\n\n\t\t<!-- script src=\"/Users/mark/Dropbox/Public/gun/db/examples/jquery.js\"></script>\n\t\t<script src=\"/Users/mark/Dropbox/Public/gun/db/gun.js\"></script>\n\t\t<script src=\"/Users/mark/Dropbox/Public/gun/db/lib/cryptomodules.js\"></script>\n\t\t<script src=\"/Users/mark/Dropbox/Public/gun/db/sea.js\"></script>\n\t\t<script src=\"/Users/mark/Dropbox/Public/gun/db/as.js\"></script -->\n\n\t\t<script src=\"/jquery.js\"></script>\n\t\t<script src=\"/gun.js\"></script>\n\t\t<script src=\"/gun/sea.js\"></script>\n\t\t<script src=\"/gun/as.js\"></script>\n\t\t<script src=\"/gun/nts.js\"></script>\n\t\t<script>\n\t\t\t// Check out the interactive tutorial\n\t\t\t// for how to build a simplified version\n\t\t\t// of this example: https://scrimba.com/c/c2gBgt4\n\t\t\tvar gun = Gun(location.origin+'/gun');\n\t\t\tvar app = gun.get('example/contacts/7');\n\t\t\tvar user = gun.user();\n\t\t\tvar c = window.c = {};\n\t\t\t(function(){\n\t\t\t\tc.hash = location.hash.slice(1);\n\t\t\t\tgun.on('auth', function(at){\n\t\t\t\t\tif('sign' === c.hash){ c.hash = '' }\n\t\t\t\t\tas.route(c.hash || 'people');\n\t\t\t\t});\n\t\t\t\tgun.on('secure', function(at){\n\t\t\t\t\t/* enforce some rules about shared app level data */\n\t\t\t\t\tif(!at.put || !at.put.users){ return }\n\t\t\t\t\tvar no;\n\t\t\t\t\tGun.node.is(at.put.users, function(val, key){\n\t\t\t\t\t\tGun.SEA.verify(val, false, function(val){\n\t\t\t\t\t\t//Gun.SEA.read(val, false, function(val){\n\t\t\t\t\t\t\tif('~@'+key === Gun.val.link.is(val)){ return }\n\t\t\t\t\t\t\tno = true;\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif(no){ return no }\n\t\t\t\t\t});\n\t\t\t\t\tif(no){ return }\n\t\t\t\t\tthis.to.next(at);\n\t\t\t\t});\n\t\t\t\t$(document).on('keyup', \"form.sign input:first\", as.wait(function(){\n\t\t\t\t\t/*\n\t\t\t\t\tvar form = $(this).closest('form'), data = {alias: $(this).val()};\n\t\t\t\t\tif(!data.alias || data.alias.length < 5){\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar exist = gun.path('alias').path(data.alias);\n\t\t\t\t\texist.get(function(at){\n\t\t\t\t\t\tform.find('.or').addClass('none');\n\t\t\t\t\t\tform.find('button:first').toggleClass('none', at.put? false : true);\n\t\t\t\t\t\tform.find('button:last').toggleClass('none', at.put? true : false);\n\t\t\t\t\t});\n\t\t\t\t\t*/\n\t\t\t\t})).on('click','form.sign button:last', function(){\n\t\t\t\t\tvar but = $(this), form = $(this).closest('form'), data = {alias: form.find('input:first').val(), pass: form.find('input:last').val()};\n\t\t\t\t\tdata.born = Gun.time.is();\n\t\t\t\t\tif(!data.alias || data.alias.length < 5){\n\t\t\t\t\t\tc.tell(\"Alias needs to be longer than 5 characters.\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(!data.pass || data.pass.length < 9){\n\t\t\t\t\t\tc.tell(\"Passphrase needs to be longer than 9 characters.\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tbut.addClass('pulse');\n\t\t\t\t\tdata.alias = data.alias.toLowerCase();\n\t\t\t\t\tuser.create(data.alias, data.pass, function(ack){\n\t\t\t\t\t\tif(!ack.wait){ but.removeClass('pulse') }\n\t\t\t\t\t\tif(ack.err){ c.tell(ack.err); return }\n\t\t\t\t\t\tif(ack.pub){\n\t\t\t\t\t\t\tgun.get('users').get(data.alias).put(gun.get('~@'+data.alias));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsession(data);\n\t\t\t\t\t\tuser.auth(data.alias, data.pass);\n\t\t\t\t\t});\n\t\t\t\t}).on('click','form.sign button:first', become);\n\t\t\t\tfunction become(){\n\t\t\t\t\tvar form = $('#sign').find('form'), data = {alias: form.find('input:first').val(), pass: form.find('input:last').val()};\n\t\t\t\t\tdata.alias = data.alias || sessionStorage.alias;\n\t\t\t\t\tdata.pass = data.pass || sessionStorage.tmp;\n\t\t\t\t\tif(!data.alias || data.alias.length < 5){\n\t\t\t\t\t\tc.tell(\"Alias needs to be longer than 5 characters.\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(!data.pass || data.pass.length < 9){\n\t\t\t\t\t\tc.tell(\"Passphrase needs to be longer than 9 characters.\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar but = form.find('button:first');\n\t\t\t\t\tbut.addClass('pulse');\n\t\t\t\t\tdata.alias = data.alias.toLowerCase();\n\t\t\t\t\tuser.auth(data.alias, data.pass, function(ack){\n\t\t\t\t\t\tif(!ack.wait){ but.removeClass('pulse') }\n\t\t\t\t\t\tif(ack.err){ c.tell(ack.err); return }\n\t\t\t\t\t\tsession(data);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif(!location.hash){\n\t\t\t\t\tas.route('sign');\n\t\t\t\t}\n\t\t\t\tif(!window.sessionStorage){ window.sessionStorage = {clear:function(){}} }\n\t\t\t\tif(sessionStorage.tmp){\n\t\t\t\t\tbecome();\n\t\t\t\t}\n\t\t\t\tfunction session(data){\n\t\t\t\t\tif(!sessionStorage){ return }\n\t\t\t\t\tsessionStorage.alias = data.alias;\n\t\t\t\t\tsessionStorage.tmp = data.pass;\n\t\t\t\t}\n\t\t\t\tc.tell = function(what, n){\n\t\t\t\t\tvar e = $('#tell').find('p');\n\t\t\t\t\te.addClass('notify').text(what);\n\t\t\t\t\tclearTimeout(c.tell.to);\n\t\t\t\t\tc.tell.to = setTimeout(function(){e.removeClass('notify')}, n || 2500);\n\t\t\t\t}\n\t\t\t}());\n\t\t\t(function(){\n\t\t\t\t$(document).on('submit', '#say', function(e){\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tuser.get('who').get('said').set({\n\t\t\t\t\t\twhat: $(this).find('.jot').val()\n\t\t\t\t\t});\n\t\t\t\t\t$(this).find('.jot').val('');\n\t\t\t\t});\n\t\t\t}());\n\t\t\tas.route.page('sign', function(){\n\t\t\t\t$(document.forms.inup.alias).focus();\n\t\t\t});\n\t\t\tas.route.page('people', function(){\n\t\t\t\tif(!user.is){ return as.route('sign') }\n\t\t\t\tas('#people', gun, function(data, key, el){\n\t\t\t\t\tif('pub' !== key){ return }\n\t\t\t\t\tel.closest('a').attr('href', '#person/' + data);\n\t\t\t\t});\n\t\t\t});\n\t\t\tas.route.page('person', function(){\n\t\t\t\tif(!user.is){ return as.route('sign') }\n\t\t\t\tvar pub = location.hash.split('/').slice(-1)[0];\n\t\t\t\t(pub === user._.pub? $('#say').show() : $('#say').hide());\n\t\t\t\tas('#person', window.PUB = gun.get('~'+pub));\n\t\t\t});\n\n\n\n\n\n\n\n\t\t\t(function(converse){\n\t\t\t\tas.route.page('converse', function(){\n\t\t\t\t\tif(!c.me){ return as.route('sign') }\n\t\t\t\t\tconverse.lock = false;\n\t\t\t\t\tvar alias = location.hash.split('/').slice(-1);\n\t\t\t\t\t$('#converse form').find('input:first').val(alias);\n\t\t\t\t\tfunction inbox(msg, id){\n\t\t\t\t\t\tif(!sign.verify(msg.pub, msg.what, msg.sig)){ return }\n\t\t\t\t\t\tmsg.fro = (msg.to === c.me.alias? alias : c.me.alias);\n\t\t\t\t\t\tas.route.render(id, '.msg', $('#converse ul'), msg);\n\t\t\t\t\t}\n\t\t\t\t\tsign.is(alias, function(acc){\n\t\t\t\t\t\tsign.is(c.me.alias).path('msgs').path(acc.pub).map(inbox);\n\t\t\t\t\t}).path('msgs').path(c.me.pub).map(inbox);\n\t\t\t\t});\n\t\t\t\t$(document).on('submit', '#converse form', function(e){\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tif(converse.lock){ return console.log('message sending already') }\n\t\t\t\t\tconverse.lock = true; // prevent duplicate sends.\n\t\t\t\t\tvar form = $(this), msg = {};\n\t\t\t\t\tmsg.to = form.find('input:first').val();\n\t\t\t\t\tmsg.what = form.find('textarea').val();\n\t\t\t\t\tsign.is(msg.to, function(to){\n\t\t\t\t\t\tif(!priv){\n\t\t\t\t\t\t\tform.find('.status').text(\"Failed to send. Please sign in again.\");\n\t\t\t\t\t\t\tconverse.lock = false;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmsg.sig = sign.sig(msg.what, priv);\n\t\t\t\t\t\tmsg.pub = c.me.pub;\n\t\t\t\t\t\tmsg.when = Gun.time.is();\n\t\t\t\t\t\tconsole.log(\"sending msg\", msg);\n\t\t\t\t\t\tsign.is(c.me.alias).path('msgs').path(to.pub).set(gun.put(msg));\n\t\t\t\t\t\tconverse.lock = false;\n\t\t\t\t\t}, function(){\n\t\t\t\t\t\tform.attr('disabled', false).find('.status').text(msg.to + \" cannot be found! Alias is case sensitive.\");\n\t\t\t\t\t\tconverse.lock = false;\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}({}));\n\t\t//}());</script>\n\t</body>\n</html>"
  },
  {
    "path": "examples/docs.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<!-- always start with these two lines to set a clean baseline for different devices -->\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\">\n<script src=\"jquery.js\"></script>\n\n<title>Docs</title>\n</head>\n<body class=\"black whitet\">\n<style>\n\t/*\n\t\tChoose white text on a black background so you can add color in.\n\t\tPick your favorite font and choose a font size.\n\t*/\n\t@import url('https://fonts.googleapis.com/css?family=Oxygen');\n\thtml, body {\n\t\tfont-family: \"Oxygen\", sans-serif;\n\t}\n\n\t[contenteditable]:focus {\n\t\toutline: none;\n\t}\n\n\t.meta-on, div:hover, ul:hover, ol:hover, li:hover, p:hover, span:hover, form:hover, button:hover, input:hover, textarea:hover, img:hover {\n\t\toutline: 1px solid;\n\t\tanimation: meta-on 3s infinite;\n\t\ttransition: none !important;\n\t} @keyframes meta-on {\n\t  0%   {outline-color: magenta;}\n\t  33% {outline-color: cyan;}\n\t  66%  {outline-color: yellow;}\n\t  100% {outline-color: magenta;}\n\t}\n</style>\n\n<div class=\"hold full hue2\">\n\t<div id=\"page\" class=\"max focus gap\" style=\"margin-top: 9%;\"></div>\n</div>\n\n<script src=\"../../gun/gun.js\"></script>\n<script src=\"../../gun/lib/monotype.js\"></script>\n<script src=\"../../gun/lib/meta.js\"></script>\n<script src=\"../../gun/lib/normalize.js\"></script>\n<script async src=\"../../gun/lib/fun.js\"></script>\n\n<script async src=\"../../gun/lib/wave.js\"></script>\n<!-- script async src=\"https://edide.io/music.lib\"></script -->\n\n<script>\nvar gun = Gun();\nvar page = {};\n//var gun = Gun(['https://guntest.herokuapp.com/gun', 'http://localhost:8765/gun']);\n\n;(window.onhashchange = function(){\n\tvar file = (location.hash||'').slice(1);\n\tvar S = +new Date;\n\t$('#page').empty().attr('contenteditable', 'false');\n\tgun.get('test/gun/docs/'+file).get('what').map().on(function render(data, i, msg, eve){\n\t\tvar tmp = page[i] || '';\n\t\tvar last = Gun.state.is(gun._.root.graph[msg.put['#']], i);\n\t\tif(last < tmp.last){ return }\n\t//});\n\t\t//if(window.LOCK){ return }\n\t\tvar p = $('#page').children().get(i);\n\t\tif(!p){\n\t\t\t$('#page').append('<p>');\n\t\t\tsetTimeout(function(){ render(data, i, msg, eve) },0);\n\t\t\treturn;\n\t\t}\n\t\tvar DBG = {s: +new Date};\n\t\tvar r = monotype(p);\n\t\tDBG.mono = +new Date;\n\t\tvar safe = $.normalize(data);\n\t\tDBG.norm = +new Date;\n\t\tp.outerHTML = data;\n\t\tDBG.html = +new Date;\n\t\tr.restore();\n\t\tDBG.rest = +new Date;\n\t\t//console.log(\"mono:\", DBG.mono - DBG.s, \"norm:\", DBG.norm - DBG.mono, 'html:', DBG.html - DBG.norm, 'rest:', DBG.rest - DBG.html, ':::', msg, eve);\n\t});\n})();\n\n\nwindow.requestAnimationFrame = window.requestAnimationFrame || setTimeout;\nwindow.requestAnimationFrame(function frame(){\n\twindow.requestAnimationFrame(frame, 16);\n\t\n}, 16);\n\ndocument.execCommand('defaultParagraphSeparator', false, 'p');\nmeta.edit({\n\tname: \"Edit\",\n\tcombo: ['E'],\n\tuse: function(eve){\n\t\tconsole.log('on');\n\t}, on: function(eve){\n\t\tif($(eve.target).closest('p').length){ return }\n\t\tvar edit = this;\n\t\tsetTimeout(function(){ meta.flip(false) },1);\n\t\tedit.init();\n\t\t$(document).on('keydown.tmp', '[contenteditable]', function(eve){\n\t\t\tif(eve.which != 13){ return }\n\t\t\teve.preventDefault();\n\t\t\tvar r = window.getSelection().getRangeAt(0);\n\t\t\tvar c = r.commonAncestorContainer, p;\n      r.deleteContents();\n      var p = c.splitText? $(c.splitText(r.startOffset)).parent() : $(c);\n      var n = $(\"<\"+p.get(0).tagName+\">\"), f;\n      p.contents().each(function(){\n      \tif(this === c){ return f = true }\n      \tif(!f){ return }\n      \tn.append(this);\n      });\n      p.after(n);\n      edit.select(n.get(0));\n      // make sure we re-save & sync each changed paragraph.\n      edit.save(p);\n      p.nextAll().each(function(){\n      \tedit.save(this);\n      });\n\t\t}).on('keyup.tmp', '[contenteditable]', function(eve){\n\t\t\t//$('#debug').val(doc.html());\n\t\t\tvar p = $(window.getSelection().anchorNode).closest('p'), tmp;\n\t\t\t(tmp = page[p.index()] || (page[p.index()] = {})).last = (+new Date) + 99;\n\t\t\tclearTimeout(tmp.to); tmp.to = setTimeout(function(){\n\t\t\tvar DBG = {s: +new Date};\n\t\t\tvar r = monotype(p);\n\t\t\tDBG.m = +new Date;\n\t\t\tvar html = p.html() || '';\n\t\t\tDBG.g = +new Date;\n\t\t\tif(!html && !p.prev().length && !p.next().length && !$('#page').html()){\n\t\t\t\tedit.init();\n\t\t\t}\n\t\t\tDBG.i = +new Date;\n\t\t\tvar safe = $.normalize(html);\n\t\t\tDBG.n = +new Date;\n\t\t\tp.html(safe);\n\t\t\tDBG.h = +new Date;\n\t\t\tr.restore();\n\t\t\tDBG.r = +new Date;\n\t\t\tedit.save(p);\n\t\t\tDBG.p = +new Date;\n\t\t\t//console.log(\"save:\", DBG.p - DBG.r, \"rest:\", DBG.r - DBG.h, \"html:\", DBG.h - DBG.n, \"norm:\", DBG.n - DBG.i, 'init:', DBG.i - DBG.g, 'grab:', DBG.g - DBG.m, 'mono:', DBG.m - DBG.s);\n\t\t},50)});\n\t},\n\tup: function(){\n\t\tconsole.log(\"UP\");\n\t\t$('[contenteditable=true]').off('.tmp');\n\t},\n\tinit: function(){\n\t\tvar edit = this;\n\t\tvar doc = $('#page').attr('contenteditable', 'true');\n\t\tif(!doc.text()){\n\t\t\tdoc.html('<p class=\"loud crack\"></p>');\n\t\t}\n\t\tedit.select(doc.children().first().get(0));\n\t},\n\tsave: function(p){\n\t\tp = $(p);\n\t\tvar i = p.index();// = Array.prototype.indexOf.call(parent.children, child);\n\t\tvar file = (location.hash||'').slice(1);\n\t\tvar data = (p.get(0)||{}).outerHTML||'';\n\t\t//data = $.normalize(data); // GOOD TO DO SECURITY ON SENDING SIDE TOO!!!\n\t\twindow.LOCK = true;\n\t\tgun.get('test/gun/docs/'+file).get('what').get(i).put(data);\n\t\twindow.LOCK = false;\n\t},\n\tselect: function(p){\n\t\tvar s = window.getSelection(),\n\t\tr = document.createRange();\n\t\tif(p.innerHTML){\n      r.setStart(p, 0);\n\t\t\tr.collapse(true);\n\t\t\ts.removeAllRanges();\n\t\t\ts.addRange(r);\n\t\t\treturn;\n\t\t}\n\t\tp.innerHTML = '\\u00a0';\n\t\tr.selectNodeContents(p);\n\t\ts.removeAllRanges();\n\t\ts.addRange(r);\n\t\tdocument.execCommand('delete', false, null);\n\t}\n});\n\n;(function(){\n\n\tmeta.edit({name: \"Design\", combo: ['D']});\n\tmeta.edit({name: \"Fill\", combo: ['D','F'], // TODO!\n\t\tuse: function(eve){},\n\t\ton: function(eve){\n\t\t\tvar on = meta.tap();\n\t\t\tmeta.ask('Color name, code, or URL?', function(color){\n\t\t\t\ton.css('background', color);\n\t\t\t}, true);\n\t\t},\n\t\tup: function(eve){}\n\t});\n\n\tmeta.edit({name: \"Add\", combo: ['D','A']});\n\tmeta.edit({name: \"Row\", combo: ['D','A', 'R'],\n    on: function(eve){\n\t\t\tmeta.tap().append('<div style=\"min-height: 9em; padding: 2%;\">');\n    }\n\t});\n\tmeta.edit({name: \"Columns\", combo: ['D','A','C'],\n    on: function(eve){\n\t\t\tvar on = meta.tap().addClass('center'), tmp, c;\n\t\t\tvar html = '<div class=\"unit col\" style=\"min-height: 9em; padding: 2%;\"></div>';\n\t\t\tif(!on.children('.col').length){ html += html }\n\t\t\tc = (tmp = on.append(html).children('.col')).length;\n\t\t\ttmp.each(function(){\n\t    \t$(this).css('width', (100/c)+'%');\n\t\t\t})\n    }\n\t});\n\tmeta.edit({name: \"Text\", combo: ['D','A','T'],\n    on: function(eve){\n    \tvar tag = $('<p>text</p>');\n\t\t\tmeta.tap().append(tag);\n\t\t\ttag.focus();\n    }\n\t});\n\tmeta.edit({name: \"Delete\", combo: ['D','A','D'],\n    on: function(eve){\n    \tmeta.tap().remove();\n    }\n\t});\n\n\tmeta.edit({name: \"Turn\", combo: ['D','T']});\n\tmeta.edit({name: \"Size\", combo: ['D','S']});\n\tmeta.edit({name: \"X\", combo: ['D','S','X'],\n\t\ton: function(eve){\n\t\t\tvar on = this.a = meta.tap().addClass('meta-on'), was = on.width();\n\t\t\t$(document).on('mousemove.tmp', function(eve){\n\t\t\t\tvar be = was + ((eve.pageX||0) - was);\n\t\t\t\ton.css({'max-width': be, width: '100%'});\n\t\t\t});\n\t\t\tmeta.ask('Width in px, %, or other unit?', function(w){\n\t\t\t\tif(!w){ return }\n\t\t\t\ton.css({'max-width': w, width: '100%'});\n\t\t\t}, true);\n\t\t}, up: function(){\n\t\t\t$(document).off('mousemove.tmp');\n\t\t\tthis.a.removeClass('meta-on');\n\t\t}\n\t});\n\tmeta.edit({name: \"Y\", combo: ['D','S','Y'],\n\t\t//on: function(eve){ console.log('on Y') },\n\t\ton: function(eve){ console.log('use Y')\n\t\t\tvar on = this.a = meta.tap().addClass('meta-on'), was = on.height();\n\t\t\t$(document).on('mousemove.tmp', function(eve){\n\t\t\t\tvar be = was + ((eve.pageY||0) - was);\n\t\t\t\ton.css({'min-height': be});\n\t\t\t})\n\t\t}, up: function(){ console.log('up Y')\n\t\t\t$(document).off('mousemove.tmp');\n\t\t\tthis.a.removeClass('meta-on');\n\t\t}\n\t});\n}());\n\n;(function(){\n\tvar logic = {};\n\n\tmeta.edit({name: \"Logic\", combo: ['L']});\n\n\tmeta.edit({name: \"Symbol\", combo: ['L','S'],\n    on: function(eve){\n    \tconsole.log(1);\n    }\n\t});\n\tmeta.edit({name: \"Action\", combo: ['L','A'],\n    on: function(eve){\n    \tconsole.log(2);\n    }\n\t});\n\tmeta.edit({name: \"Data\", combo: ['L','D'],\n    on: function(eve){\n    \tconsole.log(3);\n    }\n\t});\n}());\n\n;(function(){\n\tvar song = {};\n\t// TODO:\n\t// 1. Manually OR automatically load music.js API, dependencies, and modules. - FINE for now\n\t// 2. only export music API, not meta, not dom, not mouselock system, not UI/html, etc. better module isolation and export.\n\t// 3. `var wave = Wave('a').play()` // also on `Music.now`\n\t// defaults... instrument: pure tones, volume curve: |\\_ , speed curve: 0.5\n\t// 4. `wave.blur(0.5).itch(0.5);`\n\t// 5. wave.long(2); // how long in seconds each note plays, optionally: wave.pace(60) is bpm\n\t// 6. wave.loud(0.5); // 0% to 100% volume loudness of device output.\n\t// 7. wave.vary(0.5); // slows down or speeds up wiggle per harmonic\n\t// 8:\n\t// wave structure, does ToneJS allow us to change the sine wave smoothness/type continuously or is it a pre-fixed type?\n\t// wave structure: /\\/\\/, |_|, /|/, \\|\\| do some research with ToneJS whether these are dynamic or fixed\n\t// wave.itch(); // changes the shape of the wiggle from smooth sine to square or triangle\n\t// wave.blur(220hz); // blur may not apply/work on pure notes other than filtering them.\n\n\tmeta.edit({name: \"Music\", combo: ['M']});\n\n\tmeta.edit({name: \"Play\", combo: ['M','P'],\n    on: function(eve){\n    \t// TODO: We still need to add to meta API ability to change name.\n    \tif(song.play){\n\t\t\t\tmusic.stop();\n\t\t\t\tsong.play = false;\n\t\t\t\treturn;\n    \t}\n    \tsong.play = true;\n    \tmusic.stop();\n    \tsetTimeout(function(){\n\t\t\t\tsong.now = wave($('#page').text()).play();\n    \t},250);\n    }\n\t});\n\n\tmeta.edit({name: \"Blur\", combo: ['M','B'],\n    on: function(eve){\n\t\t\t$(document).on('mousemove.tmp', function(eve){\n\t\t\t\tvar x = eve.pageX;\n\t\t\t\tsong.now.loud(x/$('body').innerWidth());\n\t\t\t});\n    },\n    up: function(){\n    \t$(document).off('.tmp');\n  \t}\n\t});\n\n\t$(document).on('keydown', function(eve){\n\t\tif(eve.which === music.which){ return }\n\t\tmusic.play(String.fromCharCode(music.which = eve.which));\n\t});\n\n}());\n;(function(){\n/*\n\tEdit\n\t\tBold\n\t\tItalic\n\t\tLink\n\t\t?\n\t\t\tLeft\n\t\t\tMiddle\n\t\t\tRight\n\t\t\tJustify\n\t\t?\n\t\t\tSmall\n\t\t\tNormal\n\t\t\tHeader\n\t\t\tTitle\n\tDesign\n\t\tAdd\n\t\t\tRow\n\t\t\tColumn\n\t\t\tText\n\t\t\tDelete\n\t\tTurn\n\t\tGrab\n\t\tSize\n\t\t\tX\n\t\t\tY\n\t\tFill\n\tLogic\n\t\tSymbol\n\t\tAction\n\t\tData\n*/\n/*\n\n*/\n}());\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/express.js",
    "content": "console.log(\"If module not found, install express globally `npm i express -g`!\");\r\nvar port    = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8765;\r\nvar express = require('express');\r\nvar Gun     = require('..');\r\nrequire('../axe');\r\n\r\nvar app    = express();\r\napp.use(Gun.serve);\r\napp.use(express.static(__dirname));\r\n\r\nvar server = app.listen(port);\r\nvar gun = Gun({\tfile: 'data', web: server });\r\n\r\nglobal.Gun = Gun; /// make global to `node --inspect` - debug only\r\nglobal.gun = gun; /// make global to `node --inspect` - debug only\r\n\r\nconsole.log('Server started on port ' + port + ' with /gun');\r\n"
  },
  {
    "path": "examples/game/furball.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<!-- always start with these two lines to set a clean baseline for different devices -->\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../style.css\">\n<!-- link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/gun/examples/style.css\" -->\n<script src=\"https://cdn.jsdelivr.net/npm/gun/examples/jquery.js\"></script>\n\n<title>Furball</title>\n</head>\n<body class=\"black whitet\">\n<style>\n\t/*\n\t\tChoose white text on a black background so you can add color in.\n\t\tPick your favorite font and choose a font size.\n\t*/\n\t@import url('https://fonts.googleapis.com/css?family=Mali');\n\thtml, body {\n\t\tfont-family: \"Mali\", sans-serif;\n\t}\n\n\t.huef {\n\t  background: #4D79D8;\n\t  -webkit-animation: huef 9s infinite;\n\t  animation: huef 9s infinite;\n\t} @keyframes huef {\n\t  0%   {background-color: #4D79D8;}\n\t  25%  {background-color: #33cc33;}\n\t  50%  {background-color: #f2b919;}\n\t  75%  {background-color: #ea3224;}\n\t  100% {background-color: #4D79D8;}\n\t} @-webkit-keyframes huef {\n\t  0%   {background-color: #4D79D8;}\n\t  25%  {background-color: #33cc33;}\n\t  50%  {background-color: #f2b919;}\n\t  75%  {background-color: #ea3224;}\n\t  100% {background-color: #4D79D8;}\n\t}\n\n\tbutton, input {\n\t\tpadding: 1em;\n\t\tbackground: transparent;\n\t\tborder: 1px solid white;\n\t\tborder-radius: 1.5em;\n\t\tcolor: white;\n\t\tmargin: 0.5em;\n\t\tmargin-bottom: 0;\n\t\tcursor: pointer;\n\t}\n\tbutton:hover, input:hover {\n\t\tbackground: white;\n\t\tcolor: black;\n\t\ttransform: scale(1.1);\n\t}\n\n\t.air { padding-top: 9%; }\n\t.yak button { font-size: 80%; }\n\n\t.wag {\n\t  -webkit-animation: wag 3s infinite;\n\t  animation: wag 3s infinite;\n\t} @keyframes wag {\n\t  0%   {transform: rotate(0deg);}\n\t  50%  {transform: rotate(-1deg);}\n\t  100% {transform: rotate(0deg);}\n\t}\n\n\t@keyframes print {\n\t  0% { overflow: hidden; height: 0vh; }\n\t  99% { overflow: hidden; height: 100vh; }\n\t  100% { overflow: visible; height: auto; }\n\t}\n\tinput {\n\t\toutline: none;\n\t}\n\t</style>\n</style>\n\n<!-- for educational sites, consider starting with a nice full screen welcome message -->\n<div class=\"home hold full huef center air\">\n\t<div class=\"focus row\">\n\t\t<p><i>Neon ERA presents</i></p>\n\t\t<p class=\"shout wag\">Furball Forces</p>\n\t\t<!-- just like in real life, say who you are and give a concise reason why you add value to someone's life and then make a call to action, if they want to learn more they can always scroll to learn more -->\n\t\t<div>\n\t\t\t<!-- a class=\"unit hold\" href=\"#fullscreen\"><button>WATCH TRAILER</button></a -->\n\t\t\t<a class=\"unit yak\" href=\"#choose\"><button>PLAY GAME</button></a>\n\t\t</div>\n\t</div>\n\t<div class=\"focus center row leak\">\n\t\t<!-- just like in real life, looking pretty attracts attention, so show off and look glamorous! -->\n\t\t<img class=\"unit blink\" src=\"file:///Users/mark/Pictures/supercatdog.png\" style=\"min-width: 10em; width: 80%;\">\n\t</div>\n\t<script>location.hash = ''</script>\n\t<script src=\"https://cdn.jsdelivr.net/npm/gun/lib/fun.js\"></script>\n\t<script>;(function(){\n\t\t// OPTIONAL MUSIC:\n\t\t$('.home button').on('click', function(){\n\t\t\tif(window.screen.height > window.screen.width){ return }\n\t\t\t$('body').append(\"<div id='audio' onclick='$(this).remove();'><iframe width='0' height='0' src='https://www.youtube-nocookie.com/embed/LLPoZGX0qZk?autoplay=1' frameborder='0'></iframe></div>\");\n\t\t})\n\t}());\n\t</script>\n\t<style>#audio { padding: 0.5em; position: fixed; bottom: 0; left: 0; } #audio:before { content: '\\25BA'; } #audio:hover:before { content: '\\25FC'; }</style>\n</div>\n\n<div id=\"choose\" class=\"hold full hue4 center air\">\n\t<div class=\"focus row\">\n\t\t<p class=\"shout wag fur\">Choose Team:</p>\n\t\t<div>\n\t\t\t<a class=\"unit yak\" href=\"#automecha\"><button style=\"background: white; color: black;\">#AutoMecha</button></a>\n\t\t\t<a class=\"unit yak\" href=\"#cyberninjas\"><button style=\"background: black; color: white; border-color: black;\">#CyberNinjas</button></a>\n\t\t</div>\n\t</div>\n\t<div class=\"focus center row leak\">\n\t\t<img class=\"unit blink\" src=\"file:///Users/mark/Pictures/supercatdog.png\" style=\"transform: scaleX(-1); filter: invert(1); min-width: 10em; width: 80%;\">\n\t</div>\n</div>\n\n<div id=\"cyberninjas\" class=\"hold full black\">\n\t<style>\n\t#cyberninjas:target .story {\n\t  animation: print 3s steps(50, end);\n\t}\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Episode 1: Waking</p>\n\t\t<p>\"How long until they're online?\"</p>\n\t\t<p>\"We're copying the soul files, almost done.\"</p>\n\t\t<p>\"Monsters are on the bridge, we do not have time!\"</p>\n\t\t<p>\"The new body is printing now, it'll be able to outrun them all, just hold on.\"</p>\n\t\t<p>\"It won't know where to run! We're risking ruining the whole resistance, I need to talk to it now.\"</p>\n\t\t<p>\"95% done.\" The voice behind the glass turns to the soul in the body, \"My cub, can you hear me?\"</p>\n\t\t<p>...</p>\n\t\t<a class=\"unit yak\" href=\"#cyberninjas2\"><button>Reply \"Yes, Mom?\"</button></a>\n\t</div>\n\t<script>\n\t;(function(){\n\t\t$('#cyberninjas a').on('click', function(){\n\t\t\t$('#hud .life').removeClass('down');\n\t\t});\n\t}());\n\t</script>\n</div>\n\n<div id=\"cyberninjas2\" class=\"hold full red\">\n\t<style>\n\t#cyberninjas2:target .story {\n\t  animation: print 3s steps(50, end);\n\t}\n\t\n\t#hud {\n\t\topacity: 0.4;\n\t\tfont-family: 'Audiowide', cursive;\n\t\tz-index: 999999999999;\n\t\ttransition: all 3s;\n\t}\n\t#hud .life {\n\t\tposition: fixed;\n\t\tleft: 50%;\n\t\tbottom: 0px;\n\t\tpadding: 0.25em 1em 0.1em;\n\t\tborder-radius: 0.5em 0.5em 0 0;\n\t\ttransform: translateX(-50%);\n\t\tbackground: black;\n\t\ttext-shadow: 0em -0.125em 0.75em white;\n\t}\n\t#hud .score {\n\t\tposition: fixed;\n\t\tleft: 50%;\n\t\ttop: 0px;\n\t\tpadding: 0.1em 1em 0.25em;\n\t\tborder-radius: 0 0 0.5em 0.5em;\n\t\ttransform: translateX(-50%);\n\t\tbackground: black;\n\t\ttext-shadow: 0em 0.1em 0.75em white;\n\t}\n\t#hud .down {\n\t\tbottom: -2em !important;\n\t}\n\t#hud .up {\n\t\ttop: -2em !important;\n\t}\n\t</style>\n\t<div id=\"hud\">\n\t\t<div class=\"score shade up\">\n\t\t\tSCORE: <span id=\"hudscore\">0</span>%\n\t\t</div>\n\t\t<div class=\"life shade down\">\n\t\t\tLIFE: <span id=\"hudlife\">50</span>%\n\t\t</div>\n\t</div>\n\t<div class=\"story pad\">\n\t\t<p>A fire explodes in the room behind the glass as an AutoMecha blows the door open.</p>\n\t\t<p>The floor shakes and the bed crashes through the wall, flying out of the building.</p>\n\t\t<p class=\"center\">\"Mom!!!\"</p>\n\t\t<p>There is a total free fall from 10 levels up, water down below.</p>\n\t\t<p>...</p>\n\t\t<a class=\"unit yak\" href=\"#cyberninjas3\"><button>Dive or Die</button></a>\n\t</div>\n\t<script>\n\t;(function(){\n\t\t$('#cyberninjas2 a').on('click', function(){\n\t\t\t$('#hudlife').text($('#hudlife').data().is = 50);\n\t\t});\n\t}());\n\t</script>\n</div>\n\n<div id=\"cyberninjas3\" class=\"hold full blue\">\n\t<style>\n\t@import url('https://fonts.googleapis.com/css?family=Audiowide');\n\n\t#cyberninjas3:target .story {\n\t  animation: print 3s steps(50, end);\n\t}\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p>The water splashes, swelling and swirling all around.</p>\n\t\t<p>...</p>\n\t\t<p class=\"center\">Rapidly tap to swim up to air:</p>\n\t\t<a class=\"unit yak\"><button>Swim</button></a>\n\t</div>\n\t<script>\n\t;(function(){\n\t\tvar go, life = $('#hudlife').data();\n\t\t$('#cyberninjas3 a').on('click', function(){\n\t\t\t$('#hudlife').text(life.is += 5);\n\t\t\tif(100 <= life.is){\n\t\t\t\tlocation.hash = 'cyberninjas4';\n\t\t\t\tclearInterval(go);\n\t\t\t\tgo = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(go){ return }\n\t\t\tgo = setInterval(function(){\n\t\t\t\tif(0 >= life.is){\n\t\t\t\t\tlocation.hash = 'cyberninjas2';\n\t\t\t\t\t$('#hudlife').text(life.is = 50);\n\t\t\t\t\tclearInterval(go);\n\t\t\t\t\tgo = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$('#hudlife').text(life.is -= 5);\n\t\t\t}, 1000); // 1 second\n\t\t});\n\t}());\n\t</script>\n</div>\n\n<div id=\"cyberninjas4\" class=\"hold full black\">\n\t<style>\n\t#cyberninjas4:target .story {\n\t  animation: print 3s steps(50, end);\n\t}\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Episode 2: Who Am I?</p>\n\t\t<p>\"Grab on!\" A voice calls out from the darkness.</p>\n\t\t<p>A life vest hits the water and floats within arm's distance.</p>\n\t\t<p>The shivering body is pulled up onto the boat.</p>\n\t\t<p>\"Wow, you're heavier than you look. Are you OK? What's your name?\"</p>\n\t\t<p>...</p>\n\t\t<p class=\"center\">Write your reply & hit enter:</p>\n\t\t<form class=\"center\">\n\t\t\t<input class=\"loud\" style=\"width: 60%;\">\n\t\t</form>\n\t</div>\n\t<script>\n\t;(function(){\n\t\t$('form').on('submit', function(eve){ eve.preventDefault() });\n\t\t$('#cyberninjas4').on('submit', function(){\n\t\t\tvar name = $(this).find('input').val();\n\t\t\tif(!name.length){ return }\n\t\t\t$('.story-name').text(' '+(window.NAME = name));\n\t\t\t$('#hud .score').removeClass('up');\n\t\t\tlocation.hash = 'cyberninjas5';\n\t\t})\n\t}());\n\t</script>\n</div>\n\n<div id=\"cyberninjas5\" class=\"hold full green\">\n\t<style>\n\t#cyberninjas5:target .story {\n\t  animation: print 3s steps(50, end);\n\t}\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p>\"Well<span class=\"story-name\"></span>, it's a miracle you did not die in the building explosion or from that fall.\"</p>\n\t\t<p>\"What is going on? What happened?\"</p>\n\t\t<p>\"You can't remember? Your brain must be knocked up pretty hard.\"</p>\n\t\t<p>\"No, I was mid copy into this body and now my memories are glitching.\"</p>\n\t\t<p>\"Woah, you're one of those pro elite AREION revolutionaries? All flesh & blood! Dense, too. I would've assumed they were stealing AutoMecha tech for that instead.\"</p>\n\t\t<p>\"I was about to be told vital data for the resistance, but then they blew up the build--\"</p>\n\t\t<p>...</p>\n\t\t<p>\"Hey, what's the matter?\"</p>\n\t\t<p>\"My mom. She was in there. I need to go back. Please, help me and tell me everything you know.\"</p>\n\t\t<p>\"I'm so sorry. I can only get so close with the boat, you're gonna have to jump over a lot of broken bits. You ready?\"</p>\n\t\t<p>...</p>\n\t\t<a class=\"unit yak\" href=\"#cyberninjas6\"><button>GO!</button></a>\n\t</div>\n</div>\n\n<div id=\"cyberninjas6\" class=\"hold full green\">\n\t<style>\n\t#cyberninjas6:target .story {\n\t  animation: print 3s steps(50, end);\n\t}\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"center\">... to be continued ...</p>\n\t\t<div id=\"player\" style=\"position: fixed; width: 1em; height: 1em; background: white; left: 50%; top: 50%; border-radius: 100%;\"></div>\n\t\t<!-- jumping game ? like offline dinosaur ? -->\n\t</div>\n\t<script src=\"../../../gun/lib/meta.js\"></script>\n\t<script>\n\t;(function(){\n\t\tvar p = $('#player');\n\t\tp.x = 50;\n\t\tp.y = 50;\n\t\tmeta.edit({\n\t\t\tname: \"Up\",\n\t\t\tcombo: [\"W\"],\n\t\t\ton: function(){\n\t\t\t\tconsole.log(\"up\");\n\t\t\t\tthis.to = this.to || setInterval(this.on, 100);\n\t\t\t\t$(\"html, body\").stop().animate({ scrollTop: $(window).scrollTop()-100 }, 100);\n\t\t\t\tp.css({top: --p.y +'%'});\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){ clearTimeout(this.to); this.to = 0 }\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Left\",\n\t\t\tcombo: [\"A\"],\n\t\t\ton: function(){ \n\t\t\t\tconsole.log(\"left\");\n\t\t\t\tthis.to = this.to || setInterval(this.on, 100);\n\t\t\t\tp.css({left: --p.x +'%'});\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){ clearTimeout(this.to); this.to = 0 }\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Down\",\n\t\t\tcombo: [\"S\"],\n\t\t\ton: function on(){\n\t\t\t\tconsole.log(\"down\");\n\t\t\t\tthis.to = this.to || setInterval(this.on, 100);\n\t\t\t\t$(\"html, body\").stop().animate({ scrollTop: $(window).scrollTop()+100 }, 100);\n\t\t\t\tp.css({top: ++p.y +'%'});\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){ clearTimeout(this.to); this.to = 0 }\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Right\",\n\t\t\tcombo: [\"D\"],\n\t\t\ton: function(){\n\t\t\t\tconsole.log(\"right\");\n\t\t\t\tthis.to = this.to || setInterval(this.on, 100);\n\t\t\t\tp.css({left: ++p.x +'%'});\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){ clearTimeout(this.to); this.to = 0 }\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Jump\",\n\t\t\tcombo: [32],\n\t\t\ton: function(){ console.log(\"jump\") },\n\t\t\tuse: function(){},\n\t\t\tup: function(){}\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Crouch\",\n\t\t\tcombo: [16],\n\t\t\ton: function(){ console.log(\"crouch\") },\n\t\t\tuse: function(){},\n\t\t\tup: function(){}\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Use\",\n\t\t\tcombo: [\"E\"],\n\t\t\ton: function(){ console.log(\"use\") },\n\t\t\tuse: function(){},\n\t\t\tup: function(){}\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Fire\",\n\t\t\tcombo: [\"F\"],\n\t\t\ton: function(){ console.log(\"fire\") },\n\t\t\tuse: function(){},\n\t\t\tup: function(){}\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Switch\",\n\t\t\tcombo: [9],\n\t\t\ton: function(){ console.log(\"Switch\") },\n\t\t\tuse: function(){},\n\t\t\tup: function(){}\n\t\t});\n\t\twindow.requestAnimationFrame = window.requestAnimationFrame || setTimeout;\n\t\twindow.requestAnimationFrame(function frame(){\n\t\t\twindow.requestAnimationFrame(frame, 16);\n\n\t\t}, 16);\n\t}());\n\t</script>\n</div>\n\n<div id=\"automecha\" class=\"hold full white blackt\">\n\t<style>\n\t#automecha:target .story {\n\t  animation: print 3s steps(50, end);\n\t}\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Episode 1: Training</p>\n\t\t<p>...</p>\n\t</div>\n</div>\n\n\n<div class=\"hold black center\">\n\t<div class=\"pad\">\n\t\t<div class=\"left\">\n\t\t\t<p class=\"loud\">For <i>You</i>,</p>\n\t\t\t<p>Crafted with love, <span class=\"redt\">♥</span> by ERA.</p>\n\t\t</div>\n\t</div>\n\t<div>\n\t\t<img src=\"https://era.eco/media/world.png\" class=\"row\">\n\t</div>\n</div>\n\n</body>\n</html>"
  },
  {
    "path": "examples/game/nts.html",
    "content": "<html>\n\t<head>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t</head>\n\t<body style=\"text-align: center;\">\n\t\t<h1 id=\"when\" style=\"font-size: 7vw; margin-top: 43vh; font-family: monospace;\"></h1>\n\t</body>\n\t<script src=\"/gun.js\"></script>\n\t<script src=\"/gun/nts.js\"></script>\n\t<script>\n\t\twindow.gun = Gun(location.origin+'/gun');\n\t\trequestAnimationFrame(function now(){\n\t\t\trequestAnimationFrame(now);\n\t\t\tvar time = new Date(Gun.state());\n\t\t\tvar print = time.toLocaleString() +' '+ (time.getMilliseconds()/1000).toFixed(3).slice(1);\n\t\t\twhen.innerHTML = print;\n\t\t});\n\t</script>\n</html>\n"
  },
  {
    "path": "examples/game/space.html",
    "content": "<html>\n\t<head>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t</head>\n\t<div id=\"area\">\n\t\t<div id=\"me\" class=\"ship\">\n\t\t\t<div class=\"laser\"></div>\n\t\t</div>\n\t</div>\n\t<p id=\"debug\" style=\"position: fixed; bottom: 0px; color: white; height: 1em;\"></p>\n\t<script src=\"../jquery.js\"></script>\n\t<script src=\"../../../gun/gun.js\"></script>\n\t<!-- script src=\"../../../gun/nts.js\"></script -->\n\t<script src=\"../../../gun/lib/webrtc.js\"></script>\n\t<script>\n\t\t// Thanks to https://github.com/dmcinnes/HTML5-Asteroids\n\t\t//var gun = Gun();\n\t\tvar gun = GUN(location.origin + '/gun');\n\t\tvar game = {gun: gun.get('example/game/space'), area: {}, ships: {}};\n\t\tgame.keys = {38: 'up', 37: 'left', 39: 'right', 40: 'down', 32: 'space'};\n\t\t$(document).on('keydown', function(e){\n\t\t\t//e.preventDefault();\n\t\t\tvar key = e.keyCode, me;\n\t\t\tgame.keys[key = game.keys[key]] = true;\n\t\t\tif(!(me = game.me)){ return }\n\t\t\tme.last = game.now;\n\t\t\tif('space' === key){ game.shoot(game.me) }\n\t\t});\n\t\t$(document).on('keyup', function(e){\n\t\t\t//e.preventDefault();\n\t\t\tgame.sync();\n\t\t\tgame.keys[game.keys[e.keyCode]] = false;\n\t\t});\n\t\tgame.shoot = function(ship, when){\n\t\t\tif(!ship || ship.l){ return }\n\t\t\tif(!when && ship.gun && ship.data){\n\t\t\t\tship.data.l = game.now;\n\t\t\t\tgame.sync(true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(when + 250 < game.now){ return }\n\t\t\tship.l = true;\n\t\t\tship.$.children('.laser').show();\n\t\t\tsetTimeout(function(){\n\t\t\t\tship.$.children('.laser').hide();\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tship.l = false;\n\t\t\t\t}, 250);\n\t\t\t}, 250 - (game.now - when));\n\t\t}\n\t\tgame.ship = function(d, el){\n\t\t\tif(!d){ // spawn our ship\n\t\t\t\tvar id = String.random(1, 'abcdefghijklmno');\n\t\t\t\tgame.me = game.ships[id] = {data: d = {id: id, t: game.now}};\n\t\t\t\tgame.me.gun = game.gun.get('players').get(d.id).put(d);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(!d.id){ return }\n\t\t  if(!game.ships[d.id]){\n\t\t\t\tgame.ships[d.id] = {};\n\t\t  }\n\t\t  var s = game.ships[d.id];\n\t\t\ts.t = d.t || (d.t = 0);\n\t\t  s.x = d.x || (d.x = game.area.x * Math.random());\n\t\t\ts.y = d.y || (d.y = game.area.y * Math.random());\n\t\t\ts.r = d.r || (d.r = 0);\n\t\t\ts.vx = d.vx || (d.vx = 0);\n\t\t\ts.vy = d.vy || (d.vy = 0);\n\t\t\ts.vr = d.vr || (d.vr = 0);\n\t\t\ts.ax = s.ax || 0;\n\t\t\ts.ay = s.ay || 0;\n\t\t\ts.ar = s.ar || 0;\n\t\t  s.data = d;\n\t\t\ts.$ = s.$ || (s.gun? ($('#me'))\n\t\t\t: $('#me').clone(true).attr('id', d.id).appendTo('#area'));\n\t\t\tif(!s.l){\n\t\t\t\tgame.shoot(s, d.l);\n\t\t\t}\n\t\t\ts.frame = s.frame || function(t, now){\n\t\t\t\tif(s.gun){\n\t\t\t\t\ts.fly(t, now);\n\t\t\t\t}\n\t\t\t\tif(s.calc(t, now)){ return }\n\t\t\t\ts.draw();\n\t\t\t}\n\t\t\tvar keys = game.keys;\n\t\t\tvar area = game.area;\n\t\t\ts.fly = s.fly || function(t, now){\n\t\t\t\tif(keys.left){\n\t\t      s.r += -6;\n\t\t    } else\n\t\t    if(keys.right) {\n\t\t      s.r += 6;\n\t\t    }\n\t\t    if(keys.up){\n\t\t      var rad = ((s.r - 90) * Math.PI)/180;\n\t\t      s.ax = 0.0001 * Math.cos(rad);\n\t\t      s.ay = 0.0001 * Math.sin(rad);\n\t\t    } else {\n\t\t      s.ax = 0;\n\t\t      s.ay = 0;\n\t\t    }\n\n\t\t    Object.keys(game.ships).forEach(function(key, ship){\n\t\t    \tship = game.ships[key];\n\t\t    \tif(ship.gun){ return }\n\t\t    \tif(!ship.l){ return }\n\t\t    \tif(ship.x-50 <= s.x && s.x <= ship.x+50\n\t\t    \t&& ship.y-50 <= s.y && s.y <= ship.y+50){\n\t\t    \t\ts.data.t = -1;\n\t\t    \t\tgame.sync(true);\n\t\t    \t\ts.boom = true;\n\t\t    \t}\n\t\t    });\n\n\t\t    s.vx += s.ax * t;\n\t\t    s.x += s.vx * t;\n\t\t    s.vy += s.ay * t;\n\t\t    s.y += s.vy * t;\n\t\t    var data = s.data;\n\t\t    if(!data){ return }\n\t\t    data.r = s.r;\n\t\t    data.vx = s.vx;\n\t\t    data.x = s.x;\n\t\t    data.vy = s.vy;\n\t\t    data.y = s.y;\n\t\t    if(data.t < 0){ return }\n\t\t    data.t = now;\n\t\t    s.t = data.t;\n\t\t\t}\n\t\t\ts.calc = s.calc || function(t, now){\n\t\t    var d = s.data;\n\t\t    var dt = (now - d.t) || 0;\n\t\t    if(dt > 30 * 1000){\n\t\t    \tdelete game.ships[d.id];\n\t\t    \ts.$.remove();\n\t\t    \treturn true;\n\t\t    }\n\t\t    if(!d){ return }\n\t\t    var speed = Math.sqrt(d.vx * d.vx + d.vy * d.vy);\n\t\t    if(speed > 0.15){\n\t\t    \ts.vy = d.vy = d.vy / speed * 0.15;\n\t\t    \ts.vx = d.vx = d.vx / speed * 0.15;\n\t\t    }\n\t\t    s.x = d.x + d.vx * dt;\n\t\t    s.y = d.y + d.vy * dt;\n\n\t\t    s.x = s.x % area.x;\n\t\t    if(s.x < 0){\n\t\t      s.x += area.x;\n\t\t    }\n\t\t    s.y = s.y % area.y;\n\t\t    if(s.y < 0){\n\t\t      s.y += area.y;\n\t\t    }\n\t\t\t}\n\t\t\ts.draw = s.draw || function(){\n\t\t    s.css = 'rotate('+s.r+'deg)';\n\t\t    s.$.css({left: s.x, top: s.y, transform: s.css});\n\t\t  }\n\t\t\treturn s;\n\t\t}\n\t\tgame.sync = function(shoot){\n\t\t\tvar me = game.me;\n\t\t\tif(!me || me.boom){ return }\n\t\t\tvar keys = game.keys;\n\t\t\tif(shoot || keys.up || keys.right || keys.left || keys.down){\n\t\t\t\tvar data = {};\n\t\t\t\tObject.keys(me.data).forEach(function(k){ data[k] = me.data[k] }); // 1 layer clone.\n\t\t\t\tdata.x = data.x / game.area.x;\n\t\t\t\tdata.y = data.y / game.area.y;\n\t\t\t\tme.gun.put(data);\n\t\t\t}\n\t\t}\n\t\tgame.frame = window.requestAnimationFrame || setTimeout;\n\t\tgame.resize = function(){\n\t\t\tgame.area.x = $('#area').innerWidth();\n\t\t\tgame.area.y = $('#area').innerHeight();\n\t\t}\n\t\t$(window).on('resize', game.resize);\n\t\tgame.start = function(){\n\t\t\tgame.now = Gun.state();\n\t\t\tgame.resize();\n\t\t\tgame.ship();\n\t\t\tgame.gun.get('players').map().on(function(data, id){\n\t\t\t\tdata = JSON.parse(JSON.stringify(data)); // clone object, this is bad perf tho.\n\t\t\t\tdata.x = data.x * game.area.x;\n\t\t\t\tdata.y = data.y * game.area.y;\n\t\t\t\tdata.id = data.id || id;\n\t\t\t\tgame.ship(data);\n\t\t\t});\n\t\t\tvar frame = game.frame, ships = game.ships;\n\t\t\tvar last = game.now, now, diff, delta;\n\t\t\tsetInterval(game.sync, 99);\n\t\t\tframe(function next(t){\n\t\t\t\tframe(next, 1000/60);\n\t\t    now = game.now = Gun.state();\n\t\t    diff = now - last;\n\t\t    last = now;\n\t\t    Object.keys(ships).forEach(function(key, ship){\n\t\t    \tship = ships[key];\n\t\t    \tif(!ship.frame){ return }\n\t\t\t\t\tship.frame(diff, now);\n\t\t    });\n\t\t\t}, 1000/60);\n\t\t}\n\t\t$(function(){\n\t\t\tgame.start();\n\t\t});\n\n\t\t// test WebRTC\n\t\tgun.on('hi', function(peer){\n\t\t\tconsole.log(\"hi!\", peer);\n\t\t\tif(peer.url){ return }\n\t\t\tvar peers = gun.back('opt.peers');\n\t\t\tObject.keys(peers).forEach(function(id, peer){\n\t\t\t\tpeer = peers[id];\n\t\t\t\tif(!peer.url || !peer.wire){ return }\n\t\t\t\tpeer.wire._send = peer.wire.send;\n\t\t\t\tpeer.wire.send = send;\n\t\t\t\tvar tmp = 'GOBBLE GOBBLE: Not sending any non-WebRTC messages to ' + peer.url;\n\t\t\t\tconsole.log(tmp);\n\t\t\t\t$('#debug').text(tmp);\n\t\t\t});\n\t\t});\n\t\tfunction send(raw){\n\t\t\tif(!raw){ return }\n\t\t\tif(raw.indexOf('rtc') >= 0){\n\t\t\t\tif(!this._send){ return }\n\t\t\t\treturn this._send(raw);\n\t\t\t}\n\t\t}\n\t</script>\n\t<style>\n\t\thtml, body {\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\t\t\tbackground: #111;\n\t\t}\n\t\thtml, body, div {\n\t\t\tposition: relative;\n\t\t}\n\t\t#area {\n\t\t  width: 95%;\n\t\t  width: 1024px;\n\t\t  height: 768px;\n\t\t  margin: 0 auto;\n\t\t  background: black;\n\t\t  overflow: hidden;\n\t\t}\n\t\t.ship {\n\t\t\tposition: absolute;\n\t\t\twidth: 0px;\n\t\t\theight: 0px;\n\t\t\tborder-left: 5px solid transparent;\n\t\t\tborder-right: 5px solid transparent;\n\t\t\tborder-bottom: 15px solid red;\n\t\t\ttransform-origin: 50% 50%;\n\t\t\tcolor: white;\n\t\t}\n\t\t#me {\n\t\t\tborder-bottom: 15px solid limegreen;\n\t\t}\n\t\t.boom {\n\t\t\tborder: 1vmax dotted yellow;\n\t\t\tborder-bottom: 1vmax dotted yellow;\n\t\t\theight: 5vmax;\n\t\t\twidth: 1vmax;\n\t\t}\n\t\t.laser {\n\t\t\tdisplay: none;\n\t\t\tposition: relative;\n\t\t\tbackground: transparent;\n\t\t\tborder: 2px dotted yellow;\n\t\t\theight: 100px;\n\t\t\twidth: 100px;\n\t\t\ttop: -50px;\n\t\t\tleft: -50px;\n\t\t}\n\t</style>\n</html>\n"
  },
  {
    "path": "examples/game/win.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<!-- always start with these two lines to set a clean baseline for different devices -->\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../style.css\">\n<!-- link rel=\"stylesheet\" type=\"text/css\" href=\"https://cdn.jsdelivr.net/npm/gun/examples/style.css\" -->\n<script src=\"https://cdn.jsdelivr.net/npm/gun/examples/jquery.js\"></script>\n\n<title>Win</title>\n</head>\n<body class=\"black whitet\">\n<style>\n\t/*\n\t\tChoose white text on a black background so you can add color in.\n\t\tPick your favorite font and choose a font size.\n\t*/\n\t@import url('https://fonts.googleapis.com/css?family=Montserrat');\n\thtml, body {\n\t\tfont-family: \"Montserrat\", sans-serif;\n\t}\n\n\tbutton, input {\n\t\tpadding: 1em;\n\t\tbackground: transparent;\n\t\tborder: 1px solid white;\n\t\tborder-radius: 1.5em;\n\t\tcolor: white;\n\t\tmargin: 0.5em;\n\t\tmargin-bottom: 0;\n\t\tcursor: pointer;\n\t}\n\tbutton:hover, input:hover {\n\t\tbackground: white;\n\t\tcolor: black;\n\t\ttransform: scale(1.1);\n\t}\n\n\t.air { padding-top: 9%; }\n\t.yak button { font-size: 80%; }\n\t.wag {\n\t  -webkit-animation: wag 3s infinite;\n\t  animation: wag 3s infinite;\n\t} @keyframes wag {\n\t  0%   {transform: rotate(0deg);}\n\t  50%  {transform: rotate(-1deg);}\n\t  100% {transform: rotate(0deg);}\n\t}\n\t</style>\n</style>\n\n<!-- for educational sites, consider starting with a nice full screen welcome message -->\n<div class=\"home hold full huef center air\">\n\t<div class=\"focus row\">\n\t\t<p><i>how to</i></p>\n\t\t<p class=\"shout wag\">Win at Life!</p>\n\t\t<p><i>success, fame, power.</i></p>\n\t\t<p><i>sex, ethics, & integrity.</i></p>\n\t\t<!-- just like in real life, say who you are and give a concise reason why you add value to someone's life and then make a call to action, if they want to learn more they can always scroll to learn more -->\n\t\t<div>\n\t\t\t<!-- a class=\"unit hold\" href=\"#fullscreen\"><button>WATCH TRAILER</button></a -->\n\t\t\t<a class=\"unit yak gap\" href=\"#breathe\"><button>PLAY GAME</button></a>\n\t\t</div>\n\t</div>\n\t<div class=\"focus center row leak\">\n\t\t<!-- just like in real life, looking pretty attracts attention, so show off and look glamorous! -->\n\t\t<img class=\"unit blink\" src=\"\" style=\"min-width: 10em; width: 80%;\">\n\t</div>\n\t<script>location.hash = ''</script>\n\t<script src=\"https://cdn.jsdelivr.net/npm/gun/lib/fun.js\"></script>\n</div>\n\n<div id=\"breathe\" class=\"hold full green\">\n\t<style>\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Step 1: Breathe</p>\n\t\t<a class=\"unit yak\" href=\"#water\"><button>Yupe</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"water\" class=\"hold full blue\">\n\t<style>\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Step 2: Drink Water</p>\n\t\t<p></p>\n\t\t<a class=\"unit yak\" href=\"#eat\"><button>Next</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"eat\" class=\"hold full red\">\n\t<style>\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Step 3: Eat Once a Day</p>\n\t\t<p>If you do not want to be eaten, do not eat things that would not want to be eaten.</p>\n\t\t<a class=\"unit yak\" href=\"#babies\"><button>Got It</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"babies\" class=\"hold full red\">\n\t<style>\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Step 4: Babymaking* 😉</p>\n\t\t<p>Find a willing player.</p>\n\t\t<p><small> * This does not always make babies.</small></p>\n\t\t<a class=\"unit yak\" href=\"#make\"><button>How?</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"make\" class=\"hold full hue\">\n\t<style>\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Step 5: Make Dance</p>\n\t\t<p>Moving your body is how you express your thoughts.</p>\n\t\t<p>What you do with your body is what others will come to know you for. So do well.</p>\n\t\t<p>You can make art, songs, or stories; You can make science, tools, or discoveries.</p>\n\t\t<p>Who are you?</p>\n\t\t<a class=\"unit yak\" href=\"#science\"><button>I am a Scientist!</button></a>\n\t\t<a class=\"unit yak\" href=\"#art\"><button>I am an Artist!</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"science\" class=\"hold full hue\">\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Science: Knowing Games</p>\n\t\t<p>If you must win one game, it should be the game of making games.</p>\n\t\t<p>If you can make any game, then you will know how to win any game.</p>\n\t\t<a class=\"unit yak\" href=\"#games\"><button>Games?</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"games\" class=\"hold full hue\">\n\t<div class=\"story pad\">\n\t\t<p>Games have goals and play.</p>\n\t\t<p>Play is a safe space to try new dances.</p>\n\t\t<p>Goals try to get players to do a type of dance.</p>\n\t\t<a class=\"unit yak\" href=\"#swim\"><button>Start</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"swim\" class=\"hold full blue\">\n\t<style>\n\t@import url('https://fonts.googleapis.com/css?family=Audiowide');\n\t#hud {\n\t\topacity: 0.4;\n\t\tfont-family: 'Audiowide', cursive;\n\t\tz-index: 999999999999;\n\t\ttransition: all 3s;\n\t}\n\t#hud .life {\n\t\tposition: fixed;\n\t\tleft: 50%;\n\t\tbottom: 0px;\n\t\tpadding: 0.25em 1em 0.1em;\n\t\tborder-radius: 0.5em 0.5em 0 0;\n\t\ttransform: translateX(-50%);\n\t\tbackground: black;\n\t\ttext-shadow: 0em -0.125em 0.75em white;\n\t}\n\t#hud .score {\n\t\tposition: fixed;\n\t\tleft: 50%;\n\t\ttop: 0px;\n\t\tpadding: 0.1em 1em 0.25em;\n\t\tborder-radius: 0 0 0.5em 0.5em;\n\t\ttransform: translateX(-50%);\n\t\tbackground: black;\n\t\ttext-shadow: 0em 0.1em 0.75em white;\n\t}\n\t#hud .down {\n\t\tbottom: -2em !important;\n\t}\n\t#hud .up {\n\t\ttop: -2em !important;\n\t}\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p>The simplest goal is to not \"die\" in the game.</p>\n\t\t<p>Oh look, you've fallen into water and cannot breathe.</p>\n\t\t<p>If you do not push the button to swim to the top, you'll lose the game.</p>\n\t\t<a class=\"unit yak\"><button>Swim</button></a>\n\t</div>\n\t<div id=\"hud\">\n\t\t<div class=\"score shade up\">\n\t\t\tSCORE: <span id=\"hudscore\">0</span>%\n\t\t</div>\n\t\t<div class=\"life shade down\">\n\t\t\tLIFE: <span id=\"hudlife\">100</span>%\n\t\t</div>\n\t</div>\n\t<script>\n\t;(function(){\n\t\tvar go, life = $('#hudlife').data();\n\t\t$(window).on('hashchange', function(){\n\t\t\tif(location.hash != '#swim'){ return }\n\t\t\t$('#hudlife').text($('#hudlife').data().is = 100);\n\t\t\t$('#hud .life').removeClass('down');\n\t\t\tgo = setInterval(function(){\n\t\t\t\tif(0 >= life.is){\n\t\t\t\t\tlocation.hash = 'die';\n\t\t\t\t\tclearInterval(go);\n\t\t\t\t\tgo = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$('#hudlife').text(life.is -= 1);\n\t\t\t}, 100);\n\t\t})\n\t\t$('#swim a').on('click', function(){\n\t\t\t$('#hudlife').text((life.is += 5) < 100? life.is : 100);\n\t\t\tif(100 <= life.is){\n\t\t\t\tlocation.hash = 'won';\n\t\t\t\tclearInterval(go);\n\t\t\t\tgo = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t}());\n\t</script>\n</div>\n\n<div id=\"won\" class=\"hold full hue\">\n\t<div class=\"story pad\">\n\t\t<p>You won your first game! 🎉</p>\n\t\t<p>See? I told you breathing is important.</p>\n\t\t<p>You also learned the most basic dance: rapid poking.</p>\n\t\t<p>The goal of the next game is to make the game you just won.</p>\n\t\t<a class=\"unit yak\" href=\"#won\" style=\"z-index: 999999;\"><button>Make</button></a>\n\t</div>\n\t<script src=\"https://cdn.jsdelivr.net/gh/amark/gun/lib/meta.js\"></script>\n\t<script>\n\t\tmeta.edit({name: \"Add\", combo: ['A']});\n\t\tmeta.edit({\n\t\t\tname: \"Timer\",\n\t\t\tcombo: ['A','T'],\n\t\t\ton: function(){\n\t\t\t\tconsole.log(\"up\");\n\t\t\t\tthis.to = this.to || setInterval(this.on, 100);\n\t\t\t\t$(\"html, body\").stop().animate({ scrollTop: $(window).scrollTop()-100 }, 100);\n\t\t\t\tp.css({top: --p.y +'%'});\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){ clearTimeout(this.to); this.to = 0 }\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Delete\",\n\t\t\tcombo: ['A','D'],\n\t\t\ton: function(){\n\t\t\t\t$(meta.tap.on).remove();\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){}\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Button\",\n\t\t\tcombo: ['A','B'],\n\t\t\ton: function(){\n\t\t\t\t$(meta.tap.on).append(\"<a class='unit yak'><button>Button</button></a>\")\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){}\n\t\t});\n\t\tmeta.edit({\n\t\t\tname: \"Edit\",\n\t\t\tcombo: ['E'],\n\t\t\ton: function(){\n\t\t\t\t$('body').attr('contenteditable', 'true' == $('body').attr('contenteditable')? false : true);\n\t\t\t},\n\t\t\tuse: function(){},\n\t\t\tup: function(){ }\n\t\t});\n\t</script>\n\t<script>\n\t\twindow.requestAnimationFrame(function frame(){\n\t\t\treturn;\n\t\t\twindow.requestAnimationFrame(frame);\n\t\t\tif(location.hash != '#won'){ return }\n\t\t\tvar p = $('#won a').offset();\n\t\t\tvar bx = p.left, by = p.top, mx = meta.tap.x, my = meta.tap.y;\n\t\t\tbx = mx - bx; by = my - by;\n\t\t\tvar d = Math.sqrt(bx*bx + by*by);\n\t\t\t\tconsole.log(bx, by, mx, my, d);\n\t\t\tif(d > 250){ return }\n\t\t\t$('#won a').css({position: 'fixed', left: bx + (Math.random()*100), top: by + (Math.random()*100)});\n\t\t})\n\t</script>\n</div>\n\n<div id=\"rules\" class=\"hold full white blackt\">\n\t<style>\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">Bend these Rules if it is more Moral to do so</p>\n\t\t<p></p>\n\t\t<a class=\"unit yak\" href=\"#water\"><button>Next</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n<div id=\"die\" class=\"hold full red\">\n\t<style>\n\t</style>\n\t<div class=\"story pad\">\n\t\t<p class=\"loud crack\">GAME OVER</p>\n\t\t<p></p>\n\t\t<a class=\"unit yak\" href=\"#make\"><button>Start Over</button></a>\n\t</div>\n\t<script>\n\t</script>\n</div>\n\n</body>\n</html>"
  },
  {
    "path": "examples/hapi.js",
    "content": "console.log(\"If module not found, install hapi globally `npm i hapi inert -g`!\")\n\nconst Hapi  = require('hapi')\nconst Inert = require('inert')\nconst Gun   = require('..')\n\nconst server = new Hapi.Server({\n  port: 8765,\n  host: 'localhost',\n  routes: {\n    files: {\n      relativeTo: require('path').join(__dirname, '..')\n    }\n  }\n})\n\nasync function runtime() {\n  \n  const db = new Gun({\n    web: server.listener,\n    file: 'data.json'\n  })\n\n  await server.register(Inert)\n\n  server.route({\n    method: 'GET',\n    path: '/gun.js',\n    handler: {\n      file:  'gun.min.js'\n    }\n  })\n\n  server.route({\n    method: 'GET',\n    path: '/gun/nts.js',\n    handler: {\n      file:  'nts.js'\n    }\n  })\n\n  server.route({\n    method: 'GET',\n    path: '/{param*}',\n    handler: {\n      directory: {\n        path: __dirname,\n        redirectToSlash: true,\n        index: true\n      }\n    }\n  })\n\n  await server.start()\n  console.log('Server running at:', server.info.uri)\n}\n\nruntime()\n"
  },
  {
    "path": "examples/http.js",
    "content": ";(function(){\n\tvar cluster = require('cluster');\n\tif(cluster.isMaster){\n\t  return cluster.fork() && cluster.on('exit',function(){ cluster.fork(); require('../lib/crashed') });\n\t}\n\n\tvar fs = require('fs'), env = process.env;\n\tvar GUN = require('../'); // require('gun');\n\tvar opt = {\n\t\tport: env.PORT || process.argv[2] || 8765,\n\t\tpeers: env.PEERS && env.PEERS.split(',') || []\n\t};\n\n\tif(fs.existsSync((opt.home = require('os').homedir())+'/cert.pem')){\n\t\tenv.HTTPS_KEY = env.HTTPS_KEY || opt.home+'/key.pem';\n\t\tenv.HTTPS_CERT = env.HTTPS_CERT || opt.home+'/cert.pem';\n\t}\n\tif(env.HTTPS_KEY){\n\t\topt.port = 443;\n\t\topt.key = fs.readFileSync(env.HTTPS_KEY);\n\t\topt.cert = fs.readFileSync(env.HTTPS_CERT);\n\t\topt.server = require('https').createServer(opt, GUN.serve(__dirname));\n\t\trequire('http').createServer(function(req, res){\n\t\t\tres.writeHead(301, {\"Location\": \"https://\"+req.headers['host']+req.url });\n\t\t\tres.end();\n\t\t}).listen(80);\n\t} else {\n\t\topt.server = require('http').createServer(GUN.serve(__dirname));\n\t}\n\n\tvar gun = GUN({web: opt.server.listen(opt.port), peers: opt.peers});\n\tconsole.log('Relay peer started on port ' + opt.port + ' with /gun');\n\tmodule.exports = gun;\n}());"
  },
  {
    "path": "examples/https.sh",
    "content": "#!/bin/bash\ncd ~\ngit clone https://github.com/acmesh-official/acme.sh.git\ncd ~/acme.sh\n./acme.sh --install -m $EMAIL\n\nbash ~/acme.sh/acme.sh --issue -d $DOMAIN -w $WEB\nbash ~/acme.sh/acme.sh --install-cert -d $DOMAIN --key-file ~/key.pem --fullchain-file ~/cert.pem --reloadcmd \"service relay force-reload\""
  },
  {
    "path": "examples/index.html",
    "content": "<!DOCTYPE html>\r\n<p>This is the examples folder.\r\n<p>The most basic example is <a href=\"./basic/note.html\">./basic/note.html</a>!</p>\r\n<p>Home page temporarily disabled.</p>"
  },
  {
    "path": "examples/infinite-scroll/ScrollWindow.js",
    "content": "const DEFAULT_OPTIONS = {\n  size: 20,\n  stickTo: 'top',\n};\n\nclass ScrollWindow {\n  constructor(gunNode, opts = {}) {\n    this.opts = Object.assign(DEFAULT_OPTIONS, opts);\n    this.elements = new Map();\n    this.node = gunNode;\n    this.center = this.opts.startAt;\n    this.updateSubscriptions();\n  }\n\n  updateSubscriptions() {\n    this.upSubscription && this.upSubscription.off();\n    this.downSubscription && this.downSubscription.off();\n\n    const subscribe = params => {\n      this.node.get({ '.': params}).map().on((val, key, a, eve) => {\n        if (params['-']) {\n          this.downSubscription = eve;\n        } else {\n          this.upSubscription = eve;\n        }\n        this._addElement(key, val);\n      });\n    };\n\n    if (this.center) {\n      subscribe({ '>': this.center, '<': '\\uffff' });\n      subscribe({'<': this.center, '>' : '', '-': true});\n    } else {\n      subscribe({ '<': '\\uffff', '>': '', '-': this.opts.stickTo === 'top' });\n    }\n  }\n\n  _getSortedKeys() {\n    this.sortedKeys = this.sortedKeys || [...this.elements.keys()].sort();\n    return this.sortedKeys;\n  }\n\n  _upOrDown(n, up) {\n    this.opts.stickTo = null;\n    const keys = this._getSortedKeys();\n    n = n || (keys.length / 2);\n    n = up ? n : -n;\n    const half = Math.floor(keys.length / 2);\n    const newMiddleIndex = Math.max(Math.min(half + n, keys.length - 1), 0);\n    if (this.center !== keys[newMiddleIndex]) {\n      this.center = keys[newMiddleIndex];\n      this.updateSubscriptions();\n    }\n    return this.center;\n  }\n\n  up(n) {\n    return this._upOrDown(n, true);\n  }\n\n  down(n) {\n    return this._upOrDown(n, false);\n  }\n\n  _topOrBottom(top) {\n    this.opts.stickTo = top ? 'top' : 'bottom';\n    this.center = null;\n    this.updateSubscriptions();\n  }\n\n  top() {\n    this._topOrBottom(true);\n  }\n\n  bottom() {\n    this._topOrBottom(false);\n  }\n\n  _addElement(key, val) {\n    if (!val || this.elements.has(key)) return;\n    const add = () => {\n      this.elements.set(key, val);\n      this.sortedKeys = [...this.elements.keys()].sort();\n      const sortedElements = this.sortedKeys.map(k => this.elements.get(k));\n      this.opts.onChange && this.opts.onChange(sortedElements);\n    };\n    const keys = this._getSortedKeys();\n    if (keys.length < this.opts.size) {\n      add();\n    } else {\n      if (this.opts.stickTo === 'top' && key > keys[0]) {\n        this.elements.delete(keys[0]);\n        add();\n      } else if (this.opts.stickTo === 'bottom' && key < keys[keys.length - 1]) {\n        this.elements.delete(keys[keys.length - 1]);\n        add();\n      } else if (this.center) {\n        if (keys.indexOf(this.center) < (keys.length / 2)) {\n          if (key < keys[keys.length - 1]) {\n            this.elements.delete(keys[keys.length - 1]);\n            add();\n          }\n        } else {\n          if (key > keys[0]) {\n            delete this.elements.delete(keys[0]);\n            add();\n          }\n        }\n      }\n    }\n  }\n\n  getElements() {\n    return this.elements;\n  }\n}\n"
  },
  {
    "path": "examples/infinite-scroll/index.html",
    "content": "<html>\n  <head>\n    <title>Infinite scroll example</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"./style.css\">\n    <script src=\"/jquery.js\"></script>\n    <script src=\"/gun.js\"></script>\n    <script src=\"./ScrollWindow.js\"></script>\n  </head>\n\n  <body>\n    <header>\n      <form id=\"generate\">\n        <input type=\"text\" id=\"number\" placeholder=\"Number of posts\"/>\n        <button>Generate</button>\n      </form>\n      <div id=\"top-buttons\">\n        <button id=\"top\">Top</button>\n      </div>\n    </header>\n\n    <div id=\"top-sentinel\" style=\"padding-top: 0px;\"></div>\n    <div id=\"container\"></div>\n    <div id=\"bottom-sentinel\" style=\"padding-top: 0px;\"></div>\n\n    <button id=\"bottom\">Bottom</button>\n\n    <script src=\"./index.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/infinite-scroll/index.js",
    "content": "const gun = new Gun();\n\nconst size = 20;\nconst gunNode = gun.get('posts');\n\nfunction debounce(func, wait, immediate) {\n  var timeout;\n  return function() {\n    var context = this, args = arguments;\n    var later = function() {\n      timeout = null;\n      if (!immediate) func.apply(context, args);\n    };\n    var callNow = immediate && !timeout;\n    clearTimeout(timeout);\n    timeout = setTimeout(later, wait);\n    if (callNow) func.apply(context, args);\n  };\n};\n\nlet topSentinelPreviousY = 0;\nlet topSentinelPreviousRatio = 0;\nlet bottomSentinelPreviousY = 0;\nlet bottomSentinelPreviousRatio = 0;\nlet previousUpIndex = previousDownIndex = -1;\n\nconst render = elements => {\n  const t = new Date();\n  elements.reverse().forEach((data, j) => {\n    var date = new Date(data.date);\n    $('#date' + j).text(date.toLocaleDateString() + ' ' + date.toLocaleTimeString());\n    $('#text' + j).text(data.text);\n    $('#img' + j).attr('src', '');\n    $('#img' + j).attr('src', _getCatImg(date.getTime()));\n    $('#post' + j).css({visibility: 'visible'});\n  });\n  console.log('rendering took', new Date().getTime() - t.getTime(), 'ms');\n  window.onRender && window.onRender(elements);\n};\n\nconst onChange = debounce(render, 20);\n\nconst scroller = new ScrollWindow(gunNode, {size, stickTo: 'top', onChange});\n\nconst initList = () => {\n  for (var n = 0; n < size; n++) {\n    var el = $(\"<div>\").addClass('post').attr('id', 'post' + n).css({visibility: 'hidden'});\n    el.append($('<b>').attr('id', 'date' + n));\n    el.append($('<span>').attr('id', 'text' + n));\n    el.append($('<img>').attr('id', 'img' + n).attr('height', 100).attr('width', 100));\n    $('#container').append(el);\n  }\n}\n\nconst _getCatImg = (n) => {\n  const url = \"https://source.unsplash.com/collection/139386/100x100/?sig=\";\n  return url + n % 999999;\n};\n\nconst getNumFromStyle = numStr => Number(numStr.substring(0, numStr.length - 2));\n\nconst adjustPaddings = isScrollDown => {\n  const container = document.getElementById(\"container\");\n  const currentPaddingTop = getNumFromStyle(container.style.paddingTop);\n  const currentPaddingBottom = getNumFromStyle(container.style.paddingBottom);\n  const remPaddingsVal = 198 * (size / 2); // TODO: calculate actual element heights\n  if (isScrollDown) {\n    container.style.paddingTop = currentPaddingTop + remPaddingsVal + \"px\";\n    container.style.paddingBottom = currentPaddingBottom === 0 ? \"0px\" : currentPaddingBottom - remPaddingsVal + \"px\";\n  } else {\n    container.style.paddingBottom = currentPaddingBottom + remPaddingsVal + \"px\";\n    if (currentPaddingTop === 0) {\n      $(window).scrollTop($('#post0').offset().top + remPaddingsVal);\n    } else {\n      container.style.paddingTop = currentPaddingTop - remPaddingsVal + \"px\";\n    }\n  }\n}\n\nconst topSentCallback = entry => {\n  const container = document.getElementById(\"container\");\n\n  const currentY = entry.boundingClientRect.top;\n  const currentRatio = entry.intersectionRatio;\n  const isIntersecting = entry.isIntersecting;\n\n  // conditional check for Scrolling up\n  if (\n    currentY > topSentinelPreviousY &&\n    isIntersecting &&\n    currentRatio >= topSentinelPreviousRatio &&\n    scroller.center !== previousUpIndex && // stop if no new results were received\n    scroller.opts.stickTo !== 'top'\n  ) {\n    previousUpIndex = scroller.center;\n    adjustPaddings(false);\n    scroller.up(size / 2);\n  }\n  topSentinelPreviousY = currentY;\n  topSentinelPreviousRatio = currentRatio;\n}\n\nconst botSentCallback = entry => {\n  const currentY = entry.boundingClientRect.top;\n  const currentRatio = entry.intersectionRatio;\n  const isIntersecting = entry.isIntersecting;\n\n  // conditional check for Scrolling down\n  if (\n    currentY < bottomSentinelPreviousY &&\n    currentRatio > bottomSentinelPreviousRatio &&\n    isIntersecting &&\n    scroller.center !== previousDownIndex &&  // stop if no new results were received\n    scroller.opts.stickTo !== 'bottom'\n  ) {\n    previousDownIndex = scroller.center;\n    adjustPaddings(true);\n    scroller.down(size / 2);\n  }\n  bottomSentinelPreviousY = currentY;\n  bottomSentinelPreviousRatio = currentRatio;\n}\n\nconst initIntersectionObserver = () => {\n  const options = {\n    //rootMargin: '190px',\n  }\n\n  const callback = entries => {\n    entries.forEach(entry => {\n      if (entry.target.id === 'post0') {\n        topSentCallback(entry);\n      } else if (entry.target.id === `post${size - 1}`) {\n        botSentCallback(entry);\n      }\n    });\n  }\n\n  var observer = new IntersectionObserver(callback, options); // TODO: It's possible to quickly scroll past the sentinels without them firing. Top and bottom sentinels should extend to page top & bottom?\n  observer.observe(document.querySelector(\"#post0\"));\n  observer.observe(document.querySelector(`#post${size - 1}`));\n}\n\ninitList(size);\ninitIntersectionObserver();\n\n$('#top').click(() => {\n  scroller.top();\n  $('#container').css({'padding-top': 0, 'padding-bottom': 0});\n  $(document.body).animate({ scrollTop: 0 }, 500);\n});\n$('#bottom').click(() => {\n  scroller.bottom();\n  $('#container').css({'padding-top': 0, 'padding-bottom': 0});\n  $(document.body).animate({ scrollTop: $(\"#container\").height() }, 500);\n});\n\n$('#generate').submit(e => {\n  e.preventDefault();\n  const day = 24 * 60 * 60 * 1000;\n  const year = 365 * day;\n  const n = Number($('#number').val());\n  for (let i = 0; i < n; i++) {\n    const d = new Date(40 * year + i * day).toISOString();\n    gunNode.get(d).put({text: 'Hello world!', date: d});\n  }\n});\n"
  },
  {
    "path": "examples/infinite-scroll/style.css",
    "content": "html, body {\n  margin: 0;\n  padding: 0;\n}\n\nbody {\n  padding-top: 65px;\n}\n\nheader {\n  background: rgba(255,255,255,0.75);\n  padding: 15px;\n}\n\nheader {\n  position: fixed;\n  top: 0; left: 0; right: 0;\n}\n\n#bottom {\n  position: fixed;\n  right: 15px;\n  bottom: 15px;\n}\n\ninput {\n  border: 0;\n  background-color: #efefef;\n  padding: 15px;\n  border-radius: 50px;\n}\n\nbutton {\n  background-color: #4a4f9d;\n  border: 0;\n  padding: 15px;\n  color: white;\n  border-radius: 50px;\n}\n\ninput, button {\n  outline: none;\n  opacity: 1;\n}\n\ninput:focus, button:focus, button:hover {\n  opacity: 0.8;\n}\n\nbutton:hover {\n  cursor: pointer;\n}\n\n#top-buttons, form {\n  display: inline-block;\n  margin: 0;\n}\n\n#top-buttons {\n  float: right;\n}\n\n.post {\n  margin: 15px;\n  padding: 15px;\n  background-color: #9de1fe;\n  border-radius: 5px;\n}\n\n.post b {\n  margin-right: 5;\n}\n\n.post img {\n  display: block;\n  margin: 10px 0;\n}\n"
  },
  {
    "path": "examples/install.sh",
    "content": "#!/bin/bash\n\n# README\n# This will install nodejs and npm on your system,\n# should work on most places other than Windows.\n# For it to run on boot as a server, a recent OS is needed.\n# Set any environment variables before you run this,\n# like `export RAD=false` to disable storage, or\n# pass file paths of `HTTPS_CERT` & `HTTPS_KEY`, etc.\n# Copy paste and run each line into your terminal.\n# If you are on Windows, http://nodejs.org/download/ has\n# an installer that will automatically do it for you.\n# curl -o- https://raw.githubusercontent.com/amark/gun/master/examples/install.sh | bash\n# wget -O - https://raw.githubusercontent.com/amark/gun/master/examples/install.sh | bash\n\n#debian/ubuntu\ncd ~\napt-get install sudo -y\nsudo apt-get update -y\nsudo apt-get install curl git git-core systemd -y\nsudo apt-get install systemctl -y\n#fedora/openSUSE\nsudo yum check-update -y\nsudo yum install curl git git-core systemd -y\nsudo yum install systemctl -y\n\n#screen -S install # You can safely CTRL+A+D to escape without stopping the process. `screen -R install` to resume. Stop all with `killall screen`. Note: May need to `sudo apt-get install screen`\n\n# install nodejs\ngit clone https://github.com/isaacs/nave.git\n./nave/nave.sh usemain stable\n\n# If you just want nodejs and npm but not gun, stop here.\n#npm install gun@latest\n#cd ./node_modules/gun\nmkdir node_modules\ngit clone https://github.com/amark/gun.git\ncd gun\ngit checkout .\ngit pull\ngit checkout master\ngit checkout $VERSION\ngit pull\nnpm install .\n\ncp ./examples/relay.service /lib/systemd/system/relay.service\necho $PWD >> /lib/systemd/system/relay.service\necho \"fs.file-max = 999999\" >> /etc/sysctl.conf\nulimit -u unlimited\nsysctl -p /etc/sysctl.conf\nsystemctl daemon-reload\nsystemctl enable relay\nsystemctl restart relay"
  },
  {
    "path": "examples/jquery.js",
    "content": "/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */\n!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error(\"jQuery requires a window with a document\");return b(a)}:b(a)}(\"undefined\"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m=\"1.12.4\",n=function(a,b){return new n.fn.init(a,b)},o=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,p=/^-ms-/,q=/-([\\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:\"\",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for(\"boolean\"==typeof g&&(j=g,g=arguments[h]||{},h++),\"object\"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:\"jQuery\"+(m+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return\"function\"===n.type(a)},isArray:Array.isArray||function(a){return\"array\"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||\"object\"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,\"constructor\")&&!k.call(a.constructor.prototype,\"isPrototypeOf\"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+\"\":\"object\"==typeof a||\"function\"==typeof a?i[j.call(a)]||\"object\":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,\"ms-\").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?\"\":(a+\"\").replace(o,\"\")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,\"string\"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return\"string\"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),\"function\"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(a,b){i[\"[object \"+b+\"]\"]=b.toLowerCase()});function s(a){var b=!!a&&\"length\"in a&&a.length,c=n.type(a);return\"function\"===c||n.isWindow(a)?!1:\"array\"===c||0===b||\"number\"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u=\"sizzle\"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",L=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",M=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",N=\"\\\\[\"+L+\"*(\"+M+\")(?:\"+L+\"*([*^$|!~]?=)\"+L+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+M+\"))|)\"+L+\"*\\\\]\",O=\":(\"+M+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+N+\")*)|.*)\\\\)|)\",P=new RegExp(L+\"+\",\"g\"),Q=new RegExp(\"^\"+L+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+L+\"+$\",\"g\"),R=new RegExp(\"^\"+L+\"*,\"+L+\"*\"),S=new RegExp(\"^\"+L+\"*([>+~]|\"+L+\")\"+L+\"*\"),T=new RegExp(\"=\"+L+\"*([^\\\\]'\\\"]*?)\"+L+\"*\\\\]\",\"g\"),U=new RegExp(O),V=new RegExp(\"^\"+M+\"$\"),W={ID:new RegExp(\"^#(\"+M+\")\"),CLASS:new RegExp(\"^\\\\.(\"+M+\")\"),TAG:new RegExp(\"^(\"+M+\"|[*])\"),ATTR:new RegExp(\"^\"+N),PSEUDO:new RegExp(\"^\"+O),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+L+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+L+\"*(?:([+-]|)\"+L+\"*(\\\\d+)|))\"+L+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+K+\")$\",\"i\"),needsContext:new RegExp(\"^\"+L+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+L+\"*((?:-\\\\d)?\\\\d*)\"+L+\"*\\\\)|)(?=[^-]|$)\",\"i\")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\\d$/i,Z=/^[^{]+\\{\\s*\\[native \\w/,$=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,_=/[+~]/,aa=/'|\\\\/g,ba=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+L+\"?|(\"+L+\")|.)\",\"ig\"),ca=function(a,b,c){var d=\"0x\"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],\"string\"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+\" \"]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if(\"object\"!==b.nodeName.toLowerCase()){(k=b.getAttribute(\"id\"))?k=k.replace(aa,\"\\\\$&\"):b.setAttribute(\"id\",k=u),r=g(a),h=r.length,l=V.test(k)?\"#\"+k:\"[id='\"+k+\"']\";while(h--)r[h]=l+\" \"+qa(r[h]);s=r.join(\",\"),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute(\"id\")}}}return i(a.replace(Q,\"$1\"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+\" \")>d.cacheLength&&delete b[a.shift()],b[c+\" \"]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement(\"div\");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split(\"|\"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return\"input\"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return(\"input\"===c||\"button\"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&\"undefined\"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?\"HTML\"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener(\"unload\",da,!1):e.attachEvent&&e.attachEvent(\"onunload\",da)),c.attributes=ia(function(a){return a.className=\"i\",!a.getAttribute(\"className\")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment(\"\")),!a.getElementsByTagName(\"*\").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(\"undefined\"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute(\"id\")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c=\"undefined\"!=typeof a.getAttributeNode&&a.getAttributeNode(\"id\");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return\"undefined\"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if(\"*\"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return\"undefined\"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML=\"<a id='\"+u+\"'></a><select id='\"+u+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",a.querySelectorAll(\"[msallowcapture^='']\").length&&q.push(\"[*^$]=\"+L+\"*(?:''|\\\"\\\")\"),a.querySelectorAll(\"[selected]\").length||q.push(\"\\\\[\"+L+\"*(?:value|\"+K+\")\"),a.querySelectorAll(\"[id~=\"+u+\"-]\").length||q.push(\"~=\"),a.querySelectorAll(\":checked\").length||q.push(\":checked\"),a.querySelectorAll(\"a#\"+u+\"+*\").length||q.push(\".#.+[+~]\")}),ia(function(a){var b=n.createElement(\"input\");b.setAttribute(\"type\",\"hidden\"),a.appendChild(b).setAttribute(\"name\",\"D\"),a.querySelectorAll(\"[name=d]\").length&&q.push(\"name\"+L+\"*[*^$|!~]?=\"),a.querySelectorAll(\":enabled\").length||q.push(\":enabled\",\":disabled\"),a.querySelectorAll(\"*,:x\"),q.push(\",.*:\")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,\"div\"),s.call(a,\"[s!='']:x\"),r.push(\"!=\",O)}),q=q.length&&new RegExp(q.join(\"|\")),r=r.length&&new RegExp(r.join(\"|\")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,\"='$1']\"),c.matchesSelector&&p&&!A[b+\" \"]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error(\"Syntax error, unrecognized expression: \"+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c=\"\",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if(\"string\"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||\"\").replace(ba,ca),\"~=\"===a[2]&&(a[3]=\" \"+a[3]+\" \"),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),\"nth\"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*(\"even\"===a[3]||\"odd\"===a[3])),a[5]=+(a[7]+a[8]||\"odd\"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||\"\":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(\")\",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return\"*\"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+\" \"];return b||(b=new RegExp(\"(^|\"+L+\")\"+a+\"(\"+L+\"|$)\"))&&y(a,function(a){return b.test(\"string\"==typeof a.className&&a.className||\"undefined\"!=typeof a.getAttribute&&a.getAttribute(\"class\")||\"\")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?\"!=\"===b:b?(e+=\"\",\"=\"===b?e===c:\"!=\"===b?e!==c:\"^=\"===b?c&&0===e.indexOf(c):\"*=\"===b?c&&e.indexOf(c)>-1:\"$=\"===b?c&&e.slice(-c.length)===c:\"~=\"===b?(\" \"+e.replace(P,\" \")+\" \").indexOf(c)>-1:\"|=\"===b?e===c||e.slice(0,c.length+1)===c+\"-\":!1):!0}},CHILD:function(a,b,c,d,e){var f=\"nth\"!==a.slice(0,3),g=\"last\"!==a.slice(-4),h=\"of-type\"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?\"nextSibling\":\"previousSibling\",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p=\"only\"===a&&!o&&\"nextSibling\"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error(\"unsupported pseudo: \"+a);return e[u]?e(b):e.length>1?(c=[a,a,\"\",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,\"$1\"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||\"\")||fa.error(\"unsupported lang: \"+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute(\"xml:lang\")||b.getAttribute(\"lang\"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+\"-\");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&!!a.checked||\"option\"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return\"input\"===b&&\"button\"===a.type||\"button\"===b},text:function(a){var b;return\"input\"===a.nodeName.toLowerCase()&&\"text\"===a.type&&(null==(b=a.getAttribute(\"type\"))||\"text\"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+\" \"];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q,\" \")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d=\"\";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&\"parentNode\"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||\"*\",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[\" \"],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:\" \"===a[i-2].type?\"*\":\"\"})).replace(Q,\"$1\"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s=\"0\",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG(\"*\",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+\" \"];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n=\"function\"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&\"ID\"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split(\"\").sort(B).join(\"\")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement(\"div\"))}),ia(function(a){return a.innerHTML=\"<a href='#'></a>\",\"#\"===a.firstChild.getAttribute(\"href\")})||ja(\"type|href|height|width\",function(a,b,c){return c?void 0:a.getAttribute(b,\"type\"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML=\"<input/>\",a.firstChild.setAttribute(\"value\",\"\"),\"\"===a.firstChild.getAttribute(\"value\")})||ja(\"value\",function(a,b,c){return c||\"input\"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute(\"disabled\")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[\":\"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/,y=/^.[^:#\\[\\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if(\"string\"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=\":not(\"+a+\")\"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if(\"string\"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+\" \"+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,\"string\"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,\"string\"==typeof a){if(e=\"<\"===a.charAt(0)&&\">\"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?\"undefined\"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||\"string\"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?\"string\"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,\"parentNode\")},parentsUntil:function(a,b,c){return u(a,\"parentNode\",c)},next:function(a){return F(a,\"nextSibling\")},prev:function(a){return F(a,\"previousSibling\")},nextAll:function(a){return u(a,\"nextSibling\")},prevAll:function(a){return u(a,\"previousSibling\")},nextUntil:function(a,b,c){return u(a,\"nextSibling\",c)},prevUntil:function(a,b,c){return u(a,\"previousSibling\",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,\"iframe\")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return\"Until\"!==a.slice(-5)&&(d=c),d&&\"string\"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a=\"string\"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:\"\")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&\"string\"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c=\"\",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[[\"resolve\",\"done\",n.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",n.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",n.Callbacks(\"memory\")]],c=\"pending\",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+\"With\"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+\"With\"](this===e?d:this,arguments),this},e[f[0]+\"With\"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler(\"ready\"),n(d).off(\"ready\"))))}});function J(){d.addEventListener?(d.removeEventListener(\"DOMContentLoaded\",K),a.removeEventListener(\"load\",K)):(d.detachEvent(\"onreadystatechange\",K),a.detachEvent(\"onload\",K))}function K(){(d.addEventListener||\"load\"===a.event.type||\"complete\"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),\"complete\"===d.readyState||\"loading\"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener(\"DOMContentLoaded\",K),a.addEventListener(\"load\",K);else{d.attachEvent(\"onreadystatechange\",K),a.attachEvent(\"onload\",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll(\"left\")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst=\"0\"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName(\"body\")[0],c&&c.style&&(b=d.createElement(\"div\"),e=d.createElement(\"div\"),e.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",c.appendChild(e).appendChild(b),\"undefined\"!=typeof b.style.zoom&&(b.style.cssText=\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement(\"div\");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+\" \").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute(\"classid\")===b},N=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d=\"data-\"+b.replace(O,\"-$1\").toLowerCase();if(c=a.getAttribute(d),\"string\"==typeof c){try{c=\"true\"===c?!0:\"false\"===c?!1:\"null\"===c?null:+c+\"\"===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;\n}return c}function Q(a){var b;for(b in a)if((\"data\"!==b||!n.isEmptyObject(a[b]))&&\"toJSON\"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||\"string\"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),\"object\"!=typeof b&&\"function\"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),\"string\"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(\" \")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{\"applet \":!0,\"embed \":!0,\"object \":\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,\"parsedAttrs\"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf(\"data-\")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,\"parsedAttrs\",!0)}return e}return\"object\"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||\"fx\")+\"queue\",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||\"fx\";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};\"inprogress\"===e&&(e=c.shift(),d--),e&&(\"fx\"===b&&c.unshift(\"inprogress\"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+\"queueHooks\";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks(\"once memory\").add(function(){n._removeData(a,b+\"queue\"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return\"string\"!=typeof a&&(b=a,a=\"fx\",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),\"fx\"===a&&\"inprogress\"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||\"fx\",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};\"string\"!=typeof a&&(b=a,a=void 0),a=a||\"fx\";while(g--)c=n._data(f[g],a+\"queueHooks\"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName(\"body\")[0],c&&c.style?(b=d.createElement(\"div\"),e=d.createElement(\"div\"),e.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",c.appendChild(e).appendChild(b),\"undefined\"!=typeof b.style.zoom&&(b.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\",b.appendChild(d.createElement(\"div\")).style.width=\"5px\",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,U=new RegExp(\"^(?:([+-])=|)(\"+T+\")([a-z%]*)$\",\"i\"),V=[\"Top\",\"Right\",\"Bottom\",\"Left\"],W=function(a,b){return a=b||a,\"none\"===n.css(a,\"display\")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,\"\")},i=h(),j=c&&c[3]||(n.cssNumber[b]?\"\":\"px\"),k=(n.cssNumber[b]||\"px\"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||\".5\",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if(\"object\"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\\w:-]+)/,_=/^$|\\/(?:java|ecma)script/i,aa=/^\\s+/,ba=\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video\";function ca(a){var b=ba.split(\"|\"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement(\"div\"),b=d.createDocumentFragment(),c=d.createElement(\"input\");a.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName(\"tbody\").length,l.htmlSerialize=!!a.getElementsByTagName(\"link\").length,l.html5Clone=\"<:nav></:nav>\"!==d.createElement(\"nav\").cloneNode(!0).outerHTML,c.type=\"checkbox\",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML=\"<textarea>x</textarea>\",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement(\"input\"),c.setAttribute(\"type\",\"radio\"),c.setAttribute(\"checked\",\"checked\"),c.setAttribute(\"name\",\"t\"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,\"<select multiple='multiple'>\",\"</select>\"],legend:[1,\"<fieldset>\",\"</fieldset>\"],area:[1,\"<map>\",\"</map>\"],param:[1,\"<object>\",\"</object>\"],thead:[1,\"<table>\",\"</table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],col:[2,\"<table><tbody></tbody><colgroup>\",\"</colgroup></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:l.htmlSerialize?[0,\"\",\"\"]:[1,\"X<div>\",\"</div>\"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f=\"undefined\"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||\"*\"):\"undefined\"!=typeof a.querySelectorAll?a.querySelectorAll(b||\"*\"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,\"globalEval\",!b||n._data(b[d],\"globalEval\"))}var ga=/<|&#?\\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if(\"object\"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement(\"div\")),j=($.exec(g)||[\"\",\"\"])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g=\"table\"!==j||ha.test(g)?\"<table>\"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],\"tbody\")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent=\"\";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,\"input\"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),\"script\"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||\"\")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement(\"div\");for(b in{submit:!0,change:!0,focusin:!0})c=\"on\"+b,(l[b]=c in a)||(e.setAttribute(c,\"t\"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if(\"object\"==typeof b){\"string\"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&(\"string\"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return\"undefined\"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||\"\").match(G)||[\"\"],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||\"\").split(\".\").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(\".\")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent(\"on\"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||\"\").match(G)||[\"\"],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||\"\").split(\".\").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp(\"(^|\\\\.)\"+p.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&(\"**\"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,\"events\"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,\"type\")?b.type:b,r=k.call(b,\"namespace\")?b.namespace.split(\".\"):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(\".\")>-1&&(r=q.split(\".\"),q=r.shift(),r.sort()),h=q.indexOf(\":\")<0&&\"on\"+q,b=b[n.expando]?b:new n.Event(q,\"object\"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join(\".\"),b.rnamespace=b.namespace?new RegExp(\"(^|\\\\.)\"+r.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,\"events\")||{})[b.type]&&n._data(i,\"handle\"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,\"events\")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(\"click\"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||\"click\"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+\" \",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:\"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:\"focusin\"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:\"focusout\"},click:{trigger:function(){return n.nodeName(this,\"input\")&&\"checkbox\"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,\"a\")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d=\"on\"+b;a.detachEvent&&(\"undefined\"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,\"form\")?!1:void n.event.add(this,\"click._submit keypress._submit\",function(a){var b=a.target,c=n.nodeName(b,\"input\")||n.nodeName(b,\"button\")?n.prop(b,\"form\"):void 0;c&&!n._data(c,\"submit\")&&(n.event.add(c,\"submit._submit\",function(a){a._submitBubble=!0}),n._data(c,\"submit\",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate(\"submit\",this.parentNode,a))},teardown:function(){return n.nodeName(this,\"form\")?!1:void n.event.remove(this,\"._submit\")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?(\"checkbox\"!==this.type&&\"radio\"!==this.type||(n.event.add(this,\"propertychange._change\",function(a){\"checked\"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,\"click._change\",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate(\"change\",this,a)})),!1):void n.event.add(this,\"beforeactivate._change\",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,\"change\")&&(n.event.add(b,\"change._change\",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate(\"change\",this.parentNode,a)}),n._data(b,\"change\",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||\"radio\"!==b.type&&\"checkbox\"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,\"._change\"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:\"focusin\",blur:\"focusout\"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+\".\"+d.namespace:d.origType,d.selector,d.handler),this;if(\"object\"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&\"function\"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\\d+=\"(?:null|\\d+)\"/g,ua=new RegExp(\"<(?:\"+ba+\")[\\\\s/>]\",\"i\"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,wa=/<script|<style|<link/i,xa=/checked\\s*(?:[^=]|=\\s*.checked.)/i,ya=/^true\\/(.*)/,za=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement(\"div\"));function Ca(a,b){return n.nodeName(a,\"table\")&&n.nodeName(11!==b.nodeType?b:b.firstChild,\"tr\")?a.getElementsByTagName(\"tbody\")[0]||a.appendChild(a.ownerDocument.createElement(\"tbody\")):a}function Da(a){return a.type=(null!==n.find.attr(a,\"type\"))+\"/\"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute(\"type\"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}\"script\"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):\"object\"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):\"input\"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):\"option\"===c?b.defaultSelected=b.selected=a.defaultSelected:\"input\"!==c&&\"textarea\"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&\"string\"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,\"script\"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,\"script\"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||\"\")&&!n._data(g,\"globalEval\")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||\"\").replace(za,\"\")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,\"script\")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,\"<$1></$2>\")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test(\"<\"+a.nodeName+\">\")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,\"script\"),d.length>0&&fa(d,!i&&ea(a,\"script\")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||\"undefined\"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,\"select\")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,\"\"):void 0;if(\"string\"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||[\"\",\"\"])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:\"block\",BODY:\"block\"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],\"display\");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),\"none\"!==c&&c||(Ja=(Ja||n(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp(\"^(\"+T+\")(?!px)[a-z%]+$\",\"i\"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement(\"div\"),j=d.createElement(\"div\");if(j.style){j.style.cssText=\"float:left;opacity:.5\",l.opacity=\"0.5\"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip=\"content-box\",j.cloneNode(!0).style.backgroundClip=\"\",l.clearCloneStyle=\"content-box\"===j.style.backgroundClip,i=d.createElement(\"div\"),i.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",j.innerHTML=\"\",i.appendChild(j),l.boxSizing=\"\"===j.style.boxSizing||\"\"===j.style.MozBoxSizing||\"\"===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText=\"-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b=\"1%\"!==(l||{}).top,h=\"2px\"===(l||{}).marginLeft,e=\"4px\"===(l||{width:\"4px\"}).width,j.style.marginRight=\"50%\",c=\"4px\"===(l||{marginRight:\"4px\"}).marginRight,k=j.appendChild(d.createElement(\"div\")),k.style.cssText=j.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",k.style.marginRight=k.style.width=\"0\",j.style.width=\"1px\",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display=\"none\",f=0===j.getClientRects().length,f&&(j.style.display=\"\",j.innerHTML=\"<table><tr><td></td><td>t</td></tr></table>\",j.childNodes[0].style.borderCollapse=\"separate\",k=j.getElementsByTagName(\"td\"),k[0].style.cssText=\"margin:0;border:0;padding:0;display:none\",f=0===k[0].offsetHeight,f&&(k[0].style.display=\"\",k[1].style.display=\"none\",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,\"\"!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+\"\"}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left=\"fontSize\"===b?\"1em\":g,g=h.pixelLeft+\"px\",h.left=d,f&&(e.left=f)),void 0===g?g:g+\"\"||\"auto\"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\\([^)]*\\)/i,Wa=/opacity\\s*=\\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp(\"^(\"+T+\")(.*)$\",\"i\"),Za={position:\"absolute\",visibility:\"hidden\",display:\"block\"},$a={letterSpacing:\"0\",fontWeight:\"400\"},_a=[\"Webkit\",\"O\",\"Moz\",\"ms\"],ab=d.createElement(\"div\").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,\"olddisplay\"),c=d.style.display,b?(f[g]||\"none\"!==c||(d.style.display=\"\"),\"\"===d.style.display&&W(d)&&(f[g]=n._data(d,\"olddisplay\",Ma(d.nodeName)))):(e=W(d),(c&&\"none\"!==c||!e)&&n._data(d,\"olddisplay\",e?c:n.css(d,\"display\"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&\"none\"!==d.style.display&&\"\"!==d.style.display||(d.style.display=b?f[g]||\"\":\"none\"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||\"px\"):b}function eb(a,b,c,d,e){for(var f=c===(d?\"border\":\"content\")?4:\"width\"===b?1:0,g=0;4>f;f+=2)\"margin\"===c&&(g+=n.css(a,c+V[f],!0,e)),d?(\"content\"===c&&(g-=n.css(a,\"padding\"+V[f],!0,e)),\"margin\"!==c&&(g-=n.css(a,\"border\"+V[f]+\"Width\",!0,e))):(g+=n.css(a,\"padding\"+V[f],!0,e),\"padding\"!==c&&(g+=n.css(a,\"border\"+V[f]+\"Width\",!0,e)));return g}function fb(a,b,c){var d=!0,e=\"width\"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&\"border-box\"===n.css(a,\"boxSizing\",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?\"border\":\"content\"),d,f)+\"px\"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,\"opacity\");return\"\"===c?\"1\":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":l.cssFloat?\"cssFloat\":\"styleFloat\"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&\"get\"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,\"string\"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f=\"number\"),null!=c&&c===c&&(\"number\"===f&&(c+=e&&e[3]||(n.cssNumber[h]?\"\":\"px\")),l.clearCloneStyle||\"\"!==c||0!==b.indexOf(\"background\")||(i[b]=\"inherit\"),!(g&&\"set\"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&\"get\"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),\"normal\"===f&&b in $a&&(f=$a[b]),\"\"===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each([\"height\",\"width\"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,\"display\"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&\"border-box\"===n.css(a,\"boxSizing\",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||\"\")?.01*parseFloat(RegExp.$1)+\"\":b?\"1\":\"\"},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?\"alpha(opacity=\"+100*b+\")\":\"\",f=d&&d.filter||c.filter||\"\";c.zoom=1,(b>=1||\"\"===b)&&\"\"===n.trim(f.replace(Va,\"\"))&&c.removeAttribute&&(c.removeAttribute(\"filter\"),\"\"===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+\" \"+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:\"inline-block\"},Sa,[a,\"marginRight\"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,\"marginLeft\"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{\nmarginLeft:0},function(){return a.getBoundingClientRect().left}):0))+\"px\":void 0}),n.each({margin:\"\",padding:\"\",border:\"Width\"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f=\"string\"==typeof c?c.split(\" \"):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return\"boolean\"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?\"\":\"px\")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,\"\"),b&&\"auto\"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:\"swing\"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d[\"margin\"+c]=d[\"padding\"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners[\"*\"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,\"fxshow\");c.queue||(h=n._queueHooks(a,\"fx\"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,\"fx\").length||h.empty.fire()})})),1===a.nodeType&&(\"height\"in b||\"width\"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,\"display\"),k=\"none\"===j?n._data(a,\"olddisplay\")||Ma(a.nodeName):j,\"inline\"===k&&\"none\"===n.css(a,\"float\")&&(l.inlineBlockNeedsLayout&&\"inline\"!==Ma(a.nodeName)?p.zoom=1:p.display=\"inline-block\")),c.overflow&&(p.overflow=\"hidden\",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||\"toggle\"===e,e===(q?\"hide\":\"show\")){if(\"show\"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))\"inline\"===(\"none\"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?\"hidden\"in r&&(q=r.hidden):r=n._data(a,\"fxshow\",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,\"fxshow\");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start=\"width\"===d||\"height\"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&\"expand\"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{\"*\":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=[\"*\"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&\"object\"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:\"number\"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue=\"fx\"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css(\"opacity\",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,\"finish\"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return\"string\"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||\"fx\",[]),this.each(function(){var b=!0,e=null!=a&&a+\"queueHooks\",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||\"fx\"),this.each(function(){var b,c=n._data(this),d=c[a+\"queue\"],e=c[a+\"queueHooks\"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each([\"toggle\",\"show\",\"hide\"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||\"boolean\"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb(\"show\"),slideUp:mb(\"hide\"),slideToggle:mb(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||\"fx\",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement(\"input\"),c=d.createElement(\"div\"),e=d.createElement(\"select\"),f=e.appendChild(d.createElement(\"option\"));c=d.createElement(\"div\"),c.setAttribute(\"className\",\"t\"),c.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",a=c.getElementsByTagName(\"a\")[0],b.setAttribute(\"type\",\"checkbox\"),c.appendChild(b),a=c.getElementsByTagName(\"a\")[0],a.style.cssText=\"top:1px\",l.getSetAttribute=\"t\"!==c.className,l.style=/top/.test(a.getAttribute(\"style\")),l.hrefNormalized=\"/a\"===a.getAttribute(\"href\"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement(\"form\").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement(\"input\"),b.setAttribute(\"value\",\"\"),l.input=\"\"===b.getAttribute(\"value\"),b.value=\"t\",b.setAttribute(\"type\",\"radio\"),l.radioValue=\"t\"===b.value}();var rb=/\\r/g,sb=/[\\x20\\t\\r\\n\\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e=\"\":\"number\"==typeof e?e+=\"\":n.isArray(e)&&(e=n.map(e,function(a){return null==a?\"\":a+\"\"})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&\"set\"in b&&void 0!==b.set(this,e,\"value\")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&\"get\"in b&&void 0!==(c=b.get(e,\"value\"))?c:(c=e.value,\"string\"==typeof c?c.replace(rb,\"\"):null==c?\"\":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,\"value\");return null!=b?b:n.trim(n.text(a)).replace(sb,\" \")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f=\"select-one\"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute(\"disabled\"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,\"optgroup\"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each([\"radio\",\"checkbox\"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute(\"value\")?\"on\":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return\"undefined\"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+\"\"),c):e&&\"get\"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&\"radio\"===b&&n.nodeName(a,\"input\")){var c=a.value;return a.setAttribute(\"type\",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase(\"default-\"+c)]=a[d]=!1:n.attr(a,c,\"\"),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase(\"default-\"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase(\"default-\"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,\"input\")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+=\"\",\"value\"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&\"\"!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,\"\"===b?!1:b,c)}},n.each([\"width\",\"height\"],function(a,b){n.attrHooks[b]={set:function(a,c){return\"\"===c?(a.setAttribute(b,\"auto\"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+\"\"}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&\"set\"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&\"get\"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,\"tabindex\");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),l.hrefNormalized||n.each([\"href\",\"src\"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype=\"encoding\");var Bb=/[\\t\\r\\n\\f]/g;function Cb(a){return n.attr(a,\"class\")||\"\"}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if(\"string\"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(Bb,\" \")){g=0;while(f=b[g++])d.indexOf(\" \"+f+\" \")<0&&(d+=f+\" \");h=n.trim(d),e!==h&&n.attr(c,\"class\",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(\" \"+e+\" \").replace(Bb,\" \")){g=0;while(f=b[g++])while(d.indexOf(\" \"+f+\" \")>-1)d=d.replace(\" \"+f+\" \",\" \");h=n.trim(d),e!==h&&n.attr(c,\"class\",h)}}return this},toggleClass:function(a,b){var c=typeof a;return\"boolean\"==typeof b&&\"string\"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if(\"string\"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&\"boolean\"!==c||(b=Cb(this),b&&n._data(this,\"__className__\",b),n.attr(this,\"class\",b||a===!1?\"\":n._data(this,\"__className__\")||\"\"))})},hasClass:function(a){var b,c,d=0;b=\" \"+a+\" \";while(c=this[d++])if(1===c.nodeType&&(\" \"+Cb(c)+\" \").replace(Bb,\" \").indexOf(b)>-1)return!0;return!1}}),n.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\\?/,Gb=/(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+\"\");var c,d=null,e=n.trim(b+\"\");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,\"\")}))?Function(\"return \"+e)():n.error(\"Invalid JSON: \"+b)},n.parseXML=function(b){var c,d;if(!b||\"string\"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,\"text/xml\")):(c=new a.ActiveXObject(\"Microsoft.XMLDOM\"),c.async=\"false\",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName(\"parsererror\").length||n.error(\"Invalid XML: \"+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\\/\\//,Nb=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,Ob={},Pb={},Qb=\"*/\".concat(\"*\"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){\"string\"!=typeof b&&(c=b,b=\"*\");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])\"+\"===d.charAt(0)?(d=d.slice(1)||\"*\",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return\"string\"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e[\"*\"]&&g(\"*\")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while(\"*\"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader(\"Content-Type\"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+\" \"+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if(\"*\"===f)f=i;else if(\"*\"!==i&&i!==f){if(g=j[i+\" \"+f]||j[\"* \"+f],!g)for(e in j)if(h=e.split(\" \"),h[1]===f&&(g=j[i+\" \"+h[0]]||j[\"* \"+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a[\"throws\"])b=g(b);else try{b=g(b)}catch(l){return{state:\"parsererror\",error:g?l:\"No conversion from \"+i+\" to \"+f}}}return{state:\"success\",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:\"GET\",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Qb,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":n.parseJSON,\"text xml\":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){\"object\"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks(\"once memory\"),r=l.statusCode||{},s={},t={},u=0,v=\"canceled\",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+\"\").replace(Hb,\"\").replace(Mb,Sb[1]+\"//\"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||\"*\").toLowerCase().match(G)||[\"\"],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||(\"http:\"===d[1]?\"80\":\"443\"))===(Sb[3]||(\"http:\"===Sb[1]?\"80\":\"443\")))),l.data&&l.processData&&\"string\"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger(\"ajaxStart\"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?\"&\":\"?\")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,\"$1_=\"+Eb++):f+(Fb.test(f)?\"&\":\"?\")+\"_=\"+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader(\"If-Modified-Since\",n.lastModified[f]),n.etag[f]&&w.setRequestHeader(\"If-None-Match\",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader(\"Content-Type\",l.contentType),w.setRequestHeader(\"Accept\",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+(\"*\"!==l.dataTypes[0]?\", \"+Qb+\"; q=0.01\":\"\"):l.accepts[\"*\"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v=\"abort\";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger(\"ajaxSend\",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort(\"timeout\")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,\"No Transport\");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||\"\",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader(\"Last-Modified\"),x&&(n.lastModified[f]=x),x=w.getResponseHeader(\"etag\"),x&&(n.etag[f]=x)),204===b||\"HEAD\"===l.type?y=\"nocontent\":304===b?y=\"notmodified\":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y=\"error\",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+\"\",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?\"ajaxSuccess\":\"ajaxError\",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger(\"ajaxComplete\",[w,l]),--n.active||n.event.trigger(\"ajaxStop\")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,\"json\")},getScript:function(a,b){return n.get(a,void 0,b,\"script\")}}),n.each([\"get\",\"post\"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,\"body\")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,\"display\")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if(\"none\"===Yb(a)||\"hidden\"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\\[\\]$/,ac=/\\r?\\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+\"[\"+(\"object\"==typeof e&&null!=e?b:\"\")+\"]\",e,c,d)});else if(c||\"object\"!==n.type(b))d(a,b);else for(e in b)dc(a+\"[\"+e+\"]\",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?\"\":b,d[d.length]=encodeURIComponent(a)+\"=\"+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join(\"&\").replace($b,\"+\")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,\"elements\");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(\":disabled\")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,\"\\r\\n\")}}):{name:b.name,value:c.replace(ac,\"\\r\\n\")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent(\"onunload\",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&\"withCredentials\"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d[\"X-Requested-With\"]||(d[\"X-Requested-With\"]=\"XMLHttpRequest\");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+\"\");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,\"string\"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=\"\"}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject(\"Microsoft.XMLHTTP\")}catch(b){}}n.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter(\"script\",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type=\"GET\",a.global=!1)}),n.ajaxTransport(\"script\",function(a){if(a.crossDomain){var b,c=d.head||n(\"head\")[0]||d.documentElement;return{send:function(e,f){b=d.createElement(\"script\"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,\"success\"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\\?(?=&|$)|\\?\\?/;n.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var a=jc.pop()||n.expando+\"_\"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter(\"json jsonp\",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?\"url\":\"string\"==typeof b.data&&0===(b.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&kc.test(b.data)&&\"data\");return h||\"jsonp\"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,\"$1\"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?\"&\":\"?\")+b.jsonp+\"=\"+e),b.converters[\"script json\"]=function(){return g||n.error(e+\" was not called\"),g[0]},b.dataTypes[0]=\"json\",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),\"script\"):void 0}),n.parseHTML=function(a,b,c){if(!a||\"string\"!=typeof a)return null;\"boolean\"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if(\"string\"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(\" \");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&\"object\"==typeof b&&(e=\"POST\"),g.length>0&&n.ajax({url:a,type:e||\"GET\",dataType:\"html\",data:b}).done(function(a){f=arguments,g.html(d?n(\"<div>\").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,\"position\"),l=n(a),m={};\"static\"===k&&(a.style.position=\"relative\"),h=l.offset(),f=n.css(a,\"top\"),i=n.css(a,\"left\"),j=(\"absolute\"===k||\"fixed\"===k)&&n.inArray(\"auto\",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),\"using\"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(\"undefined\"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return\"fixed\"===n.css(d,\"position\")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],\"html\")||(c=a.offset()),c.top+=n.css(a[0],\"borderTopWidth\",!0),c.left+=n.css(a[0],\"borderLeftWidth\",!0)),{top:b.top-c.top-n.css(d,\"marginTop\",!0),left:b.left-c.left-n.css(d,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,\"html\")&&\"static\"===n.css(a,\"position\"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each([\"top\",\"left\"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+\"px\":c):void 0})}),n.each({Height:\"height\",Width:\"width\"},function(a,b){n.each({\npadding:\"inner\"+a,content:b,\"\":\"outer\"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||\"boolean\"!=typeof d),g=c||(d===!0||e===!0?\"margin\":\"border\");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement[\"client\"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body[\"scroll\"+a],e[\"scroll\"+a],b.body[\"offset\"+a],e[\"offset\"+a],e[\"client\"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,\"**\"):this.off(b,a||\"**\",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,\"function\"==typeof define&&define.amd&&define(\"jquery\",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});"
  },
  {
    "path": "examples/json/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<script src=\"../../gun.js\"></script>\n\t</head>\n\t<body>\n\t\t<h3>Admin JSON Editor</h3>\n\t\tThis is a live view of your data, you can edit it in realtime or add new field/values.\n\t\t<ul id=\"data\">\n\t\t</ul>\n\t\t<li id=\"model\">\n\t\t\t<b>field</b>:\n\t\t\t<span contenteditable=\"true\">val</span>\n\t\t</li>\n\t\t<ul><li>\n\t\t\t<form id=\"form\">\n\t\t\t\t<label>\n\t\t\t\t\t<input id=\"field\" placeholder=\"field\">\n\t\t\t\t\t<button type=\"submit\">add</button>\n\t\t\t\t</label>\n\t\t\t</form>\n\t\t</li></ul>\n\t\t<script> // minimal jQuery polyfill\n\t\t\tvar $ = function(s, e){ return (e || document).querySelector(s) }\n\t\t\tfunction clean(text){ return String(text).replace(/\\</ig, '&lt;') }\n\t\t</script>\n\t\t<script>\n\t\t\tvar gun = Gun(location.origin + '/gun');\n\t\t\tvar ref = gun.get('example/json/data');\n\t\t\t$('#form').onsubmit = function(e){\n\t\t\t\treturn ref.path( clean($('#field').value) ).put(\"value\"), false; // add a new field, and cancel the form submit.\n\t\t\t}\n\t\t\tdocument.onkeyup = function(e){\n\t\t\t\tif(!e || !e.target){ return } // ignore if no element!\n\t\t\t\tif(!e.target.attributes.contenteditable){ return } // ignore if element content isn't editable!\n\t\t\t\tconsole.log(\"save to\", e.target.previousElementSibling.innerHTML, \":\", e.target.innerHTML);\n\t\t\t\tref.path(clean(e.target.previousElementSibling.innerHTML)) // grab the label, which is in the previous element.\n\t\t\t\t   .put( clean(e.target.innerHTML) ); // insert the value of the text in the current element.\n\t\t\t}\n\t\t\tref.on(function(json){\n\t\t\t\tvar data = Gun.obj.copy(json); // make a snapshot!\n\t\t\t\tdelete data._; // skip meta data!\n\t\t\t\tfor(var field in data){\n\t\t\t\t\tvar val = String(data[field]), id = field.replace(/[^A-z]/ig, ''), elem; // make data safe.\n\t\t\t\t\t(elem = $('#' + id) || $('#data').appendChild($('#model').cloneNode(true))).id = id; // reuse or make element, set id.\n\t\t\t\t\t$('b', elem).innerHTML = clean(field); // escape and display field\n\t\t\t\t\t$('span', elem).innerHTML = clean(val); // escape and display value\n\t\t\t\t}\n\t\t\t});\n\t\t</script>\n\t\t<style>\n\t\t\thtml, body {\n\t\t\t\tfont-family: Verdana, Geneva, sans-serif;\n\t\t\t}\n\t\t\ta, button {\n\t\t\t\tborder: none;\n\t\t\t\tcolor: skyblue;\n\t\t\t\tbackground: transparent;\n\t\t\t\ttext-decoration: none;\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\t\t\tul, li {\n\t\t\t\tlist-style-type: none;\n\t\t\t}\n\t\t\tul:hover, li:hover {\n\t\t\t\tlist-style-type: inherit;\n\t\t\t}\n\t\t\tinput {\n\t\t\t\tborder: none;\n\t\t\t\tborder-bottom: dashed 1px gainsboro;\n\t\t\t}\n\t\t\t.none, #model {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t</style>\n\t</body>\n</html>\n"
  },
  {
    "path": "examples/move/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <!--\n      HELP WANTED!\n      Build decentralized Open Source Uber/Lyft!\n      Need people with experience on:\n       - Leaflet API, zoom and tile coordinates for subscribing to surrounding area.\n       - Creating cute little driving icons that animate with heading/direction.\n    -->\n    <title>Move by Neon ERA</title>\n    <meta content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" name=\"viewport\" />\n\t\t<meta charset=\"utf-8\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/leaflet@1.0.3/dist/leaflet.css\"/>\n    <script src=\"https://cdn.jsdelivr.net/npm/leaflet@1.0.3/dist/leaflet.js\"></script>\n  </head>\n  <body>\n    <div id=\"map\"></div>\n    <a id=\"share\" class=\"hide\"><div class=\"stick button\">Request Ride</div></a>\n    <div id=\"link\" class=\"hide\">\n      <p>Copy and Paste this URL to your friends to share your location:</p>\n      <center>\n        <p id=\"follow\">Location sharing not available!</p>\n      </center>\n      <p><b>Note</b>: Location may not sync when your device's screen is off or the tab is out of focus. You'd need to install this as an app for that to work.</p>\n      <center>\n        <a id=\"close\"><div class=\"button\">Close</div></a>\n      </center>\n    </div>\n    <textarea style=\"display: none; position: fixed; top: 0; left: 0; width: 100%; height: 5em;\" id=\"debug\"></textarea>\n    <style>\n      html, body, #map {\n        margin: 0;\n        padding: 0;\n        width: 100%;\n        height: 100%;\n        font-family: Arial;\n        font-size: 16pt;\n        z-index: 1;\n      }\n      .stick {\n        position: absolute;\n        bottom: 1em;\n        right: 1em;\n      }\n      .button {\n        display: inline-block;\n        padding: 1em;\n        opacity: .5;\n        background: blue;\n        color: white;\n        z-index: 7;\n        transition: .25s all;\n      }\n      .button:hover {\n        opacity: 1;\n      }\n      .hide {\n        display: none;\n      }\n      #link {\n        position: absolute;\n        padding: 1em;\n        top: 2em;\n        left: 2em;\n        right: 2em;\n        bottom: 2em;\n        background: white;\n        overflow: scroll;\n        z-index: 9;\n      }\n      #follow {\n        background: #EEE;\n        padding: .5em;\n        word-wrap: break-word;\n      }\n    </style>\n    <script src=\"/jquery.js\"></script>\n    <script src=\"/gun.js\"></script>\n    <script>\n      function Where(opt, cb){\n        // a small wrapper around Leaflet for map tracking.\n        var where = {};\n        where.opt = opt || {};\n        where.opt.zoom = where.opt.zoom || {};\n        where.opt.err = where.opt.err || function(){};\n\n        where.map = L.map('map', { zoom: where.opt.zoom.level });\n\n        where.opt.tile = where.opt.tile || L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {\n          maxZoom: where.opt.zoom.max,\n          minZoom: where.opt.zoom.min,\n          detectRetina: true,\n          attribution: '&copy; <a href=\"http://osm.org/copyright\">OpenStreetMap</a> contributors'\n        });\n        where.map.addLayer(where.opt.tile);\n\n        L.GridLayer.DebugCoords = L.GridLayer.extend({\n            createTile: function (coords) {\n                var tile = document.createElement('div');\n                tile.innerHTML = [coords.z, coords.x, coords.y].join(', ');\n                tile.style.outline = '1px solid black';\n                return tile;\n            }\n        });\n        L.gridLayer.debugCoords = function(opts) {\n            return new L.GridLayer.DebugCoords(opts);\n        };\n        where.map.addLayer( L.gridLayer.debugCoords() );\n\n        where.opt.zoom.ing = where.opt.zoom.ing || function(){\n          where.opt.zoom.level = where.map.getZoom();\n        }\n        where.map.on('zoomstart', where.opt.zoom.ing, where.opt.err);\n        where.map.on('zoomend', where.opt.zoom.ing, where.opt.err);\n        where.map.on('zoomlevelschange', where.opt.zoom.ing, where.opt.err);\n\n        where.update = function(latlng){\n          if((+new Date) - where.update.last < 400){\n            clearTimeout(where.update.to);\n            where.update.to = setTimeout(function(){\n              where.update(latlng);\n            });\n            return;\n          }\n          var z = 12;\n          var x = lng2tile(latlng.lng, z);\n          var y = lat2tile(latlng.lat, z);\n          console.log(x, y); //\n          where.map.setView(latlng, where.opt.zoom.level, {animate: true});\n          where.marker = where.marker || L.marker().setLatLng(latlng).addTo(where.map);\n          where.marker.setLatLng(latlng).update();\n          where.update.last = (+new Date);\n        }\n\n        if(where.opt.track){\n          where.map.on('locationfound', function(pos){\n            where.update(pos.latlng);\n            where.opt.track(pos);\n          });\n\n          where.map.locate({\n            setView: true,\n            zoom: where.opt.zoom.level,\n            watch: where.opt.continuous || true,\n            timeout: where.opt.timeout || 10000,\n            maximumAge: where.opt.maximumAge || 0,\n            enableHighAccuracy: where.opt.enableHighAccuracy || false\n          });\n        }\n\n        function lng2tile(lng,z) { return (Math.floor((lng+180)/360*Math.pow(2,z))) }\n        function lat2tile(lat,z)  { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,z))) }\n\n        return where;\n      }\n    </script>\n    <script>\n      ;(function(){\n        // the actual GPS tracking app!\n        var gun = Gun(location.origin + '/gun');\n        var gps = {};\n        gps.opt = {\n          continuous: true, // get location just once uses `getCurrentPosition()` while continuously uses `watchPosition()`\n          enableHighAccuracy: true, // HighAccuracy uses more resources, https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions\n          timeout: 5000, // have this long to get data before erring.\n          maximumAge: 0, // set to 0 to actually track.\n          zoom: {max: 18, level: 13, min: 12}\n        }\n        function start(){\n          gps.follow = (window.location.hash || '').slice(1);\n          if(gps.follow){\n            gps.where = gps.where || Where(gps.opt);\n            gps.ref = gun.get('gps/' + gps.follow);\n            gps.ref.on(function(latlng){\n              //$('#debug').value = 'track ' + JSON.stringify(latlng);\n              gps.where.update(latlng);\n            });\n            $('#share').addClass(\"hide\");\n          } else {\n            document.cookie = 'gps=' + (gps.track = (document.cookie.match(/gps\\=(.*?)(\\&|$|\\;)/i)||[])[1] || String.random(5)); // trick with cookies!\n            gps.ref = gun.get('gps/' + gps.track);\n            gps.opt.track = function(pos){\n              pos = pos.latlng;\n              if(gps.follow\n              || Gun.state() - gps.when < 1000\n              || gps.last && gps.last.lat == pos.lat && gps.last.lng == pos.lng){\n                return; // throttle!\n              }\n              gps.when = Gun.state();\n              gps.ref.put(gps.last = pos);\n              //$('#debug').value = JSON.stringify(gps.last);\n            }\n            gps.where = gps.where || Where(gps.opt);\n            $('#follow').text((location.origin + location.pathname) + '#' + gps.track);\n            $('#share').removeClass(\"hide\");\n            $('#share').on('click', function(){\n              $('#link').toggleClass(\"hide\");\n            });\n            $('#close').on('click', function(){\n              $('#link').toggleClass(\"hide\");\n            });\n          }\n        }\n        start();\n        window.onhashchange = start;\n      }());\n    </script>\n  </body>\n</html>"
  },
  {
    "path": "examples/party.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<title>Party by Neon ERA</title>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"./style.css\">\n\t\t<link href=\"https://fonts.googleapis.com/css?family=Raleway:100\" rel=\"stylesheet\">\n\t\t<link href=\"https://fonts.googleapis.com/css?family=Caveat\" rel=\"stylesheet\">\n\t\t<style>\n\t\t\t.write {\n\t\t\t\tfont-family: 'Caveat', sans-serif;\n\t\t\t}\n\t\t\t.shout {\n\t\t\t\tfont-size: 36pt;\n\t\t\t\tfont-size: 6.5vmax;\n\t\t\t}\n\t\t\t.edit {\n\t\t\t\tborder-bottom: 1px dashed white;\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\t\t\t.back {\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: 0.5%;\n\t\t\t\tleft: 0.5em;\n\t\t\t\twidth: 2em;\n\t\t\t\theight: 2em;\n\t\t\t\tz-index: 99999;\n\t\t\t}\n\t\t</style>\n\t\t<script src=\"./jquery.js\"></script>\n\t\t<script src=\"../../gun/gun.js\"></script>\n\t\t<script src=\"../../gun/sea.js\"></script>\n\t\t<script src=\"../../gun/as.js\"></script>\n\t\t<script src=\"../../gun/nts.js\"></script>\n\t\t<script src=\"../../gun/lib/time.js\"></script>\n\t\t<script src=\"../../gun/lib/upload.js\"></script>\n\t\t<script>\n\t\t\t;(() => {\n\t\t\t\tfunction S(){};\n\t\t\t\twindow.S = S;\n\t\t\t\ttry{localStorage.clear();//sessionStorage.clear();\n\t\t\t\t}catch(e){}\n\t\t\t\tS.gun = Gun(location.host? location.origin+'/gun' : 'http://localhost:8765/gun');\n\t\t\t\t//S.gun = Gun('http://localhost:8765/gun');\n\t\t\t\t//S.gun = Gun();\n\t\t\t\tS.app = S.gun.get('examples/social/2');\n\t\t\t\tS.user = S.gun.user();\n\t\t\t\tS.tell = (what, n) => {\n\t\t\t\t\tvar e = $('#tell').find('p');\n\t\t\t\t\te.addClass('notify').text(what);\n\t\t\t\t\tclearTimeout(S.tell.to);\n\t\t\t\t\tS.tell.to = setTimeout(() => { e.removeClass('notify') }, n || 2500);\n\t\t\t\t\treturn what;\n\t\t\t\t}\n\t\t\t\tthis.S = S;\n\t\t\t})();\n\t\t</script>\n\t</head>\n\t<body class=\"whitet black\">\n\n\t\t<div id=\"hi\" class=\"hue page\">\n\t\t\t<style>\n\t\t\t\t#hi input {\n\t\t\t\t\tpadding: 0.4em 0.8em;\n\t\t\t\t\tfont-size: 1.5em;\n\t\t\t\t\tmargin-left: 2%;\n\t\t\t\t\tmargin-bottom: 2%;\n\t\t\t\t}\n\t\t\t\t#hi .faces img {\n\t\t\t\t\tw-idth: 5%;\n\t\t\t\t\twidth: 3em;\n\t\t\t\t\twidth: 7vh;\n\t\t\t\t}\n\t\t\t\t#hi .ton {\n\t\t\t\t\tborder-radius: 1em;\n\t\t\t\t\tfont-size: 150%;\n\t\t\t\t\tfont-size: 2.25vmax;\n\t\t\t\t\tmargin: 0 0.5em 0 0.5em;\n\t\t\t\t\tbackground: transparent;\n\t\t\t\t\tborder: 1px solid white;\n\t\t\t\t\tcolor: white;\n\t\t\t\t\tfont-family: 'Raleway', sans-serif;\n\t\t\t\t}\n\t\t\t\t#hi .ton:hover {\n\t\t\t\t\tbackground: white;\n\t\t\t\t\tcolor: black;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<div class=\"loud write shout rim\">Join the Private Party!</div>\n\t\t\t<div id=\"faces\" class=\"flush faces\">\n\t\t\t\t<div class=\"right\" style=\"max-width: 30em;\">\n\t\t\t\t\t<a href=\"chrome://extensions\" target=\"_blank\"><button class=\"ton\">Install Now</button></a>\n\t\t\t\t\t<a href=\"#\"><button class=\"ton\">How It Works</button></a>\n\t\t\t\t\t<!-- input id=\"halias\" class=\"write jot sap\" placeholder=\"username\">\n\t\t\t\t\t<input id=\"hpass\" type=\"password\" class=\"write jot sap\" placeholder=\"passphrase\" -->\n\t\t\t\t\t<script>\n\t\t\t\t\t\t$.as.route.page('hi', () => {\n\t\t\t\t\t\t\t$('#hpass').on('focus', () => {\n\t\t\t\t\t\t\t\tvar alias = $(\"#halias\").val();\n\t\t\t\t\t\t\t\tif(!alias){ return }\n\t\t\t\t\t\t\t\t$('#alias').val(alias);\n\t\t\t\t\t\t\t\t$.as.route('sign');\n\t\t\t\t\t\t\t\t$('#pass').focus();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tsetTimeout(() => { \n\t\t\t\t\t\t\t\t$('#halias').focus();\n\t\t\t\t\t\t\t\twindow.faces('#faces', 100);\n\t\t\t\t\t\t\t\twindow.faces('#faces2', 40);\n\t\t\t\t\t\t\t},1);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif(!location.hash){\n\t\t\t\t\t\t\t$.as.route('hi');\n\t\t\t\t\t\t}\n\t\t\t\t\t</script>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<script>\n\t\t\t\t;(window.faces = function faces(id, lim, i){\n\t\t\t\t\t//return\n\t\t\t\t\tif(!$('#hi').is(':visible')){ return }\n\t\t\t\t\tif(!id){ return }\n\t\t\t\t\tif(!faces.on){ faces.on = id }\n\t\t\t\t\tif(faces.on != id){\n\t\t\t\t\t\tfaces.was = faces.was || {};\n\t\t\t\t\t\tif(faces.was[id]){ return }\n\t\t\t\t\t\t(faces.next = faces.next || []).push([faces.was[id] = id, lim]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(i >= (lim || 100)){\n\t\t\t\t\t\tfaces.on = null;\n\t\t\t\t\t\tvar tmp = faces.next && faces.next.shift();\n\t\t\t\t\t\ttmp && faces(tmp[0], tmp[1]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t$.ajax({\n\t\t\t\t\t  url: 'https://randomuser.me/api/',\n\t\t\t\t\t  dataType: 'json',\n\t\t\t\t\t  success: (data) => {\n\t\t\t\t\t    faces(id, lim || 100, (i || 0) + 1);\n\t\t\t\t\t    if(!data || !data.results){ return }\n\t\t\t\t\t    var tmp = data.results[0];\n\t\t\t\t\t \t\tif(!tmp || !(tmp = tmp.picture)){ return }\n\t\t\t\t\t  \ttmp = tmp.thumbnail;\n\t\t\t\t\t  \tif(!tmp || faces[tmp]){ return }\n\t\t\t\t\t  \tfaces[tmp] = true;\n\t\t\t\t\t  \ttmp = $('<img>').attr('src', tmp).fadeIn().appendTo(id || '#faces');\n\t\t\t\t\t  \t\n\t\t\t\t\t  \ttmp = tmp.offset(); \n\t\t\t\t\t  \tvar r = Math.random() * 30;\n\t\t\t\t\t  \twindow.fun && window.fun({x: tmp.left - r, y: tmp.top - $(window).scrollTop() - r});\n\t\t\t\t\t  }\n\t\t\t\t\t});\n\t\t\t\t\treturn faces;\n\t\t\t\t});\n\t\t\t</script>\n\t\t\t<div class=\"pad ditch\">\n\t\t\t\t<p class=\"loud\"><i>Your friend has invited you to add a privacy extension to your browser:</i></p>\n\t\t\t\t<p> - Decrypts your friends' messages across any site!</p>\n\t\t\t\t<p> - Stops tech monopolies from selling your private data to advertisers.</p>\n\t\t\t\t<p> - Gives you ownership and control over all your data online.</p>\n\t\t\t\t<p> - Creates a searchable history of your posts, friends, and more!</p>\n\t\t\t</div>\n\t\t\t<div id=\"faces2\" class=\"flush faces\"></div>\n\t\t\t<div class=\"pad ditch\">\n\t\t\t\t<p class=\"loud\"><i>Express your thoughts & connect with the world around you!</i></p>\n\t\t\t\t<p> - Discover new relationships.</p>\n\t\t\t\t<p> - Keep up with friends and news in realtime.</p>\n\t\t\t\t<p> - Watch fun videos and photos from people who share.</p>\n\t\t\t\t<p> - But this time, you own it: fully decentralized.</p>\n\t\t\t</div>\n\t\t\t<div class=\"pad ditch\" style=\"margin-top: 1em;\">\n\t\t\t\t<p><span class=\"loud write shout\">Welcome,</span><!-- span class=\"write loud\">, you are currently connected to <b id=\"peers\" class=\"huet4\">2</b> peers. <b>Why not try to sign up or log in?</b></span --></p>\n\t\t\t\t<p> - Your identity is created here, by you. Not on a server.</p>\n\t\t\t\t<p> - It uses secure <a href=\"https://gun.eco/docs/Cartoon-Cryptography\">cryptographic</a> methods to protect you.</p>\n\t\t\t\t<p> - Only you have access to it, meaning even we cannot reset your password!</p>\n\t\t\t\t<p> - For added security, you can freely <a href=\"https://github.com/amark/gun\">download</a> and run it on your own computer.</p>\n\t\t\t</div>\n\t\t\t<div class=\"black\">\n\t\t\t\t<div class=\"pad huet\">\n\t\t\t\t\t<div class=\"write center\">Crafted with <span class=\"redt\">♥</span> by <span class=\"loud\">era</span>.</div> \n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<div id=\"sign\" class=\"hue page\">\n\t\t\t<style>\n\t\t\t\t#sign input, button {\n\t\t\t\t\tmargin: 0.2em 0;\n\t\t\t\t\tpadding: 0.5em 1em;\n\t\t\t\t}\n\t\t\t\t#sign .sign {\n\t\t\t\t\tfont-size: 30pt;\n\t\t\t\t}\n\t\t\t\t#sign .pow {\n\t\t\t\t\tmargin: 0em 0;\n\t\t\t\t\tpadding: 0em 1em;\n\t\t\t\t\tbackground: transparent;\n\t\t\t\t\tborder-bottom: none;\n\t\t\t\t\ttext-align: center;\n\t\t\t\t\tfont-size: 5vmax;\n\t\t\t\t\tcolor: white;\n\t\t\t\t}\n\t\t\t\t#sign .act {\n\t\t\t\t\tpadding: 0.7em 1em;\n\t\t\t\t\twidth: 5em;\n\t\t\t\t}\n\t\t\t\t#sign .tos {\n\t\t\t\t\tfont-size: 10pt;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<form id=\"inup\" class=\"pad center\">\n\t\t\t\t<div class=\"shout write\">Welcome,</div>\n\t\t\t\t<div class=\"mid row col\">\n\t\t\t\t\t<input id=\"alias\" class=\"write sign jot sap\" placeholder=\"username\">\n\t\t\t\t</div>\n\t\t\t\t<div class=\"mid row col\">\n\t\t\t\t\t<input id=\"pass\" class=\"write sign jot sap\" type=\"password\" placeholder=\"passphrase\">\n\t\t\t\t</div>\n\t\t\t\t<div class=\"mid row col go\">\n\t\t\t\t\t<input id=\"in\" type=\"submit\" class=\"huet sap act symbol\" value=\"sign in\">\n  \t\t\t\t<input id=\"up\" type=\"button\" class=\"huet sap act symbol\" value=\"or up\">\n\t\t\t\t</div>\n\t\t\t\t<span class=\"tos\">By logging in or up, you agree to the <a href=\"https://github.com/amark/gun/blob/master/LICENSE.md\" class=\"tos\" target=\"_blank\">Terms of Service</a>.</span>\n\t\t\t\t<p class=\"tos\"><a href=\"#forgot\">Forgot password?</a></p>\n\t\t\t</form>\n\t\t\t<script>\n\t\t\t\t;(() => {\n\t\t\t\t\tS.route = location.hash.slice(1);\n\t\t\t\t\t$('#up').on('click', (e) => {\n\t\t\t\t\t\tvar form = check();\n\t\t\t\t\t\tif(!form){ return }\n\t\t\t\t\t\t$(\"#up\").addClass('pulse');\n\t\t\t\t\t\tS.user.create(form.alias, form.pass, (ack) => {\n\t\t\t\t\t\t\tif(!ack.wait){ $(\"#up\").removeClass('pulse') }\n\t\t\t\t\t\t\tif(ack.err){ return S.tell(ack.err) }\n\t\t\t\t\t\t\tcheck.up = true;\n\t\t\t\t\t\t\tS.user.auth(form.alias, form.pass);\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t$('#inup').on('submit', (e) => {\n\t\t\t\t\t\tvar form = check();\n\t\t\t\t\t\tif(!form){ return }\n\t\t\t\t\t\t$(\"#in\").addClass('pulse');\n\t\t\t\t\t\tS.user.auth(form.alias, form.pass, (ack) => {\n\t\t\t\t\t\t\tif(!ack.wait){ $(\"#in\").removeClass('pulse') }\n\t\t\t\t\t\t\tif(ack.err){ return S.tell(ack.err) }\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t$('#pass').on('focus', () => {\n\t\t\t\t\t\t$('#alias').addClass('pow');\n\t\t\t\t\t});\n\t\t\t\t\t$('#alias').on('focus', () => {\n\t\t\t\t\t\t$('#alias').removeClass('pow');\n\t\t\t\t\t});\n\t\t\t\t\t$.as.route.page('sign', () => {\n\t\t\t\t\t\tif(!$('#alias').val()){\n\t\t\t\t\t\t\tsetTimeout(() => { $('#alias').focus() },1);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tvar check = () => {\n\t\t\t\t\t\tvar form = {alias: ($('#alias').val()||'').toLowerCase(), pass: $(\"#pass\").val()||''};\n\t\t\t\t\t\tif(6 > form.alias.length){\n\t\t\t\t\t\t\tS.tell(\"Your username needs to be longer than 5 letters.\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(9 > form.pass.length){ \n\t\t\t\t\t\t\tS.tell(\"Your passphrase needs to be longer than 9 letters.\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn form;\n\t\t\t\t\t}\n\t\t\t\t\tS.gun.on('auth', (ack) => {\n\t\t\t\t\t\tif('hi' === S.route){ S.route = '' }\n\t\t\t\t\t\tif('sign' === S.route){ S.route = '' }\n\t\t\t\t\t\tif(check.up){ S.route = 'settings' }\n\t\t\t\t\t\t$.as.route(S.route = S.route || 'draft');\n\t\t\t\t\t});\n\t\t\t\t\tS.user.recall({sessionStorage: 1});\n\t\t\t\t})();\t\n\t\t\t</script>\n\t\t</div>\n\n\t\t<div id=\"forgot\" class=\"hue3 page\">\n\t\t\t<style>\n\t\t\t\t#forgot .fill {\n\t\t\t\t\tpadding: 0.5em;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<a href=\"#sign\" class=\"act back\">&larr;</a>\n\t\t\t<div class=\"pad\">\n\t\t\t\t<p class=\"shout write\">Forgot Password</p>\n\t\t\t\t<form>\n\t\t\t\t\t<ul class=\"rim\">\n\t\t\t\t\t\t<li><input class=\"alias fill sap jot\" placeholder=\"username\"></li>\t\t\t\t\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<p>What was your first pet's name, the type of animal they were, and your favorite quirk about them? <span class=\"pet let\"></span> <span class=\"pet length\"></span>\n\t\t\t\t\t\t\t<input class=\"pet fill sap jot\" placeholder='\"Bubbles was a goldfish, he played dead a lot.\" or \"Fluffy is a cat, but she eats vegetables.\"'></p>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<p>Where was your first kiss? Describe what they looked like. <span class=\"kiss let\"></span> <span class=\"kiss length\"></span>\n\t\t\t\t\t\t\t<input class=\"kiss fill sap jot\" placeholder='\"I kissed Alice in a tree, she was a redhead.\" or \"Bob kissed me at the movies, he had green eyes.\"'></p>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li class=\"loud write help\"></li>\n\t\t\t\t\t\t<li class=\"center rim sit\"><input type=\"submit\" class=\"fill huet3 sap act symbol\" value=\"go\" style=\"width: 4em;\"></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</form>\n\t\t\t\t<script>\n\t\t\t\t\t$.as.route.page('forgot', () => {\n\t\t\t\t\t\tvar _ = $('#forgot'), alias;\n\t\t\t\t\t\t$('.alias',_).on('blur', () => {\n\t\t\t\t\t\t\talias = $('.alias',_).val();\n\t\t\t\t\t\t\tif(!alias){ return }\n\t\t\t\t\t\t\t$('.pet.length',_).val('');\n\t\t\t\t\t\t\t$('.kiss.length',_).val('');\n\t\t\t\t\t\t\tS.gun.get('alias/'+alias).once().map()\n\t\t\t\t\t\t\t\t.get('settings').once(add);\n\t\t\t\t\t\t}).focus();\n\t\t\t\t\t\tvar add = (set) => {\n\t\t\t\t\t\t\tif(!set){ return }\n\t\t\t\t\t\t\tvar tmp;\n\t\t\t\t\t\t\t(tmp = $('.pet.length',_)).text(tmp.text() +' '+ set.pet);\n\t\t\t\t\t\t\t(tmp = $('.kiss.length',_)).text(tmp.text() +' '+ set.kiss);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$('.jot.pet',_).on('keyup', function(){ $('.pet.let',_).text(this.value.length + ' /') });\n\t\t\t\t\t\t$('.jot.kiss',_).on('keyup', function(){ $('.kiss.let',_).text(this.value.length + ' /') });\n\t\t\t\t\t\t$('form',_).on('submit', () => {\n\t\t\t\t\t\t\talias = alias || $('.alias',_).val();\n\t\t\t\t\t\t\tif(!alias){ return S.tell(\"You need a username.\") }\n\t\t\t\t\t\t\t$('.act',_).addClass('pulse');\n\t\t\t\t\t\t\tS.gun.get('alias/' + alias)\n\t\t\t\t\t\t\t\t.once().map()\n\t\t\t\t\t\t\t\t.get('settings')\n\t\t\t\t\t\t\t\t.get('recover')\n\t\t\t\t\t\t\t\t.once(recover);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tvar recover = async (data) => {\n\t\t\t\t\t\t\t$('.act',_).removeClass('pulse');\n\t\t\t\t\t\t\tvar pet = $('.jot.pet',_).val();\n\t\t\t\t\t\t\tvar kiss = $('.jot.kiss',_).val();\n\t\t\t\t\t\t\tvar hint;\n\t\t\t\t\t\t\ttry{ hint = await Gun.SEA.decrypt(data, await Gun.SEA.work(pet, kiss));\n\t\t\t\t\t\t\t}catch(e){}\n\t\t\t\t\t\t\tif(!hint){ return S.tell(\"Nope. Try again!\") }\n\t\t\t\t\t\t\t$('.write.help',_).text(hint);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t</script>\n\t\t\t</div>\n\t\t</div>\n\t\t\n\t\t<div id=\"settings\" class=\"hue2 page\">\n\t\t\t<style>\n\t\t\t\t#settings .fill {\n\t\t\t\t\tpadding: 0.5em;\n\t\t\t\t}\n\t\t\t\t#facedrop img {\n\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\tborder-radius: 100%;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<a href=\"#draft\" class=\"act back\">&larr;</a>\n\t\t\t<div class=\"pad\">\n\t\t\t\t<p class=\"shout write\">Settings</p>\n\t\t\t\t<p>Your username is <i name=\"alias\"></i>.</p>\n\t\t\t\t<p id=\"facedrop\">\n\t\t\t\t\tDrop in a new profile photo: <img class=\"none\">\n\t\t\t\t</p>\n\t\t\t\t<form id=\"recovery\">\n\t\t\t\t\t<p><b>Because no server can reset your password, you must fill out a \"forgot password\" recovery form.</b>\n\t\t\t\t\tWe recommend you use simple, grammatically correct, memorable sentences for your answers.\n\t\t\t\t\tKeep each sentence less than 50 letters so that it will be easy for you to reconstruct -\n\t\t\t\t\tthe length of your reply will be stored as a hint to help.</p>\n\t\t\t\t\t<ol class=\"rim\">\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<p>What was your first pet's name, the type of animal they were, and your favorite quirk about them? <span class=\"pet\"></span>\n\t\t\t\t\t\t\t<input id=\"pet\" class=\"fill sap jot\" placeholder='\"Bubbles was a goldfish, he played dead a lot.\" or \"Fluffy is a cat, but she eats vegetables.\"'></p>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<p>Where was your first kiss? Describe what they looked like. <span class=\"kiss\"></span>\n\t\t\t\t\t\t\t<input id=\"kiss\" class=\"fill sap jot\" placeholder='\"I kissed Alice in a tree, she was a redhead.\" or \"Bob kissed me at the movies, he had green eyes.\"'></p>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<p>The reminder of what your password is:</p>\n\t\t\t\t\t\t\t<input id=\"pw-reminder\" type=\"password\" class=\"fill sap jot\" placeholder='\"Hint: Usual password + name of this app!\"'></p>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li class=\"center rim sit\">\n\t\t\t\t\t\t\t<input type=\"submit\" class=\"fill huet2 sap act symbol\" value=\"set\" style=\"width: 4em;\">\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ol>\n\t\t\t\t</form>\n\t\t\t\t<form id=\"reset\">\n\t\t\t\t\t<style>\n\t\t\t\t\t\t#settings .thin {\n\t\t\t\t\t\t\tmax-width: 15em;\n\t\t\t\t\t\t\tmargin-right: 0.1em;\n\t\t\t\t\t\t\tmargin-bottom: 0.1em;\n\t\t\t\t\t\t}\n\t\t\t\t\t</style>\n\t\t\t\t\t<p>We recommend you use a memorable and grammatically correct sentence as your passphrase.\n\t\t\t\t\tThen write it down on paper and store it some place safe that will be easy for you to find. Here are some tips:</p>\n\t\t\t\t\t<ul class=\"rim\">\n\t\t\t\t\t\t<li> - What gives you purpose and meaning in your life?</li>\n\t\t\t\t\t\t<li> - Say something nice about an important person in your life.</li>\n\t\t\t\t\t\t<li> - If you could work on your hobby full time, what goals would you have?</li>\n\t\t\t\t\t\t<li> - Try to combine all of them into a rhyme, or something funny that makes you laugh.</li>\n\t\t\t\t\t\t<li class=\"center rim\">\n\t\t\t\t\t\t\t<input id=\"oldpass\" type=\"password\" class=\"center thin fill sap jot\" placeholder=\"old passphrase\">\n\t\t\t\t\t\t\t<input id=\"newpass\" type=\"password\" class=\"center thin fill sap jot\" placeholder=\"new passphrase\">\n\t\t\t\t\t\t\t<input id=\"oldnew\" type=\"submit\" class=\"fill huet2 sap act symbol\" value=\"change\" style=\"width: 5em;\"></li>\n\t\t\t\t\t\t<li> - <i>Ex, \"Uncle Ben taught me to fight for what is right, I might have a spider bite.\"</i></li>\n\t\t\t\t\t\t<li> - <i>Ex, \"I am quite better than the Dark Knight, despite any Kryptonite.\"</i></li>\n\t\t\t\t\t\t<li> - <i>Ex, \"Give me a cause for these claws, I have no paws and no laws.\"</i></li>\n\t\t\t\t\t\t<li> - <i>Ex, \"My suite is made of red supplements, with hidden jet compartments.\"</i></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</form>\n\t\t\t\t<p>You are currently connected to <i>2</i> peers.</p>\n\t\t\t\t\n\t\t\t</div>\n\t\t\t<script>\n\t\t\t\t$.as.route.page('settings', () => {\n\t\t\t\t\tif(!S.user.is){ return $.as.route('hi') }\n\t\t\t\t\t$.as('#settings', S.user);\n\t\t\t\t\t\n\t\t\t\t\t;(() => {\n\t\t\t\t\t\t$('#pet').on('keyup', function(){ $('.pet').text(this.value.length + ' letters.') });\n\t\t\t\t\t\t$('#kiss').on('keyup', function(){ $('.kiss').text(this.value.length + ' letters.') });\n\t\t\t\t\t\t\n\t\t\t\t\t\tS.user.get('settings').get('pet').on(function(l){ $('#pet').val(Gun.text.random(l, '*')) });\n\t\t\t\t\t\tS.user.get('settings').get('kiss').on(function(l){ $('#kiss').val(Gun.text.random(l, '*')) });\n\t\t\t\t\t\t\n\t\t\t\t\t\t$('#recovery').on('submit', async (e) => {\n\t\t\t\t\t\t\tvar pet = $('#pet').val();\n\t\t\t\t\t\t\tvar kiss = $('#kiss').val();\n\t\t\t\t\t\t\tvar reminder = $('#pw-reminder').val(); // NOTE: THIS IS TEMPORARY!\n\t\t\t\t\t\t\tif(!pet){ return S.tell(\"Please fill out the pet question!\") }\n\t\t\t\t\t\t\tif(!kiss){ return S.tell(\"Please fill out the first kiss question!\") }\n\t\t\t\t\t\t\tif(!reminder){ return S.tell(\"You need a password reminder.\") } // NOTE: THIS IS TEMPORARY!\n\t\t\t\t\t\t\tif(1+pet.indexOf('*') || 1+kiss.indexOf('*')){ return S.tell(\"Your answer should not have '*' in it.\") }\n\t\t\t\t\t\t\t$('#recovery .act').addClass('pulse');\n\t\t\t\t\t\t\tvar recover = await Gun.SEA.encrypt(reminder, await Gun.SEA.work(pet, kiss));\n\t\t\t\t\t\t\t// NOTE: We are currently doing this manually, in the future we want to\n\t\t\t\t\t\t\t// just automatically log the user back in based off the security questions\n\t\t\t\t\t\t\t// rather than only giving them a \"reminder\" of what theirold  password is.\n\t\t\t\t\t\t\tS.user.get('settings').put({\n\t\t\t\t\t\t\t\trecover: recover,\n\t\t\t\t\t\t\t\tpet: pet.length,\n\t\t\t\t\t\t\t\tkiss: kiss.length\n\t\t\t\t\t\t\t}, (ack) => {\n\t\t\t\t\t\t\t\t$('#recovery .act').removeClass('pulse');\n\t\t\t\t\t\t\t\tS.tell(ack.err || \"Saved!\");\n\t\t\t\t\t\t\t\t$('#pw-reminder').val(''); // NOTE: THIS IS TEMPORARY!\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t})();\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t;(() => {\n\t\t\t\t\t\t$('#reset').on('submit', (e) => {\n\t\t\t\t\t\t\tvar old = $('#oldpass').val();\n\t\t\t\t\t\t\tvar pass = $('#newpass').val() || '';\n\t\t\t\t\t\t\tif(9 > pass.length){ return S.tell(\"Your passphrase needs to be longer than 9 letters.\") }\n\t\t\t\t\t\t\tif(!S.user.is){ return S.tell(\"You need to be logged in to do that.\") }\n\t\t\t\t\t\t\t$('#oldnew').addClass('pulse');\n\t\t\t\t\t\t\tS.user.auth(S.user.is.alias, old, (ack) => {\n\t\t\t\t\t\t\t\t$('#oldnew').removeClass('pulse');\n\t\t\t\t\t\t\t\tS.tell(ack.err || \"Saved!\");\n\t\t\t\t\t\t\t\t$('#oldpass, #newpass').val('');\n\t\t\t\t\t\t\t}, {change: pass});\n\t\t\t\t\t\t});\n\t\t\t\t\t})();\n\n\t\t\t\t\t;(async () => {\n\t\t\t\t\t\t$('#settings').upload(function resize(e, up){\n\t\t\t\t\t\t\tif(e.err){ return }\n\t\t\t\t\t\t\t$('#settings').addClass('pulse');\n\t\t\t\t\t\t\tif(up){ return up.shrink(e, resize, 64) }\n\t\t\t\t\t\t\t$('#settings').removeClass('pulse');\n\t\t\t\t\t\t\t$(\"#facedrop img\").attr('src', e.base64).removeClass('none');\n\t\t\t\t\t\t\tS.user.get('who').get('face').get('small').put(e.base64);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tvar img = await S.user.get('who').get('face').get('small').then();\n\t\t\t\t\t\tif(img){ $('#facedrop img').attr('src', img).removeClass('none') }\n\t\t\t\t\t})();\n\t\t\t\t});\n\t\t\t</script>\n\t\t</div>\n\t\t\n\t\t<div id=\"out\" class=\"hue page\">\n\t\t\t<script>\n\t\t\t\t$.as.route.page('out', () => {\n\t\t\t\t\tS.user.leave();\n\t\t\t\t\tsetTimeout(() => $.as.route('hi'), 1);\n\t\t\t\t});\n\t\t\t</script>\n\t\t</div>\n\n\t\t<div id=\"draft\" class=\"hue page\">\n\t\t\t<style>\n\t\t\t\t.draft {\n\n\t\t\t\t}\n\t\t\t\t#speak {\n\t\t\t\t\toverflow: visible;\n\t\t\t\t\tmargin-bottom: 2em;\n\t\t\t\t}\n\t      #speak .draft:empty:not(:focus):before{\n\t        content:attr(data-text);\n\t      }\n\t\t\t\t#speak input {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tbottom: -1.4em;\n\t\t\t\t\tright: -2%;\n\t\t\t\t\twidth: auto;\n\t\t\t\t\tcolor: white;\n\t\t\t\t\tpadding: 0.3em 1em;\n\t\t\t\t\tbackground: transparent;\n\t\t\t\t\tborder: 1px solid white;\n\t\t\t\t\tborder-radius: 1em;\n\t\t\t\t\ttransition: all 0.2s ease-in;\n\t\t\t\t}\n\t\t\t\t#speak input:hover {\n\t\t\t\t\tbackground: white;\n\t\t\t\t\tcolor: #33cc33;\n\t\t\t\t}\n\t\t\t\t#draft ul .face {\n\t\t\t\t\tfloat: left;\n\t\t\t\t\tborder-radius: 100%;\n\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\theight: 1.5em;\n\t\t\t\t\tmargin-right: 2%;\n\t\t\t\t}\n\t\t\t\t#draft ul, #draft li {\n\t\t\t\t\toverflow: visible;\n\t\t\t\t}\n\t\t\t\t#draft .what {\n\t\t\t\t}\n\t\t\t\t#draft .spoke {\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<p class=\"pad\">Welcome!</p>\n\t\t\t<!--\n\t\t\t\tPeople:\n\t\t\t\t- stare\n\t\t\t\t- scroll\n\t\t\t\t- tap\n\t\t\t\t- type\n\t\t\t\t- talk\n\t\t\t\t- take\n\t\t\t-->\n\t\t\t<form id=\"speak\" class=\"mid row col\">\n\t\t\t\t<div id=\"d0\" class=\"draft spoke gap tint sap editable\" contenteditable=\"true\" style=\"min-height: 1em;\" data-text=\"Express yourself...\"></div>\n\t\t\t\t<input type=\"submit\" class=\"sap hide\" value=\"speak!\">\n\t\t\t</form>\n\t\t\t<ul class=\"mid row col\">\n\t\t\t</ul>\n\t\t\t<div class=\"model\">\n\t\t\t\t<li class=\"spoke tint sap gully\">\n\t\t\t\t\t<div class=\"gap\"><span class=\"sort none\"></span><img class=\"face act none\"><b class=\"name\"></b><div class=\"what\"></div></div>\n\t\t\t\t</li>\n\t\t\t</div>\n\t\t\t<div style=\"height: 10%;\"></div>\n\t\t\t<script>\n\t\t\t\t$.as.route.page('draft', () => {\n\t\t\t\t\tif(!S.user.is){ return $.as.route('hi') }\n\t\t\t\t\t$('#speak').on('keyup', (e) => {\n\t\t\t\t\t\tvar say = $('#speak .draft').text();\n\t\t\t\t\t\tif(!say){\n\t\t\t\t\t\t\t$('#speak input').addClass('hide');\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$('#speak input').removeClass('hide');\n\t\t\t\t\t});\n\t\t\t\t\twindow.user = S.user;\n\t\t\t\t\t$('#speak').on('submit', (e) => {\n\t\t\t\t\t\tvar say = $('#speak .draft').text(); //.text(); // NO NO NO NO NO\n\t\t\t\t\t\tif(!say){ return }\n\t\t\t\t\t\tconsole.log('save!', say);\n\t\t\t\t\t\tvar ref = S.user.get('who').get('all').set({what: say, when: Gun.state()});\n\t\t\t\t\t\t//ref.get('by').put(S.user.get('who'));\n\t\t\t\t\t\t//S.user.get('who').get('said').time(ref);\n\t\t\t\t\t\tS.user.get('who').get('said').set(ref);\n\t\t\t\t\t\t//S.gun.get('@').time(ref);\n\t\t\t\t\t\t$('#speak .draft').text('');\n\t\t\t\t\t});\n\t\t\t\t\t//S.gun.get('@').time(async (data, key, time) => {\n\t\t\t\t\tS.user.get('who').get('said').map().once(async (data, key, time) => {\n\t\t\t\t\t\t//var ref = S.gun.get(data), tmp;\n\t\t\t\t\t\t//var said = await ref.then();\n\t\t\t\t\t\tkey = key.replace(/[^A-Za-z]/ig,'');\n\t\t\t\t\t\tvar tmp, said = data, time = said.when;\n\t\t\t\t\t\tvar $li = $($('#'+key)[0] || $('#draft .model .spoke').clone(true,true).attr('id', key)[(tmp = $.as.sort(time, $('#draft ul').children('li').first()))[0]?'insertBefore':'appendTo'](tmp[0] || '#draft ul'));\n\t\t\t\t\t\ttmp = said.what;\n\t\t\t\t\t\tif(tmp && tmp.ct){\n\t\t\t\t\t\t\ttmp = JSON.stringify(tmp);\n\t\t\t\t\t\t\tsetTimeout(async function(){\n\t\t\t\t\t\t\t\ttmp = await SEA.decrypt(said.what, S.user._.sea);\n\t\t\t\t\t\t\t\t$li.find('.what').text(tmp);\n\t\t\t\t\t\t\t}, 750);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$li.find('.what').text(tmp); // NORMALIAZE!!!\n\t\t\t\t\t\tvar by = S.user.get('who');// ref.get('by');\n\t\t\t\t\t\tby.get('face').get('small').on(data => {\n\t\t\t\t\t\t\t$li.find('.face').attr('src', data).removeClass('none');\n\t\t\t\t\t\t});\n\t\t\t\t\t\tby.get('name').on(data => {\n\t\t\t\t\t\t\tdata && $li.find('b').text(data);\n\t\t\t\t\t\t});\n\t\t\t\t\t\t$li.find('.sort').text(time);\n\t\t\t\t\t\tvar time = new Date(time);\n\t\t\t\t\t\t$li.find('i').text(time.toDateString() + ', ' + time.toLocaleTimeString());\n\t\t\t\t\t\treturn;\n\t\t\t\t\t\tvar who = ref.get('by');\n\t\t\t\t\t\tvar face = await who.get('face').get('small').then();\n\t\t\t\t\t\tif(face){\n\t\t\t\t\t\t\t$li.find('.face').attr('src', face).removeClass('none');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t$(document).on('click', '#speak .act.face', (eve) => {\n\t\t\t\t\t\t\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t</script>\n\t\t</div>\n\n\t\t<div id=\"contacts\" class=\"hue2 page\">\n\t\t\t<style>\n\t\t\t\t#contacts ul .face {\n\t\t\t\t\tfloat: left;\n\t\t\t\t\tborder-radius: 100%;\n\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\theight: 2.5em;\n\t\t\t\t\tmargin-right: 5%;\n\t\t\t\t}\n\t\t\t\t#contacts ul, #contacts li {\n\t\t\t\t\toverflow: visible;\n\t\t\t\t}\n\t\t\t\t#contacts .who {\n\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\tmargin-right: 2%;\n\t\t\t\t\tmin-width: 250px;\n\t\t\t\t\twidth: 15em;\n\t\t\t\t\ttext-align: left;\n\t\t\t\t\tpadding: 2%;\n\t\t\t\t\tvertical-align: middle;\n\t\t\t\t}\n\t\t\t\t#contacts .what {\n\t\t\t\t}\n\t\t\t\t#contacts .spoke {\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<p class=\"pad\">Contacts</p>\n\t\t\t<ul class=\"mid row col center\">\n\t\t\t</ul>\n\t\t\t<div class=\"model\">\n\t\t\t\t<li class=\"who tint sap gully\">\n\t\t\t\t\t<div class=\"gap\">\n\t\t\t\t\t\t<span class=\"sort none\"></span>\n\t\t\t\t\t\t<img class=\"face act none\" crossOrigin=\"Anonymous\">\n\t\t\t\t\t\t<big class=\"name\"></big><br/>\n\t\t\t\t\t\t<i class=\"alias\"></i><br/>\n\t\t\t\t\t\t<small>FB ID:</small> <span class=\"fbid\"></span>\n\t\t\t\t\t</div>\n\t\t\t\t</li>\n\t\t\t</div>\n\t\t\t<div style=\"height: 10%;\"></div>\n\t\t\t<script>\n\t\t\t\t$.as.route.page('contacts', () => {\n\t\t\t\t\tif(!S.user.is){ return $.as.route('sign') }\n\t\t\t\t\t//S.gun.get('@').time(async (data, key, time) => {\n\n\t\t\t\t\t// TODO: BUG!! switch from `on` to `once` to get Martti's {_} empty object bug.\n\t\t\t\t\tvar $ul = $('#contacts ul');\n\t\t\t\t\tS.user.get('old').get('fb').map().on(async function(data){\n\t\t\t\t\t\tconsole.log('contact:', data);\n\t\t\t\t\t\tvar key = data.fbid, tmp;\n\t\t\t\t\t\tif(!key){ return }\n\t\t\t\t\t\tvar $li = $($('#fbid'+key)[0] || $('#contacts .model .who').clone(true,true).attr('id', 'fbid'+key)[(tmp = $.as.sort(data.name||1, $ul.children('li').first()))[0]?'insertBefore':'appendTo'](tmp[0] || $ul));\n\n\t\t\t\t\t\t$li.find('.name').text(data.name);\n\t\t\t\t\t\t$li.find('.alias').text(data.alias);\n\t\t\t\t\t\t$li.find('.fbid').text(data.fbid);\n\t\t\t\t\t\ttmp = $li.find('img').attr('src', data.face || data.tmp);\n\t\t\t\t\t\tif(!data.face){\n\t\t\t\t\t\t\tvar ref = this;\n\t\t\t\t\t\t\t$.fn.upload.shrink(data.tmp, function(b64){\n\t\t\t\t\t\t\t\tref.get('face').put(b64);\n\t\t\t\t\t\t\t}, 100); \n\t\t\t\t\t\t}\n\t\t\t\t\t\t$('html, body').stop(true, true).animate({scrollTop: $ul.height()});\n\t\t\t\t\t});\n\t\t\t\t\tfunction img2b64(img, cb){\n\t\t\t\t\t\tvar c = document.createElement('canvas');\n\t\t\t\t\t\tvar ctx = c.getContext(\"2d\");\n\t\t\t\t\t\tctx.drawImage(img, 10, 10);\n\t\t\t\t\t\tcb(c.toDataURL());\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t</script>\n\t\t</div>\n\n\t\t<div id=\"tell\" class=\"center\">\n\t\t\t<style>\n\t\t\t\t#tell {\n\t\t\t\t\tposition: fixed;\n\t\t\t\t\ttop: 0;\n\t\t\t\t\tleft: 0;\n\t\t\t\t\tright: 0;\n\t\t\t\t\theight: 0;\n\t\t\t\t\toverflow: visible;\n\t\t\t\t}\n\t\t\t\t#tell p {\n\t\t\t\t\ttop: -2em;\n\t\t\t\t\twidth: 50%;\n\t\t\t\t\tborder: solid #222 0.2em;\n\t\t\t\t\tborder-top: none;\n\t\t\t\t\tpadding: 1%;\n\t\t\t\t\topacity: 0;\n\t\t\t\t\tvisibility: hidden;\n\t\t\t\t\ttransition: visibility 2s, all 1s ease-in;\n\t\t\t\t}\n\t\t\t\t#tell .notify {\n\t\t\t\t\ttop: 0em;\n\t\t\t\t\topacity: 0.8;\n\t\t\t\t\tvisibility: visible;\n\t\t\t\t\ttransition: visibility 0s, all 0.25s ease-out;\n\t\t\t\t}\n\t\t\t</style>\n\t\t\t<p class=\"mid black\">Hello world!</p>\n\t\t</div>\n\t\t<!-- textarea id='debug' class=\"no-ne\" style=\"position: fixed; bottom: 0; left: 0; width: 25%; height: 30%\"></textarea -->\n\t\t\n\t\t<script>\n\t\t\t$.as.route.page('person', () => {\n\t\t\t\tif(!user.is){ return $.as.route('hi') }\n\t\t\t\tvar pub = location.hash.split('/').slice(-1)[0];\n\t\t\t\t(pub === user._.pub? $('#say').show() : $('#say').hide());\n\t\t\t\tas('#person', window.PUB = gun.get('pub/'+pub));\n\t\t\t});\n\n\t\t\t$(document).upload(function resize(e, up){\n\t\t\t\tif(e.err){ return }\n\t\t\t\tvar m = $($(\"#d\"+e.id)[0] || $('#d0').clone(true,true).attr('id', 'd'+e.id).css('backgroundImage', '').appendTo('#draft')).addClass('pulse');\n\t\t\t\tif(up){ return up.shrink(e, resize, 1000) }\n\t\t\t\t//console.log(e.id, e.base64);\n\t\t\t\tm.removeClass('pulse').css({\n\t\t\t\t\tbackgroundImage: 'url(' + e.base64 + ')',\n\t\t\t\t\tbackgroundRepeat: 'no-repeat',\n\t\t\t\t\tbackgroundPosition: 'center',\n\t\t\t\t\tbackgroundSize: 'cover'\n\t\t\t\t});\n\t\t\t});\n\t\t</script>\n\t\t<script async src=\"../../gun/lib/fun.js\"></script>\n\t\t<script async src=\"../../gun/lib/normalize.js\"></script>\n\t\t<script async src=\"../../gun/lib/monotype.js\"></script>\n\t\t<script async src=\"../../gun/lib/meta.js\"></script>\n\t</body>\n</html>"
  },
  {
    "path": "examples/react/README.md",
    "content": "You can use `todo.html` as a project template to get started with React + GUN.\n\nIt is an extremely simple in-memory only todo app that you can [try here](https://gunjs.herokuapp.com/react/todo.html).\n\nThere are some other simple examples in the `src` folder.\n\nIf you want to see next level stuff, check out any of [Nick's React apps](https://github.com/nmaro?utf8=%E2%9C%93&tab=repositories&q=gun&type=&language=).\n"
  },
  {
    "path": "examples/react/public/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <link href=\"https://fonts.googleapis.com/css?family=Raleway\" rel=\"stylesheet\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <link rel=\"shortcut icon\" href=\"%PUBLIC_URL%/favicon.ico\">\n    <!--\n      Notice the use of %PUBLIC_URL% in the tag above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n    <title>Gun - React Examples</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start`.\n      To create a production bundle, use `npm run build`.\n    -->\n  </body>\n</html>\n"
  },
  {
    "path": "examples/react/src/App.js",
    "content": "import React, { Component } from 'react'\nimport Gun from 'gun/gun'\nimport Todos from './Todos'\nimport Chat from './Chat'\nimport Json from './Json'\n\nclass App extends Component {\n  constructor() {\n    super();\n    this.gun = Gun(location.origin + '/gun')\n  }\n  \n  render() {\n    return (\n      <div>\n        <h1>React Examples</h1>\n        <h2>Todo</h2>\n        <Todos gun={this.gun} />\n        <br />\n        <hr />\n        <h2>Chat</h2>\n        <Chat gun={this.gun} />\n        <br />\n        <hr />\n        <h2>Json</h2>\n        <Json gun={this.gun} />\n      </div>\n    );\n  }\n}\n\nexport default App;\n"
  },
  {
    "path": "examples/react/src/App.test.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nit('renders without crashing', () => {\n  const div = document.createElement('div');\n  ReactDOM.render(<App />, div);\n});\n"
  },
  {
    "path": "examples/react/src/Chat.js",
    "content": "import React, { Component }  from 'react'\nimport Gun from 'gun/gun'\n\nconst formatMsgs = msgs => Object.keys(msgs)\n  .map(key => ({ key, ...msgs[key] }))\n  .filter(m => Boolean(m.when) && m.key !== '_')\n  .sort((a, b) => a.when - b.when)\n  .map(m => ((m.whenFmt = new Date(m.when).toLocaleString().toLowerCase()), m))\n\nexport default class Chat extends Component {\n  constructor({gun}) {\n    super()\n    this.gun = gun.get('chat');\n    this.state = {\n      newMsg: '',\n      name: (document.cookie.match(/alias\\=(.*?)(\\&|$|\\;)/i)||[])[1]||'',\n      msgs: {},\n    }\n  }\n  componentWillMount() {\n    const tmpState = {}\n    this.gun.map().val((msg, key) => {\n      tmpState[key] = msg\n      this.setState({msgs: Object.assign({}, this.state.msgs, tmpState)})\n    })\n\n  }\n  send = e => {\n    e.preventDefault()\n    const who = this.state.name || 'user' + Gun.text.random(6)\n    this.setState({name: who})\n    document.cookie = ('alias=' + who) \n    const when = Gun.time.is()\n    const key = `${when}_${Gun.text.random(4)}`\n    this.gun.path(key).put({\n      who,\n      when,\n      what: this.state.newMsg,\n    })\n    this.setState({newMsg: ''})\n  }\n  render() {\n    const msgs = formatMsgs(this.state.msgs)\n    return <div>\n      <ul>\n        {msgs.map(msg =>\n          <li key={msg.key}><b>{msg.who}:</b> {msg.what}<span className=\"when\">{msg.whenFmt}</span></li>\n        )}\n      </ul>\n      <form onSubmit={this.send}>\n      <input value={this.state.name} className=\"who\" onChange={e => this.setState({ name: e.target.value})} />\n      <input value={this.state.newMsg} className=\"what\" onChange={e => this.setState({ newMsg: e.target.value})} />\n      <button onClick={this.send}>Send</button>\n      </form>\n    </div>\n  }\n}\n"
  },
  {
    "path": "examples/react/src/Json.js",
    "content": "import React, { Component }  from 'react'\n\nconst formatJson = json =>\n  Object.keys(json)\n    .map(key => ({ key, val: json[key]}))\n    .filter(el => el.key !== '_')\n\nexport default class Json extends Component {\n  constructor({gun}) {\n    super()\n    this.gun = gun.get('json');\n    this.state = { newField: '', json: [] }\n  }\n\n  componentWillMount() {\n    this.gun.on(json => this.setState({ json: formatJson(json) }))\n  }\n\n  edit = key => e => {\n    e.preventDefault()\n    this.gun.path(key).put(e.target.value)\n  }\n  \n  add = e => {\n    e.preventDefault()\n    this.gun.path(this.state.newField).put('value')\n    this.setState({newField: ''})\n  }\n\n  render() {\n    return <div>\n      <ul>\n        {this.state.json.map(({ key, val }) =>\n          <li key={key}><b>{key}:</b> <input value={val} onChange={this.edit(key)} /></li>\n        )}\n      </ul>\n      <form onSubmit={this.add}>\n      <input value={this.state.newField} onChange={e => this.setState({ newField: e.target.value})} />\n      <button onClick={this.add}>Add Field</button>\n      </form>\n    </div>\n  }\n}\n\n"
  },
  {
    "path": "examples/react/src/Todos.js",
    "content": "import React, { Component }  from 'react'\nimport Gun from 'gun/gun'\nimport path from 'gun/lib/path'\nimport './style.css'\n\nconst formatTodos = todos => Object.keys(todos)\n  .map(key => ({ key, val: todos[key] }))\n  .filter(t => Boolean(t.val) && t.key !== '_')\n\nexport default class Todos extends Component {\n  constructor({gun}) {\n    super()\n    this.gun = gun.get('todos');\n    this.state = {newTodo: '', todos: []}\n  }\n\n  componentWillMount() {\n    this.gun.on(todos => this.setState({\n      todos: formatTodos(todos)\n    }))\n  }\n\n  add = e => {\n    e.preventDefault()\n    this.gun.path(Gun.text.random()).put(this.state.newTodo)\n    this.setState({newTodo: ''})\n  }\n\n  del = key => this.gun.path(key).put(null)\n\n  handleChange = e => this.setState({ newTodo: e.target.value})\n\n  render() {\n    return <div>\n      <form onSubmit={this.add}>\n        <input value={this.state.newTodo} onChange={this.handleChange} />\n        <button onClick={this.add}>Add</button>\n      </form>\n      <br />\n      <ul>\n        {this.state.todos.map(todo => <li key={todo.key} onClick={_=>this.del(todo.key)}>{todo.val}</li>)}\n      </ul>\n    </div>\n  }\n\n}\n\n"
  },
  {
    "path": "examples/react/src/index.css",
    "content": "body {\n  margin: 0;\n  padding: 0;\n  font-family: sans-serif;\n}\n"
  },
  {
    "path": "examples/react/src/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\nimport './index.css';\n\nReactDOM.render(\n  <App />,\n  document.getElementById('root')\n);\n"
  },
  {
    "path": "examples/react/src/style.css",
    "content": "html, body { font-size: 14pt; padding: 10px 2.5%;}\n.hide { display: none; }\nform .who { width: 10%; }\nform .what { width: 80%; }\nul { list-style: none; padding: 0; }\nul .when {color: #555; font-size: 12pt; float: right; display: none; }\nli:hover .when {display: inline;}\n"
  },
  {
    "path": "examples/react/todo.html",
    "content": "<!DOCTYPE html>\n<html>\n  <body>\n    <div id=\"app\"></div>\n    <script src=\"https://unpkg.com/react@16/umd/react.development.js\"></script>\n    <script src=\"https://unpkg.com/react-dom@16/umd/react-dom.development.js\"></script>\n    <script src=\"https://unpkg.com/babel-standalone@6/babel.min.js\"></script>\n    <script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\n    <script type=\"text/babel\">\n      const gun = Gun();\n      const App = () => {\n        const newTodo = React.useRef()\n        const [todos, setTodos] = React.useState({})\n\n        React.useEffect(() => {\n          return gun\n            .get(\"todos\")\n            .map()\n            .on((todo, id) => setTodos(todos => ({...todos, [id]: todo }))).off;\n        }, [])\n\n        return (\n          <div>\n            <title>TODOs</title>\n            <ul>{Object.values(todos).map(({title}, i) => <li key={i}>{title}</li>)}</ul>\n            <form onSubmit={e => {\n                e.preventDefault();\n                gun.get(\"todos\").set({ title: newTodo.current.value });\n                newTodo.current.value = ''\n              }}>\n              <input ref={newTodo} placeholder=\"new todo\"/>\n            </form>\n          </div>\n        );\n      };\n      ReactDOM.render(<App />, document.getElementById(\"app\"));\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/react-native/.babelrc",
    "content": "{\n  \"presets\": [\"module:metro-react-native-babel-preset\"]\n}\n"
  },
  {
    "path": "examples/react-native/.buckconfig",
    "content": "\n[android]\n  target = Google Inc.:Google APIs:23\n\n[maven_repositories]\n  central = https://repo1.maven.org/maven2\n"
  },
  {
    "path": "examples/react-native/.flowconfig",
    "content": "[ignore]\n; We fork some components by platform\n.*/*[.]android.js\n\n; Ignore \"BUCK\" generated dirs\n<PROJECT_ROOT>/\\.buckd/\n\n; Ignore unexpected extra \"@providesModule\"\n.*/node_modules/.*/node_modules/fbjs/.*\n\n; Ignore duplicate module providers\n; For RN Apps installed via npm, \"Libraries\" folder is inside\n; \"node_modules/react-native\" but in the source repo it is in the root\n.*/Libraries/react-native/React.js\n\n; Ignore polyfills\n.*/Libraries/polyfills/.*\n\n; Ignore metro\n.*/node_modules/metro/.*\n\n[include]\n\n[libs]\nnode_modules/react-native/Libraries/react-native/react-native-interface.js\nnode_modules/react-native/flow/\nnode_modules/react-native/flow-github/\n\n[options]\nemoji=true\n\nesproposal.optional_chaining=enable\nesproposal.nullish_coalescing=enable\n\nmodule.system=haste\nmodule.system.haste.use_name_reducers=true\n# get basename\nmodule.system.haste.name_reducers='^.*/\\([a-zA-Z0-9$_.-]+\\.js\\(\\.flow\\)?\\)$' -> '\\1'\n# strip .js or .js.flow suffix\nmodule.system.haste.name_reducers='^\\(.*\\)\\.js\\(\\.flow\\)?$' -> '\\1'\n# strip .ios suffix\nmodule.system.haste.name_reducers='^\\(.*\\)\\.ios$' -> '\\1'\nmodule.system.haste.name_reducers='^\\(.*\\)\\.android$' -> '\\1'\nmodule.system.haste.name_reducers='^\\(.*\\)\\.native$' -> '\\1'\nmodule.system.haste.paths.blacklist=.*/__tests__/.*\nmodule.system.haste.paths.blacklist=.*/__mocks__/.*\nmodule.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*\nmodule.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*\n\nmunge_underscores=true\n\nmodule.name_mapper='^[./a-zA-Z0-9$_-]+\\.\\(bmp\\|gif\\|jpg\\|jpeg\\|png\\|psd\\|svg\\|webp\\|m4v\\|mov\\|mp4\\|mpeg\\|mpg\\|webm\\|aac\\|aiff\\|caf\\|m4a\\|mp3\\|wav\\|html\\|pdf\\)$' -> 'RelativeImageStub'\n\nmodule.file_ext=.js\nmodule.file_ext=.jsx\nmodule.file_ext=.json\nmodule.file_ext=.native.js\n\nsuppress_type=$FlowIssue\nsuppress_type=$FlowFixMe\nsuppress_type=$FlowFixMeProps\nsuppress_type=$FlowFixMeState\n\nsuppress_comment=\\\\(.\\\\|\\n\\\\)*\\\\$FlowFixMe\\\\($\\\\|[^(]\\\\|(\\\\(<VERSION>\\\\)? *\\\\(site=[a-z,_]*react_native[a-z,_]*\\\\)?)\\\\)\nsuppress_comment=\\\\(.\\\\|\\n\\\\)*\\\\$FlowIssue\\\\((\\\\(<VERSION>\\\\)? *\\\\(site=[a-z,_]*react_native[a-z,_]*\\\\)?)\\\\)?:? #[0-9]+\nsuppress_comment=\\\\(.\\\\|\\n\\\\)*\\\\$FlowFixedInNextDeploy\nsuppress_comment=\\\\(.\\\\|\\n\\\\)*\\\\$FlowExpectedError\n\n[version]\n^0.78.0\n"
  },
  {
    "path": "examples/react-native/.gitattributes",
    "content": "*.pbxproj -text\n"
  },
  {
    "path": "examples/react-native/.gitignore",
    "content": "# OSX\n#\n.DS_Store\n\n# Xcode\n#\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata\n*.xccheckout\n*.moved-aside\nDerivedData\n*.hmap\n*.ipa\n*.xcuserstate\nproject.xcworkspace\n\n# Android/IntelliJ\n#\nbuild/\n.idea\n.gradle\nlocal.properties\n*.iml\n\n# node.js\n#\nnode_modules/\nnpm-debug.log\nyarn-error.log\n\n# BUCK\nbuck-out/\n\\.buckd/\n*.keystore\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the\n# screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/\n\n*/fastlane/report.xml\n*/fastlane/Preview.html\n*/fastlane/screenshots\n\n# Bundle artifact\n*.jsbundle\n"
  },
  {
    "path": "examples/react-native/.watchmanconfig",
    "content": "{}"
  },
  {
    "path": "examples/react-native/README.md",
    "content": "# Gun on react-native!\n---\n### running the demo\n1. do `yarn install` on the directory of the demo `examples/react-native`\n2. run the demo with `react-native run-ios` or `react-native run-android`\n\n### debugging\ni would recommend using [react-native-debugger](https://github.com/facebook/react-devtools/tree/master/packages/react-devtools) but you can use chrome's debugger as well\n\n- ios: `cmd+D` then `Debug JS Remotely` \n- android: `cmd+M` then `Debug JS Remotely`\n\nnow you have access to the gun globals on the console which are\n`gun` -> the root gun\n`user` -> the gun user\n---\n# how it all of this is done\nsince react-native doesnt provide the crypto module that we desire the most and all of the packages are incompatible with react-native/sea, and so to get `sea.js` working we use a webview(react-native browser) and bridge the crypto module from that browser to the global `window` and thats exactly what `webview-crypto` does, thanks to [webview-crypto repo](https://github.com/saulshanabrook/webview-crypto), the webview-crypto provided in this repo is somewhat the same but modified to get it working and mostly compatible with sea/react-native (even though there is a polyfiller for that but it just doesnt work ;/)."
  },
  {
    "path": "examples/react-native/android/app/BUCK",
    "content": "# To learn about Buck see [Docs](https://buckbuild.com/).\n# To run your application with Buck:\n# - install Buck\n# - `npm start` - to start the packager\n# - `cd android`\n# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname \"CN=Android Debug,O=Android,C=US\"`\n# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck\n# - `buck install -r android/app` - compile, install and run application\n#\n\nlib_deps = []\n\nfor jarfile in glob(['libs/*.jar']):\n  name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]\n  lib_deps.append(':' + name)\n  prebuilt_jar(\n    name = name,\n    binary_jar = jarfile,\n  )\n\nfor aarfile in glob(['libs/*.aar']):\n  name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]\n  lib_deps.append(':' + name)\n  android_prebuilt_aar(\n    name = name,\n    aar = aarfile,\n  )\n\nandroid_library(\n    name = \"all-libs\",\n    exported_deps = lib_deps,\n)\n\nandroid_library(\n    name = \"app-code\",\n    srcs = glob([\n        \"src/main/java/**/*.java\",\n    ]),\n    deps = [\n        \":all-libs\",\n        \":build_config\",\n        \":res\",\n    ],\n)\n\nandroid_build_config(\n    name = \"build_config\",\n    package = \"com.gundemo\",\n)\n\nandroid_resource(\n    name = \"res\",\n    package = \"com.gundemo\",\n    res = \"src/main/res\",\n)\n\nandroid_binary(\n    name = \"app\",\n    keystore = \"//android/keystores:debug\",\n    manifest = \"src/main/AndroidManifest.xml\",\n    package_type = \"debug\",\n    deps = [\n        \":app-code\",\n    ],\n)\n"
  },
  {
    "path": "examples/react-native/android/app/build.gradle",
    "content": "apply plugin: \"com.android.application\"\n\nimport com.android.build.OutputFile\n\n/**\n * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets\n * and bundleReleaseJsAndAssets).\n * These basically call `react-native bundle` with the correct arguments during the Android build\n * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the\n * bundle directly from the development server. Below you can see all the possible configurations\n * and their defaults. If you decide to add a configuration block, make sure to add it before the\n * `apply from: \"../../node_modules/react-native/react.gradle\"` line.\n *\n * project.ext.react = [\n *   // the name of the generated asset file containing your JS bundle\n *   bundleAssetName: \"index.android.bundle\",\n *\n *   // the entry file for bundle generation\n *   entryFile: \"index.android.js\",\n *\n *   // whether to bundle JS and assets in debug mode\n *   bundleInDebug: false,\n *\n *   // whether to bundle JS and assets in release mode\n *   bundleInRelease: true,\n *\n *   // whether to bundle JS and assets in another build variant (if configured).\n *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants\n *   // The configuration property can be in the following formats\n *   //         'bundleIn${productFlavor}${buildType}'\n *   //         'bundleIn${buildType}'\n *   // bundleInFreeDebug: true,\n *   // bundleInPaidRelease: true,\n *   // bundleInBeta: true,\n *\n *   // whether to disable dev mode in custom build variants (by default only disabled in release)\n *   // for example: to disable dev mode in the staging build type (if configured)\n *   devDisabledInStaging: true,\n *   // The configuration property can be in the following formats\n *   //         'devDisabledIn${productFlavor}${buildType}'\n *   //         'devDisabledIn${buildType}'\n *\n *   // the root of your project, i.e. where \"package.json\" lives\n *   root: \"../../\",\n *\n *   // where to put the JS bundle asset in debug mode\n *   jsBundleDirDebug: \"$buildDir/intermediates/assets/debug\",\n *\n *   // where to put the JS bundle asset in release mode\n *   jsBundleDirRelease: \"$buildDir/intermediates/assets/release\",\n *\n *   // where to put drawable resources / React Native assets, e.g. the ones you use via\n *   // require('./image.png')), in debug mode\n *   resourcesDirDebug: \"$buildDir/intermediates/res/merged/debug\",\n *\n *   // where to put drawable resources / React Native assets, e.g. the ones you use via\n *   // require('./image.png')), in release mode\n *   resourcesDirRelease: \"$buildDir/intermediates/res/merged/release\",\n *\n *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means\n *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to\n *   // date; if you have any other folders that you want to ignore for performance reasons (gradle\n *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/\n *   // for example, you might want to remove it from here.\n *   inputExcludes: [\"android/**\", \"ios/**\"],\n *\n *   // override which node gets called and with what additional arguments\n *   nodeExecutableAndArgs: [\"node\"],\n *\n *   // supply additional arguments to the packager\n *   extraPackagerArgs: []\n * ]\n */\n\nproject.ext.react = [\n    entryFile: \"index.js\"\n]\n\napply from: \"../../node_modules/react-native/react.gradle\"\n\n/**\n * Set this to true to create two separate APKs instead of one:\n *   - An APK that only works on ARM devices\n *   - An APK that only works on x86 devices\n * The advantage is the size of the APK is reduced by about 4MB.\n * Upload all the APKs to the Play Store and people will download\n * the correct one based on the CPU architecture of their device.\n */\ndef enableSeparateBuildPerCPUArchitecture = false\n\n/**\n * Run Proguard to shrink the Java bytecode in release builds.\n */\ndef enableProguardInReleaseBuilds = false\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n    buildToolsVersion rootProject.ext.buildToolsVersion\n\n    defaultConfig {\n        applicationId \"com.gundemo\"\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0\"\n        ndk {\n            abiFilters \"armeabi-v7a\", \"x86\"\n        }\n    }\n    splits {\n        abi {\n            reset()\n            enable enableSeparateBuildPerCPUArchitecture\n            universalApk false  // If true, also generate a universal APK\n            include \"armeabi-v7a\", \"x86\"\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled enableProguardInReleaseBuilds\n            proguardFiles getDefaultProguardFile(\"proguard-android.txt\"), \"proguard-rules.pro\"\n        }\n    }\n    // applicationVariants are e.g. debug, release\n    applicationVariants.all { variant ->\n        variant.outputs.each { output ->\n            // For each separate APK per architecture, set a unique version code as described here:\n            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits\n            def versionCodes = [\"armeabi-v7a\":1, \"x86\":2]\n            def abi = output.getFilter(OutputFile.ABI)\n            if (abi != null) {  // null for the universal-debug, universal-release variants\n                output.versionCodeOverride =\n                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode\n            }\n        }\n    }\n}\n\ndependencies {\n    compile project(':react-native-webview-bridge')\n    implementation fileTree(dir: \"libs\", include: [\"*.jar\"])\n    implementation \"com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}\"\n    implementation \"com.facebook.react:react-native:+\"  // From node_modules\n}\n\n// Run this once to be able to run the application with BUCK\n// puts all compile dependencies into folder libs for BUCK to use\ntask copyDownloadableDepsToLibs(type: Copy) {\n    from configurations.compile\n    into 'libs'\n}\n"
  },
  {
    "path": "examples/react-native/android/app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n"
  },
  {
    "path": "examples/react-native/android/app/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.gundemo\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>\n\n    <application\n      android:name=\".MainApplication\"\n      android:label=\"@string/app_name\"\n      android:icon=\"@mipmap/ic_launcher\"\n      android:allowBackup=\"false\"\n      android:theme=\"@style/AppTheme\">\n      <activity\n        android:name=\".MainActivity\"\n        android:label=\"@string/app_name\"\n        android:configChanges=\"keyboard|keyboardHidden|orientation|screenSize\"\n        android:windowSoftInputMode=\"adjustResize\">\n        <intent-filter>\n            <action android:name=\"android.intent.action.MAIN\" />\n            <category android:name=\"android.intent.category.LAUNCHER\" />\n        </intent-filter>\n      </activity>\n      <activity android:name=\"com.facebook.react.devsupport.DevSettingsActivity\" />\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "examples/react-native/android/app/src/main/assets/html/blank.html",
    "content": ""
  },
  {
    "path": "examples/react-native/android/app/src/main/java/com/gundemo/MainActivity.java",
    "content": "package com.gundemo;\n\nimport com.facebook.react.ReactActivity;\n\npublic class MainActivity extends ReactActivity {\n\n    /**\n     * Returns the name of the main component registered from JavaScript.\n     * This is used to schedule rendering of the component.\n     */\n    @Override\n    protected String getMainComponentName() {\n        return \"GunDemo\";\n    }\n}\n"
  },
  {
    "path": "examples/react-native/android/app/src/main/java/com/gundemo/MainApplication.java",
    "content": "package com.gundemo;\n\nimport android.app.Application;\n\nimport com.facebook.react.ReactApplication;\nimport com.github.alinz.reactnativewebviewbridge.WebViewBridgePackage;\nimport com.facebook.react.ReactNativeHost;\nimport com.facebook.react.ReactPackage;\nimport com.facebook.react.shell.MainReactPackage;\nimport com.facebook.soloader.SoLoader;\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class MainApplication extends Application implements ReactApplication {\n\n  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {\n    @Override\n    public boolean getUseDeveloperSupport() {\n      return BuildConfig.DEBUG;\n    }\n\n    @Override\n    protected List<ReactPackage> getPackages() {\n      return Arrays.<ReactPackage>asList(\n          new MainReactPackage(),\n            new WebViewBridgePackage()\n      );\n    }\n\n    @Override\n    protected String getJSMainModuleName() {\n      return \"index\";\n    }\n  };\n\n  @Override\n  public ReactNativeHost getReactNativeHost() {\n    return mReactNativeHost;\n  }\n\n  @Override\n  public void onCreate() {\n    super.onCreate();\n    SoLoader.init(this, /* native exopackage */ false);\n  }\n}\n"
  },
  {
    "path": "examples/react-native/android/app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">GunDemo</string>\n</resources>\n"
  },
  {
    "path": "examples/react-native/android/app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme here. -->\n    </style>\n\n</resources>\n"
  },
  {
    "path": "examples/react-native/android/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    ext {\n        buildToolsVersion = \"27.0.3\"\n        minSdkVersion = 16\n        compileSdkVersion = 27\n        targetSdkVersion = 26\n        supportLibVersion = \"27.1.1\"\n    }\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.1.4'\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        mavenLocal()\n        google()\n        jcenter()\n        maven {\n            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm\n            url \"$rootDir/../node_modules/react-native/android\"\n        }\n    }\n}\n\n\ntask wrapper(type: Wrapper) {\n    gradleVersion = '4.4'\n    distributionUrl = distributionUrl.replace(\"bin\", \"all\")\n}\n"
  },
  {
    "path": "examples/react-native/android/gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-4.4-all.zip\n"
  },
  {
    "path": "examples/react-native/android/gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n"
  },
  {
    "path": "examples/react-native/android/gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "examples/react-native/android/gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windows variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "examples/react-native/android/keystores/BUCK",
    "content": "keystore(\n    name = \"debug\",\n    properties = \"debug.keystore.properties\",\n    store = \"debug.keystore\",\n    visibility = [\n        \"PUBLIC\",\n    ],\n)\n"
  },
  {
    "path": "examples/react-native/android/keystores/debug.keystore.properties",
    "content": "key.store=debug.keystore\nkey.alias=androiddebugkey\nkey.store.password=android\nkey.alias.password=android\n"
  },
  {
    "path": "examples/react-native/android/settings.gradle",
    "content": "rootProject.name = 'GunDemo'\ninclude ':react-native-webview-bridge'\nproject(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')\n\ninclude ':app'\n"
  },
  {
    "path": "examples/react-native/app.json",
    "content": "{\n  \"name\": \"GunDemo\",\n  \"displayName\": \"GunDemo\"\n}"
  },
  {
    "path": "examples/react-native/index.js",
    "content": "/** @format */\nimport './shim';\nimport {AppRegistry} from 'react-native';\nimport App from './src/App';\nimport {name as appName} from './app.json';\n\nAppRegistry.registerComponent(appName, () => App);\nconsole.disableYellowBox = true;\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo/AppDelegate.h",
    "content": "/**\n * Copyright (c) 2015-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (nonatomic, strong) UIWindow *window;\n\n@end\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo/AppDelegate.m",
    "content": "/**\n * Copyright (c) 2015-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import \"AppDelegate.h\"\n\n#import <React/RCTBundleURLProvider.h>\n#import <React/RCTRootView.h>\n\n@implementation AppDelegate\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n  NSURL *jsCodeLocation;\n\n  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@\"index\" fallbackResource:nil];\n\n  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation\n                                                      moduleName:@\"GunDemo\"\n                                               initialProperties:nil\n                                                   launchOptions:launchOptions];\n  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];\n\n  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];\n  UIViewController *rootViewController = [UIViewController new];\n  rootViewController.view = rootView;\n  self.window.rootViewController = rootViewController;\n  [self.window makeKeyAndVisible];\n  return YES;\n}\n\n@end\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo/Base.lproj/LaunchScreen.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"7702\" systemVersion=\"14D136\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\">\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"7701\"/>\n        <capability name=\"Constraints with non-1.0 multipliers\" minToolsVersion=\"5.1\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"480\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Powered by React Native\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"9\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8ie-xW-0ye\">\n                    <rect key=\"frame\" x=\"20\" y=\"439\" width=\"441\" height=\"21\"/>\n                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"GunDemo\" textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"kId-c2-rCX\">\n                    <rect key=\"frame\" x=\"20\" y=\"140\" width=\"441\" height=\"43\"/>\n                    <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"36\"/>\n                    <color key=\"textColor\" cocoaTouchSystemColor=\"darkTextColor\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n            </subviews>\n            <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"calibratedWhite\"/>\n            <constraints>\n                <constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"centerY\" secondItem=\"iN0-l3-epB\" secondAttribute=\"bottom\" multiplier=\"1/3\" constant=\"1\" id=\"5cJ-9S-tgC\"/>\n                <constraint firstAttribute=\"centerX\" secondItem=\"kId-c2-rCX\" secondAttribute=\"centerX\" id=\"Koa-jz-hwk\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"bottom\" constant=\"20\" id=\"Kzo-t9-V3l\"/>\n                <constraint firstItem=\"8ie-xW-0ye\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"MfP-vx-nX0\"/>\n                <constraint firstAttribute=\"centerX\" secondItem=\"8ie-xW-0ye\" secondAttribute=\"centerX\" id=\"ZEH-qu-HZ9\"/>\n                <constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"fvb-Df-36g\"/>\n            </constraints>\n            <nil key=\"simulatedStatusBarMetrics\"/>\n            <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>\n            <point key=\"canvasLocation\" x=\"548\" y=\"455\"/>\n        </view>\n    </objects>\n</document>\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo/Images.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "examples/react-native/ios/GunDemo/Images.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>GunDemo</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>NSLocationWhenInUseUsageDescription</key>\n\t<string></string>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n\t<key>NSLocationWhenInUseUsageDescription</key>\n\t<string></string>\n\t<key>NSAppTransportSecurity</key>\n\t<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->\n\t<dict>\n    <key>NSAllowsArbitraryLoads</key>\n    <true/>\n\t\t<key>NSExceptionDomains</key>\n\t\t<dict>\n\t\t\t<key>localhost</key>\n\t\t\t<dict>\n\t\t\t\t<key>NSExceptionAllowsInsecureHTTPLoads</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo/main.m",
    "content": "/**\n * Copyright (c) 2015-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import <UIKit/UIKit.h>\n\n#import \"AppDelegate.h\"\n\nint main(int argc, char * argv[]) {\n  @autoreleasepool {\n    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n  }\n}\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo-tvOS/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n\t<key>NSLocationWhenInUseUsageDescription</key>\n\t<string></string>\n\t<key>NSAppTransportSecurity</key>\n\t<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->\n\t<dict>\n\t\t<key>NSExceptionDomains</key>\n\t\t<dict>\n\t\t\t<key>localhost</key>\n\t\t\t<dict>\n\t\t\t\t<key>NSExceptionAllowsInsecureHTTPLoads</key>\n\t\t\t\t<true/>\n\t\t\t</dict>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo-tvOSTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "examples/react-native/ios/GunDemo.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };\n\t\t00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };\n\t\t00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };\n\t\t00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };\n\t\t00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };\n\t\t00E356F31AD99517003FC87E /* GunDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* GunDemoTests.m */; };\n\t\t11D1A2F320CAFA9E000508D9 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };\n\t\t133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };\n\t\t139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };\n\t\t139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };\n\t\t13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };\n\t\t13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };\n\t\t13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };\n\t\t13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };\n\t\t140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };\n\t\t146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };\n\t\t2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };\n\t\t2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };\n\t\t2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };\n\t\t2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */; };\n\t\t2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; };\n\t\t2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; };\n\t\t2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; };\n\t\t2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */; };\n\t\t2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */; };\n\t\t2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */; };\n\t\t2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D16E6891FA4F8E400B85C8A /* libReact.a */; };\n\t\t2DCD954D1E0B4F2C00145EB5 /* GunDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* GunDemoTests.m */; };\n\t\t2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };\n\t\t832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };\n\t\t99082B67837B4425B90A62F2 /* libReact-Native-Webview-Bridge.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 929405EFCB05436C99DFC544 /* libReact-Native-Webview-Bridge.a */; };\n\t\tADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 134814201AA4EA6300B7C361;\n\t\t\tremoteInfo = RCTActionSheet;\n\t\t};\n\t\t00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 134814201AA4EA6300B7C361;\n\t\t\tremoteInfo = RCTGeolocation;\n\t\t};\n\t\t00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 58B5115D1A9E6B3D00147676;\n\t\t\tremoteInfo = RCTImage;\n\t\t};\n\t\t00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 58B511DB1A9E6C8500147676;\n\t\t\tremoteInfo = RCTNetwork;\n\t\t};\n\t\t00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 832C81801AAF6DEF007FA2F7;\n\t\t\tremoteInfo = RCTVibration;\n\t\t};\n\t\t00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 13B07F861A680F5B00A75B9A;\n\t\t\tremoteInfo = GunDemo;\n\t\t};\n\t\t139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 134814201AA4EA6300B7C361;\n\t\t\tremoteInfo = RCTSettings;\n\t\t};\n\t\t139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3C86DF461ADF2C930047B81A;\n\t\t\tremoteInfo = RCTWebSocket;\n\t\t};\n\t\t146834031AC3E56700842450 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;\n\t\t\tremoteInfo = React;\n\t\t};\n\t\t2344B40F21A4F53000763E72 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 5188B081163B45E68CD4AE92 /* React-Native-Webview-Bridge.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 4114DC4C1C187C3A003CD988;\n\t\t\tremoteInfo = \"React-Native-Webview-Bridge\";\n\t\t};\n\t\t2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;\n\t\t\tremoteInfo = \"GunDemo-tvOS\";\n\t\t};\n\t\t2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = ADD01A681E09402E00F6D226;\n\t\t\tremoteInfo = \"RCTBlob-tvOS\";\n\t\t};\n\t\t2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3DBE0D001F3B181A0099AA32;\n\t\t\tremoteInfo = fishhook;\n\t\t};\n\t\t2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;\n\t\t\tremoteInfo = \"fishhook-tvOS\";\n\t\t};\n\t\t2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = EBF21BDC1FC498900052F4D5;\n\t\t\tremoteInfo = jsinspector;\n\t\t};\n\t\t2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = EBF21BFA1FC4989A0052F4D5;\n\t\t\tremoteInfo = \"jsinspector-tvOS\";\n\t\t};\n\t\t2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 139D7ECE1E25DB7D00323FB7;\n\t\t\tremoteInfo = \"third-party\";\n\t\t};\n\t\t2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D383D3C1EBD27B6005632C8;\n\t\t\tremoteInfo = \"third-party-tvOS\";\n\t\t};\n\t\t2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 139D7E881E25C6D100323FB7;\n\t\t\tremoteInfo = \"double-conversion\";\n\t\t};\n\t\t2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D383D621EBD27B9005632C8;\n\t\t\tremoteInfo = \"double-conversion-tvOS\";\n\t\t};\n\t\t2DF0FFEA2056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 9936F3131F5F2E4B0010BF04;\n\t\t\tremoteInfo = privatedata;\n\t\t};\n\t\t2DF0FFEC2056DD460020B375 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 9936F32F1F5F2E5B0010BF04;\n\t\t\tremoteInfo = \"privatedata-tvOS\";\n\t\t};\n\t\t3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A283A1D9B042B00D4039D;\n\t\t\tremoteInfo = \"RCTImage-tvOS\";\n\t\t};\n\t\t3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A28471D9B043800D4039D;\n\t\t\tremoteInfo = \"RCTLinking-tvOS\";\n\t\t};\n\t\t3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A28541D9B044C00D4039D;\n\t\t\tremoteInfo = \"RCTNetwork-tvOS\";\n\t\t};\n\t\t3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A28611D9B046600D4039D;\n\t\t\tremoteInfo = \"RCTSettings-tvOS\";\n\t\t};\n\t\t3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A287B1D9B048500D4039D;\n\t\t\tremoteInfo = \"RCTText-tvOS\";\n\t\t};\n\t\t3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A28881D9B049200D4039D;\n\t\t\tremoteInfo = \"RCTWebSocket-tvOS\";\n\t\t};\n\t\t3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A28131D9B038B00D4039D;\n\t\t\tremoteInfo = \"React-tvOS\";\n\t\t};\n\t\t3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D3C059A1DE3340900C268FA;\n\t\t\tremoteInfo = yoga;\n\t\t};\n\t\t3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D3C06751DE3340C00C268FA;\n\t\t\tremoteInfo = \"yoga-tvOS\";\n\t\t};\n\t\t3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4;\n\t\t\tremoteInfo = cxxreact;\n\t\t};\n\t\t3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4;\n\t\t\tremoteInfo = \"cxxreact-tvOS\";\n\t\t};\n\t\t3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4;\n\t\t\tremoteInfo = jschelpers;\n\t\t};\n\t\t3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 3D3CD9181DE5FBD800167DC4;\n\t\t\tremoteInfo = \"jschelpers-tvOS\";\n\t\t};\n\t\t5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 134814201AA4EA6300B7C361;\n\t\t\tremoteInfo = RCTAnimation;\n\t\t};\n\t\t5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 2D2A28201D9B03D100D4039D;\n\t\t\tremoteInfo = \"RCTAnimation-tvOS\";\n\t\t};\n\t\t78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 134814201AA4EA6300B7C361;\n\t\t\tremoteInfo = RCTLinking;\n\t\t};\n\t\t832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 58B5119B1A9E6C1200147676;\n\t\t\tremoteInfo = RCTText;\n\t\t};\n\t\tADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 358F4ED71D1E81A9004DF814;\n\t\t\tremoteInfo = RCTBlob;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = \"<group>\"; };\n\t\t00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTActionSheet.xcodeproj; path = \"../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTGeolocation.xcodeproj; path = \"../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTImage.xcodeproj; path = \"../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTNetwork.xcodeproj; path = \"../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTVibration.xcodeproj; path = \"../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t00E356EE1AD99517003FC87E /* GunDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GunDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t00E356F21AD99517003FC87E /* GunDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GunDemoTests.m; sourceTree = \"<group>\"; };\n\t\t139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTSettings.xcodeproj; path = \"../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTWebSocket.xcodeproj; path = \"../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t13B07F961A680F5B00A75B9A /* GunDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GunDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = GunDemo/AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = GunDemo/AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = \"<group>\"; };\n\t\t13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = GunDemo/Images.xcassets; sourceTree = \"<group>\"; };\n\t\t13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = GunDemo/Info.plist; sourceTree = \"<group>\"; };\n\t\t13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = GunDemo/main.m; sourceTree = \"<group>\"; };\n\t\t146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = React.xcodeproj; path = \"../node_modules/react-native/React/React.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t2D02E47B1E0B4A5D006451C7 /* GunDemo-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"GunDemo-tvOS.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2D02E4901E0B4A5D006451C7 /* GunDemo-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"GunDemo-tvOSTests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t5188B081163B45E68CD4AE92 /* React-Native-Webview-Bridge.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = \"wrapper.pb-project\"; name = \"React-Native-Webview-Bridge.xcodeproj\"; path = \"../node_modules/react-native-webview-bridge/ios/React-Native-Webview-Bridge.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTAnimation.xcodeproj; path = \"../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTLinking.xcodeproj; path = \"../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTText.xcodeproj; path = \"../node_modules/react-native/Libraries/Text/RCTText.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t929405EFCB05436C99DFC544 /* libReact-Native-Webview-Bridge.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = \"libReact-Native-Webview-Bridge.a\"; sourceTree = \"<group>\"; };\n\t\tADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = RCTBlob.xcodeproj; path = \"../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t00E356EB1AD99517003FC87E /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t13B07F8C1A680F5B00A75B9A /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */,\n\t\t\t\t11D1A2F320CAFA9E000508D9 /* libRCTAnimation.a in Frameworks */,\n\t\t\t\t146834051AC3E58100842450 /* libReact.a in Frameworks */,\n\t\t\t\t00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,\n\t\t\t\t00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,\n\t\t\t\t00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,\n\t\t\t\t133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,\n\t\t\t\t00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,\n\t\t\t\t139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,\n\t\t\t\t832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,\n\t\t\t\t00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,\n\t\t\t\t139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,\n\t\t\t\t99082B67837B4425B90A62F2 /* libReact-Native-Webview-Bridge.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E4781E0B4A5D006451C7 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */,\n\t\t\t\t2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */,\n\t\t\t\t2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */,\n\t\t\t\t2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */,\n\t\t\t\t2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */,\n\t\t\t\t2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */,\n\t\t\t\t2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */,\n\t\t\t\t2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E48D1E0B4A5D006451C7 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t00C302A81ABCB8CE00DB3ED1 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t00C302B61ABCB90400DB3ED1 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t00C302BC1ABCB91800DB3ED1 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,\n\t\t\t\t3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t00C302D41ABCB9D200DB3ED1 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,\n\t\t\t\t3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t00C302E01ABCB9EE00DB3ED1 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t00E356EF1AD99517003FC87E /* GunDemoTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00E356F21AD99517003FC87E /* GunDemoTests.m */,\n\t\t\t\t00E356F01AD99517003FC87E /* Supporting Files */,\n\t\t\t);\n\t\t\tpath = GunDemoTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t00E356F01AD99517003FC87E /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t00E356F11AD99517003FC87E /* Info.plist */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t139105B71AF99BAD00B5F7CC /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,\n\t\t\t\t3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t139FDEE71B06529A00C62182 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,\n\t\t\t\t3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,\n\t\t\t\t2D16E6841FA4F8DC00B85C8A /* libfishhook.a */,\n\t\t\t\t2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t13B07FAE1A68108700A75B9A /* GunDemo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t008F07F21AC5B25A0029DE68 /* main.jsbundle */,\n\t\t\t\t13B07FAF1A68108700A75B9A /* AppDelegate.h */,\n\t\t\t\t13B07FB01A68108700A75B9A /* AppDelegate.m */,\n\t\t\t\t13B07FB51A68108700A75B9A /* Images.xcassets */,\n\t\t\t\t13B07FB61A68108700A75B9A /* Info.plist */,\n\t\t\t\t13B07FB11A68108700A75B9A /* LaunchScreen.xib */,\n\t\t\t\t13B07FB71A68108700A75B9A /* main.m */,\n\t\t\t);\n\t\t\tname = GunDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t146834001AC3E56700842450 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t146834041AC3E56700842450 /* libReact.a */,\n\t\t\t\t3DAD3EA31DF850E9000B6D8A /* libReact.a */,\n\t\t\t\t3DAD3EA51DF850E9000B6D8A /* libyoga.a */,\n\t\t\t\t3DAD3EA71DF850E9000B6D8A /* libyoga.a */,\n\t\t\t\t3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */,\n\t\t\t\t3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,\n\t\t\t\t3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,\n\t\t\t\t3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,\n\t\t\t\t2DF0FFDF2056DD460020B375 /* libjsinspector.a */,\n\t\t\t\t2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */,\n\t\t\t\t2DF0FFE32056DD460020B375 /* libthird-party.a */,\n\t\t\t\t2DF0FFE52056DD460020B375 /* libthird-party.a */,\n\t\t\t\t2DF0FFE72056DD460020B375 /* libdouble-conversion.a */,\n\t\t\t\t2DF0FFE92056DD460020B375 /* libdouble-conversion.a */,\n\t\t\t\t2DF0FFEB2056DD460020B375 /* libprivatedata.a */,\n\t\t\t\t2DF0FFED2056DD460020B375 /* libprivatedata-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2344B3E621A4F52C00763E72 /* Recovered References */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t929405EFCB05436C99DFC544 /* libReact-Native-Webview-Bridge.a */,\n\t\t\t);\n\t\t\tname = \"Recovered References\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2344B40C21A4F53000763E72 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2344B41021A4F53000763E72 /* libReact-Native-Webview-Bridge.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2D16E6871FA4F8E400B85C8A /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2D16E6891FA4F8E400B85C8A /* libReact.a */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t5E91572E1DD0AC6500FF2AA8 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,\n\t\t\t\t5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t78C398B11ACF4ADC00677621 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t78C398B91ACF4ADC00677621 /* libRCTLinking.a */,\n\t\t\t\t3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t832341AE1AAA6A7D00B99B32 /* Libraries */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,\n\t\t\t\t146833FF1AC3E56700842450 /* React.xcodeproj */,\n\t\t\t\t00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,\n\t\t\t\tADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */,\n\t\t\t\t00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,\n\t\t\t\t00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,\n\t\t\t\t78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,\n\t\t\t\t00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,\n\t\t\t\t139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,\n\t\t\t\t832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,\n\t\t\t\t00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,\n\t\t\t\t139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,\n\t\t\t\t5188B081163B45E68CD4AE92 /* React-Native-Webview-Bridge.xcodeproj */,\n\t\t\t);\n\t\t\tname = Libraries;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t832341B11AAA6A8300B99B32 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t832341B51AAA6A8300B99B32 /* libRCTText.a */,\n\t\t\t\t3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t83CBB9F61A601CBA00E9B192 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t13B07FAE1A68108700A75B9A /* GunDemo */,\n\t\t\t\t832341AE1AAA6A7D00B99B32 /* Libraries */,\n\t\t\t\t00E356EF1AD99517003FC87E /* GunDemoTests */,\n\t\t\t\t83CBBA001A601CBA00E9B192 /* Products */,\n\t\t\t\t2D16E6871FA4F8E400B85C8A /* Frameworks */,\n\t\t\t\t2344B3E621A4F52C00763E72 /* Recovered References */,\n\t\t\t);\n\t\t\tindentWidth = 2;\n\t\t\tsourceTree = \"<group>\";\n\t\t\ttabWidth = 2;\n\t\t\tusesTabs = 0;\n\t\t};\n\t\t83CBBA001A601CBA00E9B192 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t13B07F961A680F5B00A75B9A /* GunDemo.app */,\n\t\t\t\t00E356EE1AD99517003FC87E /* GunDemoTests.xctest */,\n\t\t\t\t2D02E47B1E0B4A5D006451C7 /* GunDemo-tvOS.app */,\n\t\t\t\t2D02E4901E0B4A5D006451C7 /* GunDemo-tvOSTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tADBDB9201DFEBF0600ED6528 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */,\n\t\t\t\t2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t00E356ED1AD99517003FC87E /* GunDemoTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget \"GunDemoTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t00E356EA1AD99517003FC87E /* Sources */,\n\t\t\t\t00E356EB1AD99517003FC87E /* Frameworks */,\n\t\t\t\t00E356EC1AD99517003FC87E /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t00E356F51AD99517003FC87E /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = GunDemoTests;\n\t\t\tproductName = GunDemoTests;\n\t\t\tproductReference = 00E356EE1AD99517003FC87E /* GunDemoTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t13B07F861A680F5B00A75B9A /* GunDemo */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget \"GunDemo\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t13B07F871A680F5B00A75B9A /* Sources */,\n\t\t\t\t13B07F8C1A680F5B00A75B9A /* Frameworks */,\n\t\t\t\t13B07F8E1A680F5B00A75B9A /* Resources */,\n\t\t\t\t00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = GunDemo;\n\t\t\tproductName = \"Hello World\";\n\t\t\tproductReference = 13B07F961A680F5B00A75B9A /* GunDemo.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t2D02E47A1E0B4A5D006451C7 /* GunDemo-tvOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"GunDemo-tvOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2D02E4771E0B4A5D006451C7 /* Sources */,\n\t\t\t\t2D02E4781E0B4A5D006451C7 /* Frameworks */,\n\t\t\t\t2D02E4791E0B4A5D006451C7 /* Resources */,\n\t\t\t\t2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"GunDemo-tvOS\";\n\t\t\tproductName = \"GunDemo-tvOS\";\n\t\t\tproductReference = 2D02E47B1E0B4A5D006451C7 /* GunDemo-tvOS.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t2D02E48F1E0B4A5D006451C7 /* GunDemo-tvOSTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"GunDemo-tvOSTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t2D02E48C1E0B4A5D006451C7 /* Sources */,\n\t\t\t\t2D02E48D1E0B4A5D006451C7 /* Frameworks */,\n\t\t\t\t2D02E48E1E0B4A5D006451C7 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"GunDemo-tvOSTests\";\n\t\t\tproductName = \"GunDemo-tvOSTests\";\n\t\t\tproductReference = 2D02E4901E0B4A5D006451C7 /* GunDemo-tvOSTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t83CBB9F71A601CBA00E9B192 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 940;\n\t\t\t\tORGANIZATIONNAME = Facebook;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t00E356ED1AD99517003FC87E = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 6.2;\n\t\t\t\t\t\tTestTargetID = 13B07F861A680F5B00A75B9A;\n\t\t\t\t\t};\n\t\t\t\t\t2D02E47A1E0B4A5D006451C7 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2.1;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t\t2D02E48F1E0B4A5D006451C7 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2.1;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t\tTestTargetID = 2D02E47A1E0B4A5D006451C7;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject \"GunDemo\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 83CBB9F61A601CBA00E9B192;\n\t\t\tproductRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;\n\t\t\t\t\tProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */;\n\t\t\t\t\tProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */;\n\t\t\t\t\tProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;\n\t\t\t\t\tProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */;\n\t\t\t\t\tProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 78C398B11ACF4ADC00677621 /* Products */;\n\t\t\t\t\tProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;\n\t\t\t\t\tProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 139105B71AF99BAD00B5F7CC /* Products */;\n\t\t\t\t\tProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 832341B11AAA6A8300B99B32 /* Products */;\n\t\t\t\t\tProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;\n\t\t\t\t\tProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 139FDEE71B06529A00C62182 /* Products */;\n\t\t\t\t\tProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 2344B40C21A4F53000763E72 /* Products */;\n\t\t\t\t\tProjectRef = 5188B081163B45E68CD4AE92 /* React-Native-Webview-Bridge.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 146834001AC3E56700842450 /* Products */;\n\t\t\t\t\tProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t13B07F861A680F5B00A75B9A /* GunDemo */,\n\t\t\t\t00E356ED1AD99517003FC87E /* GunDemoTests */,\n\t\t\t\t2D02E47A1E0B4A5D006451C7 /* GunDemo-tvOS */,\n\t\t\t\t2D02E48F1E0B4A5D006451C7 /* GunDemo-tvOSTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\t00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTActionSheet.a;\n\t\t\tremoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTGeolocation.a;\n\t\t\tremoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTImage.a;\n\t\t\tremoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTNetwork.a;\n\t\t\tremoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTVibration.a;\n\t\t\tremoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTSettings.a;\n\t\t\tremoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTWebSocket.a;\n\t\t\tremoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t146834041AC3E56700842450 /* libReact.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libReact.a;\n\t\t\tremoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2344B41021A4F53000763E72 /* libReact-Native-Webview-Bridge.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libReact-Native-Webview-Bridge.a\";\n\t\t\tremoteRef = 2344B40F21A4F53000763E72 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libRCTBlob-tvOS.a\";\n\t\t\tremoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2D16E6841FA4F8DC00B85C8A /* libfishhook.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libfishhook.a;\n\t\t\tremoteRef = 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libfishhook-tvOS.a\";\n\t\t\tremoteRef = 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFDF2056DD460020B375 /* libjsinspector.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libjsinspector.a;\n\t\t\tremoteRef = 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libjsinspector-tvOS.a\";\n\t\t\tremoteRef = 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFE32056DD460020B375 /* libthird-party.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libthird-party.a\";\n\t\t\tremoteRef = 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFE52056DD460020B375 /* libthird-party.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libthird-party.a\";\n\t\t\tremoteRef = 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFE72056DD460020B375 /* libdouble-conversion.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libdouble-conversion.a\";\n\t\t\tremoteRef = 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFE92056DD460020B375 /* libdouble-conversion.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libdouble-conversion.a\";\n\t\t\tremoteRef = 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFEB2056DD460020B375 /* libprivatedata.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libprivatedata.a;\n\t\t\tremoteRef = 2DF0FFEA2056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t2DF0FFED2056DD460020B375 /* libprivatedata-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libprivatedata-tvOS.a\";\n\t\t\tremoteRef = 2DF0FFEC2056DD460020B375 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libRCTImage-tvOS.a\";\n\t\t\tremoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libRCTLinking-tvOS.a\";\n\t\t\tremoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libRCTNetwork-tvOS.a\";\n\t\t\tremoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libRCTSettings-tvOS.a\";\n\t\t\tremoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libRCTText-tvOS.a\";\n\t\t\tremoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = \"libRCTWebSocket-tvOS.a\";\n\t\t\tremoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3EA31DF850E9000B6D8A /* libReact.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libReact.a;\n\t\t\tremoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libyoga.a;\n\t\t\tremoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libyoga.a;\n\t\t\tremoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libcxxreact.a;\n\t\t\tremoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libcxxreact.a;\n\t\t\tremoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libjschelpers.a;\n\t\t\tremoteRef = 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libjschelpers.a;\n\t\t\tremoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTAnimation.a;\n\t\t\tremoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTAnimation.a;\n\t\t\tremoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTLinking.a;\n\t\t\tremoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\t832341B51AAA6A8300B99B32 /* libRCTText.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTText.a;\n\t\t\tremoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libRCTBlob.a;\n\t\t\tremoteRef = ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t00E356EC1AD99517003FC87E /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t13B07F8E1A680F5B00A75B9A /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,\n\t\t\t\t13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E4791E0B4A5D006451C7 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E48E1E0B4A5D006451C7 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Bundle React Native code and images\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"export NODE_BINARY=node\\n../node_modules/react-native/scripts/react-native-xcode.sh\";\n\t\t};\n\t\t2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Bundle React Native Code And Images\";\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"export NODE_BINARY=node\\n../node_modules/react-native/scripts/react-native-xcode.sh\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t00E356EA1AD99517003FC87E /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t00E356F31AD99517003FC87E /* GunDemoTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t13B07F871A680F5B00A75B9A /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,\n\t\t\t\t13B07FC11A68108700A75B9A /* main.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E4771E0B4A5D006451C7 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */,\n\t\t\t\t2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t2D02E48C1E0B4A5D006451C7 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2DCD954D1E0B4F2C00145EB5 /* GunDemoTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t00E356F51AD99517003FC87E /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 13B07F861A680F5B00A75B9A /* GunDemo */;\n\t\t\ttargetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;\n\t\t};\n\t\t2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 2D02E47A1E0B4A5D006451C7 /* GunDemo-tvOS */;\n\t\t\ttargetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\t13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t13B07FB21A68108700A75B9A /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.xib;\n\t\t\tpath = GunDemo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t00E356F61AD99517003FC87E /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = GunDemoTests/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/$(TARGET_NAME)\\\"\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/GunDemo.app/GunDemo\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t00E356F71AD99517003FC87E /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = GunDemoTests/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/$(TARGET_NAME)\\\"\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/GunDemo.app/GunDemo\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t13B07F941A680F5B00A75B9A /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEAD_CODE_STRIPPING = NO;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = GunDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = GunDemo;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t13B07F951A680F5B00A75B9A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = GunDemo/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)\";\n\t\t\t\tPRODUCT_NAME = GunDemo;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2D02E4971E0B4A5E006451C7 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = \"App Icon & Top Shelf Image\";\n\t\t\t\tASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"GunDemo-tvOS/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/$(TARGET_NAME)\\\"\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.GunDemo-tvOS\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.2;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2D02E4981E0B4A5E006451C7 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = \"App Icon & Top Shelf Image\";\n\t\t\t\tASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"GunDemo-tvOS/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/$(TARGET_NAME)\\\"\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.GunDemo-tvOS\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.2;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t2D02E4991E0B4A5E006451C7 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"GunDemo-tvOSTests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/$(TARGET_NAME)\\\"\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.GunDemo-tvOSTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/GunDemo-tvOS.app/GunDemo-tvOS\";\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 10.1;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t2D02E49A1E0B4A5E006451C7 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../node_modules/react-native-webview-bridge/ios\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"GunDemo-tvOSTests/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tLIBRARY_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(SRCROOT)/$(TARGET_NAME)\\\"\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"-ObjC\",\n\t\t\t\t\t\"-lc++\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.facebook.REACT.GunDemo-tvOSTests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/GunDemo-tvOS.app/GunDemo-tvOS\";\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 10.1;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t83CBBA201A601CBA00E9B192 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t83CBBA211A601CBA00E9B192 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget \"GunDemoTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t00E356F61AD99517003FC87E /* Debug */,\n\t\t\t\t00E356F71AD99517003FC87E /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget \"GunDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t13B07F941A680F5B00A75B9A /* Debug */,\n\t\t\t\t13B07F951A680F5B00A75B9A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"GunDemo-tvOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2D02E4971E0B4A5E006451C7 /* Debug */,\n\t\t\t\t2D02E4981E0B4A5E006451C7 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget \"GunDemo-tvOSTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t2D02E4991E0B4A5E006451C7 /* Debug */,\n\t\t\t\t2D02E49A1E0B4A5E006451C7 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject \"GunDemo\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t83CBBA201A601CBA00E9B192 /* Debug */,\n\t\t\t\t83CBBA211A601CBA00E9B192 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;\n}\n"
  },
  {
    "path": "examples/react-native/ios/GunDemoTests/GunDemoTests.m",
    "content": "/**\n * Copyright (c) 2015-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n#import <UIKit/UIKit.h>\n#import <XCTest/XCTest.h>\n\n#import <React/RCTLog.h>\n#import <React/RCTRootView.h>\n\n#define TIMEOUT_SECONDS 600\n#define TEXT_TO_LOOK_FOR @\"Welcome to React Native!\"\n\n@interface GunDemoTests : XCTestCase\n\n@end\n\n@implementation GunDemoTests\n\n- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test\n{\n  if (test(view)) {\n    return YES;\n  }\n  for (UIView *subview in [view subviews]) {\n    if ([self findSubviewInView:subview matching:test]) {\n      return YES;\n    }\n  }\n  return NO;\n}\n\n- (void)testRendersWelcomeScreen\n{\n  UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];\n  NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];\n  BOOL foundElement = NO;\n\n  __block NSString *redboxError = nil;\n  RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {\n    if (level >= RCTLogLevelError) {\n      redboxError = message;\n    }\n  });\n\n  while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {\n    [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];\n    [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];\n\n    foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {\n      if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {\n        return YES;\n      }\n      return NO;\n    }];\n  }\n\n  RCTSetLogFunction(RCTDefaultLogFunction);\n\n  XCTAssertNil(redboxError, @\"RedBox error: %@\", redboxError);\n  XCTAssertTrue(foundElement, @\"Couldn't find element with text '%@' in %d seconds\", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);\n}\n\n\n@end\n"
  },
  {
    "path": "examples/react-native/ios/GunDemoTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "examples/react-native/package.json",
    "content": "{\n  \"name\": \"GunDemo\",\n  \"version\": \"0.0.1\",\n  \"private\": true,\n  \"scripts\": {\n    \"start\": \"node node_modules/react-native/local-cli/cli.js start\",\n    \"test\": \"jest\"\n  },\n  \"dependencies\": {\n    \"buffer\": \"^5.2.1\",\n    \"encode-utf8\": \"^1.0.2\",\n    \"fast-base64-encode\": \"^1.0.0\",\n    \"gun\": \"^0.9.99999\",\n    \"lodash\": \"^4.17.11\",\n    \"react\": \"16.6.1\",\n    \"react-native\": \"0.57.5\",\n    \"react-native-webview-bridge\": \"^0.40.1\",\n    \"serialize-error\": \"^3.0.0\",\n    \"text-encoding\": \"^0.7.0\"\n  },\n  \"devDependencies\": {\n    \"babel-jest\": \"23.6.0\",\n    \"jest\": \"23.6.0\",\n    \"metro-react-native-babel-preset\": \"0.49.2\",\n    \"react-test-renderer\": \"16.6.1\"\n  },\n  \"jest\": {\n    \"preset\": \"react-native\"\n  }\n}\n"
  },
  {
    "path": "examples/react-native/shim.js",
    "content": "if (typeof __dirname === 'undefined') global.__dirname = '/'\nif (typeof __filename === 'undefined') global.__filename = ''\n\nif (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer\n\nconst isDev = typeof __DEV__ === 'boolean' && __DEV__\nprocess.env['NODE_ENV'] = isDev ? 'development' : 'production'\nif (typeof localStorage !== 'undefined') {\n  localStorage.debug = isDev ? '*' : ''\n}\n\nglobal.location = {\n  protocol: 'file:',\n  host: '',\n};\n\nconst { TextEncoder, TextDecoder } = require('text-encoding');\n\nglobal.TextDecoder = TextDecoder;\nglobal.TextEncoder = TextEncoder;"
  },
  {
    "path": "examples/react-native/src/App/Demo.js",
    "content": "import * as React from 'react';\nimport {View, StyleSheet, TextInput, Text, TouchableOpacity, AsyncStorage} from 'react-native';\n\nimport Gun from 'gun/gun';\nimport 'gun/lib/open';\nimport '../extensions/sea';\n\nimport adapter from '../extensions/asyncStorageAdapter';\n\nGun.on('create', function(db) {\n\tthis.to.next(db);\n\tconst pluginInterop = function(middleware) {\n\t\treturn function(request) {\n\t\t\tthis.to.next(request);\n\t\t\treturn middleware(request, db);\n\t\t};\n\t}\n\n\t// Register the adapter\n\tdb.on('get', pluginInterop(adapter.read));\n\tdb.on('put', pluginInterop(adapter.write));\n});\n\nexport class Demo extends React.Component {\n    constructor() {\n        super();\n\n        this.gun = new Gun();\n        this.user = this.gun.user();\n\n        window.gun = this.gun;\n        window.user = this.user;\n\n        this.state = {\n            authenticated: false,\n            list: [],\n            listText: '',\n            username: '',\n            password: '',\n        }\n    }\n\n    hookUserList = () => {\n        this.user.get('list').open((list) => {\n            const userList = Object.keys(list).reduce((newList, key) => {\n                if (!!Object.keys(list[key]).length) {\n                    return [...newList, {text: list[key].text, key}];\n                };\n            }, []);\n            this.setState({\n                list: userList || [],\n            });\n        });\n    }\n\n    addToList = () => {\n        this.user.get('list').set({text: this.state.listText});\n    }\n\n    doSignin = () => {\n        this.user.auth(this.state.username, this.state.password, (d) => {\n            if (d.err) {\n                console.log('err', d.err);\n                return;\n            }\n\n            this.setState({authenticated: true});\n            this.hookUserList();\n        });\n    }\n\n    doSignup = () => {\n        this.user.create(this.state.username, this.state.password, () => {\n            this.doSignin();\n        });\n    }\n\n    loginScreen = () => {\n        return (\n            <View style={styles.sub}>\n                <TextInput placeholder=\"username\" onChangeText={(username) => this.setState({username})} value={this.state.username} style={styles.input} />\n                <TextInput placeholder=\"password\" secureTextEntry={true} onChangeText={(password) => this.setState({password})} value={this.state.password} style={styles.input} />\n                <TouchableOpacity onPress={this.doSignin} style={styles.button}>\n                    <Text>Sign in</Text>\n                </TouchableOpacity>\n                <TouchableOpacity onPress={this.doSignup} style={styles.button}>\n                    <Text>Sign up</Text>\n                </TouchableOpacity>\n            </View>\n        )\n    }\n\n    userListScreen = () => {\n        return (\n            <View style={styles.sub}>\n                {\n                    !!this.state.list.length && this.state.list.map((item) => <Text key={item.key}>*   {item.text}</Text>)\n                }\n\n                <TextInput placeholder=\"text here\" onChangeText={(listText) => this.setState({listText})} value={this.state.listText} style={styles.input} />\n                <TouchableOpacity onPress={this.addToList} style={styles.button}>\n                    <Text>Add to list</Text>\n                </TouchableOpacity>\n            </View>\n        )\n    }\n\n    render() {\n        return (\n            <View style={styles.container}>\n                {\n                    this.state.authenticated ?\n                    this.userListScreen() : this.loginScreen()\n                }\n            </View>\n        )\n    }\n}\n\nconst styles = StyleSheet.create({\n    container: {\n        justifyContent: 'center',\n        alignItems: 'center',\n        width: '100%',\n        height: '100%',\n    },\n    sub: {\n        height: '50%',\n        width: '60%',\n        justifyContent: 'space-between',\n        padding: 4,\n    },\n    button: {\n        backgroundColor: 'rgba(0, 0, 0, 0.3)',\n        borderWidth: 1,\n        borderRadius: 5,\n        alignItems: 'center',\n        justifyContent: 'center',\n        width: '100%',\n        height: 50,\n    },\n    input: {\n        borderColor: 'black',\n        borderWidth: 1,\n        borderRadius: 5,\n        width: '100%',\n        height: 50,\n        alignItems: 'center',\n        justifyContent: 'center',\n        paddingHorizontal: '32%',\n    },\n});\n"
  },
  {
    "path": "examples/react-native/src/App/PolyFillCrypto.js",
    "content": "import * as React from 'react';\nimport { Platform, StyleSheet, View } from 'react-native';\n\nimport WebViewBridge from 'react-native-webview-bridge';\n\nimport { MainWorker, webViewWorkerString } from '../webview-crypto';\n\nimport encodeUtf8 from 'encode-utf8';\nimport encodeBase64 from 'fast-base64-encode';\n\nconst base64EncodeString = (input) => {\n\treturn encodeBase64(new Uint8Array(encodeUtf8(input)));\n};\n\nconst internalLibIOS = `\n${webViewWorkerString}\n(function () {\n  var wvw = new WebViewWorker(WebViewBridge.send.bind(WebViewBridge));\n  WebViewBridge.onMessage = wvw.onMainMessage.bind(wvw);\n}());\n`;\n\nconst intermediateLib = `\n${webViewWorkerString}\n(function () {\n  var wvw = new WebViewWorker(WebViewBridge.send.bind(WebViewBridge));\n  WebViewBridge.onMessage = wvw.onMainMessage.bind(wvw);\n}());\n`;\n\nconst internalLibAndroid = `eval(window.atob('${base64EncodeString(intermediateLib)}'))`;\n\nexport default class PolyfillCrypto extends React.Component {\n\tshouldComponentUpdate() {\n\t\treturn false;\n\t}\n\n\trender() {\n\t\tlet worker;\n\t\tconst uri = 'file:///android_asset/html/blank.html';\n\t\treturn (\n\t\t\t<View style={styles.hidden}>\n\t\t\t\t<WebViewBridge\n\t\t\t\t\tref={(c) => {\n\t\t\t\t\t\tif (c && !worker) {\n\t\t\t\t\t\t\tworker = new MainWorker(c.sendToBridge, this.props.debug);\n\n\t\t\t\t\t\t\tif (window.crypto) {\n\t\t\t\t\t\t\t\t// we are in chrome debugger\n\t\t\t\t\t\t\t\t// this means overridng the crypto object itself won't\n\t\t\t\t\t\t\t\t// work, so we have to override all of it's methods\n\t\t\t\t\t\t\t\tfor (const name in worker.crypto.subtle) {\n\t\t\t\t\t\t\t\t\twindow.crypto.subtle[name] = worker.crypto.subtle[name];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.crypto.fake = true;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\twindow.crypto = worker.crypto;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twindow.crypto.loaded = true;\n\t\t\t\t\t\t\tconsole.log('*** poly injected', window.crypto);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t\tonBridgeMessage={\n\t\t\t\t\t\t// can't refer to this.state.onBridgeMessage directly\n\t\t\t\t\t\t// because it is not defined when this component is first\n\t\t\t\t\t\t// started, only set in `ref`\n\t\t\t\t\t\t(message) => {\n\t\t\t\t\t\t\tworker.onWebViewMessage(message);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tinjectedJavaScript={\n\t\t\t\t\t\tPlatform.OS === 'android' ? internalLibAndroid : internalLibIOS\n\t\t\t\t\t}\n\t\t\t\t\tonError={(error) => {\n\t\t\t\t\t\tconsole.warn('Error creating webview: ', error);\n\t\t\t\t\t}}\n\t\t\t\t\tjavaScriptEnabled={true}\n\t\t\t\t\tsource={{\n\t\t\t\t\t\turi: Platform.OS === 'android' ? uri : 'about:blank',\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</View>\n\t\t);\n\t}\n}\n\nconst styles = StyleSheet.create({\n\thidden: {\n\t\theight: 0,\n\t\topacity: 0,\n\t},\n});\n"
  },
  {
    "path": "examples/react-native/src/App/app.js",
    "content": "/**\n * Sample React Native App\n * https://github.com/facebook/react-native\n *\n * @format\n * @flow\n */\n\nimport React, {Component} from 'react';\nimport {View} from 'react-native';\n\nimport {Demo} from './Demo';\n\nimport PolyFillCrypto from './PolyFillCrypto';\n\n\nexport class App extends Component {\n  render() {\n    return (\n      <View>\n        <PolyFillCrypto />\n        <Demo/>\n      </View>\n    );\n  }\n}\n"
  },
  {
    "path": "examples/react-native/src/App/index.js",
    "content": "export {App as default} from './app';\n"
  },
  {
    "path": "examples/react-native/src/extensions/asyncStorageAdapter.js",
    "content": "import * as Gun from 'gun';\nimport { AsyncStorage } from 'react-native';\n\nconst readNode = (key, cb) => {\n\tAsyncStorage.getItem(key || '', cb);\n};\n\nconst read = (request, db) => {\n\tconst { get } = request;\n\n\tconst dedupid = request['#'];\n\tconst key = get['#'];\n\tconst field = get['.'];\n\n\tconst done = (err, data) => {\n\t\tif (!data && !err) {\n\t\t\tdb.on('in', {\n\t\t\t\t'@': dedupid,\n\t\t\t\tput: null,\n\t\t\t\terr: null,\n\t\t\t});\n\t\t} else {\n\t\t\tdb.on('in', {\n\t\t\t\t'@': dedupid,\n\t\t\t\tput: Gun.graph.node(data),\n\t\t\t\terr,\n\t\t\t});\n\t\t}\n\t};\n\n\tconst acknowledgeRet = (err, result) => {\n\t\tif (err) {\n\t\t\tdone(err);\n\t\t} else if (result === null) {\n\t\t\t// Nothing found\n\t\t\tdone(null);\n\t\t} else {\n\t\t\tconst temp = JSON.parse(result);\n\t\t\tif (field) {\n\t\t\t\tdone(null, temp[field] || null);\n\t\t\t} else {\n\t\t\t\tdone(null, temp);\n\t\t\t}\n\t\t}\n\t};\n\n\treadNode(key || '', acknowledgeRet);\n};\n\nconst write = (request, db) => {\n\tconst { put: graph } = request;\n\tconst keys = Object.keys(graph);\n\tconst dedupid = graph['#'];\n\n\tconst instructions = keys.map((key) => {\n\t\treturn [key, JSON.stringify(graph[key] || {})];\n\t});\n\n\tAsyncStorage.multiMerge(instructions, (err) => {\n\t\tdb.on('in', {\n\t\t\t'#': dedupid,\n\t\t\tok: !err || err.length === 0,\n\t\t\terr,\n\t\t});\n\t});\n};\n\n// This returns a promise, it can be awaited!\nconst reset = () => AsyncStorage.clear();\n\nexport default {\n\tread,\n\twrite,\n\treset,\n};\n"
  },
  {
    "path": "examples/react-native/src/extensions/sea.js",
    "content": ";(function(){\n\n  /* UNBUILD */\n  var root;\n  if(typeof window !== \"undefined\"){ root = window }\n  if(typeof global !== \"undefined\"){ root = global }\n  root = root || {};\n  var console = root.console || {log: function(){}};\n  function USE(arg, req){\n    return req? () => {} : arg.slice? USE[R(arg)] : function(mod, path){\n      arg(mod = {exports: {}});\n      USE[R(path)] = mod.exports;\n    }\n    function R(p){\n      return p.split('/').slice(-1).toString().replace('.js','');\n    }\n  }\n  if(typeof module !== \"undefined\"){ var common = module }\n  /* UNBUILD */\n\n  ;USE(function(module){\n    // Security, Encryption, and Authorization: SEA.js\n    // MANDATORY READING: https://gun.eco/explainers/data/security.html\n    // IT IS IMPLEMENTED IN A POLYFILL/SHIM APPROACH.\n    // THIS IS AN EARLY ALPHA!\n\n    if(typeof window !== \"undefined\"){ module.window = window }\n\n    var tmp = module.window || module;\n    var SEA = tmp.SEA || {};\n\n    if(SEA.window = module.window){ SEA.window.SEA = SEA }\n\n    try{ if(typeof common !== \"undefined\"){ common.exports = SEA } }catch(e){}\n    module.exports = SEA;\n  })(USE, './root');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    if(SEA.window){\n      if(location.protocol.indexOf('s') < 0\n      && location.host.indexOf('localhost') < 0\n      && location.protocol.indexOf('file:') < 0){\n        location.protocol = 'https:'; // WebCrypto does NOT work without HTTPS!\n      }\n    }\n  })(USE, './https');\n\n  ;USE(function(module){\n    // This is Array extended to have .toString(['utf8'|'hex'|'base64'])\n    function SeaArray() {}\n    Object.assign(SeaArray, { from: Array.from })\n    SeaArray.prototype = Object.create(Array.prototype)\n    SeaArray.prototype.toString = function(enc, start, end) { enc = enc || 'utf8'; start = start || 0;\n      const length = this.length\n      if (enc === 'hex') {\n        const buf = new Uint8Array(this)\n        return [ ...Array(((end && (end + 1)) || length) - start).keys()]\n        .map((i) => buf[ i + start ].toString(16).padStart(2, '0')).join('')\n      }\n      if (enc === 'utf8') {\n        return Array.from(\n          { length: (end || length) - start },\n          (_, i) => String.fromCharCode(this[ i + start])\n        ).join('')\n      }\n      if (enc === 'base64') {\n        return btoa(this)\n      }\n    }\n    module.exports = SeaArray;\n  })(USE, './array');\n\n  ;USE(function(module){\n    // This is Buffer implementation used in SEA. Functionality is mostly\n    // compatible with NodeJS 'safe-buffer' and is used for encoding conversions\n    // between binary and 'hex' | 'utf8' | 'base64'\n    // See documentation and validation for safe implementation in:\n    // https://github.com/feross/safe-buffer#update\n    var SeaArray = USE('./array');\n    function SafeBuffer(...props) {\n      console.warn('new SafeBuffer() is depreciated, please use SafeBuffer.from()')\n      return SafeBuffer.from(...props)\n    }\n    SafeBuffer.prototype = Object.create(Array.prototype)\n    Object.assign(SafeBuffer, {\n      // (data, enc) where typeof data === 'string' then enc === 'utf8'|'hex'|'base64'\n      from() {\n        if (!Object.keys(arguments).length) {\n          throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n        }\n        const input = arguments[0]\n        let buf\n        if (typeof input === 'string') {\n          const enc = arguments[1] || 'utf8'\n          if (enc === 'hex') {\n            const bytes = input.match(/([\\da-fA-F]{2})/g)\n            .map((byte) => parseInt(byte, 16))\n            if (!bytes || !bytes.length) {\n              throw new TypeError('Invalid first argument for type \\'hex\\'.')\n            }\n            buf = SeaArray.from(bytes)\n          } else if (enc === 'utf8') {\n            const length = input.length\n            const words = new Uint16Array(length)\n            Array.from({ length: length }, (_, i) => words[i] = input.charCodeAt(i))\n            buf = SeaArray.from(words)\n          } else if (enc === 'base64') {\n            const dec = atob(input)\n            const length = dec.length\n            const bytes = new Uint8Array(length)\n            Array.from({ length: length }, (_, i) => bytes[i] = dec.charCodeAt(i))\n            buf = SeaArray.from(bytes)\n          } else if (enc === 'binary') {\n            buf = SeaArray.from(input)\n          } else {\n            console.info('SafeBuffer.from unknown encoding: '+enc)\n          }\n          return buf\n        }\n        const byteLength = input.byteLength // what is going on here? FOR MARTTI\n        const length = input.byteLength ? input.byteLength : input.length\n        if (length) {\n          let buf\n          if (input instanceof ArrayBuffer) {\n            buf = new Uint8Array(input)\n          }\n          return SeaArray.from(buf || input)\n        }\n      },\n      // This is 'safe-buffer.alloc' sans encoding support\n      alloc(length, fill = 0 /*, enc*/ ) {\n        return SeaArray.from(new Uint8Array(Array.from({ length: length }, () => fill)))\n      },\n      // This is normal UNSAFE 'buffer.alloc' or 'new Buffer(length)' - don't use!\n      allocUnsafe(length) {\n        return SeaArray.from(new Uint8Array(Array.from({ length : length })))\n      },\n      // This puts together array of array like members\n      concat(arr) { // octet array\n        if (!Array.isArray(arr)) {\n          throw new TypeError('First argument must be Array containing ArrayBuffer or Uint8Array instances.')\n        }\n        return SeaArray.from(arr.reduce((ret, item) => ret.concat(Array.from(item)), []))\n      }\n    })\n    SafeBuffer.prototype.from = SafeBuffer.from\n    SafeBuffer.prototype.toString = SeaArray.prototype.toString\n\n    module.exports = SafeBuffer;\n  })(USE, './buffer');\n\n  ;USE(function(module){\n    const SEA = USE('./root')\n    const Buffer = USE('./buffer')\n    const api = {Buffer: Buffer}\n    var o = {};\n\n    const interval = setInterval(() => {\n      if (window.crypto.loaded) {\n        api.crypto = window.crypto;\n        api.subtle = api.crypto.subtle;\n        api.TextEncoder = window.TextEncoder;\n        api.TextDecoder = window.TextDecoder;\n        api.random = (len) => Buffer.from(api.crypto.getRandomValues(new Uint8Array(Buffer.alloc(len))))\n        console.log('*** gun sea crypto set', api);\n        clearInterval(interval);\n      }\n    }, 500);\n\n    module.exports = api\n  })(USE, './shim');\n\n  ;USE(function(module){\n    const SEA = USE('./root');\n    const Buffer = USE('./buffer')\n    const settings = {}\n    // Encryption parameters\n    const pbkdf2 = { hash: 'SHA-256', iter: 100000, ks: 64 }\n\n    const ecdsaSignProps = { name: 'ECDSA', hash: { name: 'SHA-256' } }\n    const ecdsaKeyProps = { name: 'ECDSA', namedCurve: 'P-256' }\n    const ecdhKeyProps = { name: 'ECDH', namedCurve: 'P-256' }\n\n    const _initial_authsettings = {\n      validity: 12 * 60 * 60, // internally in seconds : 12 hours\n      hook: (props) => props  // { iat, exp, alias, remember }\n      // or return new Promise((resolve, reject) => resolve(props)\n    }\n    // These are used to persist user's authentication \"session\"\n    const authsettings = Object.assign({}, _initial_authsettings)\n    // This creates Web Cryptography API compliant JWK for sign/verify purposes\n    const keysToEcdsaJwk = (pub, d) => {  // d === priv\n      //const [ x, y ] = Buffer.from(pub, 'base64').toString('utf8').split(':') // old\n      const [ x, y ] = pub.split('.') // new\n      var jwk = { kty: \"EC\", crv: \"P-256\", x: x, y: y, ext: true }\n      jwk.key_ops = d ? ['sign'] : ['verify'];\n      if(d){ jwk.d = d }\n      return jwk;\n    }\n\n    Object.assign(settings, {\n      pbkdf2: pbkdf2,\n      ecdsa: {\n        pair: ecdsaKeyProps,\n        sign: ecdsaSignProps\n      },\n      ecdh: ecdhKeyProps,\n      jwk: keysToEcdsaJwk,\n      recall: authsettings\n    })\n    SEA.opt = settings;\n    module.exports = settings\n  })(USE, './settings');\n\n  ;USE(function(module){\n    module.exports = (props) => {\n      try {\n        if(props.slice && 'SEA{' === props.slice(0,4)){\n          props = props.slice(3);\n        }\n        return props.slice ? JSON.parse(props) : props\n      } catch (e) {}  //eslint-disable-line no-empty\n      return props\n    }\n  })(USE, './parse');\n\n  ;USE(function(module){\n    const shim = USE('./shim');\n    const Buffer = USE('./buffer')\n    const parse = USE('./parse')\n    const { pbkdf2 } = USE('./settings')\n    // This internal func returns SHA-256 hashed data for signing\n    const sha256hash = async (mm) => {\n      const m = parse(mm)\n      const hash = await shim.subtle.digest({name: pbkdf2.hash}, new shim.TextEncoder().encode(m))\n      return Buffer.from(hash)\n    }\n    module.exports = sha256hash\n  })(USE, './sha256');\n\n  ;USE(function(module){\n    // This internal func returns SHA-1 hashed data for KeyID generation\n    const __shim = USE('./shim')\n    const subtle = __shim.subtle\n    const ossl = __shim.ossl ? __shim.ossl : subtle\n    const sha1hash = (b) => ossl.digest({name: 'SHA-1'}, new ArrayBuffer(b))\n    module.exports = sha1hash\n  })(USE, './sha1');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var sha = USE('./sha256');\n    var u;\n\n    SEA.work = SEA.work || (async (data, pair, cb, opt) => { try { // used to be named `proof`\n      var salt = (pair||{}).epub || pair; // epub not recommended, salt should be random!\n      var opt = opt || {};\n      if(salt instanceof Function){\n        cb = salt;\n        salt = u;\n      }\n      salt = salt || shim.random(9);\n      if('SHA-256' === opt.name){\n        var rsha = shim.Buffer.from(await sha(data), 'binary').toString('utf8')\n        if(cb){ try{ cb(rsha) }catch(e){console.log(e)} }\n        return rsha;\n      }\n      const key = await (shim.ossl || shim.subtle).importKey(\n        'raw', new shim.TextEncoder().encode(data), { name: opt.name || 'PBKDF2' }, false, ['deriveBits']\n      )\n      const result = await (shim.ossl || shim.subtle).deriveBits({\n        name: opt.name || 'PBKDF2',\n        iterations: opt.iterations || S.pbkdf2.iter,\n        salt: new shim.TextEncoder().encode(opt.salt || salt),\n        hash: opt.hash || S.pbkdf2.hash,\n      }, key, opt.length || (S.pbkdf2.ks * 8))\n      data = shim.random(data.length)  // Erase data in case of passphrase\n      const r = shim.Buffer.from(result, 'binary').toString('utf8')\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.work;\n  })(USE, './work');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var Buff = (typeof Buffer !== 'undefined')? Buffer : shim.Buffer;\n\n    SEA.name = SEA.name || (async (cb, opt) => { try {\n      if(cb){ try{ cb() }catch(e){console.log(e)} }\n      return;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    //SEA.pair = async (data, proof, cb) => { try {\n    SEA.pair = SEA.pair || (async (cb, opt) => { try {\n\n      const ecdhSubtle = shim.ossl || shim.subtle\n      // First: ECDSA keys for signing/verifying...\n      var sa = await shim.subtle.generateKey(S.ecdsa.pair, true, [ 'sign', 'verify' ])\n      .then(async (keys) => {\n        // privateKey scope doesn't leak out from here!\n        //const { d: priv } = await shim.subtle.exportKey('jwk', keys.privateKey)\n        const key = {};\n        key.priv = (await shim.subtle.exportKey('jwk', keys.privateKey)).d;\n        const pub = await shim.subtle.exportKey('jwk', keys.publicKey)\n        //const pub = Buff.from([ x, y ].join(':')).toString('base64') // old\n        key.pub = pub.x+'.'+pub.y // new\n        // x and y are already base64\n        // pub is UTF8 but filename/URL safe (https://www.ietf.org/rfc/rfc3986.txt)\n        // but split on a non-base64 letter.\n        return key;\n      })\n      \n      // To include PGPv4 kind of keyId:\n      // const pubId = await SEA.keyid(keys.pub)\n      // Next: ECDH keys for encryption/decryption...\n\n      try{\n      var dh = await ecdhSubtle.generateKey(S.ecdh, true, ['deriveKey'])\n      .then(async (keys) => {\n        // privateKey scope doesn't leak out from here!\n        const key = {};\n        key.epriv = (await ecdhSubtle.exportKey('jwk', keys.privateKey)).d;\n        const pub = await ecdhSubtle.exportKey('jwk', keys.publicKey)\n        //const epub = Buff.from([ ex, ey ].join(':')).toString('base64') // old\n        key.epub = pub.x+'.'+pub.y // new\n        // ex and ey are already base64\n        // epub is UTF8 but filename/URL safe (https://www.ietf.org/rfc/rfc3986.txt)\n        // but split on a non-base64 letter.\n        return key;\n      })\n      }catch(e){\n        if(SEA.window){ throw e }\n        if(e == 'Error: ECDH is not a supported algorithm'){ console.log('Ignoring ECDH...') }\n        else { throw e }\n      } dh = dh || {};\n\n      const r = { pub: sa.pub, priv: sa.priv, /* pubId, */ epub: dh.epub, epriv: dh.epriv }\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.pair;\n  })(USE, './pair');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var sha256hash = USE('./sha256');\n\n    SEA.sign = SEA.sign || (async (data, pair, cb, opt) => { try {\n      if(data && data.slice\n      && 'SEA{' === data.slice(0,4)\n      && '\"m\":' === data.slice(4,8)){\n        // TODO: This would prevent pair2 signing pair1's signature.\n        // So we may want to change this in the future.\n        // but for now, we want to prevent duplicate double signature.\n        if(cb){ try{ cb(data) }catch(e){console.log(e)} }\n        return data;\n      }\n      opt = opt || {};\n      if(!(pair||opt).priv){\n        pair = await SEA.I(null, {what: data, how: 'sign', why: opt.why});\n      }\n      const pub = pair.pub\n      const priv = pair.priv\n      const jwk = S.jwk(pub, priv)\n      const msg = JSON.stringify(data)\n      const hash = await sha256hash(msg)\n      const sig = await (shim.ossl || shim.subtle).importKey('jwk', jwk, S.ecdsa.pair, false, ['sign'])\n      .then((key) => (shim.ossl || shim.subtle).sign(S.ecdsa.sign, key, new Uint8Array(hash))) // privateKey scope doesn't leak out from here!\n      const r = 'SEA'+JSON.stringify({m: msg, s: shim.Buffer.from(sig, 'binary').toString('utf8')});\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.sign;\n  })(USE, './sign');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var sha256hash = USE('./sha256');\n    var parse = USE('./parse');\n    var u;\n\n    SEA.verify = SEA.verify || (async (data, pair, cb, opt) => { try {\n      const json = parse(data)\n      if(false === pair){ // don't verify!\n        const raw = (json !== data)? \n          (json.s && json.m)? parse(json.m) : data\n        : json;\n        if(cb){ try{ cb(raw) }catch(e){console.log(e)} }\n        return raw;\n      }\n      opt = opt || {};\n      // SEA.I // verify is free! Requires no user permission.\n      if(json === data){ throw \"No signature on data.\" }\n      const pub = pair.pub || pair\n      const jwk = S.jwk(pub)\n      const key = await (shim.ossl || shim.subtle).importKey('jwk', jwk, S.ecdsa.pair, false, ['verify'])\n      const hash = await sha256hash(json.m)\n      const sig = new Uint8Array(shim.Buffer.from(json.s, 'utf8'))\n      const check = await (shim.ossl || shim.subtle).verify(S.ecdsa.sign, key, sig, new Uint8Array(hash))\n      if(!check){ throw \"Signature did not match.\" }\n      const r = check? parse(json.m) : u;\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e); // mismatched owner FOR MARTTI\n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.verify;\n  })(USE, './verify');\n\n  ;USE(function(module){\n    var shim = USE('./shim');\n    var sha256hash = USE('./sha256');\n\n    const importGen = async (key, salt, opt) => {\n      //const combo = shim.Buffer.concat([shim.Buffer.from(key, 'utf8'), salt || shim.random(8)]).toString('utf8') // old\n      var opt = opt || {};\n      const combo = key + (salt || shim.random(8)).toString('utf8'); // new\n      const hash = shim.Buffer.from(await sha256hash(combo), 'binary')\n      return await shim.subtle.importKey('raw', new Uint8Array(hash), opt.name || 'AES-GCM', false, ['encrypt', 'decrypt'])\n    }\n    module.exports = importGen;\n  })(USE, './aeskey');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var aeskey = USE('./aeskey');\n\n    SEA.encrypt = SEA.encrypt || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      var key = (pair||opt).epriv || pair;\n      if(!key){\n        pair = await SEA.I(null, {what: data, how: 'encrypt', why: opt.why});\n        key = pair.epriv || pair;\n      }\n      const msg = JSON.stringify(data)\n      const rand = {s: shim.random(8), iv: shim.random(16)};\n      const ct = await aeskey(key, rand.s, opt)\n      .then((aes) => (/*shim.ossl ||*/ shim.subtle).encrypt({ // Keeping the AES key scope as private as possible...\n        name: opt.name || 'AES-GCM', iv: new Uint8Array(rand.iv)\n      }, aes, new shim.TextEncoder().encode(msg)))\n      const r = 'SEA'+JSON.stringify({\n        ct: shim.Buffer.from(ct, 'binary').toString('utf8'),\n        iv: rand.iv.toString('utf8'),\n        s: rand.s.toString('utf8')\n      });\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.encrypt;\n  })(USE, './encrypt');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var aeskey = USE('./aeskey');\n    var parse = USE('./parse');\n\n    SEA.decrypt = SEA.decrypt || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      var key = (pair||opt).epriv || pair;\n      if(!key){\n        pair = await SEA.I(null, {what: data, how: 'decrypt', why: opt.why});\n        key = pair.epriv || pair;\n      }\n      const json = parse(data)\n      const ct = await aeskey(key, shim.Buffer.from(json.s, 'utf8'), opt)\n      .then((aes) => (/*shim.ossl ||*/ shim.subtle).decrypt({  // Keeping aesKey scope as private as possible...\n        name: opt.name || 'AES-GCM', iv: new Uint8Array(shim.Buffer.from(json.iv, 'utf8'))\n      }, aes, new Uint8Array(shim.Buffer.from(json.ct, 'utf8'))))\n      const r = parse(new shim.TextDecoder('utf8').decode(ct))\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.decrypt;\n  })(USE, './decrypt');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    // Derive shared secret from other's pub and my epub/epriv \n    SEA.secret = SEA.secret || (async (key, pair, cb, opt) => { try {\n      opt = opt || {};\n      if(!pair || !pair.epriv || !pair.epub){\n        pair = await SEA.I(null, {what: key, how: 'secret', why: opt.why});\n      }\n      const pub = key.epub || key\n      const epub = pair.epub\n      const epriv = pair.epriv\n      const ecdhSubtle = shim.ossl || shim.subtle\n      const pubKeyData = keysToEcdhJwk(pub)\n      const props = Object.assign(\n        S.ecdh,\n        { public: await ecdhSubtle.importKey(...pubKeyData, true, []) }\n      )\n      const privKeyData = keysToEcdhJwk(epub, epriv)\n      const derived = await ecdhSubtle.importKey(...privKeyData, false, ['deriveKey'])\n      .then(async (privKey) => {\n        // privateKey scope doesn't leak out from here!\n        const derivedKey = await ecdhSubtle.deriveKey(props, privKey, { name: 'AES-GCM', length: 256 }, true, [ 'encrypt', 'decrypt' ])\n        return ecdhSubtle.exportKey('jwk', derivedKey).then(({ k }) => k)\n      })\n      const r = derived;\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      SEA.err = e;\n      if(cb){ cb() }\n      return;\n    }});\n\n    const keysToEcdhJwk = (pub, d) => { // d === priv\n      //const [ x, y ] = Buffer.from(pub, 'base64').toString('utf8').split(':') // old\n      const [ x, y ] = pub.split('.') // new\n      const jwk = d ? { d: d } : {}\n      return [  // Use with spread returned value...\n        'jwk',\n        Object.assign(\n          jwk,\n          { x: x, y: y, kty: 'EC', crv: 'P-256', ext: true }\n        ), // ??? refactor\n        S.ecdh\n      ]\n    }\n\n    module.exports = SEA.secret;\n  })(USE, './secret');\n\n  ;USE(function(module){\n    var shim = USE('./shim');\n    // Practical examples about usage found from ./test/common.js\n    var SEA = USE('./root');\n    SEA.work = USE('./work');\n    SEA.sign = USE('./sign');\n    SEA.verify = USE('./verify');\n    SEA.encrypt = USE('./encrypt');\n    SEA.decrypt = USE('./decrypt');\n\n    SEA.random = SEA.random || shim.random;\n\n    // This is Buffer used in SEA and usable from Gun/SEA application also.\n    // For documentation see https://nodejs.org/api/buffer.html\n    SEA.Buffer = SEA.Buffer || USE('./buffer');\n\n    // These SEA functions support now ony Promises or\n    // async/await (compatible) code, use those like Promises.\n    //\n    // Creates a wrapper library around Web Crypto API\n    // for various AES, ECDSA, PBKDF2 functions we called above.\n    // Calculate public key KeyID aka PGPv4 (result: 8 bytes as hex string)\n    SEA.keyid = SEA.keyid || (async (pub) => {\n      try {\n        // base64('base64(x):base64(y)') => Buffer(xy)\n        const pb = Buffer.concat(\n          pub.replace(/-/g, '+').replace(/_/g, '/').split('.')\n          .map((t) => Buffer.from(t, 'base64'))\n        )\n        // id is PGPv4 compliant raw key\n        const id = Buffer.concat([\n          Buffer.from([0x99, pb.length / 0x100, pb.length % 0x100]), pb\n        ])\n        const sha1 = await sha1hash(id)\n        const hash = Buffer.from(sha1, 'binary')\n        return hash.toString('hex', hash.length - 8)  // 16-bit ID as hex\n      } catch (e) {\n        console.log(e)\n        throw e\n      }\n    });\n    // all done!\n    // Obviously it is missing MANY necessary features. This is only an alpha release.\n    // Please experiment with it, audit what I've done so far, and complain about what needs to be added.\n    // SEA should be a full suite that is easy and seamless to use.\n    // Again, scroll naer the top, where I provide an EXAMPLE of how to create a user and sign in.\n    // Once logged in, the rest of the code you just read handled automatically signing/validating data.\n    // But all other behavior needs to be equally easy, like opinionated ways of\n    // Adding friends (trusted public keys), sending private messages, etc.\n    // Cheers! Tell me what you think.\n    var Gun = (SEA.window||{}).Gun || USE('./gun', 1);\n    Gun.SEA = SEA;\n    SEA.GUN = SEA.Gun = Gun;\n\n    module.exports = SEA\n  })(USE, './sea');\n\n  ;USE(function(module){\n    var Gun = USE('./sea').Gun;\n    Gun.chain.then = function(cb){\n      var gun = this, p = (new Promise(function(res, rej){\n        gun.once(res);\n      }));\n      return cb? p.then(cb) : p;\n    }\n  })(USE, './then');\n\n  ;USE(function(module){\n    var SEA = USE('./sea');\n    var Gun = SEA.Gun;\n    var then = USE('./then');\n\n    function User(root){ \n      this._ = {$: this};\n    }\n    User.prototype = (function(){ function F(){}; F.prototype = Gun.chain; return new F() }()) // Object.create polyfill\n    User.prototype.constructor = User;\n\n    // let's extend the gun chain with a `user` function.\n    // only one user can be logged in at a time, per gun instance.\n    Gun.chain.user = function(pub){\n      var gun = this, root = gun.back(-1), user;\n      if(pub){ return root.get('~'+pub) }\n      if(user = root.back('user')){ return user }\n      var root = (root._), at = root, uuid = at.opt.uuid || Gun.state.lex;\n      (at = (user = at.user = gun.chain(new User))._).opt = {};\n      at.opt.uuid = function(cb){\n        var id = uuid(), pub = root.user;\n        if(!pub || !(pub = pub.is) || !(pub = pub.pub)){ return id }\n        id = id + '~' + pub + '.';\n        if(cb && cb.call){ cb(null, id) }\n        return id;\n      }\n      return user;\n    }\n    Gun.User = User;\n    module.exports = User;\n  })(USE, './user');\n\n  ;USE(function(module){\n    // TODO: This needs to be split into all separate functions.\n    // Not just everything thrown into 'create'.\n\n    var SEA = USE('./sea');\n    var User = USE('./user');\n    var authsettings = USE('./settings');\n    var Gun = SEA.Gun;\n\n    var noop = function(){};\n\n    // Well first we have to actually create a user. That is what this function does.\n    User.prototype.create = function(alias, pass, cb, opt){\n      var gun = this, cat = (gun._), root = gun.back(-1);\n      cb = cb || noop;\n      if(cat.ing){\n        cb({err: Gun.log(\"User is already being created or authenticated!\"), wait: true});\n        return gun;\n      }\n      cat.ing = true;\n      opt = opt || {};\n      var act = {}, u;\n      act.a = function(pubs){\n        act.pubs = pubs;\n        if(pubs && !opt.already){\n          // If we can enforce that a user name is already taken, it might be nice to try, but this is not guaranteed.\n          var ack = {err: Gun.log('User already created!')};\n          cat.ing = false;\n          cb(ack);\n          gun.leave();\n          return;\n        }\n        act.salt = Gun.text.random(64); // pseudo-randomly create a salt, then use PBKDF2 function to extend the password with it.\n        SEA.work(pass, act.salt, act.b); // this will take some short amount of time to produce a proof, which slows brute force attacks.\n      }\n      act.b = function(proof){\n        act.proof = proof;\n        SEA.pair(act.c); // now we have generated a brand new ECDSA key pair for the user account.\n      }\n      act.c = function(pair){\n        act.pair = pair || {};\n        // the user's public key doesn't need to be signed. But everything else needs to be signed with it!\n        act.data = {pub: pair.pub};\n        SEA.sign(alias, pair, act.d); \n      }\n      act.d = function(alias){\n        act.data.alias = alias;\n        SEA.sign(act.pair.epub, act.pair, act.e);\n      }\n      act.e = function(epub){\n        act.data.epub = epub; \n        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, act.proof, act.f); // to keep the private key safe, we AES encrypt it with the proof of work!\n      }\n      act.f = function(auth){\n        act.data.auth = auth; \n        SEA.sign({ek: auth, s: act.salt}, act.pair, act.g);\n      }\n      act.g = function(auth){ var tmp;\n        act.data.auth = auth;\n        root.get(tmp = '~'+act.pair.pub).put(act.data); // awesome, now we can actually save the user with their public key as their ID.\n        root.get('~@'+alias).put(Gun.obj.put({}, tmp, Gun.val.link.ify(tmp))); // next up, we want to associate the alias with the public key. So we add it to the alias list.\n        setTimeout(function(){ // we should be able to delete this now, right?\n        cat.ing = false;\n        cb({ok: 0, pub: act.pair.pub}); // callback that the user has been created. (Note: ok = 0 because we didn't wait for disk to ack)\n        if(noop === cb){ gun.auth(alias, pass) } // if no callback is passed, auto-login after signing up.\n        },10);\n      }\n      root.get('~@'+alias).once(act.a);\n      return gun;\n    }\n    // now that we have created a user, we want to authenticate them!\n    User.prototype.auth = function(alias, pass, cb, opt){\n      var gun = this, cat = (gun._), root = gun.back(-1);\n      cb = cb || function(){};\n      if(cat.ing){\n        cb({err: Gun.log(\"User is already being created or authenticated!\"), wait: true});\n        return gun;\n      }\n      cat.ing = true;\n      opt = opt || {};\n      var pair = (alias.pub || alias.epub)? alias : (pass.pub || pass.epub)? pass : null;\n      var act = {}, u;\n      act.a = function(data){\n        if(!data){ return act.b() }\n        if(!data.pub){\n          var tmp = [];\n          Gun.node.is(data, function(v){ tmp.push(v) })\n          return act.b(tmp);\n        }\n        if(act.name){ return act.f(data) }\n        act.c((act.data = data).auth);\n      }\n      act.b = function(list){\n        var get = (act.list = (act.list||[]).concat(list||[])).shift();\n        if(u === get){\n          if(act.name){ return act.err('Your user account is not published for dApps to access, please consider syncing it online, or allowing local access by adding your device as a peer.') }\n          return act.err('Wrong user or password.') \n        }\n        root.get(get).once(act.a);\n      }\n      act.c = function(auth){\n        if(u === auth){ return act.b() }\n        SEA.work(pass, (act.auth = auth).s, act.d); // the proof of work is evidence that we've spent some time/effort trying to log in, this slows brute force.\n      }\n      act.d = function(proof){\n        if(u === proof){ return act.b() }\n        SEA.decrypt(act.auth.ek, proof, act.e);\n      }\n      act.e = function(half){\n        if(u === half){ return act.b() }\n        act.half = half;\n        act.f(act.data);\n      }\n      act.f = function(data){\n        if(!data || !data.pub){ return act.b() }\n        var tmp = act.half || {};\n        act.g({pub: data.pub, epub: data.epub, priv: tmp.priv, epriv: tmp.epriv});\n      }\n      act.g = function(pair){\n        act.pair = pair;\n        var user = (root._).user, at = (user._);\n        var tmp = at.tag;\n        var upt = at.opt;\n        at = user._ = root.get('~'+pair.pub)._;\n        at.opt = upt;\n        // add our credentials in-memory only to our root user instance\n        user.is = {pub: pair.pub, epub: pair.epub, alias: alias};\n        at.sea = act.pair;\n        cat.ing = false;\n        opt.change? act.z() : cb(at);\n        if(SEA.window && ((gun.back('user')._).opt||opt).remember){\n          // TODO: this needs to be modular.\n          var sS = {}; try{sS = window.sessionStorage}catch(e){}\n          sS.recall = true;\n          sS.alias = alias;\n          sS.tmp = pass;\n        }\n        try{\n          (root._).on('auth', at) // TODO: Deprecate this, emit on user instead! Update docs when you do.\n          //at.on('auth', at) // Arrgh, this doesn't work without event \"merge\" code, but \"merge\" code causes stack overflow and crashes after logging in & trying to write data.\n        }catch(e){\n          Gun.log(\"Your 'auth' callback crashed with:\", e);\n        }\n      }\n      act.z = function(){\n        // password update so encrypt private key using new pwd + salt\n        act.salt = Gun.text.random(64); // pseudo-random\n        SEA.work(opt.change, act.salt, act.y);\n      }\n      act.y = function(proof){\n        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, proof, act.x);\n      }\n      act.x = function(auth){\n        SEA.sign({ek: auth, s: act.salt}, act.pair, act.w);\n      }\n      act.w = function(auth){\n        root.get('~'+act.pair.pub).get('auth').put(auth, cb);\n      }\n      act.err = function(e){\n        var ack = {err: Gun.log(e || 'User cannot be found!')};\n        cat.ing = false;\n        cb(ack);\n      }\n      act.plugin = function(name){\n        if(!(act.name = name)){ return act.err() }\n        var tmp = [name];\n        if('~' !== name[0]){\n          tmp[1] = '~'+name;\n          tmp[2] = '~@'+name;\n        }\n        act.b(tmp);\n      }\n      if(pair){\n        act.g(pair);\n      } else\n      if(alias){\n        root.get('~@'+alias).once(act.a);\n      } else\n      if(!alias && !pass){\n        SEA.name(act.plugin);\n      }\n      return gun;\n    }\n    User.prototype.pair = function(){\n      console.log(\"user.pair() IS DEPRECATED AND WILL BE DELETED!!!\");\n      var user = this;\n      if(!user.is){ return false }\n      return user._.sea;\n    }\n    User.prototype.leave = function(opt, cb){\n      var gun = this, user = (gun.back(-1)._).user;\n      if(user){\n        delete user.is;\n        delete user._.is;\n        delete user._.sea;\n      }\n      if(SEA.window){\n        var sS = {}; try{sS = window.sessionStorage}catch(e){};\n        delete sS.alias;\n        delete sS.tmp;\n        delete sS.recall;\n      }\n      return gun;\n    }\n    // If authenticated user wants to delete his/her account, let's support it!\n    User.prototype.delete = async function(alias, pass, cb){\n      var gun = this, root = gun.back(-1), user = gun.back('user');\n      try {\n        user.auth(alias, pass, function(ack){\n          var pub = (user.is||{}).pub;\n          // Delete user data\n          user.map().once(function(){ this.put(null) });\n          // Wipe user data from memory\n          user.leave();\n          (cb || noop)({ok: 0});\n        });\n      } catch (e) {\n        Gun.log('User.delete failed! Error:', e);\n      }\n      return gun;\n    }\n    User.prototype.recall = function(opt, cb){\n      var gun = this, root = gun.back(-1), tmp;\n      opt = opt || {};\n      if(opt && opt.sessionStorage){\n        if(SEA.window){\n          var sS = {}; try{sS = window.sessionStorage}catch(e){}\n          if(sS){\n            (root._).opt.remember = true;\n            ((gun.back('user')._).opt||opt).remember = true;\n            if(sS.recall || (sS.alias && sS.tmp)){\n              root.user().auth(sS.alias, sS.tmp, cb);\n            }\n          }\n        }\n        return gun;\n      }\n      /*\n        TODO: copy mhelander's expiry code back in.\n        Although, we should check with community,\n        should expiry be core or a plugin?\n      */\n      return gun;\n    }\n    User.prototype.alive = async function(){\n      const gunRoot = this.back(-1)\n      try {\n        // All is good. Should we do something more with actual recalled data?\n        await authRecall(gunRoot)\n        return gunRoot._.user._\n      } catch (e) {\n        const err = 'No session!'\n        Gun.log(err)\n        throw { err }\n      }\n    }\n    User.prototype.trust = async function(user){\n      // TODO: BUG!!! SEA `node` read listener needs to be async, which means core needs to be async too.\n      //gun.get('alice').get('age').trust(bob);\n      if (Gun.is(user)) {\n        user.get('pub').get((ctx, ev) => {\n          console.log(ctx, ev)\n        })\n      }\n    }\n    User.prototype.grant = function(to, cb){\n      console.log(\"`.grant` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = '';\n      gun.back(function(at){ if(at.is){ return } path += (at.get||'') });\n      (async function(){\n      var enc, sec = await user.get('trust').get(pair.pub).get(path).then();\n      sec = await SEA.decrypt(sec, pair);\n      if(!sec){\n        sec = SEA.random(16).toString();\n        enc = await SEA.encrypt(sec, pair);\n        user.get('trust').get(pair.pub).get(path).put(enc);\n      }\n      var pub = to.get('pub').then();\n      var epub = to.get('epub').then();\n      pub = await pub; epub = await epub;\n      var dh = await SEA.secret(epub, pair);\n      enc = await SEA.encrypt(sec, dh);\n      user.get('trust').get(pub).get(path).put(enc, cb);\n      }());\n      return gun;\n    }\n    User.prototype.secret = function(data, cb){\n      console.log(\"`.secret` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = '';\n      gun.back(function(at){ if(at.is){ return } path += (at.get||'') });\n      (async function(){\n      var enc, sec = await user.get('trust').get(pair.pub).get(path).then();\n      sec = await SEA.decrypt(sec, pair);\n      if(!sec){\n        sec = SEA.random(16).toString();\n        enc = await SEA.encrypt(sec, pair);\n        user.get('trust').get(pair.pub).get(path).put(enc);\n      }\n      enc = await SEA.encrypt(data, sec);\n      gun.put(enc, cb);\n      }());\n      return gun;\n    }\n    module.exports = User\n  })(USE, './create');\n\n  ;USE(function(module){\n    const SEA = USE('./sea')\n    const Gun = SEA.Gun;\n    // After we have a GUN extension to make user registration/login easy, we then need to handle everything else.\n\n    // We do this with a GUN adapter, we first listen to when a gun instance is created (and when its options change)\n    Gun.on('opt', function(at){\n      if(!at.sea){ // only add SEA once per instance, on the \"at\" context.\n        at.sea = {own: {}};\n        at.on('in', security, at); // now listen to all input data, acting as a firewall.\n        at.on('out', signature, at); // and output listeners, to encrypt outgoing data.\n        at.on('node', each, at);\n      }\n      this.to.next(at); // make sure to call the \"next\" middleware adapter.\n    });\n\n    // Alright, this next adapter gets run at the per node level in the graph database.\n    // This will let us verify that every property on a node has a value signed by a public key we trust.\n    // If the signature does not match, the data is just `undefined` so it doesn't get passed on.\n    // If it does match, then we transform the in-memory \"view\" of the data into its plain value (without the signature).\n    // Now NOTE! Some data is \"system\" data, not user data. Example: List of public keys, aliases, etc.\n    // This data is self-enforced (the value can only match its ID), but that is handled in the `security` function.\n    // From the self-enforced data, we can see all the edges in the graph that belong to a public key.\n    // Example: ~ASDF is the ID of a node with ASDF as its public key, signed alias and salt, and\n    // its encrypted private key, but it might also have other signed values on it like `profile = <ID>` edge.\n    // Using that directed edge's ID, we can then track (in memory) which IDs belong to which keys.\n    // Here is a problem: Multiple public keys can \"claim\" any node's ID, so this is dangerous!\n    // This means we should ONLY trust our \"friends\" (our key ring) public keys, not any ones.\n    // I have not yet added that to SEA yet in this alpha release. That is coming soon, but beware in the meanwhile!\n    function each(msg){ // TODO: Warning: Need to switch to `gun.on('node')`! Do not use `Gun.on('node'` in your apps!\n      // NOTE: THE SECURITY FUNCTION HAS ALREADY VERIFIED THE DATA!!!\n      // WE DO NOT NEED TO RE-VERIFY AGAIN, JUST TRANSFORM IT TO PLAINTEXT.\n      var to = this.to, vertex = (msg.$._).put, c = 0, d;\n      Gun.node.is(msg.put, function(val, key, node){ c++; // for each property on the node\n        // TODO: consider async/await use here...\n        SEA.verify(val, false, function(data){ c--; // false just extracts the plain data.\n          node[key] = val = data; // transform to plain value.\n          if(d && !c && (c = -1)){ to.next(msg) }\n        });\n      });\n      d = true;\n      if(d && !c){ to.next(msg) }\n      return;\n    }\n\n    // signature handles data output, it is a proxy to the security function.\n    function signature(msg){\n      if(msg.user){\n        return this.to.next(msg);\n      }\n      var ctx = this.as;\n      msg.user = ctx.user;\n      security.call(this, msg);\n    }\n\n    // okay! The security function handles all the heavy lifting.\n    // It needs to deal read and write of input and output of system data, account/public key data, and regular data.\n    // This is broken down into some pretty clear edge cases, let's go over them:\n    function security(msg){\n      var at = this.as, sea = at.sea, to = this.to;\n      if(msg.get){\n        // if there is a request to read data from us, then...\n        var soul = msg.get['#'];\n        if(soul){ // for now, only allow direct IDs to be read.\n          if(soul !== 'string'){ return to.next(msg) } // do not handle lexical cursors.\n          if('alias' === soul){ // Allow reading the list of usernames/aliases in the system?\n            return to.next(msg); // yes.\n          } else\n          if('~@' === soul.slice(0,2)){ // Allow reading the list of public keys associated with an alias?\n            return to.next(msg); // yes.\n          } else { // Allow reading everything?\n            return to.next(msg); // yes // TODO: No! Make this a callback/event that people can filter on.\n          }\n        }\n      }\n      if(msg.put){\n        // potentially parallel async operations!!!\n        var check = {}, each = {}, u;\n        each.node = function(node, soul){\n          if(Gun.obj.empty(node, '_')){ return check['node'+soul] = 0 } // ignore empty updates, don't reject them.\n          Gun.obj.map(node, each.way, {soul: soul, node: node});\n        };\n        each.way = function(val, key){\n          var soul = this.soul, node = this.node, tmp;\n          if('_' === key){ return } // ignore meta data\n          if('~@' === soul){  // special case for shared system data, the list of aliases.\n            each.alias(val, key, node, soul); return;\n          }\n          if('~@' === soul.slice(0,2)){ // special case for shared system data, the list of public keys for an alias.\n            each.pubs(val, key, node, soul); return;\n          }\n          if('~' === soul.slice(0,1) && 2 === (tmp = soul.slice(1)).split('.').length){ // special case, account data for a public key.\n            each.pub(val, key, node, soul, tmp, msg.user); return;\n          }\n          each.any(val, key, node, soul, msg.user); return;\n          return each.end({err: \"No other data allowed!\"});\n        };\n        each.alias = function(val, key, node, soul){ // Example: {_:#~@, ~@alice: {#~@alice}}\n          if(!val){ return each.end({err: \"Data must exist!\"}) } // data MUST exist\n          if('~@'+key === Gun.val.link.is(val)){ return check['alias'+key] = 0 } // in fact, it must be EXACTLY equal to itself\n          each.end({err: \"Mismatching alias.\"}); // if it isn't, reject.\n        };\n        each.pubs = function(val, key, node, soul){ // Example: {_:#~@alice, ~asdf: {#~asdf}}\n          if(!val){ return each.end({err: \"Alias must exist!\"}) } // data MUST exist\n          if(key === Gun.val.link.is(val)){ return check['pubs'+soul+key] = 0 } // and the ID must be EXACTLY equal to its property\n          each.end({err: \"Alias must match!\"}); // that way nobody can tamper with the list of public keys.\n        };\n        each.pub = function(val, key, node, soul, pub, user){ // Example: {_:#~asdf, hello:SEA{'world',fdsa}}\n          if('pub' === key){\n            if(val === pub){ return (check['pub'+soul+key] = 0) } // the account MUST match `pub` property that equals the ID of the public key.\n            return each.end({err: \"Account must match!\"});\n          }\n          check['user'+soul+key] = 1;\n          if(user && user.is && pub === user.is.pub){\n            //var id = Gun.text.random(3);\n            SEA.sign(val, (user._).sea, function(data){ var rel;\n              if(u === data){ return each.end({err: SEA.err || 'Pub signature fail.'}) }\n              if(rel = Gun.val.link.is(val)){\n                (at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true;\n              }\n              node[key] = data;\n              check['user'+soul+key] = 0;\n              each.end({ok: 1});\n            });\n            // TODO: Handle error!!!!\n            return;\n          }\n          SEA.verify(val, pub, function(data){ var rel, tmp;\n            if(u === data){ // make sure the signature matches the account it claims to be on.\n              return each.end({err: \"Unverified data.\"}); // reject any updates that are signed with a mismatched account.\n            }\n            if((rel = Gun.val.link.is(data)) && pub === relpub(rel)){\n              (at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true;\n            }\n            check['user'+soul+key] = 0;\n            each.end({ok: 1});\n          });\n        };\n        function relpub(s){\n          if(!s){ return }\n          s = s.split('~');\n          if(!s || !(s = s[1])){ return }\n          s = s.split('.');\n          if(!s || 2 > s.length){ return }\n          s = s.slice(0,2).join('.');\n          return s;\n        }\n        each.any = function(val, key, node, soul, user){ var tmp, pub;\n          if(!user || !user.is){\n            if(tmp = relpub(soul)){\n              check['any'+soul+key] = 1;\n              SEA.verify(val, pub = tmp, function(data){ var rel;\n                if(u === data){ return each.end({err: \"Mismatched owner on '\" + key + \"'.\"}) } // thanks @rogowski !\n                if((rel = Gun.val.link.is(data)) && pub === relpub(rel)){\n                  (at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true;\n                }\n                check['any'+soul+key] = 0;\n                each.end({ok: 1});\n              });\n              return;\n            }\n            check['any'+soul+key] = 1;\n            at.on('secure', function(msg){ this.off();\n              check['any'+soul+key] = 0;\n              if(at.opt.secure){ msg = null }\n              each.end(msg || {err: \"Data cannot be modified.\"});\n            }).on.on('secure', msg);\n            //each.end({err: \"Data cannot be modified.\"});\n            return;\n          }\n          if(!(tmp = relpub(soul))){\n            if(at.opt.secure){\n              each.end({err: \"Soul is missing public key at '\" + key + \"'.\"});\n              return;\n            }\n            if(val && val.slice && 'SEA{' === (val).slice(0,4)){\n              check['any'+soul+key] = 0;\n              each.end({ok: 1});\n              return;\n            }\n            //check['any'+soul+key] = 1;\n            //SEA.sign(val, user, function(data){\n             // if(u === data){ return each.end({err: 'Any signature failed.'}) }\n            //  node[key] = data;\n              check['any'+soul+key] = 0;\n              each.end({ok: 1});\n            //});\n            return;\n          }\n          if((pub = tmp) !== (user.is||noop).pub){\n            each.any(val, key, node, soul);\n            return;\n          }\n          /*var other = Gun.obj.map(at.sea.own[soul], function(v, p){\n            if((user.is||{}).pub !== p){ return p }\n          });\n          if(other){\n            each.any(val, key, node, soul);\n            return;\n          }*/\n          check['any'+soul+key] = 1;\n          SEA.sign(val, (user._).sea, function(data){\n            if(u === data){ return each.end({err: 'My signature fail.'}) }\n            node[key] = data;\n            check['any'+soul+key] = 0;\n            each.end({ok: 1});\n          });\n        }\n        each.end = function(ctx){ // TODO: Can't you just switch this to each.end = cb?\n          if(each.err){ return }\n          if((each.err = ctx.err) || ctx.no){\n            console.log('NO!', each.err, msg.put); // 451 mistmached data FOR MARTTI\n            return;\n          }\n          if(!each.end.ed){ return }\n          if(Gun.obj.map(check, function(no){\n            if(no){ return true }\n          })){ return }\n          to.next(msg);\n        };\n        Gun.obj.map(msg.put, each.node);\n        each.end({end: each.end.ed = true});\n        return; // need to manually call next after async.\n      }\n      to.next(msg); // pass forward any data we do not know how to handle or process (this allows custom security protocols).\n    }\n    var noop = {};\n\n  })(USE, './index');\n}());"
  },
  {
    "path": "examples/react-native/src/webview-crypto/MainWorker.d.ts",
    "content": "export default class MainWorker {\n    private sendToWebView;\n    private debug;\n    readonly crypto: Crypto;\n    private readonly subtle;\n    private static uuid;\n    private toSend;\n    private readyToSend;\n    private messages;\n    constructor(sendToWebView: (message: string) => void, debug?: boolean);\n    onWebViewMessage(message: string): void;\n    private getRandomValues;\n    private callMethod;\n}\n"
  },
  {
    "path": "examples/react-native/src/webview-crypto/MainWorker.js",
    "content": "import serializeError from 'serialize-error';\nimport { parse, stringify } from './serializeBinary';\nconst SUBTLE_METHODS = [\n    'encrypt',\n    'decrypt',\n    'sign',\n    'verify',\n    'digest',\n    'generateKey',\n    'deriveKey',\n    'deriveBits',\n    'importKey',\n    'exportKey',\n    'wrapKey',\n    'unwrapKey',\n];\n/*\nMainWorker provides a `crypto` attribute that proxies method calls\nto the webview.\n\nIt sends strings to the webview in the format:\n\n    {\n      id: <id>,\n      method: getRandomValues | subtle.<method name>,\n      args: [<serialized arg>]\n    }\n\nWhen the webview succeeds in completeing that method, it gets backs:\n\n    {\n      id: <id>,\n      value: <serialized return value>\n    }\n\nAnd when it fails:\n\n    {\n      id: <id>,\n      reason: <serialized rejected reason>,\n    }\n\n*/\nexport default class MainWorker {\n    // sendToWebView should take a string and send that message to the webview\n    constructor(sendToWebView, debug = false) {\n        this.sendToWebView = sendToWebView;\n        this.debug = debug;\n        // hold a queue of messages to send, in case someone calls crypto\n        // before the webview is initialized\n        this.toSend = [];\n        this.readyToSend = false;\n        // Holds the `resolve` and `reject` function for all the promises\n        // we are working on\n        this.messages = {};\n    }\n    get crypto() {\n        const callMethod = this.callMethod;\n        return {\n            subtle: this.subtle,\n            getRandomValues: this.getRandomValues.bind(this),\n            fake: true,\n        };\n    }\n    get subtle() {\n        const s = {};\n        for (const m of SUBTLE_METHODS) {\n            s[m] = (...args) => {\n                return this.callMethod(`subtle.${m}`, args, true);\n            };\n        }\n        return s;\n    }\n    // http://stackoverflow.com/a/105074/907060\n    static uuid() {\n        function s4() {\n            return Math.floor((1 + Math.random()) * 0x10000)\n                .toString(16)\n                .substring(1);\n        }\n        return `${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}-${s4()}`;\n    }\n    onWebViewMessage(message) {\n        // first message just tells us the webview is ready\n        if (!this.readyToSend) {\n            if (this.debug) {\n                console.log('[webview-crypto] Got first message; ready to send');\n            }\n            this.readyToSend = true;\n            for (const m of this.toSend) {\n                this.sendToWebView(m);\n            }\n            return;\n        }\n        parse(message)\n            .then(({ id, value, reason }) => {\n            if (this.debug) {\n                console.log('[webview-crypto] Received message:', JSON.stringify({\n                    id,\n                    value,\n                    reason,\n                }));\n            }\n            if (!id) {\n                console.warn('[webview-crypto] no ID passed back from message:', JSON.stringify(serializeError(reason)));\n                return;\n            }\n            const { resolve, reject } = this.messages[id];\n            if (value) {\n                resolve(value);\n            }\n            else {\n                reject(reason);\n            }\n            delete this.messages[id];\n        })\n            .catch((reason) => {\n            console.warn('[webview-crypto] error in `parse` of message:', JSON.stringify(message), 'reason:', JSON.stringify(serializeError(reason)));\n        });\n    }\n    getRandomValues(array) {\n        const promise = this.callMethod('getRandomValues', [array], false);\n        // make the _promise not enumerable so it isn't JSON stringified,\n        // which could lead to an infinite loop with Angular's zone promises\n        Object.defineProperty(array, '_promise', {\n            value: promise,\n            configurable: true,\n            enumerable: false,\n            writable: true,\n        });\n        promise.then((updatedArray) => {\n            array.set(updatedArray);\n        });\n        return array;\n    }\n    callMethod(method, args, waitForArrayBufferView) {\n        const id = MainWorker.uuid();\n        // store this promise, so we can resolve it when we get a message\n        // back from the web view\n        const promise = new Promise((resolve, reject) => {\n            this.messages[id] = { resolve, reject };\n        });\n        const payloadObject = { method, id, args };\n        if (this.debug) {\n            console.log('[webview-crypto] Sending message:', JSON.stringify({\n                method,\n                args,\n                payloadObject,\n            }));\n        }\n        stringify(payloadObject, waitForArrayBufferView)\n            .then((message) => {\n            if (this.readyToSend) {\n                this.sendToWebView(message);\n            }\n            else {\n                this.toSend.push(message);\n            }\n        })\n            .catch((reason) => {\n            this.messages[id].reject({\n                message: `exception in stringify-ing message: ${method} ${id}`,\n                reason,\n            });\n            delete this.messages[id];\n        });\n        return promise;\n    }\n}\n//# sourceMappingURL=MainWorker.js.map"
  },
  {
    "path": "examples/react-native/src/webview-crypto/WebViewWorker.d.ts",
    "content": "export declare class WebViewWorker {\n    private sendToMain;\n    constructor(sendToMain: (message: string) => void);\n    onMainMessage(message: string): Promise<void>;\n    send(data: any): Promise<void>;\n}\n"
  },
  {
    "path": "examples/react-native/src/webview-crypto/WebViewWorker.js",
    "content": "var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nimport serializeError from 'serialize-error';\nimport { subtle } from './compat';\nimport { parse, stringify } from './serializeBinary';\nexport class WebViewWorker {\n    constructor(sendToMain) {\n        this.sendToMain = sendToMain;\n        sendToMain('We are ready!');\n    }\n    onMainMessage(message) {\n        return __awaiter(this, void 0, void 0, function* () {\n            let id;\n            let method;\n            let args;\n            try {\n                ({ id, method, args } = yield parse(message));\n            }\n            catch (e) {\n                yield this.send({\n                    reason: `Couldn't parse data: ${e}`,\n                });\n                return;\n            }\n            let value;\n            try {\n                if (method === 'getRandomValues') {\n                    value = crypto.getRandomValues(args[0]);\n                }\n                else {\n                    const methodName = method.split('.')[1];\n                    console.log(methodName, args);\n                    value = yield subtle()[methodName].apply(subtle(), args);\n                    // if we import a crypto key, we want to save how we imported it\n                    // so we can send that back and re-create the key later\n                    if (methodName === 'importKey') {\n                        value._import = {\n                            format: args[0],\n                            keyData: args[1],\n                        };\n                    }\n                }\n            }\n            catch (e) {\n                yield this.send({ id, reason: serializeError(e) });\n                return;\n            }\n            yield this.send({ id, value });\n        });\n    }\n    send(data) {\n        return __awaiter(this, void 0, void 0, function* () {\n            let message;\n            try {\n                message = yield stringify(data);\n            }\n            catch (e) {\n                const newData = {\n                    id: data.id,\n                    reason: `stringify error ${e}`,\n                };\n                this.sendToMain(JSON.stringify(newData));\n                return;\n            }\n            this.sendToMain(message);\n        });\n    }\n}\n//# sourceMappingURL=WebViewWorker.js.map"
  },
  {
    "path": "examples/react-native/src/webview-crypto/asyncSerialize.d.ts",
    "content": "export interface ISerializer<T, S> {\n    id: string;\n    isType: (o: any) => boolean;\n    toObject?: (t: T) => Promise<S>;\n    fromObject?: (o: S) => Promise<T>;\n}\nexport declare function toObjects(serializers: Array<ISerializer<any, any>>, o: any): Promise<any>;\nexport declare function fromObjects(serializers: Array<ISerializer<any, any>>, o: any): Promise<any>;\n"
  },
  {
    "path": "examples/react-native/src/webview-crypto/asyncSerialize.js",
    "content": "var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\n// tslint:disable\nimport find from 'lodash/find';\nclass Serialized {\n}\nfunction isSerialized(object) {\n    return object.hasOwnProperty('__serializer_id');\n}\nexport function toObjects(serializers, o) {\n    return __awaiter(this, void 0, void 0, function* () {\n        if (typeof o !== 'object') {\n            return o;\n        }\n        const serializer = find(serializers, (s) => s.isType(o));\n        if (serializer) {\n            const value = serializer.toObject ? yield serializer.toObject(o) : o;\n            return {\n                __serializer_id: serializer.id,\n                value: yield toObjects(serializers, value),\n            };\n        }\n        const newO = o instanceof Array ? [] : {};\n        for (const atr in o) {\n            newO[atr] = yield toObjects(serializers, o[atr]);\n        }\n        return newO;\n    });\n}\nexport function fromObjects(serializers, o) {\n    return __awaiter(this, void 0, void 0, function* () {\n        if (typeof o !== 'object') {\n            return o;\n        }\n        if (isSerialized(o)) {\n            const value = yield fromObjects(serializers, o.value);\n            const serializer = find(serializers, ['id', o.__serializer_id]) || {};\n            if (serializer.fromObject) {\n                return serializer.fromObject(value);\n            }\n            return value;\n        }\n        const newO = o instanceof Array ? [] : {};\n        for (const atr in o) {\n            newO[atr] = yield fromObjects(serializers, o[atr]);\n        }\n        return newO;\n    });\n}\n//# sourceMappingURL=asyncSerialize.js.map"
  },
  {
    "path": "examples/react-native/src/webview-crypto/compat.d.ts",
    "content": "export declare function subtle(): SubtleCrypto;\n"
  },
  {
    "path": "examples/react-native/src/webview-crypto/compat.js",
    "content": "export function subtle() {\n    return window.crypto.subtle || window.crypto.webkitSubtle;\n}\n//# sourceMappingURL=compat.js.map"
  },
  {
    "path": "examples/react-native/src/webview-crypto/index.d.ts",
    "content": "import MainWorker from './MainWorker';\nimport webViewWorkerString from './webViewWorkerString';\nexport { MainWorker, webViewWorkerString };\n"
  },
  {
    "path": "examples/react-native/src/webview-crypto/index.js",
    "content": "import MainWorker from './MainWorker';\nimport webViewWorkerString from './webViewWorkerString';\nexport { MainWorker, webViewWorkerString };\n//# sourceMappingURL=index.js.map"
  },
  {
    "path": "examples/react-native/src/webview-crypto/serializeBinary.d.ts",
    "content": "export declare function parse(text: string): Promise<any>;\nexport declare function stringify(value: any, waitForArrayBufferView?: boolean): Promise<string>;\nexport interface IArrayBufferViewWithPromise extends ArrayBufferView {\n    _promise?: Promise<ArrayBufferView>;\n}\n"
  },
  {
    "path": "examples/react-native/src/webview-crypto/serializeBinary.js",
    "content": "var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nimport { fromObjects, toObjects } from './asyncSerialize';\nimport { subtle } from './compat';\nexport function parse(text) {\n    return __awaiter(this, void 0, void 0, function* () {\n        // need decodeURIComponent so binary strings are transferred properly\n        const deocodedText = unescape(text);\n        const objects = JSON.parse(deocodedText);\n        return fromObjects(serializers(true), objects);\n    });\n}\nexport function stringify(value, waitForArrayBufferView = true) {\n    return __awaiter(this, void 0, void 0, function* () {\n        const serialized = yield toObjects(serializers(waitForArrayBufferView), value);\n        // need encodeURIComponent so binary strings are transferred properly\n        const message = JSON.stringify(serialized);\n        return escape(message);\n    });\n}\nfunction serializers(waitForArrayBufferView) {\n    return [\n        ArrayBufferSerializer,\n        ArrayBufferViewSerializer(waitForArrayBufferView),\n        CryptoKeySerializer,\n    ];\n}\nconst ArrayBufferSerializer = {\n    id: 'ArrayBuffer',\n    isType: (o) => o instanceof ArrayBuffer,\n    // from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String\n    // modified to use Int8Array so that we can hold odd number of bytes\n    toObject: (ab) => __awaiter(this, void 0, void 0, function* () {\n        return String.fromCharCode.apply(null, new Int8Array(ab));\n    }),\n    fromObject: (data) => __awaiter(this, void 0, void 0, function* () {\n        const buf = new ArrayBuffer(data.length);\n        const bufView = new Int8Array(buf);\n        for (let i = 0, strLen = data.length; i < strLen; i++) {\n            bufView[i] = data.charCodeAt(i);\n        }\n        return buf;\n    }),\n};\nfunction isArrayBufferViewWithPromise(obj) {\n    return obj.hasOwnProperty('_promise');\n}\n// Normally we could just do `abv.constructor.name`, but in\n// JavaScriptCore, this wont work for some weird reason.\n// list from https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView\nfunction arrayBufferViewName(abv) {\n    if (abv instanceof Int8Array) {\n        return 'Int8Array';\n    }\n    if (abv instanceof Uint8Array) {\n        return 'Uint8Array';\n    }\n    if (abv instanceof Uint8ClampedArray) {\n        return 'Uint8ClampedArray';\n    }\n    if (abv instanceof Int16Array) {\n        return 'Int16Array';\n    }\n    if (abv instanceof Uint16Array) {\n        return 'Uint16Array';\n    }\n    if (abv instanceof Int32Array) {\n        return 'Int32Array';\n    }\n    if (abv instanceof Uint32Array) {\n        return 'Uint32Array';\n    }\n    if (abv instanceof Float32Array) {\n        return 'Float32Array';\n    }\n    if (abv instanceof Float64Array) {\n        return 'Float64Array';\n    }\n    if (abv instanceof DataView) {\n        return 'DataView';\n    }\n    return '';\n}\nfunction ArrayBufferViewSerializer(waitForPromise) {\n    return {\n        id: 'ArrayBufferView',\n        isType: ArrayBuffer.isView,\n        toObject: (abv) => __awaiter(this, void 0, void 0, function* () {\n            if (waitForPromise) {\n                // wait for promise to resolve if the abv was returned from getRandomValues\n                if (isArrayBufferViewWithPromise(abv)) {\n                    yield abv._promise;\n                }\n            }\n            return {\n                name: arrayBufferViewName(abv),\n                buffer: abv.buffer,\n            };\n        }),\n        fromObject: (abvs) => __awaiter(this, void 0, void 0, function* () {\n            // tslint:disable-next-line\n            return eval(`new ${abvs.name}(abvs.buffer)`);\n        }),\n    };\n}\nfunction hasData(ck) {\n    return ck._import !== undefined;\n}\nconst CryptoKeySerializer = {\n    id: 'CryptoKey',\n    isType: (o) => {\n        const localStr = o.toLocaleString();\n        // can't use CryptoKey or constructor on WebView iOS\n        const isCryptoKey = localStr === '[object CryptoKey]' || localStr === '[object Key]';\n        const isCryptoKeyWithData = o._import && !o.serialized;\n        return isCryptoKey || isCryptoKeyWithData;\n    },\n    toObject: (ck) => __awaiter(this, void 0, void 0, function* () {\n        // if we already have the import serialized, just return that\n        if (hasData(ck)) {\n            return {\n                serialized: true,\n                _import: ck._import,\n                type: ck.type,\n                extractable: ck.extractable,\n                algorithm: ck.algorithm,\n                usages: ck.usages,\n            };\n        }\n        const jwk = yield subtle().exportKey('jwk', ck);\n        return {\n            _import: {\n                format: 'jwk',\n                keyData: jwk,\n            },\n            serialized: true,\n            algorithm: ck.algorithm,\n            extractable: ck.extractable,\n            usages: ck.usages,\n            type: ck.type,\n        };\n    }),\n    fromObject: (cks) => __awaiter(this, void 0, void 0, function* () {\n        // if we don't have access to a real crypto implementation, just return\n        // the serialized crypto key\n        if (crypto.fake) {\n            const newCks = Object.assign({}, cks);\n            delete newCks.serialized;\n            return newCks;\n        }\n        return subtle().importKey(cks._import.format, cks._import.keyData, cks.algorithm, cks.extractable, cks.usages);\n    }),\n};\n//# sourceMappingURL=serializeBinary.js.map"
  },
  {
    "path": "examples/react-native/src/webview-crypto/webViewWorkerString.d.ts",
    "content": "export declare const base64InjString = \"\\n(function (global, factory) {\\n    typeof exports === 'object' && typeof module !== 'undefined'\\n        ? module.exports = factory(global)\\n        : typeof define === 'function' && define.amd\\n        ? define(factory) : factory(global)\\n}((\\n    typeof self !== 'undefined' ? self\\n        : typeof window !== 'undefined' ? window\\n        : typeof global !== 'undefined' ? global\\n: this\\n), function(global) {\\n    'use strict';\\n    // existing version for noConflict()\\n    var _Base64 = global.Base64;\\n    var version = \\\"2.4.9\\\";\\n    // if node.js and NOT React Native, we use Buffer\\n    var buffer;\\n    if (typeof module !== 'undefined' && module.exports) {\\n        try {\\n            buffer = eval(\\\"require('buffer').Buffer\\\");\\n        } catch (err) {\\n            buffer = undefined;\\n        }\\n    }\\n    // constants\\n    var b64chars\\n        = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\\n    var b64tab = function(bin) {\\n        var t = {};\\n        for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;\\n        return t;\\n    }(b64chars);\\n    var fromCharCode = String.fromCharCode;\\n    // encoder stuff\\n    var cb_utob = function(c) {\\n        if (c.length < 2) {\\n            var cc = c.charCodeAt(0);\\n            return cc < 0x80 ? c\\n                : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))\\n                                + fromCharCode(0x80 | (cc & 0x3f)))\\n                : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))\\n                   + fromCharCode(0x80 | ((cc >>>  6) & 0x3f))\\n                   + fromCharCode(0x80 | ( cc         & 0x3f)));\\n        } else {\\n            var cc = 0x10000\\n                + (c.charCodeAt(0) - 0xD800) * 0x400\\n                + (c.charCodeAt(1) - 0xDC00);\\n            return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))\\n                    + fromCharCode(0x80 | ((cc >>> 12) & 0x3f))\\n                    + fromCharCode(0x80 | ((cc >>>  6) & 0x3f))\\n                    + fromCharCode(0x80 | ( cc         & 0x3f)));\\n        }\\n    };\\n    var re_utob = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFFF]|[^\\0-]/g;\\n    var utob = function(u) {\\n        return u.replace(re_utob, cb_utob);\\n    };\\n    var cb_encode = function(ccc) {\\n        var padlen = [0, 2, 1][ccc.length % 3],\\n        ord = ccc.charCodeAt(0) << 16\\n            | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)\\n            | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),\\n        chars = [\\n            b64chars.charAt( ord >>> 18),\\n            b64chars.charAt((ord >>> 12) & 63),\\n            padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),\\n            padlen >= 1 ? '=' : b64chars.charAt(ord & 63)\\n        ];\\n        return chars.join('');\\n    };\\n    var btoa = global.btoa ? function(b) {\\n        return global.btoa(b);\\n    } : function(b) {\\n        return b.replace(/[sS]{1,3}/g, cb_encode);\\n    };\\n    var _encode = buffer ?\\n        buffer.from && Uint8Array && buffer.from !== Uint8Array.from\\n        ? function (u) {\\n            return (u.constructor === buffer.constructor ? u : buffer.from(u))\\n                .toString('base64')\\n        }\\n        :  function (u) {\\n            return (u.constructor === buffer.constructor ? u : new  buffer(u))\\n                .toString('base64')\\n        }\\n        : function (u) { return btoa(utob(u)) }\\n    ;\\n    var encode = function(u, urisafe) {\\n        return !urisafe\\n            ? _encode(String(u))\\n            : _encode(String(u)).replace(/[+/]/g, function(m0) {\\n                return m0 == '+' ? '-' : '_';\\n            }).replace(/=/g, '');\\n    };\\n    var encodeURI = function(u) { return encode(u, true) };\\n    // decoder stuff\\n    var re_btou = new RegExp([\\n        '[\\u00C0-\\u00DF][\\u0080-\\u00BF]',\\n        '[\\u00E0-\\u00EF][\\u0080-\\u00BF]{2}',\\n        '[\\u00F0-\\u00F7][\\u0080-\\u00BF]{3}'\\n    ].join('|'), 'g');\\n    var cb_btou = function(cccc) {\\n        switch(cccc.length) {\\n        case 4:\\n            var cp = ((0x07 & cccc.charCodeAt(0)) << 18)\\n                |    ((0x3f & cccc.charCodeAt(1)) << 12)\\n                |    ((0x3f & cccc.charCodeAt(2)) <<  6)\\n                |     (0x3f & cccc.charCodeAt(3)),\\n            offset = cp - 0x10000;\\n            return (fromCharCode((offset  >>> 10) + 0xD800)\\n                    + fromCharCode((offset & 0x3FF) + 0xDC00));\\n        case 3:\\n            return fromCharCode(\\n                ((0x0f & cccc.charCodeAt(0)) << 12)\\n                    | ((0x3f & cccc.charCodeAt(1)) << 6)\\n                    |  (0x3f & cccc.charCodeAt(2))\\n            );\\n        default:\\n            return  fromCharCode(\\n                ((0x1f & cccc.charCodeAt(0)) << 6)\\n                    |  (0x3f & cccc.charCodeAt(1))\\n            );\\n        }\\n    };\\n    var btou = function(b) {\\n        return b.replace(re_btou, cb_btou);\\n    };\\n    var cb_decode = function(cccc) {\\n        var len = cccc.length,\\n        padlen = len % 4,\\n        n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)\\n            | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)\\n            | (len > 2 ? b64tab[cccc.charAt(2)] <<  6 : 0)\\n            | (len > 3 ? b64tab[cccc.charAt(3)]       : 0),\\n        chars = [\\n            fromCharCode( n >>> 16),\\n            fromCharCode((n >>>  8) & 0xff),\\n            fromCharCode( n         & 0xff)\\n        ];\\n        chars.length -= [0, 0, 2, 1][padlen];\\n        return chars.join('');\\n    };\\n    var atob = global.atob ? function(a) {\\n        return global.atob(a);\\n    } : function(a){\\n        return a.replace(/[sS]{1,4}/g, cb_decode);\\n    };\\n    var _decode = buffer ?\\n        buffer.from && Uint8Array && buffer.from !== Uint8Array.from\\n        ? function(a) {\\n            return (a.constructor === buffer.constructor\\n                    ? a : buffer.from(a, 'base64')).toString();\\n        }\\n        : function(a) {\\n            return (a.constructor === buffer.constructor\\n                    ? a : new buffer(a, 'base64')).toString();\\n        }\\n        : function(a) { return btou(atob(a)) };\\n    var decode = function(a){\\n        return _decode(\\n            String(a).replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })\\n                .replace(/[^A-Za-z0-9+/]/g, '')\\n        );\\n    };\\n    var noConflict = function() {\\n        var Base64 = global.Base64;\\n        global.Base64 = _Base64;\\n        return Base64;\\n    };\\n    // export Base64\\n    global.Base64 = {\\n        VERSION: version,\\n        atob: atob,\\n        btoa: btoa,\\n        fromBase64: decode,\\n        toBase64: encode,\\n        utob: utob,\\n        encode: encode,\\n        encodeURI: encodeURI,\\n        btou: btou,\\n        decode: decode,\\n        noConflict: noConflict,\\n        __buffer__: buffer\\n    };\\n    // if ES5 is available, make Base64.extendString() available\\n    if (typeof Object.defineProperty === 'function') {\\n        var noEnum = function(v){\\n            return {value:v,enumerable:false,writable:true,configurable:true};\\n        };\\n        global.Base64.extendString = function () {\\n            Object.defineProperty(\\n                String.prototype, 'fromBase64', noEnum(function () {\\n                    return decode(this)\\n                }));\\n            Object.defineProperty(\\n                String.prototype, 'toBase64', noEnum(function (urisafe) {\\n                    return encode(this, urisafe)\\n                }));\\n            Object.defineProperty(\\n                String.prototype, 'toBase64URI', noEnum(function () {\\n                    return encode(this, true)\\n                }));\\n        };\\n    }\\n    return {Base64: global.Base64}\\n}));\\n\";\ndeclare const _default: \"\\nvar WebViewWorker = function(t) {\\n    function r(n) {\\n        if (e[n]) return e[n].exports;\\n        var o = e[n] = {\\n            exports: {},\\n            id: n,\\n            loaded: !1\\n        };\\n        return t[n].call(o.exports, o, o.exports, r), o.loaded = !0, o.exports\\n    }\\n    var e = {};\\n    return r.m = t, r.c = e, r.p = \\\"\\\", r(0)\\n}([function(t, r, e) {\\n    t.exports = e(1)\\n}, function(t, r, e) {\\n    \\\"use strict\\\";\\n    var n = this && this.__awaiter || function(t, r, e, n) {\\n            return new(e || (e = Promise))(function(o, i) {\\n                function a(t) {\\n                    try {\\n                        c(n.next(t))\\n                    } catch (t) {\\n                        i(t)\\n                    }\\n                }\\n\\n                function u(t) {\\n                    try {\\n                        c(n.throw(t))\\n                    } catch (t) {\\n                        i(t)\\n                    }\\n                }\\n\\n                function c(t) {\\n                    t.done ? o(t.value) : new e(function(r) {\\n                        r(t.value)\\n                    }).then(a, u)\\n                }\\n                c((n = n.apply(t, r)).next())\\n            })\\n        },\\n        o = this && this.__generator || function(t, r) {\\n            function e(t) {\\n                return function(r) {\\n                    return n([t, r])\\n                }\\n            }\\n\\n            function n(e) {\\n                if (o) throw new TypeError(\\\"Generator is already executing.\\\");\\n                for (; u;) try {\\n                    if (o = 1, i && (a = i[2 & e[0] ? \\\"return\\\" : e[0] ? \\\"throw\\\" : \\\"next\\\"]) && !(a = a.call(i, e[1])).done) return a;\\n                    switch (i = 0, a && (e = [0, a.value]), e[0]) {\\n                        case 0:\\n                        case 1:\\n                            a = e;\\n                            break;\\n                        case 4:\\n                            return u.label++, {\\n                                value: e[1],\\n                                done: !1\\n                            };\\n                        case 5:\\n                            u.label++, i = e[1], e = [0];\\n                            continue;\\n                        case 7:\\n                            e = u.ops.pop(), u.trys.pop();\\n                            continue;\\n                        default:\\n                            if (a = u.trys, !(a = a.length > 0 && a[a.length - 1]) && (6 === e[0] || 2 === e[0])) {\\n                                u = 0;\\n                                continue\\n                            }\\n                            if (3 === e[0] && (!a || e[1] > a[0] && e[1] < a[3])) {\\n                                u.label = e[1];\\n                                break\\n                            }\\n                            if (6 === e[0] && u.label < a[1]) {\\n                                u.label = a[1], a = e;\\n                                break\\n                            }\\n                            if (a && u.label < a[2]) {\\n                                u.label = a[2], u.ops.push(e);\\n                                break\\n                            }\\n                            a[2] && u.ops.pop(), u.trys.pop();\\n                            continue\\n                    }\\n                    e = r.call(t, u)\\n                } catch (t) {\\n                    e = [6, t], i = 0\\n                } finally {\\n                    o = a = 0\\n                }\\n                if (5 & e[0]) throw e[1];\\n                return {\\n                    value: e[0] ? e[1] : void 0,\\n                    done: !0\\n                }\\n            }\\n            var o, i, a, u = {\\n                label: 0,\\n                sent: function() {\\n                    if (1 & a[0]) throw a[1];\\n                    return a[1]\\n                },\\n                trys: [],\\n                ops: []\\n            };\\n            return {\\n                next: e(0),\\n                throw: e(1),\\n                return: e(2)\\n            }\\n        },\\n        i = e(2),\\n        a = e(126),\\n        u = e(127),\\n        c = function() {\\n            function t(t) {\\n                this.sendToMain = t, t(\\\"We are ready!\\\")\\n            }\\n            return t.prototype.onMainMessage = function(t) {\\n                return n(this, void 0, void 0, function() {\\n                    var r, e, n, c, s, f, p, l;\\n                    return o(this, function(o) {\\n                        switch (o.label) {\\n                            case 0:\\n                                return o.trys.push([0, 2, , 4]), [4, i.parse(t)];\\n                            case 1:\\n                                return l = o.sent(), r = l.id, e = l.method, n = l.args, [3, 4];\\n                            case 2:\\n                                return c = o.sent(), [4, this.send({\\n                                    reason: \\\"Couldn't parse data: \\\" + c\\n                                })];\\n                            case 3:\\n                                return o.sent(), [2];\\n                            case 4:\\n                                return o.trys.push([4, 8, , 10]), \\\"getRandomValues\\\" !== e ? [3, 5] : (s = crypto.getRandomValues(n[0]), [3, 7]);\\n                            case 5:\\n                                // console.log(f, n)\\n                                return f = e.split(\\\".\\\")[1], [4, a.subtle()[f].apply(a.subtle(), n)];\\n                            case 6:\\n                                s = o.sent(), \\\"importKey\\\" === f && (s._import = {\\n                                    format: n[0],\\n                                    keyData: n[1]\\n                                }), o.label = 7;\\n                            case 7:\\n                                return [3, 10];\\n                            case 8:\\n                                return p = o.sent(), [4, this.send({\\n                                    id: r,\\n                                    reason: u(p)\\n                                })];\\n                            case 9:\\n                                return o.sent(), [2];\\n                            case 10:\\n                                return [4, this.send({\\n                                    id: r,\\n                                    value: s\\n                                })];\\n                            case 11:\\n                                return o.sent(), [2]\\n                        }\\n                    })\\n                })\\n            }, t.prototype.send = function(t) {\\n                return n(this, void 0, void 0, function() {\\n                    var r, e, n;\\n                    return o(this, function(o) {\\n                        switch (o.label) {\\n                            case 0:\\n                                return o.trys.push([0, 2, , 3]), [4, i.stringify(t)];\\n                            case 1:\\n                                return r = o.sent(), [3, 3];\\n                            case 2:\\n                                return e = o.sent(), n = {\\n                                    id: t.id,\\n                                    reason: \\\"stringify error \\\" + e\\n                                }, this.sendToMain(JSON.stringify(n)), [2];\\n                            case 3:\\n                                return this.sendToMain(r), [2]\\n                        }\\n                    })\\n                })\\n            }, t\\n        }();\\n    t.exports = c\\n}, function(module, exports, __webpack_require__) {\\n    \\\"use strict\\\";\\n\\n    function parse(t) {\\n        return __awaiter(this, void 0, void 0, function() {\\n            var r, e;\\n            return __generator(this, function(n) {\\n                switch (n.label) {\\n                    case 0:\\n                        // console.log('*** decoding', t);\\n                        return r = unescape(t), e = JSON.parse(r), [4, asyncSerialize_1.fromObjects(serializers(!0), e)];\\n                    case 1:\\n                        return [2, n.sent()]\\n                }\\n            })\\n        })\\n    }\\n\\n    function stringify(t, r) {\\n        return void 0 === r && (r = !0), __awaiter(this, void 0, void 0, function() {\\n            var e, n;\\n            return __generator(this, function(o) {\\n                switch (o.label) {\\n                    case 0:\\n                        return [4, asyncSerialize_1.toObjects(serializers(r), t)];\\n                    case 1:\\n                        // console.log('*** encoding', n);\\n                        return e = o.sent(), n = JSON.stringify(e), [2, escape(n)]\\n                }\\n            })\\n        })\\n    }\\n\\n    function serializers(t) {\\n        return [ArrayBufferSerializer, ArrayBufferViewSerializer(t), CryptoKeySerializer]\\n    }\\n\\n    function isArrayBufferViewWithPromise(t) {\\n        return t.hasOwnProperty(\\\"_promise\\\")\\n    }\\n\\n    function arrayBufferViewName(t) {\\n        return t instanceof Int8Array ? \\\"Int8Array\\\" : t instanceof Uint8Array ? \\\"Uint8Array\\\" : t instanceof Uint8ClampedArray ? \\\"Uint8ClampedArray\\\" : t instanceof Int16Array ? \\\"Int16Array\\\" : t instanceof Uint16Array ? \\\"Uint16Array\\\" : t instanceof Int32Array ? \\\"Int32Array\\\" : t instanceof Uint32Array ? \\\"Uint32Array\\\" : t instanceof Float32Array ? \\\"Float32Array\\\" : t instanceof Float64Array ? \\\"Float64Array\\\" : t instanceof DataView ? \\\"DataView\\\" : void 0\\n    }\\n\\n    function ArrayBufferViewSerializer(waitForPromise) {\\n        var _this = this;\\n        return {\\n            id: \\\"ArrayBufferView\\\",\\n            isType: ArrayBuffer.isView,\\n            toObject: function(t) {\\n                return __awaiter(_this, void 0, void 0, function() {\\n                    return __generator(this, function(r) {\\n                        switch (r.label) {\\n                            case 0:\\n                                return waitForPromise && isArrayBufferViewWithPromise(t) ? [4, t._promise] : [3, 2];\\n                            case 1:\\n                                r.sent(), r.label = 2;\\n                            case 2:\\n                                return [2, {\\n                                    name: arrayBufferViewName(t),\\n                                    buffer: t.buffer\\n                                }]\\n                        }\\n                    })\\n                })\\n            },\\n            fromObject: function(abvs) {\\n                return __awaiter(_this, void 0, void 0, function() {\\n                    return __generator(this, function(_a) {\\n                        return [2, eval(\\\"new \\\" + abvs.name + \\\"(abvs.buffer)\\\")]\\n                    })\\n                })\\n            }\\n        }\\n    }\\n\\n    function hasData(t) {\\n        return void 0 !== t._import\\n    }\\n    var __assign = this && this.__assign || Object.assign || function(t) {\\n            for (var r, e = 1, n = arguments.length; e < n; e++) {\\n                r = arguments[e];\\n                for (var o in r) Object.prototype.hasOwnProperty.call(r, o) && (t[o] = r[o])\\n            }\\n            return t\\n        },\\n        __awaiter = this && this.__awaiter || function(t, r, e, n) {\\n            return new(e || (e = Promise))(function(o, i) {\\n                function a(t) {\\n                    try {\\n                        c(n.next(t))\\n                    } catch (t) {\\n                        i(t)\\n                    }\\n                }\\n\\n                function u(t) {\\n                    try {\\n                        c(n.throw(t))\\n                    } catch (t) {\\n                        i(t)\\n                    }\\n                }\\n\\n                function c(t) {\\n                    t.done ? o(t.value) : new e(function(r) {\\n                        r(t.value)\\n                    }).then(a, u)\\n                }\\n                c((n = n.apply(t, r)).next())\\n            })\\n        },\\n        __generator = this && this.__generator || function(t, r) {\\n            function e(t) {\\n                return function(r) {\\n                    return n([t, r])\\n                }\\n            }\\n\\n            function n(e) {\\n                if (o) throw new TypeError(\\\"Generator is already executing.\\\");\\n                for (; u;) try {\\n                    if (o = 1, i && (a = i[2 & e[0] ? \\\"return\\\" : e[0] ? \\\"throw\\\" : \\\"next\\\"]) && !(a = a.call(i, e[1])).done) return a;\\n                    switch (i = 0, a && (e = [0, a.value]), e[0]) {\\n                        case 0:\\n                        case 1:\\n                            a = e;\\n                            break;\\n                        case 4:\\n                            return u.label++, {\\n                                value: e[1],\\n                                done: !1\\n                            };\\n                        case 5:\\n                            u.label++, i = e[1], e = [0];\\n                            continue;\\n                        case 7:\\n                            e = u.ops.pop(), u.trys.pop();\\n                            continue;\\n                        default:\\n                            if (a = u.trys, !(a = a.length > 0 && a[a.length - 1]) && (6 === e[0] || 2 === e[0])) {\\n                                u = 0;\\n                                continue\\n                            }\\n                            if (3 === e[0] && (!a || e[1] > a[0] && e[1] < a[3])) {\\n                                u.label = e[1];\\n                                break\\n                            }\\n                            if (6 === e[0] && u.label < a[1]) {\\n                                u.label = a[1], a = e;\\n                                break\\n                            }\\n                            if (a && u.label < a[2]) {\\n                                u.label = a[2], u.ops.push(e);\\n                                break\\n                            }\\n                            a[2] && u.ops.pop(), u.trys.pop();\\n                            continue\\n                    }\\n                    e = r.call(t, u)\\n                } catch (t) {\\n                    e = [6, t], i = 0\\n                } finally {\\n                    o = a = 0\\n                }\\n                if (5 & e[0]) throw e[1];\\n                return {\\n                    value: e[0] ? e[1] : void 0,\\n                    done: !0\\n                }\\n            }\\n            var o, i, a, u = {\\n                label: 0,\\n                sent: function() {\\n                    if (1 & a[0]) throw a[1];\\n                    return a[1]\\n                },\\n                trys: [],\\n                ops: []\\n            };\\n            return {\\n                next: e(0),\\n                throw: e(1),\\n                return: e(2)\\n            }\\n        },\\n        _this = this,\\n        asyncSerialize_1 = __webpack_require__(3),\\n        compat_1 = __webpack_require__(126);\\n    exports.parse = parse, exports.stringify = stringify;\\n    var ArrayBufferSerializer = {\\n            id: \\\"ArrayBuffer\\\",\\n            isType: function(t) {\\n                return t instanceof ArrayBuffer\\n            },\\n            toObject: function(t) {\\n                return __awaiter(_this, void 0, void 0, function() {\\n                    return __generator(this, function(r) {\\n                        return [2, String.fromCharCode.apply(null, new Int8Array(t))]\\n                    })\\n                })\\n            },\\n            fromObject: function(t) {\\n                return __awaiter(_this, void 0, void 0, function() {\\n                    var r, e, n, o;\\n                    return __generator(this, function(i) {\\n                        for (r = new ArrayBuffer(t.length), e = new Int8Array(r), n = 0, o = t.length; n < o; n++) e[n] = t.charCodeAt(n);\\n                        return [2, r]\\n                    })\\n                })\\n            }\\n        },\\n        CryptoKeySerializer = {\\n            id: \\\"CryptoKey\\\",\\n            isType: function(t) {\\n                var r = t.toLocaleString(),\\n                    e = \\\"[object CryptoKey]\\\" === r || \\\"[object Key]\\\" === r,\\n                    n = t._import && !t.serialized;\\n                return e || n\\n            },\\n            toObject: function(t) {\\n                return __awaiter(_this, void 0, void 0, function() {\\n                    var r;\\n                    return __generator(this, function(e) {\\n                        switch (e.label) {\\n                            case 0:\\n                                return hasData(t) ? [2, {\\n                                    serialized: !0,\\n                                    _import: t._import,\\n                                    type: t.type,\\n                                    extractable: t.extractable,\\n                                    algorithm: t.algorithm,\\n                                    usages: t.usages\\n                                }] : [4, compat_1.subtle().exportKey(\\\"jwk\\\", t)];\\n                            case 1:\\n                                return r = e.sent(), [2, {\\n                                    _import: {\\n                                        format: \\\"jwk\\\",\\n                                        keyData: r\\n                                    },\\n                                    serialized: !0,\\n                                    algorithm: t.algorithm,\\n                                    extractable: t.extractable,\\n                                    usages: t.usages,\\n                                    type: t.type\\n                                }]\\n                        }\\n                    })\\n                })\\n            },\\n            fromObject: function(t) {\\n                return __awaiter(_this, void 0, void 0, function() {\\n                    var r;\\n                    return __generator(this, function(e) {\\n                        switch (e.label) {\\n                            case 0:\\n                                return crypto.fake ? (r = __assign({}, t), delete r.serialized, [2, r]) : [4, compat_1.subtle().importKey(t._import.format, t._import.keyData, t.algorithm, t.extractable, t.usages)];\\n                            case 1:\\n                                return [2, e.sent()]\\n                        }\\n                    })\\n                })\\n            }\\n        }\\n}, function(t, r, e) {\\n    \\\"use strict\\\";\\n\\n    function n(t) {\\n        return t.hasOwnProperty(\\\"__serializer_id\\\")\\n    }\\n\\n    function o(t, r) {\\n        return a(this, void 0, void 0, function() {\\n            var e, n, i, a, s, f, p, l, v, h, y;\\n            return u(this, function(u) {\\n                switch (u.label) {\\n                    case 0:\\n                        return \\\"object\\\" != typeof r ? [2, r] : (e = c(t, function(t) {\\n                            return t.isType(r)\\n                        }), e ? e.toObject ? [4, e.toObject(r)] : [3, 2] : [3, 5]);\\n                    case 1:\\n                        return i = u.sent(), [3, 3];\\n                    case 2:\\n                        i = r, u.label = 3;\\n                    case 3:\\n                        return n = i, a = {\\n                            __serializer_id: e.id\\n                        }, [4, o(t, n)];\\n                    case 4:\\n                        return [2, (a.value = u.sent(), a)];\\n                    case 5:\\n                        s = r instanceof Array ? [] : {}, f = [];\\n                        for (p in r) f.push(p);\\n                        l = 0, u.label = 6;\\n                    case 6:\\n                        return l < f.length ? (v = f[l], h = s, y = v, [4, o(t, r[v])]) : [3, 9];\\n                    case 7:\\n                        h[y] = u.sent(), u.label = 8;\\n                    case 8:\\n                        return l++, [3, 6];\\n                    case 9:\\n                        return [2, s]\\n                }\\n            })\\n        })\\n    }\\n\\n    function i(t, r) {\\n        return a(this, void 0, void 0, function() {\\n            var e, o, a, s, f, p, l, v, h;\\n            return u(this, function(u) {\\n                switch (u.label) {\\n                    case 0:\\n                        return \\\"object\\\" != typeof r ? [2, r] : n(r) ? [4, i(t, r.value)] : [3, 2];\\n                    case 1:\\n                        return e = u.sent(), o = c(t, [\\\"id\\\", r.__serializer_id]), o.fromObject ? [2, o.fromObject(e)] : [2, e];\\n                    case 2:\\n                        a = r instanceof Array ? [] : {}, s = [];\\n                        for (f in r) s.push(f);\\n                        p = 0, u.label = 3;\\n                    case 3:\\n                        return p < s.length ? (l = s[p], v = a, h = l, [4, i(t, r[l])]) : [3, 6];\\n                    case 4:\\n                        v[h] = u.sent(), u.label = 5;\\n                    case 5:\\n                        return p++, [3, 3];\\n                    case 6:\\n                        return [2, a]\\n                }\\n            })\\n        })\\n    }\\n    var a = this && this.__awaiter || function(t, r, e, n) {\\n            return new(e || (e = Promise))(function(o, i) {\\n                function a(t) {\\n                    try {\\n                        c(n.next(t))\\n                    } catch (t) {\\n                        i(t)\\n                    }\\n                }\\n\\n                function u(t) {\\n                    try {\\n                        c(n.throw(t))\\n                    } catch (t) {\\n                        i(t)\\n                    }\\n                }\\n\\n                function c(t) {\\n                    t.done ? o(t.value) : new e(function(r) {\\n                        r(t.value)\\n                    }).then(a, u)\\n                }\\n                c((n = n.apply(t, r)).next())\\n            })\\n        },\\n        u = this && this.__generator || function(t, r) {\\n            function e(t) {\\n                return function(r) {\\n                    return n([t, r])\\n                }\\n            }\\n\\n            function n(e) {\\n                if (o) throw new TypeError(\\\"Generator is already executing.\\\");\\n                for (; u;) try {\\n                    if (o = 1, i && (a = i[2 & e[0] ? \\\"return\\\" : e[0] ? \\\"throw\\\" : \\\"next\\\"]) && !(a = a.call(i, e[1])).done) return a;\\n                    switch (i = 0, a && (e = [0, a.value]), e[0]) {\\n                        case 0:\\n                        case 1:\\n                            a = e;\\n                            break;\\n                        case 4:\\n                            return u.label++, {\\n                                value: e[1],\\n                                done: !1\\n                            };\\n                        case 5:\\n                            u.label++, i = e[1], e = [0];\\n                            continue;\\n                        case 7:\\n                            e = u.ops.pop(), u.trys.pop();\\n                            continue;\\n                        default:\\n                            if (a = u.trys, !(a = a.length > 0 && a[a.length - 1]) && (6 === e[0] || 2 === e[0])) {\\n                                u = 0;\\n                                continue\\n                            }\\n                            if (3 === e[0] && (!a || e[1] > a[0] && e[1] < a[3])) {\\n                                u.label = e[1];\\n                                break\\n                            }\\n                            if (6 === e[0] && u.label < a[1]) {\\n                                u.label = a[1], a = e;\\n                                break\\n                            }\\n                            if (a && u.label < a[2]) {\\n                                u.label = a[2], u.ops.push(e);\\n                                break\\n                            }\\n                            a[2] && u.ops.pop(), u.trys.pop();\\n                            continue\\n                    }\\n                    e = r.call(t, u)\\n                } catch (t) {\\n                    e = [6, t], i = 0\\n                } finally {\\n                    o = a = 0\\n                }\\n                if (5 & e[0]) throw e[1];\\n                return {\\n                    value: e[0] ? e[1] : void 0,\\n                    done: !0\\n                }\\n            }\\n            var o, i, a, u = {\\n                label: 0,\\n                sent: function() {\\n                    if (1 & a[0]) throw a[1];\\n                    return a[1]\\n                },\\n                trys: [],\\n                ops: []\\n            };\\n            return {\\n                next: e(0),\\n                throw: e(1),\\n                return: e(2)\\n            }\\n        },\\n        c = e(4);\\n    (function() {\\n        function t() {}\\n        return t\\n    })();\\n    r.toObjects = o, r.fromObjects = i\\n}, function(t, r, e) {\\n    var n = e(5),\\n        o = e(121),\\n        i = n(o);\\n    t.exports = i\\n}, function(t, r, e) {\\n    function n(t) {\\n        return function(r, e, n) {\\n            var u = Object(r);\\n            if (!i(r)) {\\n                var c = o(e, 3);\\n                r = a(r), e = function(t) {\\n                    return c(u[t], t, u)\\n                }\\n            }\\n            var s = t(r, e, n);\\n            return s > -1 ? u[c ? r[s] : s] : void 0\\n        }\\n    }\\n    var o = e(6),\\n        i = e(92),\\n        a = e(73);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return \\\"function\\\" == typeof t ? t : null == t ? a : \\\"object\\\" == typeof t ? u(t) ? i(t[0], t[1]) : o(t) : c(t)\\n    }\\n    var o = e(7),\\n        i = e(101),\\n        a = e(117),\\n        u = e(69),\\n        c = e(118);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = i(t);\\n        return 1 == r.length && r[0][2] ? a(r[0][0], r[0][1]) : function(e) {\\n            return e === t || o(e, t, r)\\n        }\\n    }\\n    var o = e(8),\\n        i = e(98),\\n        a = e(100);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r, e, n) {\\n        var c = e.length,\\n            s = c,\\n            f = !n;\\n        if (null == t) return !s;\\n        for (t = Object(t); c--;) {\\n            var p = e[c];\\n            if (f && p[2] ? p[1] !== t[p[0]] : !(p[0] in t)) return !1\\n        }\\n        for (; ++c < s;) {\\n            p = e[c];\\n            var l = p[0],\\n                v = t[l],\\n                h = p[1];\\n            if (f && p[2]) {\\n                if (void 0 === v && !(l in t)) return !1\\n            } else {\\n                var y = new o;\\n                if (n) var _ = n(v, h, l, t, r, y);\\n                if (!(void 0 === _ ? i(h, v, a | u, n, y) : _)) return !1\\n            }\\n        }\\n        return !0\\n    }\\n    var o = e(9),\\n        i = e(53),\\n        a = 1,\\n        u = 2;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = this.__data__ = new o(t);\\n        this.size = r.size\\n    }\\n    var o = e(10),\\n        i = e(18),\\n        a = e(19),\\n        u = e(20),\\n        c = e(21),\\n        s = e(22);\\n    n.prototype.clear = i, n.prototype.delete = a, n.prototype.get = u, n.prototype.has = c, n.prototype.set = s, t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = -1,\\n            e = null == t ? 0 : t.length;\\n        for (this.clear(); ++r < e;) {\\n            var n = t[r];\\n            this.set(n[0], n[1])\\n        }\\n    }\\n    var o = e(11),\\n        i = e(12),\\n        a = e(15),\\n        u = e(16),\\n        c = e(17);\\n    n.prototype.clear = o, n.prototype.delete = i, n.prototype.get = a, n.prototype.has = u, n.prototype.set = c, t.exports = n\\n}, function(t, r) {\\n    function e() {\\n        this.__data__ = [], this.size = 0\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = this.__data__,\\n            e = o(r, t);\\n        if (e < 0) return !1;\\n        var n = r.length - 1;\\n        return e == n ? r.pop() : a.call(r, e, 1), --this.size, !0\\n    }\\n    var o = e(13),\\n        i = Array.prototype,\\n        a = i.splice;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        for (var e = t.length; e--;)\\n            if (o(t[e][0], r)) return e;\\n        return -1\\n    }\\n    var o = e(14);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t, r) {\\n        return t === r || t !== t && r !== r\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = this.__data__,\\n            e = o(r, t);\\n        return e < 0 ? void 0 : r[e][1]\\n    }\\n    var o = e(13);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return o(this.__data__, t) > -1\\n    }\\n    var o = e(13);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        var e = this.__data__,\\n            n = o(e, t);\\n        return n < 0 ? (++this.size, e.push([t, r])) : e[n][1] = r, this\\n    }\\n    var o = e(13);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n() {\\n        this.__data__ = new o, this.size = 0\\n    }\\n    var o = e(10);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        var r = this.__data__,\\n            e = r.delete(t);\\n        return this.size = r.size, e\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t) {\\n        return this.__data__.get(t)\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t) {\\n        return this.__data__.has(t)\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        var e = this.__data__;\\n        if (e instanceof o) {\\n            var n = e.__data__;\\n            if (!i || n.length < u - 1) return n.push([t, r]), this.size = ++e.size, this;\\n            e = this.__data__ = new a(n)\\n        }\\n        return e.set(t, r), this.size = e.size, this\\n    }\\n    var o = e(10),\\n        i = e(23),\\n        a = e(38),\\n        u = 200;\\n    t.exports = n\\n}, function(t, r, e) {\\n    var n = e(24),\\n        o = e(29),\\n        i = n(o, \\\"Map\\\");\\n    t.exports = i\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        var e = i(t, r);\\n        return o(e) ? e : void 0\\n    }\\n    var o = e(25),\\n        i = e(37);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        if (!a(t) || i(t)) return !1;\\n        var r = o(t) ? h : s;\\n        return r.test(u(t))\\n    }\\n    var o = e(26),\\n        i = e(34),\\n        a = e(33),\\n        u = e(36),\\n        c = /[\\\\\\\\^$.*+?()[\\\\]{}|]/g,\\n        s = /^\\\\[object .+?Constructor\\\\]$/,\\n        f = Function.prototype,\\n        p = Object.prototype,\\n        l = f.toString,\\n        v = p.hasOwnProperty,\\n        h = RegExp(\\\"^\\\" + l.call(v).replace(c, \\\"\\\\\\\\$&\\\").replace(/hasOwnProperty|(function).*?(?=\\\\\\\\\\\\()| for .+?(?=\\\\\\\\\\\\])/g, \\\"$1.*?\\\") + \\\"$\\\");\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        if (!i(t)) return !1;\\n        var r = o(t);\\n        return r == u || r == c || r == a || r == s\\n    }\\n    var o = e(27),\\n        i = e(33),\\n        a = \\\"[object AsyncFunction]\\\",\\n        u = \\\"[object Function]\\\",\\n        c = \\\"[object GeneratorFunction]\\\",\\n        s = \\\"[object Proxy]\\\";\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return null == t ? void 0 === t ? c : u : s && s in Object(t) ? i(t) : a(t)\\n    }\\n    var o = e(28),\\n        i = e(31),\\n        a = e(32),\\n        u = \\\"[object Null]\\\",\\n        c = \\\"[object Undefined]\\\",\\n        s = o ? o.toStringTag : void 0;\\n    t.exports = n\\n}, function(t, r, e) {\\n    var n = e(29),\\n        o = n.Symbol;\\n    t.exports = o\\n}, function(t, r, e) {\\n    var n = e(30),\\n        o = \\\"object\\\" == typeof self && self && self.Object === Object && self,\\n        i = n || o || Function(\\\"return this\\\")();\\n    t.exports = i\\n}, function(t, r) {\\n    (function(r) {\\n        var e = \\\"object\\\" == typeof r && r && r.Object === Object && r;\\n        t.exports = e\\n    }).call(r, function() {\\n        return this\\n    }())\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = a.call(t, c),\\n            e = t[c];\\n        try {\\n            t[c] = void 0;\\n            var n = !0\\n        } catch (t) {}\\n        var o = u.call(t);\\n        return n && (r ? t[c] = e : delete t[c]), o\\n    }\\n    var o = e(28),\\n        i = Object.prototype,\\n        a = i.hasOwnProperty,\\n        u = i.toString,\\n        c = o ? o.toStringTag : void 0;\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        return o.call(t)\\n    }\\n    var n = Object.prototype,\\n        o = n.toString;\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t) {\\n        var r = typeof t;\\n        return null != t && (\\\"object\\\" == r || \\\"function\\\" == r)\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        return !!i && i in t\\n    }\\n    var o = e(35),\\n        i = function() {\\n            var t = /[^.]+$/.exec(o && o.keys && o.keys.IE_PROTO || \\\"\\\");\\n            return t ? \\\"Symbol(src)_1.\\\" + t : \\\"\\\"\\n        }();\\n    t.exports = n\\n}, function(t, r, e) {\\n    var n = e(29),\\n        o = n[\\\"__core-js_shared__\\\"];\\n    t.exports = o\\n}, function(t, r) {\\n    function e(t) {\\n        if (null != t) {\\n            try {\\n                return o.call(t)\\n            } catch (t) {}\\n            try {\\n                return t + \\\"\\\"\\n            } catch (t) {}\\n        }\\n        return \\\"\\\"\\n    }\\n    var n = Function.prototype,\\n        o = n.toString;\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t, r) {\\n        return null == t ? void 0 : t[r]\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = -1,\\n            e = null == t ? 0 : t.length;\\n        for (this.clear(); ++r < e;) {\\n            var n = t[r];\\n            this.set(n[0], n[1])\\n        }\\n    }\\n    var o = e(39),\\n        i = e(47),\\n        a = e(50),\\n        u = e(51),\\n        c = e(52);\\n    n.prototype.clear = o, n.prototype.delete = i, n.prototype.get = a, n.prototype.has = u, n.prototype.set = c, t.exports = n\\n}, function(t, r, e) {\\n    function n() {\\n        this.size = 0, this.__data__ = {\\n            hash: new o,\\n            map: new(a || i),\\n            string: new o\\n        }\\n    }\\n    var o = e(40),\\n        i = e(10),\\n        a = e(23);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = -1,\\n            e = null == t ? 0 : t.length;\\n        for (this.clear(); ++r < e;) {\\n            var n = t[r];\\n            this.set(n[0], n[1])\\n        }\\n    }\\n    var o = e(41),\\n        i = e(43),\\n        a = e(44),\\n        u = e(45),\\n        c = e(46);\\n    n.prototype.clear = o, n.prototype.delete = i, n.prototype.get = a, n.prototype.has = u, n.prototype.set = c, t.exports = n\\n}, function(t, r, e) {\\n    function n() {\\n        this.__data__ = o ? o(null) : {}, this.size = 0\\n    }\\n    var o = e(42);\\n    t.exports = n\\n}, function(t, r, e) {\\n    var n = e(24),\\n        o = n(Object, \\\"create\\\");\\n    t.exports = o\\n}, function(t, r) {\\n    function e(t) {\\n        var r = this.has(t) && delete this.__data__[t];\\n        return this.size -= r ? 1 : 0, r\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = this.__data__;\\n        if (o) {\\n            var e = r[t];\\n            return e === i ? void 0 : e\\n        }\\n        return u.call(r, t) ? r[t] : void 0\\n    }\\n    var o = e(42),\\n        i = \\\"__lodash_hash_undefined__\\\",\\n        a = Object.prototype,\\n        u = a.hasOwnProperty;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = this.__data__;\\n        return o ? void 0 !== r[t] : a.call(r, t)\\n    }\\n    var o = e(42),\\n        i = Object.prototype,\\n        a = i.hasOwnProperty;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        var e = this.__data__;\\n        return this.size += this.has(t) ? 0 : 1, e[t] = o && void 0 === r ? i : r, this\\n    }\\n    var o = e(42),\\n        i = \\\"__lodash_hash_undefined__\\\";\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = o(this, t).delete(t);\\n        return this.size -= r ? 1 : 0, r\\n    }\\n    var o = e(48);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        var e = t.__data__;\\n        return o(r) ? e[\\\"string\\\" == typeof r ? \\\"string\\\" : \\\"hash\\\"] : e.map\\n    }\\n    var o = e(49);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        var r = typeof t;\\n        return \\\"string\\\" == r || \\\"number\\\" == r || \\\"symbol\\\" == r || \\\"boolean\\\" == r ? \\\"__proto__\\\" !== t : null === t\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        return o(this, t).get(t)\\n    }\\n    var o = e(48);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return o(this, t).has(t)\\n    }\\n    var o = e(48);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        var e = o(this, t),\\n            n = e.size;\\n        return e.set(t, r), this.size += e.size == n ? 0 : 1, this\\n    }\\n    var o = e(48);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r, e, a, u) {\\n        return t === r || (null == t || null == r || !i(t) && !i(r) ? t !== t && r !== r : o(t, r, e, a, n, u))\\n    }\\n    var o = e(54),\\n        i = e(78);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r, e, n, _, d) {\\n        var x = s(t),\\n            g = s(r),\\n            w = x ? h : c(t),\\n            j = g ? h : c(r);\\n        w = w == v ? y : w, j = j == v ? y : j;\\n        var m = w == y,\\n            O = j == y,\\n            A = w == j;\\n        if (A && f(t)) {\\n            if (!f(r)) return !1;\\n            x = !0, m = !1\\n        }\\n        if (A && !m) return d || (d = new o), x || p(t) ? i(t, r, e, n, _, d) : a(t, r, w, e, n, _, d);\\n        if (!(e & l)) {\\n            var z = m && b.call(t, \\\"__wrapped__\\\"),\\n                k = O && b.call(r, \\\"__wrapped__\\\");\\n            if (z || k) {\\n                var S = z ? t.value() : t,\\n                    P = k ? r.value() : r;\\n                return d || (d = new o), _(S, P, e, n, d)\\n            }\\n        }\\n        return !!A && (d || (d = new o), u(t, r, e, n, _, d))\\n    }\\n    var o = e(9),\\n        i = e(55),\\n        a = e(61),\\n        u = e(65),\\n        c = e(93),\\n        s = e(69),\\n        f = e(79),\\n        p = e(83),\\n        l = 1,\\n        v = \\\"[object Arguments]\\\",\\n        h = \\\"[object Array]\\\",\\n        y = \\\"[object Object]\\\",\\n        _ = Object.prototype,\\n        b = _.hasOwnProperty;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r, e, n, s, f) {\\n        var p = e & u,\\n            l = t.length,\\n            v = r.length;\\n        if (l != v && !(p && v > l)) return !1;\\n        var h = f.get(t);\\n        if (h && f.get(r)) return h == r;\\n        var y = -1,\\n            _ = !0,\\n            b = e & c ? new o : void 0;\\n        for (f.set(t, r), f.set(r, t); ++y < l;) {\\n            var d = t[y],\\n                x = r[y];\\n            if (n) var g = p ? n(x, d, y, r, t, f) : n(d, x, y, t, r, f);\\n            if (void 0 !== g) {\\n                if (g) continue;\\n                _ = !1;\\n                break\\n            }\\n            if (b) {\\n                if (!i(r, function(t, r) {\\n                        if (!a(b, r) && (d === t || s(d, t, e, n, f))) return b.push(r)\\n                    })) {\\n                    _ = !1;\\n                    break\\n                }\\n            } else if (d !== x && !s(d, x, e, n, f)) {\\n                _ = !1;\\n                break\\n            }\\n        }\\n        return f.delete(t), f.delete(r), _\\n    }\\n    var o = e(56),\\n        i = e(59),\\n        a = e(60),\\n        u = 1,\\n        c = 2;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = -1,\\n            e = null == t ? 0 : t.length;\\n        for (this.__data__ = new o; ++r < e;) this.add(t[r])\\n    }\\n    var o = e(38),\\n        i = e(57),\\n        a = e(58);\\n    n.prototype.add = n.prototype.push = i, n.prototype.has = a, t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        return this.__data__.set(t, n), this\\n    }\\n    var n = \\\"__lodash_hash_undefined__\\\";\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t) {\\n        return this.__data__.has(t)\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t, r) {\\n        for (var e = -1, n = null == t ? 0 : t.length; ++e < n;)\\n            if (r(t[e], e, t)) return !0;\\n        return !1\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t, r) {\\n        return t.has(r)\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t, r, e, n, o, m, A) {\\n        switch (e) {\\n            case j:\\n                if (t.byteLength != r.byteLength || t.byteOffset != r.byteOffset) return !1;\\n                t = t.buffer, r = r.buffer;\\n            case w:\\n                return !(t.byteLength != r.byteLength || !m(new i(t), new i(r)));\\n            case l:\\n            case v:\\n            case _:\\n                return a(+t, +r);\\n            case h:\\n                return t.name == r.name && t.message == r.message;\\n            case b:\\n            case x:\\n                return t == r + \\\"\\\";\\n            case y:\\n                var z = c;\\n            case d:\\n                var k = n & f;\\n                if (z || (z = s), t.size != r.size && !k) return !1;\\n                var S = A.get(t);\\n                if (S) return S == r;\\n                n |= p, A.set(t, r);\\n                var P = u(z(t), z(r), n, o, m, A);\\n                return A.delete(t), P;\\n            case g:\\n                if (O) return O.call(t) == O.call(r)\\n        }\\n        return !1\\n    }\\n    var o = e(28),\\n        i = e(62),\\n        a = e(14),\\n        u = e(55),\\n        c = e(63),\\n        s = e(64),\\n        f = 1,\\n        p = 2,\\n        l = \\\"[object Boolean]\\\",\\n        v = \\\"[object Date]\\\",\\n        h = \\\"[object Error]\\\",\\n        y = \\\"[object Map]\\\",\\n        _ = \\\"[object Number]\\\",\\n        b = \\\"[object RegExp]\\\",\\n        d = \\\"[object Set]\\\",\\n        x = \\\"[object String]\\\",\\n        g = \\\"[object Symbol]\\\",\\n        w = \\\"[object ArrayBuffer]\\\",\\n        j = \\\"[object DataView]\\\",\\n        m = o ? o.prototype : void 0,\\n        O = m ? m.valueOf : void 0;\\n    t.exports = n\\n}, function(t, r, e) {\\n    var n = e(29),\\n        o = n.Uint8Array;\\n    t.exports = o\\n}, function(t, r) {\\n    function e(t) {\\n        var r = -1,\\n            e = Array(t.size);\\n        return t.forEach(function(t, n) {\\n            e[++r] = [n, t]\\n        }), e\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t) {\\n        var r = -1,\\n            e = Array(t.size);\\n        return t.forEach(function(t) {\\n            e[++r] = t\\n        }), e\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t, r, e, n, a, c) {\\n        var s = e & i,\\n            f = o(t),\\n            p = f.length,\\n            l = o(r),\\n            v = l.length;\\n        if (p != v && !s) return !1;\\n        for (var h = p; h--;) {\\n            var y = f[h];\\n            if (!(s ? y in r : u.call(r, y))) return !1\\n        }\\n        var _ = c.get(t);\\n        if (_ && c.get(r)) return _ == r;\\n        var b = !0;\\n        c.set(t, r), c.set(r, t);\\n        for (var d = s; ++h < p;) {\\n            y = f[h];\\n            var x = t[y],\\n                g = r[y];\\n            if (n) var w = s ? n(g, x, y, r, t, c) : n(x, g, y, t, r, c);\\n            if (!(void 0 === w ? x === g || a(x, g, e, n, c) : w)) {\\n                b = !1;\\n                break\\n            }\\n            d || (d = \\\"constructor\\\" == y)\\n        }\\n        if (b && !d) {\\n            var j = t.constructor,\\n                m = r.constructor;\\n            j != m && \\\"constructor\\\" in t && \\\"constructor\\\" in r && !(\\\"function\\\" == typeof j && j instanceof j && \\\"function\\\" == typeof m && m instanceof m) && (b = !1)\\n        }\\n        return c.delete(t), c.delete(r), b\\n    }\\n    var o = e(66),\\n        i = 1,\\n        a = Object.prototype,\\n        u = a.hasOwnProperty;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return o(t, a, i)\\n    }\\n    var o = e(67),\\n        i = e(70),\\n        a = e(73);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r, e) {\\n        var n = r(t);\\n        return i(t) ? n : o(n, e(t))\\n    }\\n    var o = e(68),\\n        i = e(69);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t, r) {\\n        for (var e = -1, n = r.length, o = t.length; ++e < n;) t[o + e] = r[e];\\n        return t\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    var e = Array.isArray;\\n    t.exports = e\\n}, function(t, r, e) {\\n    var n = e(71),\\n        o = e(72),\\n        i = Object.prototype,\\n        a = i.propertyIsEnumerable,\\n        u = Object.getOwnPropertySymbols,\\n        c = u ? function(t) {\\n            return null == t ? [] : (t = Object(t), n(u(t), function(r) {\\n                return a.call(t, r)\\n            }))\\n        } : o;\\n    t.exports = c\\n}, function(t, r) {\\n    function e(t, r) {\\n        for (var e = -1, n = null == t ? 0 : t.length, o = 0, i = []; ++e < n;) {\\n            var a = t[e];\\n            r(a, e, t) && (i[o++] = a)\\n        }\\n        return i\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    function e() {\\n        return []\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        return a(t) ? o(t) : i(t)\\n    }\\n    var o = e(74),\\n        i = e(88),\\n        a = e(92);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        var e = a(t),\\n            n = !e && i(t),\\n            f = !e && !n && u(t),\\n            l = !e && !n && !f && s(t),\\n            v = e || n || f || l,\\n            h = v ? o(t.length, String) : [],\\n            y = h.length;\\n        for (var _ in t) !r && !p.call(t, _) || v && (\\\"length\\\" == _ || f && (\\\"offset\\\" == _ || \\\"parent\\\" == _) || l && (\\\"buffer\\\" == _ || \\\"byteLength\\\" == _ || \\\"byteOffset\\\" == _) || c(_, y)) || h.push(_);\\n        return h\\n    }\\n    var o = e(75),\\n        i = e(76),\\n        a = e(69),\\n        u = e(79),\\n        c = e(82),\\n        s = e(83),\\n        f = Object.prototype,\\n        p = f.hasOwnProperty;\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t, r) {\\n        for (var e = -1, n = Array(t); ++e < t;) n[e] = r(e);\\n        return n\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    var n = e(77),\\n        o = e(78),\\n        i = Object.prototype,\\n        a = i.hasOwnProperty,\\n        u = i.propertyIsEnumerable,\\n        c = n(function() {\\n            return arguments\\n        }()) ? n : function(t) {\\n            return o(t) && a.call(t, \\\"callee\\\") && !u.call(t, \\\"callee\\\")\\n        };\\n    t.exports = c\\n}, function(t, r, e) {\\n    function n(t) {\\n        return i(t) && o(t) == a\\n    }\\n    var o = e(27),\\n        i = e(78),\\n        a = \\\"[object Arguments]\\\";\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        return null != t && \\\"object\\\" == typeof t\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    (function(t) {\\n        var n = e(29),\\n            o = e(81),\\n            i = \\\"object\\\" == typeof r && r && !r.nodeType && r,\\n            a = i && \\\"object\\\" == typeof t && t && !t.nodeType && t,\\n            u = a && a.exports === i,\\n            c = u ? n.Buffer : void 0,\\n            s = c ? c.isBuffer : void 0,\\n            f = s || o;\\n        t.exports = f\\n    }).call(r, e(80)(t))\\n}, function(t, r) {\\n    t.exports = function(t) {\\n        return t.webpackPolyfill || (t.deprecate = function() {}, t.paths = [], t.children = [], t.webpackPolyfill = 1), t\\n    }\\n}, function(t, r) {\\n    function e() {\\n        return !1\\n    }\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t, r) {\\n        return r = null == r ? n : r, !!r && (\\\"number\\\" == typeof t || o.test(t)) && t > -1 && t % 1 == 0 && t < r\\n    }\\n    var n = 9007199254740991,\\n        o = /^(?:0|[1-9]\\\\d*)$/;\\n    t.exports = e\\n}, function(t, r, e) {\\n    var n = e(84),\\n        o = e(86),\\n        i = e(87),\\n        a = i && i.isTypedArray,\\n        u = a ? o(a) : n;\\n    t.exports = u\\n}, function(t, r, e) {\\n    function n(t) {\\n        return a(t) && i(t.length) && !!T[o(t)]\\n    }\\n    var o = e(27),\\n        i = e(85),\\n        a = e(78),\\n        u = \\\"[object Arguments]\\\",\\n        c = \\\"[object Array]\\\",\\n        s = \\\"[object Boolean]\\\",\\n        f = \\\"[object Date]\\\",\\n        p = \\\"[object Error]\\\",\\n        l = \\\"[object Function]\\\",\\n        v = \\\"[object Map]\\\",\\n        h = \\\"[object Number]\\\",\\n        y = \\\"[object Object]\\\",\\n        _ = \\\"[object RegExp]\\\",\\n        b = \\\"[object Set]\\\",\\n        d = \\\"[object String]\\\",\\n        x = \\\"[object WeakMap]\\\",\\n        g = \\\"[object ArrayBuffer]\\\",\\n        w = \\\"[object DataView]\\\",\\n        j = \\\"[object Float32Array]\\\",\\n        m = \\\"[object Float64Array]\\\",\\n        O = \\\"[object Int8Array]\\\",\\n        A = \\\"[object Int16Array]\\\",\\n        z = \\\"[object Int32Array]\\\",\\n        k = \\\"[object Uint8Array]\\\",\\n        S = \\\"[object Uint8ClampedArray]\\\",\\n        P = \\\"[object Uint16Array]\\\",\\n        B = \\\"[object Uint32Array]\\\",\\n        T = {};\\n    T[j] = T[m] = T[O] = T[A] = T[z] = T[k] = T[S] = T[P] = T[B] = !0, T[u] = T[c] = T[g] = T[s] = T[w] = T[f] = T[p] = T[l] = T[v] = T[h] = T[y] = T[_] = T[b] = T[d] = T[x] = !1, t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        return \\\"number\\\" == typeof t && t > -1 && t % 1 == 0 && t <= n\\n    }\\n    var n = 9007199254740991;\\n    t.exports = e\\n}, function(t, r) {\\n    function e(t) {\\n        return function(r) {\\n            return t(r)\\n        }\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    (function(t) {\\n        var n = e(30),\\n            o = \\\"object\\\" == typeof r && r && !r.nodeType && r,\\n            i = o && \\\"object\\\" == typeof t && t && !t.nodeType && t,\\n            a = i && i.exports === o,\\n            u = a && n.process,\\n            c = function() {\\n                try {\\n                    return u && u.binding && u.binding(\\\"util\\\")\\n                } catch (t) {}\\n            }();\\n        t.exports = c\\n    }).call(r, e(80)(t))\\n}, function(t, r, e) {\\n    function n(t) {\\n        if (!o(t)) return i(t);\\n        var r = [];\\n        for (var e in Object(t)) u.call(t, e) && \\\"constructor\\\" != e && r.push(e);\\n        return r\\n    }\\n    var o = e(89),\\n        i = e(90),\\n        a = Object.prototype,\\n        u = a.hasOwnProperty;\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        var r = t && t.constructor,\\n            e = \\\"function\\\" == typeof r && r.prototype || n;\\n        return t === e\\n    }\\n    var n = Object.prototype;\\n    t.exports = e\\n}, function(t, r, e) {\\n    var n = e(91),\\n        o = n(Object.keys, Object);\\n    t.exports = o\\n}, function(t, r) {\\n    function e(t, r) {\\n        return function(e) {\\n            return t(r(e))\\n        }\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        return null != t && i(t.length) && !o(t)\\n    }\\n    var o = e(26),\\n        i = e(85);\\n    t.exports = n\\n}, function(t, r, e) {\\n    var n = e(94),\\n        o = e(23),\\n        i = e(95),\\n        a = e(96),\\n        u = e(97),\\n        c = e(27),\\n        s = e(36),\\n        f = \\\"[object Map]\\\",\\n        p = \\\"[object Object]\\\",\\n        l = \\\"[object Promise]\\\",\\n        v = \\\"[object Set]\\\",\\n        h = \\\"[object WeakMap]\\\",\\n        y = \\\"[object DataView]\\\",\\n        _ = s(n),\\n        b = s(o),\\n        d = s(i),\\n        x = s(a),\\n        g = s(u),\\n        w = c;\\n    (n && w(new n(new ArrayBuffer(1))) != y || o && w(new o) != f || i && w(i.resolve()) != l || a && w(new a) != v || u && w(new u) != h) && (w = function(t) {\\n        var r = c(t),\\n            e = r == p ? t.constructor : void 0,\\n            n = e ? s(e) : \\\"\\\";\\n        if (n) switch (n) {\\n            case _:\\n                return y;\\n            case b:\\n                return f;\\n            case d:\\n                return l;\\n            case x:\\n                return v;\\n            case g:\\n                return h\\n        }\\n        return r\\n    }), t.exports = w\\n}, function(t, r, e) {\\n    var n = e(24),\\n        o = e(29),\\n        i = n(o, \\\"DataView\\\");\\n    t.exports = i\\n}, function(t, r, e) {\\n    var n = e(24),\\n        o = e(29),\\n        i = n(o, \\\"Promise\\\");\\n    t.exports = i\\n}, function(t, r, e) {\\n    var n = e(24),\\n        o = e(29),\\n        i = n(o, \\\"Set\\\");\\n    t.exports = i\\n}, function(t, r, e) {\\n    var n = e(24),\\n        o = e(29),\\n        i = n(o, \\\"WeakMap\\\");\\n    t.exports = i\\n}, function(t, r, e) {\\n    function n(t) {\\n        for (var r = i(t), e = r.length; e--;) {\\n            var n = r[e],\\n                a = t[n];\\n            r[e] = [n, a, o(a)]\\n        }\\n        return r\\n    }\\n    var o = e(99),\\n        i = e(73);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return t === t && !o(t)\\n    }\\n    var o = e(33);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t, r) {\\n        return function(e) {\\n            return null != e && (e[t] === r && (void 0 !== r || t in Object(e)))\\n        }\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        return u(t) && c(r) ? s(f(t), r) : function(e) {\\n            var n = i(e, t);\\n            return void 0 === n && n === r ? a(e, t) : o(r, n, p | l)\\n        }\\n    }\\n    var o = e(53),\\n        i = e(102),\\n        a = e(114),\\n        u = e(105),\\n        c = e(99),\\n        s = e(100),\\n        f = e(113),\\n        p = 1,\\n        l = 2;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r, e) {\\n        var n = null == t ? void 0 : o(t, r);\\n        return void 0 === n ? e : n\\n    }\\n    var o = e(103);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        r = o(r, t);\\n        for (var e = 0, n = r.length; null != t && e < n;) t = t[i(r[e++])];\\n        return e && e == n ? t : void 0\\n    }\\n    var o = e(104),\\n        i = e(113);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        return o(t) ? t : i(t, r) ? [t] : a(u(t))\\n    }\\n    var o = e(69),\\n        i = e(105),\\n        a = e(107),\\n        u = e(110);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        if (o(t)) return !1;\\n        var e = typeof t;\\n        return !(\\\"number\\\" != e && \\\"symbol\\\" != e && \\\"boolean\\\" != e && null != t && !i(t)) || (u.test(t) || !a.test(t) || null != r && t in Object(r))\\n    }\\n    var o = e(69),\\n        i = e(106),\\n        a = /\\\\.|\\\\[(?:[^[\\\\]]*|([\\\"'])(?:(?!\\\\1)[^\\\\\\\\]|\\\\\\\\.)*?\\\\1)\\\\]/,\\n        u = /^\\\\w*$/;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return \\\"symbol\\\" == typeof t || i(t) && o(t) == a\\n    }\\n    var o = e(27),\\n        i = e(78),\\n        a = \\\"[object Symbol]\\\";\\n    t.exports = n\\n}, function(t, r, e) {\\n    var n = e(108),\\n        o = /^\\\\./,\\n        i = /[^.[\\\\]]+|\\\\[(?:(-?\\\\d+(?:\\\\.\\\\d+)?)|([\\\"'])((?:(?!\\\\2)[^\\\\\\\\]|\\\\\\\\.)*?)\\\\2)\\\\]|(?=(?:\\\\.|\\\\[\\\\])(?:\\\\.|\\\\[\\\\]|$))/g,\\n        a = /\\\\\\\\(\\\\\\\\)?/g,\\n        u = n(function(t) {\\n            var r = [];\\n            return o.test(t) && r.push(\\\"\\\"), t.replace(i, function(t, e, n, o) {\\n                r.push(n ? o.replace(a, \\\"$1\\\") : e || t)\\n            }), r\\n        });\\n    t.exports = u\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = o(t, function(t) {\\n                return e.size === i && e.clear(), t\\n            }),\\n            e = r.cache;\\n        return r\\n    }\\n    var o = e(109),\\n        i = 500;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        if (\\\"function\\\" != typeof t || null != r && \\\"function\\\" != typeof r) throw new TypeError(i);\\n        var e = function() {\\n            var n = arguments,\\n                o = r ? r.apply(this, n) : n[0],\\n                i = e.cache;\\n            if (i.has(o)) return i.get(o);\\n            var a = t.apply(this, n);\\n            return e.cache = i.set(o, a) || i, a\\n        };\\n        return e.cache = new(n.Cache || o), e\\n    }\\n    var o = e(38),\\n        i = \\\"Expected a function\\\";\\n    n.Cache = o, t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        return null == t ? \\\"\\\" : o(t)\\n    }\\n    var o = e(111);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        if (\\\"string\\\" == typeof t) return t;\\n        if (a(t)) return i(t, n) + \\\"\\\";\\n        if (u(t)) return f ? f.call(t) : \\\"\\\";\\n        var r = t + \\\"\\\";\\n        return \\\"0\\\" == r && 1 / t == -c ? \\\"-0\\\" : r\\n    }\\n    var o = e(28),\\n        i = e(112),\\n        a = e(69),\\n        u = e(106),\\n        c = 1 / 0,\\n        s = o ? o.prototype : void 0,\\n        f = s ? s.toString : void 0;\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t, r) {\\n        for (var e = -1, n = null == t ? 0 : t.length, o = Array(n); ++e < n;) o[e] = r(t[e], e, t);\\n        return o\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        if (\\\"string\\\" == typeof t || o(t)) return t;\\n        var r = t + \\\"\\\";\\n        return \\\"0\\\" == r && 1 / t == -i ? \\\"-0\\\" : r\\n    }\\n    var o = e(106),\\n        i = 1 / 0;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r) {\\n        return null != t && i(t, r, o)\\n    }\\n    var o = e(115),\\n        i = e(116);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t, r) {\\n        return null != t && r in Object(t)\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t, r, e) {\\n        r = o(r, t);\\n        for (var n = -1, f = r.length, p = !1; ++n < f;) {\\n            var l = s(r[n]);\\n            if (!(p = null != t && e(t, l))) break;\\n            t = t[l]\\n        }\\n        return p || ++n != f ? p : (f = null == t ? 0 : t.length, !!f && c(f) && u(l, f) && (a(t) || i(t)))\\n    }\\n    var o = e(104),\\n        i = e(76),\\n        a = e(69),\\n        u = e(82),\\n        c = e(85),\\n        s = e(113);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        return t\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        return a(t) ? o(u(t)) : i(t)\\n    }\\n    var o = e(119),\\n        i = e(120),\\n        a = e(105),\\n        u = e(113);\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t) {\\n        return function(r) {\\n            return null == r ? void 0 : r[t]\\n        }\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        return function(r) {\\n            return o(r, t)\\n        }\\n    }\\n    var o = e(103);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t, r, e) {\\n        var n = null == t ? 0 : t.length;\\n        if (!n) return -1;\\n        var c = null == e ? 0 : a(e);\\n        return c < 0 && (c = u(n + c, 0)), o(t, i(r, 3), c)\\n    }\\n    var o = e(122),\\n        i = e(6),\\n        a = e(123),\\n        u = Math.max;\\n    t.exports = n\\n}, function(t, r) {\\n    function e(t, r, e, n) {\\n        for (var o = t.length, i = e + (n ? 1 : -1); n ? i-- : ++i < o;)\\n            if (r(t[i], i, t)) return i;\\n        return -1\\n    }\\n    t.exports = e\\n}, function(t, r, e) {\\n    function n(t) {\\n        var r = o(t),\\n            e = r % 1;\\n        return r === r ? e ? r - e : r : 0\\n    }\\n    var o = e(124);\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        if (!t) return 0 === t ? t : 0;\\n        if (t = o(t), t === i || t === -i) {\\n            var r = t < 0 ? -1 : 1;\\n            return r * a\\n        }\\n        return t === t ? t : 0\\n    }\\n    var o = e(125),\\n        i = 1 / 0,\\n        a = 1.7976931348623157e308;\\n    t.exports = n\\n}, function(t, r, e) {\\n    function n(t) {\\n        if (\\\"number\\\" == typeof t) return t;\\n        if (i(t)) return a;\\n        if (o(t)) {\\n            var r = \\\"function\\\" == typeof t.valueOf ? t.valueOf() : t;\\n            t = o(r) ? r + \\\"\\\" : r\\n        }\\n        if (\\\"string\\\" != typeof t) return 0 === t ? t : +t;\\n        t = t.replace(u, \\\"\\\");\\n        var e = s.test(t);\\n        return e || f.test(t) ? p(t.slice(2), e ? 2 : 8) : c.test(t) ? a : +t\\n    }\\n    var o = e(33),\\n        i = e(106),\\n        a = NaN,\\n        u = /^\\\\s+|\\\\s+$/g,\\n        c = /^[-+]0x[0-9a-f]+$/i,\\n        s = /^0b[01]+$/i,\\n        f = /^0o[0-7]+$/i,\\n        p = parseInt;\\n    t.exports = n\\n}, function(t, r) {\\n    \\\"use strict\\\";\\n\\n    function e() {\\n        return window.crypto.subtle || window.crypto.webkitSubtle\\n    }\\n    r.subtle = e\\n}, function(t, r) {\\n    \\\"use strict\\\";\\n\\n    function e(t, r) {\\n        var n;\\n        return n = Array.isArray(t) ? [] : {}, r.push(t), Object.keys(t).forEach(function(o) {\\n            var i = t[o];\\n            if (\\\"function\\\" != typeof i) return i && \\\"object\\\" == typeof i ? r.indexOf(t[o]) === -1 ? void(n[o] = e(t[o], r.slice(0))) : void(n[o] = \\\"[Circular]\\\") : void(n[o] = i)\\n        }), \\\"string\\\" == typeof t.name && (n.name = t.name), \\\"string\\\" == typeof t.message && (n.message = t.message), \\\"string\\\" == typeof t.stack && (n.stack = t.stack), n\\n    }\\n    t.exports = function(t) {\\n        return \\\"object\\\" == typeof t ? e(t, []) : \\\"function\\\" == typeof t ? \\\"[Function: \\\" + (t.name || \\\"anonymous\\\") + \\\"]\\\" : t\\n    }\\n}]);\\n\";\nexport default _default;\n"
  },
  {
    "path": "examples/react-native/src/webview-crypto/webViewWorkerString.js",
    "content": "export const base64InjString = `\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined'\n        ? module.exports = factory(global)\n        : typeof define === 'function' && define.amd\n        ? define(factory) : factory(global)\n}((\n    typeof self !== 'undefined' ? self\n        : typeof window !== 'undefined' ? window\n        : typeof global !== 'undefined' ? global\n: this\n), function(global) {\n    'use strict';\n    // existing version for noConflict()\n    var _Base64 = global.Base64;\n    var version = \"2.4.9\";\n    // if node.js and NOT React Native, we use Buffer\n    var buffer;\n    if (typeof module !== 'undefined' && module.exports) {\n        try {\n            buffer = eval(\"require('buffer').Buffer\");\n        } catch (err) {\n            buffer = undefined;\n        }\n    }\n    // constants\n    var b64chars\n        = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n    var b64tab = function(bin) {\n        var t = {};\n        for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;\n        return t;\n    }(b64chars);\n    var fromCharCode = String.fromCharCode;\n    // encoder stuff\n    var cb_utob = function(c) {\n        if (c.length < 2) {\n            var cc = c.charCodeAt(0);\n            return cc < 0x80 ? c\n                : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6))\n                                + fromCharCode(0x80 | (cc & 0x3f)))\n                : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f))\n                   + fromCharCode(0x80 | ((cc >>>  6) & 0x3f))\n                   + fromCharCode(0x80 | ( cc         & 0x3f)));\n        } else {\n            var cc = 0x10000\n                + (c.charCodeAt(0) - 0xD800) * 0x400\n                + (c.charCodeAt(1) - 0xDC00);\n            return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07))\n                    + fromCharCode(0x80 | ((cc >>> 12) & 0x3f))\n                    + fromCharCode(0x80 | ((cc >>>  6) & 0x3f))\n                    + fromCharCode(0x80 | ( cc         & 0x3f)));\n        }\n    };\n    var re_utob = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFFF]|[^\\x00-\\x7F]/g;\n    var utob = function(u) {\n        return u.replace(re_utob, cb_utob);\n    };\n    var cb_encode = function(ccc) {\n        var padlen = [0, 2, 1][ccc.length % 3],\n        ord = ccc.charCodeAt(0) << 16\n            | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8)\n            | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)),\n        chars = [\n            b64chars.charAt( ord >>> 18),\n            b64chars.charAt((ord >>> 12) & 63),\n            padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63),\n            padlen >= 1 ? '=' : b64chars.charAt(ord & 63)\n        ];\n        return chars.join('');\n    };\n    var btoa = global.btoa ? function(b) {\n        return global.btoa(b);\n    } : function(b) {\n        return b.replace(/[\\s\\S]{1,3}/g, cb_encode);\n    };\n    var _encode = buffer ?\n        buffer.from && Uint8Array && buffer.from !== Uint8Array.from\n        ? function (u) {\n            return (u.constructor === buffer.constructor ? u : buffer.from(u))\n                .toString('base64')\n        }\n        :  function (u) {\n            return (u.constructor === buffer.constructor ? u : new  buffer(u))\n                .toString('base64')\n        }\n        : function (u) { return btoa(utob(u)) }\n    ;\n    var encode = function(u, urisafe) {\n        return !urisafe\n            ? _encode(String(u))\n            : _encode(String(u)).replace(/[+\\/]/g, function(m0) {\n                return m0 == '+' ? '-' : '_';\n            }).replace(/=/g, '');\n    };\n    var encodeURI = function(u) { return encode(u, true) };\n    // decoder stuff\n    var re_btou = new RegExp([\n        '[\\xC0-\\xDF][\\x80-\\xBF]',\n        '[\\xE0-\\xEF][\\x80-\\xBF]{2}',\n        '[\\xF0-\\xF7][\\x80-\\xBF]{3}'\n    ].join('|'), 'g');\n    var cb_btou = function(cccc) {\n        switch(cccc.length) {\n        case 4:\n            var cp = ((0x07 & cccc.charCodeAt(0)) << 18)\n                |    ((0x3f & cccc.charCodeAt(1)) << 12)\n                |    ((0x3f & cccc.charCodeAt(2)) <<  6)\n                |     (0x3f & cccc.charCodeAt(3)),\n            offset = cp - 0x10000;\n            return (fromCharCode((offset  >>> 10) + 0xD800)\n                    + fromCharCode((offset & 0x3FF) + 0xDC00));\n        case 3:\n            return fromCharCode(\n                ((0x0f & cccc.charCodeAt(0)) << 12)\n                    | ((0x3f & cccc.charCodeAt(1)) << 6)\n                    |  (0x3f & cccc.charCodeAt(2))\n            );\n        default:\n            return  fromCharCode(\n                ((0x1f & cccc.charCodeAt(0)) << 6)\n                    |  (0x3f & cccc.charCodeAt(1))\n            );\n        }\n    };\n    var btou = function(b) {\n        return b.replace(re_btou, cb_btou);\n    };\n    var cb_decode = function(cccc) {\n        var len = cccc.length,\n        padlen = len % 4,\n        n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0)\n            | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0)\n            | (len > 2 ? b64tab[cccc.charAt(2)] <<  6 : 0)\n            | (len > 3 ? b64tab[cccc.charAt(3)]       : 0),\n        chars = [\n            fromCharCode( n >>> 16),\n            fromCharCode((n >>>  8) & 0xff),\n            fromCharCode( n         & 0xff)\n        ];\n        chars.length -= [0, 0, 2, 1][padlen];\n        return chars.join('');\n    };\n    var atob = global.atob ? function(a) {\n        return global.atob(a);\n    } : function(a){\n        return a.replace(/[\\s\\S]{1,4}/g, cb_decode);\n    };\n    var _decode = buffer ?\n        buffer.from && Uint8Array && buffer.from !== Uint8Array.from\n        ? function(a) {\n            return (a.constructor === buffer.constructor\n                    ? a : buffer.from(a, 'base64')).toString();\n        }\n        : function(a) {\n            return (a.constructor === buffer.constructor\n                    ? a : new buffer(a, 'base64')).toString();\n        }\n        : function(a) { return btou(atob(a)) };\n    var decode = function(a){\n        return _decode(\n            String(a).replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' })\n                .replace(/[^A-Za-z0-9\\+\\/]/g, '')\n        );\n    };\n    var noConflict = function() {\n        var Base64 = global.Base64;\n        global.Base64 = _Base64;\n        return Base64;\n    };\n    // export Base64\n    global.Base64 = {\n        VERSION: version,\n        atob: atob,\n        btoa: btoa,\n        fromBase64: decode,\n        toBase64: encode,\n        utob: utob,\n        encode: encode,\n        encodeURI: encodeURI,\n        btou: btou,\n        decode: decode,\n        noConflict: noConflict,\n        __buffer__: buffer\n    };\n    // if ES5 is available, make Base64.extendString() available\n    if (typeof Object.defineProperty === 'function') {\n        var noEnum = function(v){\n            return {value:v,enumerable:false,writable:true,configurable:true};\n        };\n        global.Base64.extendString = function () {\n            Object.defineProperty(\n                String.prototype, 'fromBase64', noEnum(function () {\n                    return decode(this)\n                }));\n            Object.defineProperty(\n                String.prototype, 'toBase64', noEnum(function (urisafe) {\n                    return encode(this, urisafe)\n                }));\n            Object.defineProperty(\n                String.prototype, 'toBase64URI', noEnum(function () {\n                    return encode(this, true)\n                }));\n        };\n    }\n    return {Base64: global.Base64}\n}));\n`;\nexport default `\nvar WebViewWorker = function(t) {\n    function r(n) {\n        if (e[n]) return e[n].exports;\n        var o = e[n] = {\n            exports: {},\n            id: n,\n            loaded: !1\n        };\n        return t[n].call(o.exports, o, o.exports, r), o.loaded = !0, o.exports\n    }\n    var e = {};\n    return r.m = t, r.c = e, r.p = \"\", r(0)\n}([function(t, r, e) {\n    t.exports = e(1)\n}, function(t, r, e) {\n    \"use strict\";\n    var n = this && this.__awaiter || function(t, r, e, n) {\n            return new(e || (e = Promise))(function(o, i) {\n                function a(t) {\n                    try {\n                        c(n.next(t))\n                    } catch (t) {\n                        i(t)\n                    }\n                }\n\n                function u(t) {\n                    try {\n                        c(n.throw(t))\n                    } catch (t) {\n                        i(t)\n                    }\n                }\n\n                function c(t) {\n                    t.done ? o(t.value) : new e(function(r) {\n                        r(t.value)\n                    }).then(a, u)\n                }\n                c((n = n.apply(t, r)).next())\n            })\n        },\n        o = this && this.__generator || function(t, r) {\n            function e(t) {\n                return function(r) {\n                    return n([t, r])\n                }\n            }\n\n            function n(e) {\n                if (o) throw new TypeError(\"Generator is already executing.\");\n                for (; u;) try {\n                    if (o = 1, i && (a = i[2 & e[0] ? \"return\" : e[0] ? \"throw\" : \"next\"]) && !(a = a.call(i, e[1])).done) return a;\n                    switch (i = 0, a && (e = [0, a.value]), e[0]) {\n                        case 0:\n                        case 1:\n                            a = e;\n                            break;\n                        case 4:\n                            return u.label++, {\n                                value: e[1],\n                                done: !1\n                            };\n                        case 5:\n                            u.label++, i = e[1], e = [0];\n                            continue;\n                        case 7:\n                            e = u.ops.pop(), u.trys.pop();\n                            continue;\n                        default:\n                            if (a = u.trys, !(a = a.length > 0 && a[a.length - 1]) && (6 === e[0] || 2 === e[0])) {\n                                u = 0;\n                                continue\n                            }\n                            if (3 === e[0] && (!a || e[1] > a[0] && e[1] < a[3])) {\n                                u.label = e[1];\n                                break\n                            }\n                            if (6 === e[0] && u.label < a[1]) {\n                                u.label = a[1], a = e;\n                                break\n                            }\n                            if (a && u.label < a[2]) {\n                                u.label = a[2], u.ops.push(e);\n                                break\n                            }\n                            a[2] && u.ops.pop(), u.trys.pop();\n                            continue\n                    }\n                    e = r.call(t, u)\n                } catch (t) {\n                    e = [6, t], i = 0\n                } finally {\n                    o = a = 0\n                }\n                if (5 & e[0]) throw e[1];\n                return {\n                    value: e[0] ? e[1] : void 0,\n                    done: !0\n                }\n            }\n            var o, i, a, u = {\n                label: 0,\n                sent: function() {\n                    if (1 & a[0]) throw a[1];\n                    return a[1]\n                },\n                trys: [],\n                ops: []\n            };\n            return {\n                next: e(0),\n                throw: e(1),\n                return: e(2)\n            }\n        },\n        i = e(2),\n        a = e(126),\n        u = e(127),\n        c = function() {\n            function t(t) {\n                this.sendToMain = t, t(\"We are ready!\")\n            }\n            return t.prototype.onMainMessage = function(t) {\n                return n(this, void 0, void 0, function() {\n                    var r, e, n, c, s, f, p, l;\n                    return o(this, function(o) {\n                        switch (o.label) {\n                            case 0:\n                                return o.trys.push([0, 2, , 4]), [4, i.parse(t)];\n                            case 1:\n                                return l = o.sent(), r = l.id, e = l.method, n = l.args, [3, 4];\n                            case 2:\n                                return c = o.sent(), [4, this.send({\n                                    reason: \"Couldn't parse data: \" + c\n                                })];\n                            case 3:\n                                return o.sent(), [2];\n                            case 4:\n                                return o.trys.push([4, 8, , 10]), \"getRandomValues\" !== e ? [3, 5] : (s = crypto.getRandomValues(n[0]), [3, 7]);\n                            case 5:\n                                // console.log(f, n)\n                                return f = e.split(\".\")[1], [4, a.subtle()[f].apply(a.subtle(), n)];\n                            case 6:\n                                s = o.sent(), \"importKey\" === f && (s._import = {\n                                    format: n[0],\n                                    keyData: n[1]\n                                }), o.label = 7;\n                            case 7:\n                                return [3, 10];\n                            case 8:\n                                return p = o.sent(), [4, this.send({\n                                    id: r,\n                                    reason: u(p)\n                                })];\n                            case 9:\n                                return o.sent(), [2];\n                            case 10:\n                                return [4, this.send({\n                                    id: r,\n                                    value: s\n                                })];\n                            case 11:\n                                return o.sent(), [2]\n                        }\n                    })\n                })\n            }, t.prototype.send = function(t) {\n                return n(this, void 0, void 0, function() {\n                    var r, e, n;\n                    return o(this, function(o) {\n                        switch (o.label) {\n                            case 0:\n                                return o.trys.push([0, 2, , 3]), [4, i.stringify(t)];\n                            case 1:\n                                return r = o.sent(), [3, 3];\n                            case 2:\n                                return e = o.sent(), n = {\n                                    id: t.id,\n                                    reason: \"stringify error \" + e\n                                }, this.sendToMain(JSON.stringify(n)), [2];\n                            case 3:\n                                return this.sendToMain(r), [2]\n                        }\n                    })\n                })\n            }, t\n        }();\n    t.exports = c\n}, function(module, exports, __webpack_require__) {\n    \"use strict\";\n\n    function parse(t) {\n        return __awaiter(this, void 0, void 0, function() {\n            var r, e;\n            return __generator(this, function(n) {\n                switch (n.label) {\n                    case 0:\n                        console.log('*** decoding', t);\n                        return r = unescape(t), e = JSON.parse(r), [4, asyncSerialize_1.fromObjects(serializers(!0), e)];\n                    case 1:\n                        return [2, n.sent()]\n                }\n            })\n        })\n    }\n\n    function stringify(t, r) {\n        return void 0 === r && (r = !0), __awaiter(this, void 0, void 0, function() {\n            var e, n;\n            return __generator(this, function(o) {\n                switch (o.label) {\n                    case 0:\n                        return [4, asyncSerialize_1.toObjects(serializers(r), t)];\n                    case 1:\n                        console.log('*** encoding', n);\n                        return e = o.sent(), n = JSON.stringify(e), [2, escape(n)]\n                }\n            })\n        })\n    }\n\n    function serializers(t) {\n        return [ArrayBufferSerializer, ArrayBufferViewSerializer(t), CryptoKeySerializer]\n    }\n\n    function isArrayBufferViewWithPromise(t) {\n        return t.hasOwnProperty(\"_promise\")\n    }\n\n    function arrayBufferViewName(t) {\n        return t instanceof Int8Array ? \"Int8Array\" : t instanceof Uint8Array ? \"Uint8Array\" : t instanceof Uint8ClampedArray ? \"Uint8ClampedArray\" : t instanceof Int16Array ? \"Int16Array\" : t instanceof Uint16Array ? \"Uint16Array\" : t instanceof Int32Array ? \"Int32Array\" : t instanceof Uint32Array ? \"Uint32Array\" : t instanceof Float32Array ? \"Float32Array\" : t instanceof Float64Array ? \"Float64Array\" : t instanceof DataView ? \"DataView\" : void 0\n    }\n\n    function ArrayBufferViewSerializer(waitForPromise) {\n        var _this = this;\n        return {\n            id: \"ArrayBufferView\",\n            isType: ArrayBuffer.isView,\n            toObject: function(t) {\n                return __awaiter(_this, void 0, void 0, function() {\n                    return __generator(this, function(r) {\n                        switch (r.label) {\n                            case 0:\n                                return waitForPromise && isArrayBufferViewWithPromise(t) ? [4, t._promise] : [3, 2];\n                            case 1:\n                                r.sent(), r.label = 2;\n                            case 2:\n                                return [2, {\n                                    name: arrayBufferViewName(t),\n                                    buffer: t.buffer\n                                }]\n                        }\n                    })\n                })\n            },\n            fromObject: function(abvs) {\n                return __awaiter(_this, void 0, void 0, function() {\n                    return __generator(this, function(_a) {\n                        return [2, eval(\"new \" + abvs.name + \"(abvs.buffer)\")]\n                    })\n                })\n            }\n        }\n    }\n\n    function hasData(t) {\n        return void 0 !== t._import\n    }\n    var __assign = this && this.__assign || Object.assign || function(t) {\n            for (var r, e = 1, n = arguments.length; e < n; e++) {\n                r = arguments[e];\n                for (var o in r) Object.prototype.hasOwnProperty.call(r, o) && (t[o] = r[o])\n            }\n            return t\n        },\n        __awaiter = this && this.__awaiter || function(t, r, e, n) {\n            return new(e || (e = Promise))(function(o, i) {\n                function a(t) {\n                    try {\n                        c(n.next(t))\n                    } catch (t) {\n                        i(t)\n                    }\n                }\n\n                function u(t) {\n                    try {\n                        c(n.throw(t))\n                    } catch (t) {\n                        i(t)\n                    }\n                }\n\n                function c(t) {\n                    t.done ? o(t.value) : new e(function(r) {\n                        r(t.value)\n                    }).then(a, u)\n                }\n                c((n = n.apply(t, r)).next())\n            })\n        },\n        __generator = this && this.__generator || function(t, r) {\n            function e(t) {\n                return function(r) {\n                    return n([t, r])\n                }\n            }\n\n            function n(e) {\n                if (o) throw new TypeError(\"Generator is already executing.\");\n                for (; u;) try {\n                    if (o = 1, i && (a = i[2 & e[0] ? \"return\" : e[0] ? \"throw\" : \"next\"]) && !(a = a.call(i, e[1])).done) return a;\n                    switch (i = 0, a && (e = [0, a.value]), e[0]) {\n                        case 0:\n                        case 1:\n                            a = e;\n                            break;\n                        case 4:\n                            return u.label++, {\n                                value: e[1],\n                                done: !1\n                            };\n                        case 5:\n                            u.label++, i = e[1], e = [0];\n                            continue;\n                        case 7:\n                            e = u.ops.pop(), u.trys.pop();\n                            continue;\n                        default:\n                            if (a = u.trys, !(a = a.length > 0 && a[a.length - 1]) && (6 === e[0] || 2 === e[0])) {\n                                u = 0;\n                                continue\n                            }\n                            if (3 === e[0] && (!a || e[1] > a[0] && e[1] < a[3])) {\n                                u.label = e[1];\n                                break\n                            }\n                            if (6 === e[0] && u.label < a[1]) {\n                                u.label = a[1], a = e;\n                                break\n                            }\n                            if (a && u.label < a[2]) {\n                                u.label = a[2], u.ops.push(e);\n                                break\n                            }\n                            a[2] && u.ops.pop(), u.trys.pop();\n                            continue\n                    }\n                    e = r.call(t, u)\n                } catch (t) {\n                    e = [6, t], i = 0\n                } finally {\n                    o = a = 0\n                }\n                if (5 & e[0]) throw e[1];\n                return {\n                    value: e[0] ? e[1] : void 0,\n                    done: !0\n                }\n            }\n            var o, i, a, u = {\n                label: 0,\n                sent: function() {\n                    if (1 & a[0]) throw a[1];\n                    return a[1]\n                },\n                trys: [],\n                ops: []\n            };\n            return {\n                next: e(0),\n                throw: e(1),\n                return: e(2)\n            }\n        },\n        _this = this,\n        asyncSerialize_1 = __webpack_require__(3),\n        compat_1 = __webpack_require__(126);\n    exports.parse = parse, exports.stringify = stringify;\n    var ArrayBufferSerializer = {\n            id: \"ArrayBuffer\",\n            isType: function(t) {\n                return t instanceof ArrayBuffer\n            },\n            toObject: function(t) {\n                return __awaiter(_this, void 0, void 0, function() {\n                    return __generator(this, function(r) {\n                        return [2, String.fromCharCode.apply(null, new Int8Array(t))]\n                    })\n                })\n            },\n            fromObject: function(t) {\n                return __awaiter(_this, void 0, void 0, function() {\n                    var r, e, n, o;\n                    return __generator(this, function(i) {\n                        for (r = new ArrayBuffer(t.length), e = new Int8Array(r), n = 0, o = t.length; n < o; n++) e[n] = t.charCodeAt(n);\n                        return [2, r]\n                    })\n                })\n            }\n        },\n        CryptoKeySerializer = {\n            id: \"CryptoKey\",\n            isType: function(t) {\n                var r = t.toLocaleString(),\n                    e = \"[object CryptoKey]\" === r || \"[object Key]\" === r,\n                    n = t._import && !t.serialized;\n                return e || n\n            },\n            toObject: function(t) {\n                return __awaiter(_this, void 0, void 0, function() {\n                    var r;\n                    return __generator(this, function(e) {\n                        switch (e.label) {\n                            case 0:\n                                return hasData(t) ? [2, {\n                                    serialized: !0,\n                                    _import: t._import,\n                                    type: t.type,\n                                    extractable: t.extractable,\n                                    algorithm: t.algorithm,\n                                    usages: t.usages\n                                }] : [4, compat_1.subtle().exportKey(\"jwk\", t)];\n                            case 1:\n                                return r = e.sent(), [2, {\n                                    _import: {\n                                        format: \"jwk\",\n                                        keyData: r\n                                    },\n                                    serialized: !0,\n                                    algorithm: t.algorithm,\n                                    extractable: t.extractable,\n                                    usages: t.usages,\n                                    type: t.type\n                                }]\n                        }\n                    })\n                })\n            },\n            fromObject: function(t) {\n                return __awaiter(_this, void 0, void 0, function() {\n                    var r;\n                    return __generator(this, function(e) {\n                        switch (e.label) {\n                            case 0:\n                                return crypto.fake ? (r = __assign({}, t), delete r.serialized, [2, r]) : [4, compat_1.subtle().importKey(t._import.format, t._import.keyData, t.algorithm, t.extractable, t.usages)];\n                            case 1:\n                                return [2, e.sent()]\n                        }\n                    })\n                })\n            }\n        }\n}, function(t, r, e) {\n    \"use strict\";\n\n    function n(t) {\n        return t.hasOwnProperty(\"__serializer_id\")\n    }\n\n    function o(t, r) {\n        return a(this, void 0, void 0, function() {\n            var e, n, i, a, s, f, p, l, v, h, y;\n            return u(this, function(u) {\n                switch (u.label) {\n                    case 0:\n                        return \"object\" != typeof r ? [2, r] : (e = c(t, function(t) {\n                            return t.isType(r)\n                        }), e ? e.toObject ? [4, e.toObject(r)] : [3, 2] : [3, 5]);\n                    case 1:\n                        return i = u.sent(), [3, 3];\n                    case 2:\n                        i = r, u.label = 3;\n                    case 3:\n                        return n = i, a = {\n                            __serializer_id: e.id\n                        }, [4, o(t, n)];\n                    case 4:\n                        return [2, (a.value = u.sent(), a)];\n                    case 5:\n                        s = r instanceof Array ? [] : {}, f = [];\n                        for (p in r) f.push(p);\n                        l = 0, u.label = 6;\n                    case 6:\n                        return l < f.length ? (v = f[l], h = s, y = v, [4, o(t, r[v])]) : [3, 9];\n                    case 7:\n                        h[y] = u.sent(), u.label = 8;\n                    case 8:\n                        return l++, [3, 6];\n                    case 9:\n                        return [2, s]\n                }\n            })\n        })\n    }\n\n    function i(t, r) {\n        return a(this, void 0, void 0, function() {\n            var e, o, a, s, f, p, l, v, h;\n            return u(this, function(u) {\n                switch (u.label) {\n                    case 0:\n                        return \"object\" != typeof r ? [2, r] : n(r) ? [4, i(t, r.value)] : [3, 2];\n                    case 1:\n                        return e = u.sent(), o = c(t, [\"id\", r.__serializer_id]), o.fromObject ? [2, o.fromObject(e)] : [2, e];\n                    case 2:\n                        a = r instanceof Array ? [] : {}, s = [];\n                        for (f in r) s.push(f);\n                        p = 0, u.label = 3;\n                    case 3:\n                        return p < s.length ? (l = s[p], v = a, h = l, [4, i(t, r[l])]) : [3, 6];\n                    case 4:\n                        v[h] = u.sent(), u.label = 5;\n                    case 5:\n                        return p++, [3, 3];\n                    case 6:\n                        return [2, a]\n                }\n            })\n        })\n    }\n    var a = this && this.__awaiter || function(t, r, e, n) {\n            return new(e || (e = Promise))(function(o, i) {\n                function a(t) {\n                    try {\n                        c(n.next(t))\n                    } catch (t) {\n                        i(t)\n                    }\n                }\n\n                function u(t) {\n                    try {\n                        c(n.throw(t))\n                    } catch (t) {\n                        i(t)\n                    }\n                }\n\n                function c(t) {\n                    t.done ? o(t.value) : new e(function(r) {\n                        r(t.value)\n                    }).then(a, u)\n                }\n                c((n = n.apply(t, r)).next())\n            })\n        },\n        u = this && this.__generator || function(t, r) {\n            function e(t) {\n                return function(r) {\n                    return n([t, r])\n                }\n            }\n\n            function n(e) {\n                if (o) throw new TypeError(\"Generator is already executing.\");\n                for (; u;) try {\n                    if (o = 1, i && (a = i[2 & e[0] ? \"return\" : e[0] ? \"throw\" : \"next\"]) && !(a = a.call(i, e[1])).done) return a;\n                    switch (i = 0, a && (e = [0, a.value]), e[0]) {\n                        case 0:\n                        case 1:\n                            a = e;\n                            break;\n                        case 4:\n                            return u.label++, {\n                                value: e[1],\n                                done: !1\n                            };\n                        case 5:\n                            u.label++, i = e[1], e = [0];\n                            continue;\n                        case 7:\n                            e = u.ops.pop(), u.trys.pop();\n                            continue;\n                        default:\n                            if (a = u.trys, !(a = a.length > 0 && a[a.length - 1]) && (6 === e[0] || 2 === e[0])) {\n                                u = 0;\n                                continue\n                            }\n                            if (3 === e[0] && (!a || e[1] > a[0] && e[1] < a[3])) {\n                                u.label = e[1];\n                                break\n                            }\n                            if (6 === e[0] && u.label < a[1]) {\n                                u.label = a[1], a = e;\n                                break\n                            }\n                            if (a && u.label < a[2]) {\n                                u.label = a[2], u.ops.push(e);\n                                break\n                            }\n                            a[2] && u.ops.pop(), u.trys.pop();\n                            continue\n                    }\n                    e = r.call(t, u)\n                } catch (t) {\n                    e = [6, t], i = 0\n                } finally {\n                    o = a = 0\n                }\n                if (5 & e[0]) throw e[1];\n                return {\n                    value: e[0] ? e[1] : void 0,\n                    done: !0\n                }\n            }\n            var o, i, a, u = {\n                label: 0,\n                sent: function() {\n                    if (1 & a[0]) throw a[1];\n                    return a[1]\n                },\n                trys: [],\n                ops: []\n            };\n            return {\n                next: e(0),\n                throw: e(1),\n                return: e(2)\n            }\n        },\n        c = e(4);\n    (function() {\n        function t() {}\n        return t\n    })();\n    r.toObjects = o, r.fromObjects = i\n}, function(t, r, e) {\n    var n = e(5),\n        o = e(121),\n        i = n(o);\n    t.exports = i\n}, function(t, r, e) {\n    function n(t) {\n        return function(r, e, n) {\n            var u = Object(r);\n            if (!i(r)) {\n                var c = o(e, 3);\n                r = a(r), e = function(t) {\n                    return c(u[t], t, u)\n                }\n            }\n            var s = t(r, e, n);\n            return s > -1 ? u[c ? r[s] : s] : void 0\n        }\n    }\n    var o = e(6),\n        i = e(92),\n        a = e(73);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return \"function\" == typeof t ? t : null == t ? a : \"object\" == typeof t ? u(t) ? i(t[0], t[1]) : o(t) : c(t)\n    }\n    var o = e(7),\n        i = e(101),\n        a = e(117),\n        u = e(69),\n        c = e(118);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        var r = i(t);\n        return 1 == r.length && r[0][2] ? a(r[0][0], r[0][1]) : function(e) {\n            return e === t || o(e, t, r)\n        }\n    }\n    var o = e(8),\n        i = e(98),\n        a = e(100);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r, e, n) {\n        var c = e.length,\n            s = c,\n            f = !n;\n        if (null == t) return !s;\n        for (t = Object(t); c--;) {\n            var p = e[c];\n            if (f && p[2] ? p[1] !== t[p[0]] : !(p[0] in t)) return !1\n        }\n        for (; ++c < s;) {\n            p = e[c];\n            var l = p[0],\n                v = t[l],\n                h = p[1];\n            if (f && p[2]) {\n                if (void 0 === v && !(l in t)) return !1\n            } else {\n                var y = new o;\n                if (n) var _ = n(v, h, l, t, r, y);\n                if (!(void 0 === _ ? i(h, v, a | u, n, y) : _)) return !1\n            }\n        }\n        return !0\n    }\n    var o = e(9),\n        i = e(53),\n        a = 1,\n        u = 2;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        var r = this.__data__ = new o(t);\n        this.size = r.size\n    }\n    var o = e(10),\n        i = e(18),\n        a = e(19),\n        u = e(20),\n        c = e(21),\n        s = e(22);\n    n.prototype.clear = i, n.prototype.delete = a, n.prototype.get = u, n.prototype.has = c, n.prototype.set = s, t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        var r = -1,\n            e = null == t ? 0 : t.length;\n        for (this.clear(); ++r < e;) {\n            var n = t[r];\n            this.set(n[0], n[1])\n        }\n    }\n    var o = e(11),\n        i = e(12),\n        a = e(15),\n        u = e(16),\n        c = e(17);\n    n.prototype.clear = o, n.prototype.delete = i, n.prototype.get = a, n.prototype.has = u, n.prototype.set = c, t.exports = n\n}, function(t, r) {\n    function e() {\n        this.__data__ = [], this.size = 0\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        var r = this.__data__,\n            e = o(r, t);\n        if (e < 0) return !1;\n        var n = r.length - 1;\n        return e == n ? r.pop() : a.call(r, e, 1), --this.size, !0\n    }\n    var o = e(13),\n        i = Array.prototype,\n        a = i.splice;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        for (var e = t.length; e--;)\n            if (o(t[e][0], r)) return e;\n        return -1\n    }\n    var o = e(14);\n    t.exports = n\n}, function(t, r) {\n    function e(t, r) {\n        return t === r || t !== t && r !== r\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        var r = this.__data__,\n            e = o(r, t);\n        return e < 0 ? void 0 : r[e][1]\n    }\n    var o = e(13);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return o(this.__data__, t) > -1\n    }\n    var o = e(13);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        var e = this.__data__,\n            n = o(e, t);\n        return n < 0 ? (++this.size, e.push([t, r])) : e[n][1] = r, this\n    }\n    var o = e(13);\n    t.exports = n\n}, function(t, r, e) {\n    function n() {\n        this.__data__ = new o, this.size = 0\n    }\n    var o = e(10);\n    t.exports = n\n}, function(t, r) {\n    function e(t) {\n        var r = this.__data__,\n            e = r.delete(t);\n        return this.size = r.size, e\n    }\n    t.exports = e\n}, function(t, r) {\n    function e(t) {\n        return this.__data__.get(t)\n    }\n    t.exports = e\n}, function(t, r) {\n    function e(t) {\n        return this.__data__.has(t)\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t, r) {\n        var e = this.__data__;\n        if (e instanceof o) {\n            var n = e.__data__;\n            if (!i || n.length < u - 1) return n.push([t, r]), this.size = ++e.size, this;\n            e = this.__data__ = new a(n)\n        }\n        return e.set(t, r), this.size = e.size, this\n    }\n    var o = e(10),\n        i = e(23),\n        a = e(38),\n        u = 200;\n    t.exports = n\n}, function(t, r, e) {\n    var n = e(24),\n        o = e(29),\n        i = n(o, \"Map\");\n    t.exports = i\n}, function(t, r, e) {\n    function n(t, r) {\n        var e = i(t, r);\n        return o(e) ? e : void 0\n    }\n    var o = e(25),\n        i = e(37);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        if (!a(t) || i(t)) return !1;\n        var r = o(t) ? h : s;\n        return r.test(u(t))\n    }\n    var o = e(26),\n        i = e(34),\n        a = e(33),\n        u = e(36),\n        c = /[\\\\\\\\^$.*+?()[\\\\]{}|]/g,\n        s = /^\\\\[object .+?Constructor\\\\]$/,\n        f = Function.prototype,\n        p = Object.prototype,\n        l = f.toString,\n        v = p.hasOwnProperty,\n        h = RegExp(\"^\" + l.call(v).replace(c, \"\\\\\\\\$&\").replace(/hasOwnProperty|(function).*?(?=\\\\\\\\\\\\()| for .+?(?=\\\\\\\\\\\\])/g, \"$1.*?\") + \"$\");\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        if (!i(t)) return !1;\n        var r = o(t);\n        return r == u || r == c || r == a || r == s\n    }\n    var o = e(27),\n        i = e(33),\n        a = \"[object AsyncFunction]\",\n        u = \"[object Function]\",\n        c = \"[object GeneratorFunction]\",\n        s = \"[object Proxy]\";\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return null == t ? void 0 === t ? c : u : s && s in Object(t) ? i(t) : a(t)\n    }\n    var o = e(28),\n        i = e(31),\n        a = e(32),\n        u = \"[object Null]\",\n        c = \"[object Undefined]\",\n        s = o ? o.toStringTag : void 0;\n    t.exports = n\n}, function(t, r, e) {\n    var n = e(29),\n        o = n.Symbol;\n    t.exports = o\n}, function(t, r, e) {\n    var n = e(30),\n        o = \"object\" == typeof self && self && self.Object === Object && self,\n        i = n || o || Function(\"return this\")();\n    t.exports = i\n}, function(t, r) {\n    (function(r) {\n        var e = \"object\" == typeof r && r && r.Object === Object && r;\n        t.exports = e\n    }).call(r, function() {\n        return this\n    }())\n}, function(t, r, e) {\n    function n(t) {\n        var r = a.call(t, c),\n            e = t[c];\n        try {\n            t[c] = void 0;\n            var n = !0\n        } catch (t) {}\n        var o = u.call(t);\n        return n && (r ? t[c] = e : delete t[c]), o\n    }\n    var o = e(28),\n        i = Object.prototype,\n        a = i.hasOwnProperty,\n        u = i.toString,\n        c = o ? o.toStringTag : void 0;\n    t.exports = n\n}, function(t, r) {\n    function e(t) {\n        return o.call(t)\n    }\n    var n = Object.prototype,\n        o = n.toString;\n    t.exports = e\n}, function(t, r) {\n    function e(t) {\n        var r = typeof t;\n        return null != t && (\"object\" == r || \"function\" == r)\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        return !!i && i in t\n    }\n    var o = e(35),\n        i = function() {\n            var t = /[^.]+$/.exec(o && o.keys && o.keys.IE_PROTO || \"\");\n            return t ? \"Symbol(src)_1.\" + t : \"\"\n        }();\n    t.exports = n\n}, function(t, r, e) {\n    var n = e(29),\n        o = n[\"__core-js_shared__\"];\n    t.exports = o\n}, function(t, r) {\n    function e(t) {\n        if (null != t) {\n            try {\n                return o.call(t)\n            } catch (t) {}\n            try {\n                return t + \"\"\n            } catch (t) {}\n        }\n        return \"\"\n    }\n    var n = Function.prototype,\n        o = n.toString;\n    t.exports = e\n}, function(t, r) {\n    function e(t, r) {\n        return null == t ? void 0 : t[r]\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        var r = -1,\n            e = null == t ? 0 : t.length;\n        for (this.clear(); ++r < e;) {\n            var n = t[r];\n            this.set(n[0], n[1])\n        }\n    }\n    var o = e(39),\n        i = e(47),\n        a = e(50),\n        u = e(51),\n        c = e(52);\n    n.prototype.clear = o, n.prototype.delete = i, n.prototype.get = a, n.prototype.has = u, n.prototype.set = c, t.exports = n\n}, function(t, r, e) {\n    function n() {\n        this.size = 0, this.__data__ = {\n            hash: new o,\n            map: new(a || i),\n            string: new o\n        }\n    }\n    var o = e(40),\n        i = e(10),\n        a = e(23);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        var r = -1,\n            e = null == t ? 0 : t.length;\n        for (this.clear(); ++r < e;) {\n            var n = t[r];\n            this.set(n[0], n[1])\n        }\n    }\n    var o = e(41),\n        i = e(43),\n        a = e(44),\n        u = e(45),\n        c = e(46);\n    n.prototype.clear = o, n.prototype.delete = i, n.prototype.get = a, n.prototype.has = u, n.prototype.set = c, t.exports = n\n}, function(t, r, e) {\n    function n() {\n        this.__data__ = o ? o(null) : {}, this.size = 0\n    }\n    var o = e(42);\n    t.exports = n\n}, function(t, r, e) {\n    var n = e(24),\n        o = n(Object, \"create\");\n    t.exports = o\n}, function(t, r) {\n    function e(t) {\n        var r = this.has(t) && delete this.__data__[t];\n        return this.size -= r ? 1 : 0, r\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        var r = this.__data__;\n        if (o) {\n            var e = r[t];\n            return e === i ? void 0 : e\n        }\n        return u.call(r, t) ? r[t] : void 0\n    }\n    var o = e(42),\n        i = \"__lodash_hash_undefined__\",\n        a = Object.prototype,\n        u = a.hasOwnProperty;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        var r = this.__data__;\n        return o ? void 0 !== r[t] : a.call(r, t)\n    }\n    var o = e(42),\n        i = Object.prototype,\n        a = i.hasOwnProperty;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        var e = this.__data__;\n        return this.size += this.has(t) ? 0 : 1, e[t] = o && void 0 === r ? i : r, this\n    }\n    var o = e(42),\n        i = \"__lodash_hash_undefined__\";\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        var r = o(this, t).delete(t);\n        return this.size -= r ? 1 : 0, r\n    }\n    var o = e(48);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        var e = t.__data__;\n        return o(r) ? e[\"string\" == typeof r ? \"string\" : \"hash\"] : e.map\n    }\n    var o = e(49);\n    t.exports = n\n}, function(t, r) {\n    function e(t) {\n        var r = typeof t;\n        return \"string\" == r || \"number\" == r || \"symbol\" == r || \"boolean\" == r ? \"__proto__\" !== t : null === t\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        return o(this, t).get(t)\n    }\n    var o = e(48);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return o(this, t).has(t)\n    }\n    var o = e(48);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        var e = o(this, t),\n            n = e.size;\n        return e.set(t, r), this.size += e.size == n ? 0 : 1, this\n    }\n    var o = e(48);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r, e, a, u) {\n        return t === r || (null == t || null == r || !i(t) && !i(r) ? t !== t && r !== r : o(t, r, e, a, n, u))\n    }\n    var o = e(54),\n        i = e(78);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r, e, n, _, d) {\n        var x = s(t),\n            g = s(r),\n            w = x ? h : c(t),\n            j = g ? h : c(r);\n        w = w == v ? y : w, j = j == v ? y : j;\n        var m = w == y,\n            O = j == y,\n            A = w == j;\n        if (A && f(t)) {\n            if (!f(r)) return !1;\n            x = !0, m = !1\n        }\n        if (A && !m) return d || (d = new o), x || p(t) ? i(t, r, e, n, _, d) : a(t, r, w, e, n, _, d);\n        if (!(e & l)) {\n            var z = m && b.call(t, \"__wrapped__\"),\n                k = O && b.call(r, \"__wrapped__\");\n            if (z || k) {\n                var S = z ? t.value() : t,\n                    P = k ? r.value() : r;\n                return d || (d = new o), _(S, P, e, n, d)\n            }\n        }\n        return !!A && (d || (d = new o), u(t, r, e, n, _, d))\n    }\n    var o = e(9),\n        i = e(55),\n        a = e(61),\n        u = e(65),\n        c = e(93),\n        s = e(69),\n        f = e(79),\n        p = e(83),\n        l = 1,\n        v = \"[object Arguments]\",\n        h = \"[object Array]\",\n        y = \"[object Object]\",\n        _ = Object.prototype,\n        b = _.hasOwnProperty;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r, e, n, s, f) {\n        var p = e & u,\n            l = t.length,\n            v = r.length;\n        if (l != v && !(p && v > l)) return !1;\n        var h = f.get(t);\n        if (h && f.get(r)) return h == r;\n        var y = -1,\n            _ = !0,\n            b = e & c ? new o : void 0;\n        for (f.set(t, r), f.set(r, t); ++y < l;) {\n            var d = t[y],\n                x = r[y];\n            if (n) var g = p ? n(x, d, y, r, t, f) : n(d, x, y, t, r, f);\n            if (void 0 !== g) {\n                if (g) continue;\n                _ = !1;\n                break\n            }\n            if (b) {\n                if (!i(r, function(t, r) {\n                        if (!a(b, r) && (d === t || s(d, t, e, n, f))) return b.push(r)\n                    })) {\n                    _ = !1;\n                    break\n                }\n            } else if (d !== x && !s(d, x, e, n, f)) {\n                _ = !1;\n                break\n            }\n        }\n        return f.delete(t), f.delete(r), _\n    }\n    var o = e(56),\n        i = e(59),\n        a = e(60),\n        u = 1,\n        c = 2;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        var r = -1,\n            e = null == t ? 0 : t.length;\n        for (this.__data__ = new o; ++r < e;) this.add(t[r])\n    }\n    var o = e(38),\n        i = e(57),\n        a = e(58);\n    n.prototype.add = n.prototype.push = i, n.prototype.has = a, t.exports = n\n}, function(t, r) {\n    function e(t) {\n        return this.__data__.set(t, n), this\n    }\n    var n = \"__lodash_hash_undefined__\";\n    t.exports = e\n}, function(t, r) {\n    function e(t) {\n        return this.__data__.has(t)\n    }\n    t.exports = e\n}, function(t, r) {\n    function e(t, r) {\n        for (var e = -1, n = null == t ? 0 : t.length; ++e < n;)\n            if (r(t[e], e, t)) return !0;\n        return !1\n    }\n    t.exports = e\n}, function(t, r) {\n    function e(t, r) {\n        return t.has(r)\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t, r, e, n, o, m, A) {\n        switch (e) {\n            case j:\n                if (t.byteLength != r.byteLength || t.byteOffset != r.byteOffset) return !1;\n                t = t.buffer, r = r.buffer;\n            case w:\n                return !(t.byteLength != r.byteLength || !m(new i(t), new i(r)));\n            case l:\n            case v:\n            case _:\n                return a(+t, +r);\n            case h:\n                return t.name == r.name && t.message == r.message;\n            case b:\n            case x:\n                return t == r + \"\";\n            case y:\n                var z = c;\n            case d:\n                var k = n & f;\n                if (z || (z = s), t.size != r.size && !k) return !1;\n                var S = A.get(t);\n                if (S) return S == r;\n                n |= p, A.set(t, r);\n                var P = u(z(t), z(r), n, o, m, A);\n                return A.delete(t), P;\n            case g:\n                if (O) return O.call(t) == O.call(r)\n        }\n        return !1\n    }\n    var o = e(28),\n        i = e(62),\n        a = e(14),\n        u = e(55),\n        c = e(63),\n        s = e(64),\n        f = 1,\n        p = 2,\n        l = \"[object Boolean]\",\n        v = \"[object Date]\",\n        h = \"[object Error]\",\n        y = \"[object Map]\",\n        _ = \"[object Number]\",\n        b = \"[object RegExp]\",\n        d = \"[object Set]\",\n        x = \"[object String]\",\n        g = \"[object Symbol]\",\n        w = \"[object ArrayBuffer]\",\n        j = \"[object DataView]\",\n        m = o ? o.prototype : void 0,\n        O = m ? m.valueOf : void 0;\n    t.exports = n\n}, function(t, r, e) {\n    var n = e(29),\n        o = n.Uint8Array;\n    t.exports = o\n}, function(t, r) {\n    function e(t) {\n        var r = -1,\n            e = Array(t.size);\n        return t.forEach(function(t, n) {\n            e[++r] = [n, t]\n        }), e\n    }\n    t.exports = e\n}, function(t, r) {\n    function e(t) {\n        var r = -1,\n            e = Array(t.size);\n        return t.forEach(function(t) {\n            e[++r] = t\n        }), e\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t, r, e, n, a, c) {\n        var s = e & i,\n            f = o(t),\n            p = f.length,\n            l = o(r),\n            v = l.length;\n        if (p != v && !s) return !1;\n        for (var h = p; h--;) {\n            var y = f[h];\n            if (!(s ? y in r : u.call(r, y))) return !1\n        }\n        var _ = c.get(t);\n        if (_ && c.get(r)) return _ == r;\n        var b = !0;\n        c.set(t, r), c.set(r, t);\n        for (var d = s; ++h < p;) {\n            y = f[h];\n            var x = t[y],\n                g = r[y];\n            if (n) var w = s ? n(g, x, y, r, t, c) : n(x, g, y, t, r, c);\n            if (!(void 0 === w ? x === g || a(x, g, e, n, c) : w)) {\n                b = !1;\n                break\n            }\n            d || (d = \"constructor\" == y)\n        }\n        if (b && !d) {\n            var j = t.constructor,\n                m = r.constructor;\n            j != m && \"constructor\" in t && \"constructor\" in r && !(\"function\" == typeof j && j instanceof j && \"function\" == typeof m && m instanceof m) && (b = !1)\n        }\n        return c.delete(t), c.delete(r), b\n    }\n    var o = e(66),\n        i = 1,\n        a = Object.prototype,\n        u = a.hasOwnProperty;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return o(t, a, i)\n    }\n    var o = e(67),\n        i = e(70),\n        a = e(73);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r, e) {\n        var n = r(t);\n        return i(t) ? n : o(n, e(t))\n    }\n    var o = e(68),\n        i = e(69);\n    t.exports = n\n}, function(t, r) {\n    function e(t, r) {\n        for (var e = -1, n = r.length, o = t.length; ++e < n;) t[o + e] = r[e];\n        return t\n    }\n    t.exports = e\n}, function(t, r) {\n    var e = Array.isArray;\n    t.exports = e\n}, function(t, r, e) {\n    var n = e(71),\n        o = e(72),\n        i = Object.prototype,\n        a = i.propertyIsEnumerable,\n        u = Object.getOwnPropertySymbols,\n        c = u ? function(t) {\n            return null == t ? [] : (t = Object(t), n(u(t), function(r) {\n                return a.call(t, r)\n            }))\n        } : o;\n    t.exports = c\n}, function(t, r) {\n    function e(t, r) {\n        for (var e = -1, n = null == t ? 0 : t.length, o = 0, i = []; ++e < n;) {\n            var a = t[e];\n            r(a, e, t) && (i[o++] = a)\n        }\n        return i\n    }\n    t.exports = e\n}, function(t, r) {\n    function e() {\n        return []\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        return a(t) ? o(t) : i(t)\n    }\n    var o = e(74),\n        i = e(88),\n        a = e(92);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        var e = a(t),\n            n = !e && i(t),\n            f = !e && !n && u(t),\n            l = !e && !n && !f && s(t),\n            v = e || n || f || l,\n            h = v ? o(t.length, String) : [],\n            y = h.length;\n        for (var _ in t) !r && !p.call(t, _) || v && (\"length\" == _ || f && (\"offset\" == _ || \"parent\" == _) || l && (\"buffer\" == _ || \"byteLength\" == _ || \"byteOffset\" == _) || c(_, y)) || h.push(_);\n        return h\n    }\n    var o = e(75),\n        i = e(76),\n        a = e(69),\n        u = e(79),\n        c = e(82),\n        s = e(83),\n        f = Object.prototype,\n        p = f.hasOwnProperty;\n    t.exports = n\n}, function(t, r) {\n    function e(t, r) {\n        for (var e = -1, n = Array(t); ++e < t;) n[e] = r(e);\n        return n\n    }\n    t.exports = e\n}, function(t, r, e) {\n    var n = e(77),\n        o = e(78),\n        i = Object.prototype,\n        a = i.hasOwnProperty,\n        u = i.propertyIsEnumerable,\n        c = n(function() {\n            return arguments\n        }()) ? n : function(t) {\n            return o(t) && a.call(t, \"callee\") && !u.call(t, \"callee\")\n        };\n    t.exports = c\n}, function(t, r, e) {\n    function n(t) {\n        return i(t) && o(t) == a\n    }\n    var o = e(27),\n        i = e(78),\n        a = \"[object Arguments]\";\n    t.exports = n\n}, function(t, r) {\n    function e(t) {\n        return null != t && \"object\" == typeof t\n    }\n    t.exports = e\n}, function(t, r, e) {\n    (function(t) {\n        var n = e(29),\n            o = e(81),\n            i = \"object\" == typeof r && r && !r.nodeType && r,\n            a = i && \"object\" == typeof t && t && !t.nodeType && t,\n            u = a && a.exports === i,\n            c = u ? n.Buffer : void 0,\n            s = c ? c.isBuffer : void 0,\n            f = s || o;\n        t.exports = f\n    }).call(r, e(80)(t))\n}, function(t, r) {\n    t.exports = function(t) {\n        return t.webpackPolyfill || (t.deprecate = function() {}, t.paths = [], t.children = [], t.webpackPolyfill = 1), t\n    }\n}, function(t, r) {\n    function e() {\n        return !1\n    }\n    t.exports = e\n}, function(t, r) {\n    function e(t, r) {\n        return r = null == r ? n : r, !!r && (\"number\" == typeof t || o.test(t)) && t > -1 && t % 1 == 0 && t < r\n    }\n    var n = 9007199254740991,\n        o = /^(?:0|[1-9]\\\\d*)$/;\n    t.exports = e\n}, function(t, r, e) {\n    var n = e(84),\n        o = e(86),\n        i = e(87),\n        a = i && i.isTypedArray,\n        u = a ? o(a) : n;\n    t.exports = u\n}, function(t, r, e) {\n    function n(t) {\n        return a(t) && i(t.length) && !!T[o(t)]\n    }\n    var o = e(27),\n        i = e(85),\n        a = e(78),\n        u = \"[object Arguments]\",\n        c = \"[object Array]\",\n        s = \"[object Boolean]\",\n        f = \"[object Date]\",\n        p = \"[object Error]\",\n        l = \"[object Function]\",\n        v = \"[object Map]\",\n        h = \"[object Number]\",\n        y = \"[object Object]\",\n        _ = \"[object RegExp]\",\n        b = \"[object Set]\",\n        d = \"[object String]\",\n        x = \"[object WeakMap]\",\n        g = \"[object ArrayBuffer]\",\n        w = \"[object DataView]\",\n        j = \"[object Float32Array]\",\n        m = \"[object Float64Array]\",\n        O = \"[object Int8Array]\",\n        A = \"[object Int16Array]\",\n        z = \"[object Int32Array]\",\n        k = \"[object Uint8Array]\",\n        S = \"[object Uint8ClampedArray]\",\n        P = \"[object Uint16Array]\",\n        B = \"[object Uint32Array]\",\n        T = {};\n    T[j] = T[m] = T[O] = T[A] = T[z] = T[k] = T[S] = T[P] = T[B] = !0, T[u] = T[c] = T[g] = T[s] = T[w] = T[f] = T[p] = T[l] = T[v] = T[h] = T[y] = T[_] = T[b] = T[d] = T[x] = !1, t.exports = n\n}, function(t, r) {\n    function e(t) {\n        return \"number\" == typeof t && t > -1 && t % 1 == 0 && t <= n\n    }\n    var n = 9007199254740991;\n    t.exports = e\n}, function(t, r) {\n    function e(t) {\n        return function(r) {\n            return t(r)\n        }\n    }\n    t.exports = e\n}, function(t, r, e) {\n    (function(t) {\n        var n = e(30),\n            o = \"object\" == typeof r && r && !r.nodeType && r,\n            i = o && \"object\" == typeof t && t && !t.nodeType && t,\n            a = i && i.exports === o,\n            u = a && n.process,\n            c = function() {\n                try {\n                    return u && u.binding && u.binding(\"util\")\n                } catch (t) {}\n            }();\n        t.exports = c\n    }).call(r, e(80)(t))\n}, function(t, r, e) {\n    function n(t) {\n        if (!o(t)) return i(t);\n        var r = [];\n        for (var e in Object(t)) u.call(t, e) && \"constructor\" != e && r.push(e);\n        return r\n    }\n    var o = e(89),\n        i = e(90),\n        a = Object.prototype,\n        u = a.hasOwnProperty;\n    t.exports = n\n}, function(t, r) {\n    function e(t) {\n        var r = t && t.constructor,\n            e = \"function\" == typeof r && r.prototype || n;\n        return t === e\n    }\n    var n = Object.prototype;\n    t.exports = e\n}, function(t, r, e) {\n    var n = e(91),\n        o = n(Object.keys, Object);\n    t.exports = o\n}, function(t, r) {\n    function e(t, r) {\n        return function(e) {\n            return t(r(e))\n        }\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        return null != t && i(t.length) && !o(t)\n    }\n    var o = e(26),\n        i = e(85);\n    t.exports = n\n}, function(t, r, e) {\n    var n = e(94),\n        o = e(23),\n        i = e(95),\n        a = e(96),\n        u = e(97),\n        c = e(27),\n        s = e(36),\n        f = \"[object Map]\",\n        p = \"[object Object]\",\n        l = \"[object Promise]\",\n        v = \"[object Set]\",\n        h = \"[object WeakMap]\",\n        y = \"[object DataView]\",\n        _ = s(n),\n        b = s(o),\n        d = s(i),\n        x = s(a),\n        g = s(u),\n        w = c;\n    (n && w(new n(new ArrayBuffer(1))) != y || o && w(new o) != f || i && w(i.resolve()) != l || a && w(new a) != v || u && w(new u) != h) && (w = function(t) {\n        var r = c(t),\n            e = r == p ? t.constructor : void 0,\n            n = e ? s(e) : \"\";\n        if (n) switch (n) {\n            case _:\n                return y;\n            case b:\n                return f;\n            case d:\n                return l;\n            case x:\n                return v;\n            case g:\n                return h\n        }\n        return r\n    }), t.exports = w\n}, function(t, r, e) {\n    var n = e(24),\n        o = e(29),\n        i = n(o, \"DataView\");\n    t.exports = i\n}, function(t, r, e) {\n    var n = e(24),\n        o = e(29),\n        i = n(o, \"Promise\");\n    t.exports = i\n}, function(t, r, e) {\n    var n = e(24),\n        o = e(29),\n        i = n(o, \"Set\");\n    t.exports = i\n}, function(t, r, e) {\n    var n = e(24),\n        o = e(29),\n        i = n(o, \"WeakMap\");\n    t.exports = i\n}, function(t, r, e) {\n    function n(t) {\n        for (var r = i(t), e = r.length; e--;) {\n            var n = r[e],\n                a = t[n];\n            r[e] = [n, a, o(a)]\n        }\n        return r\n    }\n    var o = e(99),\n        i = e(73);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return t === t && !o(t)\n    }\n    var o = e(33);\n    t.exports = n\n}, function(t, r) {\n    function e(t, r) {\n        return function(e) {\n            return null != e && (e[t] === r && (void 0 !== r || t in Object(e)))\n        }\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t, r) {\n        return u(t) && c(r) ? s(f(t), r) : function(e) {\n            var n = i(e, t);\n            return void 0 === n && n === r ? a(e, t) : o(r, n, p | l)\n        }\n    }\n    var o = e(53),\n        i = e(102),\n        a = e(114),\n        u = e(105),\n        c = e(99),\n        s = e(100),\n        f = e(113),\n        p = 1,\n        l = 2;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r, e) {\n        var n = null == t ? void 0 : o(t, r);\n        return void 0 === n ? e : n\n    }\n    var o = e(103);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        r = o(r, t);\n        for (var e = 0, n = r.length; null != t && e < n;) t = t[i(r[e++])];\n        return e && e == n ? t : void 0\n    }\n    var o = e(104),\n        i = e(113);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        return o(t) ? t : i(t, r) ? [t] : a(u(t))\n    }\n    var o = e(69),\n        i = e(105),\n        a = e(107),\n        u = e(110);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        if (o(t)) return !1;\n        var e = typeof t;\n        return !(\"number\" != e && \"symbol\" != e && \"boolean\" != e && null != t && !i(t)) || (u.test(t) || !a.test(t) || null != r && t in Object(r))\n    }\n    var o = e(69),\n        i = e(106),\n        a = /\\\\.|\\\\[(?:[^[\\\\]]*|([\"'])(?:(?!\\\\1)[^\\\\\\\\]|\\\\\\\\.)*?\\\\1)\\\\]/,\n        u = /^\\\\w*$/;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return \"symbol\" == typeof t || i(t) && o(t) == a\n    }\n    var o = e(27),\n        i = e(78),\n        a = \"[object Symbol]\";\n    t.exports = n\n}, function(t, r, e) {\n    var n = e(108),\n        o = /^\\\\./,\n        i = /[^.[\\\\]]+|\\\\[(?:(-?\\\\d+(?:\\\\.\\\\d+)?)|([\"'])((?:(?!\\\\2)[^\\\\\\\\]|\\\\\\\\.)*?)\\\\2)\\\\]|(?=(?:\\\\.|\\\\[\\\\])(?:\\\\.|\\\\[\\\\]|$))/g,\n        a = /\\\\\\\\(\\\\\\\\)?/g,\n        u = n(function(t) {\n            var r = [];\n            return o.test(t) && r.push(\"\"), t.replace(i, function(t, e, n, o) {\n                r.push(n ? o.replace(a, \"$1\") : e || t)\n            }), r\n        });\n    t.exports = u\n}, function(t, r, e) {\n    function n(t) {\n        var r = o(t, function(t) {\n                return e.size === i && e.clear(), t\n            }),\n            e = r.cache;\n        return r\n    }\n    var o = e(109),\n        i = 500;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        if (\"function\" != typeof t || null != r && \"function\" != typeof r) throw new TypeError(i);\n        var e = function() {\n            var n = arguments,\n                o = r ? r.apply(this, n) : n[0],\n                i = e.cache;\n            if (i.has(o)) return i.get(o);\n            var a = t.apply(this, n);\n            return e.cache = i.set(o, a) || i, a\n        };\n        return e.cache = new(n.Cache || o), e\n    }\n    var o = e(38),\n        i = \"Expected a function\";\n    n.Cache = o, t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        return null == t ? \"\" : o(t)\n    }\n    var o = e(111);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        if (\"string\" == typeof t) return t;\n        if (a(t)) return i(t, n) + \"\";\n        if (u(t)) return f ? f.call(t) : \"\";\n        var r = t + \"\";\n        return \"0\" == r && 1 / t == -c ? \"-0\" : r\n    }\n    var o = e(28),\n        i = e(112),\n        a = e(69),\n        u = e(106),\n        c = 1 / 0,\n        s = o ? o.prototype : void 0,\n        f = s ? s.toString : void 0;\n    t.exports = n\n}, function(t, r) {\n    function e(t, r) {\n        for (var e = -1, n = null == t ? 0 : t.length, o = Array(n); ++e < n;) o[e] = r(t[e], e, t);\n        return o\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        if (\"string\" == typeof t || o(t)) return t;\n        var r = t + \"\";\n        return \"0\" == r && 1 / t == -i ? \"-0\" : r\n    }\n    var o = e(106),\n        i = 1 / 0;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r) {\n        return null != t && i(t, r, o)\n    }\n    var o = e(115),\n        i = e(116);\n    t.exports = n\n}, function(t, r) {\n    function e(t, r) {\n        return null != t && r in Object(t)\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t, r, e) {\n        r = o(r, t);\n        for (var n = -1, f = r.length, p = !1; ++n < f;) {\n            var l = s(r[n]);\n            if (!(p = null != t && e(t, l))) break;\n            t = t[l]\n        }\n        return p || ++n != f ? p : (f = null == t ? 0 : t.length, !!f && c(f) && u(l, f) && (a(t) || i(t)))\n    }\n    var o = e(104),\n        i = e(76),\n        a = e(69),\n        u = e(82),\n        c = e(85),\n        s = e(113);\n    t.exports = n\n}, function(t, r) {\n    function e(t) {\n        return t\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        return a(t) ? o(u(t)) : i(t)\n    }\n    var o = e(119),\n        i = e(120),\n        a = e(105),\n        u = e(113);\n    t.exports = n\n}, function(t, r) {\n    function e(t) {\n        return function(r) {\n            return null == r ? void 0 : r[t]\n        }\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        return function(r) {\n            return o(r, t)\n        }\n    }\n    var o = e(103);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t, r, e) {\n        var n = null == t ? 0 : t.length;\n        if (!n) return -1;\n        var c = null == e ? 0 : a(e);\n        return c < 0 && (c = u(n + c, 0)), o(t, i(r, 3), c)\n    }\n    var o = e(122),\n        i = e(6),\n        a = e(123),\n        u = Math.max;\n    t.exports = n\n}, function(t, r) {\n    function e(t, r, e, n) {\n        for (var o = t.length, i = e + (n ? 1 : -1); n ? i-- : ++i < o;)\n            if (r(t[i], i, t)) return i;\n        return -1\n    }\n    t.exports = e\n}, function(t, r, e) {\n    function n(t) {\n        var r = o(t),\n            e = r % 1;\n        return r === r ? e ? r - e : r : 0\n    }\n    var o = e(124);\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        if (!t) return 0 === t ? t : 0;\n        if (t = o(t), t === i || t === -i) {\n            var r = t < 0 ? -1 : 1;\n            return r * a\n        }\n        return t === t ? t : 0\n    }\n    var o = e(125),\n        i = 1 / 0,\n        a = 1.7976931348623157e308;\n    t.exports = n\n}, function(t, r, e) {\n    function n(t) {\n        if (\"number\" == typeof t) return t;\n        if (i(t)) return a;\n        if (o(t)) {\n            var r = \"function\" == typeof t.valueOf ? t.valueOf() : t;\n            t = o(r) ? r + \"\" : r\n        }\n        if (\"string\" != typeof t) return 0 === t ? t : +t;\n        t = t.replace(u, \"\");\n        var e = s.test(t);\n        return e || f.test(t) ? p(t.slice(2), e ? 2 : 8) : c.test(t) ? a : +t\n    }\n    var o = e(33),\n        i = e(106),\n        a = NaN,\n        u = /^\\\\s+|\\\\s+$/g,\n        c = /^[-+]0x[0-9a-f]+$/i,\n        s = /^0b[01]+$/i,\n        f = /^0o[0-7]+$/i,\n        p = parseInt;\n    t.exports = n\n}, function(t, r) {\n    \"use strict\";\n\n    function e() {\n        return window.crypto.subtle || window.crypto.webkitSubtle\n    }\n    r.subtle = e\n}, function(t, r) {\n    \"use strict\";\n\n    function e(t, r) {\n        var n;\n        return n = Array.isArray(t) ? [] : {}, r.push(t), Object.keys(t).forEach(function(o) {\n            var i = t[o];\n            if (\"function\" != typeof i) return i && \"object\" == typeof i ? r.indexOf(t[o]) === -1 ? void(n[o] = e(t[o], r.slice(0))) : void(n[o] = \"[Circular]\") : void(n[o] = i)\n        }), \"string\" == typeof t.name && (n.name = t.name), \"string\" == typeof t.message && (n.message = t.message), \"string\" == typeof t.stack && (n.stack = t.stack), n\n    }\n    t.exports = function(t) {\n        return \"object\" == typeof t ? e(t, []) : \"function\" == typeof t ? \"[Function: \" + (t.name || \"anonymous\") + \"]\" : t\n    }\n}]);\n`;\n//# sourceMappingURL=webViewWorkerString.js.map"
  },
  {
    "path": "examples/relay-sqlite-example/README.md",
    "content": "# gun-relay-sqlite\n\nManager+Adapter Stable version\n\nSupport iOS & Android \n\n# Quickly build a relay manager and Gun storage adapter with sqlite persistence.\n\n```base\nyarn install\n```\n\n```base\nyarn build\n```\n\n```base\nnpx cap sync\n```\n\n```base\nnpx cap open ios | android  \n```\n\n# Preview\n![relayios](https://github.com/user-attachments/assets/258050f2-328c-42f8-a8b0-0ab24efa9acf)\n"
  },
  {
    "path": "examples/relay-sqlite-example/capacitor.config.ts",
    "content": "import { CapacitorConfig } from '@capacitor/cli';\nimport { CapacitorHttp } from '@capacitor/core';\nimport { KeyboardResize, KeyboardStyle } from '@capacitor/keyboard'\nconst config: CapacitorConfig = {\n  appId: 'com.gun.relay',\n  appName: 'Relay',\n  webDir: 'dist',\n\n \n  plugins: {\n    CapacitorHttp: {\n      enabled: true,\n    },\n   \n    Keyboard: {\n      resize: KeyboardResize.None,\n      resizeOnFullScreen: true,\n   \n    },\n    CapacitorSQLite: {\n      migrate: true,\n    iosDatabaseLocation: 'Library/CapacitorDatabase',\n    iosIsEncryption: true,\n    iosKeychainPrefix: 'gundb',\n    iosBiometric: {\n        biometricAuth: false,\n        biometricTitle : \"Biometric login for capacitor sqlite\"\n    },\n    androidIsEncryption: true,\n    androidBiometric: {\n        biometricAuth : false,\n        biometricTitle : \"Biometric login for capacitor sqlite\",\n        biometricSubTitle : \"Log in using your biometric\"\n    },\n    electronIsEncryption: true,\n    electronWindowsLocation: \"C:\\\\ProgramData\\\\CapacitorDatabases\",\n    electronMacLocation: \"~/Databases/\",\n    electronLinuxLocation: \"Databases\"\n    }\n  }\n};\n\nexport default config;\n"
  },
  {
    "path": "examples/relay-sqlite-example/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Gun-Relay-sqlite</title>\n\n    <base href=\"/\" />\n\n    <meta name=\"color-scheme\" content=\"light dark\" />\n    <meta\n      name=\"viewport\"\n      content=\"viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\"\n    />\n    <meta name=\"format-detection\" content=\"telephone=no\" />\n    <meta name=\"msapplication-tap-highlight\" content=\"no\" />\n\n    <link rel=\"shortcut icon\" type=\"image/png\" href=\"/favicon.png\" />\n\n    <!-- add to homescreen for ios -->\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n    <meta name=\"apple-mobile-web-app-title\" content=\"Gun-Relay-sqlite\" />\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\" />\n  </head>\n\n  <body>\n    <div id=\"app\"></div>\n    <script type=\"module\" src=\"/src/main.ts\"></script>\n  </body>\n\n</html>\n\n"
  },
  {
    "path": "examples/relay-sqlite-example/package.json",
    "content": "{\n  \"name\": \"gun-relay-sqlite\",\n  \"private\": true,\n  \"version\": \"0.0.1\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"npm run copy:sql:wasm && vite --host\",\n    \"build:web\": \"npm run copy:sql:wasm && npm run build\",\n    \"build:native\": \"npm run remove:sql:wasm && npm run build\",\n    \"build\": \"vue-tsc && vite build\",\n    \"preview\": \"vite preview\",\n    \"ionic:serve:before\": \"npm run copy:sql:wasm\",\n    \"copy:sql:wasm\": \"copyfiles -u 3 node_modules/sql.js/dist/sql-wasm.wasm public/assets\",\n    \"remove:sql:wasm\": \"rimraf public/assets/sql-wasm.wasm\",\n    \"ios:start\": \"npm run remove:sql:wasm && npm run build:native && npx cap sync && npx cap copy && npx cap open ios\",\n    \"android:start\": \"npm run remove:sql:wasm && npm run build:native && npx cap sync && npx cap copy && npx cap open android\",\n    \"electron:install\": \"cd electron && npm install && cd ..\",\n    \"electron:prepare\": \"npm run remove:sql:wasm && npm run build && npx cap sync @capacitor-community/electron && npx cap copy @capacitor-community/electron\",\n    \"electron:start\": \"npm run electron:prepare && cd electron && npm run electron:start\",\n    \"clean:vite:cache\": \"vite clean\",\n    \"test:e2e\": \"cypress run\",\n    \"test:unit\": \"vitest\",\n    \"lint\": \"eslint\"\n  },\n  \"dependencies\": {\n    \"@angular/core\": \"^19.1.6\",\n    \"@aparajita/capacitor-biometric-auth\": \"^9.0.0\",\n    \"@aparajita/capacitor-secure-storage\": \"^6.0.1\",\n    \"@capacitor-community/barcode-scanner\": \"^4.0.1\",\n    \"@capacitor-community/electron\": \"^4.1.2\",\n    \"@capacitor-community/media\": \"^8.0.0\",\n    \"@capacitor-community/speech-recognition\": \"^6.0.1\",\n    \"@capacitor-community/sqlite\": \"^5.2.3\",\n    \"@capacitor/action-sheet\": \"^7.0.0\",\n    \"@capacitor/android\": \"^7.0.0\",\n    \"@capacitor/app\": \"^7.0.0\",\n    \"@capacitor/assets\": \"latest\",\n    \"@capacitor/background-runner\": \"^2.1.0\",\n    \"@capacitor/browser\": \"^7.0.0\",\n    \"@capacitor/camera\": \"^7.0.0\",\n    \"@capacitor/clipboard\": \"^7.0.0\",\n    \"@capacitor/core\": \"^7.0.0\",\n    \"@capacitor/device\": \"^7.0.0\",\n    \"@capacitor/dialog\": \"^7.0.0\",\n    \"@capacitor/filesystem\": \"^7.0.0\",\n    \"@capacitor/geolocation\": \"^7.0.0\",\n    \"@capacitor/haptics\": \"^7.0.0\",\n    \"@capacitor/ios\": \"^7.0.0\",\n    \"@capacitor/keyboard\": \"^7.0.0\",\n    \"@capacitor/local-notifications\": \"^7.0.0\",\n    \"@capacitor/network\": \"^7.0.0\",\n    \"@capacitor/preferences\": \"^7.0.0\",\n    \"@capacitor/push-notifications\": \"^7.0.0\",\n    \"@capacitor/status-bar\": \"^7.0.0\",\n    \"@capacitor/toast\": \"^7.0.0\",\n    \"@ffmpeg/core\": \"^0.12.10\",\n    \"@ffmpeg/ffmpeg\": \"^0.12.15\",\n    \"@ffmpeg/util\": \"^0.12.2\",\n    \"@gun-vue/composables\": \"^0.24.2\",\n    \"@gun-vue/gun-es\": \"^0.3.1240\",\n    \"@iconify/tailwind\": \"latest\",\n    \"@ionic-native/background-mode\": \"^5.36.0\",\n    \"@ionic-native/core\": \"^5.36.0\",\n    \"@ionic-native/fingerprint-aio\": \"^5.36.0\",\n    \"@ionic-native/media\": \"^5.36.0\",\n    \"@ionic-native/qr-scanner\": \"^5.36.0\",\n    \"@ionic-native/secure-storage\": \"^5.36.0\",\n    \"@ionic-native/sqlite\": \"^5.36.0\",\n    \"@ionic/cli\": \"latest\",\n    \"@ionic/pwa-elements\": \"^3.2.2\",\n    \"@ionic/storage\": \"^4.0.0\",\n    \"@ionic/storage-angular\": \"^4.0.0\",\n    \"@ionic/vue\": \"^7.0.0\",\n    \"@ionic/vue-router\": \"^7.0.0\",\n    \"@joyid/capacitor-native-passkey\": \"^0.0.3\",\n    \"@peculiar/webcrypto\": \"^1.5.0\",\n    \"@rollup/plugin-inject\": \"^5.0.5\",\n    \"@scure/bip39\": \"^1.6.0\",\n    \"@simplewebauthn/browser\": \"^13.1.0\",\n    \"@tresjs/core\": \"latest\",\n    \"@tweenjs/tween.js\": \"latest\",\n    \"@types/gun\": \"^0.9.6\",\n    \"@types/text-encoding\": \"^0.0.40\",\n    \"@types/uuid\": \"^10.0.0\",\n    \"@types/webrtc\": \"^0.0.44\",\n    \"@vue/language-plugin-pug\": \"^2.2.2\",\n    \"@vueuse/core\": \"latest\",\n    \"@vueuse/gesture\": \"^2.0.0\",\n    \"add\": \"^2.0.6\",\n    \"animate.css\": \"latest\",\n    \"autopass\": \"^2.1.0\",\n    \"axios\": \"latest\",\n    \"b4a\": \"^1.6.7\",\n    \"better-scroll\": \"^2.5.1\",\n    \"btoa\": \"^1.2.1\",\n    \"buffer\": \"^6.0.3\",\n    \"capacitor-voice-recorder\": \"^7.0.5\",\n    \"cordova-plugin-background-mode\": \"^0.7.3\",\n    \"cordova-plugin-device\": \"^3.0.0\",\n    \"cordova-plugin-fingerprint-aio\": \"^6.0.0\",\n    \"cordova-plugin-secure-storage-echo\": \"^5.1.1\",\n    \"cordova-sqlite-storage\": \"^7.0.0\",\n    \"corestore\": \"^7.1.0\",\n    \"crypto-browserify\": \"^3.12.1\",\n    \"crypto-js\": \"^4.2.0\",\n    \"cryptojs\": \"^2.5.3\",\n    \"elliptic\": \"^6.6.1\",\n    \"ffmpeg\": \"^0.0.4\",\n    \"gsap\": \"^3.13.0\",\n    \"gun\": \"^0.2020.1240\",\n    \"gun-avatar\": \"^2.2.2\",\n    \"gun-flint\": \"^0.0.28\",\n    \"ionicons\": \"^7.4.0\",\n    \"jsqr\": \"latest\",\n    \"localforage-cordovasqlitedriver\": \"^1.8.0\",\n    \"lodash\": \"^4.17.21\",\n    \"native-run\": \"^2.0.1\",\n    \"node-forge\": \"^1.3.1\",\n    \"nvm\": \"latest\",\n    \"peerjs\": \"^1.5.4\",\n    \"photoswipe\": \"^5.4.4\",\n    \"pinia\": \"^3.0.1\",\n    \"pinyin-pro\": \"^3.26.0\",\n    \"postcss\": \"latest\",\n    \"postcss-loader\": \"latest\",\n    \"pug\": \"^3.0.3\",\n    \"qrcode.vue\": \"latest\",\n    \"qrcodejs2\": \"latest\",\n    \"sass\": \"latest\",\n    \"socket.io-client\": \"latest\",\n    \"stats.js\": \"latest\",\n    \"stream-browserify\": \"^3.0.0\",\n    \"swiper\": \"^11.2.6\",\n    \"tailwind\": \"latest\",\n    \"text-encoding\": \"^0.7.0\",\n    \"three\": \"latest\",\n    \"three-stdlib\": \"^2.35.16\",\n    \"tweakpane\": \"latest\",\n    \"uint8arrays\": \"latest\",\n    \"unplugin-auto-import\": \"^19.0.0\",\n    \"uuid\": \"^11.1.0\",\n    \"vite-plugin-pwa\": \"latest\",\n    \"vm-browserify\": \"^1.1.2\",\n    \"vue\": \"latest\",\n    \"vue-chartjs\": \"latest\",\n    \"vue-count-to\": \"^1.0.13\",\n    \"vue-i18n\": \"latest\",\n    \"vue-image-lightbox\": \"^7.2.0\",\n    \"vue-lazyload\": \"^3.0.0\",\n    \"vue-router\": \"^4.1.6\",\n    \"vue-virtual-scroller\": \"^2.0.0-beta.8\",\n    \"vue3-carousel\": \"^0.15.0\",\n    \"vue3-photo-preview\": \"^0.3.0\",\n    \"vue3-qrcode-reader\": \"latest\",\n    \"vue3-touch-events\": \"latest\",\n    \"webrtc-adapter\": \"^9.0.3\"\n  },\n  \"devDependencies\": {\n    \"@capacitor/cli\": \"^7.0.0\",\n    \"@iconify-json/tabler\": \"latest\",\n    \"@iconify/json\": \"latest\",\n    \"@tsconfig/node22\": \"latest\",\n    \"@types/jsdom\": \"latest\",\n    \"@types/node\": \"^22.10.7\",\n    \"@types/stats.js\": \"latest\",\n    \"@types/three\": \"latest\",\n    \"@unocss/preset-icons\": \"^65.4.2\",\n    \"@unocss/preset-uno\": \"^65.4.2\",\n    \"@vitejs/plugin-legacy\": \"^4.0.2\",\n    \"@vitejs/plugin-vue\": \"^4.0.0\",\n    \"@vitest/eslint-plugin\": \"latest\",\n    \"@vue/eslint-config-prettier\": \"latest\",\n    \"@vue/eslint-config-typescript\": \"^11.0.2\",\n    \"@vue/test-utils\": \"^2.3.0\",\n    \"@vue/tsconfig\": \"latest\",\n    \"copyfiles\": \"^2.4.1\",\n    \"cypress\": \"^13.1.0\",\n    \"eslint\": \"^8.35.0\",\n    \"eslint-plugin-oxlint\": \"latest\",\n    \"eslint-plugin-vue\": \"^9.9.0\",\n    \"jsdom\": \"^22.1.0\",\n    \"npm-run-all2\": \"latest\",\n    \"oxlint\": \"latest\",\n    \"prettier\": \"latest\",\n    \"process\": \"^0.11.10\",\n    \"rimraf\": \"^5.0.1\",\n    \"tailwindcss\": \"latest\",\n    \"terser\": \"^5.37.0\",\n    \"typescript\": \"^5.1.6\",\n    \"unocss\": \"^65.4.2\",\n    \"unplugin-vue-components\": \"latest\",\n    \"vite\": \"^latest\",\n    \"vite-plugin-node-polyfills\": \"^0.23.0\",\n    \"vite-plugin-pages\": \"latest\",\n    \"vite-plugin-vue-devtools\": \"latest\",\n    \"vitest\": \"latest\",\n    \"vue-tsc\": \"latest\"\n  },\n  \"description\": \"gun-sqlite-relay\",\n  \"main\": \"index.js\",\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}\n"
  },
  {
    "path": "examples/relay-sqlite-example/src/App.vue",
    "content": "<template>\n  <ion-app>\n\n\n\n\n    <ion-router-outlet  />\n\n\n \n  </ion-app>\n</template>\n\n<script setup lang=\"ts\">\nimport { onMounted, onUnmounted, ref } from 'vue';\nimport { IonApp, IonRouterOutlet } from '@ionic/vue';\n\n\n\nfunction setupNetworkListener() {\n  let debounceTimer: NodeJS.Timeout;\n  window.addEventListener('online', async () => {\n    clearTimeout(debounceTimer);\n    debounceTimer = setTimeout(async () => {\n    \n    \n  \n    }, 500); \n  });\n\n}\n\n\n\n\n\n\n// 保存原始 console.warn\n const originalConsoleWarn = console.warn;\n\n\nfunction filterGunWarnings(...args: any[]) {\n  const message = args[0]?.toString() || '';\n  if (message.includes('Deprecated internal utility will break in next version')) {\n    return; // 忽略 Gun.js 警告\n  }\n  originalConsoleWarn.apply(console, args); \n}\n\n\n\n\n\nonMounted(async () => {\n   console.warn = filterGunWarnings;\n   await setupNetworkListener(); \n\n});\n\nonUnmounted(() => {\n   window.removeEventListener('online', () => {});\n   window.removeEventListener('offline', () => {});\n});\n\n\n</script>\n\n<style scoped>\n\n\n/* 滚动条样式 */\n::-webkit-scrollbar {\n  width: 0px; /* 滚动条宽度 */\n  background-color: transparent; /* 透明背景 */\n}\n\n/* 滚动条滑块 */\n::-webkit-scrollbar-thumb {\n  background-color: transparent; /* 半透明的滑块颜色 */\n  border-radius: 4px; /* 圆角 */\n}\n\n/* 滚动条轨道 */\n::-webkit-scrollbar-track {\n  background-color: transparent; /* 透明轨道 */\n}\n\n\n.ion-page,\nion-content {\n  background: transparent !important;\n  --background: transparent !important;\n}\n\nhtml,\nbody,\n#app {\n  margin: 0;\n  padding: 0;\n  width: 100%;\n  height: 100%;\n  /* touch-action: none;\n  touch-action: pan-x pan-y;\n  user-select: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none; */\n  background-color: transparent;\n  overflow: hidden;\n}\n\n\nbody {\n  font-family:\n    Inter,\n    -apple-system,\n    BlinkMacSystemFont,\n    'Segoe UI',\n    Roboto,\n    Oxygen,\n    Ubuntu,\n    Cantarell,\n    'Fira Sans',\n    'Droid Sans',\n    'Helvetica Neue',\n    sans-serif;\n  text-rendering: optimizeLegibility;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n</style>"
  },
  {
    "path": "examples/relay-sqlite-example/src/components/RelayMode.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, computed, onMounted, watch } from 'vue';\nimport { useNetworkStatus } from '@/composables/useNetworkStatus';\nimport { \n  IonIcon, \n  IonToggle, \n  IonModal,\n  IonHeader,\n  IonToolbar,\n  IonTitle,\n  IonContent,\n  IonItem,\n  IonLabel,\n  IonInput,\n  IonButton,\n  IonButtons\n} from '@ionic/vue';\nimport { addCircleSharp, closeCircleSharp, searchSharp, closeSharp, refreshOutline } from 'ionicons/icons';\nimport StorageService from '@/services/storageService';\nimport { getCurrentInstance } from 'vue';\n\n\nconst appInstance = getCurrentInstance();\nconst storageServ = appInstance?.appContext.config.globalProperties.$storageServ as StorageService;\n\n\nconst {\n  networkStatus,\n  peersStatus,\n  currentMode,\n  peerStatuses,\n  peersList,\n  enabledPeer,\n  addPeer,\n  removePeer,\n  enablePeer,\n  disablePeer,\n  peersNotes,\n  savePeerNote,\n} = useNetworkStatus(storageServ);\n\n\nconst newPeerUrl = ref('');\nconst searchQuery = ref('');\nconst selectedPeer = ref<string | null>(null);\nconst isModalOpen = ref(false);\nconst notes = ref<Record<string, string>>({});\nconst isResetting = ref(false); \n\nonMounted(async () => {\n  try {\n    const savedNotes = localStorage.getItem('relayNotes');\n    if (savedNotes) {\n      const notes = JSON.parse(savedNotes);\n      for (const [peer, note] of Object.entries(notes)) {\n        await savePeerNote(peer as string, note as string);\n      }\n      localStorage.removeItem('relayNotes'); // 迁移后删除\n      console.log('Migrated relay notes to SQLite');\n    }\n  } catch (e) {\n    console.error('Failed to migrate relay notes:', e);\n  }\n});\n\n\nwatch(peersNotes, async (newNotes) => {\n  for (const [peer, note] of Object.entries(newNotes)) {\n    await savePeerNote(peer, note);\n  }\n}, { deep: true });\n\n\nconst sortedPeers = computed(() => {\n  return peersList.value\n    .slice()\n    .sort((a, b) => {\n      if (a === enabledPeer.value) return -1;\n      if (b === enabledPeer.value) return 1;\n      return 0;\n    })\n    .filter((peer) => {\n      const searchLower = searchQuery.value.toLowerCase();\n      const peerLower = peer.toLowerCase();\n      const noteLower = (peersNotes.value[peer] || '').toLowerCase();\n      return peerLower.includes(searchLower) || noteLower.includes(searchLower);\n    });\n});\n\nconst openModal = (peer: string) => {\n  selectedPeer.value = peer;\n  isModalOpen.value = true;\n};\n\nconst closeModal = () => {\n  isModalOpen.value = false;\n  selectedPeer.value = null;\n};\n\n</script>\n\n<template>\n  <div class=\"liquid-container\" >\n    <div class=\"status-bar\" :class=\"['indicator', networkStatus]\">\n   \n        <div >\n      \n        </div>\n  \n      \n    </div>\n\n    <div class=\"add-peer\">\n      <input \n        v-model=\"newPeerUrl\" \n        placeholder=\"Enter relay URL\" \n        @keyup.enter=\"addPeer(newPeerUrl)\"\n      />\n      <ion-icon\n        :icon=\"addCircleSharp\"\n        class=\"addlink\"\n        @click=\"addPeer(newPeerUrl);newPeerUrl = ''\"\n      />\n    </div>\n\n    <div class=\"peer-list\">\n      <div class=\"peer-list-header\">\n        <h3>Gun Relays</h3>\n        <div class=\"search-container\">\n          <ion-icon :icon=\"searchSharp\" class=\"search-icon\" />\n          <input \n            v-model=\"searchQuery\" \n            placeholder=\"Search relays...\" \n            class=\"search-input\"\n          />\n        </div>\n      </div>\n      <div class=\"peer-scroll-container\">\n        <div \n          v-for=\"peer in sortedPeers\" \n          :key=\"peer\" \n          class=\"peer-item\"\n          @click=\"openModal(peer)\"\n        >\n          <div class=\"peer-header\">\n            <div :class=\"['status', peerStatuses[peer]]\">\n              {{ peerStatuses[peer] || 'Checking' }}\n            </div>\n          </div>\n          <div class=\"peer-content\">\n            <span class=\"peer-url\">{{ notes[peer] || peer }}</span>\n          </div>\n          <div class=\"peer-actions\">\n            <ion-toggle\n            @click.stop\n              :checked=\"enabledPeer === peer\"\n              @ionChange=\"enabledPeer === peer ? disablePeer() : enablePeer(peer)\"\n              color=\"primary\"\n            />\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <ion-modal :is-open=\"isModalOpen\" @didDismiss=\"closeModal\">\n  \n      <ion-content class=\"ion-padding\">\n        <ion-item lines=\"none\" v-if=\"selectedPeer\">\n          <ion-label position=\"stacked\">Relay URL</ion-label>\n          <ion-input :value=\"selectedPeer\" readonly class=\"readonly-input\" />\n        </ion-item>\n        <ion-item lines=\"none\" v-if=\"selectedPeer\">\n          <ion-label position=\"stacked\">Status</ion-label>\n          <div :class=\"['status', peerStatuses[selectedPeer]]\" class=\"status-display\">\n            {{ peerStatuses[selectedPeer] || 'Checking' }}\n          </div>\n        </ion-item>\n        <ion-item lines=\"none\" v-if=\"selectedPeer\">\n          <ion-label position=\"stacked\">Note</ion-label>\n          <ion-input \n            v-model=\"notes[selectedPeer]\" \n            placeholder=\"\" \n            clear-input\n            style=\" --padding-start: 12px;\n  --padding-end: 12px;\"\n          />\n        </ion-item>\n        <div class=\"modal-actions\">\n          <ion-button \n            expand=\"block\" \n            color=\"danger\" \n            @click=\"removePeer(selectedPeer!); closeModal()\"\n          >\n            Remove Relay\n          </ion-button>\n          <ion-button \n            expand=\"block\" \n            color=\"medium\" \n            @click=\"closeModal\"\n          >\n            Close\n          </ion-button>\n        </div>\n      </ion-content>\n    </ion-modal>\n  </div>\n</template>\n\n<style scoped>\n.liquid-container {\n  padding: 16px 20px;\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', sans-serif;\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n  background: transparent;\n  /* background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(0, 0, 0, 0.05)); */\n}\n\n.status-bar {\n  display: flex;\n  gap: 12px;\n  margin-bottom: 16px;\n  padding: 6px 8px;\n  background: rgba(130, 130, 130, 0.15);\n  border-radius: 12px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n  flex-wrap: wrap;\n  align-items: center;\n}\n\n.status-item {\n  display: flex;\n  align-items: center;\n  padding: 4px 8px;\n  transition: transform 0.2s ease;\n}\n\n.status-item:hover {\n  transform: translateY(-1px);\n}\n\n\n.reset-button-container {\n  margin-left: auto;\n}\n\n.reset-button {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  background: linear-gradient(135deg, rgba(102, 204, 255, 0.2), rgba(102, 204, 255, 0.4));\n  border: none;\n  border-radius: 8px;\n  padding: 6px 12px;\n  cursor: pointer;\n  transition: all 0.2s ease;\n  gap: 6px;\n  color: inherit;\n  font-weight: 500;\n  font-size: 13px;\n}\n\n.reset-button:hover {\n  background: linear-gradient(135deg, rgba(102, 204, 255, 0.3), rgba(102, 204, 255, 0.5));\n  transform: translateY(-1px);\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.reset-button:active {\n  transform: translateY(1px);\n  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);\n}\n\n.reset-button:disabled {\n  opacity: 0.6;\n  cursor: not-allowed;\n}\n\n.reset-icon {\n  font-size: 16px;\n}\n\n.rotating {\n  animation: spin 1.5s linear infinite;\n}\n\n@keyframes spin {\n  from { transform: rotate(0deg); }\n  to { transform: rotate(360deg); }\n}\n\n.label {\n  font-weight: 600;\n  font-size: 13px;\n  margin-right: 6px;\n  /* color: #333; */\n  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n}\n\n.indicator {\n  width: 100%;\n  /* padding: 4px 8px; */\n  border-radius: 8px;\n  font-size: 12px;\n  font-weight: 500;\n  backdrop-filter: blur(4px);\n  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.indicator.online,\n.indicator.connected,\n.indicator.relay {\n  background: linear-gradient(135deg, #88ff88, #55ccaa);\n  color: #2a2a2a;\n}\n\n.indicator.offline,\n.indicator.disconnected,\n.indicator.direct {\n  background: linear-gradient(135deg, #ff7777, #cc5555);\n  color: #fff;\n}\n\n.add-peer {\n  display: flex;\n  gap: 12px;\n  margin-bottom: 20px;\n}\n\n.add-peer input {\n  flex: 1;\n  padding: 10px 12px;\n  border: none;\n  border-radius: 12px;\n  background: rgba(150, 150, 150, 0.2);\n  font-size: 14px;\n  /* color: #333; */\n  transition: all 0.2s ease;\n}\n\n.add-peer input:hover,\n.add-peer input:focus {\n  background: rgba(150, 150, 150, 0.25);\n  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);\n  transform: translateY(-1px);\n  outline: none;\n}\n\n.addlink {\n  width: 36px;\n  height: 36px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  /* color: #66ccff; */\n  cursor: pointer;\n  transition: all 0.2s ease;\n}\n\n.addlink:hover {\n  /* color: #88ddff; */\n  transform: scale(1.1);\n}\n\n.peer-list {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n}\n\n.peer-list-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 16px;\n}\n\n.peer-list h3 {\n  font-size: 18px;\n  font-weight: 600;\n  margin: 0;\n  /* color: #333; */\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.search-container {\n  position: relative;\n  width: 220px;\n}\n\n.search-icon {\n  position: absolute;\n  left: 12px;\n  top: 50%;\n  transform: translateY(-50%);\n  color: #777;\n  font-size: 16px;\n}\n\n.search-input {\n  width: 100%;\n  padding: 8px 12px 8px 36px;\n  border: none;\n  border-radius: 12px;\n  background: rgba(150, 150, 150, 0.2);\n  font-size: 14px;\n  \n  transition: all 0.2s ease;\n}\n\n.search-input:hover,\n.search-input:focus {\n  background: rgba(150, 150, 150, 0.25);\n  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);\n  transform: translateY(-1px);\n  outline: none;\n}\n\n.peer-scroll-container {\n  border-radius: 12px;\n  max-height: 539px;\n  overflow-y: auto;\n  flex: 1;\n}\n\n.peer-scroll-container::-webkit-scrollbar {\n  width: 6px;\n}\n\n.peer-scroll-container::-webkit-scrollbar-track {\n  background: rgba(150, 150, 150, 0.2);\n  border-radius: 6px;\n}\n\n.peer-scroll-container::-webkit-scrollbar-thumb {\n  background: linear-gradient(180deg, #66ccff, #88ddff);\n  border-radius: 6px;\n}\n\n.peer-scroll-container::-webkit-scrollbar-thumb:hover {\n  background: linear-gradient(180deg, #55bbff, #77ccff);\n}\n\n.peer-item {\n  padding: 12px;\n  background: linear-gradient(135deg, rgba(150, 150, 150, 0.15), rgba(255, 255, 255, 0.05));\n  border-radius: 12px;\n  margin-bottom: 12px;\n  transition: all 0.2s ease;\n  cursor: pointer;\n}\n\n.peer-item:hover {\n  transform: translateY(-2px);\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n\n.peer-header {\n  display: flex;\n  align-items: center;\n  margin-bottom: 8px;\n}\n\n.status {\n  padding: 4px 10px;\n  border-radius: 8px;\n  font-size: 12px;\n  font-weight: 500;\n  text-align: center;\n  backdrop-filter: blur(4px);\n  text-transform: capitalize;\n}\n\n.status.connected {\n  background: linear-gradient(135deg, #88ff88, #55ccaa);\n  color: #2a2a2a;\n}\n\n.status.disconnected {\n  background: linear-gradient(135deg, #ff7777, #cc5555);\n  color: #fff;\n}\n\n.status.checking {\n  background: linear-gradient(135deg, #ffcc66, #ffaa33);\n  color: #333;\n}\n\n.peer-content {\n  margin-bottom: 10px;\n}\n\n.peer-url {\n  display: block;\n  word-break: break-all;\n  font-size: 13px;\n  line-height: 1.5;\n  padding: 6px 10px;\n  background: rgba(150, 150, 150, 0.1);\n  border-radius: 8px;\n  /* color: #444; */\n}\n\n.peer-actions {\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  gap: 12px;\n}\n\nion-toggle {\n  /* --background: rgba(150, 150, 150, 0.2);\n  --background-checked: linear-gradient(135deg, #66ccff, #88ddff);\n  --handle-background: #fff;\n  --handle-background-checked: #fff; */\n  width: 48px;\n  height: 24px;\n  /* --handle-width: 20px;\n  --handle-height: 20px; */\n}\n\n/* Modal Styles */\nion-modal {\n  --border-radius: 12px;\n  --max-width: 400px;\n  --max-height: 46%;\n\n  --backdrop-opacity: 0.4;\n}\n\n/* ion-header {\n  --background: rgba(150, 150, 150, 0.1);\n} */\n\nion-toolbar {\n  --background: transparent;\n  --border-width: 0;\n\n}\n\nion-title {\n  font-size: 18px;\n  font-weight: 600;\n  color: #333;\n  padding: 0 12px;\n}\n\nion-buttons {\n  margin-right: 8px;\n}\n\nion-button {\n  --background-activated: transparent;\n}\n\nion-button ion-icon {\n  font-size: 24px;\n  color: #666;\n}\n\nion-button:hover ion-icon {\n  color: #333;\n}\n\n.ion-padding {\n  padding: 16px;\n}\n\nion-item {\n  --background: transparent;\n  --padding-start: 0;\n  --inner-padding-end: 0;\n  /* margin-bottom: 16px; */\n}\n\nion-label {\n  /* color: #333 !important; */\n  font-weight: 500;\n  margin-bottom: 4px;\n}\n\nion-input {\n  --background: rgba(150, 150, 150, 0.15);\n  --padding-start: 12px;\n  --padding-end: 12px;\n  --padding-top: 8px;\n  --padding-bottom: 8px;\n  border-radius: 8px;\n  font-size: 14px;\n\n}\n\n.readonly-input {\n  --padding-start: 12px;\n  --padding-end: 12px;\n\n  --color: #666;\n  --background: rgba(150, 150, 150, 0.1);\n \n}\n\n.status-display {\n  width: 100%;\n  padding: 8px 12px;\n  border-radius: 8px;\n  font-size: 14px;\n  text-align: center;\n}\n\n.modal-actions {\n  display: flex;\n  gap: 12px;\n  margin-top: 20px;\n}\n\n.modal-actions ion-button {\n  --border-radius: 8px;\n  --padding-start: 16px;\n  --padding-end: 16px;\n  flex: 1;\n}\n\n.modal-actions ion-button[color=\"danger\"] {\n  --background: #ff6666;\n  --background-hover: #ff8888;\n  --background-activated: #ff5555;\n}\n\n.modal-actions ion-button[color=\"medium\"] {\n  --background: #ccc;\n  --background-hover: #ddd;\n  --background-activated: #bbb;\n}\n</style>"
  },
  {
    "path": "examples/relay-sqlite-example/src/composables/GunStorageAdapter.ts",
    "content": "import { ref, Ref } from 'vue';\nimport { Flint, NodeAdapter } from 'gun-flint';\nimport StorageService from '../services/storageService';\nimport { ISQLiteService } from '../services/sqliteService';\nimport { IDbVersionService } from '../services/dbVersionService';\n\n// 日志工具\n// const log = {\n//   debug: (msg: string, ...args: any[]) => console.debug(`[Gun-SQLite-Adapter] ${msg}`, ...args),\n//   info: (msg: string, ...args: any[]) => console.info(`[Gun-SQLite-Adapter] ${msg}`, ...args),\n//   warn: (msg: string, ...args: any[]) => console.warn(`[Gun-SQLite-Adapter] ${msg}`, ...args),\n//   error: (msg: string, ...args: any[]) => console.error(`[Gun-SQLite-Adapter] ${msg}`, ...args),\n// };\n\n// 请求队列管理，防止重复查询\nclass RequestQueue {\n  private queue: Map<string, { resolve: (data: any) => void; reject: (err: any) => void }[]> = new Map();\n  private debounceTimers: Map<string, NodeJS.Timeout> = new Map();\n  private storageServ: StorageService;\n\n  constructor(storageServ: StorageService) {\n    this.storageServ = storageServ;\n  }\n\n  async get(key: string): Promise<any> {\n    return new Promise((resolve, reject) => {\n      const handlers = this.queue.get(key) || [];\n      handlers.push({ resolve, reject });\n      this.queue.set(key, handlers);\n\n      if (!this.debounceTimers.has(key)) {\n        const timer = setTimeout(async () => {\n          const handlers = this.queue.get(key) || [];\n          this.queue.delete(key);\n          this.debounceTimers.delete(key);\n\n          try {\n            if (!this.storageServ.db) throw new Error('Database connection not available');\n            const result = await this.storageServ.query('SELECT value FROM gun_nodes WHERE key = ?', [key]);\n            const data = result.values && result.values.length > 0 ? JSON.parse(result.values[0].value) : null;\n            handlers.forEach(h => h.resolve(data));\n          } catch (err) {\n            //log.error(`Failed to get key=${key}:`, err);\n            handlers.forEach(h => h.reject(err));\n          }\n        }, 50);\n        this.debounceTimers.set(key, timer);\n      }\n    });\n  }\n\n  async put(soul: string, node: any): Promise<void> {\n    await this.storageServ.run(\n      'INSERT OR REPLACE INTO gun_nodes (key, value, timestamp) VALUES (?, ?, ?)',\n      [soul, JSON.stringify(node), Date.now()]\n    );\n  }\n\n  async batchPut(nodes: Record<string, any>): Promise<void> {\n    const updates: [string, string, number][] = [];\n    for (const soul in nodes) {\n      updates.push([soul, JSON.stringify(nodes[soul]), Date.now()]);\n    }\n    await this.storageServ.run(\n      'INSERT OR REPLACE INTO gun_nodes (key, value, timestamp) VALUES ' + updates.map(() => '(?, ?, ?)').join(','),\n      updates.flat()\n    );\n  }\n}\n\n// 定义适配器接口\ninterface GunAdapter {\n  opt?: (context: any, options: any) => void;\n  get: (key: string, done: (err: Error | null, node: any) => void) => void;\n  put: (node: any, done: (err: Error | null) => void) => void;\n}\n\nexport interface IGunSQLiteAdapter {\n  initialize(): Promise<void>;\n  getAdapter(): GunAdapter;\n  isReady: Ref<boolean>;\n}\n\n// 单例实例\nlet instance: IGunSQLiteAdapter | null = null;\n\nexport function useGunSQLiteAdapter(\n  sqliteService: ISQLiteService,\n  dbVersionService: IDbVersionService,\n  storageService: StorageService\n): IGunSQLiteAdapter {\n  if (instance) return instance;\n\n  const isReady: Ref<boolean> = ref(false);\n  const storageServ = storageService;\n  let queue: RequestQueue | null = null;\n\n  async function initialize() {\n    if (isReady.value) return;\n    try {\n      //log.info('Initializing Gun SQLite adapter...');\n      // 检查 StorageService 是否已初始化数据库\n      if (!storageServ.db) {\n        //log.warn('StorageService database not initialized, initializing now...');\n        const dbName = 'talkflowdb';\n        const loadToVersion = storageServ.loadToVersion || 2;\n        storageServ.db = await sqliteService.openDatabase(dbName, loadToVersion, false);\n      } else {\n        const isOpen = await storageServ.db.isDBOpen();\n        if (!isOpen) {\n          //log.warn('Database not open, reopening...');\n          await storageServ.db.open();\n        }\n      }\n\n      // 创建 gun_nodes 表\n      const result = await storageServ.execute(`\n        CREATE TABLE IF NOT EXISTS gun_nodes (\n          key TEXT PRIMARY KEY NOT NULL,\n          value TEXT NOT NULL,\n          timestamp INTEGER DEFAULT (strftime('%s', 'now'))\n        )\n      `);\n      if (result.changes && result.changes.changes >= 0) {\n        //log.info('gun_nodes table created or already exists');\n      } else {\n        throw new Error('Failed to create gun_nodes table: no changes returned');\n      }\n\n      queue = new RequestQueue(storageServ);\n      isReady.value = true;\n      //log.info('Gun SQLite adapter initialized successfully');\n    } catch (err) {\n      //log.error('Failed to initialize Gun SQLite adapter:', err);\n      throw err;\n    }\n  }\n\n  const adapterCore = {\n    storageServ,\n    queue,\n    opt: async function (context: any, options: any) {\n     // log.info('Adapter opt called:', { context, options });\n      await initialize();\n      return options;\n    },\n    get: async function (key: string, done: (err: Error | null, node: any) => void) {\n      try {\n        if (!isReady.value) await initialize();\n        if (!queue) throw new Error('Adapter not initialized');\n        const data = await queue.get(key);\n        done(null, data);\n      } catch (err) {\n        //log.error(`Get error for key=${key}:`, err);\n        done(err instanceof Error ? err : new Error('Unknown error'), null);\n      }\n    },\n    put: async function (node: any, done: (err: Error | null) => void) {\n      try {\n        if (!isReady.value) await initialize();\n        if (!queue) throw new Error('Adapter not initialized');\n        if (typeof node !== 'object' || node === null) throw new Error('Invalid node');\n        const souls = Object.keys(node).length > 1 ? Object.keys(node) : [node._?.['#'] || node._.id];\n        if (!souls[0]) throw new Error('Missing soul in node');\n        if (souls.length > 1) {\n          await queue.batchPut(node);\n        } else {\n          await queue.put(souls[0], node[souls[0]] || node);\n        }\n        done(null);\n      } catch (err) {\n        //log.error('Put error:', err);\n        done(err instanceof Error ? err : new Error('Unknown error'));\n      }\n    },\n  };\n\n  const adapter = new NodeAdapter(adapterCore);\n  Flint.register(adapter);\n\n  const gunSQLiteAdapter: IGunSQLiteAdapter = {\n    initialize,\n    getAdapter: () => adapter,\n    isReady,\n  };\n\n  instance = gunSQLiteAdapter;\n  return gunSQLiteAdapter;\n}\n\nexport function getGunSQLiteAdapter(\n  sqliteService: ISQLiteService,\n  dbVersionService: IDbVersionService,\n  storageService: StorageService\n): IGunSQLiteAdapter {\n  if (!instance) {\n    instance = useGunSQLiteAdapter(sqliteService, dbVersionService, storageService);\n  }\n  return instance;\n}\n\nexport default getGunSQLiteAdapter;"
  },
  {
    "path": "examples/relay-sqlite-example/src/composables/useNetwork.ts",
    "content": "\nimport { ref } from 'vue';\nimport Gun, { IGunInstance } from 'gun';\n\n// 模块级别的单例状态\nconst isOnline = ref(navigator.onLine);\nconst peersConnected = ref(false);\nconst checkInterval = 60000; // 每 60 秒检查一次\n\n// 单例初始化标志和变量\nlet initialized = false;\nlet intervalId: number | null = null;\nlet currentGunInstance: IGunInstance<any> | null = null;\nlet instance: ReturnType<typeof createNetwork> | null = null;\n\nfunction createNetwork(gunInstance: IGunInstance<any>) {\n  // 检查 Gun.js 对等节点，反复尝试直到成功\n  async function checkPeers(): Promise<boolean> {\n    const maxAttempts = 3; \n    let attempt = 0;\n    const retryDelay = 1000; // 每次尝试间隔 1 秒\n\n    while (attempt < maxAttempts) {\n      attempt++;\n      const result = await new Promise<boolean>((resolve) => {\n        let alive = false;\n        const off = gunInstance.get('~public').once((data) => {\n          alive = true;\n          off.off();\n          resolve(true);\n        });\n        setTimeout(() => {\n          if (!alive) {\n            resolve(false);\n          }\n        }, 5000); // 10 秒超时\n      });\n\n      if (result) {\n        peersConnected.value = true;\n        return true;\n      } else {\n        await new Promise(resolve => setTimeout(resolve, retryDelay));\n      }\n    }\n    return false; // 理论上不会到达这里，因为 maxAttempts 是 Infinity\n  }\n\n  async function updateNetworkStatus() {\n    isOnline.value = navigator.onLine;\n    peersConnected.value = await checkPeers();\n  }\n\n  function handleOnline() {\n    updateNetworkStatus();\n  }\n\n  function handleOffline() {\n    isOnline.value = false;\n    peersConnected.value = false;\n  }\n\n  function startChecking() {\n    updateNetworkStatus();\n    intervalId = window.setInterval(updateNetworkStatus, checkInterval);\n  }\n\n  function stopChecking() {\n    if (intervalId !== null) {\n      clearInterval(intervalId);\n      intervalId = null;\n    }\n  }\n\n  // 单例初始化逻辑\n  if (!initialized || currentGunInstance !== gunInstance) {\n    if (initialized && currentGunInstance !== gunInstance) {\n      // 如果 Gun 实例变了，清理旧的事件监听器和定时器\n      stopChecking();\n      window.removeEventListener('online', handleOnline);\n      window.removeEventListener('offline', handleOffline);\n    }\n\n    initialized = true;\n    currentGunInstance = gunInstance;\n\n    window.addEventListener('online', handleOnline);\n    window.addEventListener('offline', handleOffline);\n    startChecking();\n  }\n\n  return {\n    isOnline,\n    peersConnected,\n    updateNetworkStatus,\n    checkPeers,\n  };\n}\n\n// 导出单例\nexport function useNetwork(gunInstance: IGunInstance<any>) {\n  if (!instance || currentGunInstance !== gunInstance) {\n    instance = createNetwork(gunInstance);\n  }\n  return instance;\n}\n\n// 清理函数（可选，用于测试或应用卸载时）\nexport function cleanupNetwork() {\n  if (instance) {\n    window.removeEventListener('online', instance.updateNetworkStatus);\n    window.removeEventListener('offline', instance.updateNetworkStatus);\n    if (intervalId !== null) {\n      clearInterval(intervalId);\n      intervalId = null;\n    }\n    instance = null;\n    initialized = false;\n    currentGunInstance = null;\n  }\n}"
  },
  {
    "path": "examples/relay-sqlite-example/src/composables/useNetworkStatus.ts",
    "content": "import { ref, watch } from 'vue';\nimport { useToast } from '@/composables/useToast';\nimport { useNetwork } from '@/composables/useNetwork';\nimport StorageService from '@/services/storageService';\nimport Gun from 'gun';\nimport 'gun/sea';\n\n\n\n\n\n\n// 模块级别的单例状态\nconst networkStatus = ref<'online' | 'offline'>('online');\nconst peersStatus = ref<'connected' | 'disconnected'>('disconnected');\nconst currentMode = ref<'direct' | 'relay'>('direct');\nconst peerStatuses = ref<Record<string, 'connected' | 'disconnected'>>({});\n\n// 单例初始化标志\nlet initialized = false;\nlet instance: ReturnType<typeof createNetworkStatus> | null = null;\n\nfunction createNetworkStatus(storageService: StorageService) {\n \n  const { showToast } = useToast();\n  const { isOnline, peersConnected, updateNetworkStatus, checkPeers } = useNetwork(gun);\n  const peersNotes = ref<Record<string, string>>({});\n\n  const peersList = ref<string[]>([\n    'https://peer.wallie.io/gun',\n    'https://gun.defucc.me/gun',\n    'https://talkflow.team/gun',\n    'https://gun-manhattan.herokuapp.com/gun',\n    'https://gundb-relay-mlccl.ondigitalocean.app/gun',\n  \n   \n  ]);\n\n  const enabledPeer = ref<string>(peersList.value[0]);\n\nlet gun = Gun({\n \n  peers: [ enabledPeer.value],\n  radisk: true,\n  localStorage: false,\n  gunSQLiteAdapter: {\n    key: 'gundb',\n  },\n});\n\n\n  // 确保 storageService 已初始化\n  async function ensureStorageReady() {\n    try {\n      if (!storageService.db || !(await storageService.db.isDBOpen())) {\n        console.log('[useNetworkStatus] Initializing StorageService database...');\n        await storageService.initializeDatabase();\n        if (!storageService.db) {\n          throw new Error('StorageService 初始化后仍无数据库连接');\n        }\n        console.log('[useNetworkStatus] StorageService database initialized');\n      }\n    } catch (err) {\n      console.error('[useNetworkStatus] Failed to initialize StorageService:', err);\n      showToast('数据库初始化失败，请重试', 'error');\n      throw err;\n    }\n  }\n\n  // 保存 enabledPeer 到 SQLite\n  async function saveEnabledPeer() {\n    try {\n      await ensureStorageReady();\n      await storageService.run('UPDATE network_peers SET is_enabled = 0');\n      if (enabledPeer.value) {\n        await storageService.run(\n          'INSERT OR REPLACE INTO network_peers (url, is_enabled, note) VALUES (?, ?, ?)',\n          [enabledPeer.value, 1, peersNotes.value[enabledPeer.value] || '']\n        );\n      }\n      console.log(`Enabled peer saved: ${enabledPeer.value}`);\n    } catch (err) {\n      console.error('[useNetworkStatus] Failed to save enabled peer:', err);\n      showToast('无法保存启用节点', 'error');\n    }\n  }\n\n  // 保存节点备注\n  async function savePeerNote(peer: string, note: string) {\n    try {\n      await ensureStorageReady();\n      await storageService.run(\n        'UPDATE network_peers SET note = ? WHERE url = ?',\n        [note, peer]\n      );\n      peersNotes.value[peer] = note;\n      console.log(`Peer note saved: ${peer} -> ${note}`);\n    } catch (err) {\n      console.error('[useNetworkStatus] Failed to save peer note:', err);\n      showToast('无法保存节点备注', 'error');\n    }\n  }\n\n  // 从 SQLite 加载 Peer 配置和备注\n  // async function loadPeers() {\n  //   try {\n  //     await ensureStorageReady();\n  //     const result = await storageService.query('SELECT url, is_enabled, note FROM network_peers');\n  //     const peers = result.values || [];\n  //     peersList.value = peers.map((peer: { url: string }) => peer.url);\n  //     peersNotes.value = peers.reduce((acc: Record<string, string>, peer: { url: string; note: string }) => {\n  //       acc[peer.url] = peer.note || '';\n  //       return acc;\n  //     }, {});\n  //     const enabled = peers.find((peer: { is_enabled: number }) => peer.is_enabled === 1);\n  //     if (enabled && peersList.value.includes(enabled.url)) {\n  //       enabledPeer.value = enabled.url;\n  //     } else if (peersList.value.length > 0) {\n  //       enabledPeer.value = peersList.value[0];\n  //       await saveEnabledPeer();\n  //     }\n  //     gun.opt({ peers: peersList.value });\n  //   } catch (err) {\n  //     console.error('[useNetworkStatus] Failed to load peers:', err);\n  //     showToast('无法加载节点列表', 'error');\n  //   }\n  // }\n  async function loadPeers() {\n    try {\n        await ensureStorageReady();\n        const result = await storageService.query('SELECT url, is_enabled, note FROM network_peers');\n        const peers = result.values || [];\n\n        if (peers.length === 0) {\n            // 如果 SQLite 表为空，插入 TalkFlowCore 的预设节点\n            console.log('[useNetworkStatus] network_peers 表为空，插入预设节点');\n            const { peersList: defaultPeersList } = getTalkFlowCore(); // 获取预设节点\n            for (const peerUrl of defaultPeersList.value) {\n                await storageService.run(\n                    'INSERT OR IGNORE INTO network_peers (url, is_enabled, note) VALUES (?, ?, ?)',\n                    [peerUrl, 0, '']\n                );\n            }\n            // 重新查询以确保数据已插入\n            const newResult = await storageService.query('SELECT url, is_enabled, note FROM network_peers');\n            peersList.value = newResult.values.map((peer: { url: string }) => peer.url);\n        } else {\n            // 使用 SQLite 中的节点\n            peersList.value = peers.map((peer: { url: string }) => peer.url);\n        }\n\n        // 加载备注\n        peersNotes.value = peers.reduce((acc: Record<string, string>, peer: { url: string; note: string }) => {\n            acc[peer.url] = peer.note || '';\n            return acc;\n        }, {});\n\n        // 设置 enabledPeer\n        const enabled = peers.find((peer: { is_enabled: number }) => peer.is_enabled === 1);\n        if (enabled && peersList.value.includes(enabled.url)) {\n            enabledPeer.value = enabled.url;\n        } else if (peersList.value.length > 0) {\n            enabledPeer.value = peersList.value[0];\n            await saveEnabledPeer();\n        }\n\n        // 更新 Gun 配置\n        gun.opt({ peers: peersList.value });\n        console.log('[useNetworkStatus] Gun 配置节点:', peersList.value);\n    } catch (err) {\n        console.error('[useNetworkStatus] 加载节点失败:', err);\n        showToast('无法加载节点列表', 'error');\n    }\n}\n  // 更新网络和 Peer 状态\n  async function updateStatus() {\n    networkStatus.value = isOnline.value ? 'online' : 'offline';\n    peersStatus.value = peersConnected.value ? 'connected' : 'disconnected';\n    currentMode.value = peersConnected.value && enabledPeer.value ? 'relay' : 'direct';\n    await updatePeerStatuses();\n  }\n\n  // 检查单个 Peer 的状态（用于 UI 展示）\n  async function checkPeerStatus(peer: string): Promise<'connected' | 'disconnected'> {\n    return new Promise((resolve) => {\n      const tempGun = Gun({ peers: [peer] });\n      let connected = false;\n      tempGun.on('hi', () => {\n        connected = true;\n        resolve('connected');\n      });\n      setTimeout(() => {\n        if (!connected) resolve('disconnected');\n      }, 5000);\n    });\n  }\n\n  // 更新所有 Peer 的状态（用于 UI 展示）\n  async function updatePeerStatuses() {\n    for (const peer of peersList.value) {\n      const status = await checkPeerStatus(peer);\n      peerStatuses.value[peer] = status;\n    }\n  }\n\n  // 用户手动启用某个 Peer\n  async function enablePeer(peer: string) {\n    if (!peersList.value.includes(peer)) {\n      showToast(`节点 ${peer} 不在列表中`, 'warning');\n      return;\n    }\n    if (enabledPeer.value === peer) {\n      showToast(`${peer} 已是启用状态`, 'info');\n      return;\n    }\n\n    enabledPeer.value = peer;\n    await saveEnabledPeer();\n    gun.opt({ peers: peersList.value, priorityPeer: peer });\n    showToast(`启用节点: ${peer}`, 'success');\n\n    const connected = await checkPeers();\n    if (!connected) {\n      showToast(`无法连接到 ${peer}，将回退到其他节点`, 'warning');\n    }\n    await updateStatus();\n  }\n\n  // 用户禁用当前启用的 Peer\n  async function disablePeer() {\n    if (!enabledPeer.value) {\n      showToast('无启用的节点', 'info');\n      return;\n    }\n    const oldPeer = enabledPeer.value;\n    enabledPeer.value = peersList.value.length > 1 ? peersList.value.find(p => p !== oldPeer) || '' : '';\n    await saveEnabledPeer();\n    gun.opt({ peers: peersList.value });\n    showToast(`禁用节点: ${oldPeer}`, 'success');\n    await updateStatus();\n  }\n\n  // 添加 Peer（允许任意输入）\n  async function addPeer(url: string) {\n    if (!url) {\n        showToast('请输入节点地址', 'warning');\n        return;\n    }\n    const trimmedUrl = url.trim();\n    if (peersList.value.includes(trimmedUrl)) {\n        showToast('该节点已存在', 'warning');\n        return;\n    }\n    try {\n        await ensureStorageReady();\n        console.log('[useNetworkStatus] 添加节点:', trimmedUrl);\n        await storageService.run(\n            'INSERT INTO network_peers (url, is_enabled, note) VALUES (?, ?, ?)',\n            [trimmedUrl, 0, '']\n        );\n\n        // 重新查询 network_peers 表，确保数据一致\n        const result = await storageService.query('SELECT url FROM network_peers');\n        peersList.value = result.values.map((peer: { url: string }) => peer.url);\n        console.log('[useNetworkStatus] 更新 peersList:', peersList.value);\n\n        gun.opt({ peers: peersList.value });\n        showToast(`节点已添加: ${trimmedUrl}`, 'success');\n        await updatePeerStatuses();\n    } catch (err: any) {\n        console.error('[useNetworkStatus] Failed to add peer:', err);\n        showToast(`添加节点失败: ${err.message || '未知错误'}`, 'error');\n    }\n}\n\n  // 移除 Peer\n  async function removePeer(peer: string) {\n    try {\n      await ensureStorageReady();\n      if (enabledPeer.value === peer) {\n        await disablePeer();\n      }\n      await storageService.run('DELETE FROM network_peers WHERE url = ?', [peer]);\n      peersList.value = peersList.value.filter(p => p !== peer);\n      delete peerStatuses.value[peer];\n      gun.opt({ peers: peersList.value });\n      showToast(`删除节点 ${peer}`, 'success');\n      await updatePeerStatuses();\n    } catch (err) {\n      console.error('[useNetworkStatus] Failed to remove peer:', err);\n      showToast('删除节点失败', 'error');\n    }\n  }\n\n  // 处理网络状态变化\n  function handleOnline() {\n    updateNetworkStatus();\n    updateStatus();\n  }\n\n  function handleOffline() {\n    updateNetworkStatus();\n    updateStatus();\n  }\n\n  // 初始化逻辑，只执行一次\n  if (!initialized) {\n    initialized = true;\n    loadPeers();\n    updateStatus();\n\n    // 添加网络事件监听\n    window.addEventListener('online', handleOnline);\n    window.addEventListener('offline', handleOffline);\n\n    // 监听 peersList 和 enabledPeer 的变化\n    watch(peersList, () => {\n      updatePeerStatuses();\n    });\n    watch(enabledPeer, () => {\n      saveEnabledPeer();\n      updateStatus();\n    });\n  }\n\n  return {\n    networkStatus,\n    peersStatus,\n    currentMode,\n    peerStatuses,\n    peersList,\n    enabledPeer,\n    addPeer,\n    removePeer,\n    enablePeer,\n    disablePeer,\n    updateStatus,\n    peersNotes,\n    savePeerNote,\n  };\n}\n\n// 导出单例\nexport function useNetworkStatus(storageService: StorageService) {\n  if (!instance) {\n    instance = createNetworkStatus(storageService);\n  }\n  return instance;\n}\n\n\n// import { ref, watch } from 'vue';\n// import { useToast } from '@/composables/useToast';\n// import { useNetwork } from '@/composables/useNetwork';\n\n// // 模块级别的单例状态\n// const networkStatus = ref<'online' | 'offline'>('online');\n// const peersStatus = ref<'connected' | 'disconnected'>('disconnected');\n// const currentMode = ref<'direct' | 'relay'>('direct');\n// const peerStatuses = ref<Record<string, 'connected' | 'disconnected'>>({});\n\n// // 单例初始化标志\n// let initialized = false;\n// let instance: ReturnType<typeof createNetworkStatus> | null = null;\n\n// // 持久化 enabledPeer 的本地存储键\n// const ENABLED_PEER_KEY = 'enabledPeer';\n\n// function createNetworkStatus() {\n//   const { gun, peersList, enabledPeer } = getTalkFlowCore();\n//   const { showToast } = useToast();\n//   const { isOnline, peersConnected, updateNetworkStatus, checkPeers } = useNetwork(gun);\n\n//   // 保存 enabledPeer 到 localStorage\n//   function saveEnabledPeer() {\n//     localStorage.setItem(ENABLED_PEER_KEY, enabledPeer.value);\n//   }\n\n//   // 从 localStorage 加载 Peer 配置\n//   function loadPeers() {\n//     const savedPeers = localStorage.getItem('peers');\n//     if (savedPeers) {\n//       peersList.value = JSON.parse(savedPeers);\n//     }\n//     const savedPeer = localStorage.getItem(ENABLED_PEER_KEY);\n//     if (savedPeer && peersList.value.includes(savedPeer)) {\n//       enabledPeer.value = savedPeer;\n//     } else if (peersList.value.length > 0) {\n//       enabledPeer.value = peersList.value[0];\n//       saveEnabledPeer();\n//     }\n//     // 初始化时使用完整的 peersList\n//     gun.opt({ peers: peersList.value });\n//   }\n\n//   // 更新网络和 Peer 状态\n//   async function updateStatus() {\n//     networkStatus.value = isOnline.value ? 'online' : 'offline';\n//     peersStatus.value = peersConnected.value ? 'connected' : 'disconnected';\n//     currentMode.value = peersConnected.value && enabledPeer.value ? 'relay' : 'direct';\n//     await updatePeerStatuses();\n//   }\n\n//   // 检查单个 Peer 的状态（用于 UI 展示）\n//   async function checkPeerStatus(peer: string): Promise<'connected' | 'disconnected'> {\n//     return new Promise((resolve) => {\n//       const tempGun = Gun({ peers: [peer] });\n//       let connected = false;\n//       tempGun.on('hi', () => {\n//         connected = true;\n//         resolve('connected');\n//       });\n//       setTimeout(() => {\n//         if (!connected) resolve('disconnected');\n//       }, 5000);\n//     });\n//   }\n\n//   // 更新所有 Peer 的状态（用于 UI 展示）\n//   async function updatePeerStatuses() {\n//     for (const peer of peersList.value) {\n//       const status = await checkPeerStatus(peer);\n//       peerStatuses.value[peer] = status;\n//     }\n//   }\n\n//   // 用户手动启用某个 Peer\n//   async function enablePeer(peer: string) {\n//     if (!peersList.value.includes(peer)) {\n//       showToast(`Peer ${peer} not in list`, 'warning');\n//       return;\n//     }\n//     if (enabledPeer.value === peer) {\n//       showToast(`${peer} is already enabled`, 'info');\n//       return;\n//     }\n\n//     enabledPeer.value = peer;\n//     saveEnabledPeer();\n//     gun.opt({ peers: peersList.value, priorityPeer: peer }); // 自定义选项，优先尝试该 Peer\n//     showToast(`Enabled peer: ${peer}`, 'success');\n\n//     // 检查连接状态\n//     const connected = await checkPeers();\n//     if (!connected) {\n//       showToast(`Failed to connect to ${peer}, falling back to other peers`, 'warning');\n//     }\n//     await updateStatus();\n//   }\n\n//   // 用户禁用当前启用的 Peer\n//   function disablePeer() {\n//     if (!enabledPeer.value) {\n//       showToast('No peer enabled', 'info');\n//       return;\n//     }\n//     const oldPeer = enabledPeer.value;\n//     enabledPeer.value = peersList.value.length > 1 ? peersList.value.find(p => p !== oldPeer) || '' : '';\n//     saveEnabledPeer();\n//     gun.opt({ peers: peersList.value }); // 重置为完整列表\n//     showToast(`Disabled peer: ${oldPeer}`, 'success');\n//     updateStatus();\n//   }\n\n//   // 添加 Peer\n//   function addPeer(url: string) {\n//     if (!url) {\n//       showToast('Please enter the node URL', 'warning');\n//       return;\n//     }\n//     if (peersList.value.includes(url)) {\n//       showToast('This node already exists.', 'warning');\n//       return;\n//     }\n//     peersList.value.push(url);\n//     localStorage.setItem('peers', JSON.stringify(peersList.value));\n//     gun.opt({ peers: peersList.value });\n//     showToast(`Node added: ${url}`, 'success');\n//     updatePeerStatuses();\n//   }\n\n//   // 移除 Peer\n//   function removePeer(peer: string) {\n//     if (enabledPeer.value === peer) {\n//       disablePeer();\n//     }\n//     peersList.value = peersList.value.filter(p => p !== peer);\n//     delete peerStatuses.value[peer];\n//     localStorage.setItem('peers', JSON.stringify(peersList.value));\n//     gun.opt({ peers: peersList.value });\n//     showToast(`Deleted node ${peer}`, 'success');\n//     updatePeerStatuses();\n//   }\n\n//   // 处理网络状态变化\n//   function handleOnline() {\n//     updateNetworkStatus();\n//     updateStatus();\n//   }\n\n//   function handleOffline() {\n//     updateNetworkStatus();\n//     updateStatus();\n//   }\n\n//   // 初始化逻辑，只执行一次\n//   if (!initialized) {\n//     initialized = true;\n//     loadPeers();\n//     updateStatus();\n\n//     // 添加网络事件监听\n//     window.addEventListener('online', handleOnline);\n//     window.addEventListener('offline', handleOffline);\n\n//     // 监听 peersList 和 enabledPeer 的变化\n//     watch(peersList, () => {\n//       // gun.opt({ peers: peersList.value });\n//       updatePeerStatuses();\n//     });\n//     watch(enabledPeer, () => {\n//       saveEnabledPeer();\n//       updateStatus();\n//     });\n//   }\n\n//   return {\n//     networkStatus,\n//     peersStatus,\n//     currentMode,\n//     peerStatuses,\n//     peersList,\n//     enabledPeer,\n//     addPeer,\n//     removePeer,\n//     enablePeer,\n//     disablePeer,\n//     updateStatus,\n//   };\n// }\n\n// // 导出单例\n// export function useNetworkStatus() {\n//   if (!instance) {\n//     instance = createNetworkStatus();\n//   }\n//   return instance;\n// }\n\n// 清理函数（用于测试或应用卸载时）\n// export function cleanupNetworkStatus() {\n//   if (instance) {\n//     window.removeEventListener('online', instance.updateStatus);\n//     window.removeEventListener('offline', instance.updateStatus);\n//     instance = null;\n//     initialized = false;\n//   }\n// }"
  },
  {
    "path": "examples/relay-sqlite-example/src/composables/useToast.ts",
    "content": "// src/composables/useToast.ts\nimport { ref, onMounted } from 'vue';\nimport { Directory, Encoding, Filesystem } from '@capacitor/filesystem';\n\ntype ToastType = 'info' | 'success' | 'error' | 'warning';\n\ninterface ToastMessage {\n  id: number;\n  text: string;\n  type: ToastType;\n  duration: number;\n}\n\nconst messages = ref<ToastMessage[]>([]);\nlet idCounter = 0;\nconst isEnabled = ref(false); // 默认开启提示\nconst SETTINGS_FILE = 'toast_settings.json';\n\nasync function loadSettings(): Promise<{ isToastEnabled: boolean }> {\n  const defaultSettings = { isToastEnabled: false };\n  try {\n    const result = await Filesystem.readFile({\n      path: SETTINGS_FILE,\n      directory: Directory.Data,\n      encoding: Encoding.UTF8,\n    });\n    const data = typeof result.data === 'string' ? result.data : await result.data.text();\n    return JSON.parse(data) || defaultSettings;\n  } catch (err) {\n    console.log('未找到提示设置文件，使用默认值');\n    return defaultSettings;\n  }\n}\n\nasync function saveSettings(): Promise<void> {\n  try {\n    await Filesystem.writeFile({\n      path: SETTINGS_FILE,\n      data: JSON.stringify({ isToastEnabled: isEnabled.value }),\n      directory: Directory.Data,\n      encoding: Encoding.UTF8,\n    });\n    console.log('提示设置已保存:', { isToastEnabled: isEnabled.value });\n  } catch (err) {\n    console.error('保存提示设置失败:', err);\n  }\n}\n\nexport function showToast(msg: string, msgType: ToastType = 'info', customDuration = 3000) {\n  if (!isEnabled.value) return; // 如果关闭则不显示\n\n  const toast = {\n    id: idCounter++,\n    text: msg,\n    type: msgType,\n    duration: customDuration,\n  };\n  messages.value.push(toast);\n\n  setTimeout(() => {\n    messages.value = messages.value.filter(m => m.id !== toast.id);\n  }, customDuration);\n}\n\nfunction hideToast(id: number) {\n  messages.value = messages.value.filter(m => m.id !== id);\n}\n\nfunction toggleToast(enabled: boolean) {\n  isEnabled.value = enabled;\n  saveSettings(); // 保存设置\n}\n\n// 初始化加载设置\nonMounted(async () => {\n  const settings = await loadSettings();\n  isEnabled.value = settings.isToastEnabled;\n});\n\nexport function useToast() {\n  return {\n    messages,\n    isEnabled,\n    showToast,\n    hideToast,\n    toggleToast,\n  };\n}"
  },
  {
    "path": "examples/relay-sqlite-example/src/main.ts",
    "content": "import { createApp } from 'vue'\nimport App from './src/App.vue'\nimport router from './router';\n\nimport { IonicVue } from '@ionic/vue';\n\n\nimport { useRouter } from 'vue-router'\n\n\n\n\n\n/* Core CSS required for Ionic components to work properly */\nimport '@ionic/vue/css/core.css';\n\n/* Basic CSS for apps built with Ionic */\nimport '@ionic/vue/css/normalize.css';\nimport '@ionic/vue/css/structure.css';\nimport '@ionic/vue/css/typography.css';\nimport '@ionic/vue/css/ionic.bundle.css'\n/* Optional CSS utils that can be commented out */\nimport '@ionic/vue/css/padding.css';\nimport '@ionic/vue/css/float-elements.css';\nimport '@ionic/vue/css/text-alignment.css';\nimport '@ionic/vue/css/text-transformation.css';\nimport '@ionic/vue/css/flex-utils.css';\nimport '@ionic/vue/css/display.css';\n\n/* Theme variables */\nimport './theme/variables.css';\n\nimport { Capacitor } from '@capacitor/core';\nimport { JeepSqlite } from 'jeep-sqlite/dist/components/jeep-sqlite';\nimport { defineCustomElements as pwaElements} from '@ionic/pwa-elements/loader';\nimport SqliteService from './services/sqliteService'; \nimport DbVersionService from './services/dbVersionService';\nimport StorageService from './services/storageService';\nimport InitializeAppService from './services/initializeAppService';\n\n\n\n\npwaElements(window);\ncustomElements.define('jeep-sqlite', JeepSqlite);\nconst platform = Capacitor.getPlatform();\n\nconst app = createApp(App)\n\n  .use(IonicVue)\n  .use(useRouter)\n\n  .use(router);\n \n\n// Set the platform as global properties on the app\napp.config.globalProperties.$platform = platform;\n\n// Define and instantiate the required services\nconst sqliteServ = new SqliteService();\nconst dbVersionServ = new DbVersionService();\nconst storageServ = new StorageService(sqliteServ, dbVersionServ);\n// Set the services as global properties on the app\napp.config.globalProperties.$sqliteServ = sqliteServ;\napp.config.globalProperties.$dbVersionServ = dbVersionServ;\napp.config.globalProperties.$storageServ = storageServ;\n\n//Define and instantiate the InitializeAppService\nconst initAppServ = new InitializeAppService(sqliteServ, storageServ);\n \nconst mountApp = () => {\n  initAppServ.initializeApp()\n  .then(() => {\n    router.isReady().then(() => {\n\n      app.mount('#app');\n    });\n  })\n  .catch((error) => {\n    console.error('App Initialization error:', error);\n  });\n}\n\nif (platform !== \"web\") {\n  mountApp();\n} else {\n  window.addEventListener('DOMContentLoaded', async () => {\n      const jeepEl = document.createElement(\"jeep-sqlite\");\n      document.body.appendChild(jeepEl);\n      customElements.whenDefined('jeep-sqlite').then(() => {\n        mountApp();\n      })\n      .catch ((err) => {\n        console.error('jeep-sqlite creation error:', err);\n      });\n  });\n}"
  },
  {
    "path": "examples/relay-sqlite-example/src/pages/index.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nimport {\n  IonPage, IonHeader, IonToolbar, IonButtons, IonBackButton, IonTitle, IonContent, IonIcon,\n  IonModal, IonToggle \n} from '@ionic/vue';\nimport { addCircleSharp, closeCircleSharp, helpCircleOutline, closeOutline } from 'ionicons/icons';\nimport RelayMode from '@/components/RelayMode.vue';\n\n\nconst showHelpModal = ref(false); \n</script>\n\n<template>\n  <ion-page>\n    <ion-header :translucent=\"true\"  collapse=\"fade\">\n      <ion-toolbar class=\"liquid-toolbar\">\n        <ion-buttons slot=\"start\">\n          <ion-back-button text=\"Discover\" color=\"dark\"></ion-back-button>\n        </ion-buttons>\n        <ion-title>Network Status</ion-title>\n        <ion-buttons slot=\"end\">\n          <ion-button color=\"dark\" @click=\"showHelpModal = true\">\n            <ion-icon :icon=\"helpCircleOutline\"></ion-icon>\n          </ion-button>\n        </ion-buttons>\n      </ion-toolbar>\n    </ion-header>\n\n    <ion-content :fullscreen=\"true\"  :scroll-y=\"false\">\n\n      <RelayMode/>\n\n\n   \n    </ion-content>\n  </ion-page>\n</template>\n\n<style scoped>\n.addlink {\n  width: 39px;\n  height: 39px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n/* Ionic Toolbar */\n.liquid-toolbar {\n  --border-color: transparent;\n}\n\n/* Ionic Content */\n.liquid-content {\n  --background: transparent;\n  --padding-start: 0;\n  --padding-end: 0;\n  --padding-top: 0;\n  --padding-bottom: 0;\n}\n\n/* Original Container Styles */\n.liquid-container {\n  padding: 15px 20px;\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', sans-serif;\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n}\n\n.status-item {\n  display: flex;\n  align-items: center;\n  margin-bottom: 15px;\n  background: rgba(130, 130, 130, 0.1);\n  padding: 10px;\n  border-radius: 15px;\n  transition: transform 0.3s ease;\n}\n\n.status-item:hover {\n  transform: scale(1.02);\n}\n\n.label {\n  font-weight: 500;\n  margin-right: 10px;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);\n}\n\n.indicator {\n  display: inline-block;\n  padding: 6px 12px;\n  border-radius: 12px;\n  font-size: 14px;\n  backdrop-filter: blur(5px);\n}\n\n.indicator.online,\n.indicator.connected,\n.indicator.relay {\n  background: linear-gradient(45deg, #99ff99, #66ffcc);\n  color: #333;\n}\n\n.indicator.offline,\n.indicator.disconnected,\n.indicator.direct {\n  background: linear-gradient(45deg, #ff6666, #ff9999);\n}\n\n.add-peer {\n  display: flex;\n  gap: 15px;\n  margin-bottom: 20px;\n}\n\n.add-peer input {\n  flex: 1;\n  padding: 10px;\n  border: none;\n  border-radius: 15px;\n  background: rgba(134, 134, 134, 0.25);\n  font-size: 14px;\n  transition: transform 0.3s ease, box-shadow 0.3s ease;\n}\n\n.add-peer input:hover,\n.add-peer input:focus {\n  transform: scale(1.02);\n  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n  outline: none;\n}\n\n.peer-list {\n  margin-top: 0;\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n}\n\n.peer-list h3 {\n  font-size: 18px;\n  margin-bottom: 15px;\n  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n}\n\n.peer-scroll-container {\n  border-radius: 10px;\n  max-height: 390px;\n  overflow-y: auto;\n  flex: 1;\n}\n\n.peer-scroll-container::-webkit-scrollbar {\n  width: 8px;\n}\n\n.peer-scroll-container::-webkit-scrollbar-track {\n  background: rgba(125, 125, 125, 0.451);\n  border-radius: 10px;\n}\n\n.peer-scroll-container::-webkit-scrollbar-thumb {\n  background: linear-gradient(45deg, #66ccff, #99eeff);\n  border-radius: 10px;\n}\n\n.peer-scroll-container::-webkit-scrollbar-thumb:hover {\n  background: linear-gradient(45deg, #00b7ff, #66ddff);\n}\n\n.peer-item {\n  padding: 15px;\n  background: linear-gradient(135deg, rgba(127, 127, 127, 0.15), rgba(255, 255, 255, 0.05));\n  border-radius: 15px;\n  margin-bottom: 15px;\n  transition: transform 0.3s ease, box-shadow 0.3s ease;\n}\n\n.peer-header {\n  display: flex;\n  align-items: center;\n  margin-bottom: 10px;\n}\n\n.status {\n  display: inline-block;\n  padding: 6px 12px;\n  border-radius: 12px;\n  font-size: 12px;\n  text-align: center;\n  backdrop-filter: blur(5px);\n  animation: pulse 2s infinite ease-in-out;\n}\n\n.status.connected {\n  background: linear-gradient(45deg, #99ff99, #66ffcc);\n  color: #333;\n}\n\n.status.disconnected {\n  background: linear-gradient(45deg, #ff6666, #ff9999);\n}\n\n.status.checking {\n  background: linear-gradient(45deg, #ffcc66, #ffdd99);\n  color: #333;\n}\n\n.peer-content {\n  margin-bottom: 15px;\n}\n\n.peer-url {\n  display: block;\n  word-break: break-all;\n  font-size: 14px;\n  line-height: 1.4;\n  padding: 5px 10px;\n  background: rgba(124, 124, 124, 0.1);\n  border-radius: 10px;\n}\n\n.peer-actions {\n  display: flex;\n  align-items: center;\n  justify-content: flex-end;\n  gap: 15px;\n}\n\nion-toggle {\n  --background: rgba(128, 128, 128, 0.2);\n  --background-checked: #66ccff;\n  --handle-background: #fff;\n  --handle-background-checked: #fff;\n  width: 50px;\n  height: 24px;\n}\n\n.remove-icon {\n  color: #ff6666;\n  font-size: 30px;\n  cursor: pointer;\n  transition: transform 0.3s ease;\n}\n\n.remove-icon:hover {\n  transform: scale(1.1);\n  color: #ff9999;\n}\n\n\n.help-modal {\n  --border-radius: 16px;\n\n}\n\n.help-modal ion-toolbar {\n  --border-width: 0;\n  --background: transparent;\n}\n\n.help-content {\n  padding: 0 0 20px;\n}\n\n.help-content h2 {\n  font-size: 1.25rem;\n  margin: 20px 0 10px;\n  color: #333;\n}\n\n.help-content h3 {\n  font-size: 1.1rem;\n  margin: 15px 0 10px;\n  color: #333;\n}\n\n.help-content ion-list {\n  background: transparent;\n  margin-bottom: 15px;\n}\n\n.help-content ion-item {\n  --background: transparent;\n  --padding-start: 0;\n  --inner-padding-end: 0;\n}\n\n.help-content ion-label {\n  color: #666 !important;\n  font-size: 1rem;\n}\n\nion-button[color=\"dark\"] {\n  --background: #333;\n  --border-radius: 12px;\n  height: 44px;\n  transition: transform 0.3s ease, box-shadow 0.3s ease;\n}\n\nion-button[color=\"dark\"]:hover {\n  --background: #444;\n  transform: translateY(-2px);\n  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);\n}\n</style>"
  },
  {
    "path": "examples/relay-sqlite-example/src/router/index.ts",
    "content": "import { createRouter, createWebHistory } from '@ionic/vue-router'\nimport { createAnimation } from '@ionic/vue'\nimport routes from 'virtual:generated-pages'\n// import { useChatFlow } from '@/composables/TalkFlowCore'\n\n// const { isLoggedIn } = useChatFlow()\n\nconst customRoutes = [\n\n  {\n    path: '/',\n    component: () => import('@/pages/index.vue'),\n  }\n\n  \n\n  ...routes,\n]\n\nconst router = createRouter({\n  history: createWebHistory(import.meta.env.BASE_URL),\n  routes: customRoutes,\n})\n\n\n// 导航守卫\n// router.beforeEach((to, from, next) => {\n//   // 如果用户没有登录，且访问的不是 'i18n.vue' 页面，则重定向到 'i18n.vue'\n//   if (!isLoggedIn.value && to.path !== '/') {\n//     next('/');  // 重定向到 i18n 页面\n//   } else {\n//     next();  // 允许访问目标路由\n//   }\n// });\n\n// router.beforeEach(async (to, from, next) => {\n//   const { isLoggedIn } = await import('@/composables/TalkFlowCore');\n//   if (!isLoggedIn.value && to.path !== '/') {\n//     next('/');\n//   } else {\n//     next();\n//   }\n// });\n\n\nexport default router\n"
  },
  {
    "path": "examples/relay-sqlite-example/src/services/dbVersionService.ts",
    "content": "export interface IDbVersionService {\n    setDbVersion(dbName: string, version: number): void\n    getDbVersion(dbName: string):number| undefined\n};\nclass DbVersionService implements IDbVersionService {\n    dbNameVersionDict: Map<string, number> = new Map();\n  \n    setDbVersion(dbName: string, version: number) {\n      this.dbNameVersionDict.set(dbName, version);\n      console.log(`设置数据库 ${dbName} 版本为: ${version}`);\n    }\n  \n    getDbVersion(dbName: string): number | undefined {\n      const version = this.dbNameVersionDict.get(dbName);\n      console.log(`获取数据库 ${dbName} 版本: ${version}`);\n      return version;\n    }\n  }\nexport default DbVersionService;"
  },
  {
    "path": "examples/relay-sqlite-example/src/services/globalServices.ts",
    "content": "import SQLiteService from './sqliteService';\nimport DbVersionService from './dbVersionService';\nimport StorageService from './storageService';\n\nconst sqliteServ = new SQLiteService();\nconst dbVerServ = new DbVersionService();\nconst storageServ = new StorageService(sqliteServ, dbVerServ);\n\nexport { sqliteServ, dbVerServ, storageServ };"
  },
  {
    "path": "examples/relay-sqlite-example/src/services/initializeAppService.ts",
    "content": "import {ISQLiteService } from '../services/sqliteService'; \nimport {IStorageService } from '../services/storageService'; \n\nexport interface IInitializeAppService {\n    initializeApp(): Promise<boolean>\n};\n\nclass InitializeAppService implements IInitializeAppService  {\n    appInit = false;\n    sqliteServ!: ISQLiteService;\n    storageServ!: IStorageService;\n    platform!: string;\n  static platform: string;\n\n    constructor(sqliteService: ISQLiteService, storageService: IStorageService) {\n        this.sqliteServ = sqliteService;\n        this.storageServ = storageService;\n        this.platform = this.sqliteServ.getPlatform();\n    }\n    async initializeApp(): Promise<boolean> {\n        if (!this.appInit) {\n          try {\n            console.log('开始应用初始化');\n            if (this.platform === 'web') {\n              await this.sqliteServ.initWebStore();\n              console.log('Web 存储初始化完成');\n            }\n            await this.storageServ.initializeDatabase();\n            console.log('数据库初始化完成');\n            // if (this.platform === 'web') {\n            //   await this.sqliteServ.saveToStore(this.storageServ.getDatabaseName());\n            //   console.log('数据库保存到 Web 存储完成');\n            // }\n            this.appInit = true;\n            console.log('应用初始化成功');\n          } catch (error: any) {\n            const msg = error.message ? error.message : error;\n            console.error(`initializeAppError.initializeApp: ${msg}`, error);\n            throw new Error(`initializeAppError.initializeApp: ${msg}`);\n          }\n        }\n        return this.appInit;\n      }\n}\nexport default InitializeAppService;\n"
  },
  {
    "path": "examples/relay-sqlite-example/src/services/sqliteService.ts",
    "content": "import { CapacitorSQLite, SQLiteConnection, SQLiteDBConnection, capSQLiteUpgradeOptions } from '@capacitor-community/sqlite';\nimport { Capacitor } from '@capacitor/core';\n\nexport interface ISQLiteService {\n    getPlatform(): string\n    initWebStore(): Promise<void>\n    addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<void> \n    openDatabase(dbName: string, loadToVersion: number, readOnly: boolean): Promise<SQLiteDBConnection> \n    closeDatabase(dbName: string, readOnly: boolean): Promise<void>\n    saveToStore(dbName: string): Promise<void>\n    saveToLocalDisk(dbName: string): Promise<void>\n    isConnection(dbName: string, readOnly: boolean): Promise<boolean>\n};\n\nclass SQLiteService implements ISQLiteService {\n    platform = Capacitor.getPlatform();\n    sqlitePlugin = CapacitorSQLite;\n    sqliteConnection = new SQLiteConnection(CapacitorSQLite);\n    dbNameVersionDict: Map<string, number> = new Map();\n\n    getPlatform(): string {\n        return this.platform;\n    }\n    async initWebStore() : Promise<void>  {\n        try {\n            await this.sqliteConnection.initWebStore();\n        } catch(error: any) {\n            const msg = error.message ? error.message : error;\n            throw new Error(`sqliteService.initWebStore: ${msg}`);\n        }\n        return;\n    }\n    async addUpgradeStatement(options: capSQLiteUpgradeOptions): Promise<void> {\n        try {\n            await this.sqlitePlugin.addUpgradeStatement(options);\n        } catch(error: any) {\n            const msg = error.message ? error.message : error;\n            throw new Error(`sqliteService.addUpgradeStatement: ${msg}`);\n        }\n        return;\n    }\n    async openDatabase(dbName:string, loadToVersion: number,\n                readOnly: boolean): Promise<SQLiteDBConnection>  {\n        this.dbNameVersionDict.set(dbName, loadToVersion);\n        let encrypted = false;\n        const mode = encrypted ? \"secret\" : \"no-encryption\";\n        try {\n            let db: SQLiteDBConnection;\n            const retCC = (await this.sqliteConnection.checkConnectionsConsistency()).result;\n            let isConn = (await this.sqliteConnection.isConnection(dbName, readOnly)).result;\n            if(retCC && isConn) {\n              db = await this.sqliteConnection.retrieveConnection(dbName, readOnly);\n            } else {\n                db = await this.sqliteConnection\n                        .createConnection(dbName, encrypted, mode, loadToVersion, readOnly);\n            }\n            const jeepSQlEL = document.querySelector(\"jeep-sqlite\")\n      \n            await db.open();\n            const res = await db.isDBOpen();\n            return db;\n          \n        } catch(error: any) {\n            const msg = error.message ? error.message : error;\n            throw new Error(`sqliteService.openDatabase: ${msg}`);\n        }\n\n    }\n    async isConnection(dbName:string, readOnly: boolean): Promise<boolean> {\n        try {\n            const isConn = (await this.sqliteConnection.isConnection(dbName, readOnly)).result;\n            if (isConn != undefined) {\n                return isConn\n            } else {\n                throw new Error(`sqliteService.isConnection undefined`);\n            }\n        \n        } catch(error: any) {\n            const msg = error.message ? error.message : error;\n            throw new Error(`sqliteService.isConnection: ${msg}`);\n        }\n    }\n    async closeDatabase(dbName:string, readOnly: boolean):Promise<void> {\n        try {\n            const isConn = (await this.sqliteConnection.isConnection(dbName, readOnly)).result;\n            if(isConn) {\n                await this.sqliteConnection.closeConnection(dbName, readOnly);\n            }\n            return;\n        } catch(error: any) {\n            const msg = error.message ? error.message : error;\n            throw new Error(`sqliteService.closeDatabase: ${msg}`);\n        }\n    }\n    async saveToStore(dbName: string): Promise<void> {\n        try {\n            await this.sqliteConnection.saveToStore(dbName);\n            return;\n        } catch(error: any) {\n            const msg = error.message ? error.message : error;\n            throw new Error(`sqliteService.saveToStore: ${msg}`);\n        }\n    }\n    async saveToLocalDisk(dbName: string): Promise<void> {\n        try {\n            await this.sqliteConnection.saveToLocalDisk(dbName);\n            return;\n        } catch(err:any) {\n            const msg = err.message ? err.message : err;\n            throw new Error(`sqliteService.saveToLocalDisk: ${msg}`);\n        }\n    }\n}\nexport default SQLiteService;\n"
  },
  {
    "path": "examples/relay-sqlite-example/src/services/storageService.ts",
    "content": "import { BehaviorSubject } from 'rxjs';\nimport { CapacitorSQLite, SQLiteDBConnection } from '@capacitor-community/sqlite';\nimport { getCurrentInstance } from 'vue';\nimport { ISQLiteService } from './sqliteService';\nimport { IDbVersionService } from './dbVersionService';\n\n\nexport interface IStorageService {\n  initializeDatabase(): Promise<void>;\n\n\n  query(sql: string, params?: any[]): Promise<any>;\n  run(sql: string, params?: any[]): Promise<any>;\n  execute(sql: string): Promise<any>;\n\n}\n\nclass StorageService implements IStorageService {\n  versionUpgrades = [\n   \n    {\n      toVersion: 1,\n      statements: [\n      \n        `CREATE TABLE IF NOT EXISTS network_peers (\n          id INTEGER PRIMARY KEY AUTOINCREMENT,\n          url TEXT UNIQUE,\n          is_enabled INTEGER DEFAULT 0,\n          note TEXT DEFAULT ''\n        );`,\n      \n        `CREATE TABLE IF NOT EXISTS gun_nodes (\n          key TEXT PRIMARY KEY NOT NULL,\n          value TEXT NOT NULL,\n          timestamp INTEGER DEFAULT (strftime('%s', 'now'))\n        );`,\n        \n  \n\n\n\n\n      ],\n    },\n  ];\n\n\n  loadToVersion = 1;\n  momentsVersion = 2;\n  db!: SQLiteDBConnection;\n  database: string = 'gundb';\n  sqliteServ!: ISQLiteService;\n  dbVerServ!: IDbVersionService;\n  isInitCompleted = new BehaviorSubject(false);\n  appInstance = getCurrentInstance();\n  platform!: string;\n  private isInitialized = false;\n\n  constructor(sqliteService: ISQLiteService, dbVersionService: IDbVersionService) {\n    this.sqliteServ = sqliteService;\n    this.dbVerServ = dbVersionService;\n    this.platform = this.appInstance?.appContext.config.globalProperties.$platform || 'web';\n  }\n\n  async initializeDatabase(): Promise<void> {\n    if (this.isInitialized) {\n      console.log('数据库已初始化，跳过重复调用');\n      return;\n    }\n\n    try {\n      console.log('开始初始化数据库:', this.database);\n      await this.sqliteServ.addUpgradeStatement({\n        database: this.database,\n        upgrade: this.versionUpgrades,\n      });\n      console.log('核心升级语句已添加');\n\n      this.db = await this.sqliteServ.openDatabase(this.database, this.loadToVersion, false);\n      console.log('数据库已打开，目标版本:', this.loadToVersion);\n\n      const currentVersionResult = await this.db.getVersion();\n      const currentVersion: number = currentVersionResult.version ?? 0;\n      console.log('当前数据库版本:', currentVersion);\n\n      for (const upgrade of this.versionUpgrades) {\n        console.log(`执行核心升级到版本 ${upgrade.toVersion}`);\n        for (const stmt of upgrade.statements) {\n          try {\n            await this.db.execute(stmt);\n            console.log('执行语句成功:', stmt);\n          } catch (err) {\n            console.error('执行语句失败:', stmt, err);\n            throw err;\n          }\n        }\n      }\n      this.dbVerServ.setDbVersion(this.database, this.loadToVersion);\n      console.log('核心数据库版本已设置为:', this.loadToVersion);\n\n    \n\n      if (this.platform === 'web') {\n        try {\n          await this.sqliteServ.saveToStore(this.database);\n          console.log('数据库已保存到 Web 存储');\n        } catch (err) {\n          console.warn('Web 存储保存失败（非致命错误）:', err);\n        }\n      }\n\n      const tablesAfter = await this.db.query(\"SELECT name FROM sqlite_master WHERE type='table'\");\n      console.log('初始化后的表:', tablesAfter.values);\n      this.isInitCompleted.next(true);\n      this.isInitialized = true;\n      console.log('SQLite 数据库初始化成功');\n    } catch (error: any) {\n      console.error(`storageService.initializeDatabase: ${error.message || error}`, error);\n      throw new Error(`storageService.initializeDatabase: ${error.message || error}`);\n    }\n  }\n  async query(sql: string, params: any[] = []): Promise<any> {\n    try {\n      return await this.db.query(sql, params);\n    } catch (err) {\n      console.error(`执行查询 ${sql} 失败:`, err);\n      throw err;\n    }\n  }\n\n  async run(sql: string, params: any[] = []): Promise<any> {\n    try {\n      return await this.db.run(sql, params);\n    } catch (err) {\n      console.error(`执行语句 ${sql} 失败:`, err);\n      throw err;\n    }\n  }\n\n  async execute(sql: string): Promise<any> {\n    try {\n      return await this.db.execute(sql);\n    } catch (err) {\n      console.error(`执行语句 ${sql} 失败:`, err);\n      throw err;\n    }\n  }\n}\n\nexport default StorageService;\n\n\n\n"
  },
  {
    "path": "examples/relay-sqlite-example/src/theme/variables.css",
    "content": "/* Ionic Variables and Theming. For more info, please see:\nhttp://ionicframework.com/docs/theming/ */\n\n/** Ionic CSS Variables **/\n:root {\n  --ion-background-color: #ffffff;\n  /** primary **/\n  --ion-color-primary: #3880ff;\n  --ion-color-primary-rgb: 56, 128, 255;\n  --ion-color-primary-contrast: #ffffff;\n  --ion-color-primary-contrast-rgb: 255, 255, 255;\n  --ion-color-primary-shade: #3171e0;\n  --ion-color-primary-tint: #4c8dff;\n\n  /** secondary **/\n  --ion-color-secondary: #3dc2ff;\n  --ion-color-secondary-rgb: 61, 194, 255;\n  --ion-color-secondary-contrast: #e1dfdf;\n  --ion-color-secondary-contrast-rgb: 255, 255, 255;\n  --ion-color-secondary-shade: #36abe0;\n  --ion-color-secondary-tint: #50c8ff;\n\n  /** tertiary **/\n  --ion-color-tertiary: #5260ff;\n  --ion-color-tertiary-rgb: 82, 96, 255;\n  --ion-color-tertiary-contrast: #e3e3e3;\n  --ion-color-tertiary-contrast-rgb: 255, 255, 255;\n  --ion-color-tertiary-shade: #4854e0;\n  --ion-color-tertiary-tint: #6370ff;\n\n  /** success **/\n  --ion-color-success: #2dd36f;\n  --ion-color-success-rgb: 45, 211, 111;\n  --ion-color-success-contrast: #ededed;\n  --ion-color-success-contrast-rgb: 255, 255, 255;\n  --ion-color-success-shade: #28ba62;\n  --ion-color-success-tint: #42d77d;\n\n  /** warning #222428 **/\n  --ion-color-warning: #ffc409;\n  --ion-color-warning-rgb: 255, 196, 9;\n  --ion-color-warning-contrast: #222428;\n  --ion-color-warning-contrast-rgb: 0, 0, 0;\n  --ion-color-warning-shade: #e0ac08;\n  --ion-color-warning-tint: #ffca22;\n\n  /** danger **/\n  --ion-color-danger: #eb445a;\n  --ion-color-danger-rgb: 235, 68, 90;\n  --ion-color-danger-contrast: #ffffff;\n  --ion-color-danger-contrast-rgb: 255, 255, 255;\n  --ion-color-danger-shade: #cf3c4f;\n  --ion-color-danger-tint: #ed576b;\n\n  /** dark #000000 **/\n  --ion-color-dark: #000000;\n  --ion-color-dark-rgb: 34, 36, 40;\n  --ion-color-dark-contrast: #e1e1e1;\n  --ion-color-dark-contrast-rgb: 255, 255, 255;\n  --ion-color-dark-shade: #1e2023;\n  --ion-color-dark-tint: #383a3e;\n\n  /** medium **/\n  --ion-color-medium: #92949c;\n  --ion-color-medium-rgb: 146, 148, 156;\n  --ion-color-medium-contrast: #e6e6e6;\n  --ion-color-medium-contrast-rgb: 255, 255, 255;\n  --ion-color-medium-shade: #808289;\n  --ion-color-medium-tint: #9d9fa6;\n\n  /** light **/\n  --ion-color-light: #e8e8e8;\n  --ion-color-light-rgb: 244, 245, 248;\n  --ion-color-light-contrast: #000000;\n  --ion-color-light-contrast-rgb: 0, 0, 0;\n  --ion-color-light-shade: #d7d8da;\n  --ion-color-light-tint: #f5f6f9;\n}\n\n@media (prefers-color-scheme: dark) {\n  /*\n   * Dark Colors\n   * -------------------------------------------\n   */\n\n  body {\n    --ion-color-primary: #428cff;\n    --ion-color-primary-rgb: 66,140,255;\n    --ion-color-primary-contrast: #ffffff;\n    --ion-color-primary-contrast-rgb: 255,255,255;\n    --ion-color-primary-shade: #3a7be0;\n    --ion-color-primary-tint: #5598ff;\n\n    --ion-color-secondary: #50c8ff;\n    --ion-color-secondary-rgb: 80,200,255;\n    --ion-color-secondary-contrast: #ffffff;\n    --ion-color-secondary-contrast-rgb: 255,255,255;\n    --ion-color-secondary-shade: #46b0e0;\n    --ion-color-secondary-tint: #62ceff;\n\n    --ion-color-tertiary: #6a64ff;\n    --ion-color-tertiary-rgb: 106,100,255;\n    --ion-color-tertiary-contrast: #ffffff;\n    --ion-color-tertiary-contrast-rgb: 255,255,255;\n    --ion-color-tertiary-shade: #5d58e0;\n    --ion-color-tertiary-tint: #7974ff;\n\n    --ion-color-success: #2fdf75;\n    --ion-color-success-rgb: 47,223,117;\n    --ion-color-success-contrast: #000000;\n    --ion-color-success-contrast-rgb: 0,0,0;\n    --ion-color-success-shade: #29c467;\n    --ion-color-success-tint: #44e283;\n\n    --ion-color-warning: #ffd534;\n    --ion-color-warning-rgb: 255,213,52;\n    --ion-color-warning-contrast: #000000;\n    --ion-color-warning-contrast-rgb: 0,0,0;\n    --ion-color-warning-shade: #e0bb2e;\n    --ion-color-warning-tint: #ffd948;\n\n    --ion-color-danger: #ff4961;\n    --ion-color-danger-rgb: 255,73,97;\n    --ion-color-danger-contrast: #ffffff;\n    --ion-color-danger-contrast-rgb: 255,255,255;\n    --ion-color-danger-shade: #e04055;\n    --ion-color-danger-tint: #ff5b71;\n\n    --ion-color-dark: #dfdfdf;\n    --ion-color-dark-rgb: 244,245,248;\n    --ion-color-dark-contrast: #141414;\n    --ion-color-dark-contrast-rgb: 0,0,0;\n    --ion-color-dark-shade: #b5b5b5;\n    --ion-color-dark-tint: #dedfe0;\n\n    --ion-color-medium: #989aa2;\n    --ion-color-medium-rgb: 152,154,162;\n    --ion-color-medium-contrast: #000000;\n    --ion-color-medium-contrast-rgb: 0,0,0;\n    --ion-color-medium-shade: #86888f;\n    --ion-color-medium-tint: #a2a4ab;\n\n    --ion-color-light: #222428;\n    --ion-color-light-rgb: 34,36,40;\n    --ion-color-light-contrast: #ffffff;\n    --ion-color-light-contrast-rgb: 255,255,255;\n    --ion-color-light-shade: #1e2023;\n    --ion-color-light-tint: #383a3e;\n  }\n\n  /*\n   * iOS Dark Theme #111111\n   * -------------------------------------------\n   */\n\n  .ios body {\n    --ion-background-color: #000000;\n    --ion-background-color-rgb: 0,0,0;\n\n    --ion-text-color: #bfcbc7;\n    --ion-text-color-rgb: 255,255,255;\n\n    --ion-color-step-50: #0d0d0d;\n    --ion-color-step-100: #1a1a1a;\n    --ion-color-step-150: #262626;\n    --ion-color-step-200: #333333;\n    --ion-color-step-250: #404040;\n    --ion-color-step-300: #4d4d4d;\n    --ion-color-step-350: #595959;\n    --ion-color-step-400: #666666;\n    --ion-color-step-450: #737373;\n    --ion-color-step-500: #808080;\n    --ion-color-step-550: #8c8c8c;\n    --ion-color-step-600: #999999;\n    --ion-color-step-650: #a6a6a6;\n    --ion-color-step-700: #b3b3b3;\n    --ion-color-step-750: #bfbfbf;\n    --ion-color-step-800: #cccccc;\n    --ion-color-step-850: #d9d9d9;\n    --ion-color-step-900: #e6e6e6;\n    --ion-color-step-950: #f2f2f2;\n\n    --ion-item-background: #000000;\n\n    --ion-card-background: #1c1c1d;\n  }\n\n  .ios ion-modal {\n    --ion-background-color: var(--ion-color-step-50);\n    --ion-toolbar-background: var(--ion-color-step-100);\n    --ion-toolbar-border-color: var(--ion-color-step-150);\n  }\n\n\n  /*\n   * Material Design Dark Theme\n   * -------------------------------------------\n   */\n\n  .md body {\n    --ion-background-color: #000000;\n    --ion-background-color-rgb: 18,18,18;\n\n    --ion-text-color: #dfdede;\n    --ion-text-color-rgb: 255,255,255;\n\n    --ion-border-color: #222222;\n\n    --ion-color-step-50: #1e1e1e;\n    --ion-color-step-100: #2a2a2a;\n    --ion-color-step-150: #363636;\n    --ion-color-step-200: #414141;\n    --ion-color-step-250: #4d4d4d;\n    --ion-color-step-300: #595959;\n    --ion-color-step-350: #656565;\n    --ion-color-step-400: #717171;\n    --ion-color-step-450: #7d7d7d;\n    --ion-color-step-500: #898989;\n    --ion-color-step-550: #949494;\n    --ion-color-step-600: #a0a0a0;\n    --ion-color-step-650: #acacac;\n    --ion-color-step-700: #b8b8b8;\n    --ion-color-step-750: #c4c4c4;\n    --ion-color-step-800: #d0d0d0;\n    --ion-color-step-850: #dbdbdb;\n    --ion-color-step-900: #e7e7e7;\n    --ion-color-step-950: #f3f3f3;\n\n    --ion-item-background: #000000;\n\n    --ion-toolbar-background: #000000;\n\n    --ion-tab-bar-background: #000000;\n\n    --ion-card-background: #1e1e1e;\n  }\n}"
  },
  {
    "path": "examples/relay-sqlite-example/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"useDefineForClassFields\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Node\",\n    \"strict\": true,\n    \"jsx\": \"preserve\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"esModuleInterop\": true,\n    \"lib\": [\"ESNext\", \"DOM\"],\n    \"skipLibCheck\": true,\n    \"noEmit\": true,\n  \n    \"paths\": {\n      \"@/*\": [\"./src/*\"],\n      \"bare-plugin\": [\"./bare-plugin/dist/plugin\"]\n    }\n  },\n  \"include\": [\"src/**/*.ts\", \"src/**/*.d.ts\", \"src/**/*.tsx\", \"src/**/*.vue\"],\n  \"references\": [{ \"path\": \"./tsconfig.node.json\" }]\n}\n"
  },
  {
    "path": "examples/relay-sqlite-example/tsconfig.node.json",
    "content": "{\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Node\",\n    \"allowSyntheticDefaultImports\": true\n  },\n  \"include\": [\"vite.config.ts\"]\n}\n"
  },
  {
    "path": "examples/relay-sqlite-example/vite.config.ts",
    "content": "import legacy from '@vitejs/plugin-legacy'\nimport vue from '@vitejs/plugin-vue'\nimport path from 'path'\nimport { defineConfig } from 'vite'\nimport Components from 'unplugin-vue-components/vite'\nimport AutoImport from 'unplugin-auto-import/vite'\nimport Pages from 'vite-plugin-pages'\nimport { VitePWA } from 'vite-plugin-pwa'\n// import inject from \"@rollup/plugin-inject\";\n// https://vitejs.dev/config/\nexport default defineConfig({\n  plugins: [\n    vue(),\n    legacy(),\n    Components(),\n    // inject({\n    //   Buffer: [\"buffer\", \"Buffer\"],\n    // }),\n    AutoImport({\n    \n      imports: ['vue', 'vue-router'],\n\n  \n      dirs: [\n        'src/composables',\n    \n      ],\n\n\n      dts: 'src/auto-imports.d.ts',\n\n    \n    }),\n    Pages(),\n    VitePWA({\n      registerType: 'autoUpdate',\n      workbox: {\n        maximumFileSizeToCacheInBytes: 5000 * 1024 * 1024, \n      },\n    }),\n  ],\n  resolve: {\n    alias: {\n      '@': path.resolve(__dirname, './src'),\n      crypto: 'crypto-browserify',\n      buffer: \"buffer\",\n    \n    },\n  },\n  define: {\n    global: \"window\",\n  },\n  build: {\n    sourcemap: true,\n    rollupOptions: {\n         external: ['text-encoding'],\n        output:{\n        \n            manualChunks(id) {\n              \n                if (id.includes('node_modules')) {\n                    return id.toString().split('node_modules/')[1].split('/')[0].toString();\n                }\n                \n            }\n        }\n    }\n  },\n  // test: {\n  //   globals: true,\n  //   environment: 'jsdom'\n  // }\n})\n"
  },
  {
    "path": "examples/relay.service",
    "content": "[Unit]\nDescription=GUN relay\nDocumentation=https://gun.eco\nAfter=network.target\n\n[Install]\nWantedBy=multi-user.target\n\n[Service]\nEnvironment=PATH=/usr/bin:/usr/local/bin\nLimitNOFILE=infinity\nLimitNPROC=infinity\nLimitCORE=infinity\nStartLimitBurst=999999\nStartLimitIntervalSec=999999\nRestart=always\nExecStart=node examples/http.js 80\n# Environment=NODE_ENV=production\nWorkingDirectory="
  },
  {
    "path": "examples/smoothie.js",
    "content": "// MIT License:\n//\n// Copyright (c) 2010-2013, Joe Walnes\n//               2013-2018, Drew Noakes\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n/**\n * Smoothie Charts - http://smoothiecharts.org/\n * (c) 2010-2013, Joe Walnes\n *     2013-2018, Drew Noakes\n *\n * v1.0: Main charting library, by Joe Walnes\n * v1.1: Auto scaling of axis, by Neil Dunn\n * v1.2: fps (frames per second) option, by Mathias Petterson\n * v1.3: Fix for divide by zero, by Paul Nikitochkin\n * v1.4: Set minimum, top-scale padding, remove timeseries, add optional timer to reset bounds, by Kelley Reynolds\n * v1.5: Set default frames per second to 50... smoother.\n *       .start(), .stop() methods for conserving CPU, by Dmitry Vyal\n *       options.interpolation = 'bezier' or 'line', by Dmitry Vyal\n *       options.maxValue to fix scale, by Dmitry Vyal\n * v1.6: minValue/maxValue will always get converted to floats, by Przemek Matylla\n * v1.7: options.grid.fillStyle may be a transparent color, by Dmitry A. Shashkin\n *       Smooth rescaling, by Kostas Michalopoulos\n * v1.8: Set max length to customize number of live points in the dataset with options.maxDataSetLength, by Krishna Narni\n * v1.9: Display timestamps along the bottom, by Nick and Stev-io\n *       (https://groups.google.com/forum/?fromgroups#!topic/smoothie-charts/-Ywse8FCpKI%5B1-25%5D)\n *       Refactored by Krishna Narni, to support timestamp formatting function\n * v1.10: Switch to requestAnimationFrame, removed the now obsoleted options.fps, by Gergely Imreh\n * v1.11: options.grid.sharpLines option added, by @drewnoakes\n *        Addressed warning seen in Firefox when seriesOption.fillStyle undefined, by @drewnoakes\n * v1.12: Support for horizontalLines added, by @drewnoakes\n *        Support for yRangeFunction callback added, by @drewnoakes\n * v1.13: Fixed typo (#32), by @alnikitich\n * v1.14: Timer cleared when last TimeSeries removed (#23), by @davidgaleano\n *        Fixed diagonal line on chart at start/end of data stream, by @drewnoakes\n * v1.15: Support for npm package (#18), by @dominictarr\n *        Fixed broken removeTimeSeries function (#24) by @davidgaleano\n *        Minor performance and tidying, by @drewnoakes\n * v1.16: Bug fix introduced in v1.14 relating to timer creation/clearance (#23), by @drewnoakes\n *        TimeSeries.append now deals with out-of-order timestamps, and can merge duplicates, by @zacwitte (#12)\n *        Documentation and some local variable renaming for clarity, by @drewnoakes\n * v1.17: Allow control over font size (#10), by @drewnoakes\n *        Timestamp text won't overlap, by @drewnoakes\n * v1.18: Allow control of max/min label precision, by @drewnoakes\n *        Added 'borderVisible' chart option, by @drewnoakes\n *        Allow drawing series with fill but no stroke (line), by @drewnoakes\n * v1.19: Avoid unnecessary repaints, and fixed flicker in old browsers having multiple charts in document (#40), by @asbai\n * v1.20: Add SmoothieChart.getTimeSeriesOptions and SmoothieChart.bringToFront functions, by @drewnoakes\n * v1.21: Add 'step' interpolation mode, by @drewnoakes\n * v1.22: Add support for different pixel ratios. Also add optional y limit formatters, by @copacetic\n * v1.23: Fix bug introduced in v1.22 (#44), by @drewnoakes\n * v1.24: Fix bug introduced in v1.23, re-adding parseFloat to y-axis formatter defaults, by @siggy_sf\n * v1.25: Fix bug seen when adding a data point to TimeSeries which is older than the current data, by @Nking92\n *        Draw time labels on top of series, by @comolosabia\n *        Add TimeSeries.clear function, by @drewnoakes\n * v1.26: Add support for resizing on high device pixel ratio screens, by @copacetic\n * v1.27: Fix bug introduced in v1.26 for non whole number devicePixelRatio values, by @zmbush\n * v1.28: Add 'minValueScale' option, by @megawac\n *        Fix 'labelPos' for different size of 'minValueString' 'maxValueString', by @henryn\n * v1.29: Support responsive sizing, by @drewnoakes\n * v1.29.1: Include types in package, and make property optional, by @TrentHouliston\n * v1.30: Fix inverted logic in devicePixelRatio support, by @scanlime\n * v1.31: Support tooltips, by @Sly1024 and @drewnoakes\n * v1.32: Support frame rate limit, by @dpuyosa\n * v1.33: Use Date static method instead of instance, by @nnnoel\n *        Fix bug with tooltips when multiple charts on a page, by @jpmbiz70\n * v1.34: Add disabled option to TimeSeries, by @TechGuard (#91)\n *        Add nonRealtimeData option, by @annazhelt (#92, #93)\n *        Add showIntermediateLabels option, by @annazhelt (#94)\n *        Add displayDataFromPercentile option, by @annazhelt (#95)\n *        Fix bug when hiding tooltip element, by @ralphwetzel (#96)\n *        Support intermediate y-axis labels, by @beikeland (#99)\n * v1.35: Fix issue with responsive mode at high DPI, by @drewnoakes (#101)\n * v1.36: Add tooltipLabel to ITimeSeriesPresentationOptions.\n *        If tooltipLabel is present, tooltipLabel displays inside tooltip\n *        next to value, by @jackdesert (#102)\n *        Fix bug rendering issue in series fill when using scroll backwards, by @olssonfredrik\n *        Add title option, by @mesca\n */\n\n;(function(exports) {\n\n  // Date.now polyfill\n  Date.now = Date.now || function() { return new Date().getTime(); };\n\n  var Util = {\n    extend: function() {\n      arguments[0] = arguments[0] || {};\n      for (var i = 1; i < arguments.length; i++)\n      {\n        for (var key in arguments[i])\n        {\n          if (arguments[i].hasOwnProperty(key))\n          {\n            if (typeof(arguments[i][key]) === 'object') {\n              if (arguments[i][key] instanceof Array) {\n                arguments[0][key] = arguments[i][key];\n              } else {\n                arguments[0][key] = Util.extend(arguments[0][key], arguments[i][key]);\n              }\n            } else {\n              arguments[0][key] = arguments[i][key];\n            }\n          }\n        }\n      }\n      return arguments[0];\n    },\n    binarySearch: function(data, value) {\n      var low = 0,\n          high = data.length;\n      while (low < high) {\n        var mid = (low + high) >> 1;\n        if (value < data[mid][0])\n          high = mid;\n        else\n          low = mid + 1;\n      }\n      return low;\n    }\n  };\n\n  /**\n   * Initialises a new <code>TimeSeries</code> with optional data options.\n   *\n   * Options are of the form (defaults shown):\n   *\n   * <pre>\n   * {\n   *   resetBounds: true,        // enables/disables automatic scaling of the y-axis\n   *   resetBoundsInterval: 3000 // the period between scaling calculations, in millis\n   * }\n   * </pre>\n   *\n   * Presentation options for TimeSeries are specified as an argument to <code>SmoothieChart.addTimeSeries</code>.\n   *\n   * @constructor\n   */\n  function TimeSeries(options) {\n    this.options = Util.extend({}, TimeSeries.defaultOptions, options);\n    this.disabled = false;\n    this.clear();\n  }\n\n  TimeSeries.defaultOptions = {\n    resetBoundsInterval: 3000,\n    resetBounds: true\n  };\n\n  /**\n   * Clears all data and state from this TimeSeries object.\n   */\n  TimeSeries.prototype.clear = function() {\n    this.data = [];\n    this.maxValue = Number.NaN; // The maximum value ever seen in this TimeSeries.\n    this.minValue = Number.NaN; // The minimum value ever seen in this TimeSeries.\n  };\n\n  /**\n   * Recalculate the min/max values for this <code>TimeSeries</code> object.\n   *\n   * This causes the graph to scale itself in the y-axis.\n   */\n  TimeSeries.prototype.resetBounds = function() {\n    if (this.data.length) {\n      // Walk through all data points, finding the min/max value\n      this.maxValue = this.data[0][1];\n      this.minValue = this.data[0][1];\n      for (var i = 1; i < this.data.length; i++) {\n        var value = this.data[i][1];\n        if (value > this.maxValue) {\n          this.maxValue = value;\n        }\n        if (value < this.minValue) {\n          this.minValue = value;\n        }\n      }\n    } else {\n      // No data exists, so set min/max to NaN\n      this.maxValue = Number.NaN;\n      this.minValue = Number.NaN;\n    }\n  };\n\n  /**\n   * Adds a new data point to the <code>TimeSeries</code>, preserving chronological order.\n   *\n   * @param timestamp the position, in time, of this data point\n   * @param value the value of this data point\n   * @param sumRepeatedTimeStampValues if <code>timestamp</code> has an exact match in the series, this flag controls\n   * whether it is replaced, or the values summed (defaults to false.)\n   */\n  TimeSeries.prototype.append = function(timestamp, value, sumRepeatedTimeStampValues) {\n    // Rewind until we hit an older timestamp\n    var i = this.data.length - 1;\n    while (i >= 0 && this.data[i][0] > timestamp) {\n      i--;\n    }\n\n    if (i === -1) {\n      // This new item is the oldest data\n      this.data.splice(0, 0, [timestamp, value]);\n    } else if (this.data.length > 0 && this.data[i][0] === timestamp) {\n      // Update existing values in the array\n      if (sumRepeatedTimeStampValues) {\n        // Sum this value into the existing 'bucket'\n        this.data[i][1] += value;\n        value = this.data[i][1];\n      } else {\n        // Replace the previous value\n        this.data[i][1] = value;\n      }\n    } else if (i < this.data.length - 1) {\n      // Splice into the correct position to keep timestamps in order\n      this.data.splice(i + 1, 0, [timestamp, value]);\n    } else {\n      // Add to the end of the array\n      this.data.push([timestamp, value]);\n    }\n\n    this.maxValue = isNaN(this.maxValue) ? value : Math.max(this.maxValue, value);\n    this.minValue = isNaN(this.minValue) ? value : Math.min(this.minValue, value);\n  };\n\n  TimeSeries.prototype.dropOldData = function(oldestValidTime, maxDataSetLength) {\n    // We must always keep one expired data point as we need this to draw the\n    // line that comes into the chart from the left, but any points prior to that can be removed.\n    var removeCount = 0;\n    while (this.data.length - removeCount >= maxDataSetLength && this.data[removeCount + 1][0] < oldestValidTime) {\n      removeCount++;\n    }\n    if (removeCount !== 0) {\n      this.data.splice(0, removeCount);\n    }\n  };\n\n  /**\n   * Initialises a new <code>SmoothieChart</code>.\n   *\n   * Options are optional, and should be of the form below. Just specify the values you\n   * need and the rest will be given sensible defaults as shown:\n   *\n   * <pre>\n   * {\n   *   minValue: undefined,                      // specify to clamp the lower y-axis to a given value\n   *   maxValue: undefined,                      // specify to clamp the upper y-axis to a given value\n   *   maxValueScale: 1,                         // allows proportional padding to be added above the chart. for 10% padding, specify 1.1.\n   *   minValueScale: 1,                         // allows proportional padding to be added below the chart. for 10% padding, specify 1.1.\n   *   yRangeFunction: undefined,                // function({min: , max: }) { return {min: , max: }; }\n   *   scaleSmoothing: 0.125,                    // controls the rate at which y-value zoom animation occurs\n   *   millisPerPixel: 20,                       // sets the speed at which the chart pans by\n   *   enableDpiScaling: true,                   // support rendering at different DPI depending on the device\n   *   yMinFormatter: function(min, precision) { // callback function that formats the min y value label\n   *     return parseFloat(min).toFixed(precision);\n   *   },\n   *   yMaxFormatter: function(max, precision) { // callback function that formats the max y value label\n   *     return parseFloat(max).toFixed(precision);\n   *   },\n   *   yIntermediateFormatter: function(intermediate, precision) { // callback function that formats the intermediate y value labels\n   *     return parseFloat(intermediate).toFixed(precision);\n   *   },\n   *   maxDataSetLength: 2,\n   *   interpolation: 'bezier'                   // one of 'bezier', 'linear', or 'step'\n   *   timestampFormatter: null,                 // optional function to format time stamps for bottom of chart\n   *                                             // you may use SmoothieChart.timeFormatter, or your own: function(date) { return ''; }\n   *   scrollBackwards: false,                   // reverse the scroll direction of the chart\n   *   horizontalLines: [],                      // [ { value: 0, color: '#ffffff', lineWidth: 1 } ]\n   *   grid:\n   *   {\n   *     fillStyle: '#000000',                   // the background colour of the chart\n   *     lineWidth: 1,                           // the pixel width of grid lines\n   *     strokeStyle: '#777777',                 // colour of grid lines\n   *     millisPerLine: 1000,                    // distance between vertical grid lines\n   *     sharpLines: false,                      // controls whether grid lines are 1px sharp, or softened\n   *     verticalSections: 2,                    // number of vertical sections marked out by horizontal grid lines\n   *     borderVisible: true                     // whether the grid lines trace the border of the chart or not\n   *   },\n   *   labels\n   *   {\n   *     disabled: false,                        // enables/disables labels showing the min/max values\n   *     fillStyle: '#ffffff',                   // colour for text of labels,\n   *     fontSize: 15,\n   *     fontFamily: 'sans-serif',\n   *     precision: 2,\n   *     showIntermediateLabels: false,          // shows intermediate labels between min and max values along y axis\n   *     intermediateLabelSameAxis: true,\n   *   },\n   *   title\n   *   {\n   *     text: '',                               // the text to display on the left side of the chart\n   *     fillStyle: '#ffffff',                   // colour for text\n   *     fontSize: 15,\n   *     fontFamily: 'sans-serif',\n   *     verticalAlign: 'middle'                 // one of 'top', 'middle', or 'bottom'\n   *   },\n   *   tooltip: false                            // show tooltip when mouse is over the chart\n   *   tooltipLine: {                            // properties for a vertical line at the cursor position\n   *     lineWidth: 1,\n   *     strokeStyle: '#BBBBBB'\n   *   },\n   *   tooltipFormatter: SmoothieChart.tooltipFormatter, // formatter function for tooltip text\n   *   nonRealtimeData: false,                   // use time of latest data as current time\n   *   displayDataFromPercentile: 1,             // display not latest data, but data from the given percentile\n   *                                             // useful when trying to see old data saved by setting a high value for maxDataSetLength\n   *                                             // should be a value between 0 and 1\n   *   responsive: false,                        // whether the chart should adapt to the size of the canvas\n   *   limitFPS: 0                               // maximum frame rate the chart will render at, in FPS (zero means no limit)\n   * }\n   * </pre>\n   *\n   * @constructor\n   */\n  function SmoothieChart(options) {\n    this.options = Util.extend({}, SmoothieChart.defaultChartOptions, options);\n    this.seriesSet = [];\n    this.currentValueRange = 1;\n    this.currentVisMinValue = 0;\n    this.lastRenderTimeMillis = 0;\n    this.lastChartTimestamp = 0;\n\n    this.mousemove = this.mousemove.bind(this);\n    this.mouseout = this.mouseout.bind(this);\n  }\n\n  /** Formats the HTML string content of the tooltip. */\n  SmoothieChart.tooltipFormatter = function (timestamp, data) {\n      var timestampFormatter = this.options.timestampFormatter || SmoothieChart.timeFormatter,\n          lines = [timestampFormatter(new Date(timestamp))],\n          label;\n\n      for (var i = 0; i < data.length; ++i) {\n        label = data[i].series.options.tooltipLabel || ''\n        if (label !== ''){\n            label = label + ' ';\n        }\n        lines.push('<span style=\"color:' + data[i].series.options.strokeStyle + '\">' +\n        label +\n        this.options.yMaxFormatter(data[i].value, this.options.labels.precision) + '</span>');\n      }\n\n      return lines.join('<br>');\n  };\n\n  SmoothieChart.defaultChartOptions = {\n    millisPerPixel: 20,\n    enableDpiScaling: true,\n    yMinFormatter: function(min, precision) {\n      return parseFloat(min).toFixed(precision);\n    },\n    yMaxFormatter: function(max, precision) {\n      return parseFloat(max).toFixed(precision);\n    },\n    yIntermediateFormatter: function(intermediate, precision) {\n      return parseFloat(intermediate).toFixed(precision);\n    },\n    maxValueScale: 1,\n    minValueScale: 1,\n    interpolation: 'bezier',\n    scaleSmoothing: 0.125,\n    maxDataSetLength: 2,\n    scrollBackwards: false,\n    displayDataFromPercentile: 1,\n    grid: {\n      fillStyle: '#000000',\n      strokeStyle: '#777777',\n      lineWidth: 1,\n      sharpLines: false,\n      millisPerLine: 1000,\n      verticalSections: 2,\n      borderVisible: true\n    },\n    labels: {\n      fillStyle: '#ffffff',\n      disabled: false,\n      fontSize: 10,\n      fontFamily: 'monospace',\n      precision: 2,\n      showIntermediateLabels: false,\n      intermediateLabelSameAxis: true,\n    },\n    title: {\n      text: '',\n      fillStyle: '#ffffff',\n      fontSize: 15,\n      fontFamily: 'monospace',\n      verticalAlign: 'middle'\n    },\n    horizontalLines: [],\n    tooltip: false,\n    tooltipLine: {\n      lineWidth: 1,\n      strokeStyle: '#BBBBBB'\n    },\n    tooltipFormatter: SmoothieChart.tooltipFormatter,\n    nonRealtimeData: false,\n    responsive: false,\n    limitFPS: 0\n  };\n\n  // Based on http://inspirit.github.com/jsfeat/js/compatibility.js\n  SmoothieChart.AnimateCompatibility = (function() {\n    var requestAnimationFrame = function(callback, element) {\n          var requestAnimationFrame =\n            window.requestAnimationFrame        ||\n            window.webkitRequestAnimationFrame  ||\n            window.mozRequestAnimationFrame     ||\n            window.oRequestAnimationFrame       ||\n            window.msRequestAnimationFrame      ||\n            function(callback) {\n              return window.setTimeout(function() {\n                callback(Date.now());\n              }, 16);\n            };\n          return requestAnimationFrame.call(window, callback, element);\n        },\n        cancelAnimationFrame = function(id) {\n          var cancelAnimationFrame =\n            window.cancelAnimationFrame ||\n            function(id) {\n              clearTimeout(id);\n            };\n          return cancelAnimationFrame.call(window, id);\n        };\n\n    return {\n      requestAnimationFrame: requestAnimationFrame,\n      cancelAnimationFrame: cancelAnimationFrame\n    };\n  })();\n\n  SmoothieChart.defaultSeriesPresentationOptions = {\n    lineWidth: 1,\n    strokeStyle: '#ffffff'\n  };\n\n  /**\n   * Adds a <code>TimeSeries</code> to this chart, with optional presentation options.\n   *\n   * Presentation options should be of the form (defaults shown):\n   *\n   * <pre>\n   * {\n   *   lineWidth: 1,\n   *   strokeStyle: '#ffffff',\n   *   fillStyle: undefined,\n   *   tooltipLabel: undefined\n   * }\n   * </pre>\n   */\n  SmoothieChart.prototype.addTimeSeries = function(timeSeries, options) {\n    this.seriesSet.push({timeSeries: timeSeries, options: Util.extend({}, SmoothieChart.defaultSeriesPresentationOptions, options)});\n    if (timeSeries.options.resetBounds && timeSeries.options.resetBoundsInterval > 0) {\n      timeSeries.resetBoundsTimerId = setInterval(\n        function() {\n          timeSeries.resetBounds();\n        },\n        timeSeries.options.resetBoundsInterval\n      );\n    }\n  };\n\n  /**\n   * Removes the specified <code>TimeSeries</code> from the chart.\n   */\n  SmoothieChart.prototype.removeTimeSeries = function(timeSeries) {\n    // Find the correct timeseries to remove, and remove it\n    var numSeries = this.seriesSet.length;\n    for (var i = 0; i < numSeries; i++) {\n      if (this.seriesSet[i].timeSeries === timeSeries) {\n        this.seriesSet.splice(i, 1);\n        break;\n      }\n    }\n    // If a timer was operating for that timeseries, remove it\n    if (timeSeries.resetBoundsTimerId) {\n      // Stop resetting the bounds, if we were\n      clearInterval(timeSeries.resetBoundsTimerId);\n    }\n  };\n\n  /**\n   * Gets render options for the specified <code>TimeSeries</code>.\n   *\n   * As you may use a single <code>TimeSeries</code> in multiple charts with different formatting in each usage,\n   * these settings are stored in the chart.\n   */\n  SmoothieChart.prototype.getTimeSeriesOptions = function(timeSeries) {\n    // Find the correct timeseries to remove, and remove it\n    var numSeries = this.seriesSet.length;\n    for (var i = 0; i < numSeries; i++) {\n      if (this.seriesSet[i].timeSeries === timeSeries) {\n        return this.seriesSet[i].options;\n      }\n    }\n  };\n\n  /**\n   * Brings the specified <code>TimeSeries</code> to the top of the chart. It will be rendered last.\n   */\n  SmoothieChart.prototype.bringToFront = function(timeSeries) {\n    // Find the correct timeseries to remove, and remove it\n    var numSeries = this.seriesSet.length;\n    for (var i = 0; i < numSeries; i++) {\n      if (this.seriesSet[i].timeSeries === timeSeries) {\n        var set = this.seriesSet.splice(i, 1);\n        this.seriesSet.push(set[0]);\n        break;\n      }\n    }\n  };\n\n  /**\n   * Instructs the <code>SmoothieChart</code> to start rendering to the provided canvas, with specified delay.\n   *\n   * @param canvas the target canvas element\n   * @param delayMillis an amount of time to wait before a data point is shown. This can prevent the end of the series\n   * from appearing on screen, with new values flashing into view, at the expense of some latency.\n   */\n  SmoothieChart.prototype.streamTo = function(canvas, delayMillis) {\n    this.canvas = canvas;\n    this.delay = delayMillis;\n    this.start();\n  };\n\n  SmoothieChart.prototype.getTooltipEl = function () {\n    // Create the tool tip element lazily\n    if (!this.tooltipEl) {\n      this.tooltipEl = document.createElement('div');\n      this.tooltipEl.className = 'smoothie-chart-tooltip';\n      this.tooltipEl.style.position = 'absolute';\n      this.tooltipEl.style.display = 'none';\n      document.body.appendChild(this.tooltipEl);\n    }\n    return this.tooltipEl;\n  };\n\n  SmoothieChart.prototype.updateTooltip = function () {\n    if(!this.options.tooltip){\n     return;\n    }\n    var el = this.getTooltipEl();\n\n    if (!this.mouseover || !this.options.tooltip) {\n      el.style.display = 'none';\n      return;\n    }\n\n    var time = this.lastChartTimestamp;\n\n    // x pixel to time\n    var t = this.options.scrollBackwards\n      ? time - this.mouseX * this.options.millisPerPixel\n      : time - (this.canvas.offsetWidth - this.mouseX) * this.options.millisPerPixel;\n\n    var data = [];\n\n     // For each data set...\n    for (var d = 0; d < this.seriesSet.length; d++) {\n      var timeSeries = this.seriesSet[d].timeSeries;\n      if (timeSeries.disabled) {\n          continue;\n      }\n\n      // find datapoint closest to time 't'\n      var closeIdx = Util.binarySearch(timeSeries.data, t);\n      if (closeIdx > 0 && closeIdx < timeSeries.data.length) {\n        data.push({ series: this.seriesSet[d], index: closeIdx, value: timeSeries.data[closeIdx][1] });\n      }\n    }\n\n    if (data.length) {\n      el.innerHTML = this.options.tooltipFormatter.call(this, t, data);\n      el.style.display = 'block';\n    } else {\n      el.style.display = 'none';\n    }\n  };\n\n  SmoothieChart.prototype.mousemove = function (evt) {\n    this.mouseover = true;\n    this.mouseX = evt.offsetX;\n    this.mouseY = evt.offsetY;\n    this.mousePageX = evt.pageX;\n    this.mousePageY = evt.pageY;\n    if(!this.options.tooltip){\n     return;\n    }\n    var el = this.getTooltipEl();\n    el.style.top = Math.round(this.mousePageY) + 'px';\n    el.style.left = Math.round(this.mousePageX) + 'px';\n    this.updateTooltip();\n  };\n\n  SmoothieChart.prototype.mouseout = function () {\n    this.mouseover = false;\n    this.mouseX = this.mouseY = -1;\n    if (this.tooltipEl)\n      this.tooltipEl.style.display = 'none';\n  };\n\n  /**\n   * Make sure the canvas has the optimal resolution for the device's pixel ratio.\n   */\n  SmoothieChart.prototype.resize = function () {\n    var dpr = !this.options.enableDpiScaling || !window ? 1 : window.devicePixelRatio,\n        width, height;\n    if (this.options.responsive) {\n      // Newer behaviour: Use the canvas's size in the layout, and set the internal\n      // resolution according to that size and the device pixel ratio (eg: high DPI)\n      width = this.canvas.offsetWidth;\n      height = this.canvas.offsetHeight;\n\n      if (width !== this.lastWidth) {\n        this.lastWidth = width;\n        this.canvas.setAttribute('width', (Math.floor(width * dpr)).toString());\n        this.canvas.getContext('2d').scale(dpr, dpr);\n      }\n      if (height !== this.lastHeight) {\n        this.lastHeight = height;\n        this.canvas.setAttribute('height', (Math.floor(height * dpr)).toString());\n        this.canvas.getContext('2d').scale(dpr, dpr);\n      }\n    } else if (dpr !== 1) {\n      // Older behaviour: use the canvas's inner dimensions and scale the element's size\n      // according to that size and the device pixel ratio (eg: high DPI)\n      width = parseInt(this.canvas.getAttribute('width'));\n      height = parseInt(this.canvas.getAttribute('height'));\n\n      if (!this.originalWidth || (Math.floor(this.originalWidth * dpr) !== width)) {\n        this.originalWidth = width;\n        this.canvas.setAttribute('width', (Math.floor(width * dpr)).toString());\n        this.canvas.style.width = width + 'px';\n        this.canvas.getContext('2d').scale(dpr, dpr);\n      }\n\n      if (!this.originalHeight || (Math.floor(this.originalHeight * dpr) !== height)) {\n        this.originalHeight = height;\n        this.canvas.setAttribute('height', (Math.floor(height * dpr)).toString());\n        this.canvas.style.height = height + 'px';\n        this.canvas.getContext('2d').scale(dpr, dpr);\n      }\n    }\n  };\n\n  /**\n   * Starts the animation of this chart.\n   */\n  SmoothieChart.prototype.start = function() {\n    if (this.frame) {\n      // We're already running, so just return\n      return;\n    }\n\n    this.canvas.addEventListener('mousemove', this.mousemove);\n    this.canvas.addEventListener('mouseout', this.mouseout);\n\n    // Renders a frame, and queues the next frame for later rendering\n    var animate = function() {\n      this.frame = SmoothieChart.AnimateCompatibility.requestAnimationFrame(function() {\n        if(this.options.nonRealtimeData){\n           var dateZero = new Date(0);\n           // find the data point with the latest timestamp\n           var maxTimeStamp = this.seriesSet.reduce(function(max, series){\n             var dataSet = series.timeSeries.data;\n             var indexToCheck = Math.round(this.options.displayDataFromPercentile * dataSet.length) - 1;\n             indexToCheck = indexToCheck >= 0 ? indexToCheck : 0;\n             indexToCheck = indexToCheck <= dataSet.length -1 ? indexToCheck : dataSet.length -1;\n             if(dataSet && dataSet.length > 0)\n             {\n              // timestamp corresponds to element 0 of the data point\n              var lastDataTimeStamp = dataSet[indexToCheck][0];\n              max = max > lastDataTimeStamp ? max : lastDataTimeStamp;\n             }\n             return max;\n          }.bind(this), dateZero);\n          // use the max timestamp as current time\n          this.render(this.canvas, maxTimeStamp > dateZero ? maxTimeStamp : null);\n        } else {\n          this.render();\n        }\n        animate();\n      }.bind(this));\n    }.bind(this);\n\n    animate();\n  };\n\n  /**\n   * Stops the animation of this chart.\n   */\n  SmoothieChart.prototype.stop = function() {\n    if (this.frame) {\n      SmoothieChart.AnimateCompatibility.cancelAnimationFrame(this.frame);\n      delete this.frame;\n      this.canvas.removeEventListener('mousemove', this.mousemove);\n      this.canvas.removeEventListener('mouseout', this.mouseout);\n    }\n  };\n\n  SmoothieChart.prototype.updateValueRange = function() {\n    // Calculate the current scale of the chart, from all time series.\n    var chartOptions = this.options,\n        chartMaxValue = Number.NaN,\n        chartMinValue = Number.NaN;\n\n    for (var d = 0; d < this.seriesSet.length; d++) {\n      // TODO(ndunn): We could calculate / track these values as they stream in.\n      var timeSeries = this.seriesSet[d].timeSeries;\n      if (timeSeries.disabled) {\n          continue;\n      }\n\n      if (!isNaN(timeSeries.maxValue)) {\n        chartMaxValue = !isNaN(chartMaxValue) ? Math.max(chartMaxValue, timeSeries.maxValue) : timeSeries.maxValue;\n      }\n\n      if (!isNaN(timeSeries.minValue)) {\n        chartMinValue = !isNaN(chartMinValue) ? Math.min(chartMinValue, timeSeries.minValue) : timeSeries.minValue;\n      }\n    }\n\n    // Scale the chartMaxValue to add padding at the top if required\n    if (chartOptions.maxValue != null) {\n      chartMaxValue = chartOptions.maxValue;\n    } else {\n      chartMaxValue *= chartOptions.maxValueScale;\n    }\n\n    // Set the minimum if we've specified one\n    if (chartOptions.minValue != null) {\n      chartMinValue = chartOptions.minValue;\n    } else {\n      chartMinValue -= Math.abs(chartMinValue * chartOptions.minValueScale - chartMinValue);\n    }\n\n    // If a custom range function is set, call it\n    if (this.options.yRangeFunction) {\n      var range = this.options.yRangeFunction({min: chartMinValue, max: chartMaxValue});\n      chartMinValue = range.min;\n      chartMaxValue = range.max;\n    }\n\n    if (!isNaN(chartMaxValue) && !isNaN(chartMinValue)) {\n      var targetValueRange = chartMaxValue - chartMinValue;\n      var valueRangeDiff = (targetValueRange - this.currentValueRange);\n      var minValueDiff = (chartMinValue - this.currentVisMinValue);\n      this.isAnimatingScale = Math.abs(valueRangeDiff) > 0.1 || Math.abs(minValueDiff) > 0.1;\n      this.currentValueRange += chartOptions.scaleSmoothing * valueRangeDiff;\n      this.currentVisMinValue += chartOptions.scaleSmoothing * minValueDiff;\n    }\n\n    this.valueRange = { min: chartMinValue, max: chartMaxValue };\n  };\n\n  SmoothieChart.prototype.render = function(canvas, time) {\n    var nowMillis = Date.now();\n\n    // Respect any frame rate limit.\n    if (this.options.limitFPS > 0 && nowMillis - this.lastRenderTimeMillis < (1000/this.options.limitFPS))\n      return;\n\n    if (!this.isAnimatingScale) {\n      // We're not animating. We can use the last render time and the scroll speed to work out whether\n      // we actually need to paint anything yet. If not, we can return immediately.\n\n      // Render at least every 1/6th of a second. The canvas may be resized, which there is\n      // no reliable way to detect.\n      var maxIdleMillis = Math.min(1000/6, this.options.millisPerPixel);\n\n      if (nowMillis - this.lastRenderTimeMillis < maxIdleMillis) {\n        return;\n      }\n    }\n\n    this.resize();\n    this.updateTooltip();\n\n    this.lastRenderTimeMillis = nowMillis;\n\n    canvas = canvas || this.canvas;\n    time = time || nowMillis - (this.delay || 0);\n\n    // Round time down to pixel granularity, so motion appears smoother.\n    time -= time % this.options.millisPerPixel;\n\n    this.lastChartTimestamp = time;\n\n    var context = canvas.getContext('2d'),\n        chartOptions = this.options,\n        dimensions = { top: 0, left: 0, width: canvas.clientWidth, height: canvas.clientHeight },\n        // Calculate the threshold time for the oldest data points.\n        oldestValidTime = time - (dimensions.width * chartOptions.millisPerPixel),\n        valueToYPixel = function(value) {\n          var offset = value - this.currentVisMinValue;\n          return this.currentValueRange === 0\n            ? dimensions.height\n            : dimensions.height - (Math.round((offset / this.currentValueRange) * dimensions.height));\n        }.bind(this),\n        timeToXPixel = function(t) {\n          if(chartOptions.scrollBackwards) {\n            return Math.round((time - t) / chartOptions.millisPerPixel);\n          }\n          return Math.round(dimensions.width - ((time - t) / chartOptions.millisPerPixel));\n        };\n\n    this.updateValueRange();\n\n    context.font = chartOptions.labels.fontSize + 'px ' + chartOptions.labels.fontFamily;\n\n    // Save the state of the canvas context, any transformations applied in this method\n    // will get removed from the stack at the end of this method when .restore() is called.\n    context.save();\n\n    // Move the origin.\n    context.translate(dimensions.left, dimensions.top);\n\n    // Create a clipped rectangle - anything we draw will be constrained to this rectangle.\n    // This prevents the occasional pixels from curves near the edges overrunning and creating\n    // screen cheese (that phrase should need no explanation).\n    context.beginPath();\n    context.rect(0, 0, dimensions.width, dimensions.height);\n    context.clip();\n\n    // Clear the working area.\n    context.save();\n    context.fillStyle = chartOptions.grid.fillStyle;\n    context.clearRect(0, 0, dimensions.width, dimensions.height);\n    context.fillRect(0, 0, dimensions.width, dimensions.height);\n    context.restore();\n\n    // Grid lines...\n    context.save();\n    context.lineWidth = chartOptions.grid.lineWidth;\n    context.strokeStyle = chartOptions.grid.strokeStyle;\n    // Vertical (time) dividers.\n    if (chartOptions.grid.millisPerLine > 0) {\n      context.beginPath();\n      for (var t = time - (time % chartOptions.grid.millisPerLine);\n           t >= oldestValidTime;\n           t -= chartOptions.grid.millisPerLine) {\n        var gx = timeToXPixel(t);\n        if (chartOptions.grid.sharpLines) {\n          gx -= 0.5;\n        }\n        context.moveTo(gx, 0);\n        context.lineTo(gx, dimensions.height);\n      }\n      context.stroke();\n      context.closePath();\n    }\n\n    // Horizontal (value) dividers.\n    for (var v = 1; v < chartOptions.grid.verticalSections; v++) {\n      var gy = Math.round(v * dimensions.height / chartOptions.grid.verticalSections);\n      if (chartOptions.grid.sharpLines) {\n        gy -= 0.5;\n      }\n      context.beginPath();\n      context.moveTo(0, gy);\n      context.lineTo(dimensions.width, gy);\n      context.stroke();\n      context.closePath();\n    }\n    // Bounding rectangle.\n    if (chartOptions.grid.borderVisible) {\n      context.beginPath();\n      context.strokeRect(0, 0, dimensions.width, dimensions.height);\n      context.closePath();\n    }\n    context.restore();\n\n    // Draw any horizontal lines...\n    if (chartOptions.horizontalLines && chartOptions.horizontalLines.length) {\n      for (var hl = 0; hl < chartOptions.horizontalLines.length; hl++) {\n        var line = chartOptions.horizontalLines[hl],\n            hly = Math.round(valueToYPixel(line.value)) - 0.5;\n        context.strokeStyle = line.color || '#ffffff';\n        context.lineWidth = line.lineWidth || 1;\n        context.beginPath();\n        context.moveTo(0, hly);\n        context.lineTo(dimensions.width, hly);\n        context.stroke();\n        context.closePath();\n      }\n    }\n\n    // For each data set...\n    for (var d = 0; d < this.seriesSet.length; d++) {\n      context.save();\n      var timeSeries = this.seriesSet[d].timeSeries;\n      if (timeSeries.disabled) {\n          continue;\n      }\n\n      var dataSet = timeSeries.data,\n          seriesOptions = this.seriesSet[d].options;\n\n      // Delete old data that's moved off the left of the chart.\n      timeSeries.dropOldData(oldestValidTime, chartOptions.maxDataSetLength);\n\n      // Set style for this dataSet.\n      context.lineWidth = seriesOptions.lineWidth;\n      context.strokeStyle = seriesOptions.strokeStyle;\n      // Draw the line...\n      context.beginPath();\n      // Retain lastX, lastY for calculating the control points of bezier curves.\n      var firstX = 0, firstY = 0, lastX = 0, lastY = 0;\n      for (var i = 0; i < dataSet.length && dataSet.length !== 1; i++) {\n        var x = timeToXPixel(dataSet[i][0]),\n            y = valueToYPixel(dataSet[i][1]);\n\n        if (i === 0) {\n          firstX = x;\n          firstY = y;\n          context.moveTo(x, y);\n        } else {\n          switch (chartOptions.interpolation) {\n            case \"linear\":\n            case \"line\": {\n              context.lineTo(x,y);\n              break;\n            }\n            case \"bezier\":\n            default: {\n              // Great explanation of Bezier curves: http://en.wikipedia.org/wiki/Bezier_curve#Quadratic_curves\n              //\n              // Assuming A was the last point in the line plotted and B is the new point,\n              // we draw a curve with control points P and Q as below.\n              //\n              // A---P\n              //     |\n              //     |\n              //     |\n              //     Q---B\n              //\n              // Importantly, A and P are at the same y coordinate, as are B and Q. This is\n              // so adjacent curves appear to flow as one.\n              //\n              context.bezierCurveTo( // startPoint (A) is implicit from last iteration of loop\n                Math.round((lastX + x) / 2), lastY, // controlPoint1 (P)\n                Math.round((lastX + x)) / 2, y, // controlPoint2 (Q)\n                x, y); // endPoint (B)\n              break;\n            }\n            case \"step\": {\n              context.lineTo(x,lastY);\n              context.lineTo(x,y);\n              break;\n            }\n          }\n        }\n\n        lastX = x; lastY = y;\n      }\n\n      if (dataSet.length > 1) {\n        if (seriesOptions.fillStyle) {\n          // Close up the fill region.\n          if (chartOptions.scrollBackwards) {\n            context.lineTo(lastX, dimensions.height + seriesOptions.lineWidth);\n            context.lineTo(firstX, dimensions.height + seriesOptions.lineWidth);\n            context.lineTo(firstX, firstY);\n          } else {\n            context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, lastY);\n            context.lineTo(dimensions.width + seriesOptions.lineWidth + 1, dimensions.height + seriesOptions.lineWidth + 1);\n            context.lineTo(firstX, dimensions.height + seriesOptions.lineWidth);\n          }\n          context.fillStyle = seriesOptions.fillStyle;\n          context.fill();\n        }\n\n        if (seriesOptions.strokeStyle && seriesOptions.strokeStyle !== 'none') {\n          context.stroke();\n        }\n        context.closePath();\n      }\n      context.restore();\n    }\n\n    if (chartOptions.tooltip && this.mouseX >= 0) {\n      // Draw vertical bar to show tooltip position\n      context.lineWidth = chartOptions.tooltipLine.lineWidth;\n      context.strokeStyle = chartOptions.tooltipLine.strokeStyle;\n      context.beginPath();\n      context.moveTo(this.mouseX, 0);\n      context.lineTo(this.mouseX, dimensions.height);\n      context.closePath();\n      context.stroke();\n      this.updateTooltip();\n    }\n\n    // Draw the axis values on the chart.\n    if (!chartOptions.labels.disabled && !isNaN(this.valueRange.min) && !isNaN(this.valueRange.max)) {\n      var maxValueString = chartOptions.yMaxFormatter(this.valueRange.max, chartOptions.labels.precision),\n          minValueString = chartOptions.yMinFormatter(this.valueRange.min, chartOptions.labels.precision),\n          maxLabelPos = chartOptions.scrollBackwards ? 0 : dimensions.width - context.measureText(maxValueString).width - 2,\n          minLabelPos = chartOptions.scrollBackwards ? 0 : dimensions.width - context.measureText(minValueString).width - 2;\n      context.fillStyle = chartOptions.labels.fillStyle;\n      context.fillText(maxValueString, maxLabelPos, chartOptions.labels.fontSize);\n      context.fillText(minValueString, minLabelPos, dimensions.height - 2);\n    }\n\n    // Display intermediate y axis labels along y-axis to the left of the chart\n    if ( chartOptions.labels.showIntermediateLabels\n          && !isNaN(this.valueRange.min) && !isNaN(this.valueRange.max)\n          && chartOptions.grid.verticalSections > 0) {\n      // show a label above every vertical section divider\n      var step = (this.valueRange.max - this.valueRange.min) / chartOptions.grid.verticalSections;\n      var stepPixels = dimensions.height / chartOptions.grid.verticalSections;\n      for (var v = 1; v < chartOptions.grid.verticalSections; v++) {\n        var gy = dimensions.height - Math.round(v * stepPixels);\n        if (chartOptions.grid.sharpLines) {\n          gy -= 0.5;\n        }\n        var yValue = chartOptions.yIntermediateFormatter(this.valueRange.min + (v * step), chartOptions.labels.precision);\n        //left of right axis?\n        intermediateLabelPos =\n          chartOptions.labels.intermediateLabelSameAxis\n          ? (chartOptions.scrollBackwards ? 0 : dimensions.width - context.measureText(yValue).width - 2)\n          : (chartOptions.scrollBackwards ? dimensions.width - context.measureText(yValue).width - 2 : 0);\n\n        context.fillText(yValue, intermediateLabelPos, gy - chartOptions.grid.lineWidth);\n      }\n    }\n\n    // Display timestamps along x-axis at the bottom of the chart.\n    if (chartOptions.timestampFormatter && chartOptions.grid.millisPerLine > 0) {\n      var textUntilX = chartOptions.scrollBackwards\n        ? context.measureText(minValueString).width\n        : dimensions.width - context.measureText(minValueString).width + 4;\n      for (var t = time - (time % chartOptions.grid.millisPerLine);\n           t >= oldestValidTime;\n           t -= chartOptions.grid.millisPerLine) {\n        var gx = timeToXPixel(t);\n        // Only draw the timestamp if it won't overlap with the previously drawn one.\n        if ((!chartOptions.scrollBackwards && gx < textUntilX) || (chartOptions.scrollBackwards && gx > textUntilX))  {\n          // Formats the timestamp based on user specified formatting function\n          // SmoothieChart.timeFormatter function above is one such formatting option\n          var tx = new Date(t),\n            ts = chartOptions.timestampFormatter(tx),\n            tsWidth = context.measureText(ts).width;\n\n          textUntilX = chartOptions.scrollBackwards\n            ? gx + tsWidth + 2\n            : gx - tsWidth - 2;\n\n          context.fillStyle = chartOptions.labels.fillStyle;\n          if(chartOptions.scrollBackwards) {\n            context.fillText(ts, gx, dimensions.height - 2);\n          } else {\n            context.fillText(ts, gx - tsWidth, dimensions.height - 2);\n          }\n        }\n      }\n    }\n\n    // Display title.\n    if (chartOptions.title.text !== '') {\n      context.font = chartOptions.title.fontSize + 'px ' + chartOptions.title.fontFamily;\n      var titleXPos = chartOptions.scrollBackwards ? dimensions.width - context.measureText(chartOptions.title.text).width - 2 : 2;\n      if (chartOptions.title.verticalAlign == 'bottom') {\n        context.textBaseline = 'bottom';\n        var titleYPos = dimensions.height;\n      } else if (chartOptions.title.verticalAlign == 'middle') {\n        context.textBaseline = 'middle';\n        var titleYPos = dimensions.height / 2;\n      } else {\n        context.textBaseline = 'top';\n        var titleYPos = 0;\n      }\n      context.fillStyle = chartOptions.title.fillStyle;\n      context.fillText(chartOptions.title.text, titleXPos, titleYPos);\n    }\n\n    context.restore(); // See .save() above.\n  };\n\n  // Sample timestamp formatting function\n  SmoothieChart.timeFormatter = function(date) {\n    function pad2(number) { return (number < 10 ? '0' : '') + number }\n    return pad2(date.getHours()) + ':' + pad2(date.getMinutes()) + ':' + pad2(date.getSeconds());\n  };\n\n  exports.TimeSeries = TimeSeries;\n  exports.SmoothieChart = SmoothieChart;\n\n})(typeof exports === 'undefined' ? this : exports);\n"
  },
  {
    "path": "examples/start.js.html",
    "content": "/*<!DOCTYPE html>\n<html>\n<head></head>\n<body></body>\n<script>// */\n;(function(){try{\n\tif(typeof window == \"undefined\"){ return }\n\tvar url = location.hash.slice(1);\n\tvar xhr = new XMLHttpRequest();\n\txhr.onreadystatechange = function(e){\n\t\tif(4 != xhr.readyState){ return }\n\t\tvar d = document, doc = d.createElement(\"html\");\n\t\tdoc.innerHTML = xhr.responseText;\n\t\tvar head = doc.getElementsByTagName('head')[0] || doc.appendChild(d.createElement('head'));\n\t\tvar base = doc.getElementsByTagName('base')[0] || head.appendChild(d.createElement('base'));\n\t\tbase.href = url;\n\t\tdocument.write(doc.outerHTML);\n\t};\n\txhr.open('GET', url, true);\n\txhr.send(null);\n}catch(e){document.write(''+e)}}());\n//</script></html>"
  },
  {
    "path": "examples/stats.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link rel=\"stylesheet\" href=\"./style.css\">\n</head>\n<body>\n<style>\n\tbody {\n\t\tfont-family: helvetica;\n\t\tbackground-color: rgb(25,25,25);\n\t\tcolor: rgb(80,135,25) !important;\n\t\ttext-shadow: 1px 1px 20px rgb(80,150,25);\n\t}\n\n  .label {\n    position: absolute;\n    left: 0.5em;\n    top: 1.75em;\n  }\n\n  .input {\n    height: 30px;\n    padding:10px;\n    background-color: rgb(50,50,50);\n    color: rgb(250,50,50);\n  }\n\n  .tall { height: 5em; }\n</style>\n\n<div class=\"center\"><span class=\"shout\" id=\"peers\">0</span> peers <span class=\"shout\" id=\"time\">0</span> min <span class=\"shout\" id=\"nodes\">0</span> nodes <span class=\"shout\" id=\"hours\">0</span> hours <span class=\"shout\" id=\"block\">0</span> block <span class=\"shout\" id=\"stack\">0</span> stack</div>\n\n<input id=\"url\" class=\"center input crack\" placeholder=\"enter peer stats source url\">\n\n<div class=\"center row charts\">\n</div>\n\n<div class=\"model none\">\n\t<div class=\"chart\"><span class=\"label\"></span><canvas class=\"tall row\"></canvas></div>\n</div>\n\n\n<script src=\"./jquery.js\"></script>\n<script src=\"./smoothie.js\" charset=\"utf-8\"></script>\n<script>\n  if(window.location.search){url.value = window.location.search.split(\"?\")[1]}\n  var up, br = 0, bt = 0, tmp;\n  var fetchData = async function(){\n    // fetch the data from server\n    var S = +new Date;\n    var data = await (await fetch(url.value||(location.origin+'/gun/stats.radata'), {method: 'GET',mode: 'cors'})).json();\n    $('#block').text(((br += (+new Date - S)/1000) / ++bt).toFixed(1));\n    data.over = (data.over/1000) || 15;\n\t\t$('#stack').text((data.cpu||'').stack);\n    $('#peers').text(data.peers.count);\n\t\t$('#time').text((data.peers.time / 1000 / 60).toFixed(0));\n\t\t$('#nodes').text(data.node.count);\n\t\t$('#hours').text((data.up.time / 60 / 60).toFixed(1));\n    if(data.up.time === up){ console.log(\"up same as before\") } up = data.up.time;\n\n    ;(async function(){ try{\n      Stats('peers#').line.append(+new Date, data.peers.count);\n      return;\n      Stats('cpu%');\n      tmp = await (await fetch(new Request(location.origin+'/gun/stats.top.radata'), {method: 'GET',mode: 'cors'})).text();\n      tmp = parseFloat((tmp.split('\\n').filter(l => l.indexOf('node')+1)[0]||'').split(/\\s+/).slice(-4)[0]||'0');\n      Stats('cpu%').line.append(+new Date, tmp);\n    }catch(e){console.log(e)}}());\n\n\t\tStats('memory').line.append(+new Date, data.memory.heapTotal / 1024 / 1024);\n    try{ Stats('dam # in/s').line.append(+new Date, Math.round(data.dam.in.count / data.over)); }catch(e){}\n    try{ Stats('dam in MB/s').line.append(+new Date, data.dam.in.done / 1024 / 1024 / data.over); }catch(e){}\n    try{ Stats('dam # out/s').line.append(+new Date, Math.round(data.dam.out.count / data.over)); }catch(e){}\n    try{ Stats('dam out MB/s').line.append(+new Date, data.dam.out.done / 1024 / 1024 / data.over); }catch(e){}\n\n    console.log('data',data);\n\n    //fetch keys in all, these may be dynamically changing\n    //for each key, check if we already have created a time series, if not, create it and add it\n    // to the chart corredsponding to the unit of measure\n    $.each(data.all, function(key, arr){\n    \tvar chart = Stats(key);\n      // get data and append to line\n      // get the arrays inside the key\n      //for each array append the data to the line\n      for(var i in arr) {\n        // append data [timestamp], [data]\n        chart.line.append(arr[i][0], arr[i][1]);\n      }\n    });\n  }\n  //setInterval(fetchData, 15 * 1000);\n  setInterval(fetchData, 5000);\n  fetchData();\n\n  function Stats(key, chart){\n    // if we have already created, get data to append to it.\n  \tif(chart = Stats[key]){\n  \t\treturn chart;\n  \t}\n\t\t// create a new Series for this key\n\t\t// add it into the map\n\t\tchart = Stats[key] = new SmoothieChart({millisPerPixel:500, limitFPS: 16, responsive: true, minValue: 0, grid:{strokeStyle:'rgba(100%,100%,100%,0.2)'},labels:{fontSize:20}, grid: {verticalSections: 0, millisPerLine: 15000 * 4 /*, strokeStyle:'rgb(125, 0, 0)'*/}});\n\t\tchart.line = new TimeSeries();\n\t\tchart.addTimeSeries(chart.line,{ strokeStyle:'rgb('+Math.random()*255+', '+Math.random()*255+','+Math.random()*255+')', lineWidth:5 });\n\t\tchart.canvas = $('.model').find('.chart').clone(true).appendTo('.charts');\n\t\tchart.canvas.find('span').text(key);\n\t\tchart.streamTo(chart.canvas.find('canvas').get(0), 15 * 1000);\n    chart.line.append(0, 0);\n\t\t// check first two characters of key to determine other charts to add this in\n\t\t// tbd later\n\t\treturn chart;\n  }\n  ;(function(){\n  if('https' != (''+location).slice(0,5) && \"localhost\" != location.hostname){\n    $('body').append(\"<button id='https'>click here to try generating https certs</button>\");\n    if(/^(?!0)(?!.*\\.$)((1?\\d?\\d|25[0-5]|2[0-4]\\d)(\\.|$)){4}$/.test(location.hostname)){\n      $('#https').text(\"Link this IP address to a Domain by adding an `A Record` to your DNS settings that point to `\"+ location.hostname +\"` (we recommend the `name/host` be any subdomain you want, like `relay`, but if you want the root domain itself to directly point here use `*`). Then come back here on the domain & click this button to generate HTTPS certificates.\");\n      return;\n    }\n    $('body').append(\"<input id='email' placeholder='email'/>\");\n    $('#https').on('click', function(){\n      $(this).text(\"look at console.log for errors, if none, try https\");\n      var gun = GUN(location.origin + '/gun');\n      if(!$('#email').val()){\n        $(this).text(\"email necessary for certs! Type it in & click here again.\");\n        return;\n      }\n      setTimeout(function(){\n        gun._.opt.mesh.say({dam: 'service', try: 'https', email: $('#email').val(), domain: location.hostname});\n        setTimeout(function(){\n          if(gun._.opt.mesh.near){ return }\n          $('#https').text(\"It might have worked! try HTTPS!\");\n        }, 9000);\n      }, 999);\n    });\n  }\n  }());\n/*\n  Notes to Self about Debugging:\n  1. Read Disks can spike up to 1min, I suspect other operations are blocking it from resolving as fast as it otherwise would.\n  2. JSON parsing/stringifying sometimes way slower than other times, why?\n  3. Looks like RAD lex read is not optimized.\n  4. got prep + got emit = non-RAD problems, compare against read disk & got differentials (should be same).\n  5. Radix map/place ops could be slow?\n  6. SINGLE MESSAGE PROCESS TIME occasionally is huge, should get emailed.\n  7. Watch out for get/put loops times, maybe indicating (5) issues?\n*/\n</script>\n<script src=\"../gun.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "examples/style.css",
    "content": "html, body {\n\tmargin: 0;\n\tpadding: 0;\n\tposition: relative;\n  line-height: 1.5;\n  font-size: 18pt;\n  f-ont-size: max(18pt, 2?vw);\n}\n\ndiv, ul, ol, li, p, span, form, button, input, textarea, img {\n  margin: 0;\n  padding: 0;\n  position: relative;\n  vertical-align: inherit;\n  -webkit-transition: all 0.3s;\n  transition: all 0.3s;\n  box-sizing: border-box;\n  font: inherit;\n}\n\na, button, input, textarea {\n  background: inherit;\n  border: inherit;\n  color: inherit;\n  text-decoration: inherit;\n  outline: none;\n}\ninput:not([type=button]):not([type=submit]), textarea {\n\twidth: 100%;\n}\n\na:focus, button:focus, input[type=button]:focus, input[type=submit]:focus {\n  animation: pulse 2s infinite;\n}\n\nul, li {\n  list-style: none;\n}\n\np {\n  padding: 0;\n}\np + p {\n  padding-top: 0;\n}\n\n[contenteditable=true]:empty:before {\n  content: attr(placeholder);\n}\n::placeholder, .hint {\n  color: inherit;\n  opacity: 0.3;\n}\n\n.model, .none { display: none }\n.hide { \n  opacity: 0;\n  visibility: hidden;\n  transition: all 2s;\n}\n\n.full {\n  width: 100%;\n  min-height: 100vh;\n}\n.max {\n  max-width: 48em;\n}\n.min {\n  min-width: 12em;\n}\n.pad {\n  width: 95%;\n  margin: 5% auto;\n  max-width: 48em;\n  min-width: 12em;\n}\n\n.row {\n  width: 100%;\n}\n.row::after {\n  content: \"\";\n  display: block;\n  clear: both;\n}\n.col {\n  max-width: 24em;\n  min-width: 12em;\n}\n\n.center {\n  text-align: center;\n  vertical-align: middle;\n  margin-left: auto;\n  margin-right: auto;\n}\n.right {\n  float: right;\n  text-align: right;\n}\n.left {\n  float: left;\n  text-align: left;\n}\n.mid { \n  margin-left: auto;\n  margin-right: auto; \n}\n.top {\n  vertical-align: top;\n}\n.low {\n  vertical-align: bottom;\n}\n\n.rim { margin: 1%; }\n.gap {\n  padding: 3%;\n  padding: clamp(0.5em, 3%, 1.5em);\n}\n.stack { line-height: 0; }\n.crack { margin-bottom: 1%; }\n.sit { margin-bottom: 0; }\n\n.focus {\n  margin-left: auto;\n  margin-right: auto;\n  float: none;\n  clear: both;\n}\n\n.leak { overflow: visible; }\n.hold { overflow: hidden; }\n\n.act {\n  /*display: block;*/\n  font-weight: normal;\n  text-decoration: none;\n  -webkit-transition: all 0.3s;\n  transition: all 0.3s;\n  cursor: pointer;\n}\n\n.unit, .symbol {\n  display: inline-block;\n  vertical-align: inherit;\n}\n.sap { border-radius: 0.1em; }\n.jot { border-bottom: 1px dashed #95B2CA; }\n\n.loud {\n  font-size: 150%;\n}\n.shout {\n  font-size: 36pt;\n  font-size: 6.5vmax;\n}\n\n.red { background: #ea3224; }\n.green { background: #33cc33; }\n.blue { background: #4D79D8; }\n.yellow { background: #d3a438; }\n.black { background: black; }\n.white { background: white; }\n\n.shade { background: rgba(0%, 0%, 0%, 0.1); }\n.tint { background: rgba(100%, 100%, 100%, 0.1); }\n\n.redt { color: #ea3224; }\n.greent { color: #33cc33; }\n.bluet { color: #4D79D8; }\n.yellowt { color: #d3a438; }\n.blackt { color: black; }\n.whitet { color: white; }\n\n.hue {\n  background: #4D79D8;\n  -webkit-animation: hue 900s infinite;\n  animation: hue 900s infinite;\n} @keyframes hue {\n  0%   {background-color: #4D79D8;}\n  25%  {background-color: #33cc33;}\n  50%  {background-color: #d3a438;}\n  75%  {background-color: #ea3224;}\n  100% {background-color: #4D79D8;}\n} @-webkit-keyframes hue {\n  0%   {background-color: #4D79D8;}\n  25%  {background-color: #33cc33;}\n  50%  {background-color: #d3a438;}\n  75%  {background-color: #ea3224;}\n  100% {background-color: #4D79D8;}\n}\n\n.huet {\n  color: #4D79D8;\n  -webkit-animation: huet 900s infinite;\n  animation: huet 900s infinite;\n} @keyframes huet {\n  0%   {color: #4D79D8;}\n  25%  {color: #33cc33;}\n  50%  {color: #d3a438;}\n  75%  {color: #ea3224;}\n  100% {color: #4D79D8;}\n} @-webkit-keyframes huet {\n  0%   {color: #4D79D8;}\n  25%  {color: #33cc33;}\n  50%  {color: #d3a438;}\n  75%  {color: #ea3224;}\n  100% {color: #4D79D8;}\n}\n\n.hue2 {\n  background: #ea3224;\n  -webkit-animation: hue2 900s infinite;\n  animation: hue2 900s infinite;\n} @keyframes hue2 {\n  0%\t {background-color: #ea3224;}\n  25%  {background-color: #4D79D8;}\n  50%  {background-color: #33cc33;}\n  75%  {background-color: #d3a438;}\n  100% {background-color: #ea3224;}\n} @-webkit-keyframes hue2 {\n  0%\t {background-color: #ea3224;}\n  25%  {background-color: #4D79D8;}\n  50%  {background-color: #33cc33;}\n  75%  {background-color: #d3a438;}\n  100% {background-color: #ea3224;}\n}\n\n.huet2 {\n  color: #ea3224;\n  -webkit-animation: huet2 900s infinite;\n  animation: huet2 900s infinite;\n} @keyframes huet2 {\n  0%\t {color: #ea3224;}\n  25%  {color: #4D79D8;}\n  50%  {color: #33cc33;}\n  75%  {color: #d3a438;}\n  100% {color: #ea3224;}\n} @-webkit-keyframes huet2 {\n  0%\t {color: #ea3224;}\n  25%  {color: #4D79D8;}\n  50%  {color: #33cc33;}\n  75%  {color: #d3a438;}\n  100% {color: #ea3224;}\n}\n\n.hue3 {\n  background: #33cc33;\n  -webkit-animation: hue3 900s infinite;\n  animation: hue3 900s infinite;\n} @keyframes hue3 {\n  0%\t {background-color: #33cc33;}\n  25%  {background-color: #d3a438;}\n  50%  {background-color: #ea3224;}\n  75%  {background-color: #4D79D8;}\n  100% {background-color: #33cc33;}\n} @-webkit-keyframes hue3 {\n  0%\t {background-color: #33cc33;}\n  25%  {background-color: #d3a438;}\n  50%  {background-color: #ea3224;}\n  75%  {background-color: #4D79D8;}\n  100% {background-color: #33cc33;}\n}\n\n.huet3 {\n  color: #33cc33;\n  -webkit-animation: huet3 900s infinite;\n  animation: huet3 900s infinite;\n} @keyframes huet3 {\n  0%\t {color: #33cc33;}\n  25%  {color: #d3a438;}\n  50%  {color: #ea3224;}\n  75%  {color: #4D79D8;}\n  100% {color: #33cc33;}\n} @-webkit-keyframes huet3 {\n  0%\t {color: #33cc33;}\n  25%  {color: #d3a438;}\n  50%  {color: #ea3224;}\n  75%  {color: #4D79D8;}\n  100% {color: #33cc33;}\n}\n\n.hue4 {\n  background: #d3a438;\n  -webkit-animation: hue4 900s infinite;\n  animation: hue4 900s infinite;\n} @keyframes hue4 {\n  0%   {background-color: #d3a438;}\n  25%  {background-color: #ea3224;}\n  50%  {background-color: #4D79D8;}\n  75%\t {background-color: #33cc33;}\n  100% {background-color: #d3a438;}\n} @-webkit-keyframes hue4 {\n  0%   {background-color: #d3a438;}\n  25%  {background-color: #ea3224;}\n  50%  {background-color: #4D79D8;}\n  75%\t {background-color: #33cc33;}\n  100% {background-color: #d3a438;}\n}\n\n.huet4 {\n  color: #d3a438;\n  -webkit-animation: huet4 900s infinite;\n  animation: huet4 900s infinite;\n} @keyframes huet4 {\n  0%   {color: #d3a438;}\n  25%  {color: #ea3224;}\n  50%  {color: #4D79D8;}\n  75%\t {color: #33cc33;}\n  100% {color: #d3a438;}\n} @-webkit-keyframes huet4 {\n  0%   {color: #d3a438;}\n  25%  {color: #ea3224;}\n  50%  {color: #4D79D8;}\n  75%\t {color: #33cc33;}\n  100% {color: #d3a438;}\n}\n\n.pulse {\n  animation: pulse 2s infinite;\n} @keyframes pulse {\n  0% {opacity: 1;}\n  50% {opacity: 0.5;}\n  100% {opacity: 1;}\n}\n\n.joy {\n  width: 100px;\n  height: 100px;\n  position: absolute;\n  background: url(https://cdn.jsdelivr.net/npm/gun/examples/pop.png) no-repeat;\n  background-position: -2800px 0;\n  pointer-events: none;\n  z-index: 999999999;\n  animation: joy 1s steps(28);\n} @keyframes joy {\n  0% {background-position: 0 0;}\n  100% {background-position: -2800px 0;}\n}\n\n.visually-hidden {\n    border: 0;\n    clip: rect(1px, 1px, 1px, 1px);\n    height: 1px;\n    margin: -1px;\n    overflow: hidden;\n    padding: 0;\n    position: absolute;\n    width: 1px;\n}"
  },
  {
    "path": "examples/todo/index.html",
    "content": "<!DOCTYPE html>\r\n<html>\r\n\r\n<head>\r\n  <title>Think</title>\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\r\n  <link rel=\"stylesheet\" type=\"text/css\" href=\"/style.css\">\r\n  <link href='https://fonts.googleapis.com/css?family=Alegreya+Sans:300italic' rel='stylesheet' type='text/css'>\r\n  <style>\r\n    .thought {\r\n      font-family: 'Alegreya Sans', sans-serif;\r\n    }\r\n\r\n    .thought__heading {\r\n      text-align: center;\r\n      margin-top: 0;\r\n      margin-bottom: 0;\r\n      color: white;\r\n    }\r\n\r\n    .thought__form-container {\r\n      position: fixed;\r\n      display: flex;\r\n      align-items: center;\r\n      justify-content: space-between;\r\n      width: 100%;\r\n      padding: 10px 20px;\r\n      top: 0;\r\n      z-index: 1;\r\n    }\r\n\r\n    .thought__item {\r\n      width: 100%;\r\n      max-width: 900px;\r\n    }\r\n\r\n    .thought__input {\r\n      flex: 1;\r\n      font-family: 'Alegreya Sans', sans-serif;\r\n      font-size: 25px;\r\n      font-weight: 500;\r\n      padding: 15px;\r\n      width: 100%;\r\n      margin-bottom: 10px;\r\n      background-color: white;\r\n      border-radius: 5px;\r\n    }\r\n\r\n    .thought__add {\r\n      width: 30px;\r\n      height: 30px;\r\n      font-family: Tahoma, arial;\r\n      text-align: center;\r\n      border-radius: 50%;\r\n      background-color: white;\r\n      font-size: 25px;\r\n      font-weight: 700;\r\n    }\r\n\r\n    .thought__add:hover::after {\r\n      background-color: rgba(0,0,0,0.2);\r\n    }\r\n\r\n    .thought__add:focus::after {\r\n      background-color: rgba(0,0,0,0.2);\r\n    }\r\n\r\n    .thought__add::after {\r\n      content: '';\r\n      position: absolute;\r\n      width: 100%;\r\n      height: 100%;\r\n      left: 0;\r\n      top: 0;\r\n      border-radius: 50%;\r\n      transition: background-color 0.3s;\r\n      background-color: rgba(0,0,0,0);\r\n    }\r\n\r\n    .thought__list {\r\n      list-style-type: circle;\r\n      display: flex;\r\n      flex-direction: column;\r\n      align-items: center;\r\n      flex: 1;\r\n      overflow-y: auto;\r\n      padding: 90px 20px;\r\n      width: 100%;\r\n      background-color: rgba(0, 0, 0, 0.2);\r\n      min-height: 100vh;\r\n    }\r\n\r\n    @media (max-width: 567px) {\r\n      .thought__heading {\r\n        font-size: 30px;\r\n      }\r\n    }\r\n  </style>\r\n</head>\r\n\r\n<body>\r\n  <div class=\"thought hue page\">\r\n    <div class=\"thought__form-container hue\">\r\n      <h2 id='title' class=\"thought__heading hue\">Add a thought...</h2>\r\n      <button class=\"thought__add say huet\">\r\n        <span aria-hidden=\"true\">+</span>\r\n        <span class=\"visually-hidden\">Add thought</span>\r\n      </button>\r\n    </div>\r\n    <ul class=\"thought__list\">\r\n    </ul>\r\n  </div>\r\n\r\n  <script src=\"/jquery.js\"></script>\r\n  <script src=\"/gun.js\"></script>\r\n  <script>\r\n    // Check out the interactive tutorial\r\n    // for how to build a simplified version\r\n    // of this example: https://scrimba.com/c/cW2Vsa\r\n    var gun = Gun(location.origin + '/gun');\r\n    var think = gun.get('think1/' + location.hash.slice(1));\r\n    var thoughtItemStr = function(id) { return '<li class=\"thought__item\"><label class=\"visually-hidden\" for=\"' + id + '\">Thought</label><input id=\"' + id + '\" class=\"thought__input huet\"><li/>'}\r\n    var typing, throttle;\r\n    $('.thought__add').on('click', function () {\r\n      $(thoughtItemStr('')).prependTo('.thought__list').find('.thought__input').focus();\r\n    });\r\n    $(document).on('keyup', '.thought__input', function () {\r\n      var input = $(this), id = input.attr('id');\r\n      if (!id) {\r\n        input.attr('id', id = String.random());\r\n      }\r\n      typing = id;\r\n      clearTimeout(throttle);\r\n      throttle = setTimeout(function () {\r\n        think.get(id).put(input.val());\r\n        typing = false;\r\n      }, 10);\r\n    });\r\n    think.map().on(function (thought, id) {\r\n      var li = $('#' + id).parent()[0] || $(thoughtItemStr(id)).prependTo('.thought__list');\r\n      if (thought) {\r\n        if (id === typing) { return }\r\n        $(li).find('.thought__input').val(thought);\r\n      } else {\r\n        $(li).hide();\r\n      }\r\n    });\r\n  </script>\r\n  </div>\r\n</body>\r\n"
  },
  {
    "path": "examples/vanilla/screen.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <title>Think</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\n</head>\n\n<body>\n  <video id=\"video\" width=\"100%\"></video>\n  <center>\n    <button id=\"record\">Record</button>\n    <button id=\"play\">Play</button>\n  </center>\n\n  <script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\n\n  <script>\n    const gun = Gun(`${window.location.origin}/gun`)\n    const record = { recorder: null, recording: false }\n\n    const video = document.querySelector('#video')\n    const playButton = document.querySelector('#play')\n    const recordButton = document.querySelector('#record')\n\n    recordButton.addEventListener('click', () => {\n      console.log(record)\n      if (!record.ing) {\n        return record.stream()\n      }\n      recordButton.innerText = 'Record'\n      if (record.ing.stop) { record.ing.stop() }\n      record.ing = false\n    }, false)\n\n    record.stream = () => {\n      navigator.mediaDevices.getDisplayMedia({ video: true }).then(stream => {\n        const chunks = [] // we have a stream, we can record it\n        record.ing = new MediaRecorder(stream)\n        record.ing.ondataavailable = eve => chunks.push(eve.data)\n        record.ing.onstop = () => record.save(new Blob(chunks))\n        record.ing.start()\n        recordButton.innerText = 'End'\n      }, err => { console.log(err) })\n    }\n\n    record.save = data => {\n      record.file = record.file || new FileReader()\n      record.file.readAsDataURL(data)\n      record.file.onloadend = () => {\n        let b64 = record.file.result\n        b64 = `data:video/webm${b64.slice(b64.indexOf(';'))}`\n        gun.get('test').get('screen').put(b64)\n      }\n    }\n\n    playButton.addEventListener('click', () => {\n      if (record.playing) {\n        playButton.innerText = 'Play'\n        video.pause()\n        record.playing = false\n        return\n      }\n\n      playButton.innerText = 'Stop'\n      record.playing = true\n\n      gun.get('test').get('screen').once(data => {\n        if (!data) { return }\n        video.src = data\n        video.play()\n      })\n    }, false)\n  </script>\n</body>\n\n</html>"
  },
  {
    "path": "examples/vanilla/todo.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <title>Think</title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\n</head>\n\n<body>\n  <h1>Thoughts</h1>\n\n  <form id=\"form\">\n    <input id=\"input\">\n    <button>Add</button>\n  </form>\n\n  <ul id=\"parentList\"></ul>\n\n  <script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\n\n  <script>\n    const gun = Gun(`${window.location.origin}/gun`).get('thoughts')\n\n    const parentList = document.getElementById('parentList')\n    const input = document.getElementById('input')\n    const form = document.getElementById('form')\n\n    const dynamicEvent = e => {\n      const target = e.target;\n\n      gun.get(target.id).put(null);\n\n      target.innerHTML = document.getElementById(target.id);\n\n      if (target.innerHTML === ' null' || target.innerHTML === ' ' || target.innerHTML === '') {\n        target.style.display = 'none';\n      } else {\n        target.style.display = 'list-item';\n      }\n    }\n\n    gun.map().on((thought, id) => {\n      parentList.insertAdjacentHTML('beforeend', `<li id =${id}> ${thought}</li>`);\n\n      const links = parentList.getElementsByTagName('li');\n\n      for (const link of links) {\n        if (link.innerHTML === ' null' || link.innerHTML === ' ' || link.innerHTML === '') {\n          link.style.display = 'none';\n        } else {\n          link.style.display = 'list-item';\n        }\n        link.ondblclick = dynamicEvent;\n      }\n    })\n\n    form.addEventListener('submit', e => {\n      e.preventDefault();\n      gun.set(input.value);\n      input.value = '';\n    })\n  </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/vanilla/user.html",
    "content": "<!DOCTYPE html>\n\n<h1>User</h1>\n\n<form id=\"sign\">\n  <input id=\"alias\" placeholder=\"username\">\n  <input id=\"pass\" type=\"password\" placeholder=\"passphrase\">\n  <input id=\"signup\" type=\"button\" value=\"sign up\">\n  <input id=\"signin\" type=\"button\" value=\"sign in\">\n</form>\n\n<ul id=\"list\"></ul>\n\n<form id=\"said\">\n  <input id=\"say\">\n  <input id=\"speak\" type=\"submit\" value=\"speak\">\n</form>\n\n<script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/gun/sea.js\"></script>\n\n<script>\n  const gun = Gun(`${window.location.origin}/gun`)\n  const user = gun.user().recall({ sessionStorage: true })\n\n  const alias = document.querySelector('#alias')\n  const pass = document.querySelector('#pass')\n  const sign = document.querySelector('#sign')\n  const signup = document.querySelector('#signup')\n  const signin = document.querySelector('#signin')\n  const said = document.querySelector('#said')\n  const say = document.querySelector('#say')\n  const ul = document.querySelector('#list')\n\n  function UI (say, id) {\n    const li = document.createElement('li')\n    li.setAttribute('id', id)\n    li.appendChild(document.createTextNode(say))\n    ul.appendChild(li)\n\n    return false\n  }\n\n  signup.addEventListener('click', () => user.create(alias.value, pass.value, () => user.auth(alias.value, pass.value)))\n  signin.addEventListener('click', () => user.auth(alias.value, pass.value))\n\n  said.addEventListener('submit', e => {\n    e.preventDefault()\n    // if(!user.is){ return }\n    user.get('said').set(say.value)\n    said.value = ''\n  })\n\n  gun.on('auth', () => {\n    sign.style.display = 'none'\n    user.get('said').map().on(UI)\n  })\n</script>\n"
  },
  {
    "path": "examples/vanilla/video.html",
    "content": "<!DOCTYPE html>\n\n<video id=\"video\" width=\"100%\" controls autoplay></video>\n<center>\n  <input id=\"pass\" placeholder=\"password\">\n  Record <button class=\"record\">Camera</button> or <button class=\"screen\">Screen</button>\n</center>\n\n<script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/gun/sea.js\"></script>\n\n<script>\n  const peers = [\n    `${window.location.origin}/gun`,\n    'https://gun-us.herokuapp.com/gun',\n    'https://gun-eu.herokuapp.com/gun'\n  ]\n\n  const gun = Gun({ localStorage: true, peers })\n\n  const pass = document.querySelector('#pass')\n  const video = document.querySelector('#video')\n  const camera = document.querySelector('.record')\n  const screen = document.querySelector('.screen')\n\n  gun.get('test').get('video').on(async data => {\n    if (pass.value) { data = await SEA.decrypt(data, pass.value) }\n    video.setAttribute('src', data)\n  })\n\n  function record(type) {\n    function load(media) {\n      const chunks = []\n      record.ing = new MediaRecorder(media)\n      record.ing.ondataavailable = eve => { chunks.push(eve.data) }\n      record.ing.onstop = eve => { record.save(new Blob(chunks)) }\n      record.ing.start()\n    }\n\n    function error(err) { console.log(err) }\n\n    if (type === 'Camera') {\n      navigator.getMedia({ video: true, audio: true }, load, error)\n    }\n    if (type === 'Screen') {\n      navigator.mediaDevices.getDisplayMedia({ video: true, audio: true }).then(load, error)\n    }\n  }\n\n  function act(e) {\n    if (record.ing) {\n      if (record.ing.stop) { record.ing.stop() }\n\n      e.target.textContent = record.type\n      record.ing = false\n      return\n    }\n\n    record(record.type = e.target.textContent)\n    e.target.textContent = 'end'\n  }\n\n  record.save = data => {\n    record.file = record.file || new FileReader()\n    record.file.readAsDataURL(data)\n    record.file.onloadend = async () => {\n      const b64 = record.file.result\n      let b64formated = `data:video/webm${b64.slice(b64.indexOf(';'))}`\n\n      video.setAttribute('src', b64formated)\n\n      if (pass.value) { b64formated = await SEA.encrypt(b64formated, pass.value) }\n      gun.get('test').get('video').put(b64formated)\n    }\n  }\n\n  camera.addEventListener('click', e => act(e))\n  screen.addEventListener('click', e => act(e))\n\n  navigator.getMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia ||\n    navigator.mozGetUserMedia || navigator.msGetUserMedia)\n\n</script>"
  },
  {
    "path": "examples/vue/index.html",
    "content": "<html>\n<head>\n  <title>Gun plugin for Vue</title>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <!-- This example works only with vue 1 -->\n  <script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\"></script>\n  <script src=\"https://unpkg.com/vue@1.0.0/dist/vue.min.js\"></script>\n</head>\n<body>\n  <div id=\"app\">\n    This is example of simple Vue plugin. It works exactly same as the Vue instance data property, but the name is gunData.<br>\n    The cool part is that every property in the gunData is realtime synced via gunDB to every other page viewer!<br>\n    <table>\n      <tr>\n        <td>\n          Vue instance data:\n          <pre v-html=\"prettyJSON($data)\"></pre>\n        </td>\n        <td valign=\"top\" style=\"text-align:right;\">\n          test<br>\n          arr[1]<br>\n          obj.a<br>\n          deepObj.level1.prop<br>\n          deepObj.level1.arr[1]<br>\n        </td>\n        <td valign=\"top\">\n          <input v-model=\"test\"><br>\n          <input v-model=\"arr[1]\"><br>\n          <input v-model=\"obj.a\"><br>\n          <input v-model=\"deepObj.level1.prop\"><br>\n          <input v-model=\"deepObj.level1.arr[1]\"><br>\n          <input v-if=\"obj.newProp_1\" v-model=\"obj.newProp_1\"><br>\n          <br>\n          <button @click=\"addProp()\">Add new prop to obj</button>\n        </td>\n      </tr>\n    </table>\n  </div>\n  <script>\n    Vue.config.productionTip = false;\n    localStorage.clear();\n    var GunData = {\n      install: function (Vue, options) {\n        Vue.$gunData = {\n          gun: Gun(options),\n          arrToGunObj: function (a) {\n            var o = { _isArr: true }, l = a.length;\n            for (var i = 0; i < l; i++) if (a[i] !== undefined) o[i] = a[i];\n            return o;\n          },\n          addGunWatcher: function (keyPath, val, vm) {\n            // console.log('addGunWatcher',keyPath);\n            this.gun.get(vm.$options.$gunRootKey).path(keyPath)\n              .not(function () { this.put(typeof val == 'object' && val.constructor === Array ? this.arrToGunObj(val) : val) })\n              .on(function (gunVal, gunKey) {\n                if (typeof gunVal == 'object') return; /* only do stuff on non objects */\n                var vmPath = vm;\n                for (var i = 0, a = keyPath.split('.'), l = a.length; i < l - 1; i++) vmPath = vmPath[a[i]];\n                if (typeof vmPath[gunKey] == 'undefined') console.log('EIPÄ OO', gunkey);\n                if (vmPath[gunKey] !== gunVal) vm.$set(vmPath, vmPath.constructor === Array ? gunKey * 1 : gunKey, gunVal);\n              }, { change: true });\n          },\n          timeout: {},\n          vueWatcher: {},\n          addVueWatcher: function (keyPath, vm) {\n            // console.log('VUE WATCHER',keyPath,vm.$options.$gunRootKey);\n            this.vueWatcher[keyPath] = vm.$watch(keyPath, function (newVal) {\n              clearTimeout(Vue.$gunData.timeout[vm.$options.$gunRootKey + keyPath]);\n              Vue.$gunData.timeout[vm.$options.$gunRootKey + keyPath] = setTimeout(function () { Vue.$gunData.gun.get(vm.$options.$gunRootKey).path(keyPath).put(newVal) }, 500);\n            });\n          },\n          addWatchers: function (obj, keyPath, vm) {\n            if (keyPath) keyPath += '.';\n            var o = {}, a = obj, ok = Object.keys(a), l = ok.length, k = '', v = '';\n            for (var i = 0; i < l, k = ok[i], v = a[k]; i++) {\n              if (typeof v == 'object') {\n                this.addWatchers(v, keyPath + k, vm);\n              } else {\n                // console.log('add watcher',k,v,keyPath+k);\n                if (!this.vueWatcher[keyPath + k]) {\n                  Vue.$gunData.addVueWatcher(keyPath + k, vm);\n                  Vue.$gunData.addGunWatcher(keyPath + k, v, vm);\n                }\n              }\n            }\n          }\n        }\n        Vue.mixin({\n          data: function () {\n            var o = {}, a = this.$options.gunData;\n            this.$options.$gunRootKey = (a._rootKey || window.location.hostname).replace(/\\./g, '-');\n            delete a._rootKey;\n            for (var k = '', v = '', i = 0, ok = Object.keys(a), l = ok.length; i < l, k = ok[i], v = a[k]; i++) o[k] = v;\n            return o;\n          },\n          created: function () {\n            Vue.$gunData.addWatchers(this.$options.gunData, '', this)\n          }\n        });\n      }\n    }\n\n    /********************** SIMPLE NODE GUN SERVER EXAMPLE FOR BACKEND **********************/\n    // var http = require('http'), Gun = require('gun');\n    // Gun({ web: http.createServer().listen(8765) });\n\n    /********************** MODIFY WITH OUR OWN SERVER ADDRESS **********************/\n    // Vue.use(GunData, 'http://REPLACE.WITH.YOUR.GUN.SERVER:SERVERPORT/gun');\n\n    var inst = new Vue({\n      el: '#app',\n      methods: {\n        addProp() { Vue.set(this.obj, 'newProp_' + Object.keys(this.obj).length, 'qwerty') },\n        // the prettyJSON code is from icebob https://jsfiddle.net/icebob/0mg1v81e/\n        prettyJSON: function (json) {\n          if (json) {\n            json = JSON.stringify(json, undefined, 4);\n            json = json.replace(/&/g, '&').replace(/</g, '<').replace( />/g, '>');\n            return json.replace(/(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g, function (match) {\n              var cls = 'number';\n              if (/^\"/.test(match)) {\n                if (/:$/.test(match)) {\n                  cls = 'key';\n                } else {\n                  cls = 'string';\n                }\n              } else if (/true|false/.test(match)) {\n                cls = 'boolean';\n              } else if (/null/.test(match)) {\n                cls = 'null';\n              }\n              return '<span class=\"' + cls + '\">' + match + '</span>';\n            });\n          }\n        }\n      },\n      gunData: {\n        // _rootKey: 'put-your-gunDB-root-key-here', // DEFAULTS TO HOSTNAME\n        test: 'abc',\n        arr: [1, 2],\n        obj: { a: 1 },\n        deepObj: {\n          level1: {\n            arr: [1, 2],\n            prop: 2\n          }\n        }\n      }\n    });\n  </script>\n  <style>\n    pre {\n      overflow: auto;\n    }\n\n      pre .string {\n        color: #885800;\n      }\n\n      pre .number {\n        color: blue;\n      }\n\n      pre .boolean {\n        color: magenta;\n      }\n\n      pre .null {\n        color: red;\n      }\n\n      pre .key {\n        color: green;\n      }\n  </style>\n</body>\n</html>\n"
  },
  {
    "path": "examples/vue/todo.html",
    "content": "<!doctype html>\n<html>\n\n<head>\n    <title>Todo App: Gun + Vue</title>\n    \n    <script src=\"https://unpkg.com/vue\" type=\"text/javascript\" charset=\"utf-8\"></script>\n    <script src=\"https://cdn.jsdelivr.net/npm/gun/gun.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n    <link href='https://fonts.googleapis.com/css?family=Alegreya+Sans:300italic' rel='stylesheet' type='text/css'>\n    <style>\n\n        body,\n        html {\n            width: 100%;\n            font-family: 'Alegreya Sans', sans-serif;\n        }\n\n        body {\n            font-size: 20px;\n            background-color: rgba(0,0,0,.3);\n        }\n\n        h1,\n        h3,\n        h5 {\n            text-transform: uppercase;\n            font-weight: 600;\n        }\n\n        #app {\n            margin: 0 auto;\n            background-color: #fff;\n            max-width: 500px;\n            padding: 2em;\n        }\n\n        .add-todo {\n            font-size: 1em;\n            border: 1px solid black;\n            padding: .5em .25em;\n        }\n\n        .completed-header,\n        .completed,\n        .completed-time {\n            color: rgba(0,0,0,.3);\n        }\n\n        .completed {\n            text-decoration: line-through;\n        }\n\n        .completed-time {\n            font-size: .8em;\n        }\n    </style>\n</head>\n\n<body>\n\n<div id=\"app\">\n\n    <div class=\"todo-wrapper\">\n        <h1>Todos App</h1>\n\n        <input class=\"add-todo\" type=\"text\" placeholder=\"Add new todo\" v-model=\"newTodo\" @keyup.enter=\"addTodo\">\n\n        <h3>Active</h3>\n\n        <div v-for=\"active in activeTodos\">\n            <label><input type=\"checkbox\" @click.prevent=\"completeTodo(active.key)\"> {{ active.todo.description }}</label>\n        </div>\n\n        <h5 v-show=\"completedTodos.length > 0\" class=\"completed-header\">Completed</h5>\n \n        <div v-for=\"completed in completedTodos\" @click=\"reopenTodo(completed.key)\">\n            <span class=\"completed\">{{ completed.todo.description }}</span>\n            <span class=\"completed-time\">(completed at {{ (new Date(completed.todo.completed)).toUTCString() }})</span>\n        </div>\n    </div>\n\n</div>\n\n</body>\n\n<script>\n\n// Clear out local storage so we can start fresh each time.\nlocalStorage.clear();\n\n\n// No peers for the sake of example,\n// but this could easily be a collaborative \n// todolist by adding a few peers\nvar gun = new Gun();\nvar todos = gun.get('todos');\n\nnew Vue({\n    data: {\n        todos: [],\n        newTodo: \"\"\n    },\n    computed: {\n        activeTodos: function() {\n            return this.todos.filter(function(todo) {\n                return todo.todo.completed === '';\n            });\n        },\n        completedTodos: function() {\n            return this.todos.filter(function(todo) {\n                return todo.todo.completed !== '';\n            });\n        }\n    },\n    methods: {\n        todoUpdated: function(todo, nodeKey) {\n            if (/\\D/.test(nodeKey)) {\n                return;\n            }\n\n            var existingTodoIndex = this.todos.findIndex(function(todo) {\n                return todo.key === nodeKey\n            });\n            var todoToStore = {\n                todo: todo,\n                key: nodeKey\n            };\n            if (existingTodoIndex === -1) {\n                this.todos.push(todoToStore);\n            } else {\n                this.todos.splice(existingTodoIndex, 1, todoToStore);\n            }\n        },\n        addTodo: function() {\n            var newTodo = todos.get(Date.now().toString());\n            newTodo.put({\n                description: this.newTodo,\n                completed: ''\n            });\n            todos.set(newTodo);\n            this.newTodo = \"\";\n        },\n        completeTodo: function(key) {\n            todos.get(key).put({\n                completed: Date.now()\n            });\n        },\n        reopenTodo: function(key) {\n            todos.get(key).put({\n                completed: ''\n            });\n        }\n    },\n    mounted: function() {\n\n        // Subscribe to updates on the todos set\n        todos.map().on(this.todoUpdated.bind(this));\n    }\n}).$mount('#app');\n\n</script>\n\n</html>\n"
  },
  {
    "path": "examples/wave.html",
    "content": "<!DOCTYPE HTML>\n<html>\n  <head>\n    <title>Wave example</title>\n  </head>\n  <body>\n    <button id=\"bPiano\">Piano left</button>\n    <button id=\"bGuitar\">Guitar itched</button>\n    <button id=\"bXylo\">Xylophone slow</button>\n    <button id=\"bAll\">All in one</button>\n\n    <script src=\"../lib/wave.js\"></script>\n    <script>\n      function piano() {\n        wave(':piano:zxcvbn').balance(-1).play()\n      }\n      function guitar() {\n        wave(':guitar:zxcvbn').itch(0.5).play()\n      }\n      function xylo() {\n        wave(':xylophone:zxcvbn').pace(100).play()\n      }\n      function all() {\n        wave(`\n          :pace 400: :itch 0: :balance 0:\n\n          :piano: :balance -1: zxcvbn\n\n          :guitar: :balance 0: :itch 0.5:  zxcvbn\n\n          :xylophone: :itch 0: :pace 100: zxcvbn\n        `).play()\n      }\n      document.querySelector('#bPiano').addEventListener(\"click\", piano)\n      document.querySelector('#bGuitar').addEventListener(\"click\", guitar)\n      document.querySelector('#bXylo').addEventListener(\"click\", xylo)\n      document.querySelector('#bAll').addEventListener(\"click\", all)\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/webpack/.gitignore",
    "content": "package-lock.json\nnode_modules\npublic"
  },
  {
    "path": "examples/webpack/package.json",
    "content": "{\n  \"name\": \"webpack\",\n  \"version\": \"1.0.0\",\n  \"description\": \"webpack build example\",\n  \"scripts\": {\n    \"build\": \"webpack --devtool source-map --config webpack.config.js\",\n    \"prepare\": \"npm run build\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"gun\": \"github:amark/gun\",\n    \"html-webpack-plugin\": \"^5.5.0\",\n    \"webpack\": \"^5.72.1\",\n    \"webpack-cli\": \"^4.9.2\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/src/app.js",
    "content": "define(function(require, exports, module) {\n\n    var Gun = require(\"gun\");\n\n    var gun = new Gun();\n\n    gun.get(\"hello\").get(\"world\").put(\"from gun\").on((data, key) => console.log(data, key));\n\n});"
  },
  {
    "path": "examples/webpack/src/index.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head></head>\n    <body></body>\n</html>"
  },
  {
    "path": "examples/webpack/webpack.config.js",
    "content": "const path = require('path');\nconst HtmlWebpackPlugin = require('html-webpack-plugin');\n\nlet plugins = [];\n\nplugins.push(new HtmlWebpackPlugin({\n    filename: './index.html',\n    template: './src/index.html',\n    inject: true,\n    minify: false,\n    hash: false,\n    cache: false,\n    showErrors: false\n}));\n\nconsole.log(\"webpack config loaded\");\n\nmodule.exports = {\n\n    mode: \"development\",\n    \n    // stats: 'minimal',\n    stats: 'normal',\n    // stats: 'verbose',\n\n    entry: [path.resolve(__dirname, './src/app.js')],\n    \n    output: {\n        path: path.resolve(__dirname, './public'),\n        clean: true,\n        filename: './app.js'\n    },\n    \n    plugins: plugins\n};\n"
  },
  {
    "path": "examples/where/index.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Where</title>\n    <meta content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" name=\"viewport\" />\n\t\t<meta charset=\"utf-8\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/leaflet@1.0.3/dist/leaflet.css\"/>\n    <script src=\"https://cdn.jsdelivr.net/npm/leaflet@1.0.3/dist/leaflet.js\"></script>\n  </head>\n  <body>\n    <div id=\"map\"></div>\n    <a id=\"share\" class=\"hide\"><div class=\"stick button\">Share</div></a>\n    <div id=\"link\" class=\"hide\">\n      <p>Copy and Paste this URL to your friends to share your location:</p>\n      <center>\n        <p id=\"follow\">Location sharing not available!</p>\n      </center>\n      <p><b>Note</b>: Location may not sync when your device's screen is off or the tab is out of focus. You'd need to install this as an app for that to work.</p>\n      <center>\n        <a id=\"close\"><div class=\"button\">Close</div></a>\n      </center>\n    </div>\n    <textarea style=\"display: none; position: fixed; top: 0; left: 0; width: 100%; height: 5em;\" id=\"debug\"></textarea>\n    <style>\n      html, body, #map {\n        margin: 0;\n        padding: 0;\n        width: 100%;\n        height: 100%;\n        font-family: Arial;\n        font-size: 16pt;\n        z-index: 1;\n      }\n      .stick {\n        position: absolute;\n        bottom: 1em;\n        right: 1em;\n      }\n      .button {\n        display: inline-block;\n        padding: 1em;\n        opacity: .5;\n        background: blue;\n        color: white;\n        z-index: 7;\n        transition: .25s all;\n      }\n      .button:hover {\n        opacity: 1;\n      }\n      .hide {\n        display: none;\n      }\n      #link {\n        position: absolute;\n        padding: 1em;\n        top: 2em;\n        left: 2em;\n        right: 2em;\n        bottom: 2em;\n        background: white;\n        overflow: scroll;\n        z-index: 9;\n      }\n      #follow {\n        background: #EEE;\n        padding: .5em;\n        word-wrap: break-word;\n      }\n    </style>\n    <script src=\"/jquery.js\"></script>\n    <script src=\"/gun.js\"></script>\n    <script>\n      function Where(opt, cb){\n        // a small wrapper around Leaflet for map tracking.\n        var where = {};\n        where.opt = opt || {};\n        where.opt.zoom = where.opt.zoom || {};\n        where.opt.err = where.opt.err || function(){};\n\n        where.map = L.map('map', { zoom: where.opt.zoom.level });\n\n        where.opt.tile = where.opt.tile || L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {\n          maxZoom: where.opt.zoom.max,\n          minZoom: where.opt.zoom.min,\n          detectRetina: true,\n          attribution: '&copy; <a href=\"http://osm.org/copyright\">OpenStreetMap</a> contributors'\n        });\n        where.map.addLayer(where.opt.tile);\n\n        where.opt.zoom.ing = where.opt.zoom.ing || function(){\n          where.opt.zoom.level = where.map.getZoom();\n        }\n        where.map.on('zoomstart', where.opt.zoom.ing, where.opt.err);\n        where.map.on('zoomend', where.opt.zoom.ing, where.opt.err);\n        where.map.on('zoomlevelschange', where.opt.zoom.ing, where.opt.err);\n\n        where.update = function(latlng){\n          if((+new Date) - where.update.last < 400){\n            clearTimeout(where.update.to);\n            where.update.to = setTimeout(function(){\n              where.update(latlng);\n            });\n            return;\n          }\n          where.map.setView(latlng, where.opt.zoom.level, {animate: true});\n          where.marker = where.marker || L.marker().setLatLng(latlng).addTo(where.map);\n          where.marker.setLatLng(latlng).update();\n          where.update.last = (+new Date);\n        }\n\n        if(where.opt.track){\n          where.map.on('locationfound', function(pos){\n            where.update(pos.latlng);\n            where.opt.track(pos);\n          });\n\n          where.map.locate({\n            setView: true,\n            zoom: where.opt.zoom.level,\n            watch: where.opt.continuous || true,\n            timeout: where.opt.timeout || 10000,\n            maximumAge: where.opt.maximumAge || 0,\n            enableHighAccuracy: where.opt.enableHighAccuracy || false\n          });\n        }\n\n        return where;\n      }\n    </script>\n    <script>\n      ;(function(){\n        // the actual GPS tracking app!\n        var gun = Gun(location.origin + '/gun');\n        var gps = {};\n        gps.opt = {\n          continuous: true, // get location just once uses `getCurrentPosition()` while continuously uses `watchPosition()`\n          enableHighAccuracy: true, // HighAccuracy uses more resources, https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions\n          timeout: 5000, // have this long to get data before erring.\n          maximumAge: 0, // set to 0 to actually track.\n          zoom: {max: 18, level: 13, min: 12}\n        }\n        function start(){\n          gps.follow = (window.location.hash || '').slice(1);\n          if(gps.follow){\n            gps.where = gps.where || Where(gps.opt);\n            gps.ref = gun.get('gps/' + gps.follow);\n            gps.ref.on(function(latlng){\n              //$('#debug').value = 'track ' + JSON.stringify(latlng);\n              gps.where.update(latlng);\n            });\n            $('#share').addClass(\"hide\");\n          } else {\n            document.cookie = 'gps=' + (gps.track = (document.cookie.match(/gps\\=(.*?)(\\&|$|\\;)/i)||[])[1] || Gun.text.random(5)); // trick with cookies!\n            gps.ref = gun.get('gps/' + gps.track);\n            gps.opt.track = function(pos){\n              pos = pos.latlng;\n              if(gps.follow\n              || Gun.time.is() - gps.when < 1000\n              || gps.last && gps.last.lat == pos.lat && gps.last.lng == pos.lng){\n                return; // throttle!\n              }\n              gps.when = Gun.time.is();\n              gps.ref.put(gps.last = pos);\n              //$('#debug').value = JSON.stringify(gps.last);\n            }\n            gps.where = gps.where || Where(gps.opt);\n            $('#follow').text((\"where.gunDB.io/\" || (location.origin + location.pathname)) + '#' + gps.track);\n            $('#share').removeClass(\"hide\");\n            $('#share').on('click', function(){\n              $('#link').toggleClass(\"hide\");\n            });\n            $('#close').on('click', function(){\n              $('#link').toggleClass(\"hide\");\n            });\n          }\n        }\n        start();\n        window.onhashchange = start;\n      }());\n    </script>\n  </body>\n</html>"
  },
  {
    "path": "gun.d.ts",
    "content": "import { IGun, LEX } from './types/gun';\r\n\r\ndeclare const Gun: IGun;\r\nexport default Gun;\r\n\r\nimport {} from './types/gun/IGun';\r\ndeclare module './types/gun/IGun' {\r\n  export interface IGun {\r\n    window: Window\r\n  }\r\n}\r\n\r\ndeclare global {\r\n  interface Window {\r\n    Gun: IGun;\r\n    GUN: IGun;\r\n  }\r\n\r\n  interface StringConstructor {\r\n    match(t: string, o: LEX | string): boolean;\r\n    random(length?: number, alphabet?: string): string;\r\n  }\r\n}\r\n"
  },
  {
    "path": "gun.js",
    "content": ";(function(){\n\n  /* UNBUILD */\n  function USE(arg, req){\n    return req? require(arg) : arg.slice? USE[R(arg)] : function(mod, path){\n      arg(mod = {exports: {}});\n      USE[R(path)] = mod.exports;\n    }\n    function R(p){\n      return p.split('/').slice(-1).toString().replace('.js','');\n    }\n  }\n  if(typeof module !== \"undefined\"){ var MODULE = module }\n  /* UNBUILD */\n\n\t;USE(function(module){\n\t\t// Shim for generic javascript utilities.\n\t\tString.random = function(l, c){\n\t\t\tvar s = '';\n\t\t\tl = l || 24; // you are not going to make a 0 length random number, so no need to check type\n\t\t\tc = c || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz';\n\t\t\twhile(l-- > 0){ s += c.charAt(Math.floor(Math.random() * c.length)) }\n\t\t\treturn s;\n\t\t}\n\t\tString.match = function(t, o){ var tmp, u;\n\t\t\tif('string' !== typeof t){ return false }\n\t\t\tif('string' == typeof o){ o = {'=': o} }\n\t\t\to = o || {};\n\t\t\ttmp = (o['='] || o['*'] || o['>'] || o['<']);\n\t\t\tif(t === tmp){ return true }\n\t\t\tif(u !== o['=']){ return false }\n\t\t\ttmp = (o['*'] || o['>']);\n\t\t\tif(t.slice(0, (tmp||'').length) === tmp){ return true }\n\t\t\tif(u !== o['*']){ return false }\n\t\t\tif(u !== o['>'] && u !== o['<']){\n\t\t\t\treturn (t >= o['>'] && t <= o['<'])? true : false;\n\t\t\t}\n\t\t\tif(u !== o['>'] && t >= o['>']){ return true }\n\t\t\tif(u !== o['<'] && t <= o['<']){ return true }\n\t\t\treturn false;\n\t\t}\n\t\tString.hash = function(s, c){ // via SO\n\t\t\tif(typeof s !== 'string'){ return }\n\t    c = c || 0; // CPU schedule hashing by\n\t    if(!s.length){ return c }\n\t    for(var i=0,l=s.length,n; i<l; ++i){\n\t      n = s.charCodeAt(i);\n\t      c = ((c<<5)-c)+n;\n\t      c |= 0;\n\t    }\n\t    return c;\n\t  }\n\t\tvar has = Object.prototype.hasOwnProperty;\n\t\tObject.plain = function(o){ return o? (o instanceof Object && o.constructor === Object) || Object.prototype.toString.call(o).match(/^\\[object (\\w+)\\]$/)[1] === 'Object' : false }\n\t\tObject.empty = function(o, n){\n\t\t\tfor(var k in o){ if(has.call(o, k) && (!n || -1==n.indexOf(k))){ return false } }\n\t\t\treturn true;\n\t\t}\n\t\tObject.keys = Object.keys || function(o){\n\t\t\tvar l = [];\n\t\t\tfor(var k in o){ if(has.call(o, k)){ l.push(k) } }\n\t\t\treturn l;\n\t\t}\n\t\t;(function(){\n\t\t\tvar u, sT = setTimeout, l = 0, c = 0\n\t\t\t, sI = (typeof setImmediate !== ''+u && setImmediate) || (function(c,f){\n\t\t\t\tif(typeof MessageChannel == ''+u){ return sT }\n\t\t\t\t(c = new MessageChannel()).port1.onmessage = function(e){ ''==e.data && f() }\n\t\t\t\treturn function(q){ f=q;c.port2.postMessage('') }\n\t\t\t}()), check = sT.check = sT.check || (typeof performance !== ''+u && performance)\n\t\t\t|| {now: function(){ return +new Date }};\n\t\t\tsT.hold = sT.hold || 9; // half a frame benchmarks faster than < 1ms?\n\t\t\tsT.poll = sT.poll || function(f){\n\t\t\t\tif((sT.hold >= (check.now() - l)) && c++ < 3333){ f(); return }\n\t\t\t\tsI(function(){ l = check.now(); f() },c=0)\n\t\t\t}\n\t\t}());\n\t\t;(function(){ // Too many polls block, this \"threads\" them in turns over a single thread in time.\n\t\t\tvar sT = setTimeout, t = sT.turn = sT.turn || function(f){ 1 == s.push(f) && p(T) }\n\t\t\t, s = t.s = [], p = sT.poll, i = 0, f, T = function(){\n\t\t\t\tif(f = s[i++]){ f() }\n\t\t\t\tif(i == s.length || 99 == i){\n\t\t\t\t\ts = t.s = s.slice(i);\n\t\t\t\t\ti = 0;\n\t\t\t\t}\n\t\t\t\tif(s.length){ p(T) }\n\t\t\t}\n\t\t}());\n\t\t;(function(){\n\t\t\tvar u, sT = setTimeout, T = sT.turn;\n\t\t\t(sT.each = sT.each || function(l,f,e,S){ S = S || 9; (function t(s,L,r){\n\t\t\t  if(L = (s = (l||[]).splice(0,S)).length){\n\t\t\t  \tfor(var i = 0; i < L; i++){\n\t\t\t  \t\tif(u !== (r = f(s[i]))){ break }\n\t\t\t  \t}\n\t\t\t  \tif(u === r){ T(t); return }\n\t\t\t  } e && e(r);\n\t\t\t}())})();\n\t\t}());\n\t})(USE, './shim');\n\n\t;USE(function(module){\n\t\t// On event emitter generic javascript utility.\n\t\tmodule.exports = function onto(tag, arg, as){\n\t\t\tif(!tag){ return {to: onto} }\n\t\t\tvar u, f = 'function' == typeof arg, tag = (this.tag || (this.tag = {}))[tag] || f && (\n\t\t\t\tthis.tag[tag] = {tag: tag, to: onto._ = { next: function(arg){ var tmp;\n\t\t\t\t\tif(tmp = this.to){ tmp.next(arg) }\n\t\t\t}}});\n\t\t\tif(f){\n\t\t\t\tvar be = {\n\t\t\t\t\toff: onto.off ||\n\t\t\t\t\t(onto.off = function(){\n\t\t\t\t\t\tif(this.next === onto._.next){ return !0 }\n\t\t\t\t\t\tif(this === this.the.last){\n\t\t\t\t\t\t\tthis.the.last = this.back;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.to.back = this.back;\n\t\t\t\t\t\tthis.next = onto._.next;\n\t\t\t\t\t\tthis.back.to = this.to;\n\t\t\t\t\t\tif(this.the.last === this.the){\n\t\t\t\t\t\t\tdelete this.on.tag[this.the.tag];\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tto: onto._,\n\t\t\t\t\tnext: arg,\n\t\t\t\t\tthe: tag,\n\t\t\t\t\ton: this,\n\t\t\t\t\tas: as,\n\t\t\t\t};\n\t\t\t\t(be.back = tag.last || tag).to = be;\n\t\t\t\treturn tag.last = be;\n\t\t\t}\n\t\t\tif((tag = tag.to) && u !== arg){ tag.next(arg) }\n\t\t\treturn tag;\n\t\t};\n\t})(USE, './onto');\n\n\t;USE(function(module){\n\t\t// TODO: BUG! Unbuild will make these globals... CHANGE unbuild to wrap files in a function.\n\t\t// Book is a replacement for JS objects, maps, dictionaries.\n\t\tvar sT = setTimeout, B = sT.Book || (sT.Book = function(text){\n\t\t\tvar b = function book(word, is){\n\t\t\t\tvar has = b.all[word], p;\n\t\t\t\tif(is === undefined){ return (has && has.is) || b.get(has || word) }\n\t\t\t\tif(has){\n\t\t\t\t\tif(p = has.page){\n\t\t\t\t\t\tp.size += size(is) - size(has.is);\n\t\t\t\t\t\tp.text = '';\n\t\t\t\t\t}\n\t\t\t\t\thas.text = '';\n\t\t\t\t\thas.is = is;\n\t\t\t\t\treturn b;\n\t\t\t\t}\n\t\t\t\t//b.all[word] = {is: word}; return b;\n\t\t\t\treturn b.set(word, is);\n\t\t\t};\n\t\t\t// TODO: if from text, preserve the separator symbol.\n\t\t\tb.list = [{from: text, size: (text||'').length, substring: sub, toString: to, book: b, get: b, read: list}];\n\t\t\tb.page = page;\n\t\t\tb.set = set;\n\t\t\tb.get = get;\n\t\t\tb.all = {};\n\t\t\treturn b;\n\t\t}), PAGE = 2**12;\n\n\t\tfunction page(word){\n\t\t\tvar b = this, l = b.list, i = spot(word, l, b.parse), p = l[i];\n\t\t\tif('string' == typeof p){ l[i] = p = {size: -1, first: b.parse? b.parse(p) : p, substring: sub, toString: to, book: b, get: b, read: list} } // TODO: test, how do we arrive at this condition again?\n\t\t\t//p.i = i;\n\t\t\treturn p;\n\t\t\t// TODO: BUG! What if we get the page, it turns out to be too big & split, we must then RE get the page!\n\t\t}\n\t\tfunction get(word){\n\t\t\tif(!word){ return }\n\t\t\tif(undefined !== word.is){ return word.is } // JS falsey values!\n\t\t\tvar b = this, has = b.all[word];\n\t\t\tif(has){ return has.is }\n\t\t\t// get does an exact match, so we would have found it already, unless parseless page:\n\t\t\tvar page = b.page(word), l, has, a, i;\n\t\t\tif(!page || !page.from){ return } // no parseless data\n\t\t\treturn got(word, page);\n\t\t}\n\t\tfunction got(word, page){\n\t\t\tvar b = page.book, l, has, a, i;\n\t\t\tif(l = from(page)){ has = l[got.i = i = spot(word, l, B.decode)]; } // TODO: POTENTIAL BUG! This assumes that each word on a page uses the same serializer/formatter/structure. // TOOD: BUG!!! Not actually, but if we want to do non-exact radix-like closest-word lookups on a page, we need to check limbo & potentially sort first.\n\t\t\t// parseless may return -1 from actual value, so we may need to test both. // TODO: Double check? I think this is correct.\n\t\t\tif(has && word == has.word){ return (b.all[word] = has).is }\n\t\t\tif('string' != typeof has){ has = l[got.i = i+=1] }\n\t\t\tif(has && word == has.word){ return (b.all[word] = has).is }\n\t\t\ta = slot(has) // Escape!\n\t\t\tif(word != B.decode(a[0])){\n\t\t\t\thas = l[got.i = i+=1]; // edge case bug?\n\t\t\t\ta = slot(has); // edge case bug?\n\t\t\t\tif(word != B.decode(a[0])){ return }\n\t\t\t}\n\t\t\thas = l[i] = b.all[word] = {word: ''+word, is: B.decode(a[1]), page: page, substring: subt, toString: tot}; // TODO: convert to a JS value!!! Maybe index! TODO: BUG word needs a page!!!! TODO: Check for other types!!!\n\t\t\treturn has.is;\n\t\t}\n\n\t\tfunction spot(word, sorted, parse){ parse = parse || spot.no || (spot.no = function(t){ return t }); // TODO: BUG???? Why is there substring()||0 ? // TODO: PERF!!! .toString() is +33% faster, can we combine it with the export?\n\t\t\tvar L = sorted, min = 0, page, found, l = (word=''+word).length, max = L.length, i = max/2;\n\t\t\twhile(((word < (page = (parse(L[i=i>>0])||'').substring())) || ((parse(L[i+1])||'').substring() <= word)) && i != min){ // L[i] <= word < L[i+1]\n\t\t\t\ti += (page <= word)? (max - (min = i))/2 : -((max = i) - min)/2;\n\t\t\t}\n\t\t\treturn i;\n\t\t}\n\n\t\tfunction from(a, t, l){\n\t\t\tif('string' != typeof a.from){ return a.from }\n\t\t\t//(l = a.from = (t = a.from||'').substring(1, t.length-1).split(t[0])); // slot\n\t\t\t(l = a.from = slot(t = t||a.from||''));\n\t\t\treturn l;\n\t\t}\n\t\tfunction list(each){ each = each || function(x){return x} \n\t\t\tvar i = 0, l = sort(this), w, r = [], p = this.book.parse || function(){};\n\t\t\t//while(w = l[i++]){ r.push(each(slot(w)[1], p(w)||w, this)) }\n\t\t\twhile(w = l[i++]){ r.push(each(this.get(w = w.word||p(w)||w), w, this)) } // TODO: BUG! PERF?\n\t\t\treturn r;\n\t\t}\n\n\t\tfunction set(word, is){\n\t\t\t// TODO: Perf on random write is decent, but short keys or seq seems significantly slower.\n\t\t\tvar b = this, has = b.all[word];\n\t\t\tif(has){ return b(word, is) } // updates to in-memory items will always match exactly.\n\t\t\tvar page = b.page(word=''+word), tmp; // before we assume this is an insert tho, we need to check\n\t\t\tif(page && page.from){ // if it could be an update to an existing word from parseless.\n\t\t\t\tb.get(word);\n\t\t\t\tif(b.all[word]){ return b(word, is) }\n\t\t\t}\n\t\t\t// MUST be an insert:\n\t\t\thas = b.all[word] = {word: word, is: is, page: page, substring: subt, toString: tot};\n\t\t\tpage.first = (page.first < word)? page.first : word;\n\t\t\tif(!page.limbo){ (page.limbo = []) }\n\t\t\tpage.limbo.push(has);\n\t\t\tb(word, is);\n\t\t\tpage.size += size(word) + size(is);\n\t\t\tif((b.PAGE || PAGE) < page.size){ split(page, b) }\n\t\t\treturn b;\n\t\t}\n\n\t\tfunction split(p, b){ // TODO: use closest hash instead of half.\n\t\t\t//console.time();\n\t\t\t//var S = performance.now();\n\t\t\tvar L = sort(p), l = L.length, i = l/2 >> 0, j = i, half = L[j], tmp;\n\t\t\t//console.timeEnd();\n\t\t\tvar next = {first: half.substring(), size: 0, substring: sub, toString: to, book: b, get: b, read: list}, f = next.from = [];\n\t\t\twhile(tmp = L[i++]){\n\t\t\t\tf.push(tmp);\n\t\t\t\tnext.size += (tmp.is||'').length||1;\n\t\t\t\ttmp.page = next;\n\t\t\t}\n\t\t\tp.from = p.from.slice(0, j);\n\t\t\tp.size -= next.size;\n\t\t\tb.list.splice(spot(next.first, b.list)+1, 0, next); // TODO: BUG! Make sure next.first is decoded text. // TODO: BUG! spot may need parse too?\n\t\t\t//console.timeEnd();\n\t\t\tif(b.split){ b.split(next, p) }\n\t\t\t//console.log(S = (performance.now() - S), 'split');\n\t\t\t//console.BIG = console.BIG > S? console.BIG : S;\n\t\t}\n\n\t\tfunction slot(t){ return heal((t=t||'').substring(1, t.length-1).split(t[0]), t[0]) } B.slot = slot; // TODO: check first=last & pass `s`.\n\t\tfunction heal(l, s){ var i, e;\n\t\t\tif(0 > (i = l.indexOf(''))){ return l } // ~700M ops/sec on 4KB of Math.random()s, even faster if escape does exist.\n\t\t\tif('' == l[0] && 1 == l.length){ return [] } // annoying edge cases! how much does this slow us down?\n\t\t\t//if((c=i+2+parseInt(l[i+1])) != c){ return [] } // maybe still faster than below?\n\t\t\tif((e=i+2+parseInt((e=l[i+1]).substring(0, e.indexOf('\"'))||e)) != e){ return [] } // NaN check in JS is weird.\n\t\t\tl[i] = l.slice(i, e).join(s||'|'); // rejoin the escaped value\n\t\t\treturn l.slice(0,i+1).concat(heal(l.slice(e), s)); // merge left with checked right.\n\t\t}\n\n\t\tfunction size(t){ return (t||'').length||1 } // bits/numbers less size? Bug or feature?\n\t\tfunction subt(i,j){ return this.word }\n\t\t//function tot(){ return this.text = this.text || \"'\"+(this.word)+\"'\"+(this.is)+\"'\" }\n\t\tfunction tot(){ var tmp = {};\n\t\t\t//if((tmp = this.page) && tmp.saving){ delete tmp.book.all[this.word]; } // TODO: BUG! Book can't know about RAD, this was from RAD, so this MIGHT be correct but we need to refactor. Make sure to add tests that will re-trigger this.\n\t\t\treturn this.text = this.text || \":\"+B.encode(this.word)+\":\"+B.encode(this.is)+\":\";\n\t\t\ttmp[this.word] = this.is;\n\t\t\treturn this.text = this.text || B.encode(tmp,'|',':').slice(1,-1);\n\t\t\t//return this.text = this.text || \"'\"+(this.word)+\"'\"+(this.is)+\"'\";\n\t\t}\n\t\tfunction sub(i,j){ return (this.first||this.word||B.decode((from(this)||'')[0]||'')).substring(i,j) }\n\t\tfunction to(){ return this.text = this.text || text(this) }\n\t\tfunction text(p){ // PERF: read->[*] : text->\"*\" no edit waste 1 time perf.\n\t\t\tif(p.limbo){ sort(p) } // TODO: BUG? Empty page meaning? undef, '', '||'?\n\t\t\treturn ('string' == typeof p.from)? p.from : '|'+(p.from||[]).join('|')+'|';\n\t\t}\n\n\t\tfunction sort(p, l){\n\t\t\tvar f = p.from = ('string' == typeof p.from)? slot(p.from) : p.from||[];\n\t\t\tif(!(l = l || p.limbo)){ return f }\n\t\t\treturn mix(p).sort(function(a,b){\n\t\t\t\treturn (a.word||B.decode(''+a)) < (b.word||B.decode(''+b))? -1:1;\n\t\t\t});\n\t\t}\n\t\tfunction mix(p, l){ // TODO: IMPROVE PERFORMANCE!!!! l[j] = i is 5X+ faster than .push(\n\t\t\tl = l || p.limbo || []; p.limbo = null;\n\t\t\tvar j = 0, i, f = p.from;\n\t\t\twhile(i = l[j++]){\n\t\t\t\tif(got(i.word, p)){\n\t\t\t\t\tf[got.i] = i; // TODO: Trick: allow for a GUN'S HAM CRDT hook here.\n\t\t\t\t} else {\n\t\t\t\t\tf.push(i); \n\t\t\t\t}\n\t\t\t}\n\t\t\treturn f;\n\t\t}\n\n\t\tB.encode = function(d, s, u){ s = s || \"|\"; u = u || String.fromCharCode(32);\n\t\t\tswitch(typeof d){\n\t\t\t\tcase 'string': // text\n\t\t\t\t\tvar i = d.indexOf(s), c = 0;\n\t\t\t\t\twhile(i != -1){ c++; i = d.indexOf(s, i+1) }\n\t\t\t\t\treturn (c?s+c:'')+ '\"' + d;\n\t\t\t\tcase 'number': return (d < 0)? ''+d : '+'+d;\n\t\t\t\tcase 'boolean': return d? '+' : '-';\n\t\t\t\tcase 'object': if(!d){ return ' ' } // TODO: BUG!!! Nested objects don't slot correctly\n\t\t\t\t\tvar l = Object.keys(d).sort(), i = 0, t = s, k, v;\n\t\t\t\t\twhile(k = l[i++]){ t += u+B.encode(k,s,u)+u+B.encode(d[k],s,u)+u+s }\n\t\t\t\t\treturn t;\n\t\t\t}\n\t\t}\n\t\tB.decode = function(t, s){ s = s || \"|\";\n\t\t\tif('string' != typeof t){ return }\n\t\t\tswitch(t){ case ' ': return null; case '-': return false; case '+': return true; }\n\t\t\tswitch(t[0]){\n\t\t\t\tcase '-': case '+': return parseFloat(t);\n\t\t\t\tcase '\"': return t.slice(1);\n\t\t\t}\n\t\t\treturn t.slice(t.indexOf('\"')+1);\n\t\t}\n\n\t\tB.hash = function(s, c){ // via SO\n\t\t\tif(typeof s !== 'string'){ return }\n\t\t  c = c || 0; // CPU schedule hashing by\n\t\t  if(!s.length){ return c }\n\t\t  for(var i=0,l=s.length,n; i<l; ++i){\n\t\t    n = s.charCodeAt(i);\n\t\t    c = ((c<<5)-c)+n;\n\t\t    c |= 0;\n\t\t  }\n\t\t  return c;\n\t\t}\n\n\t\tfunction record(key, val){ return key+B.encode(val)+\"%\"+key.length }\n\t\tfunction decord(t){\n\t\t\tvar o = {}, i = t.lastIndexOf(\"%\"), c = parseFloat(t.slice(i+1));\n\t\t\to[t.slice(0,c)] = B.decode(t.slice(c,i));\n\t\t\treturn o;\n\t\t}\n\n\t\ttry{module.exports=B}catch(e){}\n\t})(USE, './book');\n\n\t;USE(function(module){\n\t\t// Valid values are a subset of JSON: null, binary, number (!Infinity), text,\n\t\t// or a soul relation. Arrays need special algorithms to handle concurrency,\n\t\t// so they are not supported directly. Use an extension that supports them if\n\t\t// needed but research their problems first.\n\t\tmodule.exports = function(v){\n\t\t  // \"deletes\", nulling out keys.\n\t\t  return v === null ||\n\t\t\t\"string\" === typeof v ||\n\t\t\t\"boolean\" === typeof v ||\n\t\t\t// we want +/- Infinity to be, but JSON does not support it, sad face.\n\t\t\t// can you guess what v === v checks for? ;)\n\t\t\t(\"number\" === typeof v && v != Infinity && v != -Infinity && v === v) ||\n\t\t\t(!!v && \"string\" == typeof v[\"#\"] && Object.keys(v).length === 1 && v[\"#\"]);\n\t\t}\n\t})(USE, './valid');\n\n\t;USE(function(module){\n\t\tUSE('./shim');\n\t\tfunction State(){\n\t\t\tvar t = +new Date;\n\t\t\tif(last < t){\n\t\t\t\treturn N = 0, last = t + State.drift;\n\t\t\t}\n\t\t\treturn last = t + ((N += 1) / D) + State.drift;\n\t\t}\n\t\tState.drift = 0;\n\t\tvar NI = -Infinity, N = 0, D = 999, last = NI, u; // WARNING! In the future, on machines that are D times faster than 2016AD machines, you will want to increase D by another several orders of magnitude so the processing speed never out paces the decimal resolution (increasing an integer effects the state accuracy).\n\t\tState.is = function(n, k, o){ // convenience function to get the state on a key on a node and return it.\n\t\t\tvar tmp = (k && n && n._ && n._['>']) || o;\n\t\t\tif(!tmp){ return }\n\t\t\treturn ('number' == typeof (tmp = tmp[k]))? tmp : NI;\n\t\t}\n\t\tState.ify = function(n, k, s, v, soul){ // put a key's state on a node.\n\t\t\t(n = n || {})._ = n._ || {}; // safety check or init.\n\t\t\tif(soul){ n._['#'] = soul } // set a soul if specified.\n\t\t\tvar tmp = n._['>'] || (n._['>'] = {}); // grab the states data.\n\t\t\tif(u !== k && k !== '_'){\n\t\t\t\tif('number' == typeof s){ tmp[k] = s } // add the valid state.\n\t\t\t\tif(u !== v){ n[k] = v } // Note: Not its job to check for valid values!\n\t\t\t}\n\t\t\treturn n;\n\t\t}\n\t\tmodule.exports = State;\n\t})(USE, './state');\n\n\t;USE(function(module){\n\t\tUSE('./shim');\n\t\tfunction Dup(opt){\n\t\t\tvar dup = {s:{}}, s = dup.s;\n\t\t\topt = opt || {max: 999, age: 1000 * 9};//*/ 1000 * 9 * 3};\n\t\t\tdup.check = function(id){\n\t\t\t\tif(!s[id]){ return false }\n\t\t\t\treturn dt(id);\n\t\t\t}\n\t\t\tvar dt = dup.track = function(id){\n\t\t\t\tvar it = s[id] || (s[id] = {});\n\t\t\t\tit.was = dup.now = +new Date;\n\t\t\t\tif(!dup.to){ dup.to = setTimeout(dup.drop, opt.age + 9) }\n\t\t\t\tif(dt.ed){ dt.ed(id) }\n\t\t\t\treturn it;\n\t\t\t}\n\t\t\tdup.drop = function(age){\n\t\t\t\tdup.to = null;\n\t\t\t\tdup.now = +new Date;\n\t\t\t\tvar l = Object.keys(s);\n\t\t\t\tconsole.STAT && console.STAT(dup.now, +new Date - dup.now, 'dup drop keys'); // prev ~20% CPU 7% RAM 300MB // now ~25% CPU 7% RAM 500MB\n\t\t\t\tsetTimeout.each(l, function(id){ var it = s[id]; // TODO: .keys( is slow?\n\t\t\t\t\tif(it && (age || opt.age) > (dup.now - it.was)){ return }\n\t\t\t\t\tdelete s[id];\n\t\t\t\t},0,99);\n\t\t\t}\n\t\t\treturn dup;\n\t\t}\n\t\tmodule.exports = Dup;\n\t})(USE, './dup');\n\n\t;USE(function(module){\n\t\t// request / response module, for asking and acking messages.\n\t\tUSE('./onto'); // depends upon onto!\n\t\tmodule.exports = function ask(cb, as){\n\t\t\tif(!this.on){ return }\n\t\t\tvar lack = (this.opt||{}).lack || 9000;\n\t\t\tif(!('function' == typeof cb)){\n\t\t\t\tif(!cb){ return }\n\t\t\t\tvar id = cb['#'] || cb, tmp = (this.tag||'')[id];\n\t\t\t\tif(!tmp){ return }\n\t\t\t\tif(as){\n\t\t\t\t\ttmp = this.on(id, as);\n\t\t\t\t\tclearTimeout(tmp.err);\n\t\t\t\t\ttmp.err = setTimeout(function(){ tmp.off() }, lack);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tvar id = (as && as['#']) || random(9);\n\t\t\tif(!cb){ return id }\n\t\t\tvar to = this.on(id, cb, as);\n\t\t\tto.err = to.err || setTimeout(function(){ to.off();\n\t\t\t\tto.next({err: \"Error: No ACK yet.\", lack: true});\n\t\t\t}, lack);\n\t\t\treturn id;\n\t\t}\n\t\tvar random = String.random || function(){ return Math.random().toString(36).slice(2) }\n\t})(USE, './ask');\n\n\t;USE(function(module){\n\n\t\tfunction Gun(o){\n\t\t\tif(o instanceof Gun){ return (this._ = {$: this}).$ }\n\t\t\tif(!(this instanceof Gun)){ return new Gun(o) }\n\t\t\treturn Gun.create(this._ = {$: this, opt: o});\n\t\t}\n\n\t\tGun.is = function($){ return ($ instanceof Gun) || ($ && $._ && ($ === $._.$)) || false }\n\n\t\tGun.version = 0.2020;\n\n\t\tGun.chain = Gun.prototype;\n\t\tGun.chain.toJSON = function(){};\n\n\t\tUSE('./shim');\n\t\tGun.valid = USE('./valid');\n\t\tGun.state = USE('./state');\n\t\tGun.on = USE('./onto');\n\t\tGun.dup = USE('./dup');\n\t\tGun.ask = USE('./ask');\n\n\t\t;(function(){\n\t\t\tGun.create = function(at){\n\t\t\t\tat.root = at.root || at;\n\t\t\t\tat.graph = at.graph || {};\n\t\t\t\tat.on = at.on || Gun.on;\n\t\t\t\tat.ask = at.ask || Gun.ask;\n\t\t\t\tat.dup = at.dup || Gun.dup();\n\t\t\t\tvar gun = at.$.opt(at.opt);\n\t\t\t\tif(!at.once){\n\t\t\t\t\tat.on('in', universe, at);\n\t\t\t\t\tat.on('out', universe, at);\n\t\t\t\t\tat.on('put', map, at);\n\t\t\t\t\tGun.on('create', at);\n\t\t\t\t\tat.on('create', at);\n\t\t\t\t}\n\t\t\t\tat.once = 1;\n\t\t\t\treturn gun;\n\t\t\t}\n\t\t\tfunction universe(msg){\n\t\t\t\t// TODO: BUG! msg.out = null being set!\n\t\t\t\t//if(!F){ var eve = this; setTimeout(function(){ universe.call(eve, msg,1) },Math.random() * 100);return; } // ADD F TO PARAMS!\n\t\t\t\tif(!msg){ return }\n\t\t\t\tif(msg.out === universe){ this.to.next(msg); return }\n\t\t\t\tvar eve = this, as = eve.as, at = as.at || as, gun = at.$, dup = at.dup, tmp, DBG = msg.DBG;\n\t\t\t\t(tmp = msg['#']) || (tmp = msg['#'] = text_rand(9));\n\t\t\t\tif(dup.check(tmp)){ return } dup.track(tmp);\n\t\t\t\ttmp = msg._; msg._ = ('function' == typeof tmp)? tmp : function(){};\n\t\t\t\t(msg.$ && (msg.$ === (msg.$._||'').$)) || (msg.$ = gun);\n\t\t\t\tif(msg['@'] && !msg.put){ ack(msg) }\n\t\t\t\tif(!at.ask(msg['@'], msg)){ // is this machine listening for an ack?\n\t\t\t\t\tDBG && (DBG.u = +new Date);\n\t\t\t\t\tif(msg.put){ put(msg); return } else\n\t\t\t\t\tif(msg.get){ Gun.on.get(msg, gun) }\n\t\t\t\t}\n\t\t\t\tDBG && (DBG.uc = +new Date);\n\t\t\t\teve.to.next(msg);\n\t\t\t\tDBG && (DBG.ua = +new Date);\n\t\t\t\tif(msg.nts || msg.NTS){ return } // TODO: This shouldn't be in core, but fast way to prevent NTS spread. Delete this line after all peers have upgraded to newer versions.\n\t\t\t\tmsg.out = universe; at.on('out', msg);\n\t\t\t\tDBG && (DBG.ue = +new Date);\n\t\t\t}\n\t\t\tfunction put(msg){\n\t\t\t\tif(!msg){ return }\n\t\t\t\tvar ctx = msg._||'', root = ctx.root = ((ctx.$ = msg.$||'')._||'').root;\n\t\t\t\tif(msg['@'] && ctx.faith && !ctx.miss){ // TODO: AXE may split/route based on 'put' what should we do here? Detect @ in AXE? I think we don't have to worry, as DAM will route it on @.\n\t\t\t\t\tmsg.out = universe;\n\t\t\t\t\troot.on('out', msg);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tctx.latch = root.hatch; ctx.match = root.hatch = [];\n\t\t\t\tvar put = msg.put;\n\t\t\t\tvar DBG = ctx.DBG = msg.DBG, S = +new Date; CT = CT || S;\n\t\t\t\tif(put['#'] && put['.']){ /*root && root.on('put', msg);*/ return } // TODO: BUG! This needs to call HAM instead.\n\t\t\t\tDBG && (DBG.p = S);\n\t\t\t\tctx['#'] = msg['#'];\n\t\t\t\tctx.msg = msg;\n\t\t\t\tctx.all = 0;\n\t\t\t\tctx.stun = 1;\n\t\t\t\tvar nl = Object.keys(put);//.sort(); // TODO: This is unbounded operation, large graphs will be slower. Write our own CPU scheduled sort? Or somehow do it in below? Keys itself is not O(1) either, create ES5 shim over ?weak map? or custom which is constant.\n\t\t\t\tconsole.STAT && console.STAT(S, ((DBG||ctx).pk = +new Date) - S, 'put sort');\n\t\t\t\tvar ni = 0, nj, kl, soul, node, states, err, tmp;\n\t\t\t\t(function pop(o){\n\t\t\t\t\tif(nj != ni){ nj = ni;\n\t\t\t\t\t\tif(!(soul = nl[ni])){\n\t\t\t\t\t\t\tconsole.STAT && console.STAT(S, ((DBG||ctx).pd = +new Date) - S, 'put');\n\t\t\t\t\t\t\tfire(ctx);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!(node = put[soul])){ err = ERR+cut(soul)+\"no node.\" } else\n\t\t\t\t\t\tif(!(tmp = node._)){ err = ERR+cut(soul)+\"no meta.\" } else\n\t\t\t\t\t\tif(soul !== tmp['#']){ err = ERR+cut(soul)+\"soul not same.\" } else\n\t\t\t\t\t\tif(!(states = tmp['>'])){ err = ERR+cut(soul)+\"no state.\" }\n\t\t\t\t\t\tkl = Object.keys(node||{}); // TODO: .keys( is slow\n\t\t\t\t\t}\n\t\t\t\t\tif(err){\n\t\t\t\t\t\tmsg.err = ctx.err = err; // invalid data should error and stun the message.\n\t\t\t\t\t\tfire(ctx);\n\t\t\t\t\t\t//console.log(\"handle error!\", err) // handle!\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tvar i = 0, key; o = o || 0;\n\t\t\t\t\twhile(o++ < 9 && (key = kl[i++])){\n\t\t\t\t\t\tif('_' === key){ continue }\n\t\t\t\t\t\tvar val = node[key], state = states[key];\n\t\t\t\t\t\tif(u === state){ err = ERR+cut(key)+\"on\"+cut(soul)+\"no state.\"; break }\n\t\t\t\t\t\tif(!valid(val)){ err = ERR+cut(key)+\"on\"+cut(soul)+\"bad \"+(typeof val)+cut(val); break }\n\t\t\t\t\t\t//ctx.all++; //ctx.ack[soul+key] = '';\n\t\t\t\t\t\tham(val, key, soul, state, msg);\n\t\t\t\t\t\t++C; // courtesy count;\n\t\t\t\t\t}\n\t\t\t\t\tif((kl = kl.slice(i)).length){ turn(pop); return }\n\t\t\t\t\t++ni; kl = null; pop(o);\n\t\t\t\t}());\n\t\t\t} Gun.on.put = put;\n\t\t\t// TODO: MARK!!! clock below, reconnect sync, SEA certify wire merge, User.auth taking multiple times, // msg put, put, say ack, hear loop...\n\t\t\t// WASIS BUG! local peer not ack. .off other people: .open\n\t\t\tfunction ham(val, key, soul, state, msg){\n\t\t\t\tvar ctx = msg._||'', root = ctx.root, graph = root.graph, lot, tmp;\n\t\t\t\tvar vertex = graph[soul] || empty, was = state_is(vertex, key, 1), known = vertex[key];\n\t\t\t\t\n\t\t\t\tvar DBG = ctx.DBG; if(tmp = console.STAT){ if(!graph[soul] || !known){ tmp.has = (tmp.has || 0) + 1 } }\n\n\t\t\t\tvar now = State(), u;\n\t\t\t\tif(state > now){\n\t\t\t\t\tsetTimeout(function(){ ham(val, key, soul, state, msg) }, (tmp = state - now) > MD? MD : tmp); // Max Defer 32bit. :(\n\t\t\t\t\tconsole.STAT && console.STAT(((DBG||ctx).Hf = +new Date), tmp, 'future');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(state < was){ /*old;*/ if(true || !ctx.miss){ return } } // but some chains have a cache miss that need to re-fire. // TODO: Improve in future. // for AXE this would reduce rebroadcast, but GUN does it on message forwarding. // TURNS OUT CACHE MISS WAS NOT NEEDED FOR NEW CHAINS ANYMORE!!! DANGER DANGER DANGER, ALWAYS RETURN! (or am I missing something?)\n\t\t\t\tif(!ctx.faith){ // TODO: BUG? Can this be used for cache miss as well? // Yes this was a bug, need to check cache miss for RAD tests, but should we care about the faith check now? Probably not.\n\t\t\t\t\tif(state === was && (val === known || L(val) <= L(known))){ /*console.log(\"same\");*/ /*same;*/ if(!ctx.miss){ return } } // same\n\t\t\t\t}\n\t\t\t\tctx.stun++; // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.\n\t\t\t\tvar aid = msg['#']+ctx.all++, id = {toString: function(){ return aid }, _: ctx}; id.toJSON = id.toString; // this *trick* makes it compatible between old & new versions.\n\t\t\t\troot.dup.track(id)['#'] = msg['#']; // fixes new OK acks for RPC like RTC.\n\t\t\t\tDBG && (DBG.ph = DBG.ph || +new Date);\n\t\t\t\troot.on('put', {'#': id, '@': msg['@'], put: {'#': soul, '.': key, ':': val, '>': state}, ok: msg.ok, _: ctx});\n\t\t\t}\n\t\t\tfunction map(msg){\n\t\t\t\tvar DBG; if(DBG = (msg._||'').DBG){ DBG.pa = +new Date; DBG.pm = DBG.pm || +new Date}\n      \tvar eve = this, root = eve.as, graph = root.graph, ctx = msg._, put = msg.put, soul = put['#'], key = put['.'], val = put[':'], state = put['>'], id = msg['#'], tmp;\n      \tif((tmp = ctx.msg) && (tmp = tmp.put) && (tmp = tmp[soul])){ state_ify(tmp, key, state, val, soul) } // necessary! or else out messages do not get SEA transforms.\n      \t//var bytes = ((graph[soul]||'')[key]||'').length||1;\n\t\t\t\tgraph[soul] = state_ify(graph[soul], key, state, val, soul);\n\t\t\t\tif(tmp = (root.next||'')[soul]){\n\t\t\t\t\t//tmp.bytes = (tmp.bytes||0) + ((val||'').length||1) - bytes;\n\t\t\t\t\t//if(tmp.bytes > 2**13){ Gun.log.once('byte-limit', \"Note: In the future, GUN peers will enforce a ~4KB query limit. Please see https://gun.eco/docs/Page\") }\n\t\t\t\t\ttmp.on('in', msg)\n\t\t\t\t}\n\t\t\t\tfire(ctx);\n\t\t\t\teve.to.next(msg);\n\t\t\t}\n\t\t\tfunction fire(ctx, msg){ var root;\n\t\t\t\tif(ctx.stop){ return }\n\t\t\t\tif(!ctx.err && 0 < --ctx.stun){ return } // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.\n\t\t\t\tctx.stop = 1;\n\t\t\t\tif(!(root = ctx.root)){ return }\n\t\t\t\tvar tmp = ctx.match; tmp.end = 1;\n\t\t\t\tif(tmp === root.hatch){ if(!(tmp = ctx.latch) || tmp.end){ delete root.hatch } else { root.hatch = tmp } }\n\t\t\t\tctx.hatch && ctx.hatch(); // TODO: rename/rework how put & this interact.\n\t\t\t\tsetTimeout.each(ctx.match, function(cb){cb && cb()}); \n\t\t\t\tif(!(msg = ctx.msg) || ctx.err || msg.err){ return }\n\t\t\t\tmsg.out = universe;\n\t\t\t\tctx.root.on('out', msg);\n\n\t\t\t\tCF(); // courtesy check;\n\t\t\t}\n\t\t\tfunction ack(msg){ // aggregate ACKs.\n\t\t\t\tvar id = msg['@'] || '', ctx, ok, tmp;\n\t\t\t\tif(!(ctx = id._)){\n\t\t\t\t\tvar dup = (dup = msg.$) && (dup = dup._) && (dup = dup.root) && (dup = dup.dup);\n\t\t\t\t\tif(!(dup = dup.check(id))){ return }\n\t\t\t\t\tmsg['@'] = dup['#'] || msg['@']; // This doesn't do anything anymore, backtrack it to something else?\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tctx.acks = (ctx.acks||0) + 1;\n\t\t\t\tif(ctx.err = msg.err){\n\t\t\t\t\tmsg['@'] = ctx['#'];\n\t\t\t\t\tfire(ctx); // TODO: BUG? How it skips/stops propagation of msg if any 1 item is error, this would assume a whole batch/resync has same malicious intent.\n\t\t\t\t}\n\t\t\t\tctx.ok = msg.ok || ctx.ok;\n\t\t\t\tif(!ctx.stop && !ctx.crack){ ctx.crack = ctx.match && ctx.match.push(function(){back(ctx)}) } // handle synchronous acks. NOTE: If a storage peer ACKs synchronously then the PUT loop has not even counted up how many items need to be processed, so ctx.STOP flags this and adds only 1 callback to the end of the PUT loop.\n\t\t\t\tback(ctx);\n\t\t\t}\n\t\t\tfunction back(ctx){\n\t\t\t\tif(!ctx || !ctx.root){ return }\n\t\t\t\tif(ctx.stun || ctx.acks !== ctx.all){ return }\n\t\t\t\tctx.root.on('in', {'@': ctx['#'], err: ctx.err, ok: ctx.err? u : ctx.ok || {'':1}});\n\t\t\t}\n\n\t\t\tvar ERR = \"Error: Invalid graph!\";\n\t\t\tvar cut = function(s){ return \" '\"+(''+s).slice(0,9)+\"...' \" }\n\t\t\tvar L = JSON.stringify, MD = 2147483647, State = Gun.state;\n\t\t\tvar C = 0, CT, CF = function(){if(C>999 && (C/-(CT - (CT = +new Date))>1)){Gun.window && console.log(\"Warning: You're syncing 1K+ records a second, faster than DOM can update - consider limiting query.\");CF=function(){C=0}}};\n\n\t\t}());\n\n\t\t;(function(){\n\t\t\tGun.on.get = function(msg, gun){\n\t\t\t\tvar root = gun._, get = msg.get, soul = get['#'], node = root.graph[soul], has = get['.'];\n\t\t\t\tvar next = root.next || (root.next = {}), at = next[soul];\n\n\t\t\t\t// TODO: Azarattum bug, what is in graph is not same as what is in next. Fix!\n\n\t\t\t\t// queue concurrent GETs?\n\t\t\t\t// TODO: consider tagging original message into dup for DAM.\n\t\t\t\t// TODO: ^ above? In chat app, 12 messages resulted in same peer asking for `#user.pub` 12 times. (same with #user GET too, yipes!) // DAM note: This also resulted in 12 replies from 1 peer which all had same ##hash but none of them deduped because each get was different.\n\t\t\t\t// TODO: Moving quick hacks fixing these things to axe for now.\n\t\t\t\t// TODO: a lot of GET #foo then GET #foo.\"\" happening, why?\n\t\t\t\t// TODO: DAM's ## hash check, on same get ACK, producing multiple replies still, maybe JSON vs YSON?\n\t\t\t\t// TMP note for now: viMZq1slG was chat LEX query #.\n\t\t\t\t/*if(gun !== (tmp = msg.$) && (tmp = (tmp||'')._)){\n\t\t\t\t\tif(tmp.Q){ tmp.Q[msg['#']] = ''; return } // chain does not need to ask for it again.\n\t\t\t\t\ttmp.Q = {};\n\t\t\t\t}*/\n\t\t\t\t/*if(u === has){\n\t\t\t\t\tif(at.Q){\n\t\t\t\t\t\t//at.Q[msg['#']] = '';\n\t\t\t\t\t\t//return;\n\t\t\t\t\t}\n\t\t\t\t\tat.Q = {};\n\t\t\t\t}*/\n\t\t\t\tvar ctx = msg._||{}, DBG = ctx.DBG = msg.DBG;\n\t\t\t\tDBG && (DBG.g = +new Date);\n\t\t\t\t//console.log(\"GET:\", get, node, has, at);\n\t\t\t\t//if(!node && !at){ return root.on('get', msg) }\n\t\t\t\t//if(has && node){ // replace 2 below lines to continue dev?\n\t\t\t\tif(!node){ return root.on('get', msg) }\n\t\t\t\tif(has){\n\t\t\t\t\tif('string' != typeof has || u === node[has]){\n\t\t\t\t\t\tif(!((at||'').next||'')[has]){ root.on('get', msg); return }\n\t\t\t\t\t}\n\t\t\t\t\tnode = state_ify({}, has, state_is(node, has), node[has], soul);\n\t\t\t\t\t// If we have a key in-memory, do we really need to fetch?\n\t\t\t\t\t// Maybe... in case the in-memory key we have is a local write\n\t\t\t\t\t// we still need to trigger a pull/merge from peers.\n\t\t\t\t}\n\t\t\t\t//Gun.window? Gun.obj.copy(node) : node; // HNPERF: If !browser bump Performance? Is this too dangerous to reference root graph? Copy / shallow copy too expensive for big nodes. Gun.obj.to(node); // 1 layer deep copy // Gun.obj.copy(node); // too slow on big nodes\n\t\t\t\tnode && ack(msg, node);\n\t\t\t\troot.on('get', msg); // send GET to storage adapters.\n\t\t\t}\n\t\t\tfunction ack(msg, node){\n\t\t\t\tvar S = +new Date, ctx = msg._||{}, DBG = ctx.DBG = msg.DBG;\n\t\t\t\tvar to = msg['#'], id = text_rand(9), keys = Object.keys(node||'').sort(), soul = ((node||'')._||'')['#'], kl = keys.length, j = 0, root = msg.$._.root, F = (node === root.graph[soul]);\n\t\t\t\tconsole.STAT && console.STAT(S, ((DBG||ctx).gk = +new Date) - S, 'got keys');\n\t\t\t\t// PERF: Consider commenting this out to force disk-only reads for perf testing? // TODO: .keys( is slow\n\t\t\t\tnode && (function go(){\n\t\t\t\t\tS = +new Date;\n\t\t\t\t\tvar i = 0, k, put = {}, tmp;\n\t\t\t\t\twhile(i < 9 && (k = keys[i++])){\n\t\t\t\t\t\tstate_ify(put, k, state_is(node, k), node[k], soul);\n\t\t\t\t\t}\n\t\t\t\t\tkeys = keys.slice(i);\n\t\t\t\t\t(tmp = {})[soul] = put; put = tmp;\n\t\t\t\t\tvar faith; if(F){ faith = function(){}; faith.ram = faith.faith = true; } // HNPERF: We're testing performance improvement by skipping going through security again, but this should be audited.\n\t\t\t\t\ttmp = keys.length;\n\t\t\t\t\tconsole.STAT && console.STAT(S, -(S - (S = +new Date)), 'got copied some');\n\t\t\t\t\tDBG && (DBG.ga = +new Date);\n\t\t\t\t\troot.on('in', {'@': to, '#': id, put: put, '%': (tmp? (id = text_rand(9)) : u), $: root.$, _: faith, DBG: DBG});\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'got in');\n\t\t\t\t\tif(!tmp){ return }\n\t\t\t\t\tsetTimeout.turn(go);\n\t\t\t\t}());\n\t\t\t\tif(!node){ root.on('in', {'@': msg['#']}) } // TODO: I don't think I like this, the default lS adapter uses this but \"not found\" is a sensitive issue, so should probably be handled more carefully/individually.\n\t\t\t} Gun.on.get.ack = ack;\n\t\t}());\n\n\t\t;(function(){\n\t\t\tGun.chain.opt = function(opt){\n\t\t\t\topt = opt || {};\n\t\t\t\tvar gun = this, at = gun._, tmp = opt.peers || opt;\n\t\t\t\tif(!Object.plain(opt)){ opt = {} }\n\t\t\t\tif(!Object.plain(at.opt)){ at.opt = opt }\n\t\t\t\tif('string' == typeof tmp){ tmp = [tmp] }\n\t\t\t\tif(!Object.plain(at.opt.peers)){ at.opt.peers = {}}\n\t\t\t\tif(tmp instanceof Array){\n\t\t\t\t\topt.peers = {};\n\t\t\t\t\ttmp.forEach(function(url){\n\t\t\t\t\t\tvar p = {}; p.id = p.url = url;\n\t\t\t\t\t\topt.peers[url] = at.opt.peers[url] = at.opt.peers[url] || p;\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tobj_each(opt, function each(k){ var v = this[k];\n\t\t\t\t\tif((this && this.hasOwnProperty(k)) || 'string' == typeof v || Object.empty(v)){ this[k] = v; return }\n\t\t\t\t\tif(v && v.constructor !== Object && !(v instanceof Array)){ return }\n\t\t\t\t\tobj_each(v, each);\n\t\t\t\t});\n\t\t\t\tat.opt.from = opt;\n\t\t\t\tGun.on('opt', at);\n\t\t\t\tat.opt.uuid = at.opt.uuid || function uuid(l){ return Gun.state().toString(36).replace('.','') + String.random(l||12) }\n\t\t\t\treturn gun;\n\t\t\t}\n\t\t}());\n\n\t\tvar obj_each = function(o,f){ Object.keys(o).forEach(f,o) }, text_rand = String.random, turn = setTimeout.turn, valid = Gun.valid, state_is = Gun.state.is, state_ify = Gun.state.ify, u, empty = {}, C;\n\n\t\tGun.log = function(){ return (!Gun.log.off && C.log.apply(C, arguments)), [].slice.call(arguments).join(' ') };\n\t\tGun.log.once = function(w,s,o){ return (o = Gun.log.once)[w] = o[w] || 0, o[w]++ || Gun.log(s) };\n\n\t\tif(typeof window !== \"undefined\"){ (window.GUN = window.Gun = Gun).window = window }\n\t\ttry{ if(typeof MODULE !== \"undefined\"){ MODULE.exports = Gun } }catch(e){}\n\t\tmodule.exports = Gun;\n\t\t\n\t\t(Gun.window||{}).console = (Gun.window||{}).console || {log: function(){}};\n\t\t(C = console).only = function(i, s){ return (C.only.i && i === C.only.i && C.only.i++) && (C.log.apply(C, arguments) || s) };\n\n\t\t;\"Please do not remove welcome log unless you are paying for a monthly sponsorship, thanks!\";\n\t\tGun.log.once(\"welcome\", \"Hello wonderful person! :) Thanks for using GUN, please ask for help on http://chat.gun.eco if anything takes you longer than 5min to figure out!\");\n\t})(USE, './root');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tGun.chain.back = function(n, opt){ var tmp;\n\t\t\tn = n || 1;\n\t\t\tif(-1 === n || Infinity === n){\n\t\t\t\treturn this._.root.$;\n\t\t\t} else\n\t\t\tif(1 === n){\n\t\t\t\treturn (this._.back || this._).$;\n\t\t\t}\n\t\t\tvar gun = this, at = gun._;\n\t\t\tif(typeof n === 'string'){\n\t\t\t\tn = n.split('.');\n\t\t\t}\n\t\t\tif(n instanceof Array){\n\t\t\t\tvar i = 0, l = n.length, tmp = at;\n\t\t\t\tfor(i; i < l; i++){\n\t\t\t\t\ttmp = (tmp||empty)[n[i]];\n\t\t\t\t}\n\t\t\t\tif(u !== tmp){\n\t\t\t\t\treturn opt? gun : tmp;\n\t\t\t\t} else\n\t\t\t\tif((tmp = at.back)){\n\t\t\t\t\treturn tmp.$.back(n, opt);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif('function' == typeof n){\n\t\t\t\tvar yes, tmp = {back: at};\n\t\t\t\twhile((tmp = tmp.back)\n\t\t\t\t&& u === (yes = n(tmp, opt))){}\n\t\t\t\treturn yes;\n\t\t\t}\n\t\t\tif('number' == typeof n){\n\t\t\t\treturn (at.back || at).$.back(n - 1);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tvar empty = {}, u;\n\t})(USE, './back');\n\n\t;USE(function(module){\n\t\t// WARNING: GUN is very simple, but the JavaScript chaining API around GUN\n\t\t// is complicated and was extremely hard to build. If you port GUN to another\n\t\t// language, consider implementing an easier API to build.\n\t\tvar Gun = USE('./root');\n\t\tGun.chain.chain = function(sub){\n\t\t\tvar gun = this, at = gun._, chain = new (sub || gun).constructor(gun), cat = chain._, root;\n\t\t\tcat.root = root = at.root;\n\t\t\tcat.id = ++root.once;\n\t\t\tcat.back = gun._;\n\t\t\tcat.on = Gun.on;\n\t\t\tcat.on('in', Gun.on.in, cat); // For 'in' if I add my own listeners to each then I MUST do it before in gets called. If I listen globally for all incoming data instead though, regardless of individual listeners, I can transform the data there and then as well.\n\t\t\tcat.on('out', Gun.on.out, cat); // However for output, there isn't really the global option. I must listen by adding my own listener individually BEFORE this one is ever called.\n\t\t\treturn chain;\n\t\t}\n\n\t\tfunction output(msg){\n\t\t\tvar put, get, at = this.as, back = at.back, root = at.root, tmp;\n\t\t\tif(!msg.$){ msg.$ = at.$ }\n\t\t\tthis.to.next(msg);\n\t\t\tif(at.err){ at.on('in', {put: at.put = u, $: at.$}); return }\n\t\t\tif(get = msg.get){\n\t\t\t\t/*if(u !== at.put){\n\t\t\t\t\tat.on('in', at);\n\t\t\t\t\treturn;\n\t\t\t\t}*/\n\t\t\t\tif(root.pass){ root.pass[at.id] = at; } // will this make for buggy behavior elsewhere?\n\t\t\t\tif(at.lex){ Object.keys(at.lex).forEach(function(k){ tmp[k] = at.lex[k] }, tmp = msg.get = msg.get || {}) }\n\t\t\t\tif(get['#'] || at.soul){\n\t\t\t\t\tget['#'] = get['#'] || at.soul;\n\t\t\t\t\t//root.graph[get['#']] = root.graph[get['#']] || {_:{'#':get['#'],'>':{}}};\n\t\t\t\t\tmsg['#'] || (msg['#'] = text_rand(9)); // A3120 ?\n\t\t\t\t\tback = (root.$.get(get['#'])._);\n\t\t\t\t\tif(!(get = get['.'])){ // soul\n\t\t\t\t\t\ttmp = back.ask && back.ask['']; // check if we have already asked for the full node\n\t\t\t\t\t\t(back.ask || (back.ask = {}))[''] = back; // add a flag that we are now.\n\t\t\t\t\t\tif(u !== back.put){ // if we already have data,\n\t\t\t\t\t\t\tback.on('in', back); // send what is cached down the chain\n\t\t\t\t\t\t\tif(tmp){ return } // and don't ask for it again.\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmsg.$ = back.$;\n\t\t\t\t\t} else\n\t\t\t\t\tif(obj_has(back.put, get)){ // TODO: support #LEX !\n\t\t\t\t\t\ttmp = back.ask && back.ask[get];\n\t\t\t\t\t\t(back.ask || (back.ask = {}))[get] = back.$.get(get)._;\n\t\t\t\t\t\tback.on('in', {get: get, put: {'#': back.soul, '.': get, ':': back.put[get], '>': state_is(root.graph[back.soul], get)}});\n\t\t\t\t\t\tif(tmp){ return }\n\t\t\t\t\t}\n\t\t\t\t\t\t/*put = (back.$.get(get)._);\n\t\t\t\t\t\tif(!(tmp = put.ack)){ put.ack = -1 }\n\t\t\t\t\t\tback.on('in', {\n\t\t\t\t\t\t\t$: back.$,\n\t\t\t\t\t\t\tput: Gun.state.ify({}, get, Gun.state(back.put, get), back.put[get]),\n\t\t\t\t\t\t\tget: back.get\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif(tmp){ return }\n\t\t\t\t\t} else\n\t\t\t\t\tif('string' != typeof get){\n\t\t\t\t\t\tvar put = {}, meta = (back.put||{})._;\n\t\t\t\t\t\tGun.obj.map(back.put, function(v,k){\n\t\t\t\t\t\t\tif(!Gun.text.match(k, get)){ return }\n\t\t\t\t\t\t\tput[k] = v;\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif(!Gun.obj.empty(put)){\n\t\t\t\t\t\t\tput._ = meta;\n\t\t\t\t\t\t\tback.on('in', {$: back.$, put: put, get: back.get})\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(tmp = at.lex){\n\t\t\t\t\t\t\ttmp = (tmp._) || (tmp._ = function(){});\n\t\t\t\t\t\t\tif(back.ack < tmp.ask){ tmp.ask = back.ack }\n\t\t\t\t\t\t\tif(tmp.ask){ return }\n\t\t\t\t\t\t\ttmp.ask = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t*/\n\t\t\t\t\troot.ask(ack, msg); // A3120 ?\n\t\t\t\t\treturn root.on('in', msg);\n\t\t\t\t}\n\t\t\t\t//if(root.now){ root.now[at.id] = root.now[at.id] || true; at.pass = {} }\n\t\t\t\tif(get['.']){\n\t\t\t\t\tif(at.get){\n\t\t\t\t\t\tmsg = {get: {'.': at.get}, $: at.$};\n\t\t\t\t\t\t(back.ask || (back.ask = {}))[at.get] = msg.$._; // TODO: PERFORMANCE? More elegant way?\n\t\t\t\t\t\treturn back.on('out', msg);\n\t\t\t\t\t}\n\t\t\t\t\tmsg = {get: at.lex? msg.get : {}, $: at.$};\n\t\t\t\t\treturn back.on('out', msg);\n\t\t\t\t}\n\t\t\t\t(at.ask || (at.ask = {}))[''] = at;\t //at.ack = at.ack || -1;\n\t\t\t\tif(at.get){\n\t\t\t\t\tget['.'] = at.get;\n\t\t\t\t\t(back.ask || (back.ask = {}))[at.get] = msg.$._; // TODO: PERFORMANCE? More elegant way?\n\t\t\t\t\treturn back.on('out', msg);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn back.on('out', msg);\n\t\t}; Gun.on.out = output;\n\n\t\tfunction input(msg, cat){ cat = cat || this.as; // TODO: V8 may not be able to optimize functions with different parameter calls, so try to do benchmark to see if there is any actual difference.\n\t\t\tvar root = cat.root, gun = msg.$ || (msg.$ = cat.$), at = (gun||'')._ || empty, tmp = msg.put||'', soul = tmp['#'], key = tmp['.'], change = (u !== tmp['='])? tmp['='] : tmp[':'], state = tmp['>'] || -Infinity, sat; // eve = event, at = data at, cat = chain at, sat = sub at (children chains).\n\t\t\tif(u !== msg.put && (u === tmp['#'] || u === tmp['.'] || (u === tmp[':'] && u === tmp['=']) || u === tmp['>'])){ // convert from old format\n\t\t\t\tif(!valid(tmp)){\n\t\t\t\t\tif(!(soul = ((tmp||'')._||'')['#'])){ console.log(\"chain not yet supported for\", tmp, '...', msg, cat); return; }\n\t\t\t\t\tgun = cat.root.$.get(soul);\n\t\t\t\t\treturn setTimeout.each(Object.keys(tmp).sort(), function(k){ // TODO: .keys( is slow // BUG? ?Some re-in logic may depend on this being sync?\n\t\t\t\t\t\tif('_' == k || u === (state = state_is(tmp, k))){ return }\n\t\t\t\t\t\tcat.on('in', {$: gun, put: {'#': soul, '.': k, '=': tmp[k], '>': state}, VIA: msg});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcat.on('in', {$: at.back.$, put: {'#': soul = at.back.soul, '.': key = at.has || at.get, '=': tmp, '>': state_is(at.back.put, key)}, via: msg}); // TODO: This could be buggy! It assumes/approxes data, other stuff could have corrupted it.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif((msg.seen||'')[cat.id]){ return } (msg.seen || (msg.seen = function(){}))[cat.id] = cat; // help stop some infinite loops\n\n\t\t\tif(cat !== at){ // don't worry about this when first understanding the code, it handles changing contexts on a message. A soul chain will never have a different context.\n\t\t\t\tObject.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {}); // make copy of message\n\t\t\t\ttmp.get = cat.get || tmp.get;\n\t\t\t\tif(!cat.soul && !cat.has){ // if we do not recognize the chain type\n\t\t\t\t\ttmp.$$$ = tmp.$$$ || cat.$; // make a reference to wherever it came from.\n\t\t\t\t} else\n\t\t\t\tif(at.soul){ // a has (property) chain will have a different context sometimes if it is linked (to a soul chain). Anything that is not a soul or has chain, will always have different contexts.\n\t\t\t\t\ttmp.$ = cat.$;\n\t\t\t\t\ttmp.$$ = tmp.$$ || at.$;\n\t\t\t\t}\n\t\t\t\tmsg = tmp; // use the message with the new context instead;\n\t\t\t}\n\t\t\tunlink(msg, cat);\n\n\t\t\tif(((cat.soul/* && (cat.ask||'')['']*/) || msg.$$) && state >= state_is(root.graph[soul], key)){ // The root has an in-memory cache of the graph, but if our peer has asked for the data then we want a per deduplicated chain copy of the data that might have local edits on it.\n\t\t\t\t(tmp = root.$.get(soul)._).put = state_ify(tmp.put, key, state, change, soul);\n\t\t\t}\n\t\t\tif(!at.soul /*&& (at.ask||'')['']*/ && state >= state_is(root.graph[soul], key) && (sat = (root.$.get(soul)._.next||'')[key])){ // Same as above here, but for other types of chains. // TODO: Improve perf by preventing echoes recaching.\n\t\t\t\tsat.put = change; // update cache\n\t\t\t\tif('string' == typeof (tmp = valid(change))){\n\t\t\t\t\tsat.put = root.$.get(tmp)._.put || change; // share same cache as what we're linked to.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.to && this.to.next(msg); // 1st API job is to call all chain listeners.\n\t\t\t// TODO: Make input more reusable by only doing these (some?) calls if we are a chain we recognize? This means each input listener would be responsible for when listeners need to be called, which makes sense, as they might want to filter.\n\t\t\tcat.any && setTimeout.each(Object.keys(cat.any), function(any){ (any = cat.any[any]) && any(msg) },0,99); // 1st API job is to call all chain listeners. // TODO: .keys( is slow // BUG: Some re-in logic may depend on this being sync.\n\t\t\tcat.echo && setTimeout.each(Object.keys(cat.echo), function(lat){ (lat = cat.echo[lat]) && lat.on('in', msg) },0,99); // & linked at chains // TODO: .keys( is slow // BUG: Some re-in logic may depend on this being sync.\n\n\t\t\tif(((msg.$$||'')._||at).soul){ // comments are linear, but this line of code is non-linear, so if I were to comment what it does, you'd have to read 42 other comments first... but you can't read any of those comments until you first read this comment. What!? // shouldn't this match link's check?\n\t\t\t\t// is there cases where it is a $$ that we do NOT want to do the following? \n\t\t\t\tif((sat = cat.next) && (sat = sat[key])){ // TODO: possible trick? Maybe have `ionmap` code set a sat? // TODO: Maybe we should do `cat.ask` instead? I guess does not matter.\n\t\t\t\t\ttmp = {}; Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] });\n\t\t\t\t\ttmp.$ = (msg.$$||msg.$).get(tmp.get = key); delete tmp.$$; delete tmp.$$$;\n\t\t\t\t\tsat.on('in', tmp);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlink(msg, cat);\n\t\t}; Gun.on.in = input;\n\n\t\tfunction link(msg, cat){ cat = cat || this.as || msg.$._;\n\t\t\tif(msg.$$ && this !== Gun.on){ return } // $$ means we came from a link, so we are at the wrong level, thus ignore it unless overruled manually by being called directly.\n\t\t\tif(!msg.put || cat.soul){ return } // But you cannot overrule being linked to nothing, or trying to link a soul chain - that must never happen.\n\t\t\tvar put = msg.put||'', link = put['=']||put[':'], tmp;\n\t\t\tvar root = cat.root, tat = root.$.get(put['#']).get(put['.'])._;\n\t\t\tif('string' != typeof (link = valid(link))){\n\t\t\t\tif(this === Gun.on){ (tat.echo || (tat.echo = {}))[cat.id] = cat } // allow some chain to explicitly force linking to simple data.\n\t\t\t\treturn; // by default do not link to data that is not a link.\n\t\t\t}\n\t\t\tif((tat.echo || (tat.echo = {}))[cat.id] // we've already linked ourselves so we do not need to do it again. Except... (annoying implementation details)\n\t\t\t\t&& !(root.pass||'')[cat.id]){ return } // if a new event listener was added, we need to make a pass through for it. The pass will be on the chain, not always the chain passed down. \n\t\t\tif(tmp = root.pass){ if(tmp[link+cat.id]){ return } tmp[link+cat.id] = 1 } // But the above edge case may \"pass through\" on a circular graph causing infinite passes, so we hackily add a temporary check for that.\n\n\t\t\t(tat.echo||(tat.echo={}))[cat.id] = cat; // set ourself up for the echo! // TODO: BUG? Echo to self no longer causes problems? Confirm.\n\n\t\t\tif(cat.has){ cat.link = link }\n\t\t\tvar sat = root.$.get(tat.link = link)._; // grab what we're linking to.\n\t\t\t(sat.echo || (sat.echo = {}))[tat.id] = tat; // link it.\n\t\t\tvar tmp = cat.ask||''; // ask the chain for what needs to be loaded next!\n\t\t\tif(tmp[''] || cat.lex){ // we might need to load the whole thing // TODO: cat.lex probably has edge case bugs to it, need more test coverage.\n\t\t\t\tsat.on('out', {get: {'#': link}});\n\t\t\t}\n\t\t\tsetTimeout.each(Object.keys(tmp), function(get, sat){ // if sub chains are asking for data. // TODO: .keys( is slow // BUG? ?Some re-in logic may depend on this being sync?\n\t\t\t\tif(!get || !(sat = tmp[get])){ return }\n\t\t\t\tsat.on('out', {get: {'#': link, '.': get}}); // go get it.\n\t\t\t},0,99);\n\t\t}; Gun.on.link = link;\n\n\t\tfunction unlink(msg, cat){ // ugh, so much code for seemingly edge case behavior.\n\t\t\tvar put = msg.put||'', change = (u !== put['='])? put['='] : put[':'], root = cat.root, link, tmp;\n\t\t\tif(u === change){ // 1st edge case: If we have a brand new database, no data will be found.\n\t\t\t\t// TODO: BUG! because emptying cache could be async from below, make sure we are not emptying a newer cache. So maybe pass an Async ID to check against?\n\t\t\t\t// TODO: BUG! What if this is a map? // Warning! Clearing things out needs to be robust against sync/async ops, or else you'll see `map val get put` test catastrophically fail because map attempts to link when parent graph is streamed before child value gets set. Need to differentiate between lack acks and force clearing.\n\t\t\t\tif(cat.soul && u !== cat.put){ return } // data may not be found on a soul, but if a soul already has data, then nothing can clear the soul as a whole.\n\t\t\t\t//if(!cat.has){ return }\n\t\t\t\ttmp = (msg.$$||msg.$||'')._||'';\n\t\t\t\tif(msg['@'] && (u !== tmp.put || u !== cat.put)){ return } // a \"not found\" from other peers should not clear out data if we have already found it.\n\t\t\t\t//if(cat.has && u === cat.put && !(root.pass||'')[cat.id]){ return } // if we are already unlinked, do not call again, unless edge case. // TODO: BUG! This line should be deleted for \"unlink deeply nested\".\n\t\t\t\tif(link = cat.link || msg.linked){\n\t\t\t\t\tdelete (root.$.get(link)._.echo||'')[cat.id];\n\t\t\t\t}\n\t\t\t\tif(cat.has){ // TODO: Empty out links, maps, echos, acks/asks, etc.?\n\t\t\t\t\tcat.link = null;\n\t\t\t\t}\n\t\t\t\tcat.put = u; // empty out the cache if, for example, alice's car's color no longer exists (relative to alice) if alice no longer has a car.\n\t\t\t\t// TODO: BUG! For maps, proxy this so the individual sub is triggered, not all subs.\n\t\t\t\tsetTimeout.each(Object.keys(cat.next||''), function(get, sat){ // empty out all sub chains. // TODO: .keys( is slow // BUG? ?Some re-in logic may depend on this being sync? // TODO: BUG? This will trigger deeper put first, does put logic depend on nested order? // TODO: BUG! For map, this needs to be the isolated child, not all of them.\n\t\t\t\t\tif(!(sat = cat.next[get])){ return }\n\t\t\t\t\t//if(cat.has && u === sat.put && !(root.pass||'')[sat.id]){ return } // if we are already unlinked, do not call again, unless edge case. // TODO: BUG! This line should be deleted for \"unlink deeply nested\".\n\t\t\t\t\tif(link){ delete (root.$.get(link).get(get)._.echo||'')[sat.id] }\n\t\t\t\t\tsat.on('in', {get: get, put: u, $: sat.$}); // TODO: BUG? Add recursive seen check?\n\t\t\t\t},0,99);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(cat.soul){ return } // a soul cannot unlink itself.\n\t\t\tif(msg.$$){ return } // a linked chain does not do the unlinking, the sub chain does. // TODO: BUG? Will this cancel maps?\n\t\t\tlink = valid(change); // need to unlink anytime we are not the same link, though only do this once per unlink (and not on init).\n\t\t\ttmp = msg.$._||'';\n\t\t\tif(link === tmp.link || (cat.has && !tmp.link)){\n\t\t\t\tif((root.pass||'')[cat.id] && 'string' !== typeof link){\n\n\t\t\t\t} else {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete (tmp.echo||'')[cat.id];\n\t\t\tunlink({get: cat.get, put: u, $: msg.$, linked: msg.linked = msg.linked || tmp.link}, cat); // unlink our sub chains.\n\t\t}; Gun.on.unlink = unlink;\n\n\t\tfunction ack(msg, ev){\n\t\t\t//if(!msg['%'] && (this||'').off){ this.off() } // do NOT memory leak, turn off listeners! Now handled by .ask itself\n\t\t\t// manhattan:\n\t\t\tvar as = this.as, at = as.$._, root = at.root, get = as.get||'', tmp = (msg.put||'')[get['#']]||'';\n\t\t\tif(!msg.put || ('string' == typeof get['.'] && u === tmp[get['.']])){\n\t\t\t\tif(u !== at.put){ return }\n\t\t\t\tif(!at.soul && !at.has){ return } // TODO: BUG? For now, only core-chains will handle not-founds, because bugs creep in if non-core chains are used as $ but we can revisit this later for more powerful extensions.\n\t\t\t\tat.ack = (at.ack || 0) + 1;\n\t\t\t\tat.on('in', {\n\t\t\t\t\tget: at.get,\n\t\t\t\t\tput: at.put = u,\n\t\t\t\t\t$: at.$,\n\t\t\t\t\t'@': msg['@']\n\t\t\t\t});\n\t\t\t\t/*(tmp = at.Q) && setTimeout.each(Object.keys(tmp), function(id){ // TODO: Temporary testing, not integrated or being used, probably delete.\n\t\t\t\t\tObject.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {}); tmp['@'] = id; // copy message\n\t\t\t\t\troot.on('in', tmp);\n\t\t\t\t}); delete at.Q;*/\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t(msg._||{}).miss = 1;\n\t\t\tGun.on.put(msg);\n\t\t\treturn; // eom\n\t\t}\n\n\t\tvar empty = {}, u, text_rand = String.random, valid = Gun.valid, obj_has = function(o, k){ return o && Object.prototype.hasOwnProperty.call(o, k) }, state = Gun.state, state_is = state.is, state_ify = state.ify;\n\t})(USE, './chain');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tGun.chain.get = function(key, cb, as){\n\t\t\tvar gun, tmp;\n\t\t\tif(typeof key === 'string'){\n\t\t\t\tif(key.length == 0) {\t\n\t\t\t\t\t(gun = this.chain())._.err = {err: Gun.log('0 length key!', key)};\n\t\t\t\t\tif(cb){ cb.call(gun, gun._.err) }\n\t\t\t\t\treturn gun;\n\t\t\t\t}\n\t\t\t\tvar back = this, cat = back._;\n\t\t\t\tvar next = cat.next || empty;\n\t\t\t\tif(!(gun = next[key])){\n\t\t\t\t\tgun = key && cache(key, back);\n\t\t\t\t}\n\t\t\t\tgun = gun && gun.$;\n\t\t\t} else\n\t\t\tif('function' == typeof key){\n\t\t\t\tif(true === cb){ return soul(this, key, cb, as), this }\n\t\t\t\tgun = this;\n\t\t\t\tvar cat = gun._, opt = cb || {}, root = cat.root, id;\n\t\t\t\topt.at = cat;\n\t\t\t\topt.ok = key;\n\t\t\t\tvar wait = {}; // can we assign this to the at instead, like in once?\n\t\t\t\t//var path = []; cat.$.back(at => { at.get && path.push(at.get.slice(0,9))}); path = path.reverse().join('.');\n\t\t\t\tfunction any(msg, eve, f){\n\t\t\t\t\tif(any.stun){ return }\n\t\t\t\t\tif((tmp = root.pass) && !tmp[id]){ return }\n\t\t\t\t\tvar at = msg.$._, sat = (msg.$$||'')._, data = (sat||at).put, odd = (!at.has && !at.soul), test = {}, link, tmp;\n\t\t\t\t\tif(odd || u === data){ // handles non-core\n\t\t\t\t\t\tdata = (u === ((tmp = msg.put)||'')['='])? (u === (tmp||'')[':'])? tmp : tmp[':'] : tmp['='];\n\t\t\t\t\t}\n\t\t\t\t\tif(link = ('string' == typeof (tmp = Gun.valid(data)))){\n\t\t\t\t\t\tdata = (u === (tmp = root.$.get(tmp)._.put))? opt.not? u : data : tmp;\n\t\t\t\t\t}\n\t\t\t\t\tif(opt.not && u === data){ return }\n\t\t\t\t\tif(u === opt.stun){\n\t\t\t\t\t\tif((tmp = root.stun) && tmp.on){\n\t\t\t\t\t\t\tcat.$.back(function(a){ // our chain stunned?\n\t\t\t\t\t\t\t\ttmp.on(''+a.id, test = {});\n\t\t\t\t\t\t\t\tif((test.run || 0) < any.id){ return test } // if there is an earlier stun on gapless parents/self.\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t!test.run && tmp.on(''+at.id, test = {}); // this node stunned?\n\t\t\t\t\t\t\t!test.run && sat && tmp.on(''+sat.id, test = {}); // linked node stunned?\n\t\t\t\t\t\t\tif(any.id > test.run){\n\t\t\t\t\t\t\t\tif(!test.stun || test.stun.end){\n\t\t\t\t\t\t\t\t\ttest.stun = tmp.on('stun');\n\t\t\t\t\t\t\t\t\ttest.stun = test.stun && test.stun.last;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif(test.stun && !test.stun.end){\n\t\t\t\t\t\t\t\t\t//if(odd && u === data){ return }\n\t\t\t\t\t\t\t\t\t//if(u === msg.put){ return } // \"not found\" acks will be found if there is stun, so ignore these.\n\t\t\t\t\t\t\t\t\t(test.stun.add || (test.stun.add = {}))[id] = function(){ any(msg,eve,1) } // add ourself to the stun callback list that is called at end of the write.\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(/*odd &&*/ u === data){ f = 0 } // if data not found, keep waiting/trying.\n\t\t\t\t\t\t/*if(f && u === data){\n\t\t\t\t\t\t\tcat.on('out', opt.out);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}*/\n\t\t\t\t\t\tif((tmp = root.hatch) && !tmp.end && u === opt.hatch && !f){ // quick hack! // What's going on here? Because data is streamed, we get things one by one, but a lot of developers would rather get a callback after each batch instead, so this does that by creating a wait list per chain id that is then called at the end of the batch by the hatch code in the root put listener.\n\t\t\t\t\t\t\tif(wait[at.$._.id]){ return } wait[at.$._.id] = 1;\n\t\t\t\t\t\t\ttmp.push(function(){any(msg,eve,1)});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}; wait = {}; // end quick hack.\n\t\t\t\t\t}\n\t\t\t\t\t// call:\n\t\t\t\t\tif(root.pass){ if(root.pass[id+at.id]){ return } root.pass[id+at.id] = 1 }\n\t\t\t\t\tif(opt.on){ opt.ok.call(at.$, data, at.get, msg, eve || any); return } // TODO: Also consider breaking `this` since a lot of people do `=>` these days and `.call(` has slower performance.\n\t\t\t\t\tif(opt.v2020){ opt.ok(msg, eve || any); return }\n\t\t\t\t\tObject.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {}); msg = tmp; msg.put = data; // 2019 COMPATIBILITY! TODO: GET RID OF THIS!\n\t\t\t\t\topt.ok.call(opt.as, msg, eve || any); // is this the right\n\t\t\t\t};\n\t\t\t\tany.at = cat;\n\t\t\t\t//(cat.any||(cat.any=function(msg){ setTimeout.each(Object.keys(cat.any||''), function(act){ (act = cat.any[act]) && act(msg) },0,99) }))[id = String.random(7)] = any; // maybe switch to this in future?\n\t\t\t\t(cat.any||(cat.any={}))[id = String.random(7)] = any;\n\t\t\t\tany.off = function(){ any.stun = 1; if(!cat.any){ return } delete cat.any[id] }\n\t\t\t\tany.rid = rid; // logic from old version, can we clean it up now?\n\t\t\t\tany.id = opt.run || ++root.once; // used in callback to check if we are earlier than a write. // will this ever cause an integer overflow?\n\t\t\t\ttmp = root.pass; (root.pass = {})[id] = 1; // Explanation: test trade-offs want to prevent recursion so we add/remove pass flag as it gets fulfilled to not repeat, however map map needs many pass flags - how do we reconcile?\n\t\t\t\topt.out = opt.out || {get: {}};\n\t\t\t\tcat.on('out', opt.out);\n\t\t\t\troot.pass = tmp;\n\t\t\t\treturn gun;\n\t\t\t} else\n\t\t\tif('number' == typeof key){\n\t\t\t\treturn this.get(''+key, cb, as);\n\t\t\t} else\n\t\t\tif('string' == typeof (tmp = valid(key))){\n\t\t\t\treturn this.get(tmp, cb, as);\n\t\t\t} else\n\t\t\tif(tmp = this.get.next){\n\t\t\t\tgun = tmp(this, key);\n\t\t\t}\n\t\t\tif(!gun){\n\t\t\t\t(gun = this.chain())._.err = {err: Gun.log('Invalid get request!', key)}; // CLEAN UP\n\t\t\t\tif(cb){ cb.call(gun, gun._.err) }\n\t\t\t\treturn gun;\n\t\t\t}\n\t\t\tif(cb && 'function' == typeof cb){\n\t\t\t\tgun.get(cb, as);\n\t\t\t}\n\t\t\treturn gun;\n\t\t}\n\t\tfunction cache(key, back){\n\t\t\tvar cat = back._, next = cat.next, gun = back.chain(), at = gun._;\n\t\t\tif(!next){ next = cat.next = {} }\n\t\t\tnext[at.get = key] = at;\n\t\t\tif(back === cat.root.$){\n\t\t\t\tat.soul = key;\n\t\t\t\t//at.put = {};\n\t\t\t} else\n\t\t\tif(cat.soul || cat.has){\n\t\t\t\tat.has = key;\n\t\t\t\t//if(obj_has(cat.put, key)){\n\t\t\t\t\t//at.put = cat.put[key];\n\t\t\t\t//}\n\t\t\t}\n\t\t\treturn at;\n\t\t}\n\t\tfunction soul(gun, cb, opt, as){\n\t\t\tvar cat = gun._, acks = 0, tmp;\n\t\t\tif(tmp = cat.soul || cat.link){ return cb(tmp, as, cat) }\n\t\t\tif(cat.jam){ return cat.jam.push([cb, as]) }\n\t\t\tcat.jam = [[cb,as]];\n\t\t\tgun.get(function go(msg, eve){\n\t\t\t\tif(u === msg.put && !cat.root.opt.super && (tmp = Object.keys(cat.root.opt.peers).length) && ++acks <= tmp){ // TODO: super should not be in core code, bring AXE up into core instead to fix? // TODO: .keys( is slow\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\teve.rid(msg);\n\t\t\t\tvar at = ((at = msg.$) && at._) || {}, i = 0, as;\n\t\t\t\ttmp = cat.jam; delete cat.jam; // tmp = cat.jam.splice(0, 100);\n\t\t\t\t//if(tmp.length){ process.nextTick(function(){ go(msg, eve) }) }\n\t\t\t\twhile(as = tmp[i++]){ //Gun.obj.map(tmp, function(as, cb){\n\t\t\t\t\tvar cb = as[0], id; as = as[1];\n\t\t\t\t\tcb && cb(id = at.link || at.soul || Gun.valid(msg.put) || ((msg.put||{})._||{})['#'], as, msg, eve);\n\t\t\t\t} //);\n\t\t\t}, {out: {get: {'.':true}}});\n\t\t\treturn gun;\n\t\t}\n\t\tfunction rid(at){\n\t\t\tvar cat = this.at || this.on;\n\t\t\tif(!at || cat.soul || cat.has){ return this.off() }\n\t\t\tif(!(at = (at = (at = at.$ || at)._ || at).id)){ return }\n\t\t\tvar map = cat.map, tmp, seen;\n\t\t\t//if(!map || !(tmp = map[at]) || !(tmp = tmp.at)){ return }\n\t\t\tif(tmp = (seen = this.seen || (this.seen = {}))[at]){ return true }\n\t\t\tseen[at] = true;\n\t\t\t//tmp.echo[cat.id] = {}; // TODO: Warning: This unsubscribes ALL of this chain's listeners from this link, not just the one callback event.\n\t\t\t//obj.del(map, at); // TODO: Warning: This unsubscribes ALL of this chain's listeners from this link, not just the one callback event.\n\t\t\treturn;\n\t\t}\n\t\tvar empty = {}, valid = Gun.valid, u;\n\t})(USE, './get');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tGun.chain.put = function(data, cb, as){ // I rewrote it :)\n\t\t\tvar gun = this, at = gun._, root = at.root;\n\t\t\tas = as || {};\n\t\t\tas.root = at.root;\n\t\t\tas.run || (as.run = root.once);\n\t\t\tstun(as, at.id); // set a flag for reads to check if this chain is writing.\n\t\t\tas.ack = as.ack || cb;\n\t\t\tas.via = as.via || gun;\n\t\t\tas.data = as.data || data;\n\t\t\tas.soul || (as.soul = at.soul || ('string' == typeof cb && cb));\n\t\t\tvar s = as.state = as.state || Gun.state();\n\t\t\tif('function' == typeof data){ data(function(d){ as.data = d; gun.put(u,u,as) }); return gun }\n\t\t\tif(!as.soul){ return get(as), gun }\n\t\t\tas.$ = root.$.get(as.soul); // TODO: This may not allow user chaining and similar?\n\t\t\tas.todo = [{it: as.data, ref: as.$}];\n\t\t\tas.turn = as.turn || turn;\n\t\t\tas.ran = as.ran || ran;\n\t\t\t//var path = []; as.via.back(at => { at.get && path.push(at.get.slice(0,9)) }); path = path.reverse().join('.');\n\t\t\t// TODO: Perf! We only need to stun chains that are being modified, not necessarily written to.\n\t\t\t(function walk(){\n\t\t\t\tvar to = as.todo, at = to.pop(), d = at.it, cid = at.ref && at.ref._.id, v, k, cat, tmp, g;\n\t\t\t\tstun(as, at.ref);\n\t\t\t\tif(tmp = at.todo){\n\t\t\t\t\tk = tmp.pop(); d = d[k];\n\t\t\t\t\tif(tmp.length){ to.push(at) }\n\t\t\t\t}\n\t\t\t\tk && (to.path || (to.path = [])).push(k);\n\t\t\t\tif(!(v = valid(d)) && !(g = Gun.is(d))){\n\t\t\t\t\tif(!Object.plain(d)){ ran.err(as, \"Invalid data: \"+ check(d) +\" at \" + (as.via.back(function(at){at.get && tmp.push(at.get)}, tmp = []) || tmp.join('.'))+'.'+(to.path||[]).join('.')); return }\n\t\t\t\t\tvar seen = as.seen || (as.seen = []), i = seen.length;\n\t\t\t\t\twhile(i--){ if(d === (tmp = seen[i]).it){ v = d = tmp.link; break } }\n\t\t\t\t}\n\t\t\t\tif(k && v){ at.node = state_ify(at.node, k, s, d) } // handle soul later.\n\t\t\t\telse {\n\t\t\t\t\tif(!as.seen){ ran.err(as, \"Data at root of graph must be a node (an object).\"); return }\n\t\t\t\t\tas.seen.push(cat = {it: d, link: {}, todo: g? [] : Object.keys(d).sort().reverse(), path: (to.path||[]).slice(), up: at}); // Any perf reasons to CPU schedule this .keys( ?\n\t\t\t\t\tat.node = state_ify(at.node, k, s, cat.link);\n\t\t\t\t\t!g && cat.todo.length && to.push(cat);\n\t\t\t\t\t// ---------------\n\t\t\t\t\tvar id = as.seen.length;\n\t\t\t\t\t(as.wait || (as.wait = {}))[id] = '';\n\t\t\t\t\ttmp = (cat.ref = (g? d : k? at.ref.get(k) : at.ref))._;\n\t\t\t\t\t(tmp = (d && (d._||'')['#']) || tmp.soul || tmp.link)? resolve({soul: tmp}) : cat.ref.get(resolve, {run: as.run, /*hatch: 0,*/ v2020:1, out:{get:{'.':' '}}}); // TODO: BUG! This should be resolve ONLY soul to prevent full data from being loaded. // Fixed now?\n\t\t\t\t\t//setTimeout(function(){ if(F){ return } console.log(\"I HAVE NOT BEEN CALLED!\", path, id, cat.ref._.id, k) }, 9000); var F; // MAKE SURE TO ADD F = 1 below!\n\t\t\t\t\tfunction resolve(msg, eve){\n\t\t\t\t\t\tvar end = cat.link['#'];\n\t\t\t\t\t\tif(eve){ eve.off(); eve.rid(msg) } // TODO: Too early! Check all peers ack not found.\n\t\t\t\t\t\t// TODO: BUG maybe? Make sure this does not pick up a link change wipe, that it uses the changign link instead.\n\t\t\t\t\t\tvar soul = end || msg.soul || (tmp = (msg.$$||msg.$)._||'').soul || tmp.link || ((tmp = tmp.put||'')._||'')['#'] || tmp['#'] || (((tmp = msg.put||'') && msg.$$)? tmp['#'] : (tmp['=']||tmp[':']||'')['#']);\n\t\t\t\t\t\t!end && stun(as, msg.$);\n\t\t\t\t\t\tif(!soul && !at.link['#']){ // check soul link above us\n\t\t\t\t\t\t\t(at.wait || (at.wait = [])).push(function(){ resolve(msg, eve) }) // wait\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(!soul){\n\t\t\t\t\t\t\tsoul = [];\n\t\t\t\t\t\t\t(msg.$$||msg.$).back(function(at){\n\t\t\t\t\t\t\t\tif(tmp = at.soul || at.link){ return soul.push(tmp) }\n\t\t\t\t\t\t\t\tsoul.push(at.get);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tsoul = soul.reverse().join('/');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcat.link['#'] = soul;\n\t\t\t\t\t\t!g && (((as.graph || (as.graph = {}))[soul] = (cat.node || (cat.node = {_:{}})))._['#'] = soul);\n\t\t\t\t\t\tdelete as.wait[id];\n\t\t\t\t\t\tcat.wait && setTimeout.each(cat.wait, function(cb){ cb && cb() });\n\t\t\t\t\t\tas.ran(as);\n\t\t\t\t\t};\n\t\t\t\t\t// ---------------\n\t\t\t\t}\n\t\t\t\tif(!to.length){ return as.ran(as) }\n\t\t\t\tas.turn(walk);\n\t\t\t}());\n\t\t\treturn gun;\n\t\t}\n\n\t\tfunction stun(as, id){\n\t\t\tif(!id){ return } id = (id._||'').id||id;\n\t\t\tvar run = as.root.stun || (as.root.stun = {on: Gun.on}), test = {}, tmp;\n\t\t\tas.stun || (as.stun = run.on('stun', function(){ }));\n\t\t\tif(tmp = run.on(''+id)){ tmp.the.last.next(test) }\n\t\t\tif(test.run >= as.run){ return }\n\t\t\trun.on(''+id, function(test){\n\t\t\t\tif(as.stun.end){\n\t\t\t\t\tthis.off();\n\t\t\t\t\tthis.to.next(test);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttest.run = test.run || as.run;\n\t\t\t\ttest.stun = test.stun || as.stun; return;\n\t\t\t\tif(this.to.to){\n\t\t\t\t\tthis.the.last.next(test);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttest.stun = as.stun;\n\t\t\t});\n\t\t}\n\n\t\tfunction ran(as){\n\t\t\tif(as.err){ ran.end(as.stun, as.root); return } // move log handle here.\n\t\t\tif(as.todo.length || as.end || !Object.empty(as.wait)){ return } as.end = 1;\n\t\t\t//(as.retry = function(){ as.acks = 0;\n\t\t\tvar cat = (as.$.back(-1)._), root = cat.root, ask = cat.ask(function(ack){\n\t\t\t\troot.on('ack', ack);\n\t\t\t\tif(ack.err && !ack.lack){ Gun.log(ack) }\n\t\t\t\tif(++acks > (as.acks || 0)){ this.off() } // Adjustable ACKs! Only 1 by default.\n\t\t\t\tif(!as.ack){ return }\n\t\t\t\tas.ack(ack, this);\n\t\t\t}, as.opt), acks = 0, stun = as.stun, tmp;\n\t\t\t(tmp = function(){ // this is not official yet, but quick solution to hack in for now.\n\t\t\t\tif(!stun){ return }\n\t\t\t\tran.end(stun, root);\n\t\t\t\tsetTimeout.each(Object.keys(stun = stun.add||''), function(cb){ if(cb = stun[cb]){cb()} }); // resume the stunned reads // Any perf reasons to CPU schedule this .keys( ?\n\t\t\t}).hatch = tmp; // this is not official yet ^\n\t\t\t//console.log(1, \"PUT\", as.run, as.graph);\n\t\t\tif(as.ack && !as.ok){ as.ok = as.acks || 9 } // TODO: In future! Remove this! This is just old API support.\n\t\t\t(as.via._).on('out', {put: as.out = as.graph, ok: as.ok && {'@': as.ok+1}, opt: as.opt, '#': ask, _: tmp});\n\t\t\t//})();\n\t\t}; ran.end = function(stun,root){\n\t\t\tstun.end = noop; // like with the earlier id, cheaper to make this flag a function so below callbacks do not have to do an extra type check.\n\t\t\tif(stun.the.to === stun && stun === stun.the.last){ delete root.stun }\n\t\t\tstun.off();\n\t\t}; ran.err = function(as, err){\n\t\t\t(as.ack||noop).call(as, as.out = { err: as.err = Gun.log(err) });\n\t\t\tas.ran(as);\n\t\t}\n\n\t\tfunction get(as){\n\t\t\tvar at = as.via._, tmp;\n\t\t\tas.via = as.via.back(function(at){\n\t\t\t\tif(at.soul || !at.get){ return at.$ }\n\t\t\t\ttmp = as.data; (as.data = {})[at.get] = tmp;\n\t\t\t});\n\t\t\tif(!as.via || !as.via._.soul){\n\t\t\t\tas.via = at.root.$.get(((as.data||'')._||'')['#'] || at.$.back('opt.uuid')())\n\t\t\t}\n\t\t\tas.via.put(as.data, as.ack, as);\n\t\t\t\n\n\t\t\treturn;\n\t\t\tif(at.get && at.back.soul){\n\t\t\t\ttmp = as.data;\n\t\t\t\tas.via = at.back.$;\n\t\t\t\t(as.data = {})[at.get] = tmp; \n\t\t\t\tas.via.put(as.data, as.ack, as);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tfunction check(d, tmp){ return ((d && (tmp = d.constructor) && tmp.name) || typeof d) }\n\n\t\tvar u, empty = {}, noop = function(){}, turn = setTimeout.turn, valid = Gun.valid, state_ify = Gun.state.ify;\n\t\tvar iife = function(fn,as){fn.call(as||empty)}\n\t})(USE, './put');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tUSE('./chain');\n\t\tUSE('./back');\n\t\tUSE('./put');\n\t\tUSE('./get');\n\t\tmodule.exports = Gun;\n\t})(USE, './core');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tUSE('./shim');\n\t\tUSE('./onto');\n\t\tUSE('./book');\n\t\tUSE('./valid');\n\t\tUSE('./state');\n\t\tUSE('./dup');\n\t\tUSE('./ask');\n\t\tUSE('./core');\n\t\tUSE('./on');\n\t\tUSE('./map');\n\t\tUSE('./set');\n\t\tUSE('./mesh');\n\t\tUSE('./websocket');\n\t\tUSE('./localStorage');\n\t\tmodule.exports = Gun;\n\t})(USE, './index');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tGun.chain.on = function(tag, arg, eas, as){ // don't rewrite!\n\t\t\tvar gun = this, cat = gun._, root = cat.root, act, off, id, tmp;\n\t\t\tif(typeof tag === 'string'){\n\t\t\t\tif(!arg){ return cat.on(tag) }\n\t\t\t\tact = cat.on(tag, arg, eas || cat, as);\n\t\t\t\tif(eas && eas.$){\n\t\t\t\t\t(eas.subs || (eas.subs = [])).push(act);\n\t\t\t\t}\n\t\t\t\treturn gun;\n\t\t\t}\n\t\t\tvar opt = arg;\n\t\t\t(opt = (true === opt)? {change: true} : opt || {}).not = 1; opt.on = 1;\n\t\t\t//opt.at = cat;\n\t\t\t//opt.ok = tag;\n\t\t\t//opt.last = {};\n\t\t\tvar wait = {}; // can we assign this to the at instead, like in once?\n\t\t\tgun.get(tag, opt);\n\t\t\t/*gun.get(function on(data,key,msg,eve){ var $ = this;\n\t\t\t\tif(tmp = root.hatch){ // quick hack!\n\t\t\t\t\tif(wait[$._.id]){ return } wait[$._.id] = 1;\n\t\t\t\t\ttmp.push(function(){on.call($, data,key,msg,eve)});\n\t\t\t\t\treturn;\n\t\t\t\t}; wait = {}; // end quick hack.\n\t\t\t\ttag.call($, data,key,msg,eve);\n\t\t\t}, opt); // TODO: PERF! Event listener leak!!!?*/\n\t\t\t/*\n\t\t\tfunction one(msg, eve){\n\t\t\t\tif(one.stun){ return }\n\t\t\t\tvar at = msg.$._, data = at.put, tmp;\n\t\t\t\tif(tmp = at.link){ data = root.$.get(tmp)._.put }\n\t\t\t\tif(opt.not===u && u === data){ return }\n\t\t\t\tif(opt.stun===u && (tmp = root.stun) && (tmp = tmp[at.id] || tmp[at.back.id]) && !tmp.end){ // Remember! If you port this into `.get(cb` make sure you allow stun:0 skip option for `.put(`.\n\t\t\t\t\ttmp[id] = function(){one(msg,eve)};\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t//tmp = one.wait || (one.wait = {}); console.log(tmp[at.id] === ''); if(tmp[at.id] !== ''){ tmp[at.id] = tmp[at.id] || setTimeout(function(){tmp[at.id]='';one(msg,eve)},1); return } delete tmp[at.id];\n\t\t\t\t// call:\n\t\t\t\tif(opt.as){\n\t\t\t\t\topt.ok.call(opt.as, msg, eve || one);\n\t\t\t\t} else {\n\t\t\t\t\topt.ok.call(at.$, data, msg.get || at.get, msg, eve || one);\n\t\t\t\t}\n\t\t\t};\n\t\t\tone.at = cat;\n\t\t\t(cat.act||(cat.act={}))[id = String.random(7)] = one;\n\t\t\tone.off = function(){ one.stun = 1; if(!cat.act){ return } delete cat.act[id] }\n\t\t\tcat.on('out', {get: {}});*/\n\t\t\treturn gun;\n\t\t}\n\t\t// Rules:\n\t\t// 1. If cached, should be fast, but not read while write.\n\t\t// 2. Should not retrigger other listeners, should get triggered even if nothing found.\n\t\t// 3. If the same callback passed to many different once chains, each should resolve - an unsubscribe from the same callback should not effect the state of the other resolving chains, if you do want to cancel them all early you should mutate the callback itself with a flag & check for it at top of callback\n\t\tGun.chain.once = function(cb, opt){ opt = opt || {}; // avoid rewriting\n\t\t\tif(!cb){ return none(this,opt) }\n\t\t\tvar gun = this, cat = gun._, root = cat.root, data = cat.put, id = String.random(7), one, tmp;\n\t\t\tgun.get(function(data,key,msg,eve){\n\t\t\t\tvar $ = this, at = $._, one = (at.one||(at.one={}));\n\t\t\t\tif(eve.stun){ return } if('' === one[id]){ return }\n\t\t\t\tif(true === (tmp = Gun.valid(data))){ once(); return }\n\t\t\t\tif('string' == typeof tmp){ return } // TODO: BUG? Will this always load?\n\t\t\t\tclearTimeout((cat.one||'')[id]); // clear \"not found\" since they only get set on cat.\n\t\t\t\tclearTimeout(one[id]); one[id] = setTimeout(once, opt.wait||99); // TODO: Bug? This doesn't handle plural chains.\n\t\t\t\tfunction once(f){\n\t\t\t\t\tif(!at.has && !at.soul){ at = {put: data, get: key} } // handles non-core messages.\n\t\t\t\t\tif(u === (tmp = at.put)){ tmp = ((msg.$$||'')._||'').put }\n\t\t\t\t\tif('string' == typeof Gun.valid(tmp)){\n\t\t\t\t\t\ttmp = root.$.get(tmp)._.put;\n\t\t\t\t\t\tif(tmp === u && !f){\n\t\t\t\t\t\t\tone[id] = setTimeout(function(){ once(1) }, opt.wait||99); // TODO: Quick fix. Maybe use ack count for more predictable control?\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t//console.log(\"AND VANISHED\", data);\n\t\t\t\t\tif(eve.stun){ return } if('' === one[id]){ return } one[id] = '';\n\t\t\t\t\tif(cat.soul || cat.has){ eve.off() } // TODO: Plural chains? // else { ?.off() } // better than one check?\n\t\t\t\t\tcb.call($, tmp, at.get);\n\t\t\t\t\tclearTimeout(one[id]); // clear \"not found\" since they only get set on cat. // TODO: This was hackily added, is it necessary or important? Probably not, in future try removing this. Was added just as a safety for the `&& !f` check.\n\t\t\t\t};\n\t\t\t}, {on: 1});\n\t\t\treturn gun;\n\t\t}\n\t\tfunction none(gun,opt,chain){\n\t\t\tGun.log.once(\"valonce\", \"Chainable val is experimental, its behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it.\");\n\t\t\t(chain = gun.chain())._.nix = gun.once(function(data, key){ chain._.on('in', this._) });\n\t\t\tchain._.lex = gun._.lex; // TODO: Better approach in future? This is quick for now.\n\t\t\treturn chain;\n\t\t}\n\n\t\tGun.chain.off = function(){\n\t\t\t// make off more aggressive. Warning, it might backfire!\n\t\t\tvar gun = this, at = gun._, tmp;\n\t\t\tvar cat = at.back;\n\t\t\tif(!cat){ return }\n\t\t\tat.ack = 0; // so can resubscribe.\n\t\t\tif(tmp = cat.next){\n\t\t\t\tif(tmp[at.get]){\n\t\t\t\t\tdelete tmp[at.get];\n\t\t\t\t} else {\n\n\t\t\t\t}\n\t\t\t}\n\t\t\t// TODO: delete cat.one[map.id]?\n\t\t\tif (tmp = cat.any) {\n\t\t\t\tdelete cat.any;\n\t\t\t\tcat.any = {};\n\t\t\t}\n\t\t\tif(tmp = cat.ask){\n\t\t\t\tdelete tmp[at.get];\n\t\t\t}\n\t\t\tif(tmp = cat.put){\n\t\t\t\tdelete tmp[at.get];\n\t\t\t}\n\t\t\tif(tmp = at.soul){\n\t\t\t\tdelete cat.root.graph[tmp];\n\t\t\t}\n\t\t\tif(tmp = at.map){\n\t\t\t\tObject.keys(tmp).forEach(function(i,at){ at = tmp[i]; //obj_map(tmp, function(at){\n\t\t\t\t\tif(at.link){\n\t\t\t\t\t\tcat.root.$.get(at.link).off();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tif(tmp = at.next){\n\t\t\t\tObject.keys(tmp).forEach(function(i,neat){ neat = tmp[i]; //obj_map(tmp, function(neat){\n\t\t\t\t\tneat.$.off();\n\t\t\t\t});\n\t\t\t}\n\t\t\tat.on('off', {});\n\t\t\treturn gun;\n\t\t}\n\t\tvar empty = {}, noop = function(){}, u;\n\t})(USE, './on');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root'), next = Gun.chain.get.next;\n\t\tGun.chain.get.next = function(gun, lex){ var tmp;\n\t\t\tif(!Object.plain(lex)){ return (next||noop)(gun, lex) }\n\t\t\tif(tmp = ((tmp = lex['#'])||'')['='] || tmp){ return gun.get(tmp) }\n\t\t\t(tmp = gun.chain()._).lex = lex; // LEX!\n\t\t\tgun.on('in', function(eve){\n\t\t\t\tif(String.match(eve.get|| (eve.put||'')['.'], lex['.'] || lex['#'] || lex)){\n\t\t\t\t\ttmp.on('in', eve);\n\t\t\t\t}\n\t\t\t\tthis.to.next(eve);\n\t\t\t});\n\t\t\treturn tmp.$;\n\t\t}\n\t\tGun.chain.map = function(cb, opt, t){\n\t\t\tvar gun = this, cat = gun._, lex, chain;\n\t\t\tif(Object.plain(cb)){ lex = cb['.']? cb : {'.': cb}; cb = u }\n\t\t\tif(!cb){\n\t\t\t\tif(chain = cat.each){ return chain }\n\t\t\t\t(cat.each = chain = gun.chain())._.lex = lex || chain._.lex || cat.lex;\n\t\t\t\tchain._.nix = gun.back('nix');\n\t\t\t\tgun.on('in', map, chain._);\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tGun.log.once(\"mapfn\", \"Map functions are experimental, their behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it.\");\n\t\t\tchain = gun.chain();\n\t\t\tgun.map().on(function(data, key, msg, eve){\n\t\t\t\tvar next = (cb||noop).call(this, data, key, msg, eve);\n\t\t\t\tif(u === next){ return }\n\t\t\t\tif(data === next){ return chain._.on('in', msg) }\n\t\t\t\tif(Gun.is(next)){ return chain._.on('in', next._) }\n\t\t\t\tvar tmp = {}; Object.keys(msg.put).forEach(function(k){ tmp[k] = msg.put[k] }, tmp); tmp['='] = next; \n\t\t\t\tchain._.on('in', {get: key, put: tmp});\n\t\t\t});\n\t\t\treturn chain;\n\t\t}\n\t\tfunction map(msg){ this.to.next(msg);\n\t\t\tvar cat = this.as, gun = msg.$, at = gun._, put = msg.put, tmp;\n\t\t\tif(!at.soul && !msg.$$){ return } // this line took hundreds of tries to figure out. It only works if core checks to filter out above chains during link tho. This says \"only bother to map on a node\" for this layer of the chain. If something is not a node, map should not work.\n\t\t\tif((tmp = cat.lex) && !String.match(msg.get|| (put||'')['.'], tmp['.'] || tmp['#'] || tmp)){ return }\n\t\t\tGun.on.link(msg, cat);\n\t\t}\n\t\tvar noop = function(){}, event = {stun: noop, off: noop}, u;\n\t})(USE, './map');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tGun.chain.set = function(item, cb, opt){\n\t\t\tvar gun = this, root = gun.back(-1), soul, tmp;\n\t\t\tcb = cb || function(){};\n\t\t\topt = opt || {}; opt.item = opt.item || item;\n\t\t\tif(soul = ((item||'')._||'')['#']){ (item = {})['#'] = soul } // check if node, make link.\n\t\t\tif('string' == typeof (tmp = Gun.valid(item))){ return gun.get(soul = tmp).put(item, cb, opt) } // check if link\n\t\t\tif(!Gun.is(item)){\n\t\t\t\tif(Object.plain(item)){\n\t\t\t\t\titem = root.get(soul = gun.back('opt.uuid')()).put(item);\n\t\t\t\t}\n\t\t\t\treturn gun.get(soul || root.back('opt.uuid')(7)).put(item, cb, opt);\n\t\t\t}\n\t\t\tgun.put(function(go){\n\t\t\t\titem.get(function(soul, o, msg){ // TODO: BUG! We no longer have this option? & go error not handled?\n\t\t\t\t\tif(!soul){ return cb.call(gun, {err: Gun.log('Only a node can be linked! Not \"' + msg.put + '\"!')}) }\n\t\t\t\t\t(tmp = {})[soul] = {'#': soul}; go(tmp);\n\t\t\t\t},true);\n\t\t\t})\n\t\t\treturn item;\n\t\t}\n\t})(USE, './set');\n\n\t;USE(function(module){\n\t\tUSE('./shim');\n\n\t\tvar noop = function(){}\n\t\tvar parse = JSON.parseAsync || function(t,cb,r){ var u, d = +new Date; try{ cb(u, JSON.parse(t,r), json.sucks(+new Date - d)) }catch(e){ cb(e) } }\n\t\tvar json = JSON.stringifyAsync || function(v,cb,r,s){ var u, d = +new Date; try{ cb(u, JSON.stringify(v,r,s), json.sucks(+new Date - d)) }catch(e){ cb(e) } }\n\t\tjson.sucks = function(d){ if(d > 99){ console.log(\"Warning: JSON blocking CPU detected. Add `gun/lib/yson.js` to fix.\"); json.sucks = noop } }\n\n\t\tfunction Mesh(root){\n\t\t\tvar mesh = function(){};\n\t\t\tvar opt = root.opt || {};\n\t\t\topt.log = opt.log || console.log;\n\t\t\topt.gap = opt.gap || opt.wait || 0;\n\t\t\topt.max = opt.max || (opt.memory? (opt.memory * 999 * 999) : 300000000) * 0.3;\n\t\t\topt.pack = opt.pack || (opt.max * 0.01 * 0.01);\n\t\t\topt.puff = opt.puff || 9; // IDEA: do a start/end benchmark, divide ops/result.\n\t\t\tvar puff = setTimeout.turn || setTimeout;\n\n\t\t\tvar dup = root.dup, dup_check = dup.check, dup_track = dup.track;\n\n\t\t\tvar ST = +new Date, LT = ST;\n\n\t\t\tvar hear = mesh.hear = function(raw, peer){\n\t\t\t\tif(!raw){ return }\n\t\t\t\tif(opt.max <= raw.length){ return mesh.say({dam: '!', err: \"Message too big!\"}, peer) }\n\t\t\t\tif(mesh === this){\n\t\t\t\t\t/*if('string' == typeof raw){ try{\n\t\t\t\t\t\tvar stat = console.STAT || {};\n\t\t\t\t\t\t//console.log('HEAR:', peer.id, (raw||'').slice(0,250), ((raw||'').length / 1024 / 1024).toFixed(4));\n\t\t\t\t\t\t\n\t\t\t\t\t\t//console.log(setTimeout.turn.s.length, 'stacks', parseFloat((-(LT - (LT = +new Date))/1000).toFixed(3)), 'sec', parseFloat(((LT-ST)/1000 / 60).toFixed(1)), 'up', stat.peers||0, 'peers', stat.has||0, 'has', stat.memhused||0, stat.memused||0, stat.memax||0, 'heap mem max');\n\t\t\t\t\t}catch(e){ console.log('DBG err', e) }}*/\n\t\t\t\t\thear.d += raw.length||0 ; ++hear.c } // STATS!\n\t\t\t\tvar S = peer.SH = +new Date;\n\t\t\t\tvar tmp = raw[0], msg;\n\t\t\t\t//raw && raw.slice && console.log(\"hear:\", ((peer.wire||'').headers||'').origin, raw.length, raw.slice && raw.slice(0,50)); //tc-iamunique-tc-package-ds1\n\t\t\t\tif('[' === tmp){\n\t\t\t\t\tparse(raw, function(err, msg){\n\t\t\t\t\t\tif(err || !msg){ return mesh.say({dam: '!', err: \"DAM JSON parse error.\"}, peer) }\n\t\t\t\t\t\tconsole.STAT && console.STAT(+new Date, msg.length, '# on hear batch');\n\t\t\t\t\t\tvar P = opt.puff;\n\t\t\t\t\t\t(function go(){\n\t\t\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\t\t\tvar i = 0, m; while(i < P && (m = msg[i++])){ mesh.hear(m, peer) }\n\t\t\t\t\t\t\tmsg = msg.slice(i); // slicing after is faster than shifting during.\n\t\t\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'hear loop');\n\t\t\t\t\t\t\tflush(peer); // force send all synchronously batched acks.\n\t\t\t\t\t\t\tif(!msg.length){ return }\n\t\t\t\t\t\t\tpuff(go, 0);\n\t\t\t\t\t\t}());\n\t\t\t\t\t});\n\t\t\t\t\traw = ''; // \n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif('{' === tmp || ((raw['#'] || Object.plain(raw)) && (msg = raw))){\n\t\t\t\t\tif(msg){ return hear.one(msg, peer, S) }\n\t\t\t\t\tparse(raw, function(err, msg){\n\t\t\t\t\t\tif(err || !msg){ return mesh.say({dam: '!', err: \"DAM JSON parse error.\"}, peer) }\n\t\t\t\t\t\thear.one(msg, peer, S);\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\thear.one = function(msg, peer, S){ // S here is temporary! Undo.\n\t\t\t\tvar id, hash, tmp, ash, DBG;\n\t\t\t\tif(msg.DBG){ msg.DBG = DBG = {DBG: msg.DBG} }\n\t\t\t\tDBG && (DBG.h = S);\n\t\t\t\tDBG && (DBG.hp = +new Date);\n\t\t\t\tif(!(id = msg['#'])){ id = msg['#'] = String.random(9) }\n\t\t\t\tif(tmp = dup_check(id)){ return }\n\t\t\t\t// DAM logic:\n\t\t\t\tif(!(hash = msg['##']) && false && u !== msg.put){ /*hash = msg['##'] = Type.obj.hash(msg.put)*/ } // disable hashing for now // TODO: impose warning/penalty instead (?)\n\t\t\t\tif(hash && (tmp = msg['@'] || (msg.get && id)) && dup.check(ash = tmp+hash)){ return } // Imagine A <-> B <=> (C & D), C & D reply with same ACK but have different IDs, B can use hash to dedup. Or if a GET has a hash already, we shouldn't ACK if same.\n\t\t\t\t(msg._ = function(){}).via = mesh.leap = peer;\n\t\t\t\tif((tmp = msg['><']) && 'string' == typeof tmp){ tmp.slice(0,99).split(',').forEach(function(k){ this[k] = 1 }, (msg._).yo = {}) } // Peers already sent to, do not resend.\n\t\t\t\t// DAM ^\n\t\t\t\tif(tmp = msg.dam){\n\t\t\t\t\t(dup_track(id)||{}).via = peer;\n\t\t\t\t\tif(tmp = mesh.hear[tmp]){\n\t\t\t\t\t\ttmp(msg, peer, root);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(tmp = msg.ok){ msg._.near = tmp['/'] }\n\t\t\t\tvar S = +new Date;\n\t\t\t\tDBG && (DBG.is = S); peer.SI = id;\n\t\t\t\tdup_track.ed = function(d){\n\t\t\t\t\tif(id !== d){ return }\n\t\t\t\t\tdup_track.ed = 0;\n\t\t\t\t\tif(!(d = dup.s[id])){ return }\n\t\t\t\t\td.via = peer;\n\t\t\t\t\tif(msg.get){ d.it = msg }\n\t\t\t\t}\n\t\t\t\troot.on('in', mesh.last = msg);\n\t\t\t\tDBG && (DBG.hd = +new Date);\n\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, msg.get? 'msg get' : msg.put? 'msg put' : 'msg');\n\t\t\t\tdup_track(id); // in case 'in' does not call track.\n\t\t\t\tif(ash){ dup_track(ash) } //dup.track(tmp+hash, true).it = it(msg);\n\t\t\t\tmesh.leap = mesh.last = null; // warning! mesh.leap could be buggy.\n\t\t\t}\n\t\t\tvar tomap = function(k,i,m){m(k,true)};\n\t\t\thear.c = hear.d = 0;\n\n\t\t\t;(function(){\n\t\t\t\tvar SMIA = 0;\n\t\t\t\tvar loop;\n\t\t\t\tmesh.hash = function(msg, peer){ var h, s, t;\n\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\tjson(msg.put, function hash(err, text){\n\t\t\t\t\t\tvar ss = (s || (s = t = text||'')).slice(0, 32768); // 1024 * 32\n\t\t\t\t\t  h = String.hash(ss, h); s = s.slice(32768);\n\t\t\t\t\t  if(s){ puff(hash, 0); return }\n\t\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'say json+hash');\n\t\t\t\t\t  msg._.$put = t;\n\t\t\t\t\t  msg['##'] = h;\n\t\t\t\t\t  mesh.say(msg, peer);\n\t\t\t\t\t  delete msg._.$put;\n\t\t\t\t\t}, sort);\n\t\t\t\t}\n\t\t\t\tfunction sort(k, v){ var tmp;\n\t\t\t\t\tif(!(v instanceof Object)){ return v }\n\t\t\t\t\tObject.keys(v).sort().forEach(sorta, {to: tmp = {}, on: v});\n\t\t\t\t\treturn tmp;\n\t\t\t\t} function sorta(k){ this.to[k] = this.on[k] }\n\n\t\t\t\tvar say = mesh.say = function(msg, peer){ var tmp;\n\t\t\t\t\tif((tmp = this) && (tmp = tmp.to) && tmp.next){ tmp.next(msg) } // compatible with middleware adapters.\n\t\t\t\t\tif(!msg){ return false }\n\t\t\t\t\tvar id, hash, raw, ack = msg['@'];\n//if(opt.super && (!ack || !msg.put)){ return } // TODO: MANHATTAN STUB //OBVIOUSLY BUG! But squelch relay. // :( get only is 100%+ CPU usage :(\n\t\t\t\t\tvar meta = msg._||(msg._=function(){});\n\t\t\t\t\tvar DBG = msg.DBG, S = +new Date; meta.y = meta.y || S; if(!peer){ DBG && (DBG.y = S) }\n\t\t\t\t\tif(!(id = msg['#'])){ id = msg['#'] = String.random(9) }\n\t\t\t\t\t!loop && dup_track(id);//.it = it(msg); // track for 9 seconds, default. Earth<->Mars would need more! // always track, maybe move this to the 'after' logic if we split function.\n\t\t\t\t\t//if(msg.put && (msg.err || (dup.s[id]||'').err)){ return false } // TODO: in theory we should not be able to stun a message, but for now going to check if it can help network performance preventing invalid data to relay.\n\t\t\t\t\tif(!(hash = msg['##']) && u !== msg.put && !meta.via && ack){ mesh.hash(msg, peer); return } // TODO: Should broadcasts be hashed?\n\t\t\t\t\tif(!peer && ack){ peer = ((tmp = dup.s[ack]) && (tmp.via || ((tmp = tmp.it) && (tmp = tmp._) && tmp.via))) || ((tmp = mesh.last) && ack === tmp['#'] && mesh.leap) } // warning! mesh.leap could be buggy! mesh last check reduces this. // TODO: CLEAN UP THIS LINE NOW? `.it` should be reliable.\n\t\t\t\t\tif(!peer && ack){ // still no peer, then ack daisy chain 'tunnel' got lost.\n\t\t\t\t\t\tif(dup.s[ack]){ return } // in dups but no peer hints that this was ack to ourself, ignore.\n\t\t\t\t\t\tconsole.STAT && console.STAT(+new Date, ++SMIA, 'total no peer to ack to'); // TODO: Delete this now. Dropping lost ACKs is protocol fine now.\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} // TODO: Temporary? If ack via trace has been lost, acks will go to all peers, which trashes browser bandwidth. Not relaying the ack will force sender to ask for ack again. Note, this is technically wrong for mesh behavior.\n\t\t\t\t\tif(ack && !msg.put && !hash && ((dup.s[ack]||'').it||'')['##']){ return false } // If we're saying 'not found' but a relay had data, do not bother sending our not found. // Is this correct, return false? // NOTE: ADD PANIC TEST FOR THIS!\n\t\t\t\t\tif(!peer && mesh.way){ return mesh.way(msg) }\n\t\t\t\t\tDBG && (DBG.yh = +new Date);\n\t\t\t\t\tif(!(raw = meta.raw)){ mesh.raw(msg, peer); return }\n\t\t\t\t\tDBG && (DBG.yr = +new Date);\n\t\t\t\t\tif(!peer || !peer.id){\n\t\t\t\t\t\tif(!Object.plain(peer || opt.peers)){ return false }\n\t\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\t\tvar P = opt.puff, ps = opt.peers, pl = Object.keys(peer || opt.peers || {}); // TODO: .keys( is slow\n\t\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'peer keys');\n\t\t\t\t\t\t;(function go(){\n\t\t\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\t\t\t//Type.obj.map(peer || opt.peers, each); // in case peer is a peer list.\n\t\t\t\t\t\t\tloop = 1; var wr = meta.raw; meta.raw = raw; // quick perf hack\n\t\t\t\t\t\t\tvar i = 0, p; while(i < 9 && (p = (pl||'')[i++])){\n\t\t\t\t\t\t\t\tif(!(p = ps[p] || (peer||'')[p])){ continue }\n\t\t\t\t\t\t\t\tmesh.say(msg, p);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmeta.raw = wr; loop = 0;\n\t\t\t\t\t\t\tpl = pl.slice(i); // slicing after is faster than shifting during.\n\t\t\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'say loop');\n\t\t\t\t\t\t\tif(!pl.length){ return }\n\t\t\t\t\t\t\tpuff(go, 0);\n\t\t\t\t\t\t\tack && dup_track(ack); // keep for later\n\t\t\t\t\t\t}());\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// TODO: PERF: consider splitting function here, so say loops do less work.\n\t\t\t\t\tif(!peer.wire && mesh.wire){ mesh.wire(peer) }\n\t\t\t\t\tif(id === peer.last){ return } peer.last = id;  // was it just sent?\n\t\t\t\t\tif(peer === meta.via){ return false } // don't send back to self.\n\t\t\t\t\tif((tmp = meta.yo) && (tmp[peer.url] || tmp[peer.pid] || tmp[peer.id]) /*&& !o*/){ return false }\n\t\t\t\t\tconsole.STAT && console.STAT(S, ((DBG||meta).yp = +new Date) - (meta.y || S), 'say prep');\n\t\t\t\t\t!loop && ack && dup_track(ack); // streaming long responses needs to keep alive the ack.\n\t\t\t\t\tif(peer.batch){\n\t\t\t\t\t\tpeer.tail = (tmp = peer.tail || 0) + raw.length;\n\t\t\t\t\t\tif(peer.tail <= opt.pack){\n\t\t\t\t\t\t\tpeer.batch += (tmp?',':'')+raw;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tflush(peer);\n\t\t\t\t\t}\n\t\t\t\t\tpeer.batch = '['; // Prevents double JSON!\n\t\t\t\t\tvar ST = +new Date;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tconsole.STAT && console.STAT(ST, +new Date - ST, '0ms TO');\n\t\t\t\t\t\tflush(peer);\n\t\t\t\t\t}, opt.gap); // TODO: queuing/batching might be bad for low-latency video game performance! Allow opt out?\n\t\t\t\t\tsend(raw, peer);\n\t\t\t\t\tconsole.STAT && (ack === peer.SI) && console.STAT(S, +new Date - peer.SH, 'say ack');\n\t\t\t\t}\n\t\t\t\tmesh.say.c = mesh.say.d = 0;\n\t\t\t\t// TODO: this caused a out-of-memory crash!\n\t\t\t\tmesh.raw = function(msg, peer){ // TODO: Clean this up / delete it / move logic out!\n\t\t\t\t\tif(!msg){ return '' }\n\t\t\t\t\tvar meta = (msg._) || {}, put, tmp;\n\t\t\t\t\tif(tmp = meta.raw){ return tmp }\n\t\t\t\t\tif('string' == typeof msg){ return msg }\n\t\t\t\t\tvar hash = msg['##'], ack = msg['@'];\n\t\t\t\t\tif(hash && ack){\n\t\t\t\t\t\tif(!meta.via && dup_check(ack+hash)){ return false } // for our own out messages, memory & storage may ack the same thing, so dedup that. Tho if via another peer, we already tracked it upon hearing, so this will always trigger false positives, so don't do that!\n\t\t\t\t\t\tif(tmp = (dup.s[ack]||'').it){\n\t\t\t\t\t\t\tif(hash === tmp['##']){ return false } // if ask has a matching hash, acking is optional.\n\t\t\t\t\t\t\tif(!tmp['##']){ tmp['##'] = hash } // if none, add our hash to ask so anyone we relay to can dedup. // NOTE: May only check against 1st ack chunk, 2nd+ won't know and still stream back to relaying peers which may then dedup. Any way to fix this wasted bandwidth? I guess force rate limiting breaking change, that asking peer has to ask for next lexical chunk.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(!msg.dam && !msg['@']){\n\t\t\t\t\t\tvar i = 0, to = []; tmp = opt.peers;\n\t\t\t\t\t\tfor(var k in tmp){ var p = tmp[k]; // TODO: Make it up peers instead!\n\t\t\t\t\t\t\tto.push(p.url || p.pid || p.id);\n\t\t\t\t\t\t\tif(++i > 6){ break }\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(i > 1){ msg['><'] = to.join() } // TODO: BUG! This gets set regardless of peers sent to! Detect?\n\t\t\t\t\t}\n\t\t\t\t\tif(msg.put && (tmp = msg.ok)){ msg.ok = {'@':(tmp['@']||1)-1, '/': (tmp['/']==msg._.near)? mesh.near : tmp['/']}; }\n\t\t\t\t\tif(put = meta.$put){\n\t\t\t\t\t\ttmp = {}; Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] });\n\t\t\t\t\t\ttmp.put = ':])([:';\n\t\t\t\t\t\tjson(tmp, function(err, raw){\n\t\t\t\t\t\t\tif(err){ return } // TODO: Handle!!\n\t\t\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\t\t\ttmp = raw.indexOf('\"put\":\":])([:\"');\n\t\t\t\t\t\t\tres(u, raw = raw.slice(0, tmp+6) + put + raw.slice(tmp + 14));\n\t\t\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'say slice');\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tjson(msg, res);\n\t\t\t\t\tfunction res(err, raw){\n\t\t\t\t\t\tif(err){ return } // TODO: Handle!!\n\t\t\t\t\t\tmeta.raw = raw; //if(meta && (raw||'').length < (999 * 99)){ meta.raw = raw } // HNPERF: If string too big, don't keep in memory.\n\t\t\t\t\t\tmesh.say(msg, peer);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}());\n\n\t\t\tfunction flush(peer){\n\t\t\t\tvar tmp = peer.batch, t = 'string' == typeof tmp, l;\n\t\t\t\tif(t){ tmp += ']' }// TODO: Prevent double JSON!\n\t\t\t\tpeer.batch = peer.tail = null;\n\t\t\t\tif(!tmp){ return }\n\t\t\t\tif(t? 3 > tmp.length : !tmp.length){ return } // TODO: ^\n\t\t\t\tif(!t){try{tmp = (1 === tmp.length? tmp[0] : JSON.stringify(tmp));\n\t\t\t\t}catch(e){return opt.log('DAM JSON stringify error', e)}}\n\t\t\t\tif(!tmp){ return }\n\t\t\t\tsend(tmp, peer);\n\t\t\t}\n\t\t\t// for now - find better place later.\n\t\t\tfunction send(raw, peer){ try{\n\t\t\t\tvar wire = peer.wire;\n\t\t\t\tif(peer.say){\n\t\t\t\t\tpeer.say(raw);\n\t\t\t\t} else\n\t\t\t\tif(wire.send){\n\t\t\t\t\twire.send(raw);\n\t\t\t\t}\n\t\t\t\tmesh.say.d += raw.length||0; ++mesh.say.c; // STATS!\n\t\t\t}catch(e){\n\t\t\t\t(peer.queue = peer.queue || []).push(raw);\n\t\t\t}}\n\n\t\t\tmesh.near = 0;\n\t\t\tmesh.hi = function(peer){\n\t\t\t\tvar wire = peer.wire, tmp;\n\t\t\t\tif(!wire){ mesh.wire((peer.length && {url: peer, id: peer}) || peer); return }\n\t\t\t\tif(peer.id){\n\t\t\t\t\topt.peers[peer.url || peer.id] = peer;\n\t\t\t\t} else {\n\t\t\t\t\ttmp = peer.id = peer.id || peer.url || String.random(9);\n\t\t\t\t\tmesh.say({dam: '?', pid: root.opt.pid}, opt.peers[tmp] = peer);\n\t\t\t\t\tdelete dup.s[peer.last]; // IMPORTANT: see https://gun.eco/docs/DAM#self\n\t\t\t\t}\n\t\t\t\tif(!peer.met){\n\t\t\t\t\tmesh.near++;\n\t\t\t\t\tpeer.met = +(new Date);\n\t\t\t\t\troot.on('hi', peer)\n\t\t\t\t}\n\t\t\t\t// @rogowski I need this here by default for now to fix go1dfish's bug\n\t\t\t\ttmp = peer.queue; peer.queue = [];\n\t\t\t\tsetTimeout.each(tmp||[],function(msg){\n\t\t\t\t\tsend(msg, peer);\n\t\t\t\t},0,9);\n\t\t\t\t//Type.obj.native && Type.obj.native(); // dirty place to check if other JS polluted.\n\t\t\t}\n\t\t\tmesh.bye = function(peer){\n\t\t\t\tpeer.met && --mesh.near;\n\t\t\t\tdelete peer.met;\n\t\t\t\troot.on('bye', peer);\n\t\t\t\tvar tmp = +(new Date); tmp = (tmp - (peer.met||tmp));\n\t\t\t\tmesh.bye.time = ((mesh.bye.time || tmp) + tmp) / 2;\n\t\t\t}\n\t\t\tmesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) }\n\t\t\tmesh.hear['?'] = function(msg, peer){\n\t\t\t\tif(msg.pid){\n\t\t\t\t\tif(!peer.pid){ peer.pid = msg.pid }\n\t\t\t\t\tif(msg['@']){ return }\n\t\t\t\t}\n\t\t\t\tmesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer);\n\t\t\t\tdelete dup.s[peer.last]; // IMPORTANT: see https://gun.eco/docs/DAM#self\n\t\t\t}\n\t\t\tmesh.hear['mob'] = function(msg, peer){ // NOTE: AXE will overload this with better logic.\n\t\t\t\tif(!msg.peers){ return }\n\t\t\t\tvar peers = Object.keys(msg.peers), one = peers[(Math.random()*peers.length) >> 0];\n\t\t\t\tif(!one){ return }\n\t\t\t\tmesh.bye(peer);\n\t\t\t\tmesh.hi(one);\n\t\t\t}\n\n\t\t\troot.on('create', function(root){\n\t\t\t\troot.opt.pid = root.opt.pid || String.random(9);\n\t\t\t\tthis.to.next(root);\n\t\t\t\troot.on('out', mesh.say);\n\t\t\t});\n\n\t\t\troot.on('bye', function(peer, tmp){\n\t\t\t\tpeer = opt.peers[peer.id || peer] || peer;\n\t\t\t\tthis.to.next(peer);\n\t\t\t\tpeer.bye? peer.bye() : (tmp = peer.wire) && tmp.close && tmp.close();\n\t\t\t\tdelete opt.peers[peer.id];\n\t\t\t\tpeer.wire = null;\n\t\t\t});\n\n\t\t\tvar gets = {};\n\t\t\troot.on('bye', function(peer, tmp){ this.to.next(peer);\n\t\t\t\tif(tmp = console.STAT){ tmp.peers = mesh.near; }\n\t\t\t\tif(!(tmp = peer.url)){ return } gets[tmp] = true;\n\t\t\t\tsetTimeout(function(){ delete gets[tmp] },opt.lack || 9000);\n\t\t\t});\n\t\t\troot.on('hi', function(peer, tmp){ this.to.next(peer);\n\t\t\t\tif(tmp = console.STAT){ tmp.peers = mesh.near }\n\t\t\t\tif(opt.super){ return } // temporary (?) until we have better fix/solution?\n\t\t\t\tvar souls = Object.keys(root.next||''); // TODO: .keys( is slow\n\t\t\t\tif(souls.length > 9999 && !console.SUBS){ console.log(console.SUBS = \"Warning: You have more than 10K live GETs, which might use more bandwidth than your screen can show - consider `.off()`.\") }\n\t\t\t\tsetTimeout.each(souls, function(soul){ var node = root.next[soul];\n\t\t\t\t\tif(opt.super || (node.ask||'')['']){ mesh.say({get: {'#': soul}}, peer); return }\n\t\t\t\t\tsetTimeout.each(Object.keys(node.ask||''), function(key){ if(!key){ return }\n\t\t\t\t\t\t// is the lack of ## a !onion hint?\n\t\t\t\t\t\tmesh.say({'##': String.hash((root.graph[soul]||'')[key]), get: {'#': soul, '.': key}}, peer);\n\t\t\t\t\t\t// TODO: Switch this so Book could route?\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t});\n\n\t\t\treturn mesh;\n\t\t}\n\t  var empty = {}, ok = true, u;\n\n\t  try{ module.exports = Mesh }catch(e){}\n\n\t})(USE, './mesh');\n\n\t;USE(function(module){\n\t\tvar Gun = USE('./root');\n\t\tGun.Mesh = USE('./mesh');\n\n\t\t// TODO: resync upon reconnect online/offline\n\t\t//window.ononline = window.onoffline = function(){ console.log('online?', navigator.onLine) }\n\n\t\tGun.on('opt', function(root){\n\t\t\tthis.to.next(root);\n\t\t\tif(root.once){ return }\n\t\t\tvar opt = root.opt;\n\t\t\tif(false === opt.WebSocket){ return }\n\n\t\t\tvar env = Gun.window || {};\n\t\t\tvar websocket = opt.WebSocket || env.WebSocket || env.webkitWebSocket || env.mozWebSocket;\n\t\t\tif(!websocket){ return }\n\t\t\topt.WebSocket = websocket;\n\n\t\t\tvar mesh = opt.mesh = opt.mesh || Gun.Mesh(root);\n\n\t\t\tvar wired = mesh.wire || opt.wire;\n\t\t\tmesh.wire = opt.wire = open;\n\t\t\tfunction open(peer){ try{\n\t\t\t\tif(!peer || !peer.url){ return wired && wired(peer) }\n\t\t\t\tvar url = peer.url.replace(/^http/, 'ws');\n\t\t\t\tvar wire = peer.wire = new opt.WebSocket(url);\n\t\t\t\twire.onclose = function(){\n\t\t\t\t\treconnect(peer);\n\t\t\t\t\topt.mesh.bye(peer);\n\t\t\t\t};\n\t\t\t\twire.onerror = function(err){\n\t\t\t\t\treconnect(peer);\n\t\t\t\t};\n\t\t\t\twire.onopen = function(){\n\t\t\t\t\topt.mesh.hi(peer);\n\t\t\t\t}\n\t\t\t\twire.onmessage = function(msg){\n\t\t\t\t\tif(!msg){ return }\n\t\t\t\t\topt.mesh.hear(msg.data || msg, peer);\n\t\t\t\t};\n\t\t\t\treturn wire;\n\t\t\t}catch(e){ opt.mesh.bye(peer) }}\n\n\t\t\tsetTimeout(function(){ !opt.super && root.on('out', {dam:'hi'}) },1); // it can take a while to open a socket, so maybe no longer lazy load for perf reasons?\n\n\t\t\tvar wait = 2 * 999;\n\t\t\tfunction reconnect(peer){\n\t\t\t\tclearTimeout(peer.defer);\n\t\t\t\tif(!opt.peers[peer.url]){ return }\n\t\t\t\tif(doc && peer.retry <= 0){ return }\n\t\t\t\tpeer.retry = (peer.retry || opt.retry+1 || 60) - ((-peer.tried + (peer.tried = +new Date) < wait*4)?1:0);\n\t\t\t\tpeer.defer = setTimeout(function to(){\n\t\t\t\t\tif(doc && doc.hidden){ return setTimeout(to,wait) }\n\t\t\t\t\topen(peer);\n\t\t\t\t}, wait);\n\t\t\t}\n\t\t\tvar doc = (''+u !== typeof document) && document;\n\t\t});\n\t\tvar noop = function(){}, u;\n\t})(USE, './websocket');\n\n\t;USE(function(module){\n\t\tif(typeof Gun === 'undefined'){ return }\n\n\t\tvar noop = function(){}, store, u;\n\t\ttry{store = (Gun.window||noop).localStorage}catch(e){}\n\t\tif(!store){\n\t\t\tGun.log(\"Warning: No localStorage exists to persist data to!\");\n\t\t\tstore = {setItem: function(k,v){this[k]=v}, removeItem: function(k){delete this[k]}, getItem: function(k){return this[k]}};\n\t\t}\n\n\t\tvar parse = JSON.parseAsync || function(t,cb,r){ var u; try{ cb(u, JSON.parse(t,r)) }catch(e){ cb(e) } }\n\t\tvar json = JSON.stringifyAsync || function(v,cb,r,s){ var u; try{ cb(u, JSON.stringify(v,r,s)) }catch(e){ cb(e) } }\n\n\t\tGun.on('create', function lg(root){\n\t\t\tthis.to.next(root);\n\t\t\tvar opt = root.opt, graph = root.graph, acks = [], disk, to, size, stop;\n\t\t\tif(false === opt.localStorage){ return }\n\t\t\topt.prefix = opt.file || 'gun/';\n\t\t\ttry{ disk = lg[opt.prefix] = lg[opt.prefix] || JSON.parse(size = store.getItem(opt.prefix)) || {}; // TODO: Perf! This will block, should we care, since limited to 5MB anyways?\n\t\t\t}catch(e){ disk = lg[opt.prefix] = {}; }\n\t\t\tsize = (size||'').length;\n\n\t\t\troot.on('get', function(msg){\n\t\t\t\tthis.to.next(msg);\n\t\t\t\tvar lex = msg.get, soul, data, tmp, u;\n\t\t\t\tif(!lex || !(soul = lex['#'])){ return }\n\t\t\t\tdata = disk[soul] || u;\n\t\t\t\tif(data && (tmp = lex['.']) && !Object.plain(tmp)){ // pluck!\n\t\t\t\t\tdata = Gun.state.ify({}, tmp, Gun.state.is(data, tmp), data[tmp], soul);\n\t\t\t\t}\n\t\t\t\t//if(data){ (tmp = {})[soul] = data } // back into a graph.\n\t\t\t\t//setTimeout(function(){\n\t\t\t\tGun.on.get.ack(msg, data); //root.on('in', {'@': msg['#'], put: tmp, lS:1});// || root.$});\n\t\t\t\t//}, Math.random() * 10); // FOR TESTING PURPOSES!\n\t\t\t});\n\n\t\t\troot.on('put', function(msg){\n\t\t\t\tthis.to.next(msg); // remember to call next middleware adapter\n\t\t\t\tvar put = msg.put, soul = put['#'], key = put['.'], id = msg['#'], ok = msg.ok||'', tmp; // pull data off wire envelope\n\t\t\t\tdisk[soul] = Gun.state.ify(disk[soul], key, put['>'], put[':'], soul); // merge into disk object\n\t\t\t\tif(stop && size > (4999880)){ root.on('in', {'@': id, err: \"localStorage max!\"}); return; }\n\t\t\t\t//if(!msg['@']){ acks.push(id) } // then ack any non-ack write. // TODO: use batch id.\n\t\t\t\tif(!msg['@'] && (!msg._.via || Math.random() < (ok['@'] / ok['/']))){ acks.push(id) } // then ack any non-ack write. // TODO: use batch id.\n\t\t\t\tif(to){ return }\n\t\t\t\tto = setTimeout(flush, 9+(size / 333)); // 0.1MB = 0.3s, 5MB = 15s \n\t\t\t});\n\t\t\tfunction flush(){\n\t\t\t\tif(!acks.length && ((setTimeout.turn||'').s||'').length){ setTimeout(flush,99); return; } // defer if \"busy\" && no saves.\n\t\t\t\tvar err, ack = acks; clearTimeout(to); to = false; acks = [];\n\t\t\t\tjson(disk, function(err, tmp){\n\t\t\t\t\ttry{!err && store.setItem(opt.prefix, tmp);\n\t\t\t\t\t}catch(e){ err = stop = e || \"localStorage failure\" }\n\t\t\t\t\tif(err){\n\t\t\t\t\t\tGun.log(err + \" Consider using GUN's IndexedDB plugin for RAD for more storage space, https://gun.eco/docs/RAD#install\");\n\t\t\t\t\t\troot.on('localStorage:error', {err: err, get: opt.prefix, put: disk});\n\t\t\t\t\t}\n\t\t\t\t\tsize = tmp.length;\n\n\t\t\t\t\t//if(!err && !Object.empty(opt.peers)){ return } // only ack if there are no peers. // Switch this to probabilistic mode\n\t\t\t\t\tsetTimeout.each(ack, function(id){\n\t\t\t\t\t\troot.on('in', {'@': id, err: err, ok: 0}); // localStorage isn't reliable, so make its `ok` code be a low number.\n\t\t\t\t\t},0,99);\n\t\t\t\t})\n\t\t\t}\n\t\t\n\t\t});\n\t})(USE, './localStorage');\n\n}());\n\n/* BELOW IS TEMPORARY FOR OLD INTERNAL COMPATIBILITY, THEY ARE IMMEDIATELY DEPRECATED AND WILL BE REMOVED IN NEXT VERSION */\n;(function(){\n\tvar u;\n\tif(''+u == typeof Gun){ return }\n\tvar DEP = function(n){ console.warn(\"Warning! Deprecated internal utility will break in next version:\", n) }\n\t// Generic javascript utilities.\n\tvar Type = Gun;\n\t//Type.fns = Type.fn = {is: function(fn){ return (!!fn && fn instanceof Function) }}\n\tType.fn = Type.fn || {is: function(fn){ DEP('fn'); return (!!fn && 'function' == typeof fn) }}\n\tType.bi = Type.bi || {is: function(b){ DEP('bi');return (b instanceof Boolean || typeof b == 'boolean') }}\n\tType.num = Type.num || {is: function(n){ DEP('num'); return !list_is(n) && ((n - parseFloat(n) + 1) >= 0 || Infinity === n || -Infinity === n) }}\n\tType.text = Type.text || {is: function(t){ DEP('text'); return (typeof t == 'string') }}\n\tType.text.ify = Type.text.ify || function(t){ DEP('text.ify');\n\t\tif(Type.text.is(t)){ return t }\n\t\tif(typeof JSON !== \"undefined\"){ return JSON.stringify(t) }\n\t\treturn (t && t.toString)? t.toString() : t;\n\t}\n\tType.text.random = Type.text.random || function(l, c){ DEP('text.random');\n\t\tvar s = '';\n\t\tl = l || 24; // you are not going to make a 0 length random number, so no need to check type\n\t\tc = c || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz';\n\t\twhile(l > 0){ s += c.charAt(Math.floor(Math.random() * c.length)); l-- }\n\t\treturn s;\n\t}\n\tType.text.match = Type.text.match || function(t, o){ var tmp, u; DEP('text.match');\n\t\tif('string' !== typeof t){ return false }\n\t\tif('string' == typeof o){ o = {'=': o} }\n\t\to = o || {};\n\t\ttmp = (o['='] || o['*'] || o['>'] || o['<']);\n\t\tif(t === tmp){ return true }\n\t\tif(u !== o['=']){ return false }\n\t\ttmp = (o['*'] || o['>'] || o['<']);\n\t\tif(t.slice(0, (tmp||'').length) === tmp){ return true }\n\t\tif(u !== o['*']){ return false }\n\t\tif(u !== o['>'] && u !== o['<']){\n\t\t\treturn (t >= o['>'] && t <= o['<'])? true : false;\n\t\t}\n\t\tif(u !== o['>'] && t >= o['>']){ return true }\n\t\tif(u !== o['<'] && t <= o['<']){ return true }\n\t\treturn false;\n\t}\n\tType.text.hash = Type.text.hash || function(s, c){ // via SO\n\t\tDEP('text.hash');\n\t\tif(typeof s !== 'string'){ return }\n\t  c = c || 0;\n\t  if(!s.length){ return c }\n\t  for(var i=0,l=s.length,n; i<l; ++i){\n\t    n = s.charCodeAt(i);\n\t    c = ((c<<5)-c)+n;\n\t    c |= 0;\n\t  }\n\t  return c;\n\t}\n\tType.list = Type.list || {is: function(l){ DEP('list'); return (l instanceof Array) }}\n\tType.list.slit = Type.list.slit || Array.prototype.slice;\n\tType.list.sort = Type.list.sort || function(k){ // creates a new sort function based off some key\n\t\tDEP('list.sort');\n\t\treturn function(A,B){\n\t\t\tif(!A || !B){ return 0 } A = A[k]; B = B[k];\n\t\t\tif(A < B){ return -1 }else if(A > B){ return 1 }\n\t\t\telse { return 0 }\n\t\t}\n\t}\n\tType.list.map = Type.list.map || function(l, c, _){ DEP('list.map'); return obj_map(l, c, _) }\n\tType.list.index = 1; // change this to 0 if you want non-logical, non-mathematical, non-matrix, non-convenient array notation\n\tType.obj = Type.boj || {is: function(o){ DEP('obj'); return o? (o instanceof Object && o.constructor === Object) || Object.prototype.toString.call(o).match(/^\\[object (\\w+)\\]$/)[1] === 'Object' : false }}\n\tType.obj.put = Type.obj.put || function(o, k, v){ DEP('obj.put'); return (o||{})[k] = v, o }\n\tType.obj.has = Type.obj.has || function(o, k){ DEP('obj.has'); return o && Object.prototype.hasOwnProperty.call(o, k) }\n\tType.obj.del = Type.obj.del || function(o, k){ DEP('obj.del'); \n\t\tif(!o){ return }\n\t\to[k] = null;\n\t\tdelete o[k];\n\t\treturn o;\n\t}\n\tType.obj.as = Type.obj.as || function(o, k, v, u){ DEP('obj.as'); return o[k] = o[k] || (u === v? {} : v) }\n\tType.obj.ify = Type.obj.ify || function(o){ DEP('obj.ify'); \n\t\tif(obj_is(o)){ return o }\n\t\ttry{o = JSON.parse(o);\n\t\t}catch(e){o={}};\n\t\treturn o;\n\t}\n\t;(function(){ var u;\n\t\tfunction map(v,k){\n\t\t\tif(obj_has(this,k) && u !== this[k]){ return }\n\t\t\tthis[k] = v;\n\t\t}\n\t\tType.obj.to = Type.obj.to || function(from, to){ DEP('obj.to'); \n\t\t\tto = to || {};\n\t\t\tobj_map(from, map, to);\n\t\t\treturn to;\n\t\t}\n\t}());\n\tType.obj.copy = Type.obj.copy || function(o){ DEP('obj.copy'); // because http://web.archive.org/web/20140328224025/http://jsperf.com/cloning-an-object/2\n\t\treturn !o? o : JSON.parse(JSON.stringify(o)); // is shockingly faster than anything else, and our data has to be a subset of JSON anyways!\n\t}\n\t;(function(){\n\t\tfunction empty(v,i){ var n = this.n, u;\n\t\t\tif(n && (i === n || (obj_is(n) && obj_has(n, i)))){ return }\n\t\t\tif(u !== i){ return true }\n\t\t}\n\t\tType.obj.empty = Type.obj.empty || function(o, n){ DEP('obj.empty'); \n\t\t\tif(!o){ return true }\n\t\t\treturn obj_map(o,empty,{n:n})? false : true;\n\t\t}\n\t}());\n\t;(function(){\n\t\tfunction t(k,v){\n\t\t\tif(2 === arguments.length){\n\t\t\t\tt.r = t.r || {};\n\t\t\t\tt.r[k] = v;\n\t\t\t\treturn;\n\t\t\t} t.r = t.r || [];\n\t\t\tt.r.push(k);\n\t\t};\n\t\tvar keys = Object.keys, map, u;\n\t\tObject.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) }\n\t\tType.obj.map = map = Type.obj.map || function(l, c, _){ DEP('obj.map'); \n\t\t\tvar u, i = 0, x, r, ll, lle, f = 'function' == typeof c;\n\t\t\tt.r = u;\n\t\t\tif(keys && obj_is(l)){\n\t\t\t\tll = keys(l); lle = true;\n\t\t\t}\n\t\t\t_ = _ || {};\n\t\t\tif(list_is(l) || ll){\n\t\t\t\tx = (ll || l).length;\n\t\t\t\tfor(;i < x; i++){\n\t\t\t\t\tvar ii = (i + Type.list.index);\n\t\t\t\t\tif(f){\n\t\t\t\t\t\tr = lle? c.call(_, l[ll[i]], ll[i], t) : c.call(_, l[i], ii, t);\n\t\t\t\t\t\tif(r !== u){ return r }\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//if(Type.test.is(c,l[i])){ return ii } // should implement deep equality testing!\n\t\t\t\t\t\tif(c === l[lle? ll[i] : i]){ return ll? ll[i] : ii } // use this for now\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor(i in l){\n\t\t\t\t\tif(f){\n\t\t\t\t\t\tif(obj_has(l,i)){\n\t\t\t\t\t\t\tr = _? c.call(_, l[i], i, t) : c(l[i], i, t);\n\t\t\t\t\t\t\tif(r !== u){ return r }\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//if(a.test.is(c,l[i])){ return i } // should implement deep equality testing!\n\t\t\t\t\t\tif(c === l[i]){ return i } // use this for now\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn f? t.r : Type.list.index? 0 : -1;\n\t\t}\n\t}());\n\tType.time = Type.time || {};\n\tType.time.is = Type.time.is || function(t){ DEP('time'); return t? t instanceof Date : (+new Date().getTime()) }\n\n\tvar fn_is = Type.fn.is;\n\tvar list_is = Type.list.is;\n\tvar obj = Type.obj, obj_is = obj.is, obj_has = obj.has, obj_map = obj.map;\n\n\tvar Val = {};\n\tVal.is = function(v){ DEP('val.is'); // Valid values are a subset of JSON: null, binary, number (!Infinity), text, or a soul relation. Arrays need special algorithms to handle concurrency, so they are not supported directly. Use an extension that supports them if needed but research their problems first.\n\t\tif(v === u){ return false }\n\t\tif(v === null){ return true } // \"deletes\", nulling out keys.\n\t\tif(v === Infinity){ return false } // we want this to be, but JSON does not support it, sad face.\n\t\tif(text_is(v) // by \"text\" we mean strings.\n\t\t|| bi_is(v) // by \"binary\" we mean boolean.\n\t\t|| num_is(v)){ // by \"number\" we mean integers or decimals.\n\t\t\treturn true; // simple values are valid.\n\t\t}\n\t\treturn Val.link.is(v) || false; // is the value a soul relation? Then it is valid and return it. If not, everything else remaining is an invalid data type. Custom extensions can be built on top of these primitives to support other types.\n\t}\n\tVal.link = Val.rel = {_: '#'};\n\t;(function(){\n\t\tVal.link.is = function(v){ DEP('val.link.is'); // this defines whether an object is a soul relation or not, they look like this: {'#': 'UUID'}\n\t\t\tif(v && v[rel_] && !v._ && obj_is(v)){ // must be an object.\n\t\t\t\tvar o = {};\n\t\t\t\tobj_map(v, map, o);\n\t\t\t\tif(o.id){ // a valid id was found.\n\t\t\t\t\treturn o.id; // yay! Return it.\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false; // the value was not a valid soul relation.\n\t\t}\n\t\tfunction map(s, k){ var o = this; // map over the object...\n\t\t\tif(o.id){ return o.id = false } // if ID is already defined AND we're still looping through the object, it is considered invalid.\n\t\t\tif(k == rel_ && text_is(s)){ // the key should be '#' and have a text value.\n\t\t\t\to.id = s; // we found the soul!\n\t\t\t} else {\n\t\t\t\treturn o.id = false; // if there exists anything else on the object that isn't the soul, then it is considered invalid.\n\t\t\t}\n\t\t}\n\t}());\n\tVal.link.ify = function(t){ DEP('val.link.ify'); return obj_put({}, rel_, t) } // convert a soul into a relation and return it.\n\tType.obj.has._ = '.';\n\tvar rel_ = Val.link._, u;\n\tvar bi_is = Type.bi.is;\n\tvar num_is = Type.num.is;\n\tvar text_is = Type.text.is;\n\tvar obj = Type.obj, obj_is = obj.is, obj_put = obj.put, obj_map = obj.map;\n\n\tType.val = Type.val || Val;\n\n\tvar Node = {_: '_'};\n\tNode.soul = function(n, o){ DEP('node.soul'); return (n && n._ && n._[o || soul_]) } // convenience function to check to see if there is a soul on a node and return it.\n\tNode.soul.ify = function(n, o){ DEP('node.soul.ify'); // put a soul on an object.\n\t\to = (typeof o === 'string')? {soul: o} : o || {};\n\t\tn = n || {}; // make sure it exists.\n\t\tn._ = n._ || {}; // make sure meta exists.\n\t\tn._[soul_] = o.soul || n._[soul_] || text_random(); // put the soul on it.\n\t\treturn n;\n\t}\n\tNode.soul._ = Val.link._;\n\t;(function(){\n\t\tNode.is = function(n, cb, as){ DEP('node.is'); var s; // checks to see if an object is a valid node.\n\t\t\tif(!obj_is(n)){ return false } // must be an object.\n\t\t\tif(s = Node.soul(n)){ // must have a soul on it.\n\t\t\t\treturn !obj_map(n, map, {as:as,cb:cb,s:s,n:n});\n\t\t\t}\n\t\t\treturn false; // nope! This was not a valid node.\n\t\t}\n\t\tfunction map(v, k){ // we invert this because the way we check for this is via a negation.\n\t\t\tif(k === Node._){ return } // skip over the metadata.\n\t\t\tif(!Val.is(v)){ return true } // it is true that this is an invalid node.\n\t\t\tif(this.cb){ this.cb.call(this.as, v, k, this.n, this.s) } // optionally callback each key/value.\n\t\t}\n\t}());\n\t;(function(){\n\t\tNode.ify = function(obj, o, as){ DEP('node.ify'); // returns a node from a shallow object.\n\t\t\tif(!o){ o = {} }\n\t\t\telse if(typeof o === 'string'){ o = {soul: o} }\n\t\t\telse if('function' == typeof o){ o = {map: o} }\n\t\t\tif(o.map){ o.node = o.map.call(as, obj, u, o.node || {}) }\n\t\t\tif(o.node = Node.soul.ify(o.node || {}, o)){\n\t\t\t\tobj_map(obj, map, {o:o,as:as});\n\t\t\t}\n\t\t\treturn o.node; // This will only be a valid node if the object wasn't already deep!\n\t\t}\n\t\tfunction map(v, k){ var o = this.o, tmp, u; // iterate over each key/value.\n\t\t\tif(o.map){\n\t\t\t\ttmp = o.map.call(this.as, v, ''+k, o.node);\n\t\t\t\tif(u === tmp){\n\t\t\t\t\tobj_del(o.node, k);\n\t\t\t\t} else\n\t\t\t\tif(o.node){ o.node[k] = tmp }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(Val.is(v)){\n\t\t\t\to.node[k] = v;\n\t\t\t}\n\t\t}\n\t}());\n\tvar obj = Type.obj, obj_is = obj.is, obj_del = obj.del, obj_map = obj.map;\n\tvar text = Type.text, text_random = text.random;\n\tvar soul_ = Node.soul._;\n\tvar u;\n\tType.node = Type.node || Node;\n\n\tvar State = Type.state;\n\tState.lex = function(){ DEP('state.lex'); return State().toString(36).replace('.','') }\n\tState.to = function(from, k, to){ DEP('state.to'); \n\t\tvar val = (from||{})[k];\n\t\tif(obj_is(val)){\n\t\t\tval = obj_copy(val);\n\t\t}\n\t\treturn State.ify(to, k, State.is(from, k), val, Node.soul(from));\n\t}\n\t;(function(){\n\t\tState.map = function(cb, s, as){ DEP('state.map'); var u; // for use with Node.ify\n\t\t\tvar o = obj_is(o = cb || s)? o : null;\n\t\t\tcb = fn_is(cb = cb || s)? cb : null;\n\t\t\tif(o && !cb){\n\t\t\t\ts = num_is(s)? s : State();\n\t\t\t\to[N_] = o[N_] || {};\n\t\t\t\tobj_map(o, map, {o:o,s:s});\n\t\t\t\treturn o;\n\t\t\t}\n\t\t\tas = as || obj_is(s)? s : u;\n\t\t\ts = num_is(s)? s : State();\n\t\t\treturn function(v, k, o, opt){\n\t\t\t\tif(!cb){\n\t\t\t\t\tmap.call({o: o, s: s}, v,k);\n\t\t\t\t\treturn v;\n\t\t\t\t}\n\t\t\t\tcb.call(as || this || {}, v, k, o, opt);\n\t\t\t\tif(obj_has(o,k) && u === o[k]){ return }\n\t\t\t\tmap.call({o: o, s: s}, v,k);\n\t\t\t}\n\t\t}\n\t\tfunction map(v,k){\n\t\t\tif(N_ === k){ return }\n\t\t\tState.ify(this.o, k, this.s) ;\n\t\t}\n\t}());\n\tvar obj = Type.obj, obj_as = obj.as, obj_has = obj.has, obj_is = obj.is, obj_map = obj.map, obj_copy = obj.copy;\n\tvar num = Type.num, num_is = num.is;\n\tvar fn = Type.fn, fn_is = fn.is;\n\tvar N_ = Node._, u;\n\n\tvar Graph = {};\n\t;(function(){\n\t\tGraph.is = function(g, cb, fn, as){ DEP('graph.is'); // checks to see if an object is a valid graph.\n\t\t\tif(!g || !obj_is(g) || obj_empty(g)){ return false } // must be an object.\n\t\t\treturn !obj_map(g, map, {cb:cb,fn:fn,as:as}); // makes sure it wasn't an empty object.\n\t\t}\n\t\tfunction map(n, s){ // we invert this because the way'? we check for this is via a negation.\n\t\t\tif(!n || s !== Node.soul(n) || !Node.is(n, this.fn, this.as)){ return true } // it is true that this is an invalid graph.\n\t\t\tif(!this.cb){ return }\n\t\t\tnf.n = n; nf.as = this.as; // sequential race conditions aren't races.\n\t\t\tthis.cb.call(nf.as, n, s, nf);\n\t\t}\n\t\tfunction nf(fn){ // optional callback for each node.\n\t\t\tif(fn){ Node.is(nf.n, fn, nf.as) } // where we then have an optional callback for each key/value.\n\t\t}\n\t}());\n\t;(function(){\n\t\tGraph.ify = function(obj, env, as){ DEP('graph.ify'); \n\t\t\tvar at = {path: [], obj: obj};\n\t\t\tif(!env){\n\t\t\t\tenv = {};\n\t\t\t} else\n\t\t\tif(typeof env === 'string'){\n\t\t\t\tenv = {soul: env};\n\t\t\t} else\n\t\t\tif('function' == typeof env){\n\t\t\t\tenv.map = env;\n\t\t\t}\n\t\t\tif(typeof as === 'string'){\n\t\t\t\tenv.soul = env.soul || as;\n\t\t\t\tas = u;\n\t\t\t}\n\t\t\tif(env.soul){\n\t\t\t\tat.link = Val.link.ify(env.soul);\n\t\t\t}\n\t\t\tenv.shell = (as||{}).shell;\n\t\t\tenv.graph = env.graph || {};\n\t\t\tenv.seen = env.seen || [];\n\t\t\tenv.as = env.as || as;\n\t\t\tnode(env, at);\n\t\t\tenv.root = at.node;\n\t\t\treturn env.graph;\n\t\t}\n\t\tfunction node(env, at){ var tmp;\n\t\t\tif(tmp = seen(env, at)){ return tmp }\n\t\t\tat.env = env;\n\t\t\tat.soul = soul;\n\t\t\tif(Node.ify(at.obj, map, at)){\n\t\t\t\tat.link = at.link || Val.link.ify(Node.soul(at.node));\n\t\t\t\tif(at.obj !== env.shell){\n\t\t\t\t\tenv.graph[Val.link.is(at.link)] = at.node;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn at;\n\t\t}\n\t\tfunction map(v,k,n){\n\t\t\tvar at = this, env = at.env, is, tmp;\n\t\t\tif(Node._ === k && obj_has(v,Val.link._)){\n\t\t\t\treturn n._; // TODO: Bug?\n\t\t\t}\n\t\t\tif(!(is = valid(v,k,n, at,env))){ return }\n\t\t\tif(!k){\n\t\t\t\tat.node = at.node || n || {};\n\t\t\t\tif(obj_has(v, Node._) && Node.soul(v)){ // ? for safety ?\n\t\t\t\t\tat.node._ = obj_copy(v._);\n\t\t\t\t}\n\t\t\t\tat.node = Node.soul.ify(at.node, Val.link.is(at.link));\n\t\t\t\tat.link = at.link || Val.link.ify(Node.soul(at.node));\n\t\t\t}\n\t\t\tif(tmp = env.map){\n\t\t\t\ttmp.call(env.as || {}, v,k,n, at);\n\t\t\t\tif(obj_has(n,k)){\n\t\t\t\t\tv = n[k];\n\t\t\t\t\tif(u === v){\n\t\t\t\t\t\tobj_del(n, k);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(!(is = valid(v,k,n, at,env))){ return }\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!k){ return at.node }\n\t\t\tif(true === is){\n\t\t\t\treturn v;\n\t\t\t}\n\t\t\ttmp = node(env, {obj: v, path: at.path.concat(k)});\n\t\t\tif(!tmp.node){ return }\n\t\t\treturn tmp.link; //{'#': Node.soul(tmp.node)};\n\t\t}\n\t\tfunction soul(id){ var at = this;\n\t\t\tvar prev = Val.link.is(at.link), graph = at.env.graph;\n\t\t\tat.link = at.link || Val.link.ify(id);\n\t\t\tat.link[Val.link._] = id;\n\t\t\tif(at.node && at.node[Node._]){\n\t\t\t\tat.node[Node._][Val.link._] = id;\n\t\t\t}\n\t\t\tif(obj_has(graph, prev)){\n\t\t\t\tgraph[id] = graph[prev];\n\t\t\t\tobj_del(graph, prev);\n\t\t\t}\n\t\t}\n\t\tfunction valid(v,k,n, at,env){ var tmp;\n\t\t\tif(Val.is(v)){ return true }\n\t\t\tif(obj_is(v)){ return 1 }\n\t\t\tif(tmp = env.invalid){\n\t\t\t\tv = tmp.call(env.as || {}, v,k,n);\n\t\t\t\treturn valid(v,k,n, at,env);\n\t\t\t}\n\t\t\tenv.err = \"Invalid value at '\" + at.path.concat(k).join('.') + \"'!\";\n\t\t\tif(Type.list.is(v)){ env.err += \" Use `.set(item)` instead of an Array.\" }\n\t\t}\n\t\tfunction seen(env, at){\n\t\t\tvar arr = env.seen, i = arr.length, has;\n\t\t\twhile(i--){ has = arr[i];\n\t\t\t\tif(at.obj === has.obj){ return has }\n\t\t\t}\n\t\t\tarr.push(at);\n\t\t}\n\t}());\n\tGraph.node = function(node){ DEP('graph.node'); \n\t\tvar soul = Node.soul(node);\n\t\tif(!soul){ return }\n\t\treturn obj_put({}, soul, node);\n\t}\n\t;(function(){\n\t\tGraph.to = function(graph, root, opt){ DEP('graph.to'); \n\t\t\tif(!graph){ return }\n\t\t\tvar obj = {};\n\t\t\topt = opt || {seen: {}};\n\t\t\tobj_map(graph[root], map, {obj:obj, graph: graph, opt: opt});\n\t\t\treturn obj;\n\t\t}\n\t\tfunction map(v,k){ var tmp, obj;\n\t\t\tif(Node._ === k){\n\t\t\t\tif(obj_empty(v, Val.link._)){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.obj[k] = obj_copy(v);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(!(tmp = Val.link.is(v))){\n\t\t\t\tthis.obj[k] = v;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(obj = this.opt.seen[tmp]){\n\t\t\t\tthis.obj[k] = obj;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.obj[k] = this.opt.seen[tmp] = Graph.to(this.graph, tmp, this.opt);\n\t\t}\n\t}());\n\tvar fn_is = Type.fn.is;\n\tvar obj = Type.obj, obj_is = obj.is, obj_del = obj.del, obj_has = obj.has, obj_empty = obj.empty, obj_put = obj.put, obj_map = obj.map, obj_copy = obj.copy;\n\tvar u;\n\tType.graph = Type.graph || Graph;\n}());\n"
  },
  {
    "path": "hooks/build",
    "content": "#!/bin/bash\nFOO=${IMAGE_NAME:=`whoami`/gun:git-local}\nBAR=${SOURCE_BRANCH:=`git rev-parse --abbrev-ref HEAD`}\ndocker build --build-arg BUILD_DATE=`date -u +\"%Y-%m-%dT%H:%M:%SZ\"` \\\n             --build-arg VCS_REF=`git rev-parse --short HEAD` \\\n             --build-arg VCS_URL=`git config --get remote.origin.url` \\\n             --build-arg VERSION=$SOURCE_BRANCH -t $IMAGE_NAME .\n"
  },
  {
    "path": "hooks/post_push",
    "content": "#!/bin/bash\ndocker tag $IMAGE_NAME $DOCKER_REPO:latest\ndocker push $DOCKER_REPO:latest\n"
  },
  {
    "path": "index.d.ts",
    "content": "export * from './types/gun';\nexport * from './types/sea';\n\nimport { IGun, LEX } from './types/gun';\nimport { ISEA } from './types/sea';\n\ndeclare const Gun: IGun;\nexport default Gun;\n\nexport const SEA: ISEA;\n\ndeclare global {\n  const Gun: IGun;\n\n  interface StringConstructor {\n    match(t: string, o: LEX | string): boolean;\n    random(length?: number, alphabet?: string): string;\n  }\n}\n"
  },
  {
    "path": "index.js",
    "content": "module.exports = require('./lib/server');"
  },
  {
    "path": "kit/web.css",
    "content": ":root {\n  --cs: 18pt;\n  --mood: white;\n  --fill: white;\n  --blur: 5px;\n  --drip: center;\n  --font: system-ui, sans-serif;\n  --time: 0.3s;\n  --oval: 2em;\n  --pop: #BF00FF;\n}\nhtml, body /*, main, .page*/ {\n\tmargin: 0;\n\tpadding: 0;\n  gap: 0.5em;\n  line-height: 1.5;\n  min-height: 100vh;\n  color: black;\n  color: var(--pop);\n\tposition: relative;\n  font-family: var(--font);\n  font-size: max(18pt, 2vw);\n  font-size: 18pt;\n  font-size: var(--cs);\n  transition: all 0.3s;\n  transition: all var(--time);\n  background-color: transparent;\n  background-attachment: fixed;\n  background-position: center;\n  background-size: cover;\n  scrollbar-width: thin;\n  scrollbar-color: var(--pop) transparent;\n} body, main, .page { display: grid; place-items: var(--drip); }\n@media (prefers-color-scheme: dark) {\n  :root { --mood: black; }\n} /*.page { dis-play:none } .page:target { display:grid; }*/\nmain, .page {\n  position: absolute; inset: 0;\n  width: 100%; min-height: 100vh;\n}\nframe, iframe, body, html {\n  overflow-x: hidden;\n } \ndiv, ul, ol, li, p, span, form, button, input, textarea, img, frame, iframe {\n  border: 0;\n  margin: 0;\n  padding: 0;\n  gap: 0.5em;\n  position: relative;\n  vertical-align: inherit;\n  display: grid; place-items: var(--drip);\n  -webkit-transition: all var(--time);\n  transition: all 0.3s;\n  transition: all var(--time);\n  background-attachment: fixed;\n  background-position: center;\n  background-size: cover;\n  box-sizing: border-box;\n  max-width: 100%;\n  font: inherit;\n}\nbutton, input, textarea { padding: 0.5em 1em; }\na, button, input, textarea {\n  display: grid; place-items: var(--drip);\n  background-color: inherit;\n  border: inherit;\n  color: inherit;\n  outline: none;\n  text-decoration: inherit;\n}\ninput:not([type=button]):not([type=submit]), textarea {\n\twidth: 100%;\n}\ninput:-internal-autofill-selected { background-color: transparent !important; }\n\na:focus, button:focus, input[type=button]:focus, input[type=submit]:focus, input[type=password]:focus {\n  animation: pulse 2s infinite;\n}\n\nul, li {\n  list-style: none;\n}\n\np {\n  padding: 0;\n}\np + p {\n  padding-top: 0;\n}\n\n[contenteditable=true]:empty:before {\n  content: attr(placeholder);\n}\n::placeholder, .hint {\n  color: inherit;\n  opacity: 0.3;\n}\n\n.model, .none { display: none }\n.hide { \n  opacity: 0;\n  visibility: hidden;\n  transition: all 2s;\n}\n\n.full {\n  width: 100%;\n  min-height: 100vh;\n}\n.max {\n  max-width: 48em;\n}\n.min {\n  min-width: 12em;\n}\n.pad {\n  width: 95%;\n  margin: 5% auto;\n  max-width: 48em;\n  min-width: 12em;\n}\n\n.row {\n  width: 100%;\n}\n.row::after {\n  content: \"\";\n  display: block;\n  clear: both;\n}\n.col {\n  max-width: 24em;\n  min-width: 12em;\n}\n\n.center {\n  text-align: center;\n  vertical-align: middle;\n  margin-left: auto;\n  margin-right: auto;\n}\n.right {\n  float: right;\n  text-align: right;\n}\n.left {\n  float: left;\n  text-align: left;\n}\n.mid { \n  margin-left: auto;\n  margin-right: auto; \n}\n.top {\n  vertical-align: top;\n}\n.low {\n  vertical-align: bottom;\n}\n\n.sap { border-radius: var(--oval); }\n.lip { border: 0.01em solid var(--pop); }\n.rim { margin: 1%; }\n.gap {\n  padding: 3%;\n  padding: clamp(0.5em, 3%, 1.5em);\n}\n.sit { margin-bottom: 0; }\n.stack { line-height: 0; }\n.crack { margin-bottom: 1%; }\n\n.fog {\n  backdrop-filter: blur(var(--blur));\n}\n\n.focus {\n  margin-left: auto;\n  margin-right: auto;\n  float: none;\n  clear: both;\n}\n\n.leak { overflow: visible; }\n.hold { overflow: hidden; }\n\n.sky {\n  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 2em, black calc(100% - 2em), transparent 100%);\n  mask-image: linear-gradient(to bottom, transparent 0%, black 2em, black calc(100% - 2em), transparent 100%);\n}\n\n.act {\n  /*display: block;*/\n  font-weight: normal;\n  text-decoration: none;\n  -webkit-transition: all var(--time);\n  transition: all var(--time);\n  cursor: pointer;\n}\n\n.unit, .symbol {\n  display: inline-block;\n  vertical-align: inherit;\n}\n.jot { border-bottom: 1px dashed #95B2CA; }\n\n.loud {\n  font-size: 150%;\n}\n.shout {\n  font-size: 36pt;\n  font-size: 6.5vmax;\n}\n\n.ink { color: black; background-color: rgba(100%,100%,100%,0.5); }\n@media (prefers-color-scheme: dark) { .ink { color: white; background-color: rgba(0,0,0,0.5); } }\n\n.dim { background-color: rgba(0,0,0,0.5); }\n.red { background: #ea3224; }\n.green { background: #33cc33; }\n.blue { background: #4D79D8; }\n.yellow { background: #d3a438; }\n.black { background: black; }\n.white { background: white; }\n\n.shade { background: rgba(0%, 0%, 0%, 0.1); }\n.tint { background: rgba(100%, 100%, 100%, 0.1); }\n\n.redt { color: #ea3224; }\n.greent { color: #33cc33; }\n.bluet { color: #4D79D8; }\n.yellowt { color: #d3a438; }\n.blackt { color: black; }\n.whitet { color: white; }\n\n.pulse {\n  animation: pulse 2s infinite;\n} @keyframes pulse {\n  0% {opacity: 1;}\n  50% {opacity: 0.5;}\n  100% {opacity: 1;}\n}\n"
  },
  {
    "path": "kit/web.js",
    "content": ";(function(){\nvar W = window, D = document, SW = screen.width, SH = screen.height, ON = 'addEventListener', HI = 'createElement', ID = 'getElementById', U, DEV = ('file://'===location.origin);\n;(function(){ if(screen.width > screen.height){ return } // phone only debug\n  var add = function(){ if(console.view){ return } (console.view = document[HI]('textarea')).style=\"position:fixed; z-index:99999; inset:0; width:100%; height:4em; padding: 0; background:rgba(100%,100%,100%,0.8); color:black; transition: 0.5s all; white-space: pre-wrap; overflow-wrap: break-word; word-break: break-all;\"; console.view.readOnly = 1; setTimeout(function(){D.body.appendChild(console.view);},99); console.view.onclick = function(eve){ console.view.style.height = ('4em'==console.view.style.height)?'50vh':'4em' ; console.view.select(); D.execCommand('copy'); navigator.clipboard.writeText(console.view.value) } }\n  console.log = console.warn = console.error = function(...args){ if(console.off){ return } add(); console.view.value += JSON.stringify(args).slice(1,-1); console.view.scrollTop = console.view.scrollHeight; }\n  window.onerror = window.onunhandledrejection = console.log;\n}());\nvar tmp = D[HI]('meta'); tmp.name = 'viewport'; tmp.content = 'width=device-width, initial-scale=1, interactive-widget=resizes-content'; D.head.appendChild(tmp);\n//(tmp=D[HI]('link')).rel=\"stylesheet\"; tmp.href=((D.currentScript||'').src||'').replace('.js','.css'); D.head.appendChild(tmp); // auto-add CSS?\nW.parent === W && ((tmp = D.head.parentNode.style)['overscroll-behavior-y'] = 'contain') && (tmp['background-color'] = 'var(--fill)');\nfunction LOAD(src, h, s){ (s = D[HI]('script')).onload = h; s.src = src; D.head.appendChild(s) };\nfunction MAP(scroll, screen){ return (scroll / screen)>>0 }; // scroll, screen\nkit = function(){};\n// dip, dive, into, eat, lid, tin, key, face\nkit.ear = function(h,e,v){ (v=v||W)[ON](e=(h.call?(h.where=e):(e.where=h,(h=e).where))||'',h); h.off = function(){ v.removeEventListener(e,h) }; W===v&&kit.up(e,'ear'); return h; };\nkit.say = function(d,e,v,s){ (v=v||W).dispatchEvent(new CustomEvent(e=e||'',{detail:d,bubbles:true})); !s&&(W===v)&&kit.up(d,e) };\nkit.up = function up(data,type,tmp){\n  if(W === W.parent){ return }\n  if(U === data){ return } // TODO: BUG? maybe allow?\n  if('message' == type){ return }\n  //console.log(location.pathname.split('/').slice(-1)[0], \"SENDING UP\", type, data);\n  W.parent.postMessage({detail:data,type:type,wrap:1},DEV?'*':location.origin);\n}\nW[ON]('message',function(eve,data,i,tmp){\n  if(W === eve.source){ return }\n  if(eve.origin !== (DEV?'null':location.origin)){//.replace('file://','')||'null')){\n    eve.preventDefault();\n    eve.stopImmediatePropagation();\n    eve.stopPropagation();\n    return;\n  }\n  if(U === (data = eve.data||eve.detail)){ return } // TODO: BUG? maybe allow?\n  if(!(i = kit.views.get(eve.source))){ // no iframe view? then message coming down to us from above.\n    //console.log(location.pathname.split('/').slice(-1)[0], \"GOT FROM ABOVE:\", eve);\n    kit.say(data.data||data.detail,data.type,0,1);\n    return;\n  }\n  if('ear'==data.type){ kit.ear(data.detail||data.data,function hear(eve){ if(!(i||'').contentWindow){hear.off(); return } i.contentWindow.postMessage({data:eve.detail||eve.data,type:eve.type,wrap:-1}, DEV?'*':location.origin) }); return; }\n  kit.say(data.data||data.detail,data.type,i);\n});\nkit.views = new Map;\n(kit.watch = new MutationObserver(function(eve,b,low){eve.forEach(function(changes){changes.addedNodes.forEach(function(node){ //console.log(\"observed change on\", node);\n  node.dispatchEvent(new CustomEvent('join '+node.nodeName.toLowerCase(), {bubbles:true}));\n  node.dispatchEvent(new CustomEvent('join', {bubbles:true}));\n  //low = kit.watch.low(node, low); \n})});\n  //console.log(location.pathname.split('/').slice(-1)[0], \"LOWEST\", low, kit.watch.low(D.body), D.body.scrollHeight);\n  kit.up({height:D.body.scrollHeight,width:D.body.scrollWidth},'style');\n})).observe(D.documentElement||D,{childList:true,subtree:true,characterData:true});\n\nkit.watch.low = function(v,l,f){ f='getBoundingClientRect'; return Math.max(((v[f]?v[f]():'').bottom||0) + (W.pageYOffset || D.documentElement.scrollTop),l||0) }\nkit.ear('join iframe',kit.add=function(eve){\n  //console.log(location.pathname.split('/').slice(-1)[0], \"JOIN\");\n  kit.views.set(eve.target.contentWindow, eve.target);\n});\nkit.ear('style',function(eve,i){\n  if(!eve.target || !eve.target.style){ return }\n  //console.log(location.pathname.split('/').slice(-1)[0], \"resize:\", eve.target, eve.detail);\n  var h = (eve.detail||'').height; if(h) eve.target.style.height = isNaN(h) ? h : h+'px';\n  var w = (eve.detail||'').width; if(w) eve.target.style.width = isNaN(w) ? w : w+'px';\n},document);\nkit.http = {createServer: function(h){\n  h.listen = function(port,ip,cb){cb&&cb()};\n  return kit.server = h;\n},serve: function(req, res){ if(W.parent !== W){ return }\n  kit.fs.createReadStream(req.url).pipe(res);\n},req:function(path,body){ return this._last={url:path,\n  method:body?'POST':'GET',body:body,\n  headers:{},rawHeaders:[],rawTrailers:[],\n  socket:tmp={},client:tmp,connection:tmp,\n  resume: function(){},\n  pause: function(){},\n  isPaused: function(){}\n}},res:function(end){ return {_req:this._last,\n  end: end||kit.http.end,\n  getHeader: function(){},\n  setHeader: function(name, value){},\n  writeHead: function(statusCode,headers){},\n  write: function(data){},\n  pipe: function(){}\n}},end:function(data,id,i){\n  id = this._req.url.replace(location.__dirname,'').replace('file://','')/*.replace('.html','')*/.split('#')[0];\n  //console.log(\"http.end\", id, data, 'URL:', this._req.url);\n  //(i = ((data||'').src? data : (D[ID](id) || D[HI]('iframe')))).id || (i.id = id);\n  (i = D[ID](id) || D[HI]('iframe')).id || (i.id = id);\n  D.querySelectorAll('.main').forEach(function(e){ e.classList.remove('main') });\n  i.className = 'main page'; i.src||(i===D.body)||(i.srcdoc = data, D.body.appendChild(i)); location.hash = i.id; // TODO: BUG? Prevent double hash change\n}};\nW[ON]('submit', function(eve, act){ eve.preventDefault();\n  act = (eve.target.action||'').replace(location.__dirname+'/','').split('#')[0];\n  //console.log(location.pathname.split('/').slice(-1)[0], 'submit', act);\n  (kit.server||kit.http.serve)(\n    kit.http.req(act,Object.fromEntries(new FormData(eve.target))),\n    kit.http.res()\n  );\n});\nlocation.__dirname = location.href.split('/').slice(0,-1).join('/');\nObject.defineProperty(location, 'path', {\n  get(){ return kit.path },\n  set(path){ if(!path){ return }\n    path = path.replace(location.__dirname,'');\n    if('.' == path[0]){ path = path.slice(1) }\n    if('/' == path[0]){  path = path.slice(1) }\n    //console.log(location.pathname.split('/').slice(-1)[0], 'path=', path, kit.path);\n    if(kit.path === (kit.path = path)){ return }\n    (kit.server||kit.http.serve)(kit.http.req(path),kit.http.res());\n  }\n});\nkit.querystring = {\n  parse: function(qs){ return Object.fromEntries((new URLSearchParams(qs)).entries()) }\n}\nkit.fs = {files:{},\n  createReadStream(url){ url = (url||'').replace(location.__dirname+'/','').split('#')[0];\n    //console.log(\"fs.cRS:\", url);\n    var data = this.files[url], end = 0, tmp;\n    return {_:{},\n      on(eve,cb){ this._[eve] = cb; 'open'==eve&&setTimeout(cb, 0); return this }, // fake immediate open\n      pipe(dest){ var rs = this, i;\n        if(end){ return dest } end = 1;\n        function load(){ (data = i).onload = 0;;\n          if(!data){ return (tmp=rs._.error)&&tmp({code:'ENOENT'}) }\n          (tmp=rs._.data)&&tmp(data);\n          (tmp=rs._.end)&&tmp();\n          dest.end(data);\n        };\n        if(i = D[ID](url)){ setTimeout(load,0) }\n        else {\n          (i = D[HI]('iframe')).onload = load\n          i.id = (i.src = url)/*.replace('.html','')*/; D.body.appendChild(i);\n        }\n        //setTimeout(i.onload,0);\n        return dest;\n      }\n    };\n  }, readFileSync: function(path){\n\n  }, readFile: function(path,opt,cb){\n\n  }, writeFileSync: function(path,data){\n\n  }, writeFile: function(path,data,opt,cb){\n\n  }, createWriteStream: function(path,opt){\n\n  }, readdir: function(path,cb){\n\n  }\n};\nW[ON]('DOMContentLoaded',function(m){\n  //m = D[HI]('main'); while(D.body.firstChild){ m.appendChild(D.body.firstChild) } D.body.appendChild(m);\n  m=D.body;m.className = 'main page'; m.id = (kit.path = location.href.replace(location.__dirname+'/','').split('#')[0])/*.replace('.html','')*/;\n  //console.log(location.pathname.split('/').slice(-1)[0], \"kit hash add!\");\n  (function(){ function change(eve){ eve = eve||''; eve = eve.detail||eve.data||eve;\n    var hash = (eve.newURL||'').split('#')[1]||'';\n    if('.' == hash[0]){ location.hash = hash.slice(1); return; }\n    if('/' == hash[0]){ location.hash = hash.slice(1); return; }\n    //console.log(location.pathname.split('/').slice(-1)[0], \"kit hashchange\", hash, 'eve:', eve);\n    if(!eve && !hash){ return }\n    location.path = hash;\n    eve && kit.up({newURL: eve.newURL, oldURL: eve.oldURL},'hashchange');\n  }; W[ON]('hashchange',change) }());\n  kit.up('','load');\n  return;\n  //if(location.hash){ kit.say('','hashchange') }\n});\n}());\n"
  },
  {
    "path": "lib/afore.js",
    "content": "function afore(tag, hear){\n\tif(!tag){ return }\n\ttag = tag.the; // grab the linked list root\n\tvar tmp = tag.to; // grab first listener\n\thear = tmp.on.on(tag.tag, hear); // add us to end\n\thear.to = tmp || hear.to; // make our next be current first\n\thear.back.to = hear.to; // make our back point to our next\n\ttag.last = hear.back; // make last be same as before\n\thear.back = tag; // make our back be the start\n\ttag.to = hear; // make the start be us\n\treturn hear;\n}\nif(typeof module !== \"undefined\"){ module.exports = afore } // afore(gun._.on('in'), function(){ })"
  },
  {
    "path": "lib/aws.js",
    "content": ";module.exports = (function(a, own){\r\n\r\n\tfunction s3(opt){\r\n\t\tif(!(this instanceof s3)){\r\n\t\t\treturn new s3(opt);\r\n\t\t}\r\n\t\tvar s = this;\r\n\t\topt = opt || {};\r\n\t\topt.bucket = opt.bucket || opt.Bucket || process.env.AWS_S3_BUCKET;\r\n\t\topt.region = opt.region || process.env.AWS_REGION || \"us-east-1\";\r\n\t\topt.accessKeyId = opt.key = opt.key || opt.accessKeyId || process.env.AWS_ACCESS_KEY_ID;\r\n\t\topt.secretAccessKey = opt.secret = opt.secret || opt.secretAccessKey || process.env.AWS_SECRET_ACCESS_KEY;\r\n\t\tif(!opt.accessKeyId || !opt.secretAccessKey){\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\ts.config = opt;\r\n\t\ts.AWS = require('aws-sdk');\r\n\t\ts.on = a.on;\r\n\t\tif(s.config.fakes3 = s.config.fakes3 || opt.fakes3 || process.env.fakes3){\r\n\t\t\ts.AWS.config.endpoint = s.config.endpoint = opt.fakes3 || s.config.fakes3 || process.env.fakes3;\r\n\t\t\ts.AWS.config.sslEnabled = s.config.sslEnabled = false;\r\n\t\t\ts.AWS.config.bucket = s.config.bucket = s.config.bucket.replace('.','p');\r\n\t\t}\r\n\t\ts.AWS.config.update(s.config);\r\n\t\ts.S3 = function(){\r\n\t\t\tvar s = new this.AWS.S3();\r\n\t\t\tif(this.config.fakes3){\r\n\t\t\t\ts.endpoint = s.config.endpoint;\r\n\t\t\t}\r\n\t\t\treturn s;\r\n\t\t}\r\n\t\treturn s;\r\n\t};\r\n\ts3.id = function(m){ return m.Bucket +'/'+ m.Key }\r\n\ts3.chain = s3.prototype;\r\n\ts3.chain.PUT = function(key, o, cb, m){\r\n\t\tif(!key){ return }\r\n\t\tm = m || {}\r\n\t\tm.Bucket = m.Bucket || this.config.bucket;\r\n\t\tm.Key = m.Key || key;\r\n\t\tif(a.obj.is(o) || a.list.is(o)){\r\n\t\t\tm.Body = a.text.ify(o);\r\n\t\t\tm.ContentType = 'application/json';\r\n\t\t} else {\r\n\t\t\tm.Body = a.text.is(o)? o : a.text.ify(o);\r\n\t\t}\r\n\t\tthis.S3().putObject(m, function(e,r){\r\n\t\t\t//a.log('saved', e,r);\r\n\t\t\tif(!cb){ return }\r\n\t\t\tcb(e,r);\r\n\t\t});\r\n\t\treturn this;\r\n\t}\r\n\ts3.chain.GET = function(key, cb, o){\r\n\t\tif(!key){ return }\r\n\t\tvar s = this\r\n\t\t, m = {\r\n\t\t\tBucket: s.config.bucket\r\n\t\t\t,Key: key\r\n\t\t}, id = s3.id(m);\r\n\t\ts.on(id, function(arg){\r\n\t\t\tvar e = arg[0], d = arg[1], t = arg[2], m = arg[3], r = arg[4];\r\n\t\t\tthis.off();\r\n\t\t\tdelete s.batch[id];\r\n\t\t\tif(!a.fn.is(cb)){ return }\r\n\t\t\ttry{ cb(e,d,t,m,r);\r\n\t\t\t}catch(e){\r\n\t\t\t\tconsole.log(e);\r\n\t\t\t}\r\n\t\t});\r\n\t\ts.batch = s.batch || {};\r\n\t\tif(s.batch[id]){ return s }\r\n\t\ts.batch[id] = (s.batch[id] || 0) + 1;\r\n\t\ts.S3().getObject(m, function(e,r){\r\n\t\t\tvar d, t, m;\r\n\t\t\tr = r || (this && this.httpResponse);\r\n\t\t\tif(e || !r){ return s.on(id, [e]) }\r\n\t\t\tr.Text = r.text = t = (r.Body||r.body||'').toString('utf8');\r\n\t\t\tr.Type = r.type = r.ContentType || (r.headers||{})['content-type'];\r\n\t\t\tif(r.type && 'application/json' === r.type){\r\n\t\t\t\td = a.obj.ify(t);\r\n\t\t\t}\r\n\t\t\tm = r.Metadata;\r\n\t\t\ts.on(id, [e, d, t, m, r]); // Warning about the r parameter, is is the raw response and may result in stupid SAX errors.\r\n\t\t});\r\n\t\treturn s;\r\n\t}\r\n\ts3.chain.del = function(key, cb){\r\n\t\tif(!key){ return }\r\n\t\tvar m = {\r\n\t\t\tBucket: this.config.bucket\r\n\t\t\t,Key: key\r\n\t\t}\r\n\t\tthis.S3().deleteObject(m, function(e,r){\r\n\t\t\tif(!cb){ return }\r\n\t\t\tcb(e, r);\r\n\t\t});\r\n\t\treturn this;\r\n\t}\r\n\ts3.chain.dbs = function(o, cb){\r\n\t\tcb = cb || o;\r\n\t\tvar m = {}\r\n\t\tthis.S3().listBuckets(m, function(e,r){\r\n\t\t\t//a.log('dbs',e);\r\n\t\t\ta.list.map((r||{}).Contents, function(v){console.log(v);});\r\n\t\t\t//a.log('---end list---');\r\n\t\t\tif(!a.fn.is(cb)) return;\r\n\t\t\tcb(e,r);\r\n\t\t});\r\n\t\treturn this;\r\n\t}\r\n\ts3.chain.keys = function(from, upto, cb){\r\n\t\tcb = cb || upto || from;\r\n\t\tvar m = {\r\n\t\t\tBucket: this.config.bucket\r\n\t\t}\r\n\t\tif(a.text.is(from)){\r\n\t\t\tm.Prefix = from;\r\n\t\t}\r\n\t\tif(a.text.is(upto)){\r\n\t\t\tm.Delimiter = upto;\r\n\t\t}\r\n\t\tthis.S3().listObjects(m, function(e,r){\r\n\t\t\t//a.log('list',e);\r\n\t\t\ta.list.map((r||{}).Contents, function(v){console.log(v)});\r\n\t\t\t//a.log('---end list---');\r\n\t\t\tif(!a.fn.is(cb)) return;\r\n\t\t\tcb(e,r);\r\n\t\t});\r\n\t\treturn this;\r\n\t}\r\n\treturn s3;\r\n})(require('../gun'), {});\r\n/**\r\nKnox S3 Config is:\r\nknox.createClient({\r\n    key: ''\r\n  , secret: ''\r\n  , bucket: ''\r\n  , endpoint: 'us-standard'\r\n  , port: 0\r\n  , secure: true\r\n  , token: ''\r\n  , style: ''\r\n  , agent: ''\r\n});\r\n\r\naws-sdk for s3 is:\r\n{ \"accessKeyId\": \"akid\", \"secretAccessKey\": \"secret\", \"region\": \"us-west-2\" }\r\nAWS.config.loadFromPath('./config.json');\r\n {\r\n\taccessKeyId: process.env.AWS_ACCESS_KEY_ID = ''\r\n\t,secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY = ''\r\n\t,Bucket: process.env.s3Bucket = ''\r\n\t,region: process.env.AWS_REGION = \"us-east-1\"\r\n\t,sslEnabled: ''\r\n}\r\n**/\r\n"
  },
  {
    "path": "lib/axe.js",
    "content": "// I don't quite know where this should go yet, so putting it here\n// what will probably wind up happening is that minimal AXE logic added to end of gun.js\n// and then rest of AXE logic (here) will be moved back to gun/axe.js\n// but for now... I gotta rush this out!\nvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun'), u;\nGun.on('opt', function(at){ start(at); this.to.next(at) }); // make sure to call the \"next\" middleware adapter.\n// TODO: BUG: panic test/panic/1 & test/panic/3 fail when AXE is on.\nfunction start(root){\n\tif(root.axe){ return }\n\tvar opt = root.opt, peers = opt.peers;\n\tif(false === opt.axe){ return }\n\tif((typeof process !== \"undefined\") && 'false' === ''+(opt.env=process.env||'').AXE){ return }\n\tGun.log.once(\"AXE\", \"AXE relay enabled!\");\n\tvar axe = root.axe = {}, tmp, id;\n\tvar mesh = opt.mesh = opt.mesh || Gun.Mesh(root); // DAM!\n\tvar dup = root.dup;\n\n\tmesh.way = function(msg){\n\t\tif(!msg){ return }\n\t\t//relayUp(msg); // TEMPORARY!!!\n\t\tif(msg.get){ return GET(msg) }\n\t\tif(msg.put){ return }\n\t\tfall(msg);\n\t}\n\n\tfunction GET(msg){\n\t\tif(!msg){ return }\n\t\tvar via = (msg._||'').via, soul, has, tmp, ref;\n\t\tif(!via || !via.id){ return fall(msg) }\n\t\t// SUBSCRIPTION LOGIC MOVED TO GET'S ACK REPLY.\n\t\tif(!(ref = REF(msg)._)){ return fall(msg) }\n\t\tref.asked = +new Date;\n\t\tGET.turn(msg, ref.route, 0);\n\t}\n\tGET.turn = function(msg, route, turn){\n\t\tvar tmp = msg['#'], tag = dup.s[tmp], next; \n\t\tif(!tmp || !tag){ return } // message timed out, GUN may require us to relay, tho AXE does not like that. Rethink?\n\t\t// TOOD: BUG! Handle edge case where live updates occur while these turn hashes are being checked (they'll never be consistent), but we don't want to degrade to O(N), if we know the via asking peer got an update, then we should do something like cancel these turns asking for data.\n\t\t// Ideas: Save a random seed that sorts the route, store it and the index. // Or indexing on lowest latency is probably better.\n\t\tclearTimeout(tag.lack);\n\t\tif(tag.ack && (tmp = tag['##']) && msg['##'] === tmp){ return } // hashes match, stop asking other peers!\n\t\tnext = (Object.maps(route||opt.peers)).slice(turn = turn || 0);\n\t\tif(!next.length){\n\t\t\tif(!route){ return } // asked all peers, stop asking!\n\t\t\tGET.turn(msg, u, 0); // asked all subs, now now ask any peers. (not always the best idea, but stays )\n\t\t\treturn;\n\t\t}\n\t\tsetTimeout.each(next, function(id){\n\t\t\tvar peer = opt.peers[id]; turn++;\n\t\t\tif(!peer || !peer.wire){ route && route.delete(id); return } // bye! // TODO: CHECK IF 0 OTHER PEERS & UNSUBSCRIBE\n\t\t\tif(mesh.say(msg, peer) === false){ return } // was self\n\t\t\tif(0 == (turn % 3)){ return 1 }\n\t\t}, function(){\n\t\t\ttag['##'] = msg['##']; // should probably set this in a more clever manner, do live `in` checks ++ --, etc. but being lazy for now. // TODO: Yes, see `in` TODO, currently this might match against only in-mem cause no other peers reply, which is \"fine\", but could cause a false positive.\n\t\t\ttag.lack = setTimeout(function(){ GET.turn(msg, route, turn) }, 25);\n\t\t}, 3);\n\t}\n\tfunction fall(msg){ mesh.say(msg, opt.peers) }\n\tfunction REF(msg){\n\t\tvar ref = '', soul, has, tmp;\n\t\tif(!msg || !msg.get){ return ref }\n\t\tif('string' == typeof (soul = msg.get['#'])){ ref = root.$.get(soul) }\n\t\tif('string' == typeof (tmp = msg.get['.'])){ has = tmp } else { has = '' }\n\n\t\tvar via = (msg._||'').via, sub = (via.sub || (via.sub = new Object.Map)); (sub.get(soul) || (sub.set(soul, tmp = new Object.Map) && tmp)).set(has, 1); // {soul: {'':1, has: 1}} // TEMPORARILY REVERT AXE TOWER TYING TO SUBSCRIBING TO EVERYTHING. UNDO THIS!\n\t\tvia.id && ref._ && (ref._.route || (ref._.route = new Object.Map)).set(via.id, via); // SAME AS ^\n\n\t\treturn ref;\n\t}\n\tfunction LEX(lex){ return (lex = lex || '')['='] || lex['*'] || lex['>'] || lex }\n\t\n\troot.on('in', function(msg){ var to = this.to, tmp;\n\t\tif((tmp = msg['@']) && (tmp = dup.s[tmp])){\n\t\t\ttmp.ack = (tmp.ack || 0) + 1; // count remote ACKs to GET. // TODO: If mismatch, should trigger next asks.\n\t\t\tif(tmp.it && tmp.it.get && msg.put){ // WHEN SEEING A PUT REPLY TO A GET...\n\t\t\t\tvar get = tmp.it.get||'', ref = REF(tmp.it)._, via = (tmp.it._||'').via||'', sub;\n\t\t\t\tif(via && ref){ // SUBSCRIBE THE PEER WHO ASKED VIA FOR IT:\n\t\t\t\t\t//console.log(\"SUBSCRIBING\", Object.maps(ref.route||''), \"to\", LEX(get['#']));\n\t\t\t\t\tvia.id && (ref.route || (ref.route = new Object.Map)).set(via.id, via);\n\t\t\t\t\tsub = (via.sub || (via.sub = new Object.Map));\n\t\t\t\t\tref && (sub.get(LEX(get['#'])) || (sub.set(LEX(get['#']), sub = new Object.Map) && sub)).set(LEX(get['.']), 1); // {soul: {'':1, has: 1}}\n\n\t\t\t\t\tvia = (msg._||'').via||'';\n\t\t\t\t\tif(via){ // BIDIRECTIONAL SUBSCRIBE: REPLIER IS NOW SUBSCRIBED. DO WE WANT THIS?\n\t\t\t\t\t\tvia.id && (ref.route || (ref.route = new Object.Map)).set(via.id, via);\n\t\t\t\t\t\tsub = (via.sub || (via.sub = new Object.Map));\n\t\t\t\t\t\tif(ref){\n\t\t\t\t\t\t\tvar soul = LEX(get['#']), sift = sub.get(soul), has = LEX(get['.']);\n\t\t\t\t\t\t\tif(has){\n\t\t\t\t\t\t\t\t(sift || (sub.set(soul, sift = new Object.Map) && sift)).set(has, 1);\n\t\t\t\t\t\t\t} else\n\t\t\t\t\t\t\tif(!sift){\n\t\t\t\t\t\t\t\tsub.set(soul, sift = new Object.Map);\n\t\t\t\t\t\t\t\tsift.set('', 1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif((tmp = tmp.back)){ // backtrack OKs since AXE splits PUTs up.\n\t\t\t\tsetTimeout.each(Object.keys(tmp), function(id){\n\t\t\t\t\tto.next({'#': msg['#'], '@': id, ok: msg.ok});\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tto.next(msg);\n\t});\n\n\troot.on('create', function(root){\n\t\tthis.to.next(root);\n\t\tvar Q = {};\n\t\troot.on('put', function(msg){\n\t\t\tvar eve = this, at = eve.as, put = msg.put, soul = put['#'], has = put['.'], val = put[':'], state = put['>'], q, tmp;\n\t\t\teve.to.next(msg);\n\t\t\tif(msg['@']){ return } // acks send existing data, not updates, so no need to resend to others.\n\t\t\tif(!soul || !has){ return }\n\t\t\tvar ref = root.$.get(soul)._, route = (ref||'').route;\n\t\t\tif(!route){ return }\n\t\t\tif(ref.skip && ref.skip.has == has){ ref.skip.now = msg['#']; return }\n\t\t\t(ref.skip = {now: msg['#'], has: has}).to = setTimeout(function(){\n\t\t\tsetTimeout.each(Object.maps(route), function(pid){ var peer, tmp;\n\t\t\t\tvar skip = ref.skip||''; ref.skip = null;\n\t\t\t\tif(!(peer = route.get(pid))){ return }\n\t\t\t\tif(!peer.wire){ route.delete(pid); return } // bye!\n\t\t\t\tvar sub = (peer.sub || (peer.sub = new Object.Map)).get(soul);\n\t\t\t\tif(!sub){ return }\n\t\t\t\tif(!sub.get(has) && !sub.get('')){ return }\n\t\t\t\tvar put = peer.put || (peer.put = {});\n\t\t\t\tvar node = root.graph[soul], tmp;\n\t\t\t\tif(node && u !== (tmp = node[has])){\n\t\t\t\t\tstate = state_is(node, has);\n\t\t\t\t\tval = tmp;\n\t\t\t\t}\n\t\t\t\tput[soul] = state_ify(put[soul], has, state, val, soul);\n\t\t\t\ttmp = dup.track(peer.next = peer.next || String.random(9));\n\t\t\t\t(tmp.back || (tmp.back = {}))[''+(skip.now||msg['#'])] = 1;\n\t\t\t\tif(peer.to){ return }\n\t\t\t\tpeer.to = setTimeout(function(){ flush(peer) }, opt.gap);\n\t\t\t}) }, 9);\n\t\t});\n\t});\n\n\tfunction flush(peer){\n\t\tvar msg = {'#': peer.next, put: peer.put, ok: {'@': 3, '/': mesh.near}}; // BUG: TODO: sub count!\n\t\t// TODO: what about DAM's >< dedup? Current thinking is, don't use it, however, you could store first msg# & latest msg#, and if here... latest === first then likely it is the same >< thing, so if(firstMsg['><'][peer.id]){ return } don't send.\n\t\tpeer.next = peer.put = peer.to = null;\n\t\tmesh.say(msg, peer);\n\t}\n\tvar state_ify = Gun.state.ify, state_is = Gun.state.is;\n\n\tfunction relayUp(msg){\n\t\tmesh.say(msg, axe.up);\n\t}\n\n\t;(function(){ // THIS IS THE UP MODULE;\n\t\taxe.up = {};\n\t\tvar hi = mesh.hear['?']; // lower-level integration with DAM! This is abnormal but helps performance.\n\t\tmesh.hear['?'] = function(msg, peer){ var p; // deduplicate unnecessary connections:\n\t\t\thi(msg, peer);\n\t\t\tif(!peer.pid){ return }\n\t\t\tif(peer.pid === opt.pid){ mesh.bye(peer); return } // if I connected to myself, drop.\n\t\t\tif(p = axe.up[peer.pid]){ // if we both connected to each other...\n\t\t\t\tif(p === peer){ return } // do nothing if no conflict,\n\t\t\t\tif(opt.pid > peer.pid){ // else deterministically sort\n\t\t\t\t\tp = peer; // so we will wind up choosing the same to keep\n\t\t\t\t\tpeer = axe.up[p.pid]; // and the same to drop.\n\t\t\t\t}\n\t\t\t\tp.url = p.url || peer.url; // copy if not\n\t\t\t\tmesh.bye(peer); // drop\n\t\t\t\taxe.up[p.pid] = p; // update same to be same.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(!peer.url){ return }\n\t\t\taxe.up[peer.pid] = peer;\n\t\t\tif(axe.stay){ axe.stay() }\n\t\t};\n\n\t\tmesh.hear['opt'] = function(msg, peer){\n\t\t\tif(msg.ok){ return }\n\t\t\tvar tmp = msg.opt;\n\t\t\tif(!tmp){ return }\n\t\t\ttmp = tmp.peers;\n\t\t\tif(!tmp || 'string' != typeof tmp){ return }\n\t\t\tif(99 <= Object.keys(axe.up).length){ return } // 99 TEMPORARILY UNTIL BENCHMARKED!\n\t\t\tmesh.hi({id: tmp, url: tmp, retry: 9});\n\t\t\tif(peer){ mesh.say({dam: 'opt', ok: 1, '@': msg['#']}, peer) }\n\t\t}\n\n\t\taxe.stay = function(){\n\t\t\tclearTimeout(axe.stay.to);\n\t\t\taxe.stay.to = setTimeout(function(tmp, urls){\n\t\t\t\tif(!(tmp = root.stats && root.stats.stay)){ return }\n\t\t\t\turls = {}; Object.keys(axe.up||'').forEach(function(p){\n\t\t\t\t\tp = (axe.up||'')[p]; if(p.url){ urls[p.url] = {} }\n\t\t\t\t});\n\t\t\t\t(tmp.axe = tmp.axe || {}).up = urls;\n\t\t\t}, 1000 * 9);//1000 * 60);\n\t\t};\n\t\tsetTimeout(function(tmp){\n\t\t\tif(!(tmp = root.stats && root.stats.stay && root.stats.stay.axe)){ return }\n\t\t\tif(!(tmp = tmp.up)){ return }\n\t\t\tif(!(tmp instanceof Array)){ tmp = Object.keys(tmp) }\n\t\t\tsetTimeout.each(tmp||[], function(url){ mesh.hear.opt({opt: {peers: url}}) });\n\t\t},1000);\n\t}());\n\n\tsetTimeout(function(){ require('./service')(root) },9);\n\n\t;(function(){ // THIS IS THE MOB MODULE;\n\t\t//return; // WORK IN PROGRESS, TEST FINALIZED, NEED TO MAKE STABLE.\n\t\t/*\n\t\t\tAXE should have a couple of threshold items...\n\t\t\tlet's pretend there is a variable max peers connected\n\t\t\tmob = 10000\n\t\t\tif we get more peers than that...\n\t\t\twe should start sending those peers a remote command\n\t\t\tthat they should connect to this or that other peer\n\t\t\tand then once they (or before they do?) drop them from us.\n\t\t\tsake of the test... gonna set that peer number to 1.\n\t\t\tThe mob threshold might be determined by other factors,\n\t\t\tlike how much RAM or CPU stress we have.\n\t\t*/\n\t\topt.mob = opt.mob || parseFloat((opt.env||'').MOB) || 999999; // should be based on ulimit, some clouds as low as 10K.\n\n\t\t// handle rebalancing a mob of peers:\n\t\troot.on('hi', function(peer){\n\t\t\tthis.to.next(peer);\n\t\t\tif(peer.url){ return } // I am assuming that if we are wanting to make an outbound connection to them, that we don't ever want to drop them unless our actual config settings change.\n\t\t\tvar count = /*Object.keys(opt.peers).length ||*/ mesh.near; // TODO: BUG! This is slow, use .near, but near is buggy right now, fix in DAM.\n\t\t\t//console.log(\"are we mobbed?\", opt.mob, Object.keys(opt.peers).length, mesh.near);\n\t\t\tif(opt.mob >= count){ return }  // TODO: Make dynamic based on RAM/CPU also. Or possibly even weird stuff like opt.mob / axe.up length?\n\t\t\tvar peers = {};Object.keys(axe.up).forEach(function(p){ p = axe.up[p]; p.url && (peers[p.url]={}) });\n\t\t\t// TODO: BUG!!! Infinite reconnection loop happens if not enough relays, or if some are missing. For instance, :8766 says to connect to :8767 which then says to connect to :8766. To not DDoS when system overload, figure clever way to tell peers to retry later, that network does not have enough capacity?\n\t\t\tmesh.say({dam: 'mob', mob: count, peers: peers}, peer);\n\t\t\tsetTimeout(function(){ mesh.bye(peer) }, 9); // something with better perf?\n\t\t});\n\t\troot.on('bye', function(peer){\n\t\t\tthis.to.next(peer);\n\t\t});\n\n\t}());\n\n\t;(function(){ // THIS IS THE UNIVERSAL NOTIFICATION MODULE\n\t\tvar to = {}, key = {}, email = require('./email');\n\t\tif(email.err){ return }\n\t\tmesh.hear['tag'] = function(msg, peer, who){\n\t\t\tif(who = key[msg.key]){ who.rate = Math.max(msg.rate||1000*60*15, 1000*60); return }\n\t\t\tif(!msg.src || !msg.email){ return }\n\t\t\tif(+new Date < peer.emailed + 1000*60*2){ mesh.say({dam:'tag',err:'too fast'},peer); return } // peer can only send notifications > 2min\n\t\t\tvar src; try{ src = new URL(msg.src = msg.src.split(/\\s/)[0]); } catch(e){ return } // throws if invalid URL.\n\t\t\t(who = (to[msg.email] = to[msg.email] || {go:{}})).go[''+src] = 1; // we're keeping in-memory for now, maybe will \"stay\" to disk in future.\n\t\t\tpeer.emailed = +new Date;\n\t\t\tif(who.batch){ return }\n\t\t\tkey[who.key = Math.random().toString(36).slice(2)] = who;\n\t\t\twho.batch = setTimeout(function(){\n\t\t\t\temail.send({\n\t\t\t\t\tfrom: process.env.EMAIL,\n\t\t\t\t\tto: msg.email,\n\t\t\t\t\tsubject: \"Notification:\",\n\t\t\t\t\ttext: 'Someone or a bot tagged you at: (⚠️ only click link if you recognize & trust it ⚠️)\\n'+\n\t\t\t\t\t\t'[use #'+who.key+' to unsubscribe please mute this thread by tapping the top most \"⋮\" button and clicking mute]\\n\\n' +\n\t\t\t\t\t\tObject.keys(who.go).join('\\n'), // TODO: NEEDS TO BE CPU SCHEDULED\n\t\t\t\t\theaders: {'message-id': '<123456789.8765@example.com>'} // hardcode id so all batches also group into the same email thread to reduce clutter.\n\t\t\t\t}, function(err, r){\n\t\t\t\t\twho.batch = null; who.go = {};\n\t\t\t\t\terr && console.log(\"email TAG:\", err);\n\t\t\t\t});\n\t\t\t}, who.rate || (1000*60*60*24)); // default to 1 day\n\t\t};\n\t}());\n};\n\n;(function(){\n\tvar from = Array.from;\n\tObject.maps = function(o){\n\t\tif(from && o instanceof Map){ return from(o.keys()) }\n\t\tif(o instanceof Object.Map){ o = o.s }\n\t\treturn Object.keys(o);\n\t}\n\tif(from){ return Object.Map = Map }\n\t(Object.Map = function(){ this.s = {} }).prototype = {set:function(k,v){this.s[k]=v;return this},get:function(k){return this.s[k]},delete:function(k){delete this.s[k]}};\n}());\n"
  },
  {
    "path": "lib/book.js",
    "content": "console.log(\"Officially moved to gun.js core, use gun/src/book.js on own.\");"
  },
  {
    "path": "lib/bye.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.on('create', function(root){\n\tthis.to.next(root);\n\tvar mesh = root.opt.mesh;\n\tif(!mesh){ return }\n\tmesh.hear['bye'] = function(msg, peer){\n\t\t(peer.byes = peer.byes || []).push(msg.bye);\n\t}\n\troot.on('bye', function(peer){\n\t\tthis.to.next(peer);\n\t\tif(!peer.byes){ return }\n\t\tvar gun = root.$;\n\t\tGun.obj.map(peer.byes, function(data){\n\t\t\tGun.obj.map(data, function(put, soul){\n\t\t\t\tgun.get(soul).put(put);\n\t\t\t});\n\t\t});\n\t\tpeer.byes = [];\n\t});\n});\n\nGun.chain.bye = function(){\n\tvar gun = this, bye = gun.chain(), root = gun.back(-1), put = bye.put;\n\tbye.put = function(data){\n\t\tgun.back(function(at){\n\t\t\tif(!at.get){ return }\n\t\t\tvar tmp = data;\n\t\t\t(data = {})[at.get] = tmp;\n\t\t});\n\t\troot.on('out', {bye: data});\n\t\treturn gun;\n\t}\n\treturn bye;\n}\n"
  },
  {
    "path": "lib/crashed.js",
    "content": ";(function(){ try {\n\tvar fs = require('fs'), logs = [], up = __dirname+'/../';\n\tfs.readdir(up, function(err, list){ try{\n\t\tvar i = 0, f; while(f = list[i++]){\n\t\t\tif(0 === f.indexOf('isolate-') && '.log' === f.slice(-4)){ logs.push(f) }\n\t\t}\n\t\tlogs = logs.sort();\n\t\tvar i = 0, f, lf; while(f = list[i++]){\n\t\t\tif(0 <= f.indexOf('-v8-') && '.log' === f.slice(-4)){ lf = f }\n\t\t} f = lf;\n\t\tif(!f){ return }\n\t\tfs.rename(up+f, up+'v8.log', function(err,ok){\n\t\t\tvar i = 0, f; while(f = logs[i++]){ fs.unlink(up+f, noop) }\n\t\t\tif(!process.env.EMAIL){ return } // ONLY EMAIL IF DEVELOPER OPTS IN!!!\n\t\t\temail(); // ONLY EMAIL IF DEVELOPER OPTS IN!!!\n\t\t});\n\t}catch(e){} });\n\tfunction noop(){};\n\tfunction email(){ try{\n\t\tif(!process.env.EMAIL){ return } // ONLY EMAIL IF DEVELOPER OPTS IN!!!\n\t\tvar address = process.env.EMAIL || \"mark@gun.eco\";\n\t\t// you also have to specify your EMAIL_KEY gmail 2F' app's password (not reg) to send out.\n\t\trequire('./email').send({\n\t\t\ttext: \"log attached\",\n\t\t\tfrom: address,\n\t\t\tto: address,\n\t\t\tsubject: \"GUN V8 LOG\",\n\t\t\tattachment:[{path: up+'v8.log', type:\"text/plain\", name:\"v8.log\"}]\n\t\t}, noop);\n\t}catch(e){} };\n}catch(e){}\n}());"
  },
  {
    "path": "lib/cryptomodules.js",
    "content": ";console.log(\"cryptomodules no longer needed\");"
  },
  {
    "path": "lib/debug.js",
    "content": ";(function(){\n\tif('debug' !== process.env.GUN_ENV){ return }\n\n\tvar db = {length: 0, hash: {}};\n\n\tconsole.log(\"start :)\");\n\tglobal.DEBUG = 1;\n\tsetInterval(function(){\n\t\tvar print = '', tmp;\n\t\tvar mem = process.memoryUsage();\n\t\tvar used = mem.rss / 1024 / 1024;\n\t\tused = used.toFixed(1);\n\t\tprint += used +' MB rss. ';\n\t\tvar used = mem.heapTotal / 1024 / 1024;\n\t\tused = used.toFixed(1);\n\t\tprint += used +' MB hT. ';\n\t\tvar used = mem.heapUsed / 1024 / 1024;\n\t\tused = used.toFixed(1);\n\t\tprint += used +' MB hU. ';\n\t\tif(db.root){\n\t\t\tdb.concurrency = Object.keys(db.peers||{}).length;\n\t\t\tprint += db.concurrency +' peers. ';\n\t\t\tdb.nodes = Object.keys(db.root.graph||{}).length;\n\t\t\tprint += db.nodes + ' nodes. ';\n\t\t\tif(db.count){ print += db.count + ' msgs. '}\n\t\t\tif(tmp = db.root.msgsLength){\n\t\t\t\ttmp = (tmp / 1024 / 1024).toFixed(2);\n\t\t\t\tprint += tmp + ' length MB. ';\n\t\t\t}\n\t\t\tif(db.last){ print += '\\n' + JSON.stringify(db.last, null, 2) }\n\t\t\tif(db.hash){ \n\t\t\t\tprint += '\\nSome 100 Fast Hash Counts: \\n' + JSON.stringify(db.hash, null, 2);\n\t\t\t\tvar l = Object.keys(db.hash), i = l.length;\n\t\t\t\tif(i > 100){\n\t\t\t\t\ti = i - 100;\n\t\t\t\t\tGun.list.map(l, function(k){\n\t\t\t\t\t\tif(--i <= 0){ return }\n\t\t\t\t\t\tdelete db.hash[k];\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t\tdb.print = print;\n\t\tprint = print.split('\\n')[0];\n\t\tconsole.log(print);\n\t}, 2500);\n\n\tvar Gun = require('../gun');\n\tGun.on('opt', function(root){\n\t\tthis.to.next(root);\n\t\tif(root.once){ return }\n\t\tconsole.log(\">>>>>>>>>\", root);\n\t\troot.debug = db;\n\t\tdb.root = root;\n\t\tdb.peers = root.opt.peers;\n\n\t\tdb.count = 0;\n\t\troot.on('in', function(msg){\n\t\t\tthis.to.next(msg);\n\t\t\tif(!msg.NTS){ db.last = msg }\n\t\t\tdb.count++;\n\t\t\tvar tmp = msg['##'];\n\t\t\tif(tmp && msg.put){\n\t\t\t\tif(!db.hash[tmp]){ db.hash[tmp] = [0, ''] }\n\t\t\t\tdb.hash[tmp][0] = (db.hash[tmp][0] || 0) + 1;\n\t\t\t\tvar preview = Object.keys(msg.put||{});\n\t\t\t\tdb.hash[tmp][1] = preview.toString(', ').slice(0,500) + ' ...';\n\t\t\t}\n\t\t});\n\t})\n\n}());"
  },
  {
    "path": "lib/dom.js",
    "content": ";(function(){ // jQuery shim\n\t// u = undefined, n = null, b = boolean = true/false, n = number, t = text, l = list = array, o = object, cb = callback = function, q = query CSS, k = key, eve = event.\n\tif(window.$){ return }\n\t(($ = window.$ = function(q, tag, I, u){\n\t\tif(q instanceof $){ return q }\n\t\tif(!((I = this) instanceof $)){ return new $(q, tag) }\n\t\tif('string' != typeof q){ return I.tags = (q = q||[]).tags || (u === q.length)? [q] : q, I }\n\t\tif('<' === q[0]){ return I.add(q) }\n\t\treturn q.split(\",\").forEach(function(q){ I.add((tag||document).querySelectorAll(q)) }), I;\n\t}).fn = $.prototype).each = function(cb){ return $.each(this.tags, cb), this }\n\t$.each = function(o, cb){ Object.keys(o).forEach(function(k){ cb(k, o[k]) }) }\n\t$.isPlainObject = function(o){\n\t\treturn (o? (o instanceof Object && o.constructor === Object)\n\t\t|| 'Object' === Object.prototype.toString.call(o).match(/^\\[object (\\w+)\\]$/)[1] \n\t\t: false);\n\t}\n\t$.fn.add = function(add, tmp, u){ if(!add){ return this }\n\t\tif('<' === (tmp = add)[0]){ (add = document.createElement('div')).innerHTML = tmp; add = add.children[0] }\n\t\tadd = ('string' == typeof add)? $(add).tags : (u == add.length)? add : [].slice.call(add);\n\t\treturn this.tags = [].slice.call(this.tags||[]).concat(add), this;\n\t}\n\t$.fn.get = function(i, l, u){ return l = this.tags, (i === u)? l : l[i] }\n\t$.fn.is = function(q, b){ return this.each(function(i, tag){ b = b || tag.matches(q) }), b }\n\t$.fn.css = function(o){ return this.each(function(i, tag){ $.each(o, function(k,v){ tag.style[k] = v }) })}\n\t$.fn.on = function(t, cb){ return this.each(function(i, tag){\n\t\tt.split(\" \").forEach(function(t){ tag.addEventListener(t, cb) });\n\t})}\n\t$.fn.val = function(t, k, f, u){\n\t\tt = (t === u)? '' : (f = 1) && t;\n\t\tk = k || 'value';\n\t\treturn this.each(function(i, tag){\n\t\t\tif(f){ tag[k] = t }\n\t\t\telse { t += (tag[k]||'') }\n\t\t}), f? this : t;\n\t}\n\t$.fn.text = function(t){ return this.val(t, 'textContent') }\n\t$.fn.html = function(html){ return this.val(html, 'innerHTML') }\n\t$.fn.attr = function(attr,val){ return this.val(val, attr) }\n\t$.fn.find = function(q, I, l){\n\t\tI = $(), l = I.tags;\n\t\treturn this.each(function(i, tag){\n\t\t\t$(q, tag).each(function(i, tag){\n\t\t\t\tif(0 > l.indexOf(tag)){ l.push(tag) }\n\t\t\t});\n\t\t}), I;\n\t}\n\t$.fn.place = function(where, on, f, op, I){ return (I = this).each(function(i, tag){ $(on).each(function(i, node){\n\t\t(f? tag : node)[op||'insertAdjacentElement'](({\n\t\t\t'-1':'beforebegin', '-0.1': 'afterbegin', '0.1':'beforeend', '1': 'afterend'\n\t\t})[where], (f? node : tag));\n\t})})}\n\t$.fn.append = function(html){ return $(html).place(0.1, this), this }\n\t$.fn.appendTo = function(html){ return this.place(0.1, $(html)) }\n\tfunction rev(o, I){ (I = $()).tags = [].slice.call(o.tags).reverse(); return I };\n\t$.fn.prependTo = function(html){ return rev(this).place(-0.1, $(html)), this }\n\t$.fn.prepend = function(html){ return rev($(html)).place(-0.1, this), this }\n\t$.fn.parents = function(q, c, I, l, p){\n\t\tI = $(), l = I.tags, p = 'parentElement';\n\t\tthis.each(function(i, tag){\n\t\t\tif(c){ (c = {})[p] = tag ; tag = c }\n\t\t\twhile(tag){ if((tag = tag[p]) && $(tag).is(q)){\n\t\t\t\tl.push(tag); if(c){ return }\n\t\t\t}}\n\t\t});\n\t\treturn I;\n\t}\n\t$.fn.closest = function(q, c){ return this.parents(q, 1) }\n\t$.fn.clone = function(b, I, l){\n\t\tI = $(), l = I.tags;\n\t\tthis.each(function(i, tag){\n\t\t\tl.push(tag.cloneNode(true))\n\t\t});\n\t\treturn I;\n\t}\n}());"
  },
  {
    "path": "lib/email.js",
    "content": ";(function(){\n\tvar email, fail = {send: function(opt, cb){ cb && cb(\"You do not have email installed.\") } };\n\tif(!process.env.EMAIL){ return module.exports = fail }\n\ttry{ email = require('emailjs') }catch(e){};\n\tif(!email){ return module.exports = fail }\n\treturn module.exports = email.server.connect({\n\t  user: process.env.EMAIL,\n\t  password: process.env.EMAIL_KEY,\n\t  host: process.env.EMAIL_HOST || \"smtp.gmail.com\",\n\t  ssl: process.env.EMAIL_SSL || true\n\t});\n}());"
  },
  {
    "path": "lib/erase.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.on('opt', function(root){\n\tthis.to.next(root);\n\tif(root.once){ return }\n\troot.on('put', function(msg){\n\t\tGun.graph.is(msg.put, null, function(val, key, node, soul){\n\t\t\tif(null !== val){ return }\n\t\t\t// TODO: Refactor this to use `.off()`?\n\t\t\tvar tmp = root.graph[soul];\n\t\t\tif(tmp){\n\t\t\t\tdelete tmp[key];\n\t\t\t}\n\t\t\ttmp = tmp && tmp._ && tmp._['>'];\n\t\t\tif(tmp){\n\t\t\t\tdelete tmp[key];\n\t\t\t}\n\t\t\ttmp = root.next;\n\t\t\tif(tmp && (tmp = tmp[soul]) && (tmp = tmp.put)){\n\t\t\t\tdelete tmp[key];\n\t\t\t\ttmp = tmp._ && tmp._['>'];\n\t\t\t\tif(tmp){\n\t\t\t\t\tdelete tmp[key];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.to.next(msg);\n\t});\n});"
  },
  {
    "path": "lib/evict.js",
    "content": ";(function(){\n\tvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\tvar ev = {}, empty = {}, u;\n\tGun.on('opt', function(root){\n\t\tthis.to.next(root);\n\t\tif(root.once){ return }\n\t\tif(typeof process == 'undefined'){ return }\n\t\tvar util = process.memoryUsage, heap;\n\t\tif(!util){ return }\n\t\ttry{ heap = require('v8').getHeapStatistics }catch(e){}\n\t\tif(!heap){ return }\n\n\t\tev.max = parseFloat(root.opt.memory || (heap().heap_size_limit / 1024 / 1024) || process.env.WEB_MEMORY || 1399) * 0.8; // max_old_space_size defaults to 1400 MB. Note: old space !== memory space though. // KEEPING USED_HEA_SIZE < HEAP_SIZE_LIMIT ONLY THING TO BE BELOW TO PREVENT CRASH!\n\t\t\n\t\tsetInterval(check, 1000);\n\t\tfunction check(){\n\t\t\tvar used = util().rss / 1024 / 1024;\n\t\t\tvar hused = heap().used_heap_size / 1024 / 1024;\n\t\t\tvar tmp; if(tmp = console.STAT){ tmp.memax = parseFloat(ev.max.toFixed(1)); tmp.memused = parseFloat(used.toFixed(1)); tmp.memhused = parseFloat(hused.toFixed(1)); }\n\t\t\tif(hused < ev.max && used < ev.max){ return }\n\t\t\t//if(used < ev.max){ return }\n\t\t\tconsole.STAT && console.STAT('evict memory:', hused.toFixed(), used.toFixed(), ev.max.toFixed());\n\t\t\tGC();//setTimeout(GC, 1);\n\t\t}\n\t\tfunction GC(){\n\t\t\tvar S = +new Date;\n\t\t\tvar souls = Object.keys(root.graph||empty);\n\t\t\tvar toss = Math.ceil(souls.length * 0.01);\n\t\t\tsetTimeout.each(souls, function(soul){\n\t\t\t\tif(--toss < 0){ return 1 }\n\t\t\t\troot.$.get(soul).off();\n\t\t\t},0,99);\n\t\t\troot.dup.drop(1000 * 9); // clean up message tracker\n\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'evict');\n\t\t}\n\t\t/*\n\t\troot.on('in', function(msg){\n\t\t\tthis.to.next(msg);\n\t\t\tif(msg.get){\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tGun.graph.is(msg, function(node, soul){\n\t\t\t\tvar meta = (root.next||empty)[soul];\n\t\t\t\tif(!meta){ return }\n\t\t\t\tGun.node.is(node, function(data, key){\n\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t\t*/\n\t});\n}());"
  },
  {
    "path": "lib/file.js",
    "content": "// This was written by the wonderful Forrest Tait\n// modified by Mark to be part of core for convenience\n// twas not designed for production use\n// only simple local development.\n\nvar Gun = require('../gun'),\nfs = require('fs');\n\nGun.on('create', function(root){\n\tthis.to.next(root);\n\tvar opt = root.opt;\n\tif(true !== opt.localStorage){ return }\n\tif(false === opt.localStorage){ return }\n\t//if(process.env.RAD_ENV){ return }\n\t//if(process.env.AWS_S3_BUCKET){ return }\n\topt.file = String(opt.file || 'data.json');\n\tvar graph = root.graph, acks = {}, count = 0, to;\n\tvar disk = Gun.obj.ify((fs.existsSync || require('path').existsSync)(opt.file)? \n\t\tfs.readFileSync(opt.file).toString()\n\t: null) || {};\n\n\tGun.log.once(\n\t\t'file-warning',\n\t\t'WARNING! This `file.js` module for gun is ' +\n\t\t'intended for local development testing only!'\n\t);\n\t\n\troot.on('put', function(at){\n\t\tthis.to.next(at);\n\t\tGun.graph.is(at.put, null, map);\n\t\tif(!at['@']){ acks[at['#']] = true; } // only ack non-acks.\n\t\tcount += 1;\n\t\tif(count >= (opt.batch || 10000)){\n\t\t\treturn flush();\n\t\t}\n\t\tif(to){ return }\n\t\tto = setTimeout(flush, opt.wait || 1);\n\t});\n\n\troot.on('get', function(at){\n\t\tthis.to.next(at);\n\t\tvar lex = at.get, soul, data, opt, u;\n\t\t//setTimeout(function(){\n\t\tif(!lex || !(soul = lex['#'])){ return }\n\t\t//if(0 >= at.cap){ return }\n\t\tif(Gun.obj.is(soul)){ return match(at) }\n\t\tvar field = lex['.'];\n\t\tdata = disk[soul] || u;\n\t\tif(data && field){\n\t\t\tdata = Gun.state.to(data, field);\n\t\t}\n\t\troot.on('in', {'@': at['#'], put: Gun.graph.node(data)});\n\t\t//},11);\n\t});\n\n\tvar map = function(val, key, node, soul){\n\t\tdisk[soul] = Gun.state.to(node, key, disk[soul]);\n\t}\n\n\tvar wait, u;\n\tvar flush = function(){\n\t\tif(wait){ return }\n\t\tclearTimeout(to);\n\t\tto = false;\n\t\tvar ack = acks;\n\t\tacks = {};\n\t\tfs.writeFile(opt.file, JSON.stringify(disk), function(err, ok){\n\t\t\twait = false;\n\t\t\tvar tmp = count;\n\t\t\tcount = 0;\n\t\t\tGun.obj.map(ack, function(yes, id){\n\t\t\t\troot.on('in', {\n\t\t\t\t\t'@': id,\n\t\t\t\t\terr: err,\n\t\t\t\t\tok: err? u : 1\n\t\t\t\t});\n\t\t\t});\n\t\t\tif(1 < tmp){ flush() }\n\t\t});\n\t}\n\n\tfunction match(at){\n\t\tvar rgx = at.get['#'], has = at.get['.'];\n\t\tGun.obj.map(disk, function(node, soul, put){\n\t\t\tif(!Gun.text.match(soul, rgx)){ return }\n\t\t\tif(has){ node = Gun.state.to(node, has) }\n\t\t\t(put = {})[soul] = node;\n\t\t\troot.on('in', {put: put, '@': at['#']});\n\t\t});\n\t}\n});"
  },
  {
    "path": "lib/forget.js",
    "content": ";(function(){\n\tvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\n\tGun.on('opt', function(root){\n\t\tonce(root);\n\t\tthis.to.next(root);\n\t});\n\n\tfunction once(root){\n\t\tif(root.once){ return }\n\t\tvar forget = root.opt.forget = root.opt.forget || {};\n\t\troot.on('put', function(msg){\n\t\t\tGun.graph.is(msg.put, function(node, soul){\n\t\t\t\tif(!Gun.obj.has(forget, soul)){ return }\n\t\t\t\tdelete msg.put[soul];\n\t\t\t});\n\t\t\tthis.to.next(msg);\n\t\t});\n\t}\n\n}());"
  },
  {
    "path": "lib/fork.js",
    "content": "/*\ndescribe('API Chain Features', function(){\n\n    describe('Gun.chain.fork', function(){\n        var gun = Gun();\n        var fork;\n        it('create fork', function(done){\n            fork = gun.fork().wire();\n            done();\n        });\t\t\t\n        it('put data via fork', function(done){\t\t\t\t\t\t\t\t\n            fork.get(\"fork-test\").get(\"fork\").put(\"test123\").once(()=>done());\t\t\t\t\n        });\t\t\t\n        it('get data via main', function(done){\t\t\t\t\t\t\t\t\n            gun.get(\"fork-test\").get(\"fork\").once((data)=>{\n                expect(data).to.be(\"test123\");\n                done();\n            });\t\t\t\t\n        });\t\t\t\n        it('put data via main', function(done){\t\t\t\t\t\t\t\t\n            gun.get(\"fork-test\").get(\"main\").put(\"test321\").once(()=>done());\t\t\t\t\n        });\t\t\t\n        it('get data via fork', function(done){\t\t\t\t\t\t\t\t\n            fork.get(\"fork-test\").get(\"main\").once((data)=>{\n                expect(data).to.be(\"test321\");\n                done();\n            });\t\t\t\t\n        });\n    })\n\n})\n*/\n(function (Gun, u) {\n    /**\n     * \n     *  credits: \n     *      github:bmatusiak\n     * \n     */\n    Gun.chain.fork = function(g) {\n        var gun = this._;\n        var w = {},\n            mesh = () => {\n                var root = gun.root,\n                    opt = root.opt;\n                return opt.mesh || Gun.Mesh(root);\n            }\n        w.link = function() {\n            if (this._l) return this._l;\n            this._l = {\n                send: (msg) => {\n                    if (!this.l || !this.l.onmessage)\n                        throw 'not attached';\n                    this.l.onmessage(msg);\n                }\n            }\n            return this._l;\n        };\n        w.attach = function(l) {\n            if (this.l)\n                throw 'already attached';\n            var peer = { wire: l };\n            l.onmessage = function(msg) {\n                mesh().hear(msg.data || msg, peer);\n            };\n            mesh().hi(this.l = l && peer);\n        };\n        w.wire = function(opts) {\n            var f = new Gun(opts);\n            f.fork(w);\n            return f;\n        };\n        if (g) {\n            w.attach(g.link());\n            g.attach(w.link());\n        }\n        return w;\n    };\n\n    \n})((typeof window !== \"undefined\") ? window.Gun : require('../gun'))"
  },
  {
    "path": "lib/fsrm.js",
    "content": "var fs = require('fs');\nvar nodePath = require('path');\n\nvar dir = __dirname + '/../';\n\nmodule.exports = function rm(path, full) {\n\tpath = full || nodePath.join(dir, path);\n  if(!fs.existsSync(path)){ return }\n  fs.readdirSync(path).forEach(function(file,index){\n    var curPath = path + \"/\" + file;\n    if(fs.lstatSync(curPath).isDirectory()) { // recurse\n      rm(null, curPath);\n    } else { // delete file\n      fs.unlinkSync(curPath);\n    }\n  });\n  fs.rmdirSync(path);\n};"
  },
  {
    "path": "lib/fun.js",
    "content": "window.fun = function fun(e){ setTimeout(() => {\n\te = e || {}; var $img = $('<div class=\"joy\"></div>')\n\t\t.css({position: 'fixed', width: 100,\n\t\t\ttop: (e.y || e.clientY || (Math.random() * $(window).height()))-50,\n\t\t\tleft: (e.x || e.clientX || e.pageX || (Math.random() * $(window).width()))-50,\n\t\t\ttransform: 'rotate('+(Math.random() * 360)+'deg)'\n\t\t}).appendTo('body');\n\t\tsetTimeout(() => { $img.remove() },800);\n},10)};\n$(document).on('keyup', fun).on('touchstart', fun).on('mousedown', fun);"
  },
  {
    "path": "lib/hot.js",
    "content": ";(function(){\n\t// on fires when shortcut keydowns or on touch after command selected and then touchdown\n\tvar m = meta;\n\tm.edit({name: \"Add\", combo: ['A']});\n\tm.edit({name: \"Row\", combo: ['A', 'R'],\n\t\ton: function(eve){\n\t\t\tm.tap().append('<div class=\"hold center\" style=\"min-height: 9em; padding: 2%;\">');\n\t\t}\n\t});\n\tm.edit({name: \"Columns\", combo: ['A','C'],\n\t\ton: function(eve){\n\t\t\tvar on = m.tap(), tmp, c;\n\t\t\tvar html = '<div class=\"unit col\" style=\"min-height: 9em; padding: 2%;\"></div>';\n\t\t\tif(!on.children('.col').length){ html += html }\n\t\t\tc = (tmp = on.append(html).children('.col')).length;\n\t\t\ttmp.each(function(){\n\t\t\t\t$(this).css('width', (100/c)+'%');\n\t\t\t})\n\t\t}\n\t});\n\tm.edit({name: \"Text\", combo: ['A','T'],\n\t\ton: function(eve){\n\t\t\tm.tap().append('<p contenteditable=\"true\">Text</p>');\n\t\t}\n\t});\n\tm.edit({name: \"Drag\", combo: ['D']});\n\t;(function(){\n\t\t$(document).on('click', function(){\n\t\t\tvar tmp = $('.m-on');\n\t\t\tif(!tmp.length){ return }\n\t\t\ttmp.removeClass('m-on');\n\t\t})\n\t\tm.edit({combo: [38], // up\n\t\t\ton: function(eve){\n\t\t\t\tvar on = m.tap().removeClass('m-on');\n\t\t\t\ton = on.prev().or(on.parent()).or(on);\n\t\t\t\ton.addClass('m-on');\n\t\t\t}, up: function(){ \n\t\t\t}\n\t\t});\n\t\tm.edit({combo: [40], // down\n\t\t\ton: function(eve){\n\t\t\t\tvar on = m.tap().removeClass('m-on');\n\t\t\t\ton = on.next().or(on.children().first()).or(on);\n\t\t\t\ton.addClass('m-on');\n\t\t\t}, up: function(){ \n\t\t\t}\n\t\t});\n\t\tm.edit({combo: [39], // right\n\t\t\ton: function(eve){\n\t\t\t\tvar on = m.tap().removeClass('m-on');\n\t\t\t\ton = on.children().first().or(on.next()).or(on.parent()).or(on);\n\t\t\t\ton.addClass('m-on');\n\t\t\t}, up: function(){ \n\t\t\t}\n\t\t});\n\t\tm.edit({combo: [37], // left\n\t\t\ton: function(eve){\n\t\t\t\tvar on = m.tap().removeClass('m-on');\n\t\t\t\ton = on.parent().or(on);\n\t\t\t\ton.addClass('m-on');\n\t\t\t}, up: function(){ \n\t\t\t}\n\t\t});\n\t}());\n\tm.edit({name: \"Turn\", combo: ['T']});\n\tm.edit({name: \"Size\", combo: ['S']});\n\tm.edit({name: \"X\", combo: ['S','X'],\n\t\ton: function(eve){\n\t\t\tvar on = m.tap(), was = on.width();\n\t\t\t$(document).on('mousemove.tmp', function(eve){\n\t\t\t\tvar be = was + ((eve.pageX||0) - was);\n\t\t\t\ton.css({'max-width': be, width: '100%'});\n\t\t\t})\n\t\t}, up: function(){ $(document).off('mousemove.tmp') }\n\t});\n\tm.edit({name: \"Y\", combo: ['S','Y'],\n\t\ton: function(eve){\n\t\t\tvar on = m.tap(), was = on.height();\n\t\t\t$(document).on('mousemove.tmp', function(eve){\n\t\t\t\tvar be = was + ((eve.pageY||0) - was);\n\t\t\t\ton.css({'min-height': be});\n\t\t\t})\n\t\t}, up: function(){ $(document).off('mousemove.tmp') }\n\t});\n\tm.edit({name: \"Fill\", combo: ['F'],\n\t\ton: function(eve){\n\t\t\tvar on = m.tap();\n\t\t\tm.ask('Color name, code, or URL?', function(color){\n\t\t\t\tvar css = on.closest('p').length? 'color' : 'background';\n\t\t\t\ton.css(css, color);\n\t\t\t});\n\t\t}\n\t});\n}());"
  },
  {
    "path": "lib/http.js",
    "content": "var Gun = require('../gun')\r\n,\tformidable = require('formidable')\r\n,\turl = require('url');\r\nmodule.exports = function(req, res, next){\r\n\tnext = next || function(){}; // if not next, and we don't handle it, we should res.end\r\n\tif(!req || !res){ return next() }\r\n\tif(!req.url){ return next() }\r\n\tif(!req.method){ return next() }\r\n\tvar msg = {};\r\n\tmsg.url = url.parse(req.url, true);\r\n\tmsg.method = (req.method||'').toLowerCase();\r\n\tmsg.headers = req.headers;\r\n\tvar u, body\r\n\t,\tform = new formidable.IncomingForm()\r\n\t,\tpost = function(err, body){\r\n\t\tif(u !== body){ msg.body = body }\r\n\t\tnext(msg, function(reply){\r\n\t\t\tif(!res){ return }\r\n\t\t\tif(!reply){ return res.end() }\r\n\t\t\tif(Gun.obj.has(reply, 'statusCode') || Gun.obj.has(reply, 'status')){\r\n\t\t\t\tres.statusCode = reply.statusCode || reply.status;\r\n\t\t\t}\r\n\t\t\tif(reply.headers){\r\n\t\t\t\tif(!(res.headersSent || res.headerSent || res._headerSent || res._headersSent)){\r\n\t\t\t\t\tGun.obj.map(reply.headers, function(val, field){\r\n\t\t\t\t\t\tif(val !== 0 && !val){ return }\r\n\t\t\t\t\t\tres.setHeader(field, val);\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif(Gun.obj.has(reply,'chunk') || Gun.obj.has(reply,'write')){\r\n\t\t\t\tres.write(Gun.text.ify(reply.chunk || reply.write) || '');\r\n\t\t\t}\r\n\t\t\tif(Gun.obj.has(reply,'body') || Gun.obj.has(reply,'end')){\r\n\t\t\t\tres.end(Gun.text.ify(reply.body || reply.end) || '');\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\tform.on('field',function(k,v){\r\n\t\t(body = body || {})[k] = v;\r\n\t}).on('file',function(k,v){\r\n\t\treturn; // files not supported in gun yet\r\n\t}).on('error',function(e){\r\n\t\tif(form.done){ return }\r\n\t\tpost(e);\r\n\t}).on('end', function(){\r\n\t\tif(form.done){ return }\r\n\t\tpost(null, body);\r\n\t});\r\n\tform.parse(req);\r\n}"
  },
  {
    "path": "lib/hub.js",
    "content": "const fs = require('fs');\nconst Gun = require('../index.js');\n\nconst gun = Gun();\n\nlet chokidar;\n\ntry { chokidar = require('chokidar') } catch (error) {\n} // Must install chokidar to use this feature.\n\n/**\n * Watches a directory and send all its content in the database\n * @constructor\n * @param {string} what - Which directory hub should watch.\n * @param {Object} options - https://gun.eco/docs/hub.js#options\n */\nfunction watch(what, options) {\n  options = options ?? { msg: true, hubignore: false, alias: require('os').userInfo().username }\n  \n  options.msg = options.msg ?? true;\n  options.hubignore = options.hubignore ?? false;\n  options.alias = options.alias ?? require('os').userInfo().username\n  \n  let modifiedPath = options.alias;\n\n  let watcher; \n  try {\n\n    if (options.hubignore) {\n\n      watcher = chokidar.watch(what, {\n        persistent: true\n      });\n    \n    } else if (!options.hubignore) {\n\n      watcher = chokidar.watch(what, {\n        ignored: /(^|[\\/\\\\])\\../, // ignore dotfiles\n        persistent: true\n      });\n\n    }\n    \n    const log = console.log.bind(console);\n    \n    let hubignore;\n\n    // Handle events !\n    watcher\n      .on('add', async function(path) { \n\n        if (options.hubignore && path.includes('.hubignore')) {\n\n          hubignore = fs.readFileSync(what + '/.hubignore', 'utf-8');\n\n        } else if (!path.includes('.hubignore') && !hubignore?.includes(path.substring(path.lastIndexOf(\"/\") + 1))) {\n\n          if (options.msg) log(`File ${path} has been added`);\n\n          if(path[path.search(/^./gm)] === \"/\" || \".\") {\n            gun.get('hub').get(modifiedPath + path.split(require('os').userInfo().username)[1]).put(fs.readFileSync(path, 'utf-8'))\n          } else {\n            gun.get('hub').get(modifiedPath + '/' + path.split(require('os').userInfo().username)[1]).put(fs.readFileSync(path, 'utf-8'))\n          }\n\n        } else {\n\n          if(options.msg) log(`The addition of ${path} has been ignored !`)\n\n        }\n     \n      })\n      .on('change', async function(path) { \n\n        if (options.hubignore && path.includes('.hubignore')) {\n\n          hubignore = fs.readFileSync(what + '/.hubignore', 'utf-8');\n\n        } else if (!path.includes('.hubignore') && !hubignore?.includes(path.substring(path.lastIndexOf('/') + 1))) {\n          \n          if (options.msg) log(`File ${path} has been changed`);\n          if(path[path.search(/^./gm)] === \"/\" || \".\") {\n            gun.get('hub').get(modifiedPath + path.split(require('os').userInfo().username)[1]).put(fs.readFileSync(path, 'utf-8'))\n          } else {\n            gun.get('hub').get(modifiedPath + '/' + path.split(require('os').userInfo().username)[1]).put(fs.readFileSync(path, 'utf-8'))\n          }\n        \n        } else {\n\n          if(options.msg) log(`The changes on ${path} has been ignored.`)\n\n        }\n\n      })\n      .on('unlink', async function (path) {\n        \n        if (options.hubignore && path.includes('.hubignore')) {\n          \n          hubignore = fs.readFileSync(what + '/.hubignore', 'utf-8');\n\n        } else if (!path.includes('.hubignore') && !hubignore?.includes(path.substring(path.lastIndexOf('/') + 1))) {\n\n          if(options.msg) log(`File ${path} has been removed`);  \n          if(path[path.search(/^./gm)] === \"/\" || \".\") {\n            gun.get('hub').get(modifiedPath + path.split(require('os').userInfo().username)[1]).put(null)\n          } else {\n\t\t\t\t\t\tgun.get('hub').get(modifiedPath + '/' + path.split(require('os').userInfo().username)[1]).put(null)\n          }\n\n\n        } else {\n\n          if(options.msg) log(`The deletion of ${path} has been ignored!`)\n\n        }\n      \n      })\n      if (options.msg) {\n        watcher\n        .on('addDir', path => log(`Directory ${path} has been added`))\n        .on('unlinkDir', path => log(`Directory ${path} has been removed`))\n        .on('error', error => log(`Watcher error: ${error}`))\n        .on('ready', () => log('Initial scan complete. Ready for changes'))\n      }\n\n  } catch (err) {\n    console.log('If you want to use the hub feature, you must install `chokidar` by typing `npm i chokidar` in your terminal.')\n  }\n}\n\nmodule.exports = { watch : watch }"
  },
  {
    "path": "lib/ipfs.js",
    "content": "console.log(\"IPFS PLUGIN NOT OFFICIALLY MAINTAINED! PROBABLY WON'T WORK! USE AT YOUR OWN RISK! PLEASE CONTRIBUTE FIXES!\");\nvar opt = gun._.opt, u;\nif (u === opt.ipfs.directory) {\n  opt.ipfs.directory = '/gun';\n}\nopt.store = {};\nopt.store.put = function(file, data, cb){\n  var uri = opt.ipfs.directory + '/' + file;\n  opt.ipfs.instance.files.write(uri, Buffer.from(JSON.stringify(data)), {create:true})\n  .then(res => {\n    console.log('File written to IPFS directory', uri, res);\n    return opt.ipfs.instance.files.stat(opt.ipfs.directory, {hash:true});\n  }).then(res => {\n    console.log('Directory hash:', res.hash);\n    return opt.ipfs.instance.name.publish(res.hash);\n    // currently throws \"This command must be run in online mode. Try running 'ipfs daemon' first.\" for some reason, maybe js-ipfs IPNS not ready yet\n  }).then(res => {\n    console.log('IPFS put request successful:', res);\n    cb(undefined, 1);\n  }).catch(error => {\n    console.error('IPFS put request failed', error);\n  });\n}\nopt.store.get = function(file, cb){\n    var uri = opt.ipfs.directory + '/' + file;\n    opt.ipfs.instance.files.read(uri, {})\n    .then(res => {\n      var data = JSON.parse(res.toString());\n      console.log(uri + ' was loaded from ipfs:', data);\n      cb(data);\n    });\n}\nopt.store.list = function(cb){\n    var stream = opt.ipfs.files.lsReadableStream(opt.ipfs.directory);\n\n    stream.on('data', (file) => {\n      console.log('ls', file.name);\n      if (cb(file.name)) {\n        stream.destroy();\n      }\n    });\n\n    stream.on('finish', () => {\n      cb();\n    });\n}"
  },
  {
    "path": "lib/ison.js",
    "content": "/* **************************************************************************\n * A modified version of yieldable-json package that's backwards compatible\n * with GunDB's YSON implementation\n *\n * (c) Copyright IBM Corp. 2017\n *\n *  This program and the accompanying materials are made available\n *  under the terms of the Apache License v2.0 which accompanies\n *  this distribution.\n *\n *      The Apache License v2.0 is available at\n *      http://www.opensource.org/licenses/apache2.0.php\n *\n * Contributors:\n *   Multiple authors (IBM Corp.) - initial implementation and documentation\n * **************************************************************************/\n\n;(function () {\nvar yson = {}, u;\n\nlet counter = 0;\nlet objStack = [];\nlet temp = '';\nconst limit = 100000;\n\nfunction StringifyError(m) {\n  this.name = 'Error';\n  this.message = m;\n}\n\n/**\n * Checking for unicode and backslash characters and replaces if any.\n * @param { string }\n * @return { string }\n */\n\nlet normalize = (string, flagN) => {\n  let retStr = '';\n  let transform = '';\n  let uc =\n  '/[\\\\\\'\\u0000-\\u001f\\u007f-\\u009f\\u00ad\\u0600-\\u0604\\u070f\\u17b4' +\n  '\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g';\n  let unicode = new RegExp(uc);\n  // Taking '\\\\' out of the loop to avoid change in\n  // order of execution of object entries resulting\n  // in unwanted side effect\n  string = string.replace(/\\\\/gi, '\\\\\\\\');\n  let escape = {\n    '\\b': '\\\\b',\n    '\\t': '\\\\t',\n    '\\n': '\\\\n',\n    '\\f': '\\\\f',\n    '\\r': '\\\\r',\n    '\"': '\\\\\"',\n  };\n  // Escape is implemented globally\n  for(var pattern in escape) {\n    var regex = new RegExp(pattern,'gi')\n    string = string.replace(regex, escape[pattern])\n  }\n  unicode.lastIndex = 0;\n  if (unicode.test(string)) {\n    // Unicode logic here\n    transform = string.replace(unicode, (a) => {\n      return '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n    });\n    if (flagN === 1) {\n      transform += temp;\n      transform += transform;\n      temp = '';\n      return '\"' + transform + '\"';\n    } else if (flagN === 2) {\n      return '\"' + transform + '\"';\n    } else {\n      temp += transform;\n    }\n  } else {\n    if (flagN === 1) {\n      retStr += temp;\n      retStr += string;\n      temp = '';\n      return '\"' + retStr + '\"';\n    } else if (flagN === 2) {\n      return '\"' + string + '\"';\n    } else {\n      temp += string;\n      return;\n    }\n  }\n};\n\n/**\n * Obtain stringified value by yielding at required intensity\n * @param { string} field\n * @param { primitive data type } container\n * @param { function or array } replacer\n * @param { number or string } space\n * @param { number } intensity\n * @return { function } yieldCPU\n */\n\nfunction * stringifyYield(field, container, replacer, space, intensity) {\n  let itr = 0;\n  let key = '';\n  let val = '';\n  let length = 0;\n  let tempVal = '';\n  let result = '';\n  let value = container[field];\n  // Made scope local handling async issues\n  let flag1 = 0;\n  let returnStr = '';\n  let subStr = '';\n  let len = 0;\n\n  // Yield the stringification at definite intervals\n  if (++counter > 512 * intensity) {\n    counter = 0;\n    yield val;\n  }\n\n  // Call replacer if one is present (SPEC)\n  if (typeof replacer === 'function') {\n    value = replacer.call(container, field, value);\n  }\n\n  switch (typeof value) {\n    case 'string':\n      if (value.length > limit) {\n        for (let l = 0; l < value.length; l += limit) {\n          flag1 = 0;\n          yield value;\n          subStr = value.substr(l, limit);\n          len += subStr.length;\n          if (len === value.length)\n            flag1 = 1;\n          returnStr = normalize(subStr, flag1);\n        }\n      } else\n        returnStr = normalize(value, 2);\n      return returnStr;\n    case 'number':\n      return isFinite(value)\n        ? String(value)\n        : 'null';\n    case 'boolean':\n    case 'null':\n      return String(value);\n    case 'undefined':\n\t\t\treturn;\n\t\tcase 'function':\n\t\t\treturn 'null';\n    case 'object':\n      if (!value)\n        return 'null';\n\n    // Manage special cases of Arrays and Objects\n      let getResult = (decision) => {\n        if (result.length === 0)\n          if (decision)\n            return '{}';\n          else\n          return '[]';\n        else\n        if (decision)\n          if (space)\n            return '{\\n' + space + result.join(',\\n' + space) + '\\n' + '}';\n          else\n            return '{' + result.join(',') + '}';\n        else\n          if (space)\n            return '[\\n' + space + result.join(',\\n' + space) + '\\n' + ']';\n          else\n            return '[' + result.join(',') + ']';\n      };\n\n      result = [];\n    // If toJSON is present, invoke it (SPEC)\n\t\t\tif (value && typeof value.toJSON === 'function') {\n\t\t\t\tconst response = value.toJSON(field);\n\t\t\t\tif (response === undefined) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tif (typeof response === \"number\") {\n\t\t\t\t\tresult.push(value.toJSON(field));\n\t\t\t\t} else {\n\t\t\t\t\tresult.push('\"' + value.toJSON(field) + '\"');\n\t\t\t\t}\n        if (result.length === 0)\n          return '{}';\n        else\n        if (space)\n          return space + result.join(',\\n' + space) + '\\n';\n        else\n          return result.join(',');\n      }\n    // Array case\n      if (value && value.constructor === Array) {\n        length = value.length;\n        for (itr = 0; itr < length; itr += 1) {\n          tempVal =\n          yield *stringifyYield(itr, value, replacer, space, intensity) ||\n          'null';\n          if (tempVal !== undefined)\n            result.push(tempVal);\n        }\n        return getResult(false);\n      }\n\n    // Manage replacing object scenario (SPEC)\n      if (replacer && typeof replacer === 'object') {\n        length = replacer.length;\n        for (itr = 0; itr < length; itr += 1) {\n          if (typeof replacer[itr] === 'string') {\n            key = replacer[itr];\n            val = yield *stringifyYield(key, value, replacer, space, intensity);\n            if (val !== undefined)\n\t\t\t\t\t\t\tresult.push(normalize(key, 2) + (space\n\t\t\t\t\t\t\t\t? ': '\n\t\t\t\t\t\t\t\t: ':') + val);\n          }\n        }\n      } else {\n      // Object case\n        objStack.push(value);\n        for (key in value) {\n          if (typeof value[key] === 'object' && value[key] !== null &&\n          value[key] !== undefined) {\n            if (objStack.indexOf(value[key]) !== -1) {\n              return new StringifyError('Circular Structure Detected');\n            } else\n            objStack.push(value[key]);\n          }\n          if (Object.hasOwnProperty.call(value, key)) {\n            val = yield *stringifyYield(key, value, replacer, space, intensity);\n            if (val !== undefined)\n              result.push(normalize(key, 2) + (space\n              ? ': '\n              : ':') + val);\n          }\n          objStack = objStack.filter((v, i, a) => { return v !== value[key] });\n        }\n        objStack = objStack.filter((v, i, a) => { return v !== value });\n      }\n      return getResult(true);\n    default:\n      return new StringifyError('Unexpected Character');\n  }\n}\n\n/**\n * Calling appropriate functions each time.\n * @param { primitive data types } value\n * @param { function or array } replacer\n * @param { number or string } space\n * @param { number } intensity\n * @param { function } callback\n * @return { function } yieldCPU\n */\n\nlet stringifyWrapper = (value, replacer, space, intensity, callback) => {\n  let indent = '';\n  if (typeof space === 'number') {\n    indent = ' '.repeat(space);\n  } else if (typeof space === 'string') {\n    indent = space;\n  }\n\n  let yielding;\n\n  // To hold 'stringifyYield' genarator function\n  function * yieldBridge() {\n    yielding = yield *stringifyYield('', {'': value}, replacer, indent, 1);\n  }\n\n  let rs = yieldBridge();\n  let g = rs.next();\n\n  let yieldCPU = () => {\n    setTimeout(() => {\n      g = rs.next();\n      if (g && g.done === true) {\n        // Reinitializing the values at the end of API call\n        counter = 0;\n        temp = ''\n        objStack = [];\n        if (typeof yielding === 'object')\n          return callback(yielding, null);\n        else\n          return callback(null, yielding);\n      }\n      yieldCPU();\n    }, 0);\n  };\n  return yieldCPU();\n};\n\n/**\n * This method parses a JSON text to produce an object or array.\n * It can throw a SyntaxError exception, if the string is malformed.\n * @param { string } text\n * @param { function or array } reviver\n * @param { number } intensity\n * @param { function } cb\n * @return { function } yieldCPU\n */\nlet parseWrapper = (text, reviver, intensity, cb) => {\n  let counter = 0;\n  let keyN = 0;\n  let parseStr = text;\n  let at = 0;\n  let ch = ' ';\n  let word = '';\n  function ParseError(m) {\n    this.name = 'ParseError';\n    this.message = m;\n    this.text = parseStr;\n  }\n\n  // Seek to the next character, after skipping white spaces, if any.\n  let seek = () => {\n    ch = parseStr.charAt && parseStr.charAt(at);\n    at++;\n    while (ch && ch <= ' ') {\n      seek();\n    }\n    return ch;\n  };\n\n  // Seek to the previous character, required in some special cases.\n  let unseek = () => {\n    ch = parseStr.charAt(--at);\n  };\n\n  // Match 'true', 'false' and  'null' built-ins.\n  let wordCheck = () => {\n    word = '';\n    do {\n      word += ch;\n      seek();\n    } while (ch.match(/[a-z]/i));\n    parseStr = parseStr.slice(at - 1);\n    at = 0;\n    return word;\n  };\n\n  // Process strings specially.\n  let normalizeUnicodedString = () => {\n    let inQuotes = ' ';\n    let tempIndex = at;\n    let index = 0;\n    let slash = 0;\n    let c = '\"';\n    while (c) {\n      index = parseStr.indexOf('\"', tempIndex + 1);\n      tempIndex = index;\n      ch = parseStr.charAt(tempIndex - 1);\n      while (ch === '\\\\') {\n        slash++;\n        ch = parseStr.charAt(tempIndex - (slash + 1));\n      }\n      if (slash % 2 === 0) {\n        inQuotes = parseStr.substring(at, index);\n        parseStr = parseStr.slice(++index);\n        slash = 0;\n        break;\n      } else\n        slash = 0;\n    }\n\n    // When parsing string values, look for \" and \\ characters.\n    index = inQuotes.indexOf('\\\\');\n    while (index >= 0) {\n      let escapee = {\n        '\"': '\"',\n        '\\'': '\\'',\n        '/': '/',\n        '\\\\': '\\\\',\n        b: '\\b',\n        f: '\\f',\n        n: '\\n',\n        r: '\\r',\n        t: '\\t',\n      };\n      let hex = 0;\n      let i = 0;\n      let uffff = 0;\n      at = index;\n      ch = inQuotes.charAt(++at);\n      if (ch === 'u') {\n        uffff = 0;\n        for (i = 0; i < 4; i += 1) {\n          hex = parseInt(ch = inQuotes.charAt(++at), 16);\n          if (!isFinite(hex)) {\n            break;\n          }\n          uffff = uffff * 16 + hex;\n        }\n        inQuotes = inQuotes.slice(0, index) +\n                   String.fromCharCode(uffff) + inQuotes.slice(index + 6);\n        at = index;\n      } else if (typeof escapee[ch] === 'string') {\n        inQuotes = inQuotes.slice(0, index) +\n                   escapee[ch] + inQuotes.slice(index + 2);\n        at = index + 1;\n      } else\n        break;\n      index = inQuotes.indexOf('\\\\', at);\n    }\n    at = 0;\n    return inQuotes;\n  };\n\n  /**\n  * This function parses the current string and returns the JavaScript\n  * Object, through recursive method, and yielding back occasionally\n  * based on the intensity parameter.\n  * @return { object } returnObj\n  */\n  function * parseYield() {\n    let key = '';\n    let returnObj = {};\n    let returnArr = [];\n    let v = '';\n    let inQuotes = '';\n    let num = 0;\n    let numHolder = '';\n    let addup = () => {\n      numHolder += ch;\n      seek();\n    };\n    // Handle premitive types. eg: JSON.parse(21)\n    if (typeof parseStr === 'number' || typeof parseStr === 'boolean' || typeof parseStr === \"function\" ||\n        parseStr === null) {\n      parseStr = '';\n      return text;\n    } else if (typeof parseStr === 'undefined') {\n      parseStr = undefined;\n      return text;\n\t\t} else if (parseStr.charAt && parseStr.charAt(0) === '[' && parseStr.charAt(1) === ']') {\n      parseStr = '';\n      return [];\n    } else if (parseStr.charAt && parseStr.charAt(0) === '{' && parseStr.charAt(1) === '}') {\n      parseStr = '';\n      return {};\n    } else {\n      // Yield the parsing work at specified intervals.\n      if (++counter > 512 * intensity) {\n        counter = 0;\n        yield;\n      }\n      // Common case: non-premitive types.\n      if (keyN !== 1)\n        seek();\n      switch (ch) {\n        case '{':\n        // Object case\n          seek();\n          if (ch === '}') {\n            parseStr = parseStr.slice(at);\n            at = 0;\n            return returnObj;\n          }\n          do {\n            if (ch !== '\"')\n              seek();\n            keyN = 1;\n            key = yield *parseYield();\n            keyN = 0;\n            seek();\n            returnObj[key] = yield *parseYield();\n            seek();\n            if (ch === '}') {\n              parseStr = parseStr.slice(at);\n              at = 0;\n              return returnObj;\n            }\n          } while (ch === ',');\n          return new ParseError('Bad object');\n        case '[':\n        // Array case\n          seek();\n          if (ch === ']') {\n            parseStr = parseStr.slice(at);\n            at = 0;\n            return returnArr;\n          }\n          unseek();\n          do {\n            v = yield *parseYield();\n            returnArr.push(v);\n            seek();\n            if (ch === ']') {\n              parseStr = parseStr.slice(at);\n              at = 0;\n              return returnArr;\n            }\n\t\t\t\t\t} while (ch === ',');\n          return new ParseError('Bad array');\n        case '\"':\n          parseStr = parseStr.slice(at - 1);\n          at = 0;\n          if (parseStr.charAt(0) === '\"' && parseStr.charAt(1) === '\"') {\n            parseStr = parseStr.slice(2);\n            at = 0;\n            return inQuotes;\n          } else {\n            seek();\n            return normalizeUnicodedString();\n          }\n        case '0':\n        case '1':\n        case '2':\n        case '3':\n        case '4':\n        case '5':\n        case '6':\n        case '7':\n        case '8':\n        case '9':\n        case '-':\n          if (ch === '-') addup();\n          do {\n            addup();\n            if (ch === '.' || ch === 'e' || ch === 'E' ||\n              ch === '-' || ch === '+' ||\n              (ch >= String.fromCharCode(65) &&\n              ch <= String.fromCharCode(70)))\n              addup();\n          } while (ch === '-' || ch === '+' || (isFinite(ch) && ch !== ''));\n          num = Number(numHolder);\n          parseStr = parseStr.slice(at - 1);\n          at = 0;\n          return num;\n        case 't':\n          word = wordCheck();\n          if (word === 'true')\n            return true;\n          else return new ParseError('Unexpected character');\n        case 'f':\n          word = wordCheck();\n          if (word === 'false')\n            return false;\n          else return new ParseError('Unexpected character');\n        case 'n':\n          word = wordCheck();\n          if (word === 'null')\n            return null;\n          else return new ParseError('Unexpected character');\n        default:\n          return new ParseError('Unexpected character');\n      }\n    }\n  }\n\n  /**\n   * If there is a reviver function, we recursively walk the new structure,\n   * passing each name/value pair to the reviver function for possible\n   * transformation, starting with a temporary root object that holds the result\n   * in an empty key. If there is not a reviver function, we simply return the\n   * result.\n   * @param { object } yieldedObject\n   * @param { string } key\n   * @return { function } reviver\n   */\n  let revive = (yieldedObject, key) => {\n    let k = '';\n    let v = '';\n    let val = yieldedObject[key];\n    if (val && typeof val === 'object') {\n      for (k in val) {\n        if (Object.prototype.hasOwnProperty.call(val, k)) {\n          v = revive(val, k);\n          if (v !== undefined)\n            val[k] = v;\n          else\n            delete val[k];\n        }\n      }\n    }\n    return reviver.call(yieldedObject, key, val);\n  };\n\n  let yielding = '';\n  // To hold 'parseYield' genarator function\n  function * yieldBridge() {\n    yielding = yield* parseYield();\n  }\n  let rs = yieldBridge();\n  let gen = rs.next();\n\n  // Main yield control logic.\n  let yieldCPU = () => {\n    setTimeout(() => {\n      gen = rs.next();\n\n      if (gen && gen.done === true) {\n        let isEmpty = (value) => {\n          if (value.charAt(0) === '}' || value.charAt(0) === ']')\n            value = value.substring(1, value.length);\n          return typeof value === 'string' && !value.trim();\n        };\n        if (typeof yielding === 'undefined')\n          return cb(new ParseError('Unexpected Character'), null);\n        else if (yielding instanceof ParseError)\n          return cb(yielding, null);\n        else if (!isEmpty(parseStr))\n          return cb(new ParseError('Unexpected Character'), null);\n        else {\n          if (reviver !== null) {\n            if (typeof reviver === 'function') {\n              let result = revive({'': yielding}, '');\n              return cb(null, result);\n            }\n          } else\n            return cb(null, yielding);\n        }\n      }\n      yieldCPU();\n    }), 0;\n  };\n  return yieldCPU();\n};\n\n/**\n * Checks whether the provided space\n * @param { string or number } space\n * @return { string or number }\n */\n let validateSpace = (space) => {\n  if (typeof space === 'number') {\n    space = Math.round(space);\n    if (space >= 1 && space <= 10)\n      return space;\n    else if (space < 1)\n      return 0;\n    else\n      return 10;\n  } else {\n    if (space.length <= 10)\n      return space;\n    else\n    return space.substr(0, 9);\n  }\n};\n\n/**\n * Checks whether the provided intensity\n * @param { number } intensity\n * @return { number }\n */\nlet validateIntensity = (intensity) => {\n  intensity = Math.round(intensity);\n  if (intensity > 0 && intensity <= 32)\n    return intensity;\n  else if (intensity <= 0)\n    return 1;\n  else\n    return 32;\n};\n\nyson.parseAsync = function (data, callback, reviver = null, intensity = 1) {\n\t//Bring parity with the in-built parser, that takes both string and buffer\n\tif (Buffer.isBuffer(data))\n\t\tdata = data.toString();\n\n\tif (!callback)\n\t\tthrow new Error('Missing Callback');\n\n\n  intensity = validateIntensity(intensity);\n\treturn parseWrapper(data, reviver, intensity, callback);\n};\n\n  /**\n  * Error checking  and call of appropriate functions for JSON stringify API\n  * @param { primitive data types } data\n  * @param { function or array } replacer\n  * @param { number or string } space\n  * @param { number } intensity\n  * @param { function } callback\n  * @return { function } stringifyWrapper\n  */\nyson.stringifyAsync = function(data, callback, replacer = null, space, intensity = 1) {\n  if (typeof callback !== 'function') {\n    throw new TypeError('Callback is not a function');\n  }\n  if (typeof space === 'number' || typeof space === 'string')\n    space = validateSpace(space);\n  if (typeof intensity === 'number')\n    intensity = validateIntensity(intensity);\n  return stringifyWrapper(data, replacer, space, intensity, callback);\n}\n\nif(typeof window != ''+u){ window.YSON = yson }\ntry{ if(typeof module != ''+u){ module.exports = yson } }catch(e){}\nif(typeof JSON != ''+u){\n\tJSON.parseAsync = yson.parseAsync;\n\tJSON.stringifyAsync = yson.stringifyAsync;\n}\n\n}());\n"
  },
  {
    "path": "lib/jsonp.js",
    "content": "var Gun = require('../gun');\r\nmodule.exports = function(req, cb){\r\n\tif(!req.url || !req.url.query || !req.url.query.jsonp){ return cb }\r\n\tcb.jsonp = req.url.query.jsonp;\r\n\tdelete req.url.query.jsonp;\r\n\tGun.obj.map(Gun.obj.ify(req.url.query['`']), function(val, i){\r\n\t\treq.headers[i] = val;\r\n\t});\r\n\tdelete req.url.query['`'];\r\n\tif(req.url.query.$){\r\n\t\treq.body = req.url.query.$;\r\n\t\tif(!Gun.obj.has(req.url.query, '^') || 'json' == req.url.query['^']){\r\n\t\t\treq.body = Gun.obj.ify(req.body); // TODO: BUG! THIS IS WRONG! This doesn't handle multipart chunking, and will fail!\r\n\t\t}\r\n\t}\r\n\tdelete req.url.query.$;\r\n\tdelete req.url.query['^'];\r\n\tdelete req.url.query['%'];\r\n\tvar reply = {headers:{}};\r\n\treturn function(res){\r\n\t\tif(!res){ return }\r\n\t\tif(res.headers){\r\n\t\t\tGun.obj.map(res.headers, function(val, field){\r\n\t\t\t\treply.headers[field] = val;\r\n\t\t\t});\r\n\t\t}\r\n\t\treply.headers['Content-Type'] = \"text/javascript\";\r\n\t\tif(Gun.obj.has(res,'chunk') && (!reply.body || Gun.list.is(reply.chunks))){\r\n\t\t\t(reply.chunks = reply.chunks || []).push(res.chunk);\r\n\t\t}\r\n\t\tif(Gun.obj.has(res,'body')){\r\n\t\t\treply.body = res.body; // self-reference yourself so on the client we can get the headers and body.\r\n\t\t\treply.body = ';'+ cb.jsonp + '(' + Gun.text.ify(reply) + ');'; // javascriptify it! can't believe the client trusts us.\r\n\t\t\tcb(reply);\r\n\t\t}\r\n\t}\r\n}\r\n"
  },
  {
    "path": "lib/later.d.ts",
    "content": "import {} from '../types/gun/IGunChain';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * > Warning: Dependency script for browser: <script src=\"/gun/lib/open.js\"></script>`\n     *\n     * Exact timing is not guaranteed! Because it uses `setTimeout` underneath. Further, after\n     *  the timeout, it must then open and load the snapshot, this will likely add at least 1ms\n     *  to the delay. Experimental: If this is problematic, please report it, as we can modify\n     *  the implementation of later to be more precise.)\n     *\n     * If a process/browser has to restart, the timeout will not be called. Experimental: If\n     *  this behavior is needed, please report it, as it could be added to the implementation\n     *\n     * Say you save some data, but want to do something with it later, like expire it or refresh\n     *  it. Well, then later is for you! You could use this to easily implement a TTL or similar\n     *  behavior\n     *\n     * @param seconds the number of seconds you want to wait before firing the callback\n     */\n    later(\n      /**\n       * @param data a safe snapshot of what you saved, including full depth documents or circular\n       *  graphs, without any of the metadata\n       * @param key name of the data\n       */\n      callback: (data: TNode, key: string) => void,\n      seconds: number\n    ): IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n  }\n}\n"
  },
  {
    "path": "lib/later.js",
    "content": "var Gun = Gun || require('../gun');\nGun.chain.open || require('./open');\n\nGun.chain.later = function(cb, age){\n\tvar gun = this;\n\tage = age * 1000; // convert to milliseconds.\n\tsetTimeout(function(){\n\t\tgun.open(cb, {off: true});\n\t}, age);\n\treturn gun;\n}"
  },
  {
    "path": "lib/les.js",
    "content": ";\n(function() {\n\n\t//  _     _____ ____    _     \n\t// | |   | ____/ ___|  (_)___ \n\t// | |   |  _| \\___ \\  | / __|\n\t// | |___| |___ ___) | | \\__ \\\n\t// |_____|_____|____(_)/ |___/\n\t// ----------------------------\n\t// LES.js (Last rEcently uSed)\n\t// ----------------------------\n\t// A Small, lightweight, queue-based\n\t// Garbage Collector for Gun\n\t// Originally By: Collin Conrad (@masterex1000)\n\n\t/**\n\t *\n\t * Usage: require the file in your application\n\t * \n\t * Gun Params: these are passed to the new gun constructor\n\t *\n\t *  - gc_enable : enables the gc, good if you are running multiple instances of gun, etc... def. true\n\t *\t- gc_delay\t: sets the amount of time between attempted garbage collections in milliseconds\n\t *\t- gc_info_enable : Enables or Disables the info printout\n\t *\t- gc_info\t: sets the ~ amount of time between info messages\n\t *\t\t\t\t  this is checked every time the gc is ran\n\t *\t- gc_info_mini : this will use a smaller, less user friendly info printout\n\t *\t- gc_importance_func : This will be the function used for finding the importance of a potential collect\n\t *\t\t\t\t\t\t\ttakes the form of func(timestamp, ctime, memoryUsageRatio) {return val}\n\t *\t\t\t\t\t\t\tCollects when returned value is 100\n\t */\n\t\n\t//NOTE: set to false to use require for getting gun DEFAULT: false\n\tvar USELOCALGUN = false; \n\t\t\n\t\n\t//NOTE: adds some debug messages DEFAULT: false\n\tvar DEBUG = false;\n\t\n\tif(!(typeof window !== \"undefined\") && USELOCALGUN)\n\t\tconsole.log(\"NOTE: You currently have LES.js set to use the 'local' file version of gun, This might crash if set wrong!\");\n\t\n\tvar Gun = (typeof window !== \"undefined\") ? window.Gun : (USELOCALGUN ? require('../gun') : require(\"gun\"));\n\t\n\t//Removes a node from the garbage collection until next write\n\tGun.chain.gcDequeue = function() {\n\t\t//console.log(this._.root.dequeueNode);\n\t\tif(this._.root.dequeueNode) { // check that we actually have the dequeue command on this node\n\t\t\tlet ctx = this;\n\t\t\n\t\t\tthis.get(function (soul) {\n\t\t\t\tctx._.root.dequeueNode(soul);\n\t\t\t}, true);\n\t\t}\n\t}\n\t\n\t//Puts node at the front for garbage collection, NOTE: only collects when it is hit it's time\n\tGun.chain.gcCollect = function() {\n\t\tif(this._.root.collectNode) { // check that we actually have the dequeue command on this node\n\t\t\tlet ctx = this;\n\t\t\t\n\t\t\tthis.get(function (soul) {\n\t\t\t\tctx._.root.collectNode(soul);\n\t\t\t}, true);\n\t\t}\n\t}\n\t\n\tGun.on('opt', function(root) {\n\t\t//Setup various options\n\t\t\n\t\tconst gc_enable = root.opt.gc_enable ? root.opt.gc_enable : true;\n\t\tconst gc_delay = root.opt.gc_delay ? root.opt.gc_delay : 1000;\n\t\t\n\t\tconst gc_info_enable  = (\"gc_info_enable\" in root.opt) ? root.opt.gc_info_enable  : true;\n\t\tconst gc_info  = root.opt.gc_info  ? root.opt.gc_info  : 5000;\n\t\tconst gc_info_mini = root.opt.gc_info_mini ? root.opt.gc_info_mini : false;\n\t\t\n\t\t//This is long, but it works well\n\t\tconst calcRemoveImportance = root.opt.gc_importance_func ? root.opt.gc_importance_func : function (timestamp, ctime, memoryUsageRatio) {\n\t\t\tvar time = (ctime - timestamp) * 0.001;\n\t\t\treturn time * 10 * (memoryUsageRatio * memoryUsageRatio);\n\t\t}\n\t\t\n\t\tif(DEBUG) console.log(root.opt);\n\t\t\n\t\tthis.to.next(root);\n\t\t\n\t\tif (root.once)\n\t\t\treturn;\n\t\tif (typeof process == 'undefined')\n\t\t\treturn\n\t\tvar mem = process.memoryUsage;\n\n\t\tif(!gc_enable) // exit because the gc is disabled\n\t\t\treturn;\n\t\t\n\t\tif (!mem) //exit because we are in the browser\n\t\t\treturn;\n\n\t\tvar ev = {}; //stores the environment\n\t\tvar empty = {}; //An empty list used to prevent crashes\n\t\t\n\t\t//Figure out the most amount of memory we can use. TODO: make configurable?\n\t\tev.max = parseFloat(root.opt.memory || process.env.WEB_MEMORY || 512) * 0.8;\n\n\t\tvar nodes = {}; //checks if the node already exists\n\t\tvar nodesArray = []; //used to easily sort everything and store info about the nodes\n\t\tvar memoryUpdate = 0; // last time we printed the current memory stats\n\n\t\troot.dequeueNode = (soul) => {  //forward the call to our gc\n\t\t\tdequeueNode(soul);\n\t\t}\n\t\t\n\t\troot.collectNode = (soul) => {  //forward the call to our gc\n\t\t\tcollectNode(soul);\n\t\t}\n\t\t\n\t\tvar check = function() {\n\t\t\tev.used = mem().rss / 1024 / 1024; //Contains the amt. of used ram in MB\n\t\t\tsetTimeout(function() { // So we can handle requests etc. before we start collecting\n\t\t\t\tGC(ev.used / ev.max); // Calculate the memory ratio, and execute the garbage collector\n\t\t\t\t//GC(0.99);\n\t\t\t}, 1);\n\t\t}\n\t\t\n\t\tsetInterval(check, gc_delay); // set the garbage collector to run every second\n\t\t\n\t\t//Executed every time a node gets modified\n\t\troot.on(\"put\", function(e) {\n\t\t\tthis.to.next(e);\n\t\t\tvar ctime = Date.now();\n\t\t\tvar souls = Object.keys(e.put || empty); // get all of the nodes in the update\n\t\t\tfor (var i = 0; i < souls.length; i++) { // iterate over them and add them\n\t\t\t\tenqueueNode(souls[i], ctime);\n\t\t\t}\n\t\t});\n\n\t\t//Adds a soul the garbage collectors \"freeing\" queue\n\t\tfunction enqueueNode(soul, ctime) {\n\t\t\tif (nodes[soul] == true) { //The node already exists in the queue\n\t\t\t\tvar index = nodesArray.findIndex(function(e) {\n\t\t\t\t\treturn e[0] === soul;\n\t\t\t\t});\n\t\t\t\tif (index == -1) {\n\t\t\t\t\tconsole.error(\"Something happened and the node '\" + soul + \"' won't get garbage collection unless the value is updated again\");\n\t\t\t\t\treturn;\n\t\t\t\t} else {\n\t\t\t\t\tnodesArray.splice(index, 1); // remove the existing ref. faster than dequeue\n\t\t\t\t\tnodesArray.push([soul, ctime]); // push the new instance\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnodesArray.push([soul, ctime]);\n\t\t\t\tnodes[soul] = true;\n\t\t\t}\n\t\t}\n\n\t\t//Removes a node from the queue\n\t\tfunction dequeueNode(soul) {\n\t\t\tif (nodes[soul] == true) { //The node already exists in the queue\n\t\t\t\tvar index = nodesArray.findIndex(function(e) {\n\t\t\t\t\treturn e[0] === soul;\n\t\t\t\t});\n\t\t\t\tif (index != -1) {\n\t\t\t\t\t//nodesArray.splice(index, 1); // remove the existing ref.\n\t\t\t\t\tnodesArray.shift();\n\t\t\t\t\tnodes[soul] = false; // store that we no longer have that node in the queue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t//Moves a node to the start of the queue\n\t\tfunction collectNode(soul) {\n\t\t\tif (nodes[soul] == true) { //The node already exists in the queue\n\t\t\t\tvar index = nodesArray.findIndex(function(e) {\n\t\t\t\t\treturn e[0] === soul;\n\t\t\t\t});\n\t\t\t\tif (index != -1) {\n\t\t\t\t\t//nodesArray.splice(index, 1); // remove the existing ref.\n\t\t\t\t\tnodesArray.shift(); // WAY faster than splice\n\t\t\t\t}\n\t\t\t\tnodesArray.unshift([soul, nodesArray[0][1]]); // create a new node with the next nodes time stamp\n\t\t\t\tnodes[soul] = true; // store that we no longer have that node in the queue\n\t\t\t}\n\t\t}\n\t\t\n\t\t//The main garbage collecting routine\n\t\tfunction GC(memRatio) {\n\t\t\tvar curTime = Date.now(); // get the current time\n\n\t\t\tif (gc_info_enable && curTime - memoryUpdate >= gc_info) { // check if we need to print info\n\t\t\t\tif(!gc_info_mini)\n\t\t\t\t\tconsole.log(\"|GC| %s | Current Memory Ratio: %d | Current Ram Usage %sMB | Nodes in Memory %s\", new Date().toLocaleString(), round(memRatio, 2), round(ev.used, 2), Object.keys(root.graph || empty).length);\n\t\t\t\telse\n\t\t\t\t\tconsole.log(\"|GC| %s, Mem Ratio %d, Ram %sMB, Nodes in mem %s, Tracked Nodes %s\", new Date().toLocaleString(), round(memRatio, 2), round(ev.used, 2), Object.keys(root.graph || empty).length, nodesArray.length);\n\t\t\t\tmemoryUpdate = curTime; // reset the last update time\n\t\t\t}\n\n\t\t\tvar freed = 0; // Just a nice performance counter\n\n\t\t\twhile (nodesArray.length > 0) { // iterate over all of our nodes\n\t\t\t\tvar soul = nodesArray[0][0];\n\t\t\t\tvar nts = nodesArray[0][1];\n\t\t\t\tif (DEBUG)\n\t\t\t\t\tconsole.log(\"Soul: \" + soul + \" | Remove Importance: \" + calcRemoveImportance(nts, curTime, memRatio) +\n\t\t\t\t\t\t\" | Memory Ratio: \" + memRatio + \" | Time Existed: \" + (curTime - nts) / 1000);\n\t\t\t\tif (calcRemoveImportance(nodesArray[0][1], curTime, memRatio) >= 100) {\n\t\t\t\t\troot.gun.get(nodesArray[0][0]).off(); //Remove the node\n\t\t\t\t\tdelete nodes[nodesArray[0][0]]; // remove the lookup value\n\t\t\t\t\t//nodesArray.splice(0, 1);\n\t\t\t\t\tnodesArray.shift();\n\t\t\t\t\tfreed++; // add one to our perf counter\n\t\t\t\t} else\n\t\t\t\t\tbreak; // Break out of the loop because we don't have any more nodes to free\n\t\t\t}\n\t\t\tif (freed > 0)\n\t\t\t\tconsole.log(\"|GC| Removed %s nodes in %s seconds-----------------------------------------------------------------\", freed, (Date.now() - curTime) * 0.001);\n\t\t}\n\t\t\n\t\tfunction round(value, decimals) { //a basic rounding function\n\t\t\treturn Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);\n\t\t}\n\t});\n}());\n"
  },
  {
    "path": "lib/level.js",
    "content": "// CAUTION: This adapter does NOT handle encoding. an encoding mechanism like the encoding-down package will need to be included\n// Based on localStorage adapter in 05349a5\n\nvar Gun   = ('undefined' !== typeof window) ? window.Gun : require('../gun');\nvar debug = false;\n\nGun.on('opt', function(ctx) {\n  var opt = ctx.opt;\n  var ev  = this.to;\n\n  if (debug) debug.emit('create');\n  if (ctx.once) return ev.next(ctx);\n\n  // Check if the given 'level' argument implements all the components we need\n  // Intentionally doesn't check for levelup explicitly, to allow different handlers implementing the same api\n  if (\n    (!opt.level) ||\n    ('object' !== typeof opt.level) ||\n    ('function' !== typeof opt.level.get) ||\n    ('function' !== typeof opt.level.put)\n  ) {\n    return;\n  }\n\n  ctx.on('put', function(msg) {\n   this.to.next(msg);\n\n    // Extract data from message\n    var put   = msg.put;\n    var soul  = put['#'];\n    var key   = put['.'];\n    var val   = put[':'];\n    var state = put['>'];\n\n    if (debug) debug.emit('put', soul, val);\n\n    // Fetch previous version\n    opt.level.get(soul, function(err, data) {\n      if (err && (err.name === 'NotFoundError')) err = undefined;\n      if (debug && err) debug.emit('error', err);\n      if (err) return;\n\n      // Unclear required transformation\n      data = Gun.state.ify(data, key, state, val, soul);\n\n      // Write into storage\n      opt.level.put(soul, data, function(err) {\n        if (err) return;\n        if (debug) debug.emit('put', soul, val);\n\n        // Bail if message was an ack\n        if (msg['@']) return;\n\n        // Send ack back\n        ctx.on('in', {\n          '@' : msg['@'],\n          ok  : 0,\n        });\n      });\n    });\n  });\n\n  ctx.on('get', function(msg) {\n    this.to.next(msg);\n\n    // Extract soul from message\n    var lex = msg.get;\n    if (!lex || !(soul = lex['#'])) return;\n    var has = lex['.'];\n\n    if (debug) debug.emit('get', soul);\n\n    // Fetch data from storage\n    opt.level.get(soul, function(err, data) {\n      if (err) return;\n\n      // Another unclear transformation\n      if (data && has) {\n        data = Gun.state.to(data, has);\n      }\n\n      // Emulate incoming ack\n      ctx.on('in', {\n        '@' : msg['#'],\n        put : Gun.graph.node(data),\n      });\n    });\n  });\n\n});\n\n// Export debug interface\nif ('undefined' === typeof window) {\n  var EventEmitter = require('events').EventEmitter;\n  module.exports = debug = new EventEmitter();\n}\n"
  },
  {
    "path": "lib/lex.js",
    "content": "(function (Gun, u) {\n    /**\n     * \n     *  credits: \n     *      github:bmatusiak\n     * \n     */    \n    var lex = (gun) => {\n        function Lex() {}\n\n        Lex.prototype = Object.create(Object.prototype, {\n            constructor: {\n                value: Lex\n            }\n        });\n        Lex.prototype.toString = function () {\n            return JSON.stringify(this);\n        }\n        Lex.prototype.more = function (m) {\n            this[\">\"] = m;\n            return this;\n        }\n        Lex.prototype.less = function (le) {\n            this[\"<\"] = le;\n            return this;\n        }\n        Lex.prototype.in = function () {\n            var l = new Lex();\n            this[\".\"] = l;\n            return l;\n        }\n        Lex.prototype.of = function () {\n            var l = new Lex();\n            this.hash(l)\n            return l;\n        }\n        Lex.prototype.hash = function (h) {\n            this[\"#\"] = h;\n            return this;\n        }\n        Lex.prototype.prefix = function (p) {\n            this[\"*\"] = p;\n            return this;\n        }\n        Lex.prototype.return = function (r) {\n            this[\"=\"] = r;\n            return this;\n        }\n        Lex.prototype.limit = function (l) {\n            this[\"%\"] = l;\n            return this;\n        }\n        Lex.prototype.reverse = function (rv) {\n            this[\"-\"] = rv || 1;\n            return this;\n        }\n        Lex.prototype.includes = function (i) {\n            this[\"+\"] = i;\n            return this;\n        }\n        Lex.prototype.map = function (...args) {\n            return gun.map(this, ...args);\n        }\n        Lex.prototype.match = lex.match;\n        \n        return new Lex();\n    };\n\n    lex.match = function(t,o){ var tmp, u;\n        o = o || this || {};            \n        if('string' == typeof o){ o = {'=': o} }\n        if('string' !== typeof t){ return false }\n        tmp = (o['='] || o['*'] || o['>'] || o['<']);\n        if(t === tmp){ return true }\n        if(u !== o['=']){ return false }\n        tmp = (o['*'] || o['>']);\n        if(t.slice(0, (tmp||'').length) === tmp){ return true }\n        if(u !== o['*']){ return false }\n        if(u !== o['>'] && u !== o['<']){\n            return (t >= o['>'] && t <= o['<'])? true : false;\n        }\n        if(u !== o['>'] && t >= o['>']){ return true }\n        if(u !== o['<'] && t <= o['<']){ return true }\n        return false;\n    }\n\n    Gun.Lex = lex;\n\n    Gun.chain.lex = function () {\n        return lex(this);\n    }\n\n})((typeof window !== \"undefined\") ? window.Gun : require('../gun'))"
  },
  {
    "path": "lib/list.js",
    "content": "var Gun = Gun || require('../gun');\n\nGun.chain.list = function(cb, opt){\n\topt = opt || {};\n\tcb = cb || function(){}; \n\tvar gun = this.put({}); // insert assumes a graph node. So either create it or merge with the existing one.\n\tgun.last = function(obj, cb){\n\t\tvar last = gun.path('last');\n\t\tif(!arguments.length){ return last }\n\t\treturn gun.path('last').put(null).put(obj).val(function(val){ // warning! these are not transactional! They could be.\n\t\t\tconsole.log(\"last is\", val);\n\t\t\tlast.path('next').put(this._.node, cb);\n\t\t});\n\t}\n\tgun.first = function(obj, cb){\n\t\tvar first = gun.path('first');\n\t\tif(!arguments.length){ return first }\n\t\treturn gun.path('first').put(null).put(obj).val(function(){ // warning! these are not transactional! They could be.\n\t\t\tfirst.path('prev').put(this._.node, cb);\n\t\t});\n\t}\n\treturn gun;\n};\n\n(function(){ // list tests\n\treturn;\n\tvar Gun = require('../index');\n\tvar gun = Gun({file: 'data.json'});\n\tGun.log.verbose = true;\n\t\n\tvar list = gun.list();\n\tlist.last({name: \"Mark Nadal\", type: \"human\", age: 23}).val(function(val){\n\t\t//console.log(\"oh yes?\", val, '\\n', this.__.graph);\n\t});\n\tlist.last({name: \"Timber Nadal\", type: \"cat\", age: 3}).val(function(val){\n\t\t//console.log(\"oh yes?\", val, '\\n', this.__.graph);\n\t});\n\tlist.list().last({name: \"Hobbes\", type: \"kitten\", age: 4}).val(function(val){\n\t\t//console.log(\"oh yes?\", val, '\\n', this.__.graph);\n\t});\n\tlist.list().last({name: \"Skid\", type: \"kitten\", age: 2}).val(function(val){\n\t\t//console.log(\"oh yes?\", val, '\\n', this.__.graph);\n\t});\n\tsetTimeout(function(){ list.val(function(val){\n\t\tconsole.log(\"the list!\", list.__.graph);\n\t\treturn;\n\t\tlist.path('first').val(Gun.log)\n\t\t\t.path('next').val(Gun.log)\n\t\t\t.path('next').val(Gun.log);\n\t})}, 1000);\n\n\treturn;\n\tgun.list().map(function(val, id){\n\t\tconsole.log(\"each!\", id, val);\n\t})\n\n}());"
  },
  {
    "path": "lib/load.d.ts",
    "content": "import {} from '../types/gun/IGunChain';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * > Warning: Dependency script for browser: <script src=\"/gun/lib/open.js\"></script>`\n     *\n     * Loads the full object once. It is the same as open but with the behavior of once\n     */\n    load(\n      callback: (data: TNode) => void\n    ): IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n  }\n}\n"
  },
  {
    "path": "lib/load.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\nGun.chain.open || require('./open');\n\nGun.chain.load = function(cb, opt, at){\n\t(opt = opt || {}).off = !0;\n\treturn this.open(cb, opt, at);\n}"
  },
  {
    "path": "lib/match.js",
    "content": "var Type = require('../src/type');\nfunction match(t, o){ var r = false;\n\tt = t || '';\n\to = Type.text.is(o)? {'=': o} : o || {}; // {'~', '=', '*', '<', '>', '+', '-', '?', '!'} // ignore case, exactly equal, anything after, lexically larger, lexically lesser, added in, subtacted from, questionable fuzzy match, and ends with.\n\tif(Type.obj.has(o,'~')){ t = t.toLowerCase(); o['='] = (o['='] || o['~']).toLowerCase() }\n\tif(Type.obj.has(o,'=')){ return t === o['='] }\n\tif(Type.obj.has(o,'*')){ if(t.slice(0, o['*'].length) === o['*']){ r = true; t = t.slice(o['*'].length) } else { return false }}\n\tif(Type.obj.has(o,'!')){ if(t.slice(-o['!'].length) === o['!']){ r = true } else { return false }}\n\tif(Type.obj.has(o,'+')){\n\t\tif(Type.list.map(Type.list.is(o['+'])? o['+'] : [o['+']], function(m){\n\t\t\tif(t.indexOf(m) >= 0){ r = true } else { return true }\n\t\t})){ return false }\n\t}\n\tif(Type.obj.has(o,'-')){\n\t\tif(Type.list.map(Type.list.is(o['-'])? o['-'] : [o['-']], function(m){\n\t\t\tif(t.indexOf(m) < 0){ r = true } else { return true }\n\t\t})){ return false }\n\t}\n\tif(Type.obj.has(o,'>')){ if(t > o['>']){ r = true } else { return false }}\n\tif(Type.obj.has(o,'<')){ if(t < o['<']){ r = true } else { return false }}\n\tfunction fuzzy(t,f){ var n = -1, i = 0, c; for(;c = f[i++];){ if(!~(n = t.indexOf(c, n+1))){ return false }} return true } // via http://stackoverflow.com/questions/9206013/javascript-fuzzy-search\n\tif(Type.obj.has(o,'?')){ if(fuzzy(t, o['?'])){ r = true } else { return false }} // change name!\n\treturn r;\n}\nmodule.exports = match;"
  },
  {
    "path": "lib/memdisk.js",
    "content": "// Take caution running this in production, it ONLY saves to disk what is in memory.\n\nvar Gun = require('../gun'),\nfs = require('fs');\n\nGun.on('opt', function(ctx){\n\tthis.to.next(ctx);\n\tvar opt = ctx.opt;\n\tif(ctx.once){ return }\n\topt.file = String(opt.file || 'data.json');\n\tvar graph = ctx.graph, acks = {}, count = 0, to;\n\tvar disk = Gun.obj.ify((fs.existsSync || require('path').existsSync)(opt.file)? \n\t\tfs.readFileSync(opt.file).toString()\n\t: null) || {};\n\t\n\tctx.on('put', function(at){\n\t\tthis.to.next(at);\n\t\tGun.graph.is(at.put, null, map);\n\t\tif(!at['@']){ acks[at['#']] = true; } // only ack non-acks.\n\t\tcount += 1;\n\t\tif(count >= (opt.batch || 10000)){\n\t\t\treturn flush();\n\t\t}\n\t\tif(to){ return }\n\t\tto = setTimeout(flush, opt.wait || 1);\n\t});\n\n\tctx.on('get', function(at){\n\t\tthis.to.next(at);\n\t\tvar lex = at.get, soul, data, opt, u;\n\t\t//setTimeout(function(){\n\t\tif(!lex || !(soul = lex['#'])){ return }\n\t\t//if(0 >= at.cap){ return }\n\t\tvar field = lex['.'];\n\t\tdata = disk[soul] || u;\n\t\tif(data && field){\n\t\t\tdata = Gun.state.to(data, field);\n\t\t}\n\t\tctx.on('in', {'@': at['#'], put: Gun.graph.node(data)});\n\t\t//},11);\n\t});\n\n\tvar map = function(val, key, node, soul){\n\t\tdisk[soul] = Gun.state.to(node, key, disk[soul]);\n\t}\n\n\tvar wait;\n\tvar flush = function(){\n\t\tif(wait){ return }\n\t\twait = true;\n\t\tclearTimeout(to);\n\t\tto = false;\n\t\tvar ack = acks;\n\t\tacks = {};\n\t\tfs.writeFile(opt.file, JSON.stringify(disk, null, 2), function(err, ok){\n\t\t\twait = false;\n\t\t\tvar tmp = count;\n\t\t\tcount = 0;\n\t\t\tGun.obj.map(ack, function(yes, id){\n\t\t\t\tctx.on('in', {\n\t\t\t\t\t'@': id,\n\t\t\t\t\terr: err,\n\t\t\t\t\tok: 0 // memdisk should not be relied upon as permanent storage.\n\t\t\t\t});\n\t\t\t});\n\t\t\tif(1 < tmp){ flush() }\n\t\t});\n\t}\n});"
  },
  {
    "path": "lib/meta.js",
    "content": ";(function(){\n  function USE(arg, req){\n    return req? require(arg) : arg.slice? USE[R(arg)] : function(mod, path){\n      arg(mod = {exports: {}});\n      USE[R(path)] = mod.exports;\n    }\n    function R(p){\n      return p.split('/').slice(-1).toString().replace('.js','');\n    }\n  }\n  if(typeof module !== \"undefined\"){ var MODULE = module }\n\n\t/* UNBUILD */\n\t;USE(function(module){\n\t\tvar noop = function(){}, u;\n\t\t$.fn.or = function(s){ return this.length ? this : $(s||'body') };\n\t\tvar m = window.meta = {edit:[]};\n\t\tvar k = m.key = {};\n\t\tk.meta = {17:17, 91:17, 93:17, 224:17, 18: 17}; // ALT added\n\t\tfunction withMeta(eve){ return eve.metaKey || eve.ctrlKey || eve.altKey } // ALT added\n\t\tk.down = function(eve){\n\t\t\tvar key = (k.eve = m.eve = eve).which = eve.which || eve.fake || eve.keyCode;\n\t\t  if(eve.repeat){ return }\n\t\t\tif(!k.meta[key] && withMeta(eve) && !k.at[key]) {\n\t\t\t  return m.flip(false)\n\t\t  } // cancel and close when no action and \"meta key\" held down (e.g. ctrl+c)\n\t\t\tif(!eve.fake && key === k.last){ return }; k.last = key; // jussi: polyfilling eve.repeat?\n\t\t\tif(!eve.fake && $(eve.target).closest('input, textarea, [contenteditable=true]').length/* && !$(eve.target).closest('#meta').get().length*/){\n\t\t\t\treturn;\n\t\t    //if(meta.flip.is() && !withMeta(eve)) eve.preventDefault()\n\t\t\t}\n\t\t\tm.check('on', key, k.at || (k.at = m.edit));\n\t\t\tif(k.meta[key]){ m.flip() }\n\t\t}\n\t\tk.down.keys = {} // currently pressed keys\n\t\tk.up = function(eve){ var tmp;\n\t\t\tvar key = (k.eve = m.eve = eve).which = eve.which || eve.fake || eve.keyCode;\n\t\t\tk.last = null;\n\t\t\tm.check('up', key);\n\t\t\tif(k.meta[key] && m.check.fired){\n\t\t\t\tm.close()\n\t\t\t}\n\t\t}\n\t\tm.flip = function(tmp){\n\t\t  m.flip.active = true;\n\t\t\t((tmp === false) || (!tmp && m.ui.board.is(':visible')))?\n\t\t\t\tm.close() : m.open();\n\t\t  m.flip.active = false;\n\t\t}\n\t\tm.open = function(){\n\t\t  m.check.fired = null;\n\t\t  m.ui.board.removeClass('meta-none');\n\t\t}\n\t\tm.close = function(){\n\t\t\tObject.keys(k.down.keys).forEach((keyDown) => {\n\t\t\t  m.check('up', keyDown);\n\t\t\t})\n\t\t\tm.ui.board.addClass('meta-none')\n\t\t}\n\t\tm.flip.is = function(){\n\t\t\treturn m.ui.board.is(':visible');\n\t\t}\n\t\tm.flip.wait = 500;\n\t\tm.check = function(how, key, at){\n\t\t  if(!m.flip.is() && !k.meta[key]){ return } // TEMP: cancel non-open events when closed TODO make optional\n\t\t  at = k.at || m.edit;\n\t\t\tvar next = at[key];\n\t\t\tif(!next){ return }\n\t\t\tvar tmp = k.eve || noop;\n\t\t\tif(tmp.preventDefault){ tmp.preventDefault()} // prevent typing (etc) when action found\n\t\t\tif(next[how]){\n\t\t\t\t\tnext[how](m.eve);\n\t\t\t\t\tmeta.ui.blink();\n\t\t\t\t\tm.check.fired = true;\n\t\t\t\t\tif(how == 'up') delete k.down.keys[key]\n\t\t\t\t\telse            k.down.keys[key] = 1;\n\t\t\t}\n\t\t\tif('up' == how){ return }\n\t\t\tif(at != next && !next.back){ next.back = at }\n\t\t\t(k.combo || (k.combo = [])).push(key);\n\t\t\tm.list(next, true);\n\t\t}\n\t\tfunction defaultSort(a,b){\n\t\t\ta = a.combo.slice(-1)[0] || 0;\n\t\t\tif(a.length){ a = a.toUpperCase().charCodeAt(0) }\n\t\t\tb = b.combo.slice(-1)[0] || 0;\n\t\t\tif(b.length){ b = b.toUpperCase().charCodeAt(0) }\n\t\t\treturn (a < b)? -1 : 1;\n\t\t}\n\t\tm.list = function(at, opt){\n\t\t\tif(!at){ return m.flip(false) }\n\t\t\tvar l = [];\n\t\t\t$.each(at, function(i,k){ 'back' != i && k && k.combo && k.name && l.push(k) });\n\t\t\tif(!l.length){ return }\n\t\t\tk.at = at;\n\t\t\tif(at.sort !== null){ l = l.sort(at.sort || defaultSort) }\n\t\t\tvar $ul = $('#meta .meta-menu ul')\n\t\t\t$ul.children('li').addClass('meta-none').hide(); setTimeout(function(){ $ul.children('.meta-none').remove() },250); // necessary fix for weird bug glitch\n\t\t\t$.each(l, function(i, k){\n\t\t\t  var $li = $('<li>').text(k.name).data(k)\n\t\t\t\t$ul.append($li);\n\t\t\t\tif(k.styles) meta.ui.iniline($li[0], k.styles);\n\t\t\t});\n\t\t\tif(opt){ m.flip(true) }\n\t\t\t$ul.append($('<li>').html('&larr;').on('click', back));\n\t\t}\n\t\tm.ask = function(help, cb, opt){\n\t\t\tvar $ul = $('#meta .meta-menu ul').empty();\n\t\t\tvar $put = $('<input>').attr('id', 'meta-ask').attr('placeholder', help);\n\t\t\tvar $form = $('<form>').append($put).on('submit', function(eve){\n\t\t\t\teve.preventDefault();\n\t\t\t\tcb($put.val());\n\t\t\t\t$li.remove();\n\t\t\t\tk.wipe();\n\t\t\t});\n\t\t\tif(opt){\n\t\t\t\t$form.on('keyup', function(eve){ cb($put.val()) })\n\t\t\t}\n\t\t\tvar $li = $('<li>').append($form);\n\t\t\t$ul.append($li);\n\t\t\tm.flip(true);\n\t\t\t$put.focus();\n\t\t}\n\t\tk.wipe = function(opt){\n\t\t\tk.combo = [];\n\t\t\tif(!opt){ m.flip(false) }\n\t\t\tm.list(k.at = m.edit);\n\t\t};\n\t\tm.tap = function(){\n\t\t\tvar on = $('.meta-on')\n\t\t\t\t.or($($(document.querySelectorAll(':hover')).get().reverse()).first())\n\t\t\t\t.or($(document.elementFromPoint(meta.tap.x, meta.tap.y)));\n\t\t\treturn on;\n\t\t}\n\t\tmeta.edit = function(e){\n\t\t\tvar path = [];\n\t\t\t$.each(e.combo || (e.combo = []), function(i,k){\n\t\t\t\tif(!k || !k.length){ if('number' == typeof k){ path.push(k) } return }\n\t\t\t\tpath.push(k.toUpperCase().charCodeAt(0));\n\t\t\t});\n\t\t\tvar at = meta.edit, l = e.combo.length;\n\t\t\t$.each(path, function(i,k){ at = at[k] = at[k] || Object.create(defaults) });\n\t\t  $.extend(at, e) // fixes overwriting when sub action is defined before parent\n\t\t\te.combow = path.join(','); // deprecate?\n\t\t\tm.list(k.at || meta.edit);\n\t\t}\n\t\tfunction back(){ // close root or go back on submenu\n\t\t  k.at == m.edit ? m.flip(false) : m.check('down', 'back')\n\t\t}\n\t\tvar defaults = {\n\t\t\t8:  { on: back },  // backspace\n\t\t\t27: { up: k.wipe } // esc: close and reset menu\n\t\t}\n\t\t$.extend(meta.edit, defaults)\n\t})(USE, './metaCore');\n\t;USE(function(module){\n\t\t/* UI */\n\t\tmeta.ui = {\n\t\t\tblink: function(){ // hint visually that action has happened\n\t\t\t\t$('#meta').css('transition', 'none').css('background', 'none')\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t$('#meta')[0].style.transition = null\n\t\t\t\t\t$('#meta')[0].style.background = null\n\t\t\t\t})\n\t\t\t},\n\t\t\tdepth: function(n){\n\t\t\t  if (n) {\n\t\t\t\t\t$('#meta').css('background', 'hsl(60, 100%,'+(85-(n*10))+'%)');\n\t\t\t\t} else {\n\t\t\t\t\t$('#meta')[0].style.background = null\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvar $m = $('<div>').attr('id', 'meta');\n\t\t//$m.append($('<span>').html('&#9776;').addClass('meta-start'));\n\t\t$m.append($('<span>').html('+').addClass('meta-start'));\n\t\t$m.append($('<div>').addClass('meta-menu meta-none').append('<ul>'));\n\t\t$m.on('mouseenter', function(){\n\t\t  if (meta.flip.active || meta.flip.is()) return;\n\t\t  meta.flip();\n\t\t})\n\t\t$m.on('mouseleave', function(){\n\t\t  if (meta.flip.active || !meta.flip.is()) return;\n\t\t  meta.flip(false);\n\t\t})\n\t\t$(document.body).append($m);\n\t\tmeta.ui.board = $('.meta-menu', $m);\n\t\tcss({\n\t\t\t'#meta': {\n\t\t\t\tdisplay: 'block',\n\t\t\t\tposition: 'fixed',\n\t\t\t\tbottom: '2em',\n\t\t\t\tright: '2em',\n\t\t\t\t'font-size': '18pt',\n\t\t\t\t'font-family': 'Tahoma, arial',\n\t\t\t\t'border-radius': '1em',\n\t\t\t\t'text-align': 'center',\n\t\t\t\t'z-index': 999999,\n\t\t\t\tmargin: 0,\n\t\t\t\tpadding: 0,\n\t\t\t\twidth: '2em',\n\t\t\t\theight: '2em',\n\t\t\t\toutline: 'none',\n\t\t\t\toverflow: 'visible',\n\t\t\t\tbackground: 'rgba(0,0,0,0.5)', color: 'white',\n\t\t\t\ttransition: 'all 0.2s ease-in'\n\t\t\t},\n\t\t\t'#meta *': {outline: 'none'},\n\t\t\t'#meta .meta-none': {display: 'none'},\n\t\t\t'#meta span': {'line-height': '2em'},\n\t\t\t'#meta .meta-menu': {\n\t\t\t\tbackground: 'rgba(0,0,0,0.2)',\n\t\t\t\twidth: '12em',\n\t\t\t\tright: '-2em',\n\t\t\t\tbottom: '-2em',\n\t\t\t\toverflow: 'visible',\n\t\t\t\tposition: 'absolute',\n\t\t\t\t'overflow-y': 'scroll',\n\t\t\t\t'text-align': 'right',\n\t\t\t\t'min-height': '20em',\n\t\t\t\theight: '100vh'\n\t\t\t},\n\t\t\t'#meta .meta-menu ul': {\n\t\t\t\tpadding: 0,\n\t\t\t\tmargin: '1em 1em 2em 0',\n\t\t\t\t'list-style-type': 'none'\n\t\t\t},\n\t\t\t'#meta .meta-menu ul li': {\n\t\t\t\tdisplay: 'block',\n\t\t\t\t'float': 'right',\n\t\t\t\tpadding: '0.5em 1em',\n\t\t\t\t'border-radius': '1em',\n\t\t\t\t'margin-left': '0.25em',\n\t\t\t\t'margin-top': '0.25em',\n\t\t\t\tbackground: 'rgba(0,0,0,0.2)', 'backdrop-filter': 'blur(10px)', color: 'white',\n\t\t\t\t'cursor':  'pointer'\n\t\t\t},\n\t\t\t'#meta .meta-menu ul li:hover': {\n\t\t\t\tbackground: 'rgba(0,0,0,0.5)'\n\t\t\t},\n\t\t\t'#meta a': {color: 'black'},\n\t\t\t'#meta:hover': {opacity: 1},\n\t\t\t'#meta:hover .meta-menu': {display: 'block'},\n\t\t\t'#meta .meta-menu ul:before': {\n\t\t\t\tcontent: \"' '\",\n\t\t\t\tdisplay: 'block',\n\t\t\t\t'min-height': '15em',\n\t\t\t\theight: '50vh'\n\t\t\t},\n\t\t\t'#meta .meta-start': {\n\t\t\t\tcursor: 'pointer'\n\t\t\t}\n\t\t});\n\t\tfunction css(css){\n\t\t\tvar tmp = '';\n\t\t\t$.each(css, function(c,r){\n\t\t\t\ttmp += c + ' {\\n';\n\t\t\t\t$.each(r, function(k,v){\n\t\t\t\t\ttmp += '\\t'+ k +': '+ v +';\\n';\n\t\t\t\t});\n\t\t\t\ttmp += '}\\n';\n\t\t\t});\n\t\t\tvar tag = document.createElement('style');\n\t\t\ttag.innerHTML = tmp;\n\t\t\t$m.append(tag)\n\t\t}\n\t\tmeta.ui.iniline = function(el, cssObj){\n\t\t\tfor(var k in cssObj) { el.style[k] = cssObj[k]; }\n\t\t}\n\t})(USE, './metaUI');\n\t;USE(function(module){\n\t\tvar m = meta, k = m.key;\n\t\t//$(window).on('focus', k.wipe.bind(null, false)); // .on('blur', k.wipe.bind(null, false))\n\t\t$(document).on('mousedown mousemove mouseup', function(eve){\n\t\t\tm.tap.eve = eve;\n\t\t\tm.tap.x = eve.pageX||0;\n\t\t\tm.tap.y = eve.pageY||0;\n\t\t\tm.tap.on = $(eve.target);\n\t\t})\n\t\tvar [start, end] = 'ontouchstart' in window\n\t\t\t\t\t\t\t\t\t\t\t\t? ['touchstart', 'touchend']\n\t\t\t\t\t\t\t\t\t\t\t\t: ['mousedown', 'mouseup']\n\t\t$(document).on(start, '#meta .meta-menu li', function(eve){\n\t\t\tvar combo = $(this).data().combo;\n\t\t\teve.fake = eve.which = combo && combo.slice(-1)[0].toUpperCase().charCodeAt(0);\n\t\t\teve.tap = true;\n\t\t\tk.down(eve);\n\t\t\t$(document).one(end, () => k.up(eve))\n\t\treturn;\n\t\t});\n\t\t$(document).on('keydown', k.down).on('keyup', k.up);\n\t\t$('#meta').on(start, function(ev) {\n\t\t  if (ev.target.tagName == 'LI' || ev.target.tagName == 'UL') return\n\t\t\tmeta.flip()\n\t\t})\n\t})(USE, './metaEvents');\n}());\n"
  },
  {
    "path": "lib/mix.js",
    "content": ";(function(){\n\tvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\tGun.state.node = function(node, vertex, opt){\n\t\topt = opt || {};\n\t\topt.state = opt.state || Gun.state();\n\t\tvar now = Gun.obj.copy(vertex);\n\t\tGun.node.is(node, function(val, key){\n\t\t\tvar ham = Gun.HAM(opt.state, Gun.state.is(node, key), Gun.state.is(vertex, key), val, vertex[key]);\n\t\t\tif(!ham.incoming){\n\t\t\t\t// if(ham.defer){}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnow = Gun.state.to(node, key, now);\n\t\t});\n\t\treturn now;\n\t}\n}());"
  },
  {
    "path": "lib/mobile.js",
    "content": "import Buffer from \"buffer\";\nimport { TextEncoder, TextDecoder } from \"text-encoding\";\nglobal.Buffer = global.Buffer || Buffer.Buffer;\nglobal.TextEncoder = TextEncoder;\nglobal.TextDecoder = TextDecoder;"
  },
  {
    "path": "lib/monotype.js",
    "content": ";var monotype = monotype || (function(monotype){\n\tmonotype.range = function(n){\n\t\tvar R, s, t, n = n || 0, win = monotype.win || window, doc = win.document;\n\t\tif(!arguments.length) return doc.createRange();\n\t\tif(!(win.Range && R instanceof Range)){\n\t\t\ts = win.getSelection? win.getSelection() : {};\n\t\t\tif(s.rangeCount){ \n\t\t\t\tR = s.getRangeAt(n);\n\t\t\t} else {\n\t\t\t\tif(doc.createRange){\n\t\t\t\t\tR = doc.createRange();\n\t\t\t\t\tR.setStart(doc.body, 0);\n\t\t\t\t} else \n\t\t\t\tif (doc.selection){ // <IE9\n\t\t\t\t\tR = doc.selection.createRange();\n\t\t\t\t\tR = R.getBookmark();\n\t\t\t\t}\n\t\t\t}\n\t\t\ts.end = (s.extentNode || s.focusNode || R.startContainer);\n\t\t\tif(s.anchorNode === s.end){\n\t\t\t\tR.direction = s.anchorOffset <= (s.extentOffset || s.focusOffset || 0)? 1 : -1;\n\t\t\t} else\n\t\t\tif($.contains(s.anchorNode||{}, s.end||{})){\n\t\t\t\ts.end = $(s.anchorNode).contents().filter(s.end).length? s.end : $(s.end).parentsUntil(s.anchorNode).last()[0];\n\t\t\t\tR.direction = s.anchorOffset < $(s.anchorNode).contents().index(s.end)? 1 : -1; // Compare immediate descendants to see which comes first.\n\t\t\t} else {\n\t\t\t\tR.direction = s.anchorNode === R.endContainer? -1 : 1; // Checking against startContainer fails going backward.\n\t\t\t}\n\t\t}\n\t\treturn R;\n\t}\n\tmonotype.restore = function(R){\n\t\tvar win = monotype.win, doc = win.document;\n\t\tif(R.R && R.restore){ \n\t\t\tR.restore();\n\t\t\treturn;\n\t\t}\n\t\tif(win.getSelection){\n\t\t\tvar s = win.getSelection();\n\t\t\ts.removeAllRanges();\n\t\t\tif(s.extend && R.direction < 0){\n\t\t\t\tR.esC = R.startContainer;\n\t\t\t\tR.esO = R.startOffset;\n\t\t\t\tR.setStart(R.endContainer, R.endOffset);\n\t\t\t}\n\t\t\ts.addRange(R);\n\t\t\tR.esC && s.extend(R.esC, R.esO);\n\t\t} else {\n\t\t\tif(doc.body.createTextRange) { // <IE9\n\t\t\t\tvar ier = doc.body.createTextRange();\n\t\t\t\tier.moveToBookmark(R);\n\t\t\t\tier.select();\n\t\t\t}\n\t\t}\n\t}\n\tmonotype.text = function(n){\n\t\treturn !n? false : (n.nodeType == 3 || n.nodeType == Node.TEXT_NODE);\n\t}\n\tmonotype.prev = function(n,c,d){\n\t\treturn !n? null : n === c? null\n\t\t: n[(d?'next':'previous')+'Sibling']?\n\t\t\tmonotype.deep(n[(d?'next':'previous')+'Sibling'],d?-1:Infinity).container\n\t\t: monotype.prev($(n).parent()[0],c,d);\n\t}; monotype.next = function(n,c){ return monotype.prev(n,c,1) }\n\tmonotype.deep = function(n, o, c, i){\n\t\treturn i = (o === Infinity? $(n).contents().length-1 : o),\n\t\ti = (i === -1? 0 : i),\n\t\t(c = $(n).contents()).length?\n\t\t\tmonotype.deep(c = c[i < c.length? i : c.length - 1], monotype.text(c)? 0 : o)\n\t\t: {\n\t\t\tcontainer: n\n\t\t\t,offset: $(n).text() && o !== -1? (o === Infinity? $(n).text().length : o) : 0\n\t\t};\n\t}\n\tmonotype.count = function(n, o, c){\n\t\tvar g = monotype.deep(n, o)\n\t\t, m = g.container\n\t\t, i = g.offset || 0;\n\t\twhile(m = monotype.prev(m,c)){\n\t\t\ti += $(m).text().length;\n\t\t}\n\t\treturn i;\n\t}\n\tmonotype.hint = function(n, o, c){\n\t\tvar g = monotype.deep(n, o)\n\t\t, m = g.container\n\t\t, i = g.offset || 0\n\t\t, h = [], t;\n\t\twhile(m){\n\t\t\th.push({\n\t\t\t\tt: t = $(m).text()\n\t\t\t\t,n: t? 'TEXT' : m.nodeName\n\t\t\t});\n\t\t\tm = t? null : monotype.prev(m,c);\n\t\t}\n\t\tif(h.length == 1 && h[0].t){\n\t\t\treturn [];\n\t\t}\n\t\tif((t = $(n).contents()).length && o == t.length){\n\t\t\th.push(1); // Indicate that the selection is after the last element.\n\t\t}\n\t\treturn h;\n\t}\n\tmonotype.reach = function(i, c, o){\n\t\to = o || {};\n\t\to.i = o.i || o.offset || 0;\n\t\to.$ = o.$? o.$.jquery? o.$ : $(o.$) \n\t\t: o.container? $(o.container) : $(c);\n\t\tvar n = monotype.deep(o.$[0], -1).container, t;\n\t\twhile(n){\n\t\t\tt = $(n).text().length;\n\t\t\tif(i <= o.i + t){\n\t\t\t\to.$ = $(n);\n\t\t\t\to.i = i - o.i;\n\t\t\t\tn = null;\n\t\t\t} else {\n\t\t\t\to.i += t;\n\t\t\t}\n\t\t\tn = monotype.next(n,c);\n\t\t}\n\t\treturn o;\n\t}\n\treturn monotype;\n})(function(e,opt){\n\tvar r = {}, t, m = monotype;\n\topt = opt || {};\n\tm.win = opt.win || window;\n\tr = (e||r).jquery || m.text(e)? {root: $(e||m.win.document.body)} : r;\n\tr.root = $(r.root || m.win.document.body);\n\t//console.log('_______________________');\n\tr.R = m.range(0);\n\tr.H = {};\n\tr.H.R = $.extend({}, r.R);\n\tr.d = r.R.direction || 1;\n\tr.t = r.R.toString();\n\tr.H.s = m.hint(r.R.startContainer, r.R.startOffset, r.root[0]);\n\tr.s = m.count(r.R.startContainer, r.R.startOffset, r.root[0]);\n\tt = m.deep(r.R.startContainer, r.R.startOffset);\n\t(!t.offset && !r.H.s.length) && (r.s += 0.1); // At the beginning of a text, not at the end of a text.\n\tr.H.e = m.hint(r.R.endContainer, r.R.endOffset, r.root[0]);\n\tr.e = (function(n, o, c, t){\n\t\tif(r.R.collapsed\n\t\t|| (o === r.R.startOffset \n\t\t&& n === r.R.startContainer)){\n\t\t\treturn r.s;\n\t\t} c = m.count(n, o, r.root[0]);\n\t\tt = m.deep(n, o);\n\t\t(!t.offset && !r.H.e.length) && (c += 0.1); // Same as above.\n\t\treturn c;\n\t})(r.R.endContainer, r.R.endOffset);\n\t//console.log(r.s, r.R.startOffset, r.H.s, 'M',r.d,'E', r.H.e, r.R.endOffset, r.e);\n\tt = r.root.text();\n\tr.L = t.length;\n\tr.T = {\n\t\ts: t.slice(r.s - 9, r.s)\n\t\t,e: t.slice(r.e, r.e + 9)\n\t\t,t: function(){ return r.T.s + r.T.e }\n\t}\n\tr.range = function(){\n\t\t//console.log('----');\n\t\tr.H = r.H || {};\n\t\tvar s = m.reach(r.s, r.root[0])\n\t\t, st = s.$.text()\n\t\t, e = m.reach(r.e, r.root[0])\n\t\t, et = e.$.text()\n\t\t, R = m.range()\n\t\t, p = function(g, c){ // TODO: BUG! Backtracking in non-Chrome and non-IE9+ browsers. IE9 doesn't like end selections.\n\t\t\tif(!c || !c.length){\n\t\t\t\treturn g;\n\t\t\t}\n\t\t\tvar n = g.$[0], f = [], i = 0, t;\n\t\t\twhile((n = m.next(n,r.root[0])) && ++i < c.length){\n\t\t\t\tt = $(n).text();\n\t\t\t\tif(t){\n\t\t\t\t\tn = null;\n\t\t\t\t} else {\n\t\t\t\t\tf.push(n);\n\t\t\t\t}\n\t\t\t}\n\t\t\tn = $(f[f.length-1] || g.$);\n\t\t\tt = n.parent();\n\t\t\tif(c[c.length-1] === 1 || (i && f.length === i \n\t\t\t&& (f.length < c.length-1))){ // tests pass with this condition, yet failed without\n\t\t\t\treturn {\n\t\t\t\t\ti: t.contents().length\n\t\t\t\t\t,$: t\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(f.length < c.length - 1){ // despite above's addition, this still gets activated.\n\t\t\t\tf = t.contents().slice(n = t.contents().index(n));\n\t\t\t\ti = f.map(function(j){ return $(this).text()? (n+j+1) : null})[0] || t.contents().length;\n\t\t\t\tf = f.slice(0, i - n);\n\t\t\t\tn = f.last()[0];\n\t\t\t\tif(g.$[0] === n){\n\t\t\t\t\treturn g;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\t$: t\n\t\t\t\t\t,i: t.contents().index(n)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn {\n\t\t\t\ti: 0\n\t\t\t\t,$: n\n\t\t\t};\n\t\t}\n\t\ts = p(s, r.H.s);\n\t\te = p(e, r.H.e);\n\t\t//console.log(\"START\", parseInt(s.i), 'in \"\"\"',(s.$[0]),'\"\"\" with hint of', r.H.s, 'from original', r.s);\n\t\t//console.log(\"END\", parseInt(e.i), 'in \"\"\"',(e.$[0]),'\"\"\" hint clue of', r.H.e, 'from original', r.e);\n\t\tR.setStart(s.$[0], parseInt(s.i));\n\t\tR.setEnd(e.$[0], parseInt(e.i));\n\t\treturn R;\n\t}\n\tr.restore = function(R){\n\t\tif(r.R.startOffset !== r.H.R.startOffset\n\t\t|| r.R.endOffset !== r.H.R.endOffset\n\t\t|| r.R.startContainer !== r.H.R.startContainer\n\t\t|| r.R.endContainer !== r.H.R.endContainer){\n\t\t\tr.R = R = r.range();\n\t\t} else {\n\t\t\tR = r.R;\n\t\t}\n\t\tR.direction = r.d;\n\t\tm.restore(R);\n\t\treturn r;\n\t}\n\treturn monotype.late(r,opt);\n\t//return r;\n});\nmonotype.late = function(r,opt){\n\tvar u, m = r //monotype(r,opt)\n\t, strhml = function(t){\n\t\treturn (t[0] === '<' && $(t).length)\n\t}, jqtxt = function(n){\n\t\treturn n.jquery?n:(strhml(n))?$('<div>'+n+'</div>').contents():$(document.createTextNode(n));\n\t}\n\tm.get = function(d){\n\t\tif(u === d){ return $([m.R.startContainer, m.R.endContainer]) }\n\t\treturn monotype.deep((d = (d && d > 0))? m.R.endContainer : m.R.startContainer\n\t\t\t, d? m.R.endOffset : m.R.startOffset).container;\n\t}\n\tm.remove = function(n,R){\n\t\tR = m.R || m.range();\n\t\tR.deleteContents();\n\t\tmonotype.restore(R);\n\t\tm = monotype(m,opt);\n\t\treturn m;\n\t}\n\tm.insert = function(n,R){\n\t\tn = jqtxt(n);\n\t\tR = m.R || m.range();\n\t\tR.deleteContents();\n\t\t$(n.get().reverse()).each(function(){\n\t\t\tR.insertNode(this);\n\t\t});\n\t\tR.selectNodeContents(n.last()[0]);\n\t\tmonotype.restore(R);\n\t\tm = monotype(m,opt);\n\t\treturn m;\n\t}\n\tm.wrap = function(n,R){\n\t\tvar jq;\n\t\tn = jqtxt(n);\n\t\tn = n[0];\n\t\tR = m.R || m.range();\n\t\tif(monotype.text(R.startContainer) || monotype.text(R.endContainer)){\n\t\t\tvar b = R.cloneContents();\n\t\t\tR.deleteContents();\n\t\t\tjq = $(n);\n\t\t\tjq.html(b);\n\t\t\tjq = jq[0];\n\t\t\tR.insertNode(jq);\n\t\t}else{\n\t\t\tR.surroundContents(n);\n\t\t}\n\t\tR.selectNodeContents(jq||n);\n\t\tmonotype.restore(R);\n\t\tm = monotype(m,opt);\n\t\treturn m;\n\t}\n\tm.select = function(n,i,e,j){\n\t\tvar R = m.R || m.range(), t = e;\n\t\tn = $(n);\n\t\tif($.isNumeric(e)){\n\t\t\te = j || n;\n\t\t\tj = t;\n\t\t} else {\n\t\t\te = e || n;\n\t\t}\n\t\tj = $.isNumeric(j)? j : $.isNumeric(i)? i : Infinity;\n\t\ti = i || 0;\n\t\tif(i < 0){\n\t\t\tt = n.contents().length || n.text().length;\n\t\t\ti = t + i;\n\t\t} if(j < 0){\n\t\t\tt = n.contents().length || n.text().length;\n\t\t\tj = t + j;\n\t\t} if(j === Infinity){\n\t\t\tR.selectNodeContents(n[0]);\n\t\t} else {\n\t\t\tR.setStart(n[0],i);\n\t\t\tR.setEnd(e[0],j);\n\t\t}\n\t\tmonotype.restore(R);\n\t\tm = monotype(m,opt);\n\t\treturn m;\n\t}\n\treturn m;\n}"
  },
  {
    "path": "lib/multicast.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.on('create', function(root){\n\tthis.to.next(root);\n\tvar opt = root.opt;\n  if(false === opt.multicast){ return }\n  if((typeof process !== \"undefined\") && 'false' === ''+(process.env||{}).MULTICAST){ return }\n\t//if(true !== opt.multicast){ return } // disable multicast by default for now.\n\n  var udp = opt.multicast = opt.multicast || {};\n  udp.address = udp.address || '233.255.255.255';\n  udp.pack = udp.pack || 50000; // UDP messages limited to 65KB.\n  udp.port  = udp.port || 8765;\n\n  var noop = function(){}, u;\n  var pid = '2'+Math.random().toString().slice(-8);\n  var mesh = opt.mesh = opt.mesh || Gun.Mesh(root);\n  var dgram;\n\n  try{ dgram = require(\"dgram\") }catch(e){ return }\n  var socket = dgram.createSocket({type: \"udp4\", reuseAddr: true});\n  socket.bind({port: udp.port, exclusive: true}, function(){\n    socket.setBroadcast(true);\n    socket.setMulticastTTL(128);\n  });\n\n  socket.on(\"listening\", function(){\n    try { socket.addMembership(udp.address) }catch(e){ console.error(e); return; }\n    udp.peer = {id: udp.address + ':' + udp.port, wire: socket};\n\n    udp.peer.say = function(raw){\n      var buf = Buffer.from(raw, 'utf8');\n      if(udp.pack <= buf.length){ // message too big!!!\n        return;\n      }\n      socket.send(buf, 0, buf.length, udp.port, udp.address, noop);\n    }\n    //opt.mesh.hi(udp.peer);\n\n    Gun.log.once('multi', 'Multicast on '+udp.peer.id);\n    return; // below code only needed for when WebSocket connections desired!\n    setInterval(function broadcast(){\n      port = port || (opt.web && opt.web.address()||{}).port;\n      if(!port){ return }\n      udp.peer.say(JSON.stringify({id: opt.pid || (opt.pid = Math.random().toString(36).slice(2)), port: port}));\n    }, 1000);\n  });\n\n  socket.on(\"message\", function(raw, info) { try {\n    if(!raw){ return }\n    raw = raw.toString('utf8');\n    if('2'===raw[0]){ return check(raw, info) }\n    opt.mesh.hear(raw, udp.peer);\n\n    return; // below code only needed for when WebSocket connections desired!\n    var message;\n    message = JSON.parse(raw.toString('utf8'));\n\n    if(opt.pid === message.id){ return } // ignore self\n\n    var url = 'http://' + info.address + ':' + (port || (opt.web && opt.web.address()||{}).port) + '/gun';\n    if(root.opt.peers[url]){ return }\n\n    //console.log('discovered', url, message, info);\n    root.$.opt(url);\n\n  } catch(e){\n    //console.log('multicast error', e, raw);\n    return;\n  } });\n\n  function say(msg){\n    this.to.next(msg);\n    if(!udp.peer){ return }\n    mesh.say(msg, udp.peer);\n  }\n\n  function check(id, info){ var tmp;\n    if(!udp.peer){ return }\n    if(!id){\n      id = check.id = check.id || Buffer.from(pid, 'utf8');\n      socket.send(id, 0, id.length, udp.port, udp.address, noop);\n      return;\n    }\n    if((tmp = root.stats) && (tmp = tmp.gap) && info){ (tmp.near || (tmp.near = {}))[info.address] = info.port || 1 } // STATS!\n    if(check.on || id === pid){ return }\n    root.on('out', check.on = say); // TODO: MULTICAST NEEDS TO BE CHECKED FOR NEW CODE SYSTEM!!!!!!!!!! // TODO: This approach seems interferes with other relays, below does not but...\n    //opt.mesh.hi(udp.peer); //  IS THIS CORRECT?\n  }\n\n  setInterval(check, 1000 * 1);\n\n});\n"
  },
  {
    "path": "lib/nomem.js",
    "content": "function Nomem(){\n  var opt = {}, u;\n  opt.put = function(file, data, cb){ cb(null, -9) }; // dev/null!\n  opt.get = function(file, cb){ cb(null) };\n  return opt;\n}\nif(typeof window !== \"undefined\"){\n  window.Nomem = Nomem;\n} else {\n\ttry{ module.exports = Nomem }catch(e){}\n}"
  },
  {
    "path": "lib/normalize.js",
    "content": "(function(){\n\n  $.normalize = function(html, customOpt){\n    html = html || '';\n    var root$, wrapped, opt;\n    opt = html.opt || (customOpt ? prepareOptTags($.extend(true, baseOpt, customOpt))\n                                 : defaultOpt);\n    if(!html.opt){\n      // first call\n      unstableList.length = 0; // drop state from previous run (in case there has been error)\n      root$ = $('<div>'+html+'</div>');\n    }\n    // initial recursion\n    (html.$ || root$).contents().each(function(){\n      if(this.nodeType === this.TEXT_NODE) {\n      this.textContent = this.textContent.replace(/^[ \\n]+|[ \\n]+$/g, ' ');\n        return;\n      }\n      var a = {$: $(this), opt: opt};\n      initTag(a);\n      $.normalize(a);\n    });\n    if(root$){\n      stateMachine();\n      return root$.html();\n    }\n  }\n\n  var baseOpt = {\n    hierarchy: ['div', 'pre', 'ol', 'ul', 'li',\n                'h1', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'a', // block\n                'b', 'code', 'i', 'span', 's', 'sub', 'sup', 'u',   // inline\n                'br', 'img']                                               // empty\n    ,tags: {\n      'a': {attrs:{'href':1}, exclude:{'a':1}},\n      'b': {exclude:{'b':1,'p':1}},\n      'br': {empty: 1},\n      'i': {exclude:{'i':1,'p':1}},\n      'img': {attrs:{'src':1}, empty: 1},\n      'span': {exclude:{'p':1,'ul':1,'ol':1,'li':1,'br':1}},\n      's': {space:1},\n      'u': {exclude:{'u':1,'p':1},space:1},\n    }\n    ,convert: {\n      'em': 'i', 'strong': 'b', 'strike': 's',\n    }\n    ,attrs: {\n      'id':1\n      ,'class':1\n      ,'style':1\n    }\n    ,blockTag: function(a){\n      return a.opt.tags[a.tag].order < a.opt.tags.a.order;\n    }\n    ,mutate: [exclude, moveSpaceUp, next, parentOrderWrap]\n  }\n\n  var defaultOpt = prepareOptTags($.extend(true, {}, baseOpt));\n\n  var unstableList = [];\n\n  function addUnstable(a) { // NOT ES5\n    if(!a.tag) { throw Error(\"not tag in \", a) }\n    if(a.unstable) return;\n    unstableList.push(a);\n    a.unstable = true;\n  }\n\n  function initTag(a) {\n    // initial handling (container, convert, attributes):\n    a.tag = tag(a.$);\n      if(empty(a)) {\n      return;\n    }\n    parseAndRemoveAttrs(a);\n    convert(a);\n    setAttrs(a);\n    a.$[0].a = a; // link from dom element back to a\n    // state machine init\n    unstableList.push(a);\n    a.unstable = true;\n    return a;\n  }\n\n  function stateMachine() {\n    if(unstableList.length===0)\n      return;\n    var a, i = -1;\n    while (a = unstableList.pop()) { // PERF: running index is probably faster than shift (mutates array)\n      a.unstable = false;\n      $(a.opt.mutate).each(function(i,fn){\n        return fn && fn(a, addUnstable);\n      });\n    }\n  }\n\n  function prepareOptTags(opt) {\n    var name, tag, tags = opt.tags;\n    for(name in tags) {\n      if(opt.hierarchy.indexOf(name)===-1)\n        throw Error('tag \"'+name+'\" is missing hierarchy definition');\n    }\n    opt.hierarchy.forEach(function(name){\n      if(!tags[name]){\n        tags[name] = {attrs: opt.attrs};\n      }\n      (tag=tags[name]).attrs = $.extend(tag.attrs||{}, opt.attrs);\n      tag.name = name; // not used, debug help (REMOVE later?)\n      // order\n      tag.order = opt.hierarchy.indexOf(name)\n      if(tag.order === -1) {\n      throw Error(\"Order of '\"+name+\"' not defined in hierarchy\");\n    }\n    });\n    return opt;\n  }\n\n  // GENERAL UTILS\n\n  function get(o, args){ // path arguments as separate string parameters\n    if(typeof args === 'string')\n      return o[args[0]];\n    var i = 0, l = args.length, u;\n    while((o = o[args[i++]]) != null && i < l){};\n    return i < l ? u : o;\n  }\n\n  function has(obj,prop){\n    return Object.prototype.hasOwnProperty.call(obj, prop);\n  }\n\n  // ELEMENT UTILS\n\n  function tag(e){\n    return (($(e)[0]||{}).nodeName||'').toLowerCase();\n  }\n\n  function joint(e, d){\n    d = (d? 'next' : 'previous') + 'Sibling';\n    return $(($(e)[0]||{})[d]);\n  }\n\n  var xssattr = /[^a-z:]/ig, xssjs = /javascript:/ig;\n  // url(\"javascript: // and all permutations\n  // stylesheets can apparently have XSS?\n\n  // create key val attributes object from elements attributes\n  function attrsAsObj(e, filterCb){\n    var attrObj = {};\n    (e = $(e)) && e.length && $(e[0].attributes||[]).each(function(value,name){\n      name = name.nodeName||name.name;\n      value = e.attr(name);\n      if(value.replace(xssattr,'').match(xssjs)){ e.removeAttr(name); return }\n      value = filterCb? filterCb(value,name,e) : value;\n      if(value !== undefined && value !== false)\n        attrObj[name] = value;\n    });\n    return attrObj;\n  }\n\n  // TODO: PERF testing - for loop to compare through?\n  function sameAttrs(a, b) {\n    return JSON.stringify(a.attr) === JSON.stringify(b.attr);\n  }\n\n  // INITIAL MUTATORS\n\n  function parseAndRemoveAttrs(a) {\n    a.attrs = [];\n    var tag = a.opt.convert[a.tag] || a.tag,\n    tOpt = a.opt.tags[tag];\n    a.attr = tOpt && attrsAsObj(a.$, function(value,name){\n    a.$.removeAttr(name);\n    if(tOpt.attrs[name.toLowerCase()]){\n      a.attrs.push(name)\n      return value;\n    }\n    });\n  }\n\n  function setAttrs(a){\n    var l  = function(ind,name){\n      var t = name;\n      name = a.attrs? name : ind;\n      var value = a.attrs? a.attr[name.toLowerCase()] : t;\n      a.$.attr(name, value);\n    }\n    a.attrs? $(a.attrs.sort()).each(l) : $.each(a.attr,l);\n  }\n\n  function convert(a){\n    var t;\n    if(t = a.opt.convert[a.tag]){\n      a.$.replaceWith(a.$ = $('<'+ (a.tag = t.toLowerCase()) +'>').append(a.$.contents()));\n    }\n  }\n\n  // LOOPING (STATE MACHINE) MUTATORS\n\n  function exclude(a, addUnstable){\n    var t = get(a.opt, ['tags', a.tag]),\n    pt = get(a.opt, ['tags', tag(a.$.parent())]);\n    if(!t || (pt && get(pt, ['exclude', a.tag]))){\n      var c = a.$.contents();\n      a.$.replaceWith(c);\n      c.length===1 && c[0].a && addUnstable(c[0].a);\n      return false;\n    }\n  }\n\n  function moveSpaceUp(a, addUnstable){\n    var n = a.$[0];\n    if(moveSpace(n, true) + moveSpace(n, false)) {\n      // either front, back or both spaces moved\n      var c;\n      if(n.textContent==='') {\n        empty(a);\n      } else if((c = a.$.contents()[0]) && c.a) {\n        parentOrderWrap(c.a, addUnstable)\n      }\n    }\n  }\n\n  function moveSpace(n, bef) {\n    var childRe  = bef? /^ / : / $/,\n        parentRe = bef? / $/ : /^ /,\n        c = bef? 'firstChild' : 'lastChild',\n        s = bef? 'previousSibling' : 'nextSibling';\n        sAdd = bef? 'after' : 'before';\n        pAdd = bef? 'prepend' : 'append';\n    if(!n || !n[c] || n[c].nodeType !== n.TEXT_NODE || !n[c].wholeText.match(childRe)) {\n      return 0;\n    }\n    if((n2 = n[s]) && !n.a.opt.blockTag(n.a)) {\n      if(n2.nodeType === 3 && !n2.textContent.match(parentRe)) {\n        n2.textContent = (bef?'':' ') + n2.textContent + (bef?' ':'');\n      } else if(n2.nodeType === 1) {\n        $(n2)[sAdd](' ');\n      }\n    } else if((n2 = n.parentNode) && !n.a.opt.blockTag(n.a)) {\n      $(n2)[pAdd](' ');\n    } else {\n      return 0;\n    }\n    n[c].textContent = n[c].wholeText.replace(childRe, '');\n    if(!n[c].wholeText.length)\n      $(n[c]).remove();\n    return 1;\n  }\n\n  function next(a, addUnstable, t){\n    var t = t || joint(a.$, true), sm;\n    if(!t.length || a.opt.blockTag(a))\n      return;\n    if(a.opt.spaceMerge && t.length===1 && t[0].nodeType === 3 && t[0].wholeText===' '){\n      if(!(t2 = joint(t, true)).length || a.opt.blockTag(t2[0].a))\n        return;\n      t.remove();\n      t2.prepend(' ');\n      return next(a, addUnstable, t2);\n    }\n    if(!t[0].a || a.tag !== t[0].a.tag || !sameAttrs(a, t[0].a))\n      return;\n    t.prepend(a.$.contents());\n    empty(a);\n    addUnstable(t[0].a);\n    (t = t.children(\":first\")).length && addUnstable(t[0].a);\n  }\n\n  function empty(a){\n    var t = a.opt.tags[a.tag];\n    if((!t || !t.empty) && !a.$.contents().length && !a.$[0].attributes.length){\n      a.$.remove();\n      return true; // NOTE true/false - different API than in exclude\n    }\n  }\n\n  function parentOrderWrap(a, addUnstable){\n    var parent = a.$.parent(), children = parent.contents(),\n    tags = a.opt.tags, ptag;\n\n    if(children.length===1 && children[0] === a.$[0]\n    && (ptag=tags[tag(parent)]) && ptag.order > tags[a.tag].order){\n      parent.after(a.$);\n      parent.append(a.$.contents());\n      a.$.append(parent);\n      addUnstable(parent[0].a);\n      addUnstable(a);\n    }\n  }\n})();"
  },
  {
    "path": "lib/not.d.ts",
    "content": "import {} from '../types/gun/IGunChain';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * > Warning: `.not` has no guarantees, since data could theoretically exist on an unrelated\n     *  peer that we have no knowledge of. If you only have one server, and data is synced\n     *  through it, then you have a pretty reasonable assurance that a not found means that\n     *  the data doesn't exist yet. Just be mindful of how you use it\n     *\n     * @param callback If there's reason to believe the data doesn't exist, the callback will be\n     *  invoked. This can be used as a check to prevent implicitly writing data\n     */\n    not(\n      callback: (key: string) => void\n    ): IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n  }\n}\n"
  },
  {
    "path": "lib/not.js",
    "content": "if(typeof window !== \"undefined\"){\n  var Gun = window.Gun;\n} else { \n  var Gun = require('../gun');\n}\n\nvar u;\n\nGun.chain.not = function(cb, opt, t){\n\treturn this.get(ought, {not: cb});\n}\n\nfunction ought(at, ev){ ev.off();\n\tif(at.err || (u !== at.put)){ return }\n\tif(!this.not){ return }\n\tthis.not.call(at.gun, at.get, function(){ console.log(\"Please report this bug on https://gitter.im/amark/gun and in the issues.\"); need.to.implement; });\n}"
  },
  {
    "path": "lib/open.d.ts",
    "content": "import {} from '../types/gun/IGunChain';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * Note: This will automatically load everything it can find on the context. This may sound\n     *  convenient, but may be unnecessary and excessive - resulting in more bandwidth and\n     *  slower load times for larger data. It could also result in your entire database being\n     *  loaded, if your app is highly interconnected\n     *\n     * Open behaves very similarly to `gun.on`, except it gives you the full depth of a document\n     *  on every update. It also works with graphs, tables, or other data structures. Think of\n     *  it as opening up a live connection to a document\n     *\n     * @param callback The callback has 1 parameter, and will get called every time an update\n     *  happens anywhere in the full depth of the data. Unlike most of the API, open does not\n     *  give you a node. It gives you a copy of your data with all metadata removed. Updates to\n     *  the callback will return the same data, with changes modified onto it\n     */\n    open(\n      callback: (data: TNode) => void\n    ): IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n  }\n}\n"
  },
  {
    "path": "lib/open.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.chain.open = function(cb, opt, at, depth){ // this is a recursive function, BEWARE!\n\tdepth = depth || 1;\n\topt = opt || {}; // init top level options.\n\topt.doc = opt.doc || {};\n\topt.ids = opt.ids || {};\n\topt.any = opt.any || cb;\n\topt.meta = opt.meta || false;\n\topt.eve = opt.eve || {off: function(){ // collect all recursive events to unsubscribe to if needed.\n\t\tObject.keys(opt.eve.s).forEach(function(i,e){ // switch to CPU scheduled setTimeout.each?\n\t\t\tif(e = opt.eve.s[i]){ e.off() }\n\t\t});\n\t\topt.eve.s = {};\n\t}, s:{}}\n\treturn this.on(function(data, key, ctx, eve){ // subscribe to 1 deeper of data!\n\t\tclearTimeout(opt.to); // do not trigger callback if bunch of changes...\n\t\topt.to = setTimeout(function(){ // but schedule the callback to fire soon!\n\t\t\tif(!opt.any){ return }\n\t\t\topt.any.call(opt.at.$, opt.doc, opt.key, opt, opt.eve); // call it.\n\t\t\tif(opt.off){ // check for unsubscribing.\n\t\t\t\topt.eve.off();\n\t\t\t\topt.any = null;\n\t\t\t}\n\t\t}, opt.wait || 9);\n\t\topt.at = opt.at || ctx; // opt.at will always be the first context it finds.\n\t\topt.key = opt.key || key;\n\t\topt.eve.s[this._.id] = eve; // collect all the events together.\n\t\tif(true === Gun.valid(data)){ // if primitive value...\n\t\t\tif(!at){\n\t\t\t\topt.doc = data;\n\t\t\t} else {\n\t\t\t\tat[key] = data;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tvar tmp = this; // else if a sub-object, CPU schedule loop over properties to do recursion.\n\t\tsetTimeout.each(Object.keys(data), function(key, val){\n\t\t\tif('_' === key && !opt.meta){ return }\n\t\t\tval = data[key];\n\t\t\tvar doc = at || opt.doc, id; // first pass this becomes the root of open, then at is passed below, and will be the parent for each sub-document/object.\n\t\t\tif(!doc){ return } // if no \"parent\"\n\t\t\tif('string' !== typeof (id = Gun.valid(val))){ // if primitive...\n\t\t\t\tdoc[key] = val;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(opt.ids[id]){ // if we've already seen this sub-object/document\n\t\t\t\tdoc[key] = opt.ids[id]; // link to itself, our already in-memory one, not a new copy.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(opt.depth <= depth){ // stop recursive open at max depth.\n\t\t\t\tdoc[key] = doc[key] || val; // show link so app can load it if need.\n\t\t\t\treturn;\n\t\t\t} // now open up the recursion of sub-documents!\n\t\t\ttmp.get(key).open(opt.any, opt, opt.ids[id] = doc[key] = {}, depth+1); // 3rd param is now where we are \"at\".\n\t\t});\n\t})\n}"
  },
  {
    "path": "lib/path.d.ts",
    "content": "import { IGunChain, GunSchema } from '../types/gun';\n\nimport {} from '../types/gun/IGunInstance';\ndeclare module '../types/gun/IGunInstance' {\n  export interface IGunInstance<TNode> {\n    /**\n     * > Warning: This extension was removed from core, you probably shouldn't be using it!\n     *\n     * Path does the same thing as get but has some conveniences built in\n     *\n     * Once you've changed the context, you can read, write, and path again from that field.\n     *  While you can just chain one path after another, it becomes verbose, so there are two\n     *  shorthand styles:\n     * - dot format\n     * - array format\n     *\n     * The dot notation can do some strange things if you're not expecting it. Under the hood,\n     *  everything is changed into a string, including floating point numbers. If you use a\n     *  decimal in your path, it will split into two paths...\n     *\n     * This can be especially confusing as the chain might never resolve to a value\n     */\n    path<T extends GunSchema & Record<string, GunSchema>>(\n      value: string | string[]\n    ): IGunChain<T, any, IGunInstance<TNode>, string>;\n  }\n}\n\nimport {} from '../types/gun/IGunChain';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * > Warning: This extension was removed from core, you probably shouldn't be using it!\n     *\n     * > Warning: Not included by default! You must\n     *  include it yourself via `require('gun/lib/path.js')` or\n     *  `<script src=\"https://cdn.jsdelivr.net/npm/gun/lib/path.js\"></script>`!\n     *\n     * Path does the same thing as get but has some conveniences built in\n     *\n     * Once you've changed the context, you can read, write, and path again from that field.\n     *  While you can just chain one path after another, it becomes verbose, so there are two\n     *  shorthand styles:\n     * - dot format\n     * - array format\n     *\n     * The dot notation can do some strange things if you're not expecting it. Under the hood,\n     *  everything is changed into a string, including floating point numbers. If you use a\n     *  decimal in your path, it will split into two paths...\n     *\n     * This can be especially confusing as the chain might never resolve to a value\n     */\n    path<T extends GunSchema & Record<string, GunSchema>>(\n      value: string | string[]\n    ): IGunChain<T, any, TGunInstance, string>;\n  }\n}\n"
  },
  {
    "path": "lib/path.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.chain.path = function(field, opt){\n\tvar back = this, gun = back, tmp;\n\tif(typeof field === 'string'){\n\t\ttmp = field.split(opt || '.');\n\t\tif(1 === tmp.length){\n\t\t\tgun = back.get(field);\n\t\t\treturn gun;\n\t\t}\n\t\tfield = tmp;\n\t}\n\tif(field instanceof Array){\n\t\tif(field.length > 1){\n\t\t\tgun = back;\n\t\t\tvar i = 0, l = field.length;\n\t\t\tfor(i; i < l; i++){\n\t\t\t\t//gun = gun.get(field[i], (i+1 === l)? cb : null, opt);\n\t\t\t\tgun = gun.get(field[i]);\n\t\t\t}\n\t\t} else {\n\t\t\tgun = back.get(field[0]);\n\t\t}\n\t\treturn gun;\n\t}\n\tif(!field && 0 != field){\n\t\treturn back;\n\t}\n\tgun = back.get(''+field);\n\treturn gun;\n}"
  },
  {
    "path": "lib/promise.d.ts",
    "content": "import { IGunChain2TNode } from '../types/utils.d';\nimport {\n  GunCallbackOn,\n  GunDataNode,\n  GunMessagePut,\n  GunOptionsOn,\n  GunOptionsOnce,\n  GunOptionsPut,\n  IGunChain,\n  GunSchema,\n  GunSoul,\n} from '../types/gun';\n\nimport {} from '../types/gun/IGunInstance';\ndeclare module '../types/gun/IGunInstance' {\n  export interface IGunInstance<TNode> {\n    /**\n     * @param value the data to save\n     * @param options `put` options\n     */\n    promPut<V extends TNode & Record<string, GunSchema>>(\n      value: V,\n      options: GunOptionsPut\n    ): Promise<{\n      ref: IGunChain<TNode, IGunInstance<TNode>, IGunInstance<TNode>, ''>;\n      ack: GunMessagePut;\n    }>;\n  }\n}\n\nimport {} from '../types/gun/IGunChain';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * @param value the data to save\n     * @param options `put` options\n     */\n    promPut<\n      V extends\n        | (TNode extends object ? Partial<TNode> : TNode)\n        | GunSoul<TNode>\n        | IGunChain<TNode, any, any, any>\n        | IGunChain<NonNullable<TNode>, any, any, any>\n    >(\n      value: V,\n      options: GunOptionsPut\n    ): Promise<{\n      ref: IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n      ack: GunMessagePut;\n    }>;\n\n    /**\n     * @param value the data to save\n     * @param options `put` options\n     */\n    promSet<\n      V extends Partial<N> | GunSoul<N> | IGunChain<N, any, any, any>,\n      K extends keyof TNode & string,\n      N extends TNode[K] & Record<string, GunSchema>\n    >(\n      value: V,\n      options: GunOptionsPut\n    ): Promise<{\n      ref: V extends GunSchema\n        ? IGunChain<\n            N,\n            IGunChain<TNode, TChainParent, TGunInstance, TKey>,\n            TGunInstance,\n            K\n          >\n        : IGunChain<\n            IGunChain2TNode<V>,\n            IGunChain<TNode, TChainParent, TGunInstance, TKey>,\n            TGunInstance,\n            K\n          >;\n      ack: GunMessagePut;\n    }>;\n\n    /**\n     * @param callback function to be called upon changes to data\n     * @param options `put` options\n     */\n    promOn<V extends TNode>(\n      callback: GunCallbackOn<V, TKey>,\n      options: GunOptionsOn\n    ): Promise<GunDataNode<V>>;\n\n    /**\n     * @param limit due to promises resolving too fast if we do not set a timer we will not be\n     *  able receive any data back from gun before returning the promise works both following a\n     *  `Chain.get` and a `Chain.map` (limit only applies to map). If no limit is chosen,\n     *  defaults to 100 ms (quite sufficient to fetch about 2000 nodes or more)\n     * @param options `once` options\n     */\n    promOnce(\n      limit: number,\n      options: GunOptionsOnce\n    ): Promise<{\n      ref: IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n      data: GunDataNode<TNode>;\n      key: keyof IGunChain2TNode<TChainParent> & string;\n    }>;\n  }\n}\n"
  },
  {
    "path": "lib/promise.js",
    "content": "/* Promise Library v1.1 for GUN DB\n*  Turn any part of a gun chain into a promise, that you can then use\n*  .then().catch() pattern.\n*  In normal gun doing var item = gun.get('someKey'), gun returns a reference\n*  to the someKey synchronously. Using a reference is quite helpful in making\n*  graph structures, so I have chosen to follow the following paradigm.\n*  Whenever a promise is resolved, gun will return an object of data, I will\n*  wrap that data in an object together with the reference like so:\n*  {ref: gunRef, data: data}.\n* This code is freely given in the spirit of open source MIT license.\n* Author: Jachen Duschletta / 2019\n*/\n\n// Get window or node Gun instance\n\nvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\n/*\n* Function promOnce\n* @param limit - due to promises resolving too fast if we do not set a timer\n*  we will not be able receive any data back from gun before returning the promise\n*  works both following a Chain.get and a Chain.map (limit only applies to map)\n*  If no limit is chosen, defaults to 100 ms (quite sufficient to fetch about 2000 nodes or more)\n* @param opt - option object\n* @return {ref: gunReference, data: object / string (data), key: string (soulOfData)}\n*/\n\nGun.chain.promOnce = async function (limit, opt) {\n var gun = this, cat = gun._;\n if(!limit){limit = 100}\n if(cat.subs){\n  var array = [];\n  gun.map().once((data, key)=>{\n    var gun = this;\n    array.push(new Promise((res, rej)=>{\n      res({ref: gun, data:data, key:key});\n    })\n   )\n }, opt);\n  await sleep(limit);\n  return Promise.all(array)\n} else {\n  return (new Promise((res, rej)=>{\n    gun.once(function (data, key) {\n      var gun = this;\n      res({ref:gun,data:data,key:key});\n      }, opt);\n    }))\n  }\n var chain = gun.chain();\n return chain;\n}\n\nfunction sleep (limit) {\n return (new Promise((res, rej)=>{\n   setTimeout(res, limit);\n }))\n}\n\n/*\n* Function promPut\n* @param item (string / object) - item to be put to that key in the chain\n* @param opt - option object\n* @return object - Returns an object with the ref to that node that was just\n*  created as well as the 'ack' which acknowledges the put was successful\n*  object {ref: gunReference, ack: acknowledgmentObject}\n* If put had an error we can catch the return via .catch\n*/\n\nGun.chain.promPut = async function (item, opt) {\n  var gun = this;\n  return (new Promise((res, rej)=>{\n    gun.put(item, function(ack) {\n        if(ack.err){console.log(ack.err); ack.ok=-1; res({ref:gun, ack:ack})}\n        res({ref:gun, ack:ack});\n    }, opt);\n  }))\n}\n\n/*\n* Function promSet\n* @param item (string / object) - item to be set into a list at this key\n* @param opt - option object\n* @return object - Returns object with the ref to that node that was just\n*  created as well as the 'ack' which acknowledges the set was successful\n*  object {ref: gunReference, ack: acknowledgmentObject}\n* If set had an error we can catch the return via .catch\n*/\n\nGun.chain.promSet = async function(item, opt){\n\tvar gun = this, soul;\n  var cb = cb || function(){};\n\topt = opt || {}; opt.item = opt.item || item;\n  return (new Promise(async function (res,rej) {\n    if(soul = Gun.node.soul(item)){ item = Gun.obj.put({}, soul, Gun.val.link.ify(soul)) }\n\t\tif(!Gun.is(item)){\n\t\t\tif(Gun.obj.is(item)){;\n\t\t\t\titem = await gun.back(-1).get(soul = soul || Gun.node.soul(item) || gun.back('opt.uuid')()).promPut(item);\n        item = item.ref;\n\t\t\t}\n\t\t\tres(gun.get(soul || (Gun.state.lex() + Gun.text.random(7))).promPut(item));\n\t\t}\n\t\titem.get(function(soul, o, msg){\n      var ack = {};\n\t\t\tif(!soul){ rej({ack:{err: Gun.log('Only a node can be linked! Not \"' + msg.put + '\"!')}} ) }\n\t\t\tgun.put(Gun.obj.put({}, soul, Gun.val.link.ify(soul)), cb, opt);\n\t\t},true);\n\t\tres({ref:item, ack:{ok:0}});\n  }))\n}\n\n/*\n* Function promOn\n* @param callback (function) - function to be called upon changes to data\n* @param option (object) - {change: true} only allow changes to trigger the callback\n* @return - data and key\n* subscribes callback to data\n*/\n\nGun.chain.promOn = async function (callback, option) {\n  var gun = this;\n  return (new Promise((res, rej)=>{\n    gun.on(function (data, key){\n      callback(data, key);\n      res(data, key);\n    }, option);\n  }));\n}\n"
  },
  {
    "path": "lib/radisk.d.ts",
    "content": "import { IRadix } from './radix';\n\nimport {} from './radisk'\ndeclare module './radisk' {\n  export const Radisk: IRadisk;\n  export interface IRadisk {\n    Radix: IRadix;\n  }\n}\n\ndeclare global {\n  interface Window {\n    Radisk: IRadisk;\n  }\n}\n"
  },
  {
    "path": "lib/radisk.js",
    "content": ";(function(){\n\n\tfunction Radisk(opt){\n\n\t\topt = opt || {};\n\t\topt.log = opt.log || console.log;\n\t\topt.file = String(opt.file || 'radata');\n\t\tvar has = (Radisk.has || (Radisk.has = {}))[opt.file];\n\t\tif(has){ return has }\n\n\t\topt.max = opt.max || (opt.memory? (opt.memory * 999 * 999) : 300000000) * 0.3;\n\t\topt.until = opt.until || opt.wait || 250;\n\t\topt.batch = opt.batch || (10 * 1000);\n\t\topt.chunk = opt.chunk || (1024 * 1024 * 1); // 1MB\n\t\topt.code = opt.code || {};\n\t\topt.code.from = opt.code.from || '!';\n\t\topt.jsonify = true;\n\n\n\t\tfunction ename(t){ return encodeURIComponent(t).replace(/\\*/g, '%2A') } // TODO: Hash this also, but allow migration!\n\t\tfunction atomic(v){ return u !== v && (!v || 'object' != typeof v) }\n\t\tvar timediate = (''+u === typeof setImmediate)? setTimeout : setImmediate;\n\t\tvar puff = setTimeout.turn || timediate, u;\n\t\tvar map = Radix.object;\n\t\tvar ST = 0;\n\n\t\tif(!opt.store){\n\t\t\treturn opt.log(\"ERROR: Radisk needs `opt.store` interface with `{get: fn, put: fn (, list: fn)}`!\");\n\t\t}\n\t\tif(!opt.store.put){\n\t\t\treturn opt.log(\"ERROR: Radisk needs `store.put` interface with `(file, data, cb)`!\");\n\t\t}\n\t\tif(!opt.store.get){\n\t\t\treturn opt.log(\"ERROR: Radisk needs `store.get` interface with `(file, cb)`!\");\n\t\t}\n\t\tif(!opt.store.list){\n\t\t\t//opt.log(\"WARNING: `store.list` interface might be needed!\");\n\t\t}\n\n\t\tif(''+u != typeof require){ require('./yson') }\n\t\tvar parse = JSON.parseAsync || function(t,cb,r){ var u; try{ cb(u, JSON.parse(t,r)) }catch(e){ cb(e) } }\n\t\tvar json = JSON.stringifyAsync || function(v,cb,r,s){ var u; try{ cb(u, JSON.stringify(v,r,s)) }catch(e){ cb(e) } }\n\t\t/*\n\t\t\tAny and all storage adapters should...\n\t\t\t1. Because writing to disk takes time, we should batch data to disk. This improves performance, and reduces potential disk corruption.\n\t\t\t2. If a batch exceeds a certain number of writes, we should immediately write to disk when physically possible. This caps total performance, but reduces potential loss.\n\t\t*/\n\t\tvar r = function(key, data, cb, tag, DBG){\n\t\t\tif('function' === typeof data){\n\t\t\t\tvar o = cb || {};\n\t\t\t\tcb = data;\n\t\t\t\tr.read(key, cb, o, DBG || tag);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t//var tmp = (tmp = r.batch = r.batch || {})[key] = tmp[key] || {};\n\t\t\t//var tmp = (tmp = r.batch = r.batch || {})[key] = data;\n\t\t\tr.save(key, data, cb, tag, DBG);\n\t\t}\n\t\tr.save = function(key, data, cb, tag, DBG){\n\t\t\tvar s = {key: key}, tags, f, d, q;\n\t\t\ts.find = function(file){ var tmp;\n\t\t\t\ts.file = file || (file = opt.code.from);\n\t\t\t\tDBG && (DBG = DBG[file] = DBG[file] || {});\n\t\t\t\tDBG && (DBG.sf = DBG.sf || +new Date);\n\t\t\t\t//console.only.i && console.log('found', file);\n\t\t\t\tif(tmp = r.disk[file]){ s.mix(u, tmp); return }\n\t\t\t\tr.parse(file, s.mix, u, DBG);\n\t\t\t}\n\t\t\ts.mix = function(err, disk){\n\t\t\t\tDBG && (DBG.sml = +new Date);\n\t\t\t\tDBG && (DBG.sm = DBG.sm || +new Date);\n\t\t\t\tif(s.err = err || s.err){ cb(err); return } // TODO: HANDLE BATCH EMIT\n\t\t\t\tvar file = s.file = (disk||'').file || s.file, tmp;\n\t\t\t\tif(!disk && file !== opt.code.from){ // corrupt file?\n\t\t\t\t\tr.find.bad(file); // remove from dir list\n\t\t\t\t\tr.save(key, data, cb, tag); // try again\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t(disk = r.disk[file] || (r.disk[file] = disk || Radix())).file || (disk.file = file);\n\t\t\t\tif(opt.compare){\n\t\t\t\t\tdata = opt.compare(disk(key), data, key, file);\n\t\t\t\t\tif(u === data){ cb(err, -1); return } // TODO: HANDLE BATCH EMIT\n\t\t\t\t}\n\t\t\t\t(s.disk = disk)(key, data);\n\t\t\t\tif(tag){\n\t\t\t\t\t(tmp = (tmp = disk.tags || (disk.tags = {}))[tag] || (tmp[tag] = r.tags[tag] || (r.tags[tag] = {})))[file] || (tmp[file] = r.one[tag] || (r.one[tag] = cb));\n\t\t\t\t\tcb = null;\n\t\t\t\t}\n\t\t\t\tDBG && (DBG.st = DBG.st || +new Date);\n\t\t\t\t//console.only.i && console.log('mix', disk.Q);\n\t\t\t\tif(disk.Q){ cb && disk.Q.push(cb); return } disk.Q = (cb? [cb] : []);\n\t\t\t\tdisk.to = setTimeout(s.write, opt.until);\n\t\t\t}\n\t\t\ts.write = function(){\n\t\t\t\tDBG && (DBG.sto = DBG.sto || +new Date);\n\t\t\t\tvar file = f = s.file, disk = d = s.disk;\n\t\t\t\tq = s.q = disk.Q;\n\t\t\t\ttags = s.tags = disk.tags;\n\t\t\t\tdelete disk.Q;\n\t\t\t\tdelete r.disk[file];\n\t\t\t\tdelete disk.tags;\n\t\t\t\t//console.only.i && console.log('write', file, disk, 'was saving:', key, data);\n\t\t\t\tr.write(file, disk, s.ack, u, DBG);\n\t\t\t}\n\t\t\ts.ack = function(err, ok){\n\t\t\t\tDBG && (DBG.sa = DBG.sa || +new Date);\n\t\t\t\tDBG && (DBG.sal = q.length);\n\t\t\t\tvar ack, tmp;\n\t\t\t\t// TODO!!!! CHANGE THIS INTO PUFF!!!!!!!!!!!!!!!!\n\t\t\t\tfor(var id in r.tags){\n\t\t\t\t\tif(!r.tags.hasOwnProperty(id)){ continue } var tag = r.tags[id];\n\t\t\t\t\tif((tmp = r.disk[f]) && (tmp = tmp.tags) && tmp[tag]){ continue }\n\t\t\t\t\tack = tag[f];\n\t\t\t\t\tdelete tag[f];\n\t\t\t\t\tvar ne; for(var k in tag){ if(tag.hasOwnProperty(k)){ ne = true; break } } // is not empty?\n\t\t\t\t\tif(ne){ continue } //if(!obj_empty(tag)){ continue }\n\t\t\t\t\tdelete r.tags[tag];\n\t\t\t\t\tack && ack(err, ok);\n\t\t\t\t}\n\t\t\t\t!q && (q = '');\n\t\t\t\tvar l = q.length, i = 0;\n\t\t\t\t// TODO: PERF: Why is acks so slow, what work do they do??? CHECK THIS!!\n\t\t\t\t// TODO: PERF: Why is acks so slow, what work do they do??? CHECK THIS!!\n\t\t\t\t// TODO: PERF: Why is acks so slow, what work do they do??? CHECK THIS!!\n\t\t\t\t// TODO: PERF: Why is acks so slow, what work do they do??? CHECK THIS!!\n\t\t\t\t// TODO: PERF: Why is acks so slow, what work do they do??? CHECK THIS!!\n\t\t\t\t// TODO: PERF: Why is acks so slow, what work do they do??? CHECK THIS!!\n\t\t\t\t// TODO: PERF: Why is acks so slow, what work do they do??? CHECK THIS!!\n\t\t\t\tvar S = +new Date;\n\t\t\t\tfor(;i < l; i++){ (ack = q[i]) && ack(err, ok) }\n\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'rad acks', ename(s.file));\n\t\t\t\tconsole.STAT && console.STAT(S, q.length, 'rad acks #', ename(s.file));\n\t\t\t}\n\t\t\tcb || (cb = function(err, ok){ // test delete!\n\t\t\t\tif(!err){ return }\n\t\t\t});\n\t\t\t//console.only.i && console.log('save', key);\n\t\t\tr.find(key, s.find);\n    }\n    r.disk = {};\n    r.one = {};\n    r.tags = {};\n\n\t\t/*\n\t\t\tAny storage engine at some point will have to do a read in order to write.\n\t\t\tThis is true of even systems that use an append only log, if they support updates.\n\t\t\tTherefore it is unavoidable that a read will have to happen,\n\t\t\tthe question is just how long you delay it.\n\t\t*/\n\t\tvar RWC = 0;\n\t\tr.write = function(file, rad, cb, o, DBG){\n\t\t\tif(!rad){ cb('No radix!'); return }\n\t\t\to = ('object' == typeof o)? o : {force: o};\n\t\t\tvar f = function Fractal(){}, a, b;\n\t\t\tf.text = '';\n\t\t\tf.file = file = rad.file || (rad.file = file);\n\t\t\tif(!file){ cb('What file?'); return }\n\t\t\tf.write = function(){\n\t\t\t\tvar text = rad.raw = f.text;\n\t\t\t\tr.disk[file = rad.file || f.file || file] = rad;\n\t\t\t\tvar S = +new Date;\n\t\t\t\tDBG && (DBG.wd = S);\n\t\t\t\t//console.only.i && console.log('add', file);\n\t\t\t\tr.find.add(file, function add(err){\n\t\t\t\t\tDBG && (DBG.wa = +new Date);\n\t\t\t\t\tif(err){ cb(err); return }\n\t\t\t\t\t//console.only.i && console.log('disk', file, text);\n\t\t\t\t\topt.store.put(ename(file), text, function safe(err, ok){\n\t\t\t\t\t\tDBG && (DBG.wp = +new Date);\n\t\t\t\t\t\tconsole.STAT && console.STAT(S, ST = +new Date - S, \"wrote disk\", JSON.stringify(file), ++RWC, 'total all writes.');\n\t\t\t\t\t\t//console.only.i && console.log('done', err, ok || 1, cb);\n\t\t\t\t\t\tcb(err, ok || 1);\n\t\t\t\t\t\tif(!rad.Q){ delete r.disk[file] } // VERY IMPORTANT! Clean up memory, but not if there is already queued writes on it!\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\t\t\tf.split = function(){\n\t\t\t\tvar S = +new Date;\n\t\t\t\tDBG && (DBG.wf = S);\n\t\t\t\tf.text = '';\n\t\t\t\tif(!f.count){ f.count = 0;\n\t\t\t\t\tRadix.map(rad, function count(){ f.count++ }); // TODO: Perf? Any faster way to get total length?\n\t\t\t\t}\n\t\t\t\tDBG && (DBG.wfc = f.count);\n\t\t\t\tf.limit = Math.ceil(f.count/2);\n\t\t\t\tvar SC = f.count;\n\t\t\t\tf.count = 0;\n\t\t\t\tDBG && (DBG.wf1 = +new Date);\n\t\t\t\tf.sub = Radix();\n\t\t\t\tRadix.map(rad, f.slice, {reverse: 1}); // IMPORTANT: DO THIS IN REVERSE, SO LAST HALF OF DATA MOVED TO NEW FILE BEFORE DROPPING FROM CURRENT FILE.\n\t\t\t\tDBG && (DBG.wf2 = +new Date);\n\t\t\t\tr.write(f.end, f.sub, function(err, ok){\n\t\t\t\t\tif(err){ return cb(err) }\n\t\t\t\t\tDBG && (DBG.wf3 = +new Date);\n\t\t\t\t\tf.hub = Radix();\n\t\t\t\t\tRadix.map(rad, f.stop);\n\t\t\t\t\tDBG && (DBG.wf4 = +new Date);\n\t\t\t\t\tr.write(rad.file, f.hub, cb, o);\n\t\t\t\t}, o);\n\t\t\t\tDBG && (DBG.wf5 = +new Date);\n\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, \"rad split\", ename(rad.file), SC);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tf.slice = function(val, key){\n\t\t\t\tf.sub(f.end = key, val);\n\t\t\t\tif(f.limit <= (++f.count)){ return true }\n\t\t\t}\n\t\t\tf.stop = function(val, key){\n\t\t\t\tif(key >= f.end){ return true }\n\t\t\t\tf.hub(key, val);\n\t\t\t}\n\t\t\tf.both = function(err, ok){\n\t\t\t\tDBG && (DBG.wfd = +new Date);\n\t\t\t\tif(b){ cb(err || b); return }\n\t\t\t\tif(a){ cb(err, ok); return }\n\t\t\t\ta = true;\n\t\t\t\tb = err;\n\t\t\t}\n\t\t\tf.each = function(val, key, k, pre){\n\t\t\t\tif(u !== val){ f.count++ }\n\t\t\t\tif(opt.max <= (val||'').length){ return cb(\"Data too big!\"), true }\n\t\t\t\tvar enc = Radisk.encode(pre.length) +'#'+ Radisk.encode(k) + (u === val? '' : ':'+ Radisk.encode(val)) +'\\n';\n\t\t\t\tif((opt.chunk < f.text.length + enc.length) && (1 < f.count) && !o.force){\n\t\t\t\t\treturn f.split();\n\t\t\t\t}\n\t\t\t\tf.text += enc;\n\t\t\t}\n\t\t\t//console.only.i && console.log('writing');\n\t\t\tif(opt.jsonify){ r.write.jsonify(f, rad, cb, o, DBG); return } // temporary testing idea\n\t\t\tif(!Radix.map(rad, f.each, true)){ f.write() }\n\t\t}\n\n\t\tr.write.jsonify = function(f, rad, cb, o, DBG){\n\t\t\tvar raw;\n\t\t\tvar S = +new Date;\n\t\t\tDBG && (DBG.w = S);\n\t\t\ttry{raw = JSON.stringify(rad.$);\n\t\t\t}catch(e){ cb(\"Cannot radisk!\"); return }\n\t\t\tDBG && (DBG.ws = +new Date);\n\t\t\tconsole.STAT && console.STAT(S, +new Date - S, \"rad stringified JSON\");\n\t\t\tif(opt.chunk < raw.length && !o.force){\n\t\t\t\tvar c = 0;\n\t\t\t\tRadix.map(rad, function(){\n\t\t\t\t\tif(c++){ return true } // more than 1 item\n\t\t\t\t});\n\t\t\t\tif(c > 1){\n\t\t\t\t\treturn f.split();\n\t\t\t\t}\n\t\t\t}\n\t\t\tf.text = raw;\n\t\t\tf.write();\n\t\t}\n\n\t\tr.range = function(tree, o){\n\t\t\tif(!tree || !o){ return }\n\t\t\tif(u === o.start && u === o.end){ return tree }\n\t\t\tif(atomic(tree)){ return tree }\n\t\t\tvar sub = Radix();\n\t\t\tRadix.map(tree, function(v,k){ sub(k,v) }, o); // ONLY PLACE THAT TAKES TREE, maybe reduce API for better perf?\n\t\t\treturn sub('');\n\t\t}\n\n\t\t;(function(){\n\t\t\tr.read = function(key, cb, o, DBG){\n\t\t\t\to = o || {};\n\t\t\t\tvar g = {key: key};\n\t\t\t\tg.find = function(file){ var tmp;\n\t\t\t\t\tg.file = file || (file = opt.code.from);\n\t\t\t\t\tDBG && (DBG = DBG[file] = DBG[file] || {});\n\t\t\t\t\tDBG && (DBG.rf = DBG.rf || +new Date);\n\t\t\t\t\tif(tmp = r.disk[g.file = file]){ g.check(u, tmp); return }\n\t\t\t\t\tr.parse(file, g.check, u, DBG);\n\t\t\t\t}\n\t\t\t\tg.get = function(err, disk, info){\n\t\t\t\t\tDBG && (DBG.rgl = +new Date);\n\t\t\t\t\tDBG && (DBG.rg = DBG.rg || +new Date);\n\t\t\t\t\tif(g.err = err || g.err){ cb(err); return }\n\t\t\t\t\tvar file = g.file = (disk||'').file || g.file;\n\t\t\t\t\tif(!disk && file !== opt.code.from){ // corrupt file?\n\t\t\t\t\t\tr.find.bad(file); // remove from dir list\n\t\t\t\t\t\tr.read(key, cb, o); // try again\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tdisk = r.disk[file] || (r.disk[file] = disk);\n\t\t\t\t\tif(!disk){ cb(file === opt.code.from? u : \"No file!\"); return }\n\t\t\t\t\tdisk.file || (disk.file = file);\n\t\t\t\t\tvar data = r.range(disk(key), o);\n\t\t\t\t\tDBG && (DBG.rr = +new Date);\n\t\t\t\t\to.unit = disk.unit;\n\t\t\t\t\to.chunks = (o.chunks || 0) + 1;\n\t\t\t\t\to.parsed = (o.parsed || 0) + ((info||'').parsed||(o.chunks*opt.chunk));\n\t\t\t\t\to.more = 1;\n\t\t\t\t\to.next = u;\n\t\t\t\t\tRadix.map(r.list, function next(v,f){\n\t\t\t\t\t\tif(!v || file === f){ return }\n\t\t\t\t\t\to.next = f;\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}, o.reverse? {reverse: 1, end: file} : {start: file});\n\t\t\t\t\tDBG && (DBG.rl = +new Date);\n\t\t\t\t\tif(!o.next){ o.more = 0 }\n\t\t\t\t\tif(o.next){\n\t\t\t\t\t\tif(!o.reverse && ((key < o.next && 0 != o.next.indexOf(key)) || (u !== o.end && (o.end || '\\uffff') < o.next))){ o.more = 0 }\n\t\t\t\t\t\tif(o.reverse && ((key > o.next && 0 != key.indexOf(o.next)) || ((u !== o.start && (o.start || '') > o.next && file <= o.start)))){ o.more = 0 }\n\t\t\t\t\t}\n\t\t\t\t\t//console.log(5, process.memoryUsage().heapUsed);\n\t\t\t\t\tif(!o.more){ cb(g.err, data, o); return }\n\t\t\t\t\tif(data){ cb(g.err, data, o) }\n\t\t\t\t\tif(o.parsed >= o.limit){ return }\n\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\tDBG && (DBG.rm = S);\n\t\t\t\t\tvar next = o.next;\n\t\t\t\t\ttimediate(function(){\n\t\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'rad more');\n\t\t\t\t\t\tr.parse(next, g.check);\n\t\t\t\t\t},0);\n\t\t\t\t}\n\t\t\t\tg.check = function(err, disk, info){\n\t\t\t\t\t//console.log(4, process.memoryUsage().heapUsed);\n\t\t\t\t\tg.get(err, disk, info);\n\t\t\t\t\tif(!disk || disk.check){ return } disk.check = 1;\n\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\t(info || (info = {})).file || (info.file = g.file);\n\t\t\t\t\tRadix.map(disk, function(val, key){\n\t\t\t\t\t\t// assume in memory for now, since both write/read already call r.find which will init it.\n\t\t\t\t\t\tr.find(key, function(file){\n\t\t\t\t\t\t\tif((file || (file = opt.code.from)) === info.file){ return }\n\t\t\t\t\t\t\tvar id = (''+Math.random()).slice(-3);\n\t\t\t\t\t\t\tpuff(function(){\n\t\t\t\t\t\t\tr.save(key, val, function ack(err, ok){\n\t\t\t\t\t\t\t\tif(err){ r.save(key, val, ack); return } // ad infinitum???\n\t\t\t\t\t\t\t\t// TODO: NOTE!!! Mislocated data could be because of a synchronous `put` from the `g.get(` other than perf shouldn't we do the check first before acking?\n\t\t\t\t\t\t\t\tconsole.STAT && console.STAT(\"MISLOCATED DATA CORRECTED\", id, ename(key), ename(info.file), ename(file));\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t},0);\n\t\t\t\t\t\t})\n\t\t\t\t\t});\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, \"rad check\");\n\t\t\t\t}\n\t\t\t\tr.find(key || (o.reverse? (o.end||'') : (o.start||'')), g.find); \n\t\t\t}\n\t\t\tfunction rev(a,b){ return b }\n\t\t\tvar revo = {reverse: true};\n\t\t}());\n\n\t\t;(function(){\n\t\t\t/*\n\t\t\t\tLet us start by assuming we are the only process that is\n\t\t\t\tchanging the directory or bucket. Not because we do not want\n\t\t\t\tto be multi-process/machine, but because we want to experiment\n\t\t\t\twith how much performance and scale we can get out of only one.\n\t\t\t\tThen we can work on the harder problem of being multi-process.\n\t\t\t*/\n\t\t\tvar RPC = 0;\n\t\t\tvar Q = {}, s = String.fromCharCode(31);\n\t\t\tr.parse = function(file, cb, raw, DBG){ var q;\n\t\t\t\tif(!file){ return cb(); }\n\t\t\t\tif(q = Q[file]){ q.push(cb); return } q = Q[file] = [cb];\n\t\t\t\tvar p = function Parse(){}, info = {file: file};\n\t\t\t\t(p.disk = Radix()).file = file;\n\t\t\t\tp.read = function(err, data){ var tmp;\n\t\t\t\t\tDBG && (DBG.rpg = +new Date);\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'read disk', JSON.stringify(file), ++RPC, 'total all parses.');\n\t\t\t\t\t//console.log(2, process.memoryUsage().heapUsed);\n\t\t\t\t\tif((p.err = err) || (p.not = !data)){\n\t\t\t\t\t\tdelete Q[file];\n\t\t\t\t\t\tp.map(q, p.ack);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif('string' !== typeof data){\n\t\t\t\t\t\ttry{\n\t\t\t\t\t\t\tif(opt.max <= data.length){\n\t\t\t\t\t\t\t\tp.err = \"Chunk too big!\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdata = data.toString(); // If it crashes, it crashes here. How!?? We check size first!\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}catch(e){ p.err = e }\n\t\t\t\t\t\tif(p.err){\n\t\t\t\t\t\t\tdelete Q[file];\n\t\t\t\t\t\t\tp.map(q, p.ack);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tinfo.parsed = data.length;\n\t\t\t\t\tDBG && (DBG.rpl = info.parsed);\n\t\t\t\t\tDBG && (DBG.rpa = q.length);\n\t\t\t\t\tS = +new Date;\n\t\t\t\t\tif(!(opt.jsonify || '{' === data[0])){\n\t\t\t\t\t\tp.radec(err, data);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tparse(data, function(err, tree){\n\t\t\t\t\t\t//console.log(3, process.memoryUsage().heapUsed);\n\t\t\t\t\t\tif(!err){\n\t\t\t\t\t\t\tdelete Q[file];\n\t\t\t\t\t\t\tp.disk.$ = tree;\n\t\t\t\t\t\t\tconsole.STAT && (ST = +new Date - S) > 9 && console.STAT(S, ST, 'rad parsed JSON');\n\t\t\t\t\t\t\tDBG && (DBG.rpd = +new Date);\n\t\t\t\t\t\t\tp.map(q, p.ack); // hmmm, v8 profiler can't see into this cause of try/catch?\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif('{' === data[0]){\n\t\t\t\t\t\t\tdelete Q[file];\n\t\t\t\t\t\t\tp.err = tmp || \"JSON error!\";\n\t\t\t\t\t\t\tp.map(q, p.ack);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.radec(err, data);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tp.map = function(){ // switch to setTimeout.each now?\n\t\t\t\t\tif(!q || !q.length){ return }\n\t\t\t\t\t//var i = 0, l = q.length, ack;\n\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\tvar err = p.err, data = p.not? u : p.disk;\n\t\t\t\t\tvar i = 0, ack; while(i < 9 && (ack = q[i++])){ ack(err, data, info) } // too much?\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'rad packs', ename(file));\n\t\t\t\t\tconsole.STAT && console.STAT(S, i, 'rad packs #', ename(file)); \n\t\t\t\t\tif(!(q = q.slice(i)).length){ return }\n\t\t\t\t\tpuff(p.map, 0);\n\t\t\t\t}\n\t\t\t\tp.ack = function(cb){\n\t\t\t\t\tif(!cb){ return }\n\t\t\t\t\tif(p.err || p.not){\n\t\t\t\t\t\tcb(p.err, u, info);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcb(u, p.disk, info);\n\t\t\t\t}\n\t\t\t\tp.radec = function(err, data){\n\t\t\t\t\tdelete Q[file];\n\t\t\t\t\tS = +new Date;\n\t\t\t\t\tvar tmp = p.split(data), pre = [], i, k, v;\n\t\t\t\t\tif(!tmp || 0 !== tmp[1]){\n\t\t\t\t\t\tp.err = \"File '\"+file+\"' does not have root radix! \";\n\t\t\t\t\t\tp.map(q, p.ack);\n\t\t\t\t\t\treturn; \n\t\t\t\t\t}\n\t\t\t\t\twhile(tmp){\n\t\t\t\t\t\tk = v = u;\n\t\t\t\t\t\ti = tmp[1];\n\t\t\t\t\t\ttmp = p.split(tmp[2])||'';\n\t\t\t\t\t\tif('#' == tmp[0]){\n\t\t\t\t\t\t\tk = tmp[1];\n\t\t\t\t\t\t\tpre = pre.slice(0,i);\n\t\t\t\t\t\t\tif(i <= pre.length){\n\t\t\t\t\t\t\t\tpre.push(k);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttmp = p.split(tmp[2])||'';\n\t\t\t\t\t\tif('\\n' == tmp[0]){ continue }\n\t\t\t\t\t\tif('=' == tmp[0] || ':' == tmp[0]){ v = tmp[1] }\n\t\t\t\t\t\tif(u !== k && u !== v){ p.disk(pre.join(''), v) }\n\t\t\t\t\t\ttmp = p.split(tmp[2]);\n\t\t\t\t\t}\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'parsed RAD');\n\t\t\t\t\tp.map(q, p.ack);\n\t\t\t\t};\n\t\t\t\tp.split = function(t){\n\t\t\t\t\tif(!t){ return }\n\t\t\t\t\tvar l = [], o = {}, i = -1, a = '', b, c;\n\t\t\t\t\ti = t.indexOf(s);\n\t\t\t\t\tif(!t[i]){ return }\n\t\t\t\t\ta = t.slice(0, i);\n\t\t\t\t\tl[0] = a;\n\t\t\t\t\tl[1] = b = Radisk.decode(t.slice(i), o);\n\t\t\t\t\tl[2] = t.slice(i + o.i);\n\t\t\t\t\treturn l;\n\t\t\t\t}\n\t\t\t\tif(r.disk){ raw || (raw = (r.disk[file]||'').raw) }\n\t\t\t\tvar S = +new Date, SM, SL;\n\t\t\t\tDBG && (DBG.rp = S);\n\t\t\t\tif(raw){ return puff(function(){ p.read(u, raw) }, 0) }\n\t\t\t\topt.store.get(ename(file), p.read);\n\t\t\t\t// TODO: What if memory disk gets filled with updates, and we get an old one back?\n\t\t\t}\n\t\t}());\n\n\t\t;(function(){\n\t\t\tvar dir, f = String.fromCharCode(28), Q;\n\t\t\tr.find = function(key, cb){\n\t\t\t\tif(!dir){\n\t\t\t\t\tif(Q){ Q.push([key, cb]); return } Q = [[key, cb]];\n\t\t\t\t\tr.parse(f, init);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tRadix.map(r.list = dir, function(val, key){\n\t\t\t\t\tif(!val){ return }\n\t\t\t\t\treturn cb(key) || true;\n\t\t\t\t}, {reverse: 1, end: key}) || cb(opt.code.from);\n\t\t\t}\n\t\t\tr.find.add = function(file, cb){\n\t\t\t\tvar has = dir(file);\n\t\t\t\tif(has || file === f){ cb(u, 1); return }\n\t\t\t\tdir(file, 1);\n\t\t\t\tcb.found = (cb.found || 0) + 1;\n\t\t\t\tr.write(f, dir, function(err, ok){\n\t\t\t\t\tif(err){ cb(err); return }\n\t\t\t\t\tcb.found = (cb.found || 0) - 1;\n\t\t\t\t\tif(0 !== cb.found){ return }\n\t\t\t\t\tcb(u, 1);\n\t\t\t\t}, true);\n\t\t\t}\n\t\t\tr.find.bad = function(file, cb){\n\t\t\t\tdir(file, 0);\n\t\t\t\tr.write(f, dir, cb||noop);\n\t\t\t}\n\t\t\tfunction init(err, disk){\n\t\t\t\tif(err){\n\t\t\t\t\topt.log('list', err);\n\t\t\t\t\tsetTimeout(function(){ r.parse(f, init) }, 1000);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(disk){ drain(disk); return }\n\t\t\t\tdir = dir || disk || Radix();\n\t\t\t\tif(!opt.store.list){ drain(dir); return }\n\t\t\t\t// import directory.\n\t\t\t\topt.store.list(function(file){\n\t\t\t\t\tif(!file){ drain(dir); return }\n\t\t\t\t\tr.find.add(file, noop);\n\t\t\t\t});\n\t\t\t}\n\t\t\tfunction drain(rad, tmp){\n\t\t\t\tdir = dir || rad;\n\t\t\t\tdir.file = f;\n\t\t\t\ttmp = Q; Q = null;\n\t\t\t\tmap(tmp, function(arg){\n\t\t\t\t\tr.find(arg[0], arg[1]);\n\t\t\t\t});\n\t\t\t}\n\t\t}());\n\n\t\ttry{ !Gun.window && require('./radmigtmp')(r) }catch(e){}\n\n\t\tvar noop = function(){}, RAD, u;\n\t\tRadisk.has[opt.file] = r;\n\t\treturn r;\n\t}\n\n\t;(function(){\n\t\tvar _ = String.fromCharCode(31), u;\n\t\tRadisk.encode = function(d, o, s){ s = s || _;\n\t\t\tvar t = s, tmp;\n\t\t\tif(typeof d == 'string'){\n\t\t\t\tvar i = d.indexOf(s);\n\t\t\t\twhile(i != -1){ t += s; i = d.indexOf(s, i+1) }\n\t\t\t\treturn t + '\"' + d + s;\n\t\t\t} else\n\t\t\tif(d && d['#'] && 1 == Object.keys(d).length){\n\t\t\t\treturn t + '#' + tmp + t;\n\t\t\t} else\n\t\t\tif('number' == typeof d){\n\t\t\t\treturn t + '+' + (d||0) + t;\n\t\t\t} else\n\t\t\tif(null === d){\n\t\t\t\treturn t + ' ' + t;\n\t\t\t} else\n\t\t\tif(true === d){\n\t\t\t\treturn t + '+' + t;\n\t\t\t} else\n\t\t\tif(false === d){\n\t\t\t\treturn t + '-' + t;\n\t\t\t}// else\n\t\t\t//if(binary){}\n\t\t}\n\t\tRadisk.decode = function(t, o, s){ s = s || _;\n\t\t\tvar d = '', i = -1, n = 0, c, p;\n\t\t\tif(s !== t[0]){ return }\n\t\t\twhile(s === t[++i]){ ++n }\n\t\t\tp = t[c = n] || true;\n\t\t\twhile(--n >= 0){ i = t.indexOf(s, i+1) }\n\t\t\tif(i == -1){ i = t.length }\n\t\t\td = t.slice(c+1, i);\n\t\t\tif(o){ o.i = i+1 }\n\t\t\tif('\"' === p){\n\t\t\t\treturn d;\n\t\t\t} else\n\t\t\tif('#' === p){\n\t\t\t\treturn {'#':d};\n\t\t\t} else\n\t\t\tif('+' === p){\n\t\t\t\tif(0 === d.length){\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn parseFloat(d);\n\t\t\t} else\n\t\t\tif(' ' === p){\n\t\t\t\treturn null;\n\t\t\t} else\n\t\t\tif('-' === p){\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}());\n\n\tvar Gun = (typeof window !== \"undefined\" && window.Gun)? window.Gun : require('../gun');\n\tvar Radix = (typeof window !== \"undefined\" && window.Radix)? window.Radix : require('./radix');\n\n\tRadisk.Radix = Radix;\n\t((name, exports) => {\n\t\ttry { module.exports = exports } catch (e) { }\n\t\tif (typeof window !== \"undefined\") {\n\t\t\twindow[name] = window[name]||exports;\n\t\t}\n\t})(\"Radisk\", Radisk);\n\n}());"
  },
  {
    "path": "lib/radisk2.js",
    "content": ";(function(){\n\tconsole.log(\"RADISK 2!!!!\");\n\n\tfunction Radisk(opt){\n\n\t\topt = opt || {};\n\t\topt.log = opt.log || console.log;\n\t\topt.file = String(opt.file || 'radata');\n\t\tvar has = (Radisk.has || (Radisk.has = {}))[opt.file];\n\t\tif(has){ return has }\n\n\t\topt.pack = opt.pack || (opt.memory? (opt.memory * 1000 * 1000) : 1399000000) * 0.3; // max_old_space_size defaults to 1400 MB.\n\t\topt.until = opt.until || opt.wait || 250;\n\t\topt.batch = opt.batch || (10 * 1000);\n\t\topt.chunk = opt.chunk || (1024 * 1024 * 1); // 1MB\n\t\topt.code = opt.code || {};\n\t\topt.code.from = opt.code.from || '!';\n\t\t//opt.jsonify = true; // TODO: REMOVE!!!!\n\n\t\tfunction ename(t){ return encodeURIComponent(t).replace(/\\*/g, '%2A') }\n\t\tfunction atomic(v){ return u !== v && (!v || 'object' != typeof v) }\n\t\tvar map = Gun.obj.map;\n\t\tvar LOG = false;\n\n\t\tif(!opt.store){\n\t\t\treturn opt.log(\"ERROR: Radisk needs `opt.store` interface with `{get: fn, put: fn (, list: fn)}`!\");\n\t\t}\n\t\tif(!opt.store.put){\n\t\t\treturn opt.log(\"ERROR: Radisk needs `store.put` interface with `(file, data, cb)`!\");\n\t\t}\n\t\tif(!opt.store.get){\n\t\t\treturn opt.log(\"ERROR: Radisk needs `store.get` interface with `(file, cb)`!\");\n\t\t}\n\t\tif(!opt.store.list){\n\t\t\t//opt.log(\"WARNING: `store.list` interface might be needed!\");\n\t\t}\n\n\t\t/*\n\t\t\tAny and all storage adapters should...\n\t\t\t1. Because writing to disk takes time, we should batch data to disk. This improves performance, and reduces potential disk corruption.\n\t\t\t2. If a batch exceeds a certain number of writes, we should immediately write to disk when physically possible. This caps total performance, but reduces potential loss.\n\t\t*/\n\t\tvar r = function(key, val, cb){\n\t\t\tkey = ''+key;\n\t\t\tif(val instanceof Function){\n\t\t\t\tvar o = cb || {};\n\t\t\t\tcb = val;\n\t\t\t\tval = r.batch(key);\n\t\t\t\tif(u !== val){\n\t\t\t\t\tcb(u, r.range(val, o), o);\n\t\t\t\t\tif(atomic(val)){ return }\n\t\t\t\t\t// if a node is requested and some of it is cached... the other parts might not be.\n\t\t\t\t}\n\t\t\t\tif(r.thrash.at){\n\t\t\t\t\tval = r.thrash.at(key);\n\t\t\t\t\tif(u !== val){\n\t\t\t\t\t\tcb(u, r.range(val, o), o);\n\t\t\t\t\t\tif(atomic(val)){ cb(u, val, o); return }\n\t\t\t\t\t\t// if a node is requested and some of it is cached... the other parts might not be.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn r.read(key, cb, o);\n\t\t\t}\n\t\t\tr.batch(key, val);\n\t\t\tif(cb){ r.batch.acks.push(cb) }\n\t\t\tif(++r.batch.ed >= opt.batch){ return r.thrash() } // (2)\n\t\t\tif(r.batch.to){ return }\n\t\t\t//clearTimeout(r.batch.to); // (1) // THIS LINE IS EVIL! NEVER USE IT! ALSO NEVER DELETE THIS SO WE NEVER MAKE THE SAME MISTAKE AGAIN!\n\t\t\tr.batch.to = setTimeout(r.thrash, opt.until || 1);\n\t\t}\n\n\t\tr.batch = Radix();\n\t\tr.batch.acks = [];\n\t\tr.batch.ed = 0;\n\n\t\tr.thrash = function(){\n\t\t\tvar thrash = r.thrash;\n\t\t\tif(thrash.ing){ return thrash.more = true }\n\t\t\tthrash.more = false;\n\t\t\tthrash.ing = true;\n\t\t\tvar batch = thrash.at = r.batch, i = 0;\n\t\t\tclearTimeout(r.batch.to);\n\t\t\tr.batch = null;\n\t\t\tr.batch = Radix();\n\t\t\tr.batch.acks = [];\n\t\t\tr.batch.ed = 0;\n\t\t\t//var id = Gun.text.random(2), S = (+new Date); console.log(\"<<<<<<<<<<<<\", id);\n\t\t\tr.save(batch, function(err, ok){\n\t\t\t\tif(++i > 1){ opt.log('RAD ERR: Radisk has callbacked multiple times, please report this as a BUG at github.com/amark/gun/issues ! ' + i); return }\n\t\t\t\tif(err){ opt.log('err', err) }\n\t\t\t\t//console.log(\">>>>>>>>>>>>\", id, ((+new Date) - S), batch.acks.length);\n\t\t\t\tmap(batch.acks, function(cb){ cb(err, ok) });\n\t\t\t\tthrash.at = null;\n\t\t\t\tthrash.ing = false;\n\t\t\t\tif(thrash.more){ thrash() }\n\t\t\t});\n\t\t}\n\n\t\t/*\n\t\t\t1. Find the first radix item in memory.\n\t\t\t2. Use that as the starting index in the directory of files.\n\t\t\t3. Find the first file that is lexically larger than it,\n\t\t\t4. Read the previous file to that into memory\n\t\t\t5. Scan through the in memory radix for all values lexically less than the limit.\n\t\t\t6. Merge and write all of those to the in-memory file and back to disk.\n\t\t\t7. If file too large, split. More details needed here.\n\t\t*/\n\t\tr.save = function(rad, cb){\n\t\t\tvar s = function Span(){};\n\t\t\ts.find = function(tree, key){\n\t\t\t\tif(key < s.start){ return }\n\t\t\t\ts.start = key;\n\t\t\t\tr.list(s.lex);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\ts.lex = function(file){\n\t\t\t\tfile = (u === file)? u : decodeURIComponent(file);\n\t\t\t\tif(!file || file > s.start){\n\t\t\t\t\ts.mix(s.file || opt.code.from, s.start, s.end = file);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\ts.file = file;\n\t\t\t}\n\t\t\ts.mix = function(file, start, end){\n\t\t\t\ts.start = s.end = s.file = u;\n\t\t\t\tr.parse(file, function(err, disk){\n\t\t\t\t\tif(err){ return cb(err) }\n\t\t\t\t\tdisk = disk || Radix();\n\t\t\t\t\tRadix.map(rad, function(val, key){\n\t\t\t\t\t\tif(key < start){ return }\n\t\t\t\t\t\tif(end && end < key){ return s.start = key }\n\t\t\t\t\t\t// PLUGIN: consider adding HAM as an extra layer of protection\n\t\t\t\t\t\tdisk(key, val); // merge batch[key] -> disk[key]\n\t\t\t\t\t});\n\t\t\t\t\tr.write(file, disk, s.next);\n\t\t\t\t});\n\t\t\t}\n\t\t\ts.next = function(err, ok){\n\t\t\t\tif(s.err = err){ return cb(err) }\n\t\t\t\tif(s.start){ return Radix.map(rad, s.find) }\n\t\t\t\tcb(err, ok);\n\t\t\t}\n\t\t\tRadix.map(rad, s.find);\n\t\t}\n\n\t\t/*\n\t\t\tAny storage engine at some point will have to do a read in order to write.\n\t\t\tThis is true of even systems that use an append only log, if they support updates.\n\t\t\tTherefore it is unavoidable that a read will have to happen,\n\t\t\tthe question is just how long you delay it.\n\t\t*/\n\t\tr.write = function(file, rad, cb, o){\n\t\t\to = ('object' == typeof o)? o : {force: o};\n\t\t\tvar f = function Fractal(){};\n\t\t\tf.text = '';\n\t\t\tf.count = 0;\n\t\t\tf.file = file;\n\t\t\tf.each = function(val, key, k, pre){\n\t\t\t\t//console.log(\"RAD:::\", JSON.stringify([val, key, k, pre]));\n\t\t\t\tif(u !== val){ f.count++ }\n\t\t\t\tif(opt.pack <= (val||'').length){ return cb(\"Record too big!\"), true }\n\t\t\t\tvar enc = Radisk.encode(pre.length) +'#'+ Radisk.encode(k) + (u === val? '' : ':'+ Radisk.encode(val)) +'\\n';\n\t\t\t\tif((opt.chunk < f.text.length + enc.length) && (1 < f.count) && !o.force){\n\t\t\t\t\tf.text = '';\n\t\t\t\t\tf.limit = Math.ceil(f.count/2);\n\t\t\t\t\tf.count = 0;\n\t\t\t\t\tf.sub = Radix();\n\t\t\t\t\tRadix.map(rad, f.slice);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tf.text += enc;\n\t\t\t}\n\t\t\tf.write = function(){\n\t\t\t\tvar tmp = ename(file);\n\t\t\t\tvar start; LOG && (start = (+new Date)); // comment this out!\n\t\t\t\topt.store.put(tmp, f.text, function(err){\n\t\t\t\t\tLOG && console.log(\"wrote JSON in\", (+new Date) - start); // comment this out!\n\t\t\t\t\tif(err){ return cb(err) }\n\t\t\t\t\tr.list.add(tmp, cb);\n\t\t\t\t});\n\t\t\t}\n\t\t\tf.slice = function(val, key){\n\t\t\t\tif(key < f.file){ return }\n\t\t\t\tif(f.limit < (++f.count)){\n\t\t\t\t\tvar name = f.file;\n\t\t\t\t\tf.file = key;\n\t\t\t\t\tf.count = 0;\n\t\t\t\t\tr.write(name, f.sub, f.next, o);\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tf.sub(key, val);\n\t\t\t}\n\t\t\tf.next = function(err){\n\t\t\t\tif(err){ return cb(err) }\n\t\t\t\tf.sub = Radix();\n\t\t\t\tif(!Radix.map(rad, f.slice)){\n\t\t\t\t\tr.write(f.file, f.sub, cb, o);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(opt.jsonify){ return r.write.jsonify(f, file, rad, cb, o) } // temporary testing idea\n\t\t\tif(!Radix.map(rad, f.each, true)){ f.write() }\n\t\t}\n\n\t\tr.write.jsonify = function(f, file, rad, cb, o){\n\t\t\tvar raw;\n\t\t\tvar start; LOG && (start = (+new Date)); // comment this out!\n\t\t\ttry{raw = JSON.stringify(rad.$);\n\t\t\t}catch(e){ return cb(\"Record too big!\") }\n\t\t\tLOG && console.log(\"stringified JSON in\", (+new Date) - start); // comment this out!\n\t\t\tif(opt.chunk < raw.length && !o.force){\n\t\t\t\tif(Radix.map(rad, f.each, true)){ return }\n\t\t\t}\n\t\t\tf.text = raw;\n\t\t\tf.write();\n\t\t}\n\n\t\tr.range = function(tree, o){\n\t\t\tif(!tree || !o){ return }\n\t\t\tif(u === o.start && u === o.end){ return tree }\n\t\t\tif(atomic(tree)){ return tree }\n\t\t\tvar sub = Radix();\n\t\t\tRadix.map(tree, function(v,k){\n\t\t\t\tsub(k,v);\n\t\t\t}, o)\n\t\t\treturn sub('');\n\t\t}\n\n\t\t;(function(){\n\t\t\tvar Q = {};\n\t\t\tr.read = function(key, cb, o){\n\t\t\t\to = o || {};\n\t\t\t\tif(RAD && !o.next){ // cache\n\t\t\t\t\tvar val = RAD(key);\n\t\t\t\t\t//if(u !== val){\n\t\t\t\t\t\t//cb(u, val, o);\n\t\t\t\t\t\tif(atomic(val)){ cb(u, val, o); return }\n\t\t\t\t\t\t// if a node is requested and some of it is cached... the other parts might not be.\n\t\t\t\t\t//}\n\t\t\t\t}\n\t\t\t\to.span = (u !== o.start) || (u !== o.end);\n\t\t\t\tvar g = function Get(){};\n\t\t\t\tg.lex = function(file){ var tmp;\n\t\t\t\t\tfile = (u === file)? u : decodeURIComponent(file);\n\t\t\t\t\ttmp = o.next || key || (o.reverse? o.end || '\\uffff' : o.start || '');\n\t\t\t\t\tif(!file || (o.reverse? file < tmp : file > tmp)){\n\t\t\t\t\t\tif(o.next || o.reverse){ g.file = file }\n\t\t\t\t\t\tif(tmp = Q[g.file]){\n\t\t\t\t\t\t\ttmp.push({key: key, ack: cb, file: g.file, opt: o});\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tQ[g.file] = [{key: key, ack: cb, file: g.file, opt: o}];\n\t\t\t\t\t\tif(!g.file){\n\t\t\t\t\t\t\tg.it(null, u, {});\n\t\t\t\t\t\t\treturn true; \n\t\t\t\t\t\t}\n\t\t\t\t\t\tr.parse(g.file, g.it);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\tg.file = file;\n\t\t\t\t}\n\t\t\t\tg.it = function(err, disk, info){\n\t\t\t\t\tif(g.err = err){ opt.log('err', err) }\n\t\t\t\t\tg.info = info;\n\t\t\t\t\tif(disk){ RAD = g.disk = disk }\n\t\t\t\t\tdisk = Q[g.file]; delete Q[g.file];\n\t\t\t\t\tmap(disk, g.ack);\n\t\t\t\t}\n\t\t\t\tg.ack = function(as){\n\t\t\t\t\tif(!as.ack){ return }\n\t\t\t\t\tvar tmp = as.key, o = as.opt, info = g.info, rad = g.disk || noop, data = r.range(rad(tmp), o), last = rad.last;\n\t\t\t\t\to.parsed = (o.parsed || 0) + (info.parsed||0);\n\t\t\t\t\to.chunks = (o.chunks || 0) + 1;\n\t\t\t\t\tif(!o.some){ o.some = (u !== data) }\n\t\t\t\t\tif(u !== data){ as.ack(g.err, data, o) }\n\t\t\t\t\telse if(!as.file){ !o.some && as.ack(g.err, u, o); return }\n\t\t\t\t\tif(!o.span){\n\t\t\t\t\t\tif(/*!last || */last === tmp){ !o.some && as.ack(g.err, u, o); return }\n\t\t\t\t\t\tif(last && last > tmp && 0 != last.indexOf(tmp)){ !o.some && as.ack(g.err, u, o); return }\n\t\t\t\t\t}\n\t\t\t\t\tif(o.some && o.parsed >= o.limit){ return }\n\t\t\t\t\to.next = as.file;\n\t\t\t\t\tr.read(tmp, as.ack, o);\n\t\t\t\t}\n\t\t\t\tif(o.reverse){ g.lex.reverse = true }\n\t\t\t\tr.list(g.lex);\n\t\t\t}\n\t\t}());\n\n\t\t;(function(){\n\t\t\t/*\n\t\t\t\tLet us start by assuming we are the only process that is\n\t\t\t\tchanging the directory or bucket. Not because we do not want\n\t\t\t\tto be multi-process/machine, but because we want to experiment\n\t\t\t\twith how much performance and scale we can get out of only one.\n\t\t\t\tThen we can work on the harder problem of being multi-process.\n\t\t\t*/\n\t\t\tvar Q = {}, s = String.fromCharCode(31);\n\t\t\tr.parse = function(file, cb, raw){ var q;\n\t\t\t\tif(q = Q[file]){ return q.push(cb) } q = Q[file] = [cb];\n\t\t\t\tvar p = function Parse(){}, info = {};\n\t\t\t\tp.disk = Radix();\n\t\t\t\tp.read = function(err, data){ var tmp;\n\t\t\t\t\tdelete Q[file];\n\t\t\t\t\tif((p.err = err) || (p.not = !data)){\n\t\t\t\t\t\treturn map(q, p.ack);\n\t\t\t\t\t}\n\t\t\t\t\tif(typeof data !== 'string'){\n\t\t\t\t\t\ttry{\n\t\t\t\t\t\t\tif(opt.pack <= data.length){\n\t\t\t\t\t\t\t\tp.err = \"Chunk too big!\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdata = data.toString(); // If it crashes, it crashes here. How!?? We check size first!\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}catch(e){ p.err = e }\n\t\t\t\t\t\tif(p.err){ return map(q, p.ack) }\n\t\t\t\t\t}\n\t\t\t\t\tinfo.parsed = data.length;\n\n\t\t\t\t\tvar start; LOG && (start = (+new Date)); // keep this commented out in production!\n\t\t\t\t\tif(opt.jsonify){ // temporary testing idea\n\t\t\t\t\t\ttry{\n\t\t\t\t\t\t\tvar json = JSON.parse(data);\n\t\t\t\t\t\t\tp.disk.$ = json;\n\t\t\t\t\t\t\tLOG && console.log('parsed JSON in', (+new Date) - start); // keep this commented out in production!\n\t\t\t\t\t\t\tmap(q, p.ack);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}catch(e){ tmp = e }\n\t\t\t\t\t\tif('{' === data[0]){\n\t\t\t\t\t\t\tp.err = tmp || \"JSON error!\";\n\t\t\t\t\t\t\treturn map(q, p.ack);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar start; LOG && (start = (+new Date)); // keep this commented out in production!\n\t\t\t\t\tvar tmp = p.split(data), pre = [], i, k, v, at, ats=[];\n\t\t\t\t\tif(!tmp || 0 !== tmp[1]){\n\t\t\t\t\t\tp.err = \"File '\"+file+\"' does not have root radix! \";\n\t\t\t\t\t\treturn map(q, p.ack);\n\t\t\t\t\t}\n\t\t\t\t\twhile(tmp){\n\t\t\t\t\t\tk = v = u;\n\t\t\t\t\t\ti = tmp[1];\n\t\t\t\t\t\ttmp = p.split(tmp[2])||'';\n\t\t\t\t\t\tif('#' == tmp[0]){\n\t\t\t\t\t\t\tk = tmp[1];\n\t\t\t\t\t\t\tpre = pre.slice(0,i);\n\t\t\t\t\t\t\tif(i <= pre.length){\n\t\t\t\t\t\t\t\tpre.push(k);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttmp = p.split(tmp[2])||'';\n\t\t\t\t\t\tif('\\n' == tmp[0]){\n\t\t\t\t\t\t\tat = ats[i] || p.disk.at;\n\t\t\t\t\t\t\tp.disk(k, u, at);\n\t\t\t\t\t\t\tats[i] = p.disk.at;\n\t\t\t\t\t\t\tats[i+1] = p.disk.at[k] || (p.disk.at[k]={});\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif('=' == tmp[0] || ':' == tmp[0]){ v = tmp[1] }\n\t\t\t\t\t\tif(u !== k && u !== v){\n// \t\t\t\t\t\t\tp.disk(pre.join(''), v)// mark's code\n\t\t\t\t\t\t\tat = ats[i];// || p.disk.at;\n\t\t\t\t\t\t\tp.disk(k, v, at);\n\t\t\t\t\t\t\tats[i] = p.disk.at;\n\t\t\t\t\t\t\tats[i+1] = p.disk.at[k];\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttmp = p.split(tmp[2]);\n\t\t\t\t\t}\n\t\t\t\t\tLOG && console.log('parsed JSON in', (+new Date) - start); // keep this commented out in production!\n\t\t\t\t\t//cb(err, p.disk);\n\t\t\t\t\tmap(q, p.ack);\n\t\t\t\t};\n\t\t\t\tp.split = function(t){\n\t\t\t\t\tif(!t){ return }\n\t\t\t\t\tvar l = [], o = {}, i = -1, a = '', b, c;\n\t\t\t\t\ti = t.indexOf(s);\n\t\t\t\t\tif(!t[i]){ return }\n\t\t\t\t\ta = t.slice(0, i);\n\t\t\t\t\tl[0] = a;\n\t\t\t\t\tl[1] = b = Radisk.decode(t.slice(i), o);\n\t\t\t\t\tl[2] = t.slice(i + o.i);\n\t\t\t\t\treturn l;\n\t\t\t\t}\n\t\t\t\tp.ack = function(cb){ \n\t\t\t\t\tif(!cb){ return }\n\t\t\t\t\tif(p.err || p.not){ return cb(p.err, u, info) }\n\t\t\t\t\tcb(u, p.disk, info);\n\t\t\t\t}\n\t\t\t\tif(raw){ return p.read(null, raw) }\n\t\t\t\topt.store.get(ename(file), p.read);\n\t\t\t}\n\t\t}());\n\n\t\t;(function(){\n\t\t\tvar dir, q, f = String.fromCharCode(28), ef = ename(f);\n\t\t\tr.list = function(cb){\n\t\t\t\tif(dir){\n\t\t\t\t\tvar tmp = {reverse: (cb.reverse)? 1 : 0};\n\t\t\t\t\tRadix.map(dir, function(val, key){\n\t\t\t\t\t\treturn cb(key);\n\t\t\t\t\t}, tmp) || cb();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(q){ return q.push(cb) } q = [cb];\n\t\t\t\tr.parse(f, r.list.init);\n\t\t\t}\n\t\t\tr.list.add = function(file, cb){\n\t\t\t\tvar has = dir(file);\n\t\t\t\tif(has || file === ef){\n\t\t\t\t\treturn cb(u, 1);\n\t\t\t\t}\n\t\t\t\tdir(file, true);\n\t\t\t\tcb.listed = (cb.listed || 0) + 1;\n\t\t\t\tr.write(f, dir, function(err, ok){\n\t\t\t\t\tif(err){ return cb(err) }\n\t\t\t\t\tcb.listed = (cb.listed || 0) - 1;\n\t\t\t\t\tif(cb.listed !== 0){ return }\n\t\t\t\t\tcb(u, 1);\n\t\t\t\t}, true);\n\t\t\t}\n\t\t\tr.list.init = function(err, disk){\n\t\t\t\tif(err){\n\t\t\t\t\topt.log('list', err);\n\t\t\t\t\tsetTimeout(function(){ r.parse(f, r.list.init) }, 1000);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(disk){\n\t\t\t\t\tr.list.drain(disk);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(!opt.store.list){\n\t\t\t\t\tr.list.drain(Radix());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// import directory.\n\t\t\t\topt.store.list(function(file){\n\t\t\t\t\tdir = dir || Radix();\n\t\t\t\t\tif(!file){ return r.list.drain(dir) }\n\t\t\t\t\tr.list.add(file, noop);\n\t\t\t\t});\n\t\t\t}\n\t\t\tr.list.drain = function(rad, tmp){\n\t\t\t\tr.list.dir = dir = rad;\n\t\t\t\ttmp = q; q = null;\n\t\t\t\tGun.list.map(tmp, function(cb){\n\t\t\t\t\tr.list(cb);\n\t\t\t\t});\n\t\t\t}\n\t\t}());\n\n\t\tvar noop = function(){}, RAD, u;\n\t\tRadisk.has[opt.file] = r;\n\t\treturn r;\n\t}\n\n\n\n\t;(function(){\n\t\tvar _ = String.fromCharCode(31), u;\n\t\tRadisk.encode = function(d, o, s){ s = s || _;\n\t\t\tvar t = s, tmp;\n\t\t\tif(typeof d == 'string'){\n\t\t\t\tvar i = d.indexOf(s);\n\t\t\t\twhile(i != -1){ t += s; i = d.indexOf(s, i+1) }\n\t\t\t\treturn t + '\"' + d + s;\n\t\t\t} else\n\t\t\tif(d && d['#'] && (tmp = Gun.val.link.is(d))){\n\t\t\t\treturn t + '#' + tmp + t;\n\t\t\t} else\n\t\t\tif(Gun.num.is(d)){\n\t\t\t\treturn t + '+' + (d||0) + t;\n\t\t\t} else\n\t\t\tif(null === d){\n\t\t\t\treturn t + ' ' + t;\n\t\t\t} else\n\t\t\tif(true === d){\n\t\t\t\treturn t + '+' + t;\n\t\t\t} else\n\t\t\tif(false === d){\n\t\t\t\treturn t + '-' + t;\n\t\t\t}// else\n\t\t\t//if(binary){}\n\t\t}\n\t\tRadisk.decode = function(t, o, s){ s = s || _;\n\t\t\tvar d = '', i = -1, n = 0, c, p;\n\t\t\tif(s !== t[0]){ return }\n\t\t\twhile(s === t[++i]){ ++n }\n\t\t\tp = t[c = n] || true;\n\t\t\twhile(--n >= 0){ i = t.indexOf(s, i+1) }\n\t\t\tif(i == -1){ i = t.length }\n\t\t\td = t.slice(c+1, i);\n\t\t\tif(o){ o.i = i+1 }\n\t\t\tif('\"' === p){\n\t\t\t\treturn d;\n\t\t\t} else\n\t\t\tif('#' === p){\n\t\t\t\treturn Gun.val.link.ify(d);\n\t\t\t} else\n\t\t\tif('+' === p){\n\t\t\t\tif(0 === d.length){\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn parseFloat(d);\n\t\t\t} else\n\t\t\tif(' ' === p){\n\t\t\t\treturn null;\n\t\t\t} else\n\t\t\tif('-' === p){\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}());\n\n\tif(typeof window !== \"undefined\"){\n\t  var Gun = window.Gun;\n\t  var Radix = window.Radix;\n\t  window.Radisk = Radisk;\n\t} else { \n\t  var Gun = require('../gun');\n\t\tvar Radix = require('./radix2');\n\t\ttry{ module.exports = Radisk }catch(e){}\n\t}\n\n\tRadisk.Radix = Radix;\n\n}());\n"
  },
  {
    "path": "lib/radix.d.ts",
    "content": "import {} from './radix'\ndeclare module './radix' {\n  export const Radix: IRadix;\n  export interface IRadix {}\n}\n\ndeclare global {\n  interface Window {\n    Radix: IRadix;\n  }\n}\n"
  },
  {
    "path": "lib/radix.js",
    "content": ";(function(){\n\n\tfunction Radix(){\n\t\tvar radix = function(key, val, t){\n\t\t\tradix.unit = 0;\n\t\t\tif(!t && u !== val){ \n\t\t\t\tradix.last = (''+key < radix.last)? radix.last : ''+key;\n\t\t\t\tdelete (radix.$||{})[_];\n\t\t\t}\n\t\t\tt = t || radix.$ || (radix.$ = {});\n\t\t\tif(!key && Object.keys(t).length){ return t }\n\t\t\tkey = ''+key;\n\t\t\tvar i = 0, l = key.length-1, k = key[i], at, tmp;\n\t\t\twhile(!(at = t[k]) && i < l){\n\t\t\t\tk += key[++i];\n\t\t\t}\n\t\t\tif(!at){\n\t\t\t\tif(!each(t, function(r, s){\n\t\t\t\t\tvar ii = 0, kk = '';\n\t\t\t\t\tif((s||'').length){ while(s[ii] == key[ii]){\n\t\t\t\t\t\tkk += s[ii++];\n\t\t\t\t\t} }\n\t\t\t\t\tif(kk){\n\t\t\t\t\t\tif(u === val){\n\t\t\t\t\t\t\tif(ii <= l){ return }\n\t\t\t\t\t\t\t(tmp || (tmp = {}))[s.slice(ii)] = r;\n\t\t\t\t\t\t\t//(tmp[_] = function $(){ $.sort = Object.keys(tmp).sort(); return $ }()); // get rid of this one, cause it is on read?\n\t\t\t\t\t\t\treturn r;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar __ = {};\n\t\t\t\t\t\t__[s.slice(ii)] = r;\n\t\t\t\t\t\tii = key.slice(ii);\n\t\t\t\t\t\t('' === ii)? (__[''] = val) : ((__[ii] = {})[''] = val);\n\t\t\t\t\t\t//(__[_] = function $(){ $.sort = Object.keys(__).sort(); return $ }());\n\t\t\t\t\t\tt[kk] = __;\n\t\t\t\t\t\tif(Radix.debug && 'undefined' === ''+kk){ console.log(0, kk); debugger }\n\t\t\t\t\t\tdelete t[s];\n\t\t\t\t\t\t//(t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }());\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t})){\n\t\t\t\t\tif(u === val){ return; }\n\t\t\t\t\t(t[k] || (t[k] = {}))[''] = val;\n\t\t\t\t\tif(Radix.debug && 'undefined' === ''+k){ console.log(1, k); debugger }\n\t\t\t\t\t//(t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }());\n\t\t\t\t}\n\t\t\t\tif(u === val){\n\t\t\t\t\treturn tmp;\n\t\t\t\t}\n\t\t\t} else \n\t\t\tif(i == l){\n\t\t\t\t//if(u === val){ return (u === (tmp = at['']))? at : tmp } // THIS CODE IS CORRECT, below is\n\t\t\t\tif(u === val){ return (u === (tmp = at['']))? at : ((radix.unit = 1) && tmp) } // temporary help??\n\t\t\t\tat[''] = val;\n\t\t\t\t//(at[_] = function $(){ $.sort = Object.keys(at).sort(); return $ }());\n\t\t\t} else {\n\t\t\t\tif(u !== val){ delete at[_] }\n\t\t\t\t//at && (at[_] = function $(){ $.sort = Object.keys(at).sort(); return $ }());\n\t\t\t\treturn radix(key.slice(++i), val, at || (at = {}));\n\t\t\t}\n\t\t}\n\t\treturn radix;\n\t};\n\n\tRadix.map = function rap(radix, cb, opt, pre){\n\t\ttry {\n\t\t\tpre = pre || []; // TODO: BUG: most out-of-memory crashes come from here.\n\t\t\tvar t = ('function' == typeof radix)? radix.$ || {} : radix;\n\t\t\t//!opt && console.log(\"WHAT IS T?\", JSON.stringify(t).length);\n\t\t\tif(!t){ return }\n\t\t\tif('string' == typeof t){ if(Radix.debug){ throw ['BUG:', radix, cb, opt, pre] } return; }\n\t\t\tvar keys = (t[_]||no).sort || (t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }()).sort, rev; // ONLY 17% of ops are pre-sorted!\n\t\t\t//var keys = Object.keys(t).sort();\n\t\t\topt = (true === opt)? {branch: true} : (opt || {});\n\t\t\tif(rev = opt.reverse){ keys = keys.slice(0).reverse() }\n\t\t\tvar start = opt.start, end = opt.end, END = '\\uffff';\n\t\t\tvar i = 0, l = keys.length;\n\t\t\tfor(;i < l; i++){ var key = keys[i], tree = t[key], tmp, p, pt;\n\t\t\t\tif(!tree || '' === key || _ === key || 'undefined' === key){ continue }\n\t\t\t\tp = pre.slice(0); p.push(key);\n\t\t\t\tpt = p.join('');\n\t\t\t\tif(u !== start && pt < (start||'').slice(0,pt.length)){ continue }\n\t\t\t\tif(u !== end && (end || END) < pt){ continue }\n\t\t\t\tif(rev){ // children must be checked first when going in reverse.\n\t\t\t\t\ttmp = rap(tree, cb, opt, p);\n\t\t\t\t\tif(u !== tmp){ return tmp }\n\t\t\t\t}\n\t\t\t\tif(u !== (tmp = tree[''])){\n\t\t\t\t\tvar yes = 1;\n\t\t\t\t\tif(u !== start && pt < (start||'')){ yes = 0 }\n\t\t\t\t\tif(u !== end && pt > (end || END)){ yes = 0 }\n\t\t\t\t\tif(yes){\n\t\t\t\t\t\ttmp = cb(tmp, pt, key, pre);\n\t\t\t\t\t\tif(u !== tmp){ return tmp }\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\tif(opt.branch){\n\t\t\t\t\ttmp = cb(u, pt, key, pre);\n\t\t\t\t\tif(u !== tmp){ return tmp }\n\t\t\t\t}\n\t\t\t\tpre = p;\n\t\t\t\tif(!rev){\n\t\t\t\t\ttmp = rap(tree, cb, opt, pre);\n\t\t\t\t\tif(u !== tmp){ return tmp }\n\t\t\t\t}\n\t\t\t\tpre.pop();\n\t\t\t}\n\t\t} catch (e) { console.error(e); }\n\t};\n\n\t(function(name, exports){\n\t\tif(typeof window !== \"undefined\"){\n\t\t\twindow[name] = window[name]||exports;\n\t\t} \n\t\ttry{ module.exports = exports }catch(e){}\n\t})(\"Radix\",Radix);\n\tvar each = Radix.object = function(o, f, r){\n\t\tfor(var k in o){\n\t\t\tif(!o.hasOwnProperty(k)){ continue }\n\t\t\tif((r = f(o[k], k)) !== u){ return r }\n\t\t}\n\t}, no = {}, u;\n\tvar _ = String.fromCharCode(24);\n\t\n}());\n"
  },
  {
    "path": "lib/radix2.js",
    "content": ";(function(){\n\n\tfunction Radix(){\n\t\tvar radix = function(key, val, t){\n\t\t\tkey = ''+key;\n\t\t\tif(!t && u !== val){ \n\t\t\t\tradix.last = (key < radix.last)? radix.last : key;\n\t\t\t\tdelete (radix.$||{})[_];\n\t\t\t}\n\t\t\tt = t || radix.$ || (radix.$ = {});\n\t\t\tif(!key && Object.keys(t).length){ return t }\n\t\t\tvar i = 0, l = key.length-1, k = key[i], at, tmp;\n\t\t\twhile(!(at = t[k]) && i < l){\n\t\t\t\tk += key[++i];\n\t\t\t}\n\t\t\tradix.at = t; /// caching to external access.\n\t\t\tif(!at){\n\t\t\t\tif(!map(t, function(r, s){\n\t\t\t\t\tvar ii = 0, kk = '';\n\t\t\t\t\tif((s||'').length){ while(s[ii] == key[ii]){\n\t\t\t\t\t\tkk += s[ii++];\n\t\t\t\t\t} }\n\t\t\t\t\tif(kk){\n\t\t\t\t\t\tif(u === val){\n\t\t\t\t\t\t\tif(ii <= l){ return }\n\t\t\t\t\t\t\treturn (tmp || (tmp = {}))[s.slice(ii)] = r;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar __ = {};\n\t\t\t\t\t\t__[s.slice(ii)] = r;\n\t\t\t\t\t\tii = key.slice(ii);\n\t\t\t\t\t\t('' === ii)? (__[''] = val) : ((__[ii] = {})[''] = val);\n\t\t\t\t\t\tt[kk] = __;\n\t\t\t\t\t\tdelete t[s];\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t})){\n\t\t\t\t\tif(u === val){ return; }\n\t\t\t\t\t(t[k] || (t[k] = {}))[''] = val;\n\t\t\t\t}\n\t\t\t\tif(u === val){\n\t\t\t\t\treturn tmp;\n\t\t\t\t}\n\t\t\t} else \n\t\t\tif(i == l){\n\t\t\t\tif(u === val){ return (u === (tmp = at['']))? at : tmp }\n\t\t\t\tat[''] = val;\n\t\t\t} else {\n\t\t\t\tif(u !== val){ delete at[_] }\n\t\t\t\treturn radix(key.slice(++i), val, at || (at = {}));\n\t\t\t}\n\t\t}\n\t\treturn radix;\n\t};\n\n\tRadix.map = function map(radix, cb, opt, pre){ pre = pre || [];\n\t\tvar t = ('function' == typeof radix)? radix.$ || {} : radix;\n\t\tif(!t){ return }\n\t\tvar keys = (t[_]||no).sort || (t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }()).sort;\n\t\t//var keys = Object.keys(t).sort();\n\t\topt = (true === opt)? {branch: true} : (opt || {});\n\t\tif(opt.reverse){ keys = keys.slice().reverse() }\n\t\tvar start = opt.start, end = opt.end;\n\t\tvar i = 0, l = keys.length;\n\t\tfor(;i < l; i++){ var key = keys[i], tree = t[key], tmp, p, pt;\n\t\t\tif(!tree || '' === key || _ === key){ continue }\n\t\t\tp = pre.slice(); p.push(key);\n\t\t\tpt = p.join('');\n\t\t\tif(u !== start && pt < (start||'').slice(0,pt.length)){ continue }\n\t\t\tif(u !== end && (end || '\\uffff') < pt){ continue }\n\t\t\tif(u !== (tmp = tree[''])){\n\t\t\t\ttmp = cb(tmp, pt, key, pre);\n\t\t\t\tif(u !== tmp){ return tmp }\n\t\t\t} else\n\t\t\tif(opt.branch){\n\t\t\t\ttmp = cb(u, pt, key, pre);\n\t\t\t\tif(u !== tmp){ return tmp }\n\t\t\t}\n\t\t\tpre = p;\n\t\t\ttmp = map(tree, cb, opt, pre);\n\t\t\tif(u !== tmp){ return tmp }\n\t\t\tpre.pop();\n\t\t}\n\t};\n\n\tObject.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) }\n\n\tif(typeof window !== \"undefined\"){\n\t  var Gun = window.Gun;\n\t  window.Radix = Radix;\n\t} else { \n\t  var Gun = require('../gun');\n\t\ttry{ module.exports = Radix }catch(e){}\n\t}\n\t\n\tvar map = Gun.obj.map, no = {}, u;\n\tvar _ = String.fromCharCode(24);\n\t\n}());\n"
  },
  {
    "path": "lib/radmigtmp.js",
    "content": "module.exports = function(r){\n\tvar Radix = require('./radix');\n\tr.find('a', function(){\n\t\tvar l = [];\n\t\tRadix.map(r.list, function(v,f){\n\t\t\tif(!(f.indexOf('%1B') + 1)){ return }\n\t\t\tif(!v){ return }\n\t\t\tl.push([f,v]);\n\t\t});\n\t\tif(l.length){\n\t\t\tconsole.log(\"\\n! ! ! WARNING ! ! !\\nRAD v0.2020.x has detected OLD v0.2019.x data & automatically migrating. Automatic migration will be turned OFF in future versions! If you are just developing/testing, we recommend you reset your data. Please contact us if you have any concerns.\\nThis message should only log once.\")\n\t\t}\n\t\tvar f, v;\n\t\tl.forEach(function(a){\n\t\t\tf = a[0]; v = a[1];\n\t\t\tr.list(decodeURIComponent(f), v);\n\t\t\tr.list(f, 0);\n\t\t});\n\t\tif(!f){ return }\n\t\tr.find.bad(f);\n\t})\n};"
  },
  {
    "path": "lib/ras.js",
    "content": "(function(){\n\n  /**\n  Radix AsyncStorage adapter\n  make sure to pass AsyncStorage instance in opt.AsyncStorage\n  example:\n  import AsyncStorage from 'react-native'\n  const store = Store({AsyncStorage})\n  const gun = new Gun({store,peers:[...]})\n  **/\n  function Store(opt){\n    opt = opt || {};\n    const store = function(){}\n    const as = opt.AsyncStorage;\n    store.put = function(key, data, cb)\n      { \n        as.setItem(''+key,data)\n          .then(_ => cb(null,1))\n          .then(_ => console.log(\"ok put\"))\n          .catch(_ => {\n            console.error(`failed saving to asyncstorage`,{key, data})\n            cb(null,0)\n          })\n      }\n\n    store.get = (key,cb) => {\n        as.getItem(''+key)\n          .then(data => cb(null,data))\n          .then(_ => console.log(\"ok get\"))\n          .catch(_ => {\n            console.error(`failed fetching from asyncstorage`,{key})\n            cb(null,0)\n          })\n      }\n    \n    return store;\n  }\n\n  module.exports = Store\n\n}());"
  },
  {
    "path": "lib/reboot.js",
    "content": ";(function(){\n\tvar exec = require('child_process').execSync;\n\tvar dir = __dirname, tmp;\n\n\ttry{exec(\"crontab -l\");\n\t}catch(e){tmp = e}\n\tif(0 > tmp.toString().indexOf('no')){ return }\n\n\ttry{tmp = exec('which node').toString();\n\t}catch(e){console.log(e);return}\n\n\ttry{tmp = exec('echo \"@reboot '+tmp+' '+dir+'/../examples/http.js\" > '+dir+'/reboot.cron');\n\t}catch(e){console.log(e);return}\n\n\ttry{tmp = exec('crontab '+dir+'/reboot.cron');\n\t}catch(e){console.log(e);return}\n\tconsole.log(tmp.toString());\n\n}());"
  },
  {
    "path": "lib/rfs.js",
    "content": "function Store(opt){\n\topt = opt || {};\n\topt.log = opt.log || console.log;\n\topt.file = String(opt.file || 'radata');\n\tvar fs = require('fs'), u;\n\n\tvar store = function Store(){};\n\tif(Store[opt.file]){\n\t\tconsole.log(\"Warning: reusing same fs store and options as 1st.\");\n\t\treturn Store[opt.file];\n\t}\n\tStore[opt.file] = store;\n\tvar puts = {};\n\n\t// TODO!!! ADD ZLIB INFLATE / DEFLATE COMPRESSION!\n\tstore.put = function(file, data, cb){\n\t\tvar random = Math.random().toString(36).slice(-3);\n\t\tputs[file] = {id: random, data: data};\n\t\tvar tmp = opt.file+'-'+file+'-'+random+'.tmp';\n\t\tfs.writeFile(tmp, data, function(err, ok){\n\t\t\tif(err){\n\t\t\t\tif(random === (puts[file]||'').id){ delete puts[file] }\n\t\t\t\treturn cb(err);\n\t\t\t}\n\t\t\tmove(tmp, opt.file+'/'+file, function(err, ok){\n\t\t\t\tif(random === (puts[file]||'').id){ delete puts[file] }\n\t\t\t\tcb(err, ok || !err);\n\t\t\t});\n\t\t});\n\t};\n\tstore.get = function(file, cb){ var tmp; // this took 3s+?\n\t\tif(tmp = puts[file]){ cb(u, tmp.data); return }\n\t\tfs.readFile(opt.file+'/'+file, function(err, data){\n\t\t\tif(err){\n\t\t\t\tif('ENOENT' === (err.code||'').toUpperCase()){\n\t\t\t\t\treturn cb();\n\t\t\t\t}\n\t\t\t\topt.log(\"ERROR:\", err);\n\t\t\t}\n\t\t\tcb(err, data);\n\t\t});\n\t};\n\n\tif(!fs.existsSync(opt.file)){ fs.mkdirSync(opt.file) }\n\n\tfunction move(oldPath, newPath, cb) {\n\t\tfs.rename(oldPath, newPath, function (err) {\n\t\t\tif (err) {\n\t\t\t\tif (err.code === 'EXDEV') {\n\t\t\t\t\tvar readStream = fs.createReadStream(oldPath);\n\t\t\t\t\tvar writeStream = fs.createWriteStream(newPath);\n\n\t\t\t\t\treadStream.on('error', cb);\n\t\t\t\t\twriteStream.on('error', cb);\n\n\t\t\t\t\treadStream.on('close', function () {\n\t\t\t\t\t\tfs.unlink(oldPath, cb);\n\t\t\t\t\t});\n\n\t\t\t\t\treadStream.pipe(writeStream);\n\t\t\t\t} else {\n\t\t\t\t\tcb(err);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcb();\n\t\t\t}\n\t\t});\n\t};\n\n\tstore.list = function(cb, match, params, cbs){\n\t\tvar dir = fs.readdirSync(opt.file);\n\t\tdir.forEach(function(file){\n\t\t\tcb(file);\n\t\t})\n\t\tcb();\n\t};\n\t\n\treturn store;\n}\n\nvar Gun = (typeof window !== \"undefined\" && window.Gun) ? window.Gun : require('../gun');\nGun.on('create', function(root){\n\tthis.to.next(root);\n\tvar opt = root.opt;\n\tif(opt.rfs === false){ return }\n\topt.store = opt.store || ((!Gun.window || opt.rfs === true) && Store(opt));\n});\n\nmodule.exports = Store;"
  },
  {
    "path": "lib/rfsmix.js",
    "content": "module.exports = function(opt, store){\n\tvar rfs = require('./rfs')(opt);\n\tvar p = store.put;\n\tvar g = store.get;\n\tstore.put = function(file, data, cb){\n\t\tvar a, b, c = function(err, ok){\n\t\t\tif(b){ return cb(err || b) }\n\t\t\tif(a){ return cb(err, ok) }\n\t\t\ta = true;\n\t\t\tb = err;\n\t\t}\n\t\tp(file, data, c); // parallel\n\t\trfs.put(file, data, c); // parallel\n\t}\n\tstore.get = function(file, cb){\n\t\trfs.get(file, function(err, data){\n\t\t\t//console.log(\"rfs3 hijacked\", file);\n\t\t\tif(data){ return cb(err, data) }\n\t\t\tg(file, cb);\n\t\t});\n\t}\n\treturn store;\n}"
  },
  {
    "path": "lib/rindexed.d.ts",
    "content": "import {} from './rindexed'\ndeclare module './rindexed' {\n  export const Store: IRindexedDB;\n  export interface IRindexedDB {\n    indexedDB: IRindexedDB;\n    window: Window;\n  }\n}\n\ndeclare global {\n  interface Window {\n    RindexedDB: IRindexedDB;\n  }\n}\n"
  },
  {
    "path": "lib/rindexed.js",
    "content": ";(function(){\n/* // from @jabis\nif (navigator.storage && navigator.storage.estimate) {\n  const quota = await navigator.storage.estimate();\n  // quota.usage -> Number of bytes used.\n  // quota.quota -> Maximum number of bytes available.\n  const percentageUsed = (quota.usage / quota.quota) * 100;\n  console.log(`You've used ${percentageUsed}% of the available storage.`);\n  const remaining = quota.quota - quota.usage;\n  console.log(`You can write up to ${remaining} more bytes.`);\n}\n*/\n  function Store(opt){\n    opt = opt || {};\n    opt.file = String(opt.file || 'radata');\n    var store = Store[opt.file], db = null, u;\n\n    if(store){\n      console.log(\"Warning: reusing same IndexedDB store and options as 1st.\");\n      return Store[opt.file];\n    }\n    store = Store[opt.file] = function(){};\n\n    try{opt.indexedDB = opt.indexedDB || Store.indexedDB || indexedDB}catch(e){}\n    try{if(!opt.indexedDB || 'file:' == location.protocol){\n      var s = store.d || (store.d = {});\n      store.put = function(f, d, cb){ s[f] = d; setTimeout(function(){ cb(null, 1) },250) };\n      store.get = function(f, cb){ setTimeout(function(){ cb(null, s[f] || u) },5) };\n      console.log('Warning: No indexedDB exists to persist data to!');\n      return store;\n    }}catch(e){}\n    \n\n    store.start = function(){\n      var o = indexedDB.open(opt.file, 1);\n      o.onupgradeneeded = function(eve){ (eve.target.result).createObjectStore(opt.file) }\n      o.onsuccess = function(){ db = o.result }\n      o.onerror = function(eve){ console.log(eve||1); }\n    }; store.start();\n\n    store.put = function(key, data, cb){\n      if(!db){ setTimeout(function(){ store.put(key, data, cb) },1); return }\n      var tx = db.transaction([opt.file], 'readwrite');\n      var obj = tx.objectStore(opt.file);\n      var req = obj.put(data, ''+key);\n      req.onsuccess = obj.onsuccess = tx.onsuccess = function(){ cb(null, 1) }\n      req.onabort = obj.onabort = tx.onabort = function(eve){ cb(eve||'put.tx.abort') }\n      req.onerror = obj.onerror = tx.onerror = function(eve){ cb(eve||'put.tx.error') }\n    }\n\n    store.get = function(key, cb){\n      if(!db){ setTimeout(function(){ store.get(key, cb) },9); return }\n      var tx = db.transaction([opt.file], 'readonly');\n      var obj = tx.objectStore(opt.file);\n      var req = obj.get(''+key);\n      req.onsuccess = function(){ cb(null, req.result) }\n      req.onabort = function(eve){ cb(eve||4) }\n      req.onerror = function(eve){ cb(eve||5) }\n    }\n    setInterval(function(){ db && db.close(); db = null; store.start() }, 1000 * 15); // reset webkit bug?\n    return store;\n  }\n\n  if(typeof window !== \"undefined\"){\n    (Store.window = window).RindexedDB = Store;\n    Store.indexedDB = window.indexedDB; // safari bug\n  } else {\n    try{ module.exports = Store }catch(e){}\n  }\n\n  try{\n    var Gun = Store.window.Gun || require('../gun');\n    Gun.on('create', function(root){\n      this.to.next(root);\n      root.opt.store = root.opt.store || Store(root.opt);\n    });\n  }catch(e){}\n\n}());"
  },
  {
    "path": "lib/rls.js",
    "content": ";(function(){\n\n  function Store(opt){\n    opt = opt || {};\n    opt.file = String(opt.file || 'radata');\n    var store = function Store(){};\n\n    var ls = localStorage;\n    store.put = function(key, data, cb){ ls[''+key] = data; cb(null, 1) }\n    store.get = function(key, cb){ cb(null, ls[''+key]) }\n\n    return store;\n  }\n\n  if(typeof window !== \"undefined\"){\n    (Store.window = window).RlocalStorage = Store;\n  } else {\n    try{ module.exports = Store }catch(e){}\n  }\n\n  try{\n    var Gun = Store.window.Gun || require('../gun');\n    Gun.on('create', function(root){\n      this.to.next(root);\n      root.opt.store = root.opt.store || Store(root.opt);\n    });\n  }catch(e){}\n\n}());"
  },
  {
    "path": "lib/rmem.js",
    "content": "function Rmem(){\n  var opt = {}, store = {}, u;\n  opt.put = function(file, data, cb){\n  \t//setTimeout(function(){ // make async\n    store[file] = data;\n    cb(null, 1);\n    //}, 1);\n  };\n  opt.get = function(file, cb){\n    //setTimeout(function(){ // make async\n    var tmp = store[file] || u;\n    cb(null, tmp);\n    //}, 1);\n  };\n  return opt;\n}\n\nif(typeof window !== \"undefined\"){\n  window.Rmem = Rmem;\n} else {\n\ttry{ module.exports = Rmem }catch(e){}\n}"
  },
  {
    "path": "lib/role.js",
    "content": ";(function(){\n\n\tfunction resolve(chain){\n\t\t/*\n\t\t\tIf we say \"Spray paint all of Bob's friends' cat blue\",\n\t\t\tthe embedded question we might need to ask is:\n\t\t\tIf one of Bob's friends winds up unfriending him,\n\t\t\tAND has their cat die that they get a new cat,\n\t\t\tdo we want THAT cat painted blue?\n\t\t\tI believe the answer is NO.\n\t\t*/\n\t\t// soul.key=value\n\t\t// soul ???\n\t\t// stream -> soul.key ...\n\t\t// stream -> soul.key\n\t\t// if you have a dynamic map, and you want to \"process it\", you wind up waiting until at least 1 item exists, calling off, then calling each.\n\t\t// in this sense, resolve can only know it has processed each item once, but not whether it itself is done. and that is fair.\n\t\t// what about ops that read before writing like timegraph?\n\t\t//console.debug.i=1;console.log(\"----------------\");\n\t\t/*\ngun.get('a').get('b').put({\n  x: {\n    x1: {c: {d: {'yay':1}}},\n    x2: {c: {d: {'cake':1}}}\n  },\n  y: {\n    y1: {c: {d: {'foo':1}}},\n    y2: {c: {d: {'bar':1}}}\n  }\n});\n\t/*\n\t\tmap {10:{}, 5:{}} -> get link to load\n\t*/\n\t\t// FOR THIS CHAIN: Each item gets called 3 times.\n\t\tGun.debug=1;\n\t\t//return;\n\t\tchain = chain || gun.get('a').get('b').map().map().get('c').get('d').get(function(a,b,c,tmp){\n\t\t\t// a.gun._.soul || a.gun._.link;\n\t\t\ta.ID = a.ID || Gun.text.random(2);\n\t\t\tconsole.log('********', a.put || a);//, Gun.node.soul(a.put), a.gun._);//, a.gun.back(function back(_){_.get && (tmp || (tmp = [])).push(_.get);return _.back? undefined : tmp;})); \n\t\t\t//b.rid(a);\n\t\t});\n\t\tconsole.log(\"~~~~~~~~~~~~~~\");\n\t\twindow.chain = chain;\n\t}\n\t/*\n\t\tsync put: 5 node - 1 stop\n\t\tsync reload: 1 link 2 node - X stop\n\t\tsync resolve: 6 node - 0 stop : 3 node - 0 stop\n\t\tasync put: 5 node + 3 node - 1 stop\n\t\tasync reload: 2 link 1 node - X stop (2 links per each stop)\n\t\tasync resolve: 6 node - 0 stop : 3 node - 0 stop\n\n\t\tsync put: 1 mum\n\t\tsync reload: 1 mum\n\t\tsync resolve: 1 mum\n\t\tasync put: 1 mum\n\t\tasync reload: 0 mum: 2 link 1 node\n\t\tasync resolve: 1 mum\n\n\t*/\n\n\tfunction off(chain){\n\t\t//Gun.debug = 1;\n\t\tchain = chain || gun.get('users').map().get(function(a,b,c,tmp){\n\t\t\tconsole.log(\"***\", a.put);\n\t\t\tb.rid(a);\n\t\t});\n\t\tgun.get('users').get('alice').get(function(a,b){\n\t\t\tconsole.log(\">>>\", a.put);\n\t\t});\n\t\tconsole.log(\"vvvvvvvvvvvvv\");\n\t\twindow.chain = chain;\n\t}\n/*\ngun.get('users').put({\n\talice: {age: 29},\n\tbob: {age: 32}\n});\n*/\n\n\tfunction soul(chain){\n\t\tGun.debug = 1;\n\t\tgun.get('x').get('y').get('z').get('q').get(function(a,b,c){\n\t\t\tconsole.log(\"***\", a.put || a);//,b,c);\n\t\t});\n\t\tsetTimeout(function(){\n\t\t\tconsole.debug.j=1;\n\t\t\tconsole.debug.i=1;console.log(\"------------\");\n\t\t\tgun.get('x').get('y').put({\n\t\t\t\tz: {\n\t\t\t\t\tq: {r: {hello: 'world'}}\n\t\t\t\t}\n\t\t\t});\n\t\t},20);\n\t\tconsole.log(\"..............\");\n\t\twindow.chain = chain;\n\t}\n/*\ngun.get('x').get('y').get('z').put({xyz: 'zyx'});\n*/\n\n\twindow.resolve = resolve;\n\twindow.off = off;\n\twindow.soul = soul;\n\t//localStorage.clear();sessionStorage.clear();\n\tsetTimeout(function(){ resolve() },1);\n\t\n\t/*\n\t\tAt the end of the day, you trust an entity, not data.\n\t\tThat entity might be a person, or a group of people,\n\t\tit doesn't really matter - you do not trust a machine.\n\n\t\tTrust gives write access (public).\n\t\tGrant gives read access (private).\n\n\t*/\n\n  function Role(){}\n  if(typeof window !== \"undefined\"){ Role.window = window }\n\tvar Gun = (Role.window||{}).Gun || require('../gun');\n\tGun.SEA || require('../sea');\n\tif(!Gun.User){ throw \"No User System!\" }\n\tvar User = Gun.User;\n\n\tUser.prototype.trust = function(user){\n\n\t}\n\n}());"
  },
  {
    "path": "lib/rs3.js",
    "content": "var Gun = require('../gun');\nvar Radisk = require('./radisk');\nvar Radix = Radisk.Radix;\nvar u, AWS;\n\nGun.on('create', function(root){\n\tthis.to.next(root);\n\tvar opt = root.opt;\n\tif(!opt.s3 && !process.env.AWS_S3_BUCKET){ return }\n\t//opt.batch = opt.batch || (1000 * 10);\n\t//opt.until = opt.until || (1000 * 3); // ignoring these now, cause perf > cost\n\t//opt.chunk = opt.chunk || (1024 * 1024 * 10); // 10MB // when cost only cents\n\n\ttry{AWS = require('aws-sdk');\n\t}catch(e){\n\t\tconsole.log(\"Please `npm install aws-sdk` or add it to your package.json !\");\n\t\tAWS_SDK_NOT_INSTALLED;\n\t}\n\n\tvar opts = opt.s3 || (opt.s3 = {});\n\topts.bucket = opts.bucket || process.env.AWS_S3_BUCKET;\n\topts.region = opts.region || process.env.AWS_REGION || \"us-east-1\";\n\topts.accessKeyId = opts.key = opts.key || opts.accessKeyId || process.env.AWS_ACCESS_KEY_ID;\n\topts.secretAccessKey = opts.secret = opts.secret || opts.secretAccessKey || process.env.AWS_SECRET_ACCESS_KEY;\n\n\t// opts.fakes3 should be the domain name of the S3-compatible service\n\tif(opts.fakes3 = opts.fakes3 || process.env.fakes3){\n\t\topts.endpoint = opts.fakes3;\n\t\topts.sslEnabled = false;\n\t\topts.bucket = opts.bucket.replace('.','p');\n\t}\n\n\topts.config = new AWS.Config(opts);\n\topts.s3 = opts.s3 || new AWS.S3(opts.config);\n\n\topt.store = Object.keys(opts.s3).length === 0 ? opt.store : Store(opt);\n});\n\nfunction Store(opt){\n\topt = opt || {};\n\topt.file = String(opt.file || 'radata');\n\tvar opts = opt.s3, s3 = opts.s3;\n\tvar c = {p: {}, g: {}, l: {}};\n\t\n\tvar store = function Store(){};\n\tif(Store[opt.file]){\n\t\tconsole.log(\"Warning: reusing same S3 store and options as 1st.\");\n\t\treturn Store[opt.file];\n\t}\n\tStore[opt.file] = store;\n\n\tstore.put = function(file, data, cb){\n\t\tvar params = {Bucket: opts.bucket, Key: file, Body: data};\n\t\t//console.log(\"RS3 PUT ---->\", (data||\"\").slice(0,20));\n\t\tc.p[file] = data;\n\t\tdelete c.g[file];//Gun.obj.del(c.g, file);\n\t\tdelete c.l[1];//Gun.obj.del(c.l, 1);\n    s3.putObject(params, function(err, ok){\n    \tdelete c.p[file];\n    \tcb(err, 's3');\n    });\n\t};\n\tstore.get = function(file, cb){ var tmp;\n\t\tif(tmp = c.p[file]){ cb(u, tmp); return }\n\t\tif(tmp = c.g[file]){ tmp.push(cb); return }\n\t\tvar cbs = c.g[file] = [cb];\n\t\tvar params = {Bucket: opts.bucket, Key: file||''};\n\t\t//console.log(\"RS3 GET ---->\", file);\n\t\ts3.getObject(params, function got(err, ack){\n\t\t\tif(err && 'NoSuchKey' === err.code){ err = u }\n\t\t\t//console.log(\"RS3 GOT <----\", err, file, cbs.length, ((ack||{}).Body||'').length);//.toString().slice(0,20));\n\t\t\tdelete c.g[file];//Gun.obj.del(c.g, file);\n\t\t\tvar data, data = (ack||'').Body;\n\t\t\t//console.log(1, process.memoryUsage().heapUsed);\n\t\t\tvar i = 0, cba; while(cba = cbs[i++]){ cba && cba(err, data) }//Gun.obj.map(cbs, cbe);\n\t\t});\n\t};\n\tstore.list = function(cb, match, params, cbs){\n\t\tif(!cbs){\n\t\t\tif(c.l[1]){ return c.l[1].push(cb) }\n\t\t\tcbs = c.l[1] = [cb];\n\t\t}\n\t\tparams = params || {Bucket: opts.bucket};\n\t\t//console.log(\"RS3 LIST --->\");\n\t\ts3.listObjectsV2(params, function(err, data){\n\t\t\t//console.log(\"RS3 LIST <---\", err, data, cbs.length);\n\t\t\tif(err){ return Gun.log(err, err.stack) }\n\t\t\tvar IT = data.IsTruncated, cbe = function(cb){\n\t\t\t\tif(cb.end){ return }\n\t\t\t\tif(Gun.obj.map(data.Contents, function(content){\n\t\t\t\t\treturn cb(content.Key);\n\t\t\t\t})){ cb.end = true; return }\n\t\t\t\tif(IT){ return }\n\t\t\t\t// Stream interface requires a final call to know when to be done.\n\t\t\t\tcb.end = true; cb();\n\t\t\t}\n\t\t\t// Gun.obj.map(cbs, cbe); // lets see if fixes heroku\n\t\t\tif(!IT){ delete c.l[1]; return }\n\t    params.ContinuationToken = data.NextContinuationToken;\n\t  \tstore.list(cb, match, params, cbs);\n    });\n\t};\n\t//store.list(function(){ return true });\n\tif(false !== opt.rfs){ require('./rfsmix')(opt, store) } // ugly, but gotta move fast for now.\n\treturn store;\n}\n\nmodule.exports = Store;\n"
  },
  {
    "path": "lib/serve.js",
    "content": "var fs = require('fs');\nvar path = require('path');\nvar dot = /\\.\\.+/g;\nvar slash = /\\/\\/+/g;\n\nfunction CDN(dir){\n\treturn function(req, res){\n\t\treq.url = (req.url||'').replace(dot,'').replace(slash,'/');\n\t\tif(serve(req, res)){ return } // filters GUN requests!\n\t\tif (req.url.slice(-3) === '.js') {\n\t\t\tres.writeHead(200, {'Content-Type': 'text/javascript'});\n\t\t}\n\t\tfs.createReadStream(path.join(dir, req.url)).on('error',function(tmp){ // static files!\n\t\t\tfs.readFile(path.join(dir, 'index.html'), function(err, tmp){\n\t\t\t\ttry{ res.writeHead(200, {'Content-Type': 'text/html'});\n\t\t\t\tres.end(tmp+''); }catch(e){} // or default to index\n\t\t})}).pipe(res); // stream\n\t}\n}\n\nfunction serve(req, res, next){ var tmp;\n\tif(typeof req === 'string'){\n\t\treturn CDN(req);\n\t}\n\tif(!req || !res){ return false }\n\tnext = next || serve;\n\tif(!req.url){ return next() }\n\tif(res.setHeader){ res.setHeader('Access-Control-Allow-Origin', '*') }\n\tif(0 <= req.url.indexOf('gun.js')){\n\t\tres.writeHead(200, {'Content-Type': 'text/javascript'});\n\t\tres.end(serve.js = serve.js || require('fs').readFileSync(__dirname + '/../gun.js'));\n\t\treturn true;\n\t}\n\tif(0 <= req.url.indexOf('gun/')){\n\t\tvar path = __dirname + '/../' + req.url.split('/').slice(2).join('/');\n\t\tif('/' === path.slice(-1)){\n\t\t\tfs.readdir(path, function(err, dir){ res.end((dir || (err && 404))+'') });\n\t\t\treturn true;\n\t\t}\n\t\tvar S = +new Date;\n\t\tvar rs = fs.createReadStream(path);\n\t\trs.on('open', function(){ console.STAT && console.STAT(S, +new Date - S, 'serve file open'); rs.pipe(res) });\n\t\trs.on('error', function(err){ res.end(404+'') });\n\t\trs.on('end', function(){ console.STAT && console.STAT(S, +new Date - S, 'serve file end') });\n\t\treturn true;\n\t}\n\tif((tmp = req.socket) && (tmp = tmp.server) && (tmp = tmp.route)){ var url;\n\t\tif(tmp = tmp[(((req.url||'').slice(1)).split('/')[0]||'').split('.')[0]]){\n\t\t\ttry{ return tmp(req, res, next) }catch(e){ console.log(req.url+' crashed with '+e) }\n\t\t}\n\t}\n\treturn next();\n}\n\nmodule.exports = serve;\n"
  },
  {
    "path": "lib/server.js",
    "content": ";(function(){\n\trequire('./yson');\n\tvar Gun = require('../gun'), u;\n\tGun.serve = require('./serve');\n\t//process.env.GUN_ENV = process.env.GUN_ENV || 'debug';\n\t//console.LOG = {}; // only do this for dev.\n\tGun.on('opt', function(root){\n\t\tif(u === root.opt.super){ root.opt.super = true }\n\t\tif(u === root.opt.faith){ root.opt.faith = true } // HNPERF: This should probably be off, but we're testing performance improvements, please audit.\n\t\troot.opt.log = root.opt.log || Gun.log;\n\t\tthis.to.next(root);\n\t})\n\t//require('../nts');\n\trequire('./store');\n\trequire('./rfs');\n\trequire('./rs3');\n\trequire('./wire');\n\n\ttry{require('../sea');}catch(e){}\n\ttry{require('../axe');}catch(e){}\n\t//require('./file');\n\t//require('./evict');\n\trequire('./multicast');\n\trequire('./stats');\n\tmodule.exports = Gun;\n}());\n"
  },
  {
    "path": "lib/service.js",
    "content": "module.exports = function(root){\n\tvar mesh = root.opt.mesh, cmd = {}, run = require('child_process').exec, fs = require('fs'), home = require('os').homedir(), examp = require('path').resolve(__dirname, '../examples');\n\tmesh.hear['service'] = function(msg, peer){\n\t\tif(!fs.existsSync('/lib/systemd/system/relay.service')){\n\t\t\tmesh.say({dam: '!', err: \"Not serviced.\"});\n\t\t\treturn;\n\t\t}\n\t\ttry{ (cmd[msg.try]||cmd.any)(msg, peer); }catch(err){ mesh.say({dam: '!', err: \"service error: \"+err}) }\n\t}\n\tcmd.https = function(msg, peer){ var log;\n\t\tif(!msg.email || !msg.domain){\n\t\t\tmesh.say({dam: '!', err: 'Domain/email missing, use `location.hostname`!'});\n\t\t\treturn;\n\t\t}\n\t\tif(fs.existsSync(home+'/cert.pem')){\n\t\t\tmesh.say({dam: '!', err: 'Cert already exists.'});\n\t\t\treturn;\n\t\t}\n\t\tfs.writeFile(examp+'/../email', msg.email, function(){});\n\t\trun(\"bash \"+examp+\"/https.sh\", {env: {'EMAIL': msg.email, 'WEB': examp, 'DOMAIN':  msg.domain}}, function(e, out, err){\n\t\t\tlog = \"|\"+e+\"|\"+out+\"|\"+err;\n\t\t\tmesh.say({dam: '!', log: ''+log}, peer);\n\t\t\tsetTimeout(function(){ process.exit() },999);\n\t\t});\n\t}\n\tcmd.update = function(msg, peer){ var log, pass;\n\t\ttry{ pass = (''+fs.readFileSync(home+'/pass')).trim() }catch(e){}\n\t\tif(!pass || (msg.pass||'').trim() != pass){ return }\n\t\troot.stats.stay.updated = +new Date;\n\t\trun(\"bash \"+examp+\"/install.sh\", {env: {VERSION: msg.version||''}}, function(e, out, err){\n\t\t\tlog = e+\"|\"+out+\"|\"+err;\n\t\t\tmesh.say({dam: '!', log: ''+log}, peer);\n\t\t\tsetTimeout(function(){ process.exit() },999);\n\t\t});\n\t}\n\t;(function update(){ var last;\n\t\tif(!fs.existsSync(home+'/cert.pem')){ return }\n\t\tsetTimeout(update, 1000*60*60*24);\n\t\tlast = root.stats.stay.updated || 0;\n\t\tif(+new Date - last < 1000*60*60*24*15){ return }\n\t\troot.stats.stay.updated = +new Date;\n\t\trun(\"bash \"+examp+\"/install.sh\", {}, function(){});\n\t}());\n\n\tcmd.any = function(){};\n\n};"
  },
  {
    "path": "lib/shim.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.chain.open || require('./open');\n\nvar _on = Gun.chain.on;\nGun.chain.on = function(a,b,c){\n\tif('value' === a){\n\t\treturn this.open(b,c);\n\t}\n\treturn _on.call(this, a,b,c);\n}\n\nGun.chain.bye || require('./bye');\nGun.chain.onDisconnect = Gun.chain.bye;\nGun.chain.connected = function(cb){\n\tvar root = this.back(-1), last;\n\troot.on('hi', function(peer){\n\t\tif(!cb){ return }\n\t\tcb(last = true, peer);\n\t});\n\troot.on('bye', function(peer){\n\t\tif(!cb || last === peer){ return }\n\t\tcb(false, last = peer);\n\t});\n\treturn this;\n}"
  },
  {
    "path": "lib/space.js",
    "content": ";(function(){\n\tvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\tvar ify = Gun.node.ify, empty = {}, u;\n\tconsole.log(\"Index space is beta, API may change!\");\n\tGun.chain.space = function(key, data, opt){\n\t\tif(data instanceof Function){\n\t\t\treturn travel(key, data, opt, this);\n\t\t}\n\t\tvar gun = this;\n\t\tif(Gun.is(data)){\n\t\t\tdata.get(function(soul){\n\t\t\t\tif(!soul){\n\t\t\t\t\treturn cb && cb({err: \"Indexspace cannot link `undefined`!\"});\n\t\t\t\t}\n\t\t\t\tgun.space(key, Gun.val.link.ify(soul), opt);\n\t\t\t}, true);\n\t\t\treturn gun;\n\t\t}\n\t\tvar cb = (opt instanceof Function && opt), rank = (opt||empty).rank || opt, root = gun.back(-1), tmp;\n\t\tgun.get(function(soul){\n\t\t\tif(!soul){\n\t\t\t\tsoul = (gun.back('opt.uuid') || Gun.text.random)(9);\n\t\t\t}\n      /*var space = ify({}, soul), sub = space, l = 0, tmp;\n      var atom = Gun.text.ify({get: key, put: data});\n      Gun.list.map(index(0, key.length), function(i){\n          sub[(tmp = key.slice(l, i))+'\"'] = atom;\n          sub = sub[tmp] = ify({}, soul+'\"'+key.slice(0,i));\n          l = i;\n      });\n      tmp = {}; tmp[key] = atom.put; tmp = ify(tmp, soul+'\"');\n      sub[key.slice(l, key.length)] = tmp;\n      console.log('????', space);*/\n\t\t\tvar shell = {}, l = 0, tmp;\n\t\t\tvar atom = Gun.text.ify({get: key, put: data});\n\t\t\ttmp = {}; tmp[key] = data;\n\t\t\tshell.$ = ify(tmp, soul);\n\t\t\ttmp = {}; tmp[key.slice(0,l = 1)] = atom;\n\t\t\tshell[0] = ify(tmp, soul+'\"');\n\t\t\tGun.list.map(index(1, key.length), function(i){\n\t\t\t\ttmp = {}; tmp[key.slice(l,i)] = atom;\n\t\t\t\tshell[i] = ify(tmp, soul+'\"'+key.slice(0,l));\n\t\t\t\tl = i;\n\t\t\t});\n\t\t\ttmp = {}; tmp[key.slice(l, key.length)] = atom;\n\t\t\tshell[l+1] = ify(tmp, soul+'\"'+key.slice(0,l));\n\t\t\t//tmp = {}; tmp[key.slice(l, key.length)] = Gun.val.link.ify(soul); shell[l+1] = ify(tmp, soul+'\"'+key.slice(0,l));\n\t\t\t//console.log('???', shell);\n\t\t\tgun.put(shell, cb, {soul: soul, shell: shell});\n\t\t},true);\n\t\treturn gun;\n\t}\n\tfunction travel(key, cb, opt, ref){\n\t\tvar root = ref.back(-1), tmp;\n\t\topt = opt || {};\n\t\topt.ack = opt.ack || {};\n\t\tref.get(function(soul){\n\t\t\tref.get(key).get(function(msg, eve){\n\t\t\t\teve.off();\n\t\t\t\topt.exact = true;\n\t\t\t\topt.ack.key = key;\n\t\t\t\topt.ack.data = msg.put;\n\t\t\t\tif(opt.match){ cb(opt.ack, key, msg, eve) }\n\t\t\t});\n\t\t\t//if(u !== msg.put){\n\t\t\t//\tcb(msg.put, msg.get, msg, eve);\n\t\t\t//\treturn;\n\t\t\t//}\n\t\t\topt.soul = soul;\n\t\t\topt.start = soul+'\"';\n\t\t\topt.key = key;\n\t\t\topt.top = index(0, opt.find);\n\t\t\topt.low = opt.top.reverse();\n\t\t\tfind(opt, cb, root);\n\t\t}, true);\n\t}\n\tfunction find(o, cb, root){\n\t\tvar id = o.start+o.key.slice(0,o.low[0]);\n\t\troot.get(id).get(function(msg, eve){\n\t\t\teve.off();\n\t\t\to.ack.tree = {};\n\t\t\tif(u === msg.put){\n\t\t\t\tif(!o.exact){ return o.match = true }\n\t\t\t\tcb(o.ack, id, msg, eve);\n\t\t\t\treturn;\n\t\t\t\to.low = o.low.slice(1);\n\t\t\t\tif(!o.low.length){\n\t\t\t\t\tcb(u, o.key, msg, eve);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfind(o, cb, root);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tGun.node.is(msg.put, function(v,k){\n\t\t\t\tif(!(k = Gun.obj.ify(v) || empty).get){ return }\n\t\t\t\to.ack.tree[k.get] = k.put;\n\t\t\t});\n\t\t\tif(!o.exact){ return o.match = true }\n\t\t\tcb(o.ack, id, msg, eve);\n\t\t});\n\t}\n\tfunction index(n, m, l, k){\n\t\tl = l || [];\n\t\tif(!m){ return l }\n\t  k = Math.ceil((n||1) / 10);\n\t  if((n+k) >= m){ return l }\n\t  l.push(n + k);\n\t  return index(n + k, m, l);\n\t}\n}());\n\n/*\ngun.user('google').space('martti', \"testing 123!\");\ngun.user('google').get('search').space('ma', function(){\n\t// tree & index\n\t// UNFINISHED API!\n});\n*/\n"
  },
  {
    "path": "lib/stats.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.on('opt', function(root){\n\tthis.to.next(root);\n\tif(root.once){ return }\n\tif(typeof process === 'undefined'){ return }\n\tif(typeof require === 'undefined'){ return }\n\tif(false === root.opt.stats){ return }\n\tvar path = require('path') || {};\n\tvar file = root.opt.file ? path.resolve(root.opt.file).split(path.sep).slice(-1)[0] : 'radata';\n\tvar noop = function(){};\n\tvar os = require('os') || {};\n\tvar fs = require('fs') || {};\n\tfs.existsSync = fs.existsSync || path.existsSync;\n\tif(!fs.existsSync){ return }\n\tif(!process){ return }\n\tprocess.uptime = process.uptime || noop;\n\tprocess.cpuUsage = process.cpuUsage || noop;\n\tprocess.memoryUsage = process.memoryUsage || noop;\n\tos.totalmem = os.totalmem || noop;\n\tos.freemem = os.freemem || noop;\n\tos.loadavg = os.loadavg || noop;\n\tos.cpus = os.cpus || noop;\n\tvar S = +new Date, W;\n\tvar obj_ify = function(o){try{o = JSON.parse(o)}catch(e){o={}};return o;}\n\tsetTimeout(function(){\n\t\troot.stats = obj_ify((fs.existsSync(__dirname+'/../stats.'+file) && fs.readFileSync(__dirname+'/../stats.'+file).toString())) || {};\n\t\troot.stats.up = root.stats.up || {};\n\t\troot.stats.up.start = root.stats.up.start || +(new Date);\n\t\troot.stats.up.count = (root.stats.up.count || 0) + 1;\n\t\troot.stats.stay = root.stats.stay || {};\n\t\troot.stats.over = +new Date;\n\t},1);\n\tsetInterval(function(){\n\t\tif(!root.stats){ root.stats = {} }\n\t\tif(W){ return }\n\t\tvar stats = root.stats, tmp;\n\t\tstats.over = -(S - (S = +new Date));\n\t\t(stats.up||{}).time = process.uptime();\n\t\tstats.memory = process.memoryUsage() || {};\n\t\tstats.memory.totalmem = os.totalmem();\n\t\tstats.memory.freemem = os.freemem();\n\t\tstats.cpu = process.cpuUsage() || {};\n\t\tstats.cpu.loadavg = os.loadavg();\n\t\tstats.cpu.stack = (((setTimeout||'').turn||'').s||'').length;\n\t\tstats.peers = {};\n\n\t\tstats.peers.count = console.STAT.peers || Object.keys(root.opt.peers||{}).length; // TODO: .keys( is slow\n\t\tstats.node = {};\n\t\tstats.node.count = Object.keys(root.graph||{}).length; // TODO: .keys( is slow\n\t\tstats.all = all;\n\t\tstats.sites = console.STAT.sites;\n\t\tall = {}; // will this cause missing stats?\n\t\tvar dam = root.opt.mesh;\n\t\tif(dam){\n\t\t\tstats.dam = {'in': {count: dam.hear.c, done: dam.hear.d}, 'out': {count: dam.say.c, done: dam.say.d}};\n\t\t\tdam.hear.c = dam.hear.d = dam.say.c = dam.say.d = 0; // reset\n\t\t\tstats.peers.time = dam.bye.time || 0;\n\t\t}\n\t\tvar rad = root.opt.store; rad = rad && rad.stats;\n\t\tif(rad){\n\t\t\tstats.rad = rad;\n\t\t\troot.opt.store.stats = {get:{time:{}, count:0}, put: {time:{}, count:0}}; // reset\n\t\t}\n\t\tJSON.stringifyAsync(stats, function(err, raw){ if(err){ return } W = true;\n\t\t\tfs.writeFile(__dirname+'/../stats.'+file, raw, function(err){ W = false; err && console.log(console.STAT.err = err); console.STAT && console.STAT(S, +new Date - S, 'stats stash') });\n\t\t});\n\n\t\t//exec(\"top -b -n 1\", function(err, out){ out && fs.writeFile(__dirname+'/../stats.top.'+file, out, noop) }); // was it really seriously actually this?\n\t//}, 1000 * 15);\n\t}, 1000 * 5);\n});\n\nvar exec = require(\"child_process\").exec, noop = function(){};\nrequire('./yson');\n\nvar log = Gun.log, all = {}, max = 1000;\nconsole.STAT = function(a,b,c,d){\n\tif('number' == typeof a && 'number' == typeof b && 'string' == typeof c){\n\t\tvar tmp = (all[c] || (all[c] = []));\n\t\tif(max < tmp.push([a,b])){ all[c] = [] } // reset\n\t\t//return;\n\t}\n\tif(!console.LOG || log.off){ return a }\n\treturn log.apply(Gun, arguments);\n}"
  },
  {
    "path": "lib/store.d.ts",
    "content": "import {} from './store'\ndeclare module './store' {}\n"
  },
  {
    "path": "lib/store.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nGun.on('create', function(root){\n    if(Gun.TESTING){ root.opt.file = 'radatatest' }\n    this.to.next(root);\n    var opt = root.opt, empty = {}, u;\n    if(false === opt.rad || false === opt.radisk){ return }\n    if((u+'' != typeof process) && 'false' === ''+(process.env||'').RAD){ return }\n    var Radisk = (Gun.window && Gun.window.Radisk) || require('./radisk');\n    var Radix = Radisk.Radix;\n    var dare = Radisk(opt), esc = String.fromCharCode(27);\n    var ST = 0;\n \n    root.on('put', function(msg){\n        this.to.next(msg);\n        if((msg._||'').rad){ return } // don't save what just came from a read.\n        //if(msg['@']){ return } // WHY DID I NOT ADD THIS?\n        var id = msg['#'], put = msg.put, soul = put['#'], key = put['.'], val = put[':'], state = put['>'], tmp;\n        var DBG = (msg._||'').DBG; DBG && (DBG.sp = DBG.sp || +new Date);\n        //var lot = (msg._||'').lot||''; count[id] = (count[id] || 0) + 1; \n        var S = (msg._||'').RPS || ((msg._||'').RPS = +new Date);\n        //console.log(\"PUT ------->>>\", soul,key, val, state);\n        //dare(soul+esc+key, {':': val, '>': state}, dare.one[id] || function(err, ok){\n        dare(soul+esc+key, {':': val, '>': state}, function(err, ok){\n            //console.log(\"<<<------- PAT\", soul,key, val, state, 'in', +new Date - S);\n            DBG && (DBG.spd = DBG.spd || +new Date);\n            console.STAT && console.STAT(S, +new Date - S, 'put');\n            //if(!err && count[id] !== lot.s){ console.log(err = \"Disk count not same as ram count.\"); console.STAT && console.STAT(+new Date, lot.s - count[id], 'put ack != count') } delete count[id];\n            if(err){ root.on('in', {'@': id, err: err, DBG: DBG}); return }\n            root.on('in', {'@': id, ok: ok, DBG: DBG});\n        //}, id, DBG && (DBG.r = DBG.r || {}));\n        }, false && id, DBG && (DBG.r = DBG.r || {}));\n        DBG && (DBG.sps = DBG.sps || +new Date);\n    });\n    var count = {}, obj_empty = Object.empty;\n \n    root.on('get', function(msg){\n        this.to.next(msg);\n        var ctx = msg._||'', DBG = ctx.DBG = msg.DBG; DBG && (DBG.sg = +new Date);\n        var id = msg['#'], get = msg.get, soul = msg.get['#'], has = msg.get['.']||'', o = {}, graph, lex, key, tmp, force;\n        if('string' == typeof soul){\n            key = soul;\n        } else \n        if(soul){\n            if(u !== (tmp = soul['*'])){ o.limit = force = 1 }\n            if(u !== soul['>']){ o.start = soul['>'] }\n            if(u !== soul['<']){ o.end = soul['<'] }\n            key = force? (''+tmp) : tmp || soul['='];\n            force = null;\n        }\n        if(key && !o.limit){ // a soul.has must be on a soul, and not during soul*\n            if('string' == typeof has){\n                key = key+esc+(o.atom = has);\n            } else \n            if(has){\n                if(u !== has['>']){ o.start = has['>']; o.limit = 1 }\n                if(u !== has['<']){ o.end = has['<']; o.limit = 1 }\n                if(u !== (tmp = has['*'])){ o.limit = force = 1 }\n                if(key){ key = key+esc + (force? (''+(tmp||'')) : tmp || (o.atom = has['='] || '')) }\n            }\n        }\n        if((tmp = get['%']) || o.limit){\n            o.limit = (tmp <= (o.pack || (1000 * 100)))? tmp : 1;\n        }\n        if(has['-'] || (soul||{})['-'] || get['-']){ o.reverse = true }\n        if((tmp = (root.next||'')[soul]) && tmp.put){\n            if(o.atom){\n                tmp = (tmp.next||'')[o.atom] ;\n                if(tmp && tmp.root && tmp.root.graph && tmp.root.graph[soul] && tmp.root.graph[soul][o.atom]){ return }\n            } else\n            if(tmp && tmp.rad){ return }\n        }\n        var now = Gun.state();\n        var S = (+new Date), C = 0, SPT = 0; // STATS!\n        DBG && (DBG.sgm = S);\n        //var GID = String.random(3); console.log(\"GET ------->>>\", GID, key, o, '?', get);\n        dare(key||'', function(err, data, info){\n            //console.log(\"<<<------- GOT\", GID, +new Date - S, err, data);\n            DBG && (DBG.sgr = +new Date);\n            DBG && (DBG.sgi = info);\n            try{opt.store.stats.get.time[statg % 50] = (+new Date) - S; ++statg;\n                opt.store.stats.get.count++;\n                if(err){ opt.store.stats.get.err = err }\n            }catch(e){} // STATS!\n            //if(u === data && info.chunks > 1){ return } // if we already sent a chunk, ignore ending empty responses. // this causes tests to fail.\n            console.STAT && console.STAT(S, +new Date - S, 'got', JSON.stringify(key)); S = +new Date;\n            info = info || '';\n            var va, ve;\n            if(info.unit && data && u !== (va = data[':']) && u !== (ve = data['>'])){ // new format\n                var tmp = key.split(esc), so = tmp[0], ha = tmp[1];\n                (graph = graph || {})[so] = Gun.state.ify(graph[so], ha, ve, va, so);\n                root.$.get(so).get(ha)._.rad = now;\n                // REMEMBER TO ADD _rad TO NODE/SOUL QUERY!\n            } else\n            if(data){ // old code path\n                if(typeof data !== 'string'){\n                    if(o.atom){\n                        data = u;\n                    } else {\n                        Radix.map(data, each, o); // IS A RADIX TREE, NOT FUNCTION!\n                    }\n                }\n                if(!graph && data){ each(data, '') }\n                // TODO: !has what about soul lookups?\n                if(!o.atom && !has & 'string' == typeof soul && !o.limit && !o.more){\n                    root.$.get(soul)._.rad = now;\n                }\n            }\n            DBG && (DBG.sgp = +new Date);\n            // TODO: PERF NOTES! This is like 0.2s, but for each ack, or all? Can you cache these preps?\n            // TODO: PERF NOTES! This is like 0.2s, but for each ack, or all? Can you cache these preps?\n            // TODO: PERF NOTES! This is like 0.2s, but for each ack, or all? Can you cache these preps?\n            // TODO: PERF NOTES! This is like 0.2s, but for each ack, or all? Can you cache these preps?\n            // TODO: PERF NOTES! This is like 0.2s, but for each ack, or all? Can you cache these preps?\n            // Or benchmark by reusing first start date.\n            if(console.STAT && (ST = +new Date - S) > 9){ console.STAT(S, ST, 'got prep time'); console.STAT(S, C, 'got prep #') } SPT += ST; C = 0; S = +new Date;\n            var faith = function(){}; faith.faith = true; faith.rad = get; // HNPERF: We're testing performance improvement by skipping going through security again, but this should be audited.\n            root.on('in', {'@': id, put: graph, '%': info.more? 1 : u, err: err? err : u, _: faith, DBG: DBG});\n            console.STAT && (ST = +new Date - S) > 9 && console.STAT(S, ST, 'got emit', Object.keys(graph||{}).length);\n            graph = u; // each is outside our scope, we have to reset graph to nothing!\n        }, o, DBG && (DBG.r = DBG.r || {}));\n        DBG && (DBG.sgd = +new Date);\n        console.STAT && (ST = +new Date - S) > 9 && console.STAT(S, ST, 'get call'); // TODO: Perf: this was half a second??????\n        function each(val, has, a,b){ // TODO: THIS CODE NEEDS TO BE FASTER!!!!\n            C++;\n            if(!val){ return }\n            has = (key+has).split(esc);\n            var soul = has.slice(0,1)[0];\n            has = has.slice(-1)[0];\n            if(o.limit && o.limit <= o.count){ return true }\n            var va, ve, so = soul, ha = has;\n            //if(u !== (va = val[':']) && u !== (ve = val['>'])){ // THIS HANDLES NEW CODE!\n            if('string' != typeof val){ // THIS HANDLES NEW CODE!\n                va = val[':']; ve = val['>'];\n                (graph = graph || {})[so] = Gun.state.ify(graph[so], ha, ve, va, so);\n                //root.$.get(so).get(ha)._.rad = now;\n                o.count = (o.count || 0) + ((va||'').length || 9);\n                return;\n            }\n            o.count = (o.count || 0) + val.length;\n            var tmp = val.lastIndexOf('>');\n            var state = Radisk.decode(val.slice(tmp+1), null, esc);\n            val = Radisk.decode(val.slice(0,tmp), null, esc);\n            (graph = graph || {})[soul] = Gun.state.ify(graph[soul], has, state, val, soul);\n        }\n    });\n    var val_is = Gun.valid;\n    (opt.store||{}).stats = {get:{time:{}, count:0}, put: {time:{}, count:0}}; // STATS!\n    var statg = 0, statp = 0; // STATS!\n});"
  },
  {
    "path": "lib/super.js",
    "content": ";(function(){\n\tvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\tvar Rad = (Gun.window||{}).Radix || require('./radix');\n\t/// Store the subscribes\n\tGun.subs = Rad();\n\tfunction input(msg){\n\t\tvar at = this.as, to = this.to, peer = (msg._||empty).via;\n\t\tvar get = msg.get, soul, key;\n\t\tif(!peer || !get){ return to.next(msg) }\n\t\t// console.log(\"super\", msg);\n\t\tif(soul = get['#']){\n\t\t\tif(key = get['.']){\n\n\t\t\t} else {\n\n\t\t\t}\n\t\t\tif (!peer.id) {console.log('[*** WARN] no peer.id %s', soul);}\n\t\t\tvar subs = Gun.subs(soul) || null;\n\t\t\tvar tmp = subs ? subs.split(',') : [], p = at.opt.peers;\n\t\t\tif (subs) {\n\t\t\t\tGun.obj.map(subs.split(','), function(peerid) {\n\t\t\t\t\tif (peerid in p) { tmp.push(peerid); }\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (tmp.indexOf(peer.id) === -1) { tmp.push(peer.id);}\n\t\t\ttmp = tmp.join(',');\n\t\t\tGun.subs(soul, tmp);\n\t\t\tvar dht = {};\n\t\t\tdht[soul] = tmp;\n\t\t\tat.opt.mesh.say({dht:dht}, peer);\n\t\t}\n\t\tto.next(msg);\n\t}\n\tvar empty = {}, u;\n\tif(Gun.window){ return }\n\ttry{module.exports = input}catch(e){}\n}());\n"
  },
  {
    "path": "lib/text-encoding/LICENSE.md",
    "content": "The encoding indexes, algorithms, and many comments in the code\nderive from the Encoding Standard https://encoding.spec.whatwg.org/\n\nOtherwise, the code of this repository is released under the Unlicense\nlicense and is also dual-licensed under an Apache 2.0 license. Both\nare included below.\n\n# Unlicense\n\nThis is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, compile, sell, or\ndistribute this software, either in source code form or as a compiled\nbinary, for any purpose, commercial or non-commercial, and by any\nmeans.\n\nIn jurisdictions that recognize copyright laws, the author or authors\nof this software dedicate any and all copyright interest in the\nsoftware to the public domain. We make this dedication for the benefit\nof the public at large and to the detriment of our heirs and\nsuccessors. We intend this dedication to be an overt act of\nrelinquishment in perpetuity of all present and future rights to this\nsoftware under copyright law.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\nOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\nFor more information, please refer to <http://unlicense.org/>\n\n# Apache 2.0 License\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "lib/text-encoding/README.md",
    "content": "text-encoding\n==============\n\nThis is a polyfill for the [Encoding Living\nStandard](https://encoding.spec.whatwg.org/) API for the Web, allowing\nencoding and decoding of textual data to and from Typed Array buffers\nfor binary data in JavaScript.\n\nBy default it adheres to the spec and does not support *encoding* to\nlegacy encodings, only *decoding*. It is also implemented to match the\nspecification's algorithms, rather than for performance. The intended\nuse is within Web pages, so it has no dependency on server frameworks\nor particular module schemes.\n\nBasic examples and tests are included.\n\n### Install ###\n\nThere are a few ways you can get and use the `text-encoding` library.\n\n### HTML Page Usage ###\n\nClone the repo and include the files directly:\n\n```html\n  <!-- Required for non-UTF encodings -->\n  <script src=\"encoding-indexes.js\"></script>\n  <script src=\"encoding.js\"></script>\n```\n\nThis is the only use case the developer cares about. If you want those\nfancy module and/or package manager things that are popular these days\nyou should probably use a different library.\n\n#### Package Managers ####\n\nThe package is published to **npm** and **bower** as `text-encoding`.\nUse through these is not really supported, since they aren't used by\nthe developer of the library. Using `require()` in interesting ways\nprobably breaks. Patches welcome, as long as they don't break the\nbasic use of the files via `<script>`.\n\n### API Overview ###\n\nBasic Usage\n\n```js\n  var uint8array = new TextEncoder().encode(string);\n  var string = new TextDecoder(encoding).decode(uint8array);\n```\n\nStreaming Decode\n\n```js\n  var string = \"\", decoder = new TextDecoder(encoding), buffer;\n  while (buffer = next_chunk()) {\n    string += decoder.decode(buffer, {stream:true});\n  }\n  string += decoder.decode(); // finish the stream\n```\n\n### Encodings ###\n\nAll encodings from the Encoding specification are supported:\n\nutf-8 ibm866 iso-8859-2 iso-8859-3 iso-8859-4 iso-8859-5 iso-8859-6\niso-8859-7 iso-8859-8 iso-8859-8-i iso-8859-10 iso-8859-13 iso-8859-14\niso-8859-15 iso-8859-16 koi8-r koi8-u macintosh windows-874\nwindows-1250 windows-1251 windows-1252 windows-1253 windows-1254\nwindows-1255 windows-1256 windows-1257 windows-1258 x-mac-cyrillic\ngb18030 hz-gb-2312 big5 euc-jp iso-2022-jp shift_jis euc-kr\nreplacement utf-16be utf-16le x-user-defined\n\n(Some encodings may be supported under other names, e.g. ascii,\niso-8859-1, etc. See [Encoding](https://encoding.spec.whatwg.org/) for\nadditional labels for each encoding.)\n\nEncodings other than **utf-8**, **utf-16le** and **utf-16be** require\nan additional `encoding-indexes.js` file to be included. It is rather\nlarge (596kB uncompressed, 188kB gzipped); portions may be deleted if\nsupport for some encodings is not required.\n\n### Non-Standard Behavior ###\n\nAs required by the specification, only encoding to **utf-8** is\nsupported. If you want to try it out, you can force a non-standard\nbehavior by passing the `NONSTANDARD_allowLegacyEncoding` option to\nTextEncoder and a label. For example:\n\n```js\nvar uint8array = new TextEncoder(\n  'windows-1252', { NONSTANDARD_allowLegacyEncoding: true }).encode(text);\n```\n\nBut note that the above won't work if you're using the polyfill in a\nbrowser that natively supports the TextEncoder API natively, since the\npolyfill won't be used!\n\nYou can force the polyfill to be used by using this before the polyfill:\n\n```html\n<script>\nwindow.TextEncoder = window.TextDecoder = null;\n</script>\n```\n\nTo support the legacy encodings (which may be stateful), the\nTextEncoder `encode()` method accepts an optional dictionary and\n`stream` option, e.g. `encoder.encode(string, {stream: true});` This\nis not needed for standard encoding since the input is always in\ncomplete code points.\n"
  },
  {
    "path": "lib/text-encoding/index.js",
    "content": "// This is free and unencumbered software released into the public domain.\n// See LICENSE.md for more information.\n\nvar encoding = require(\"./lib/encoding.js\");\n\nmodule.exports = {\n  TextEncoder: encoding.TextEncoder,\n  TextDecoder: encoding.TextDecoder,\n};\n"
  },
  {
    "path": "lib/text-encoding/lib/encoding-indexes.js",
    "content": "(function(global) {\n  'use strict';\n\n  if (typeof module !== \"undefined\" && module.exports) {\n    module.exports = global;\n  }\n\n  global[\"encoding-indexes\"] =\n{\n  \"big5\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,17392,19506,17923,17830,17784,160359,19831,17843,162993,19682,163013,15253,18230,18244,19527,19520,148159,144919,160594,159371,159954,19543,172881,18255,17882,19589,162924,19719,19108,18081,158499,29221,154196,137827,146950,147297,26189,22267,null,32149,22813,166841,15860,38708,162799,23515,138590,23204,13861,171696,23249,23479,23804,26478,34195,170309,29793,29853,14453,138579,145054,155681,16108,153822,15093,31484,40855,147809,166157,143850,133770,143966,17162,33924,40854,37935,18736,34323,22678,38730,37400,31184,31282,26208,27177,34973,29772,31685,26498,31276,21071,36934,13542,29636,155065,29894,40903,22451,18735,21580,16689,145038,22552,31346,162661,35727,18094,159368,16769,155033,31662,140476,40904,140481,140489,140492,40905,34052,144827,16564,40906,17633,175615,25281,28782,40907,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,12736,12737,12738,12739,12740,131340,12741,131281,131277,12742,12743,131275,139240,12744,131274,12745,12746,12747,12748,131342,12749,12750,256,193,461,192,274,201,282,200,332,211,465,210,null,7870,null,7872,202,257,225,462,224,593,275,233,283,232,299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,476,252,null,7871,null,7873,234,609,9178,9179,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,172969,135493,null,25866,null,null,20029,28381,40270,37343,null,null,161589,25745,20250,20264,20392,20822,20852,20892,20964,21153,21160,21307,21326,21457,21464,22242,22768,22788,22791,22834,22836,23398,23454,23455,23706,24198,24635,25993,26622,26628,26725,27982,28860,30005,32420,32428,32442,32455,32463,32479,32518,32567,33402,33487,33647,35270,35774,35810,36710,36711,36718,29713,31996,32205,26950,31433,21031,null,null,null,null,37260,30904,37214,32956,null,36107,33014,133607,null,null,32927,40647,19661,40393,40460,19518,171510,159758,40458,172339,13761,null,28314,33342,29977,null,18705,39532,39567,40857,31111,164972,138698,132560,142054,20004,20097,20096,20103,20159,20203,20279,13388,20413,15944,20483,20616,13437,13459,13477,20870,22789,20955,20988,20997,20105,21113,21136,21287,13767,21417,13649,21424,13651,21442,21539,13677,13682,13953,21651,21667,21684,21689,21712,21743,21784,21795,21800,13720,21823,13733,13759,21975,13765,163204,21797,null,134210,134421,151851,21904,142534,14828,131905,36422,150968,169189,16467,164030,30586,142392,14900,18389,164189,158194,151018,25821,134524,135092,134357,135412,25741,36478,134806,134155,135012,142505,164438,148691,null,134470,170573,164073,18420,151207,142530,39602,14951,169460,16365,13574,152263,169940,161992,142660,40302,38933,null,17369,155813,25780,21731,142668,142282,135287,14843,135279,157402,157462,162208,25834,151634,134211,36456,139681,166732,132913,null,18443,131497,16378,22643,142733,null,148936,132348,155799,134988,134550,21881,16571,17338,null,19124,141926,135325,33194,39157,134556,25465,14846,141173,36288,22177,25724,15939,null,173569,134665,142031,142537,null,135368,145858,14738,14854,164507,13688,155209,139463,22098,134961,142514,169760,13500,27709,151099,null,null,161140,142987,139784,173659,167117,134778,134196,157724,32659,135375,141315,141625,13819,152035,134796,135053,134826,16275,134960,134471,135503,134732,null,134827,134057,134472,135360,135485,16377,140950,25650,135085,144372,161337,142286,134526,134527,142417,142421,14872,134808,135367,134958,173618,158544,167122,167321,167114,38314,21708,33476,21945,null,171715,39974,39606,161630,142830,28992,33133,33004,23580,157042,33076,14231,21343,164029,37302,134906,134671,134775,134907,13789,151019,13833,134358,22191,141237,135369,134672,134776,135288,135496,164359,136277,134777,151120,142756,23124,135197,135198,135413,135414,22428,134673,161428,164557,135093,134779,151934,14083,135094,135552,152280,172733,149978,137274,147831,164476,22681,21096,13850,153405,31666,23400,18432,19244,40743,18919,39967,39821,154484,143677,22011,13810,22153,20008,22786,138177,194680,38737,131206,20059,20155,13630,23587,24401,24516,14586,25164,25909,27514,27701,27706,28780,29227,20012,29357,149737,32594,31035,31993,32595,156266,13505,null,156491,32770,32896,157202,158033,21341,34916,35265,161970,35744,36125,38021,38264,38271,38376,167439,38886,39029,39118,39134,39267,170000,40060,40479,40644,27503,63751,20023,131207,38429,25143,38050,null,20539,28158,171123,40870,15817,34959,147790,28791,23797,19232,152013,13657,154928,24866,166450,36775,37366,29073,26393,29626,144001,172295,15499,137600,19216,30948,29698,20910,165647,16393,27235,172730,16931,34319,133743,31274,170311,166634,38741,28749,21284,139390,37876,30425,166371,40871,30685,20131,20464,20668,20015,20247,40872,21556,32139,22674,22736,138678,24210,24217,24514,141074,25995,144377,26905,27203,146531,27903,null,29184,148741,29580,16091,150035,23317,29881,35715,154788,153237,31379,31724,31939,32364,33528,34199,40873,34960,40874,36537,40875,36815,34143,39392,37409,40876,167353,136255,16497,17058,23066,null,null,null,39016,26475,17014,22333,null,34262,149883,33471,160013,19585,159092,23931,158485,159678,40877,40878,23446,40879,26343,32347,28247,31178,15752,17603,143958,141206,17306,17718,null,23765,146202,35577,23672,15634,144721,23928,40882,29015,17752,147692,138787,19575,14712,13386,131492,158785,35532,20404,131641,22975,33132,38998,170234,24379,134047,null,139713,166253,16642,18107,168057,16135,40883,172469,16632,14294,18167,158790,16764,165554,160767,17773,14548,152730,17761,17691,19849,19579,19830,17898,16328,150287,13921,17630,17597,16877,23870,23880,23894,15868,14351,23972,23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791,24893,23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193,14851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037,26111,26195,15090,26258,15138,26390,15170,26532,26624,15192,26698,26756,15218,15217,15227,26889,26947,29276,26980,27039,27013,15292,27094,15325,27237,27252,27249,27266,15340,27289,15346,27307,27317,27348,27382,27521,27585,27626,27765,27818,15563,27906,27910,27942,28033,15599,28068,28081,28181,28184,28201,28294,166336,28347,28386,28378,40831,28392,28393,28452,28468,15686,147265,28545,28606,15722,15733,29111,23705,15754,28716,15761,28752,28756,28783,28799,28809,131877,17345,13809,134872,147159,22462,159443,28990,153568,13902,27042,166889,23412,31305,153825,169177,31333,31357,154028,31419,31408,31426,31427,29137,156813,16842,31450,31453,31466,16879,21682,154625,31499,31573,31529,152334,154878,31650,31599,33692,154548,158847,31696,33825,31634,31672,154912,15789,154725,33938,31738,31750,31797,154817,31812,31875,149634,31910,26237,148856,31945,31943,31974,31860,31987,31989,31950,32359,17693,159300,32093,159446,29837,32137,32171,28981,32179,32210,147543,155689,32228,15635,32245,137209,32229,164717,32285,155937,155994,32366,32402,17195,37996,32295,32576,32577,32583,31030,156368,39393,32663,156497,32675,136801,131176,17756,145254,17667,164666,32762,156809,32773,32776,32797,32808,32815,172167,158915,32827,32828,32865,141076,18825,157222,146915,157416,26405,32935,166472,33031,33050,22704,141046,27775,156824,151480,25831,136330,33304,137310,27219,150117,150165,17530,33321,133901,158290,146814,20473,136445,34018,33634,158474,149927,144688,137075,146936,33450,26907,194964,16859,34123,33488,33562,134678,137140,14017,143741,144730,33403,33506,33560,147083,159139,158469,158615,144846,15807,33565,21996,33669,17675,159141,33708,33729,33747,13438,159444,27223,34138,13462,159298,143087,33880,154596,33905,15827,17636,27303,33866,146613,31064,33960,158614,159351,159299,34014,33807,33681,17568,33939,34020,154769,16960,154816,17731,34100,23282,159385,17703,34163,17686,26559,34326,165413,165435,34241,159880,34306,136578,159949,194994,17770,34344,13896,137378,21495,160666,34430,34673,172280,34798,142375,34737,34778,34831,22113,34412,26710,17935,34885,34886,161248,146873,161252,34910,34972,18011,34996,34997,25537,35013,30583,161551,35207,35210,35238,35241,35239,35260,166437,35303,162084,162493,35484,30611,37374,35472,162393,31465,162618,147343,18195,162616,29052,35596,35615,152624,152933,35647,35660,35661,35497,150138,35728,35739,35503,136927,17941,34895,35995,163156,163215,195028,14117,163155,36054,163224,163261,36114,36099,137488,36059,28764,36113,150729,16080,36215,36265,163842,135188,149898,15228,164284,160012,31463,36525,36534,36547,37588,36633,36653,164709,164882,36773,37635,172703,133712,36787,18730,166366,165181,146875,24312,143970,36857,172052,165564,165121,140069,14720,159447,36919,165180,162494,36961,165228,165387,37032,165651,37060,165606,37038,37117,37223,15088,37289,37316,31916,166195,138889,37390,27807,37441,37474,153017,37561,166598,146587,166668,153051,134449,37676,37739,166625,166891,28815,23235,166626,166629,18789,37444,166892,166969,166911,37747,37979,36540,38277,38310,37926,38304,28662,17081,140922,165592,135804,146990,18911,27676,38523,38550,16748,38563,159445,25050,38582,30965,166624,38589,21452,18849,158904,131700,156688,168111,168165,150225,137493,144138,38705,34370,38710,18959,17725,17797,150249,28789,23361,38683,38748,168405,38743,23370,168427,38751,37925,20688,143543,143548,38793,38815,38833,38846,38848,38866,38880,152684,38894,29724,169011,38911,38901,168989,162170,19153,38964,38963,38987,39014,15118,160117,15697,132656,147804,153350,39114,39095,39112,39111,19199,159015,136915,21936,39137,39142,39148,37752,39225,150057,19314,170071,170245,39413,39436,39483,39440,39512,153381,14020,168113,170965,39648,39650,170757,39668,19470,39700,39725,165376,20532,39732,158120,14531,143485,39760,39744,171326,23109,137315,39822,148043,39938,39935,39948,171624,40404,171959,172434,172459,172257,172323,172511,40318,40323,172340,40462,26760,40388,139611,172435,172576,137531,172595,40249,172217,172724,40592,40597,40606,40610,19764,40618,40623,148324,40641,15200,14821,15645,20274,14270,166955,40706,40712,19350,37924,159138,40727,40726,40761,22175,22154,40773,39352,168075,38898,33919,40802,40809,31452,40846,29206,19390,149877,149947,29047,150008,148296,150097,29598,166874,137466,31135,166270,167478,37737,37875,166468,37612,37761,37835,166252,148665,29207,16107,30578,31299,28880,148595,148472,29054,137199,28835,137406,144793,16071,137349,152623,137208,14114,136955,137273,14049,137076,137425,155467,14115,136896,22363,150053,136190,135848,136134,136374,34051,145062,34051,33877,149908,160101,146993,152924,147195,159826,17652,145134,170397,159526,26617,14131,15381,15847,22636,137506,26640,16471,145215,147681,147595,147727,158753,21707,22174,157361,22162,135135,134056,134669,37830,166675,37788,20216,20779,14361,148534,20156,132197,131967,20299,20362,153169,23144,131499,132043,14745,131850,132116,13365,20265,131776,167603,131701,35546,131596,20120,20685,20749,20386,20227,150030,147082,20290,20526,20588,20609,20428,20453,20568,20732,20825,20827,20829,20830,28278,144789,147001,147135,28018,137348,147081,20904,20931,132576,17629,132259,132242,132241,36218,166556,132878,21081,21156,133235,21217,37742,18042,29068,148364,134176,149932,135396,27089,134685,29817,16094,29849,29716,29782,29592,19342,150204,147597,21456,13700,29199,147657,21940,131909,21709,134086,22301,37469,38644,37734,22493,22413,22399,13886,22731,23193,166470,136954,137071,136976,23084,22968,37519,23166,23247,23058,153926,137715,137313,148117,14069,27909,29763,23073,155267,23169,166871,132115,37856,29836,135939,28933,18802,37896,166395,37821,14240,23582,23710,24158,24136,137622,137596,146158,24269,23375,137475,137476,14081,137376,14045,136958,14035,33066,166471,138682,144498,166312,24332,24334,137511,137131,23147,137019,23364,34324,161277,34912,24702,141408,140843,24539,16056,140719,140734,168072,159603,25024,131134,131142,140827,24985,24984,24693,142491,142599,149204,168269,25713,149093,142186,14889,142114,144464,170218,142968,25399,173147,25782,25393,25553,149987,142695,25252,142497,25659,25963,26994,15348,143502,144045,149897,144043,21773,144096,137433,169023,26318,144009,143795,15072,16784,152964,166690,152975,136956,152923,152613,30958,143619,137258,143924,13412,143887,143746,148169,26254,159012,26219,19347,26160,161904,138731,26211,144082,144097,26142,153714,14545,145466,145340,15257,145314,144382,29904,15254,26511,149034,26806,26654,15300,27326,14435,145365,148615,27187,27218,27337,27397,137490,25873,26776,27212,15319,27258,27479,147392,146586,37792,37618,166890,166603,37513,163870,166364,37991,28069,28427,149996,28007,147327,15759,28164,147516,23101,28170,22599,27940,30786,28987,148250,148086,28913,29264,29319,29332,149391,149285,20857,150180,132587,29818,147192,144991,150090,149783,155617,16134,16049,150239,166947,147253,24743,16115,29900,29756,37767,29751,17567,159210,17745,30083,16227,150745,150790,16216,30037,30323,173510,15129,29800,166604,149931,149902,15099,15821,150094,16127,149957,149747,37370,22322,37698,166627,137316,20703,152097,152039,30584,143922,30478,30479,30587,149143,145281,14942,149744,29752,29851,16063,150202,150215,16584,150166,156078,37639,152961,30750,30861,30856,30930,29648,31065,161601,153315,16654,31131,33942,31141,27181,147194,31290,31220,16750,136934,16690,37429,31217,134476,149900,131737,146874,137070,13719,21867,13680,13994,131540,134157,31458,23129,141045,154287,154268,23053,131675,30960,23082,154566,31486,16889,31837,31853,16913,154547,155324,155302,31949,150009,137136,31886,31868,31918,27314,32220,32263,32211,32590,156257,155996,162632,32151,155266,17002,158581,133398,26582,131150,144847,22468,156690,156664,149858,32733,31527,133164,154345,154947,31500,155150,39398,34373,39523,27164,144447,14818,150007,157101,39455,157088,33920,160039,158929,17642,33079,17410,32966,33033,33090,157620,39107,158274,33378,33381,158289,33875,159143,34320,160283,23174,16767,137280,23339,137377,23268,137432,34464,195004,146831,34861,160802,23042,34926,20293,34951,35007,35046,35173,35149,153219,35156,161669,161668,166901,166873,166812,166393,16045,33955,18165,18127,14322,35389,35356,169032,24397,37419,148100,26068,28969,28868,137285,40301,35999,36073,163292,22938,30659,23024,17262,14036,36394,36519,150537,36656,36682,17140,27736,28603,140065,18587,28537,28299,137178,39913,14005,149807,37051,37015,21873,18694,37307,37892,166475,16482,166652,37927,166941,166971,34021,35371,38297,38311,38295,38294,167220,29765,16066,149759,150082,148458,16103,143909,38543,167655,167526,167525,16076,149997,150136,147438,29714,29803,16124,38721,168112,26695,18973,168083,153567,38749,37736,166281,166950,166703,156606,37562,23313,35689,18748,29689,147995,38811,38769,39224,134950,24001,166853,150194,38943,169178,37622,169431,37349,17600,166736,150119,166756,39132,166469,16128,37418,18725,33812,39227,39245,162566,15869,39323,19311,39338,39516,166757,153800,27279,39457,23294,39471,170225,19344,170312,39356,19389,19351,37757,22642,135938,22562,149944,136424,30788,141087,146872,26821,15741,37976,14631,24912,141185,141675,24839,40015,40019,40059,39989,39952,39807,39887,171565,39839,172533,172286,40225,19630,147716,40472,19632,40204,172468,172269,172275,170287,40357,33981,159250,159711,158594,34300,17715,159140,159364,159216,33824,34286,159232,145367,155748,31202,144796,144960,18733,149982,15714,37851,37566,37704,131775,30905,37495,37965,20452,13376,36964,152925,30781,30804,30902,30795,137047,143817,149825,13978,20338,28634,28633,28702,28702,21524,147893,22459,22771,22410,40214,22487,28980,13487,147884,29163,158784,151447,23336,137141,166473,24844,23246,23051,17084,148616,14124,19323,166396,37819,37816,137430,134941,33906,158912,136211,148218,142374,148417,22932,146871,157505,32168,155995,155812,149945,149899,166394,37605,29666,16105,29876,166755,137375,16097,150195,27352,29683,29691,16086,150078,150164,137177,150118,132007,136228,149989,29768,149782,28837,149878,37508,29670,37727,132350,37681,166606,166422,37766,166887,153045,18741,166530,29035,149827,134399,22180,132634,134123,134328,21762,31172,137210,32254,136898,150096,137298,17710,37889,14090,166592,149933,22960,137407,137347,160900,23201,14050,146779,14000,37471,23161,166529,137314,37748,15565,133812,19094,14730,20724,15721,15692,136092,29045,17147,164376,28175,168164,17643,27991,163407,28775,27823,15574,147437,146989,28162,28428,15727,132085,30033,14012,13512,18048,16090,18545,22980,37486,18750,36673,166940,158656,22546,22472,14038,136274,28926,148322,150129,143331,135856,140221,26809,26983,136088,144613,162804,145119,166531,145366,144378,150687,27162,145069,158903,33854,17631,17614,159014,159057,158850,159710,28439,160009,33597,137018,33773,158848,159827,137179,22921,23170,137139,23137,23153,137477,147964,14125,23023,137020,14023,29070,37776,26266,148133,23150,23083,148115,27179,147193,161590,148571,148170,28957,148057,166369,20400,159016,23746,148686,163405,148413,27148,148054,135940,28838,28979,148457,15781,27871,194597,150095,32357,23019,23855,15859,24412,150109,137183,32164,33830,21637,146170,144128,131604,22398,133333,132633,16357,139166,172726,28675,168283,23920,29583,31955,166489,168992,20424,32743,29389,29456,162548,29496,29497,153334,29505,29512,16041,162584,36972,29173,149746,29665,33270,16074,30476,16081,27810,22269,29721,29726,29727,16098,16112,16116,16122,29907,16142,16211,30018,30061,30066,30093,16252,30152,30172,16320,30285,16343,30324,16348,30330,151388,29064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616,16490,16495,23646,30654,30667,22770,30744,28857,30748,16552,30777,30791,30801,30822,33864,152885,31027,26627,31026,16643,16649,31121,31129,36795,31238,36796,16743,31377,16818,31420,33401,16836,31439,31451,16847,20001,31586,31596,31611,31762,31771,16992,17018,31867,31900,17036,31928,17044,31981,36755,28864,134351,32207,32212,32208,32253,32686,32692,29343,17303,32800,32805,31545,32814,32817,32852,15820,22452,28832,32951,33001,17389,33036,29482,33038,33042,30048,33044,17409,15161,33110,33113,33114,17427,22586,33148,33156,17445,33171,17453,33189,22511,33217,33252,33364,17551,33446,33398,33482,33496,33535,17584,33623,38505,27018,33797,28917,33892,24803,33928,17668,33982,34017,34040,34064,34104,34130,17723,34159,34160,34272,17783,34418,34450,34482,34543,38469,34699,17926,17943,34990,35071,35108,35143,35217,162151,35369,35384,35476,35508,35921,36052,36082,36124,18328,22623,36291,18413,20206,36410,21976,22356,36465,22005,36528,18487,36558,36578,36580,36589,36594,36791,36801,36810,36812,36915,39364,18605,39136,37395,18718,37416,37464,37483,37553,37550,37567,37603,37611,37619,37620,37629,37699,37764,37805,18757,18769,40639,37911,21249,37917,37933,37950,18794,37972,38009,38189,38306,18855,38388,38451,18917,26528,18980,38720,18997,38834,38850,22100,19172,24808,39097,19225,39153,22596,39182,39193,20916,39196,39223,39234,39261,39266,19312,39365,19357,39484,39695,31363,39785,39809,39901,39921,39924,19565,39968,14191,138178,40265,39994,40702,22096,40339,40381,40384,40444,38134,36790,40571,40620,40625,40637,40646,38108,40674,40689,40696,31432,40772,131220,131767,132000,26906,38083,22956,132311,22592,38081,14265,132565,132629,132726,136890,22359,29043,133826,133837,134079,21610,194619,134091,21662,134139,134203,134227,134245,134268,24807,134285,22138,134325,134365,134381,134511,134578,134600,26965,39983,34725,134660,134670,134871,135056,134957,134771,23584,135100,24075,135260,135247,135286,26398,135291,135304,135318,13895,135359,135379,135471,135483,21348,33965,135907,136053,135990,35713,136567,136729,137155,137159,20088,28859,137261,137578,137773,137797,138282,138352,138412,138952,25283,138965,139029,29080,26709,139333,27113,14024,139900,140247,140282,141098,141425,141647,33533,141671,141715,142037,35237,142056,36768,142094,38840,142143,38983,39613,142412,null,142472,142519,154600,142600,142610,142775,142741,142914,143220,143308,143411,143462,144159,144350,24497,26184,26303,162425,144743,144883,29185,149946,30679,144922,145174,32391,131910,22709,26382,26904,146087,161367,155618,146961,147129,161278,139418,18640,19128,147737,166554,148206,148237,147515,148276,148374,150085,132554,20946,132625,22943,138920,15294,146687,148484,148694,22408,149108,14747,149295,165352,170441,14178,139715,35678,166734,39382,149522,149755,150037,29193,150208,134264,22885,151205,151430,132985,36570,151596,21135,22335,29041,152217,152601,147274,150183,21948,152646,152686,158546,37332,13427,152895,161330,152926,18200,152930,152934,153543,149823,153693,20582,13563,144332,24798,153859,18300,166216,154286,154505,154630,138640,22433,29009,28598,155906,162834,36950,156082,151450,35682,156674,156746,23899,158711,36662,156804,137500,35562,150006,156808,147439,156946,19392,157119,157365,141083,37989,153569,24981,23079,194765,20411,22201,148769,157436,20074,149812,38486,28047,158909,13848,35191,157593,157806,156689,157790,29151,157895,31554,168128,133649,157990,37124,158009,31301,40432,158202,39462,158253,13919,156777,131105,31107,158260,158555,23852,144665,33743,158621,18128,158884,30011,34917,159150,22710,14108,140685,159819,160205,15444,160384,160389,37505,139642,160395,37680,160486,149968,27705,38047,160848,134904,34855,35061,141606,164979,137137,28344,150058,137248,14756,14009,23568,31203,17727,26294,171181,170148,35139,161740,161880,22230,16607,136714,14753,145199,164072,136133,29101,33638,162269,168360,23143,19639,159919,166315,162301,162314,162571,163174,147834,31555,31102,163849,28597,172767,27139,164632,21410,159239,37823,26678,38749,164207,163875,158133,136173,143919,163912,23941,166960,163971,22293,38947,166217,23979,149896,26046,27093,21458,150181,147329,15377,26422,163984,164084,164142,139169,164175,164233,164271,164378,164614,164655,164746,13770,164968,165546,18682,25574,166230,30728,37461,166328,17394,166375,17375,166376,166726,166868,23032,166921,36619,167877,168172,31569,168208,168252,15863,168286,150218,36816,29327,22155,169191,169449,169392,169400,169778,170193,170313,170346,170435,170536,170766,171354,171419,32415,171768,171811,19620,38215,172691,29090,172799,19857,36882,173515,19868,134300,36798,21953,36794,140464,36793,150163,17673,32383,28502,27313,20202,13540,166700,161949,14138,36480,137205,163876,166764,166809,162366,157359,15851,161365,146615,153141,153942,20122,155265,156248,22207,134765,36366,23405,147080,150686,25566,25296,137206,137339,25904,22061,154698,21530,152337,15814,171416,19581,22050,22046,32585,155352,22901,146752,34672,19996,135146,134473,145082,33047,40286,36120,30267,40005,30286,30649,37701,21554,33096,33527,22053,33074,33816,32957,21994,31074,22083,21526,134813,13774,22021,22001,26353,164578,13869,30004,22000,21946,21655,21874,134209,134294,24272,151880,134774,142434,134818,40619,32090,21982,135285,25245,38765,21652,36045,29174,37238,25596,25529,25598,21865,142147,40050,143027,20890,13535,134567,20903,21581,21790,21779,30310,36397,157834,30129,32950,34820,34694,35015,33206,33820,135361,17644,29444,149254,23440,33547,157843,22139,141044,163119,147875,163187,159440,160438,37232,135641,37384,146684,173737,134828,134905,29286,138402,18254,151490,163833,135147,16634,40029,25887,142752,18675,149472,171388,135148,134666,24674,161187,135149,null,155720,135559,29091,32398,40272,19994,19972,13687,23309,27826,21351,13996,14812,21373,13989,149016,22682,150382,33325,21579,22442,154261,133497,null,14930,140389,29556,171692,19721,39917,146686,171824,19547,151465,169374,171998,33884,146870,160434,157619,145184,25390,32037,147191,146988,14890,36872,21196,15988,13946,17897,132238,30272,23280,134838,30842,163630,22695,16575,22140,39819,23924,30292,173108,40581,19681,30201,14331,24857,143578,148466,null,22109,135849,22439,149859,171526,21044,159918,13741,27722,40316,31830,39737,22494,137068,23635,25811,169168,156469,160100,34477,134440,159010,150242,134513,null,20990,139023,23950,38659,138705,40577,36940,31519,39682,23761,31651,25192,25397,39679,31695,39722,31870,39726,31810,31878,39957,31740,39689,40727,39963,149822,40794,21875,23491,20477,40600,20466,21088,15878,21201,22375,20566,22967,24082,38856,40363,36700,21609,38836,39232,38842,21292,24880,26924,21466,39946,40194,19515,38465,27008,20646,30022,137069,39386,21107,null,37209,38529,37212,null,37201,167575,25471,159011,27338,22033,37262,30074,25221,132092,29519,31856,154657,146685,null,149785,30422,39837,20010,134356,33726,34882,null,23626,27072,20717,22394,21023,24053,20174,27697,131570,20281,21660,21722,21146,36226,13822,24332,13811,null,27474,37244,40869,39831,38958,39092,39610,40616,40580,29050,31508,null,27642,34840,32632,null,22048,173642,36471,40787,null,36308,36431,40476,36353,25218,164733,36392,36469,31443,150135,31294,30936,27882,35431,30215,166490,40742,27854,34774,30147,172722,30803,194624,36108,29410,29553,35629,29442,29937,36075,150203,34351,24506,34976,17591,null,137275,159237,null,35454,140571,null,24829,30311,39639,40260,37742,39823,34805,null,34831,36087,29484,38689,39856,13782,29362,19463,31825,39242,155993,24921,19460,40598,24957,null,22367,24943,25254,25145,25294,14940,25058,21418,144373,25444,26626,13778,23895,166850,36826,167481,null,20697,138566,30982,21298,38456,134971,16485,null,30718,null,31938,155418,31962,31277,32870,32867,32077,29957,29938,35220,33306,26380,32866,160902,32859,29936,33027,30500,35209,157644,30035,159441,34729,34766,33224,34700,35401,36013,35651,30507,29944,34010,13877,27058,36262,null,35241,29800,28089,34753,147473,29927,15835,29046,24740,24988,15569,29026,24695,null,32625,166701,29264,24809,19326,21024,15384,146631,155351,161366,152881,137540,135934,170243,159196,159917,23745,156077,166415,145015,131310,157766,151310,17762,23327,156492,40784,40614,156267,12288,65292,12289,12290,65294,8231,65307,65306,65311,65281,65072,8230,8229,65104,65105,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075,9588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309,65081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087,65088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,65115,65116,65117,65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,167,12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,12963,8453,175,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,65120,65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,8734,8786,8801,65122,65123,65124,65125,65126,65374,8745,8746,8869,8736,8735,8895,13266,13265,8747,8750,8757,8756,9792,9794,8853,8857,8593,8595,8592,8594,8598,8599,8601,8600,8741,8739,65295,65340,8725,65128,65284,65509,12306,65504,65505,65285,65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,13217,13198,13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,31950,9601,9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,9609,9532,9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,9582,9584,9583,9552,9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,12321,12322,12323,12324,12325,12326,12327,12328,12329,21313,21316,21317,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,12585,729,713,714,711,715,9216,9217,9218,9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240,9241,9242,9243,9244,9245,9246,9247,9249,8364,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,19968,20057,19969,19971,20035,20061,20102,20108,20154,20799,20837,20843,20960,20992,20993,21147,21269,21313,21340,21448,19977,19979,19976,19978,20011,20024,20961,20037,20040,20063,20062,20110,20129,20800,20995,21242,21315,21449,21475,22303,22763,22805,22823,22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,24037,24049,24050,24051,24062,24178,24318,24331,24339,25165,19985,19984,19981,20013,20016,20025,20043,23609,20104,20113,20117,20114,20116,20130,20161,20160,20163,20166,20167,20173,20170,20171,20164,20803,20801,20839,20845,20846,20844,20887,20982,20998,20999,21000,21243,21246,21247,21270,21305,21320,21319,21317,21342,21380,21451,21450,21453,22764,22825,22827,22826,22829,23380,23569,23588,23610,23663,24052,24187,24319,24340,24341,24515,25096,25142,25163,25166,25903,25991,26007,26020,26041,26085,26352,26376,26408,27424,27490,27513,27595,27604,27611,27663,27700,28779,29226,29238,29243,29255,29273,29275,29356,29579,19993,19990,19989,19988,19992,20027,20045,20047,20046,20197,20184,20180,20181,20182,20183,20195,20196,20185,20190,20805,20804,20873,20874,20908,20985,20986,20984,21002,21152,21151,21253,21254,21271,21277,20191,21322,21321,21345,21344,21359,21358,21435,21487,21476,21491,21484,21486,21481,21480,21500,21496,21493,21483,21478,21482,21490,21489,21488,21477,21485,21499,22235,22234,22806,22830,22833,22900,22902,23381,23427,23612,24040,24039,24038,24066,24067,24179,24188,24321,24344,24343,24517,25098,25171,25172,25170,25169,26021,26086,26414,26412,26410,26411,26413,27491,27597,27665,27664,27704,27713,27712,27710,29359,29572,29577,29916,29926,29976,29983,29992,29993,30000,30001,30002,30003,30091,30333,30382,30399,30446,30683,30690,30707,31034,31166,31348,31435,19998,19999,20050,20051,20073,20121,20132,20134,20133,20223,20233,20249,20234,20245,20237,20240,20241,20239,20210,20214,20219,20208,20211,20221,20225,20235,20809,20807,20806,20808,20840,20849,20877,20912,21015,21009,21010,21006,21014,21155,21256,21281,21280,21360,21361,21513,21519,21516,21514,21520,21505,21515,21508,21521,21517,21512,21507,21518,21510,21522,22240,22238,22237,22323,22320,22312,22317,22316,22319,22313,22809,22810,22839,22840,22916,22904,22915,22909,22905,22914,22913,23383,23384,23431,23432,23429,23433,23546,23574,23673,24030,24070,24182,24180,24335,24347,24537,24534,25102,25100,25101,25104,25187,25179,25176,25910,26089,26088,26092,26093,26354,26355,26377,26429,26420,26417,26421,27425,27492,27515,27670,27741,27735,27737,27743,27744,27728,27733,27745,27739,27725,27726,28784,29279,29277,30334,31481,31859,31992,32566,32650,32701,32769,32771,32780,32786,32819,32895,32905,32907,32908,33251,33258,33267,33276,33292,33307,33311,33390,33394,33406,34411,34880,34892,34915,35199,38433,20018,20136,20301,20303,20295,20311,20318,20276,20315,20309,20272,20304,20305,20285,20282,20280,20291,20308,20284,20294,20323,20316,20320,20271,20302,20278,20313,20317,20296,20314,20812,20811,20813,20853,20918,20919,21029,21028,21033,21034,21032,21163,21161,21162,21164,21283,21363,21365,21533,21549,21534,21566,21542,21582,21543,21574,21571,21555,21576,21570,21531,21545,21578,21561,21563,21560,21550,21557,21558,21536,21564,21568,21553,21547,21535,21548,22250,22256,22244,22251,22346,22353,22336,22349,22343,22350,22334,22352,22351,22331,22767,22846,22941,22930,22952,22942,22947,22937,22934,22925,22948,22931,22922,22949,23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,23614,23696,23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,24420,24418,24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,25105,25220,25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,25234,25199,25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,26463,26446,26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,27493,27599,27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,27760,27788,27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,27796,27800,27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,29996,29995,30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,32918,32915,32925,32920,32923,32922,32946,33391,33426,33419,33421,35211,35282,35328,35895,35910,35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,36806,36805,36804,24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,38446,38449,38442,38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,20381,20365,20339,20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,20347,20374,20350,20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,20925,20989,21051,21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,21332,21331,21329,21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,21624,21653,21632,21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,21658,21602,21608,21643,21629,21646,22266,22403,22391,22378,22377,22369,22374,22372,22396,22812,22857,22855,22856,22852,22868,22974,22971,22996,22969,22958,22993,22982,22992,22989,22987,22995,22986,22959,22963,22994,22981,23391,23396,23395,23447,23450,23448,23452,23449,23451,23578,23624,23621,23622,23735,23713,23736,23721,23723,23729,23731,24088,24090,24086,24085,24091,24081,24184,24218,24215,24220,24213,24214,24310,24358,24359,24361,24448,24449,24447,24444,24541,24544,24573,24565,24575,24591,24596,24623,24629,24598,24618,24597,24609,24615,24617,24619,24603,25110,25109,25151,25150,25152,25215,25289,25292,25284,25279,25282,25273,25298,25307,25259,25299,25300,25291,25288,25256,25277,25276,25296,25305,25287,25293,25269,25306,25265,25304,25302,25303,25286,25260,25294,25918,26023,26044,26106,26132,26131,26124,26118,26114,26126,26112,26127,26133,26122,26119,26381,26379,26477,26507,26517,26481,26524,26483,26487,26503,26525,26519,26479,26480,26495,26505,26494,26512,26485,26522,26515,26492,26474,26482,27427,27494,27495,27519,27667,27675,27875,27880,27891,27825,27852,27877,27827,27837,27838,27836,27874,27819,27861,27859,27832,27844,27833,27841,27822,27863,27845,27889,27839,27835,27873,27867,27850,27820,27887,27868,27862,27872,28821,28814,28818,28810,28825,29228,29229,29240,29256,29287,29289,29376,29390,29401,29399,29392,29609,29608,29599,29611,29605,30013,30109,30105,30106,30340,30402,30450,30452,30693,30717,31038,31040,31041,31177,31176,31354,31353,31482,31998,32596,32652,32651,32773,32954,32933,32930,32945,32929,32939,32937,32948,32938,32943,33253,33278,33293,33459,33437,33433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470,33463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046,37319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738,38750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419,20406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407,20823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193,21187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688,21670,21683,21703,21698,21693,21674,21697,21700,21704,21679,21675,21681,21691,21673,21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,22865,22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,23014,23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,23627,23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,24421,24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,24616,24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,25366,25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,25332,25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,26143,26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,26613,26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,26585,26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,27954,27946,27969,27941,27916,27953,27934,27927,27963,27965,27966,27958,27931,27893,27961,27943,27960,27945,27950,27957,27918,27947,28843,28858,28851,28844,28847,28845,28856,28846,28836,29232,29298,29295,29300,29417,29408,29409,29623,29642,29627,29618,29645,29632,29619,29978,29997,30031,30028,30030,30027,30123,30116,30117,30114,30115,30328,30342,30343,30344,30408,30406,30403,30405,30465,30457,30456,30473,30475,30462,30460,30471,30684,30722,30740,30732,30733,31046,31049,31048,31047,31161,31162,31185,31186,31179,31359,31361,31487,31485,31869,32002,32005,32000,32009,32007,32004,32006,32568,32654,32703,32772,32784,32781,32785,32822,32982,32997,32986,32963,32964,32972,32993,32987,32974,32990,32996,32989,33268,33314,33511,33539,33541,33507,33499,33510,33540,33509,33538,33545,33490,33495,33521,33537,33500,33492,33489,33502,33491,33503,33519,33542,34384,34425,34427,34426,34893,34923,35201,35284,35336,35330,35331,35998,36000,36212,36211,36276,36557,36556,36848,36838,36834,36842,36837,36845,36843,36836,36840,37066,37070,37057,37059,37195,37194,37325,38274,38480,38475,38476,38477,38754,38761,38859,38893,38899,38913,39080,39131,39135,39318,39321,20056,20147,20492,20493,20515,20463,20518,20517,20472,20521,20502,20486,20540,20511,20506,20498,20497,20474,20480,20500,20520,20465,20513,20491,20505,20504,20467,20462,20525,20522,20478,20523,20489,20860,20900,20901,20898,20941,20940,20934,20939,21078,21084,21076,21083,21085,21290,21375,21407,21405,21471,21736,21776,21761,21815,21756,21733,21746,21766,21754,21780,21737,21741,21729,21769,21742,21738,21734,21799,21767,21757,21775,22275,22276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,23064,23068,23071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,23640,23472,23475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,23789,23805,23803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,24237,24231,24369,24466,24465,24464,24665,24675,24677,24656,24661,24685,24681,24687,24708,24735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,25406,25391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,25421,25420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,26181,26177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,26708,26665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,26693,26643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,28010,28053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,28020,28009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,28879,29241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,29674,29662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,30140,30137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,30697,30768,30759,30776,30749,30772,30775,30757,30765,30752,30751,30770,31061,31056,31072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,31192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,32020,32016,32021,32026,32028,32013,32025,32027,32570,32607,32660,32709,32705,32774,32792,32789,32793,32791,32829,32831,33009,33026,33008,33029,33005,33012,33030,33016,33011,33032,33021,33034,33020,33007,33261,33260,33280,33296,33322,33323,33320,33324,33467,33579,33618,33620,33610,33592,33616,33609,33589,33588,33615,33586,33593,33590,33559,33600,33585,33576,33603,34388,34442,34474,34451,34468,34473,34444,34467,34460,34928,34935,34945,34946,34941,34937,35352,35344,35342,35340,35349,35338,35351,35347,35350,35343,35345,35912,35962,35961,36001,36002,36215,36524,36562,36564,36559,36785,36865,36870,36855,36864,36858,36852,36867,36861,36869,36856,37013,37089,37085,37090,37202,37197,37196,37336,37341,37335,37340,37337,38275,38498,38499,38497,38491,38493,38500,38488,38494,38587,39138,39340,39592,39640,39717,39730,39740,20094,20602,20605,20572,20551,20547,20556,20570,20553,20581,20598,20558,20565,20597,20596,20599,20559,20495,20591,20589,20828,20885,20976,21098,21103,21202,21209,21208,21205,21264,21263,21273,21311,21312,21310,21443,26364,21830,21866,21862,21828,21854,21857,21827,21834,21809,21846,21839,21845,21807,21860,21816,21806,21852,21804,21859,21811,21825,21847,22280,22283,22281,22495,22533,22538,22534,22496,22500,22522,22530,22581,22519,22521,22816,22882,23094,23105,23113,23142,23146,23104,23100,23138,23130,23110,23114,23408,23495,23493,23492,23490,23487,23494,23561,23560,23559,23648,23644,23645,23815,23814,23822,23835,23830,23842,23825,23849,23828,23833,23844,23847,23831,24034,24120,24118,24115,24119,24247,24248,24246,24245,24254,24373,24375,24407,24428,24425,24427,24471,24473,24478,24472,24481,24480,24476,24703,24739,24713,24736,24744,24779,24756,24806,24765,24773,24763,24757,24796,24764,24792,24789,24774,24799,24760,24794,24775,25114,25115,25160,25504,25511,25458,25494,25506,25509,25463,25447,25496,25514,25457,25513,25481,25475,25499,25451,25512,25476,25480,25497,25505,25516,25490,25487,25472,25467,25449,25448,25466,25949,25942,25937,25945,25943,21855,25935,25944,25941,25940,26012,26011,26028,26063,26059,26060,26062,26205,26202,26212,26216,26214,26206,26361,21207,26395,26753,26799,26786,26771,26805,26751,26742,26801,26791,26775,26800,26755,26820,26797,26758,26757,26772,26781,26792,26783,26785,26754,27442,27578,27627,27628,27691,28046,28092,28147,28121,28082,28129,28108,28132,28155,28154,28165,28103,28107,28079,28113,28078,28126,28153,28088,28151,28149,28101,28114,28186,28085,28122,28139,28120,28138,28145,28142,28136,28102,28100,28074,28140,28095,28134,28921,28937,28938,28925,28911,29245,29309,29313,29468,29467,29462,29459,29465,29575,29701,29706,29699,29702,29694,29709,29920,29942,29943,29980,29986,30053,30054,30050,30064,30095,30164,30165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524,30518,30520,30522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520,31528,31515,31532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113,32046,32057,32060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670,32666,32716,32718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072,33060,33282,33333,33335,33334,33337,33678,33694,33688,33656,33698,33686,33725,33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,34389,24426,34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,34974,34952,34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,35377,35373,35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,36199,36198,36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,36880,36885,36894,36896,36879,36898,36886,36891,36884,37096,37101,37117,37207,37326,37365,37350,37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,38516,38518,38519,38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,40565,40575,40613,40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,26368,20977,21106,21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,21927,21884,21898,21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,21934,21919,21822,21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,22575,22570,22580,22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,23194,23167,23186,23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,23601,23884,23888,23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,24258,24260,24380,24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,24867,24826,24853,24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,25119,25161,25507,25484,25551,25536,25577,25545,25542,25549,25554,25571,25552,25569,25558,25581,25582,25462,25588,25578,25563,25682,25562,25593,25950,25958,25954,25955,26001,26000,26031,26222,26224,26228,26230,26223,26257,26234,26238,26231,26366,26367,26399,26397,26874,26837,26848,26840,26839,26885,26847,26869,26862,26855,26873,26834,26866,26851,26827,26829,26893,26898,26894,26825,26842,26990,26875,27454,27450,27453,27544,27542,27580,27631,27694,27695,27692,28207,28216,28244,28193,28210,28263,28234,28192,28197,28195,28187,28251,28248,28196,28246,28270,28205,28198,28271,28212,28237,28218,28204,28227,28189,28222,28363,28297,28185,28238,28259,28228,28274,28265,28255,28953,28954,28966,28976,28961,28982,29038,28956,29260,29316,29312,29494,29477,29492,29481,29754,29738,29747,29730,29733,29749,29750,29748,29743,29723,29734,29736,29989,29990,30059,30058,30178,30171,30179,30169,30168,30174,30176,30331,30332,30358,30355,30388,30428,30543,30701,30813,30828,30831,31245,31240,31243,31237,31232,31384,31383,31382,31461,31459,31561,31574,31558,31568,31570,31572,31565,31563,31567,31569,31903,31909,32094,32080,32104,32085,32043,32110,32114,32097,32102,32098,32112,32115,21892,32724,32725,32779,32850,32901,33109,33108,33099,33105,33102,33081,33094,33086,33100,33107,33140,33298,33308,33769,33795,33784,33805,33760,33733,33803,33729,33775,33777,33780,33879,33802,33776,33804,33740,33789,33778,33738,33848,33806,33796,33756,33799,33748,33759,34395,34527,34521,34541,34516,34523,34532,34512,34526,34903,35009,35010,34993,35203,35222,35387,35424,35413,35422,35388,35393,35412,35419,35408,35398,35380,35386,35382,35414,35937,35970,36015,36028,36019,36029,36033,36027,36032,36020,36023,36022,36031,36024,36234,36229,36225,36302,36317,36299,36314,36305,36300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918,37122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389,37392,37383,37393,38292,38287,38283,38289,38291,38290,38286,38538,38542,38539,38525,38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,38860,38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,40653,40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,20679,21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,21990,21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,21961,22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,22626,22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,23913,23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,24863,24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,24845,24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,25628,25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,26248,26262,26244,26264,26253,26371,27028,26989,26970,26999,26976,26964,26997,26928,27010,26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,27506,27584,27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,28357,28325,28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,28340,29006,29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,28998,29032,29014,29242,29266,29495,29509,29503,29502,29807,29786,29781,29791,29790,29761,29759,29785,29787,29788,30070,30072,30208,30192,30209,30194,30193,30202,30207,30196,30195,30430,30431,30555,30571,30566,30558,30563,30585,30570,30572,30556,30565,30568,30562,30702,30862,30896,30871,30872,30860,30857,30844,30865,30867,30847,31098,31103,31105,33836,31165,31260,31258,31264,31252,31263,31262,31391,31392,31607,31680,31584,31598,31591,31921,31923,31925,32147,32121,32145,32129,32143,32091,32622,32617,32618,32626,32681,32680,32676,32854,32856,32902,32900,33137,33136,33144,33125,33134,33139,33131,33145,33146,33126,33285,33351,33922,33911,33853,33841,33909,33894,33899,33865,33900,33883,33852,33845,33889,33891,33897,33901,33862,34398,34396,34399,34553,34579,34568,34567,34560,34558,34555,34562,34563,34566,34570,34905,35039,35028,35033,35036,35032,35037,35041,35018,35029,35026,35228,35299,35435,35442,35443,35430,35433,35440,35463,35452,35427,35488,35441,35461,35437,35426,35438,35436,35449,35451,35390,35432,35938,35978,35977,36042,36039,36040,36036,36018,36035,36034,36037,36321,36319,36328,36335,36339,36346,36330,36324,36326,36530,36611,36617,36606,36618,36767,36786,36939,36938,36947,36930,36948,36924,36949,36944,36935,36943,36942,36941,36945,36926,36929,37138,37143,37228,37226,37225,37321,37431,37463,37432,37437,37440,37438,37467,37451,37476,37457,37428,37449,37453,37445,37433,37439,37466,38296,38552,38548,38549,38605,38603,38601,38602,38647,38651,38649,38646,38742,38772,38774,38928,38929,38931,38922,38930,38924,39164,39156,39165,39166,39347,39345,39348,39649,40169,40578,40718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689,20721,20686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039,22013,22036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296,22294,22645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820,22890,22889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521,23525,23526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149,24151,24148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930,24931,24927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722,25681,25703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036,27048,27029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085,27053,27084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404,28457,28478,28448,28460,28431,28418,28450,28415,28399,28422,28465,28472,28466,28451,28437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,29066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,29956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,30913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,31469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,31929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,32186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,32862,32858,32903,33104,33152,33167,33160,33162,33151,33154,33255,33274,33287,33300,33310,33355,33993,33983,33990,33988,33945,33950,33970,33948,33995,33976,33984,34003,33936,33980,34001,33994,34623,34588,34619,34594,34597,34612,34584,34645,34615,34601,35059,35074,35060,35065,35064,35069,35048,35098,35055,35494,35468,35486,35491,35469,35489,35475,35492,35498,35493,35496,35480,35473,35482,35495,35946,35981,35980,36051,36049,36050,36203,36249,36245,36348,36628,36626,36629,36627,36771,36960,36952,36956,36963,36953,36958,36962,36957,36955,37145,37144,37150,37237,37240,37239,37236,37496,37504,37509,37528,37526,37499,37523,37532,37544,37500,37521,38305,38312,38313,38307,38309,38308,38553,38556,38555,38604,38610,38656,38780,38789,38902,38935,38936,39087,39089,39171,39173,39180,39177,39361,39599,39600,39654,39745,39746,40180,40182,40179,40636,40763,40778,20740,20736,20731,20725,20729,20738,20744,20745,20741,20956,21127,21128,21129,21133,21130,21232,21426,22062,22075,22073,22066,22079,22068,22057,22099,22094,22103,22132,22070,22063,22064,22656,22687,22686,22707,22684,22702,22697,22694,22893,23305,23291,23307,23285,23308,23304,23534,23532,23529,23531,23652,23653,23965,23956,24162,24159,24161,24290,24282,24287,24285,24291,24288,24392,24433,24503,24501,24950,24935,24942,24925,24917,24962,24956,24944,24939,24958,24999,24976,25003,24974,25004,24986,24996,24980,25006,25134,25705,25711,25721,25758,25778,25736,25744,25776,25765,25747,25749,25769,25746,25774,25773,25771,25754,25772,25753,25762,25779,25973,25975,25976,26286,26283,26292,26289,27171,27167,27112,27137,27166,27161,27133,27169,27155,27146,27123,27138,27141,27117,27153,27472,27470,27556,27589,27590,28479,28540,28548,28497,28518,28500,28550,28525,28507,28536,28526,28558,28538,28528,28516,28567,28504,28373,28527,28512,28511,29087,29100,29105,29096,29270,29339,29518,29527,29801,29835,29827,29822,29824,30079,30240,30249,30239,30244,30246,30241,30242,30362,30394,30436,30606,30599,30604,30609,30603,30923,30917,30906,30922,30910,30933,30908,30928,31295,31292,31296,31293,31287,31291,31407,31406,31661,31665,31684,31668,31686,31687,31681,31648,31692,31946,32224,32244,32239,32251,32216,32236,32221,32232,32227,32218,32222,32233,32158,32217,32242,32249,32629,32631,32687,32745,32806,33179,33180,33181,33184,33178,33176,34071,34109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028,34085,34047,34054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636,34643,34907,34909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524,35477,35531,35576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547,35916,35918,35948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074,36065,36205,36255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382,36538,36637,36635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968,36973,36983,37168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559,37610,37548,37604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660,38662,38663,38665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187,39186,39192,39389,39376,39391,39387,39377,39381,39378,39385,39607,39662,39663,39719,39749,39748,39799,39791,40198,40201,40195,40617,40638,40654,22696,40786,20754,20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,22105,22123,22137,22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,22134,22721,22718,22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,24977,25001,24970,25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,25788,25818,25796,25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,26297,26308,26311,26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,27233,27211,27207,27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,28580,28609,28583,28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,29138,29128,29141,29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,29855,29854,29922,29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,30629,30952,30938,30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,31761,31689,31716,31707,31713,31721,31718,31957,31958,32266,32273,32264,32283,32291,32286,32285,32265,32272,32633,32690,32752,32753,32750,32808,33203,33193,33192,33275,33288,33368,33369,34122,34137,34120,34152,34153,34115,34121,34157,34154,34142,34691,34719,34718,34722,34701,34913,35114,35122,35109,35115,35105,35242,35238,35558,35578,35563,35569,35584,35548,35559,35566,35582,35585,35586,35575,35565,35571,35574,35580,35947,35949,35987,36084,36420,36401,36404,36418,36409,36405,36667,36655,36664,36659,36776,36774,36981,36980,36984,36978,36988,36986,37172,37266,37664,37686,37624,37683,37679,37666,37628,37675,37636,37658,37648,37670,37665,37653,37678,37657,38331,38567,38568,38570,38613,38670,38673,38678,38669,38675,38671,38747,38748,38758,38808,38960,38968,38971,38967,38957,38969,38948,39184,39208,39198,39195,39201,39194,39405,39394,39409,39608,39612,39675,39661,39720,39825,40213,40227,40230,40232,40210,40219,40664,40660,40845,40860,20778,20767,20769,20786,21237,22158,22144,22160,22149,22151,22159,22741,22739,22737,22734,23344,23338,23332,23418,23607,23656,23996,23994,23997,23992,24171,24396,24509,25033,25026,25031,25062,25035,25138,25140,25806,25802,25816,25824,25840,25830,25836,25841,25826,25837,25986,25987,26329,26326,27264,27284,27268,27298,27292,27355,27299,27262,27287,27280,27296,27484,27566,27610,27656,28632,28657,28639,28640,28635,28644,28651,28655,28544,28652,28641,28649,28629,28654,28656,29159,29151,29166,29158,29157,29165,29164,29172,29152,29237,29254,29552,29554,29865,29872,29862,29864,30278,30274,30284,30442,30643,30634,30640,30636,30631,30637,30703,30967,30970,30964,30959,30977,31143,31146,31319,31423,31751,31757,31742,31735,31756,31712,31968,31964,31966,31970,31967,31961,31965,32302,32318,32326,32311,32306,32323,32299,32317,32305,32325,32321,32308,32313,32328,32309,32319,32303,32580,32755,32764,32881,32882,32880,32879,32883,33222,33219,33210,33218,33216,33215,33213,33225,33214,33256,33289,33393,34218,34180,34174,34204,34193,34196,34223,34203,34183,34216,34186,34407,34752,34769,34739,34770,34758,34731,34747,34746,34760,34763,35131,35126,35140,35128,35133,35244,35598,35607,35609,35611,35594,35616,35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,36425,36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,36994,36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,37656,37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,38584,38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,39850,39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,22165,22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,25851,25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,27487,27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,29176,29559,29557,29863,29887,29973,30294,30296,30290,30653,30655,30651,30652,30990,31150,31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,31975,32340,32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,33229,33231,33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,34796,34802,34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,36451,36454,36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,37328,37780,37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,38358,38352,38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,38989,38991,38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,39683,39686,39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,40672,40725,40748,20787,22181,22750,22751,22754,23541,40848,24300,25074,25079,25078,25077,25856,25871,26336,26333,27365,27357,27354,27347,28699,28703,28712,28698,28701,28693,28696,29190,29197,29272,29346,29560,29562,29885,29898,29923,30087,30086,30303,30305,30663,31001,31153,31339,31337,31806,31807,31800,31805,31799,31808,32363,32365,32377,32361,32362,32645,32371,32694,32697,32696,33240,34281,34269,34282,34261,34276,34277,34295,34811,34821,34829,34809,34814,35168,35167,35158,35166,35649,35676,35672,35657,35674,35662,35663,35654,35673,36104,36106,36476,36466,36487,36470,36460,36474,36468,36692,36686,36781,37002,37003,37297,37294,37857,37841,37855,37827,37832,37852,37853,37846,37858,37837,37848,37860,37847,37864,38364,38580,38627,38698,38695,38753,38876,38907,39006,39000,39003,39100,39237,39241,39446,39449,39693,39912,39911,39894,39899,40329,40289,40306,40298,40300,40594,40599,40595,40628,21240,22184,22199,22198,22196,22204,22756,23360,23363,23421,23542,24009,25080,25082,25880,25876,25881,26342,26407,27372,28734,28720,28722,29200,29563,29903,30306,30309,31014,31018,31020,31019,31431,31478,31820,31811,31821,31983,31984,36782,32381,32380,32386,32588,32768,33242,33382,34299,34297,34321,34298,34310,34315,34311,34314,34836,34837,35172,35258,35320,35696,35692,35686,35695,35679,35691,36111,36109,36489,36481,36485,36482,37300,37323,37912,37891,37885,38369,38704,39108,39250,39249,39336,39467,39472,39479,39477,39955,39949,40569,40629,40680,40751,40799,40803,40801,20791,20792,22209,22208,22210,22804,23660,24013,25084,25086,25885,25884,26005,26345,27387,27396,27386,27570,28748,29211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349,34330,34851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490,36493,36491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370,38712,38713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764,39761,39981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807,20796,20795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489,28753,28760,29568,29924,30090,30318,30316,31155,31840,31839,32894,32893,33247,35186,35183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717,38718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995,40403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348,27408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865,35722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635,39636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321,30322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312,37994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572,40573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313,38002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522,39525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015,40474,29224,39530,39729,40475,40478,31858,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,20022,20031,20101,20128,20866,20886,20907,21241,21304,21353,21430,22794,23424,24027,12083,24191,24308,24400,24417,25908,26080,30098,30326,36789,38582,168,710,12541,12542,12445,12446,12291,20189,12293,12294,12295,12540,65339,65341,10045,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,8679,8632,8633,12751,131276,20058,131210,20994,17553,40880,20872,40881,161287,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,65506,65508,65287,65282,12849,8470,8481,12443,12444,11904,11908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,11946,11948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,11998,12003,null,null,null,643,592,603,596,629,339,248,331,650,618,20034,20060,20981,21274,21378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,20014,20115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,24063,26081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,20186,21004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,23667,24068,24192,24194,24521,25097,25168,27669,27702,27715,27711,27707,29358,29360,29578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,20253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,21282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,22917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,23678,24031,24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,25185,25190,25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,26426,26431,26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,28785,29278,29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,33407,34381,35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,20283,20322,20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,20287,20321,20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,21391,21552,21559,21546,21588,21573,21529,21532,21541,21528,21565,21583,21569,21544,21540,21575,22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,22848,22950,22936,22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,23592,23594,23693,23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,24074,24078,24203,24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,24528,24557,24552,24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,24564,25146,25219,25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,25224,25207,25213,25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,26457,26453,26444,26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,27755,27780,27787,27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,27763,27749,27771,27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,29381,29589,29591,29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,32917,32921,32912,32914,32924,33424,33423,33413,33422,33425,33427,33418,33411,33412,35960,36809,36799,37023,37025,37029,37022,37031,37024,38448,38440,38447,38445,20019,20376,20348,20357,20349,20352,20359,20342,20340,20361,20356,20343,20300,20375,20330,20378,20345,20353,20344,20368,20380,20372,20382,20370,20354,20373,20331,20334,20894,20924,20926,21045,21042,21043,21062,21041,21180,21258,21259,21308,21394,21396,21639,21631,21633,21649,21634,21640,21611,21626,21630,21605,21612,21620,21606,21645,21615,21601,21600,21656,21603,21607,21604,22263,22265,22383,22386,22381,22379,22385,22384,22390,22400,22389,22395,22387,22388,22370,22376,22397,22796,22853,22965,22970,22991,22990,22962,22988,22977,22966,22972,22979,22998,22961,22973,22976,22984,22964,22983,23394,23397,23443,23445,23620,23623,23726,23716,23712,23733,23727,23720,23724,23711,23715,23725,23714,23722,23719,23709,23717,23734,23728,23718,24087,24084,24089,24360,24354,24355,24356,24404,24450,24446,24445,24542,24549,24621,24614,24601,24626,24587,24628,24586,24599,24627,24602,24606,24620,24610,24589,24592,24622,24595,24593,24588,24585,24604,25108,25149,25261,25268,25297,25278,25258,25270,25290,25262,25267,25263,25275,25257,25264,25272,25917,26024,26043,26121,26108,26116,26130,26120,26107,26115,26123,26125,26117,26109,26129,26128,26358,26378,26501,26476,26510,26514,26486,26491,26520,26502,26500,26484,26509,26508,26490,26527,26513,26521,26499,26493,26497,26488,26489,26516,27429,27520,27518,27614,27677,27795,27884,27883,27886,27865,27830,27860,27821,27879,27831,27856,27842,27834,27843,27846,27885,27890,27858,27869,27828,27786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857,28820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398,29387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606,29602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451,30449,30448,30453,30712,30716,30713,30715,30714,30711,31042,31039,31173,31352,31355,31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,33472,33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,33441,33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,36811,36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,38460,38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,20411,20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,21309,21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,21687,21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,21680,22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,22437,22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,23037,23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,23021,23464,23628,23760,23768,23756,23767,23755,23771,23774,23770,23753,23751,23754,23766,23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,24099,24096,24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,24631,24633,24660,24690,24670,24645,24659,24647,24649,24667,24652,24640,24642,24671,24612,24644,24664,24678,24686,25154,25155,25295,25357,25355,25333,25358,25347,25323,25337,25359,25356,25336,25334,25344,25363,25364,25338,25365,25339,25328,25921,25923,26026,26047,26166,26145,26162,26165,26140,26150,26146,26163,26155,26170,26141,26164,26169,26158,26383,26384,26561,26610,26568,26554,26588,26555,26616,26584,26560,26551,26565,26603,26596,26591,26549,26573,26547,26615,26614,26606,26595,26562,26553,26574,26599,26608,26546,26620,26566,26605,26572,26542,26598,26587,26618,26569,26570,26563,26602,26571,27432,27522,27524,27574,27606,27608,27616,27680,27681,27944,27956,27949,27935,27964,27967,27922,27914,27866,27955,27908,27929,27962,27930,27921,27904,27933,27970,27905,27928,27959,27907,27919,27968,27911,27936,27948,27912,27938,27913,27920,28855,28831,28862,28849,28848,28833,28852,28853,28841,29249,29257,29258,29292,29296,29299,29294,29386,29412,29416,29419,29407,29418,29414,29411,29573,29644,29634,29640,29637,29625,29622,29621,29620,29675,29631,29639,29630,29635,29638,29624,29643,29932,29934,29998,30023,30024,30119,30122,30329,30404,30472,30467,30468,30469,30474,30455,30459,30458,30695,30696,30726,30737,30738,30725,30736,30735,30734,30729,30723,30739,31050,31052,31051,31045,31044,31189,31181,31183,31190,31182,31360,31358,31441,31488,31489,31866,31864,31865,31871,31872,31873,32003,32008,32001,32600,32657,32653,32702,32775,32782,32783,32788,32823,32984,32967,32992,32977,32968,32962,32976,32965,32995,32985,32988,32970,32981,32969,32975,32983,32998,32973,33279,33313,33428,33497,33534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516,33505,33522,33525,33548,33531,33526,33520,33514,33508,33504,33530,33523,33517,34423,34420,34428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835,36833,36846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332,37331,38484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528,20507,20469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533,20527,20529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082,21074,21086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735,21747,21732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751,21752,21728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470,22461,22460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062,23085,23086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555,23638,23636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238,24234,24236,24371,24368,24423,24669,24666,24679,24641,24738,24712,24704,24722,24705,24733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430,25388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396,25432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930,25926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650,26697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671,26702,26692,26676,26653,26642,26644,26662,26664,26670,26701,26682,26661,26656,27436,27439,27437,27441,27444,27501,32898,27528,27622,27620,27624,27619,27618,27623,27685,28026,28003,28004,28022,27917,28001,28050,27992,28002,28013,28015,28049,28045,28143,28031,28038,27998,28007,28000,28055,28016,28028,27999,28034,28056,27951,28008,28043,28030,28032,28036,27926,28035,28027,28029,28021,28048,28892,28883,28881,28893,28875,32569,28898,28887,28882,28894,28896,28884,28877,28869,28870,28871,28890,28878,28897,29250,29304,29303,29302,29440,29434,29428,29438,29430,29427,29435,29441,29651,29657,29669,29654,29628,29671,29667,29673,29660,29650,29659,29652,29661,29658,29655,29656,29672,29918,29919,29940,29941,29985,30043,30047,30128,30145,30139,30148,30144,30143,30134,30138,30346,30409,30493,30491,30480,30483,30482,30499,30481,30485,30489,30490,30498,30503,30755,30764,30754,30773,30767,30760,30766,30763,30753,30761,30771,30762,30769,31060,31067,31055,31068,31059,31058,31057,31211,31212,31200,31214,31213,31210,31196,31198,31197,31366,31369,31365,31371,31372,31370,31367,31448,31504,31492,31507,31493,31503,31496,31498,31502,31497,31506,31876,31889,31882,31884,31880,31885,31877,32030,32029,32017,32014,32024,32022,32019,32031,32018,32015,32012,32604,32609,32606,32608,32605,32603,32662,32658,32707,32706,32704,32790,32830,32825,33018,33010,33017,33013,33025,33019,33024,33281,33327,33317,33587,33581,33604,33561,33617,33573,33622,33599,33601,33574,33564,33570,33602,33614,33563,33578,33544,33596,33613,33558,33572,33568,33591,33583,33577,33607,33605,33612,33619,33566,33580,33611,33575,33608,34387,34386,34466,34472,34454,34445,34449,34462,34439,34455,34438,34443,34458,34437,34469,34457,34465,34471,34453,34456,34446,34461,34448,34452,34883,34884,34925,34933,34934,34930,34944,34929,34943,34927,34947,34942,34932,34940,35346,35911,35927,35963,36004,36003,36214,36216,36277,36279,36278,36561,36563,36862,36853,36866,36863,36859,36868,36860,36854,37078,37088,37081,37082,37091,37087,37093,37080,37083,37079,37084,37092,37200,37198,37199,37333,37346,37338,38492,38495,38588,39139,39647,39727,20095,20592,20586,20577,20574,20576,20563,20555,20573,20594,20552,20557,20545,20571,20554,20578,20501,20549,20575,20585,20587,20579,20580,20550,20544,20590,20595,20567,20561,20944,21099,21101,21100,21102,21206,21203,21293,21404,21877,21878,21820,21837,21840,21812,21802,21841,21858,21814,21813,21808,21842,21829,21772,21810,21861,21838,21817,21832,21805,21819,21824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528,22509,22525,22536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508,22497,22542,22524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876,23136,23128,23125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123,23140,23127,23107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116,23152,23145,23111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838,23819,23837,23834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843,23839,23854,24126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470,24479,24714,24720,24710,24766,24752,24762,24787,24788,24783,24804,24793,24797,24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,25482,25474,25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,25454,25519,25461,25500,25453,25518,25468,25508,25403,25503,25464,25477,25473,25489,25485,25456,25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,26759,26768,26780,26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,26740,26802,26767,26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,26774,26763,26784,26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,27447,27448,27537,27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,28076,28137,28130,28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,28124,28125,28123,28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,28112,28146,28115,28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,28940,28912,28932,28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,28930,28942,29310,29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,29439,29455,29470,29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,29692,29695,29708,29707,29684,29704,30052,30051,30158,30162,30159,30155,30156,30161,30160,30351,30345,30419,30521,30511,30509,30513,30514,30516,30515,30525,30501,30523,30517,30792,30802,30793,30797,30794,30796,30758,30789,30800,31076,31079,31081,31082,31075,31083,31073,31163,31226,31224,31222,31223,31375,31380,31376,31541,31559,31540,31525,31536,31522,31524,31539,31512,31530,31517,31537,31531,31533,31535,31538,31544,31514,31523,31892,31896,31894,31907,32053,32061,32056,32054,32058,32069,32044,32041,32065,32071,32062,32063,32074,32059,32040,32611,32661,32668,32669,32667,32714,32715,32717,32720,32721,32711,32719,32713,32799,32798,32795,32839,32835,32840,33048,33061,33049,33051,33069,33055,33068,33054,33057,33045,33063,33053,33058,33297,33336,33331,33338,33332,33330,33396,33680,33699,33704,33677,33658,33651,33700,33652,33679,33665,33685,33689,33653,33684,33705,33661,33667,33676,33693,33691,33706,33675,33662,33701,33711,33672,33687,33712,33663,33702,33671,33710,33654,33690,34393,34390,34495,34487,34498,34497,34501,34490,34480,34504,34489,34483,34488,34508,34484,34491,34492,34499,34493,34494,34898,34953,34965,34984,34978,34986,34970,34961,34977,34975,34968,34983,34969,34971,34967,34980,34988,34956,34963,34958,35202,35286,35289,35285,35376,35367,35372,35358,35897,35899,35932,35933,35965,36005,36221,36219,36217,36284,36290,36281,36287,36289,36568,36574,36573,36572,36567,36576,36577,36900,36875,36881,36892,36876,36897,37103,37098,37104,37108,37106,37107,37076,37099,37100,37097,37206,37208,37210,37203,37205,37356,37364,37361,37363,37368,37348,37369,37354,37355,37367,37352,37358,38266,38278,38280,38524,38509,38507,38513,38511,38591,38762,38916,39141,39319,20635,20629,20628,20638,20619,20643,20611,20620,20622,20637,20584,20636,20626,20610,20615,20831,20948,21266,21265,21412,21415,21905,21928,21925,21933,21879,22085,21922,21907,21896,21903,21941,21889,21923,21906,21924,21885,21900,21926,21887,21909,21921,21902,22284,22569,22583,22553,22558,22567,22563,22568,22517,22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,22587,22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,23189,23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,23183,23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,23875,23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,23857,23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,24408,24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,24854,24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,24836,24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,25546,25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,25555,25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,25948,25960,25957,25996,26013,26014,26030,26064,26066,26236,26220,26235,26240,26225,26233,26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,26895,26838,26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,26992,26804,26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,26903,26830,26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,26823,27449,27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,27696,28156,28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,28225,28253,28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,28252,28257,28209,28200,28256,28273,28267,28217,28194,28208,28243,28261,28199,28280,28260,28279,28245,28281,28242,28262,28213,28214,28250,28960,28958,28975,28923,28974,28977,28963,28965,28962,28978,28959,28968,28986,28955,29259,29274,29320,29321,29318,29317,29323,29458,29451,29488,29474,29489,29491,29479,29490,29485,29478,29475,29493,29452,29742,29740,29744,29739,29718,29722,29729,29741,29745,29732,29731,29725,29737,29728,29746,29947,29999,30063,30060,30183,30170,30177,30182,30173,30175,30180,30167,30357,30354,30426,30534,30535,30532,30541,30533,30538,30542,30539,30540,30686,30700,30816,30820,30821,30812,30829,30833,30826,30830,30832,30825,30824,30814,30818,31092,31091,31090,31088,31234,31242,31235,31244,31236,31385,31462,31460,31562,31547,31556,31560,31564,31566,31552,31576,31557,31906,31902,31912,31905,32088,32111,32099,32083,32086,32103,32106,32079,32109,32092,32107,32082,32084,32105,32081,32095,32078,32574,32575,32613,32614,32674,32672,32673,32727,32849,32847,32848,33022,32980,33091,33098,33106,33103,33095,33085,33101,33082,33254,33262,33271,33272,33273,33284,33340,33341,33343,33397,33595,33743,33785,33827,33728,33768,33810,33767,33764,33788,33782,33808,33734,33736,33771,33763,33727,33793,33757,33765,33752,33791,33761,33739,33742,33750,33781,33737,33801,33807,33758,33809,33798,33730,33779,33749,33786,33735,33745,33770,33811,33731,33772,33774,33732,33787,33751,33762,33819,33755,33790,34520,34530,34534,34515,34531,34522,34538,34525,34539,34524,34540,34537,34519,34536,34513,34888,34902,34901,35002,35031,35001,35000,35008,35006,34998,35004,34999,35005,34994,35073,35017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392,35415,35416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968,36026,36030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310,36316,36303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590,36581,36597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911,37126,37164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123,37217,37220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388,37376,37394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381,37398,38267,38285,38284,38288,38535,38526,38536,38537,38531,38528,38594,38600,38595,38641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150,20669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657,20683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968,21963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986,21974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601,22639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236,23243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242,23220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882,23909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139,24261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901,24886,24882,24878,24902,24879,24911,24873,24896,25120,37224,25123,25125,25124,25541,25585,25579,25616,25618,25609,25632,25636,25651,25667,25631,25621,25624,25657,25655,25634,25635,25612,25638,25648,25640,25665,25653,25647,25610,25626,25664,25637,25639,25611,25575,25627,25646,25633,25614,25967,26002,26067,26246,26252,26261,26256,26251,26250,26265,26260,26232,26400,26982,26975,26936,26958,26978,26993,26943,26949,26986,26937,26946,26967,26969,27002,26952,26953,26933,26988,26931,26941,26981,26864,27000,26932,26985,26944,26991,26948,26998,26968,26945,26996,26956,26939,26955,26935,26972,26959,26961,26930,26962,26927,27003,26940,27462,27461,27459,27458,27464,27457,27547,64013,27643,27644,27641,27639,27640,28315,28374,28360,28303,28352,28319,28307,28308,28320,28337,28345,28358,28370,28349,28353,28318,28361,28343,28336,28365,28326,28367,28338,28350,28355,28380,28376,28313,28306,28302,28301,28324,28321,28351,28339,28368,28362,28311,28334,28323,28999,29012,29010,29027,29024,28993,29021,29026,29042,29048,29034,29025,28994,29016,28995,29003,29040,29023,29008,29011,28996,29005,29018,29263,29325,29324,29329,29328,29326,29500,29506,29499,29498,29504,29514,29513,29764,29770,29771,29778,29777,29783,29760,29775,29776,29774,29762,29766,29773,29780,29921,29951,29950,29949,29981,30073,30071,27011,30191,30223,30211,30199,30206,30204,30201,30200,30224,30203,30198,30189,30197,30205,30361,30389,30429,30549,30559,30560,30546,30550,30554,30569,30567,30548,30553,30573,30688,30855,30874,30868,30863,30852,30869,30853,30854,30881,30851,30841,30873,30848,30870,30843,31100,31106,31101,31097,31249,31256,31257,31250,31255,31253,31266,31251,31259,31248,31395,31394,31390,31467,31590,31588,31597,31604,31593,31602,31589,31603,31601,31600,31585,31608,31606,31587,31922,31924,31919,32136,32134,32128,32141,32127,32133,32122,32142,32123,32131,32124,32140,32148,32132,32125,32146,32621,32619,32615,32616,32620,32678,32677,32679,32731,32732,32801,33124,33120,33143,33116,33129,33115,33122,33138,26401,33118,33142,33127,33135,33092,33121,33309,33353,33348,33344,33346,33349,34033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926,33895,33840,33869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850,33844,33914,33859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887,33904,33849,33870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896,33918,33860,33835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518,34549,34637,34552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022,35038,35035,35034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298,35292,35302,35446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457,35444,35450,35900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200,36201,36241,36236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332,36337,36334,36304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609,36608,36613,36615,36616,36610,36619,36946,36927,36932,36937,36925,37136,37133,37135,37137,37142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427,37477,37470,37507,37422,37450,37446,37485,37484,37455,37472,37479,37487,37430,37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,37462,37426,38303,38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,38648,38645,38771,38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,39346,39344,39349,39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,20695,20712,20723,20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,20952,21120,21121,21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,22044,22017,22035,22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,22662,22657,22655,22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,22676,22671,22782,22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,23266,23264,23259,23276,23262,23261,23257,23272,23263,23415,23520,23523,23651,23938,23936,23933,23942,23930,23937,23927,23946,23945,23944,23934,23932,23949,23929,23935,24152,24153,24147,24280,24273,24279,24270,24284,24277,24281,24274,24276,24388,24387,24431,24502,24876,24872,24897,24926,24945,24947,24914,24915,24946,24940,24960,24948,24916,24954,24923,24933,24891,24938,24929,24918,25129,25127,25131,25643,25677,25691,25693,25716,25718,25714,25715,25725,25717,25702,25766,25678,25730,25694,25692,25675,25683,25696,25680,25727,25663,25708,25707,25689,25701,25719,25971,26016,26273,26272,26271,26373,26372,26402,27057,27062,27081,27040,27086,27030,27056,27052,27068,27025,27033,27022,27047,27021,27049,27070,27055,27071,27076,27069,27044,27092,27065,27082,27034,27087,27059,27027,27050,27041,27038,27097,27031,27024,27074,27061,27045,27078,27466,27469,27467,27550,27551,27552,27587,27588,27646,28366,28405,28401,28419,28453,28408,28471,28411,28462,28425,28494,28441,28442,28455,28440,28475,28434,28397,28426,28470,28531,28409,28398,28461,28480,28464,28476,28469,28395,28423,28430,28483,28421,28413,28406,28473,28444,28412,28474,28447,28429,28446,28424,28449,29063,29072,29065,29056,29061,29058,29071,29051,29062,29057,29079,29252,29267,29335,29333,29331,29507,29517,29521,29516,29794,29811,29809,29813,29810,29799,29806,29952,29954,29955,30077,30096,30230,30216,30220,30229,30225,30218,30228,30392,30593,30588,30597,30594,30574,30592,30575,30590,30595,30898,30890,30900,30893,30888,30846,30891,30878,30885,30880,30892,30882,30884,31128,31114,31115,31126,31125,31124,31123,31127,31112,31122,31120,31275,31306,31280,31279,31272,31270,31400,31403,31404,31470,31624,31644,31626,31633,31632,31638,31629,31628,31643,31630,31621,31640,21124,31641,31652,31618,31931,31935,31932,31930,32167,32183,32194,32163,32170,32193,32192,32197,32157,32206,32196,32198,32203,32204,32175,32185,32150,32188,32159,32166,32174,32169,32161,32201,32627,32738,32739,32741,32734,32804,32861,32860,33161,33158,33155,33159,33165,33164,33163,33301,33943,33956,33953,33951,33978,33998,33986,33964,33966,33963,33977,33972,33985,33997,33962,33946,33969,34000,33949,33959,33979,33954,33940,33991,33996,33947,33961,33967,33960,34006,33944,33974,33999,33952,34007,34004,34002,34011,33968,33937,34401,34611,34595,34600,34667,34624,34606,34590,34593,34585,34587,34627,34604,34625,34622,34630,34592,34610,34602,34605,34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,34577,35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,35051,35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,35478,35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,36362,36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,37148,37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,37541,37540,37494,37531,37498,37536,37524,37546,37517,37542,37530,37547,37497,37527,37503,37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,37516,37529,37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,38781,38778,38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,39085,39086,39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,39367,39601,39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,20735,20739,20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,21132,21233,21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,22080,22067,22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,22691,22703,22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,23298,23289,23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,23957,23968,23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,24289,24393,24498,24971,24963,24953,25009,25008,24994,24969,24987,24979,25007,25005,24991,24978,25002,24993,24973,24934,25011,25133,25710,25712,25750,25760,25733,25751,25756,25743,25739,25738,25740,25763,25759,25704,25777,25752,25974,25978,25977,25979,26034,26035,26293,26288,26281,26290,26295,26282,26287,27136,27142,27159,27109,27128,27157,27121,27108,27168,27135,27116,27106,27163,27165,27134,27175,27122,27118,27156,27127,27111,27200,27144,27110,27131,27149,27132,27115,27145,27140,27160,27173,27151,27126,27174,27143,27124,27158,27473,27557,27555,27554,27558,27649,27648,27647,27650,28481,28454,28542,28551,28614,28562,28557,28553,28556,28514,28495,28549,28506,28566,28534,28524,28546,28501,28530,28498,28496,28503,28564,28563,28509,28416,28513,28523,28541,28519,28560,28499,28555,28521,28543,28565,28515,28535,28522,28539,29106,29103,29083,29104,29088,29082,29097,29109,29085,29093,29086,29092,29089,29098,29084,29095,29107,29336,29338,29528,29522,29534,29535,29536,29533,29531,29537,29530,29529,29538,29831,29833,29834,29830,29825,29821,29829,29832,29820,29817,29960,29959,30078,30245,30238,30233,30237,30236,30243,30234,30248,30235,30364,30365,30366,30363,30605,30607,30601,30600,30925,30907,30927,30924,30929,30926,30932,30920,30915,30916,30921,31130,31137,31136,31132,31138,31131,27510,31289,31410,31412,31411,31671,31691,31678,31660,31694,31663,31673,31690,31669,31941,31944,31948,31947,32247,32219,32234,32231,32215,32225,32259,32250,32230,32246,32241,32240,32238,32223,32630,32684,32688,32685,32749,32747,32746,32748,32742,32744,32868,32871,33187,33183,33182,33173,33186,33177,33175,33302,33359,33363,33362,33360,33358,33361,34084,34107,34063,34048,34089,34062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060,34036,34090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046,34088,34077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031,34041,34072,34080,34096,34059,34073,34095,34402,34646,34659,34660,34679,34785,34675,34648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655,34653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665,34906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081,35234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541,35515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983,36069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387,36389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376,36371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979,36976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254,37258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617,37599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606,37581,37589,37577,37600,37598,37607,37585,37587,37557,37601,37574,37556,38268,38316,38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,38792,38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,39162,39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,39382,39384,39371,39383,39372,39603,39660,39659,39667,39666,39665,39750,39747,39783,39796,39793,39782,39798,39797,39792,39784,39780,39788,40188,40186,40189,40191,40183,40199,40192,40185,40187,40200,40197,40196,40579,40659,40719,40720,20764,20755,20759,20762,20753,20958,21300,21473,22128,22112,22126,22131,22118,22115,22125,22130,22110,22135,22300,22299,22728,22717,22729,22719,22714,22722,22716,22726,23319,23321,23323,23329,23316,23315,23312,23318,23336,23322,23328,23326,23535,23980,23985,23977,23975,23989,23984,23982,23978,23976,23986,23981,23983,23988,24167,24168,24166,24175,24297,24295,24294,24296,24293,24395,24508,24989,25000,24982,25029,25012,25030,25025,25036,25018,25023,25016,24972,25815,25814,25808,25807,25801,25789,25737,25795,25819,25843,25817,25907,25983,25980,26018,26312,26302,26304,26314,26315,26319,26301,26299,26298,26316,26403,27188,27238,27209,27239,27186,27240,27198,27229,27245,27254,27227,27217,27176,27226,27195,27199,27201,27242,27236,27216,27215,27220,27247,27241,27232,27196,27230,27222,27221,27213,27214,27206,27477,27476,27478,27559,27562,27563,27592,27591,27652,27651,27654,28589,28619,28579,28615,28604,28622,28616,28510,28612,28605,28574,28618,28584,28676,28581,28590,28602,28588,28586,28623,28607,28600,28578,28617,28587,28621,28591,28594,28592,29125,29122,29119,29112,29142,29120,29121,29131,29140,29130,29127,29135,29117,29144,29116,29126,29146,29147,29341,29342,29545,29542,29543,29548,29541,29547,29546,29823,29850,29856,29844,29842,29845,29857,29963,30080,30255,30253,30257,30269,30259,30268,30261,30258,30256,30395,30438,30618,30621,30625,30620,30619,30626,30627,30613,30617,30615,30941,30953,30949,30954,30942,30947,30939,30945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416,31413,31409,31415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700,31722,31714,31708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289,32279,32268,32287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278,32269,32276,32293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876,33201,33190,33198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266,33365,33366,33367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148,34113,34146,34116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133,34151,34144,34188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703,34711,34707,34706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705,34717,34692,34708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121,35106,35113,35107,35119,35116,35103,35313,35552,35554,35570,35572,35573,35549,35604,35556,35551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984,36085,36078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416,36421,36406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665,36663,36660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265,37261,37263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667,37650,37633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623,37684,37634,37668,37631,37673,37689,37685,37674,37652,37644,37643,37630,37641,37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,38325,38333,38569,38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,38959,38962,39204,39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,39402,39401,39399,39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,39813,39815,39804,39806,39803,39810,39827,39826,39824,39802,39829,39805,39816,40229,40215,40224,40222,40212,40233,40221,40216,40226,40208,40217,40223,40584,40582,40583,40622,40621,40661,40662,40698,40722,40765,20774,20773,20770,20772,20768,20777,21236,22163,22156,22157,22150,22148,22147,22142,22146,22143,22145,22742,22740,22735,22738,23341,23333,23346,23331,23340,23335,23334,23343,23342,23419,23537,23538,23991,24172,24170,24510,24507,25027,25013,25020,25063,25056,25061,25060,25064,25054,25839,25833,25827,25835,25828,25832,25985,25984,26038,26074,26322,27277,27286,27265,27301,27273,27295,27291,27297,27294,27271,27283,27278,27285,27267,27304,27300,27281,27263,27302,27290,27269,27276,27282,27483,27565,27657,28620,28585,28660,28628,28643,28636,28653,28647,28646,28638,28658,28637,28642,28648,29153,29169,29160,29170,29156,29168,29154,29555,29550,29551,29847,29874,29867,29840,29866,29869,29873,29861,29871,29968,29969,29970,29967,30084,30275,30280,30281,30279,30372,30441,30645,30635,30642,30647,30646,30644,30641,30632,30704,30963,30973,30978,30971,30972,30962,30981,30969,30974,30980,31147,31144,31324,31323,31318,31320,31316,31322,31422,31424,31425,31749,31759,31730,31744,31743,31739,31758,31732,31755,31731,31746,31753,31747,31745,31736,31741,31750,31728,31729,31760,31754,31976,32301,32316,32322,32307,38984,32312,32298,32329,32320,32327,32297,32332,32304,32315,32310,32324,32314,32581,32639,32638,32637,32756,32754,32812,33211,33220,33228,33226,33221,33223,33212,33257,33371,33370,33372,34179,34176,34191,34215,34197,34208,34187,34211,34171,34212,34202,34206,34167,34172,34185,34209,34170,34168,34135,34190,34198,34182,34189,34201,34205,34177,34210,34178,34184,34181,34169,34166,34200,34192,34207,34408,34750,34730,34733,34757,34736,34732,34745,34741,34748,34734,34761,34755,34754,34764,34743,34735,34756,34762,34740,34742,34751,34744,34749,34782,34738,35125,35123,35132,35134,35137,35154,35127,35138,35245,35247,35246,35314,35315,35614,35608,35606,35601,35589,35595,35618,35599,35602,35605,35591,35597,35592,35590,35612,35603,35610,35919,35952,35954,35953,35951,35989,35988,36089,36207,36430,36429,36435,36432,36428,36423,36675,36672,36997,36990,37176,37274,37282,37275,37273,37279,37281,37277,37280,37793,37763,37807,37732,37718,37703,37756,37720,37724,37750,37705,37712,37713,37728,37741,37775,37708,37738,37753,37719,37717,37714,37711,37745,37751,37755,37729,37726,37731,37735,37760,37710,37721,38343,38336,38345,38339,38341,38327,38574,38576,38572,38688,38687,38680,38685,38681,38810,38817,38812,38814,38813,38869,38868,38897,38977,38980,38986,38985,38981,38979,39205,39211,39212,39210,39219,39218,39215,39213,39217,39216,39320,39331,39329,39426,39418,39412,39415,39417,39416,39414,39419,39421,39422,39420,39427,39614,39678,39677,39681,39676,39752,39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,40243,40257,40295,40246,40238,40239,40241,40248,40240,40261,40258,40259,40254,40247,40256,40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,40740,40739,40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,22169,22896,23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,25066,25072,25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,26075,26330,26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,27316,27309,27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,28672,28667,28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,29888,29877,29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,30291,30295,30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,30992,30994,30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,31782,31784,31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,32352,32343,32339,32693,32691,32759,32760,32885,33233,33234,33232,33375,33374,34228,34246,34240,34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,34248,34245,34225,34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,34779,34795,34794,34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,34724,34775,34777,34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,35153,35145,35626,35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,35621,35639,35622,35638,35630,35620,35643,35645,35642,35906,35957,35993,35992,35991,36094,36100,36098,36096,36444,36450,36448,36439,36438,36446,36453,36455,36443,36442,36449,36445,36457,36436,36678,36679,36680,36683,37160,37178,37179,37182,37288,37285,37287,37295,37290,37813,37772,37778,37815,37787,37789,37769,37799,37774,37802,37790,37798,37781,37768,37785,37791,37773,37809,37777,37810,37796,37800,37812,37795,37797,38354,38355,38353,38579,38615,38618,24002,38623,38616,38621,38691,38690,38693,38828,38830,38824,38827,38820,38826,38818,38821,38871,38873,38870,38872,38906,38992,38993,38994,39096,39233,39228,39226,39439,39435,39433,39437,39428,39441,39434,39429,39431,39430,39616,39644,39688,39684,39685,39721,39733,39754,39756,39755,39879,39878,39875,39871,39873,39861,39864,39891,39862,39876,39865,39869,40284,40275,40271,40266,40283,40267,40281,40278,40268,40279,40274,40276,40287,40280,40282,40590,40588,40671,40705,40704,40726,40741,40747,40746,40745,40744,40780,40789,20788,20789,21142,21239,21428,22187,22189,22182,22183,22186,22188,22746,22749,22747,22802,23357,23358,23359,24003,24176,24511,25083,25863,25872,25869,25865,25868,25870,25988,26078,26077,26334,27367,27360,27340,27345,27353,27339,27359,27356,27344,27371,27343,27341,27358,27488,27568,27660,28697,28711,28704,28694,28715,28705,28706,28707,28713,28695,28708,28700,28714,29196,29194,29191,29186,29189,29349,29350,29348,29347,29345,29899,29893,29879,29891,29974,30304,30665,30666,30660,30705,31005,31003,31009,31004,30999,31006,31152,31335,31336,31795,31804,31801,31788,31803,31980,31978,32374,32373,32376,32368,32375,32367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888,33239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263,34284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274,34816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826,34818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254,35318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666,35671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461,36472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184,37183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849,37801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269,38362,38363,38625,38697,38699,38700,38696,38694,38835,38839,38838,38877,38878,38879,39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,39335,39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,39444,39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,39906,39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,40330,40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,40304,40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,40640,40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,22755,23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,26079,26344,26339,26340,27379,27376,27370,27368,27385,27377,27374,27375,28732,28725,28719,28727,28724,28721,28738,28728,28735,28730,28729,28736,28731,28723,28737,29203,29204,29352,29565,29564,29882,30379,30378,30398,30445,30668,30670,30671,30669,30706,31013,31011,31015,31016,31012,31017,31154,31342,31340,31341,31479,31817,31816,31818,31815,31813,31982,32379,32382,32385,32384,32698,32767,32889,33243,33241,33291,33384,33385,34338,34303,34305,34302,34331,34304,34294,34308,34313,34309,34316,34301,34841,34832,34833,34839,34835,34838,35171,35174,35257,35319,35680,35690,35677,35688,35683,35685,35687,35693,36270,36486,36488,36484,36697,36694,36695,36693,36696,36698,37005,37187,37185,37303,37301,37298,37299,37899,37907,37883,37920,37903,37908,37886,37909,37904,37928,37913,37901,37877,37888,37879,37895,37902,37910,37906,37882,37897,37880,37898,37887,37884,37900,37878,37905,37894,38366,38368,38367,38702,38703,38841,38843,38909,38910,39008,39010,39011,39007,39105,39106,39248,39246,39257,39244,39243,39251,39474,39476,39473,39468,39466,39478,39465,39470,39480,39469,39623,39626,39622,39696,39698,39697,39947,39944,39927,39941,39954,39928,40000,39943,39950,39942,39959,39956,39945,40351,40345,40356,40349,40338,40344,40336,40347,40352,40340,40348,40362,40343,40353,40346,40354,40360,40350,40355,40383,40361,40342,40358,40359,40601,40603,40602,40677,40676,40679,40678,40752,40750,40795,40800,40798,40797,40793,40849,20794,20793,21144,21143,22211,22205,22206,23368,23367,24011,24015,24305,25085,25883,27394,27388,27395,27384,27392,28739,28740,28746,28744,28745,28741,28742,29213,29210,29209,29566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394,32391,32392,32395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335,34339,34332,34329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843,34848,34852,34844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653,35706,35707,36112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189,37305,37951,37947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952,37937,38373,38372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256,39254,39481,39485,39494,39492,39490,39489,39482,39487,39629,39701,39703,39704,39702,39738,39762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374,40380,40385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378,40364,40392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685,40731,40728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897,23371,23372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661,28757,28758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317,30381,31029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401,32591,32647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854,34858,34853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117,36501,36500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962,37963,37967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252,39259,39502,39507,39508,39500,39503,39496,39498,39497,39506,39504,39632,39705,39723,39739,39766,39765,40006,40008,39999,40004,39993,39987,40001,39996,39991,39988,39986,39997,39990,40411,40402,40414,40410,40395,40400,40412,40401,40415,40425,40409,40408,40406,40437,40405,40413,40630,40688,40757,40755,40754,40770,40811,40853,40866,20797,21145,22760,22759,22898,23373,24024,34863,24399,25089,25091,25092,25897,25893,26006,26347,27409,27410,27407,27594,28763,28762,29218,29570,29569,29571,30320,30676,31847,31846,32405,33388,34362,34368,34361,34364,34353,34363,34366,34864,34866,34862,34867,35190,35188,35187,35326,35724,35726,35723,35720,35909,36121,36504,36708,36707,37308,37986,37973,37981,37975,37982,38852,38853,38912,39510,39513,39710,39711,39712,40018,40024,40016,40010,40013,40011,40021,40025,40012,40014,40443,40439,40431,40419,40427,40440,40420,40438,40417,40430,40422,40434,40432,40418,40428,40436,40435,40424,40429,40642,40656,40690,40691,40710,40732,40760,40759,40758,40771,40783,40817,40816,40814,40815,22227,22221,23374,23661,25901,26349,26350,27411,28767,28769,28765,28768,29219,29915,29925,30677,31032,31159,31158,31850,32407,32649,33389,34371,34872,34871,34869,34891,35732,35733,36510,36511,36512,36509,37310,37309,37314,37995,37992,37993,38629,38726,38723,38727,38855,38885,39518,39637,39769,40035,40039,40038,40034,40030,40032,40450,40446,40455,40451,40454,40453,40448,40449,40457,40447,40445,40452,40608,40734,40774,40820,40821,40822,22228,25902,26040,27416,27417,27415,27418,28770,29222,29354,30680,30681,31033,31849,31851,31990,32410,32408,32411,32409,33248,33249,34374,34375,34376,35193,35194,35196,35195,35327,35736,35737,36517,36516,36515,37998,37997,37999,38001,38003,38729,39026,39263,40040,40046,40045,40459,40461,40464,40463,40466,40465,40609,40693,40713,40775,40824,40827,40826,40825,22302,28774,31855,34876,36274,36518,37315,38004,38008,38006,38005,39520,40052,40051,40049,40053,40468,40467,40694,40714,40868,28776,28773,31991,34410,34878,34877,34879,35742,35996,36521,36553,38731,39027,39028,39116,39265,39339,39524,39526,39527,39716,40469,40471,40776,25095,27422,29223,34380,36520,38018,38016,38017,39529,39528,39726,40473,29225,34379,35743,38019,40057,40631,30325,39531,40058,40477,28777,28778,40612,40830,40777,40856,30849,37561,35023,22715,24658,31911,23290,9556,9574,9559,9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,9575,9563,9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,9584,9583,65517,132423,37595,132575,147397,34124,17077,29679,20917,13897,149826,166372,37700,137691,33518,146632,30780,26436,25311,149811,166314,131744,158643,135941,20395,140525,20488,159017,162436,144896,150193,140563,20521,131966,24484,131968,131911,28379,132127,20605,20737,13434,20750,39020,14147,33814,149924,132231,20832,144308,20842,134143,139516,131813,140592,132494,143923,137603,23426,34685,132531,146585,20914,20920,40244,20937,20943,20945,15580,20947,150182,20915,20962,21314,20973,33741,26942,145197,24443,21003,21030,21052,21173,21079,21140,21177,21189,31765,34114,21216,34317,158483,21253,166622,21833,28377,147328,133460,147436,21299,21316,134114,27851,136998,26651,29653,24650,16042,14540,136936,29149,17570,21357,21364,165547,21374,21375,136598,136723,30694,21395,166555,21408,21419,21422,29607,153458,16217,29596,21441,21445,27721,20041,22526,21465,15019,134031,21472,147435,142755,21494,134263,21523,28793,21803,26199,27995,21613,158547,134516,21853,21647,21668,18342,136973,134877,15796,134477,166332,140952,21831,19693,21551,29719,21894,21929,22021,137431,147514,17746,148533,26291,135348,22071,26317,144010,26276,26285,22093,22095,30961,22257,38791,21502,22272,22255,22253,166758,13859,135759,22342,147877,27758,28811,22338,14001,158846,22502,136214,22531,136276,148323,22566,150517,22620,22698,13665,22752,22748,135740,22779,23551,22339,172368,148088,37843,13729,22815,26790,14019,28249,136766,23076,21843,136850,34053,22985,134478,158849,159018,137180,23001,137211,137138,159142,28017,137256,136917,23033,159301,23211,23139,14054,149929,23159,14088,23190,29797,23251,159649,140628,15749,137489,14130,136888,24195,21200,23414,25992,23420,162318,16388,18525,131588,23509,24928,137780,154060,132517,23539,23453,19728,23557,138052,23571,29646,23572,138405,158504,23625,18653,23685,23785,23791,23947,138745,138807,23824,23832,23878,138916,23738,24023,33532,14381,149761,139337,139635,33415,14390,15298,24110,27274,24181,24186,148668,134355,21414,20151,24272,21416,137073,24073,24308,164994,24313,24315,14496,24316,26686,37915,24333,131521,194708,15070,18606,135994,24378,157832,140240,24408,140401,24419,38845,159342,24434,37696,166454,24487,23990,15711,152144,139114,159992,140904,37334,131742,166441,24625,26245,137335,14691,15815,13881,22416,141236,31089,15936,24734,24740,24755,149890,149903,162387,29860,20705,23200,24932,33828,24898,194726,159442,24961,20980,132694,24967,23466,147383,141407,25043,166813,170333,25040,14642,141696,141505,24611,24924,25886,25483,131352,25285,137072,25301,142861,25452,149983,14871,25656,25592,136078,137212,25744,28554,142902,38932,147596,153373,25825,25829,38011,14950,25658,14935,25933,28438,150056,150051,25989,25965,25951,143486,26037,149824,19255,26065,16600,137257,26080,26083,24543,144384,26136,143863,143864,26180,143780,143781,26187,134773,26215,152038,26227,26228,138813,143921,165364,143816,152339,30661,141559,39332,26370,148380,150049,15147,27130,145346,26462,26471,26466,147917,168173,26583,17641,26658,28240,37436,26625,144358,159136,26717,144495,27105,27147,166623,26995,26819,144845,26881,26880,15666,14849,144956,15232,26540,26977,166474,17148,26934,27032,15265,132041,33635,20624,27129,144985,139562,27205,145155,27293,15347,26545,27336,168348,15373,27421,133411,24798,27445,27508,141261,28341,146139,132021,137560,14144,21537,146266,27617,147196,27612,27703,140427,149745,158545,27738,33318,27769,146876,17605,146877,147876,149772,149760,146633,14053,15595,134450,39811,143865,140433,32655,26679,159013,159137,159211,28054,27996,28284,28420,149887,147589,159346,34099,159604,20935,27804,28189,33838,166689,28207,146991,29779,147330,31180,28239,23185,143435,28664,14093,28573,146992,28410,136343,147517,17749,37872,28484,28508,15694,28532,168304,15675,28575,147780,28627,147601,147797,147513,147440,147380,147775,20959,147798,147799,147776,156125,28747,28798,28839,28801,28876,28885,28886,28895,16644,15848,29108,29078,148087,28971,28997,23176,29002,29038,23708,148325,29007,37730,148161,28972,148570,150055,150050,29114,166888,28861,29198,37954,29205,22801,37955,29220,37697,153093,29230,29248,149876,26813,29269,29271,15957,143428,26637,28477,29314,29482,29483,149539,165931,18669,165892,29480,29486,29647,29610,134202,158254,29641,29769,147938,136935,150052,26147,14021,149943,149901,150011,29687,29717,26883,150054,29753,132547,16087,29788,141485,29792,167602,29767,29668,29814,33721,29804,14128,29812,37873,27180,29826,18771,150156,147807,150137,166799,23366,166915,137374,29896,137608,29966,29929,29982,167641,137803,23511,167596,37765,30029,30026,30055,30062,151426,16132,150803,30094,29789,30110,30132,30210,30252,30289,30287,30319,30326,156661,30352,33263,14328,157969,157966,30369,30373,30391,30412,159647,33890,151709,151933,138780,30494,30502,30528,25775,152096,30552,144044,30639,166244,166248,136897,30708,30729,136054,150034,26826,30895,30919,30931,38565,31022,153056,30935,31028,30897,161292,36792,34948,166699,155779,140828,31110,35072,26882,31104,153687,31133,162617,31036,31145,28202,160038,16040,31174,168205,31188],\n  \"euc-kr\":[44034,44035,44037,44038,44043,44044,44045,44046,44047,44056,44062,44063,44065,44066,44067,44069,44070,44071,44072,44073,44074,44075,44078,44082,44083,44084,null,null,null,null,null,null,44085,44086,44087,44090,44091,44093,44094,44095,44097,44098,44099,44100,44101,44102,44103,44104,44105,44106,44108,44110,44111,44112,44113,44114,44115,44117,null,null,null,null,null,null,44118,44119,44121,44122,44123,44125,44126,44127,44128,44129,44130,44131,44132,44133,44134,44135,44136,44137,44138,44139,44140,44141,44142,44143,44146,44147,44149,44150,44153,44155,44156,44157,44158,44159,44162,44167,44168,44173,44174,44175,44177,44178,44179,44181,44182,44183,44184,44185,44186,44187,44190,44194,44195,44196,44197,44198,44199,44203,44205,44206,44209,44210,44211,44212,44213,44214,44215,44218,44222,44223,44224,44226,44227,44229,44230,44231,44233,44234,44235,44237,44238,44239,44240,44241,44242,44243,44244,44246,44248,44249,44250,44251,44252,44253,44254,44255,44258,44259,44261,44262,44265,44267,44269,44270,44274,44276,44279,44280,44281,44282,44283,44286,44287,44289,44290,44291,44293,44295,44296,44297,44298,44299,44302,44304,44306,44307,44308,44309,44310,44311,44313,44314,44315,44317,44318,44319,44321,44322,44323,44324,44325,44326,44327,44328,44330,44331,44334,44335,44336,44337,44338,44339,null,null,null,null,null,null,44342,44343,44345,44346,44347,44349,44350,44351,44352,44353,44354,44355,44358,44360,44362,44363,44364,44365,44366,44367,44369,44370,44371,44373,44374,44375,null,null,null,null,null,null,44377,44378,44379,44380,44381,44382,44383,44384,44386,44388,44389,44390,44391,44392,44393,44394,44395,44398,44399,44401,44402,44407,44408,44409,44410,44414,44416,44419,44420,44421,44422,44423,44426,44427,44429,44430,44431,44433,44434,44435,44436,44437,44438,44439,44440,44441,44442,44443,44446,44447,44448,44449,44450,44451,44453,44454,44455,44456,44457,44458,44459,44460,44461,44462,44463,44464,44465,44466,44467,44468,44469,44470,44472,44473,44474,44475,44476,44477,44478,44479,44482,44483,44485,44486,44487,44489,44490,44491,44492,44493,44494,44495,44498,44500,44501,44502,44503,44504,44505,44506,44507,44509,44510,44511,44513,44514,44515,44517,44518,44519,44520,44521,44522,44523,44524,44525,44526,44527,44528,44529,44530,44531,44532,44533,44534,44535,44538,44539,44541,44542,44546,44547,44548,44549,44550,44551,44554,44556,44558,44559,44560,44561,44562,44563,44565,44566,44567,44568,44569,44570,44571,44572,null,null,null,null,null,null,44573,44574,44575,44576,44577,44578,44579,44580,44581,44582,44583,44584,44585,44586,44587,44588,44589,44590,44591,44594,44595,44597,44598,44601,44603,44604,null,null,null,null,null,null,44605,44606,44607,44610,44612,44615,44616,44617,44619,44623,44625,44626,44627,44629,44631,44632,44633,44634,44635,44638,44642,44643,44644,44646,44647,44650,44651,44653,44654,44655,44657,44658,44659,44660,44661,44662,44663,44666,44670,44671,44672,44673,44674,44675,44678,44679,44680,44681,44682,44683,44685,44686,44687,44688,44689,44690,44691,44692,44693,44694,44695,44696,44697,44698,44699,44700,44701,44702,44703,44704,44705,44706,44707,44708,44709,44710,44711,44712,44713,44714,44715,44716,44717,44718,44719,44720,44721,44722,44723,44724,44725,44726,44727,44728,44729,44730,44731,44735,44737,44738,44739,44741,44742,44743,44744,44745,44746,44747,44750,44754,44755,44756,44757,44758,44759,44762,44763,44765,44766,44767,44768,44769,44770,44771,44772,44773,44774,44775,44777,44778,44780,44782,44783,44784,44785,44786,44787,44789,44790,44791,44793,44794,44795,44797,44798,44799,44800,44801,44802,44803,44804,44805,null,null,null,null,null,null,44806,44809,44810,44811,44812,44814,44815,44817,44818,44819,44820,44821,44822,44823,44824,44825,44826,44827,44828,44829,44830,44831,44832,44833,44834,44835,null,null,null,null,null,null,44836,44837,44838,44839,44840,44841,44842,44843,44846,44847,44849,44851,44853,44854,44855,44856,44857,44858,44859,44862,44864,44868,44869,44870,44871,44874,44875,44876,44877,44878,44879,44881,44882,44883,44884,44885,44886,44887,44888,44889,44890,44891,44894,44895,44896,44897,44898,44899,44902,44903,44904,44905,44906,44907,44908,44909,44910,44911,44912,44913,44914,44915,44916,44917,44918,44919,44920,44922,44923,44924,44925,44926,44927,44929,44930,44931,44933,44934,44935,44937,44938,44939,44940,44941,44942,44943,44946,44947,44948,44950,44951,44952,44953,44954,44955,44957,44958,44959,44960,44961,44962,44963,44964,44965,44966,44967,44968,44969,44970,44971,44972,44973,44974,44975,44976,44977,44978,44979,44980,44981,44982,44983,44986,44987,44989,44990,44991,44993,44994,44995,44996,44997,44998,45002,45004,45007,45008,45009,45010,45011,45013,45014,45015,45016,45017,45018,45019,45021,45022,45023,45024,45025,null,null,null,null,null,null,45026,45027,45028,45029,45030,45031,45034,45035,45036,45037,45038,45039,45042,45043,45045,45046,45047,45049,45050,45051,45052,45053,45054,45055,45058,45059,null,null,null,null,null,null,45061,45062,45063,45064,45065,45066,45067,45069,45070,45071,45073,45074,45075,45077,45078,45079,45080,45081,45082,45083,45086,45087,45088,45089,45090,45091,45092,45093,45094,45095,45097,45098,45099,45100,45101,45102,45103,45104,45105,45106,45107,45108,45109,45110,45111,45112,45113,45114,45115,45116,45117,45118,45119,45120,45121,45122,45123,45126,45127,45129,45131,45133,45135,45136,45137,45138,45142,45144,45146,45147,45148,45150,45151,45152,45153,45154,45155,45156,45157,45158,45159,45160,45161,45162,45163,45164,45165,45166,45167,45168,45169,45170,45171,45172,45173,45174,45175,45176,45177,45178,45179,45182,45183,45185,45186,45187,45189,45190,45191,45192,45193,45194,45195,45198,45200,45202,45203,45204,45205,45206,45207,45211,45213,45214,45219,45220,45221,45222,45223,45226,45232,45234,45238,45239,45241,45242,45243,45245,45246,45247,45248,45249,45250,45251,45254,45258,45259,45260,45261,45262,45263,45266,null,null,null,null,null,null,45267,45269,45270,45271,45273,45274,45275,45276,45277,45278,45279,45281,45282,45283,45284,45286,45287,45288,45289,45290,45291,45292,45293,45294,45295,45296,null,null,null,null,null,null,45297,45298,45299,45300,45301,45302,45303,45304,45305,45306,45307,45308,45309,45310,45311,45312,45313,45314,45315,45316,45317,45318,45319,45322,45325,45326,45327,45329,45332,45333,45334,45335,45338,45342,45343,45344,45345,45346,45350,45351,45353,45354,45355,45357,45358,45359,45360,45361,45362,45363,45366,45370,45371,45372,45373,45374,45375,45378,45379,45381,45382,45383,45385,45386,45387,45388,45389,45390,45391,45394,45395,45398,45399,45401,45402,45403,45405,45406,45407,45409,45410,45411,45412,45413,45414,45415,45416,45417,45418,45419,45420,45421,45422,45423,45424,45425,45426,45427,45428,45429,45430,45431,45434,45435,45437,45438,45439,45441,45443,45444,45445,45446,45447,45450,45452,45454,45455,45456,45457,45461,45462,45463,45465,45466,45467,45469,45470,45471,45472,45473,45474,45475,45476,45477,45478,45479,45481,45482,45483,45484,45485,45486,45487,45488,45489,45490,45491,45492,45493,45494,45495,45496,null,null,null,null,null,null,45497,45498,45499,45500,45501,45502,45503,45504,45505,45506,45507,45508,45509,45510,45511,45512,45513,45514,45515,45517,45518,45519,45521,45522,45523,45525,null,null,null,null,null,null,45526,45527,45528,45529,45530,45531,45534,45536,45537,45538,45539,45540,45541,45542,45543,45546,45547,45549,45550,45551,45553,45554,45555,45556,45557,45558,45559,45560,45562,45564,45566,45567,45568,45569,45570,45571,45574,45575,45577,45578,45581,45582,45583,45584,45585,45586,45587,45590,45592,45594,45595,45596,45597,45598,45599,45601,45602,45603,45604,45605,45606,45607,45608,45609,45610,45611,45612,45613,45614,45615,45616,45617,45618,45619,45621,45622,45623,45624,45625,45626,45627,45629,45630,45631,45632,45633,45634,45635,45636,45637,45638,45639,45640,45641,45642,45643,45644,45645,45646,45647,45648,45649,45650,45651,45652,45653,45654,45655,45657,45658,45659,45661,45662,45663,45665,45666,45667,45668,45669,45670,45671,45674,45675,45676,45677,45678,45679,45680,45681,45682,45683,45686,45687,45688,45689,45690,45691,45693,45694,45695,45696,45697,45698,45699,45702,45703,45704,45706,45707,45708,45709,45710,null,null,null,null,null,null,45711,45714,45715,45717,45718,45719,45723,45724,45725,45726,45727,45730,45732,45735,45736,45737,45739,45741,45742,45743,45745,45746,45747,45749,45750,45751,null,null,null,null,null,null,45752,45753,45754,45755,45756,45757,45758,45759,45760,45761,45762,45763,45764,45765,45766,45767,45770,45771,45773,45774,45775,45777,45779,45780,45781,45782,45783,45786,45788,45790,45791,45792,45793,45795,45799,45801,45802,45808,45809,45810,45814,45820,45821,45822,45826,45827,45829,45830,45831,45833,45834,45835,45836,45837,45838,45839,45842,45846,45847,45848,45849,45850,45851,45853,45854,45855,45856,45857,45858,45859,45860,45861,45862,45863,45864,45865,45866,45867,45868,45869,45870,45871,45872,45873,45874,45875,45876,45877,45878,45879,45880,45881,45882,45883,45884,45885,45886,45887,45888,45889,45890,45891,45892,45893,45894,45895,45896,45897,45898,45899,45900,45901,45902,45903,45904,45905,45906,45907,45911,45913,45914,45917,45920,45921,45922,45923,45926,45928,45930,45932,45933,45935,45938,45939,45941,45942,45943,45945,45946,45947,45948,45949,45950,45951,45954,45958,45959,45960,45961,45962,45963,45965,null,null,null,null,null,null,45966,45967,45969,45970,45971,45973,45974,45975,45976,45977,45978,45979,45980,45981,45982,45983,45986,45987,45988,45989,45990,45991,45993,45994,45995,45997,null,null,null,null,null,null,45998,45999,46000,46001,46002,46003,46004,46005,46006,46007,46008,46009,46010,46011,46012,46013,46014,46015,46016,46017,46018,46019,46022,46023,46025,46026,46029,46031,46033,46034,46035,46038,46040,46042,46044,46046,46047,46049,46050,46051,46053,46054,46055,46057,46058,46059,46060,46061,46062,46063,46064,46065,46066,46067,46068,46069,46070,46071,46072,46073,46074,46075,46077,46078,46079,46080,46081,46082,46083,46084,46085,46086,46087,46088,46089,46090,46091,46092,46093,46094,46095,46097,46098,46099,46100,46101,46102,46103,46105,46106,46107,46109,46110,46111,46113,46114,46115,46116,46117,46118,46119,46122,46124,46125,46126,46127,46128,46129,46130,46131,46133,46134,46135,46136,46137,46138,46139,46140,46141,46142,46143,46144,46145,46146,46147,46148,46149,46150,46151,46152,46153,46154,46155,46156,46157,46158,46159,46162,46163,46165,46166,46167,46169,46170,46171,46172,46173,46174,46175,46178,46180,46182,null,null,null,null,null,null,46183,46184,46185,46186,46187,46189,46190,46191,46192,46193,46194,46195,46196,46197,46198,46199,46200,46201,46202,46203,46204,46205,46206,46207,46209,46210,null,null,null,null,null,null,46211,46212,46213,46214,46215,46217,46218,46219,46220,46221,46222,46223,46224,46225,46226,46227,46228,46229,46230,46231,46232,46233,46234,46235,46236,46238,46239,46240,46241,46242,46243,46245,46246,46247,46249,46250,46251,46253,46254,46255,46256,46257,46258,46259,46260,46262,46264,46266,46267,46268,46269,46270,46271,46273,46274,46275,46277,46278,46279,46281,46282,46283,46284,46285,46286,46287,46289,46290,46291,46292,46294,46295,46296,46297,46298,46299,46302,46303,46305,46306,46309,46311,46312,46313,46314,46315,46318,46320,46322,46323,46324,46325,46326,46327,46329,46330,46331,46332,46333,46334,46335,46336,46337,46338,46339,46340,46341,46342,46343,46344,46345,46346,46347,46348,46349,46350,46351,46352,46353,46354,46355,46358,46359,46361,46362,46365,46366,46367,46368,46369,46370,46371,46374,46379,46380,46381,46382,46383,46386,46387,46389,46390,46391,46393,46394,46395,46396,46397,46398,46399,46402,46406,null,null,null,null,null,null,46407,46408,46409,46410,46414,46415,46417,46418,46419,46421,46422,46423,46424,46425,46426,46427,46430,46434,46435,46436,46437,46438,46439,46440,46441,46442,null,null,null,null,null,null,46443,46444,46445,46446,46447,46448,46449,46450,46451,46452,46453,46454,46455,46456,46457,46458,46459,46460,46461,46462,46463,46464,46465,46466,46467,46468,46469,46470,46471,46472,46473,46474,46475,46476,46477,46478,46479,46480,46481,46482,46483,46484,46485,46486,46487,46488,46489,46490,46491,46492,46493,46494,46495,46498,46499,46501,46502,46503,46505,46508,46509,46510,46511,46514,46518,46519,46520,46521,46522,46526,46527,46529,46530,46531,46533,46534,46535,46536,46537,46538,46539,46542,46546,46547,46548,46549,46550,46551,46553,46554,46555,46556,46557,46558,46559,46560,46561,46562,46563,46564,46565,46566,46567,46568,46569,46570,46571,46573,46574,46575,46576,46577,46578,46579,46580,46581,46582,46583,46584,46585,46586,46587,46588,46589,46590,46591,46592,46593,46594,46595,46596,46597,46598,46599,46600,46601,46602,46603,46604,46605,46606,46607,46610,46611,46613,46614,46615,46617,46618,46619,46620,46621,null,null,null,null,null,null,46622,46623,46624,46625,46626,46627,46628,46630,46631,46632,46633,46634,46635,46637,46638,46639,46640,46641,46642,46643,46645,46646,46647,46648,46649,46650,null,null,null,null,null,null,46651,46652,46653,46654,46655,46656,46657,46658,46659,46660,46661,46662,46663,46665,46666,46667,46668,46669,46670,46671,46672,46673,46674,46675,46676,46677,46678,46679,46680,46681,46682,46683,46684,46685,46686,46687,46688,46689,46690,46691,46693,46694,46695,46697,46698,46699,46700,46701,46702,46703,46704,46705,46706,46707,46708,46709,46710,46711,46712,46713,46714,46715,46716,46717,46718,46719,46720,46721,46722,46723,46724,46725,46726,46727,46728,46729,46730,46731,46732,46733,46734,46735,46736,46737,46738,46739,46740,46741,46742,46743,46744,46745,46746,46747,46750,46751,46753,46754,46755,46757,46758,46759,46760,46761,46762,46765,46766,46767,46768,46770,46771,46772,46773,46774,46775,46776,46777,46778,46779,46780,46781,46782,46783,46784,46785,46786,46787,46788,46789,46790,46791,46792,46793,46794,46795,46796,46797,46798,46799,46800,46801,46802,46803,46805,46806,46807,46808,46809,46810,46811,46812,46813,null,null,null,null,null,null,46814,46815,46816,46817,46818,46819,46820,46821,46822,46823,46824,46825,46826,46827,46828,46829,46830,46831,46833,46834,46835,46837,46838,46839,46841,46842,null,null,null,null,null,null,46843,46844,46845,46846,46847,46850,46851,46852,46854,46855,46856,46857,46858,46859,46860,46861,46862,46863,46864,46865,46866,46867,46868,46869,46870,46871,46872,46873,46874,46875,46876,46877,46878,46879,46880,46881,46882,46883,46884,46885,46886,46887,46890,46891,46893,46894,46897,46898,46899,46900,46901,46902,46903,46906,46908,46909,46910,46911,46912,46913,46914,46915,46917,46918,46919,46921,46922,46923,46925,46926,46927,46928,46929,46930,46931,46934,46935,46936,46937,46938,46939,46940,46941,46942,46943,46945,46946,46947,46949,46950,46951,46953,46954,46955,46956,46957,46958,46959,46962,46964,46966,46967,46968,46969,46970,46971,46974,46975,46977,46978,46979,46981,46982,46983,46984,46985,46986,46987,46990,46995,46996,46997,47002,47003,47005,47006,47007,47009,47010,47011,47012,47013,47014,47015,47018,47022,47023,47024,47025,47026,47027,47030,47031,47033,47034,47035,47036,47037,47038,47039,47040,47041,null,null,null,null,null,null,47042,47043,47044,47045,47046,47048,47050,47051,47052,47053,47054,47055,47056,47057,47058,47059,47060,47061,47062,47063,47064,47065,47066,47067,47068,47069,null,null,null,null,null,null,47070,47071,47072,47073,47074,47075,47076,47077,47078,47079,47080,47081,47082,47083,47086,47087,47089,47090,47091,47093,47094,47095,47096,47097,47098,47099,47102,47106,47107,47108,47109,47110,47114,47115,47117,47118,47119,47121,47122,47123,47124,47125,47126,47127,47130,47132,47134,47135,47136,47137,47138,47139,47142,47143,47145,47146,47147,47149,47150,47151,47152,47153,47154,47155,47158,47162,47163,47164,47165,47166,47167,47169,47170,47171,47173,47174,47175,47176,47177,47178,47179,47180,47181,47182,47183,47184,47186,47188,47189,47190,47191,47192,47193,47194,47195,47198,47199,47201,47202,47203,47205,47206,47207,47208,47209,47210,47211,47214,47216,47218,47219,47220,47221,47222,47223,47225,47226,47227,47229,47230,47231,47232,47233,47234,47235,47236,47237,47238,47239,47240,47241,47242,47243,47244,47246,47247,47248,47249,47250,47251,47252,47253,47254,47255,47256,47257,47258,47259,47260,47261,47262,47263,null,null,null,null,null,null,47264,47265,47266,47267,47268,47269,47270,47271,47273,47274,47275,47276,47277,47278,47279,47281,47282,47283,47285,47286,47287,47289,47290,47291,47292,47293,null,null,null,null,null,null,47294,47295,47298,47300,47302,47303,47304,47305,47306,47307,47309,47310,47311,47313,47314,47315,47317,47318,47319,47320,47321,47322,47323,47324,47326,47328,47330,47331,47332,47333,47334,47335,47338,47339,47341,47342,47343,47345,47346,47347,47348,47349,47350,47351,47354,47356,47358,47359,47360,47361,47362,47363,47365,47366,47367,47368,47369,47370,47371,47372,47373,47374,47375,47376,47377,47378,47379,47380,47381,47382,47383,47385,47386,47387,47388,47389,47390,47391,47393,47394,47395,47396,47397,47398,47399,47400,47401,47402,47403,47404,47405,47406,47407,47408,47409,47410,47411,47412,47413,47414,47415,47416,47417,47418,47419,47422,47423,47425,47426,47427,47429,47430,47431,47432,47433,47434,47435,47437,47438,47440,47442,47443,47444,47445,47446,47447,47450,47451,47453,47454,47455,47457,47458,47459,47460,47461,47462,47463,47466,47468,47470,47471,47472,47473,47474,47475,47478,47479,47481,47482,47483,47485,null,null,null,null,null,null,47486,47487,47488,47489,47490,47491,47494,47496,47499,47500,47503,47504,47505,47506,47507,47508,47509,47510,47511,47512,47513,47514,47515,47516,47517,47518,null,null,null,null,null,null,47519,47520,47521,47522,47523,47524,47525,47526,47527,47528,47529,47530,47531,47534,47535,47537,47538,47539,47541,47542,47543,47544,47545,47546,47547,47550,47552,47554,47555,47556,47557,47558,47559,47562,47563,47565,47571,47572,47573,47574,47575,47578,47580,47583,47584,47586,47590,47591,47593,47594,47595,47597,47598,47599,47600,47601,47602,47603,47606,47611,47612,47613,47614,47615,47618,47619,47620,47621,47622,47623,47625,47626,47627,47628,47629,47630,47631,47632,47633,47634,47635,47636,47638,47639,47640,47641,47642,47643,47644,47645,47646,47647,47648,47649,47650,47651,47652,47653,47654,47655,47656,47657,47658,47659,47660,47661,47662,47663,47664,47665,47666,47667,47668,47669,47670,47671,47674,47675,47677,47678,47679,47681,47683,47684,47685,47686,47687,47690,47692,47695,47696,47697,47698,47702,47703,47705,47706,47707,47709,47710,47711,47712,47713,47714,47715,47718,47722,47723,47724,47725,47726,47727,null,null,null,null,null,null,47730,47731,47733,47734,47735,47737,47738,47739,47740,47741,47742,47743,47744,47745,47746,47750,47752,47753,47754,47755,47757,47758,47759,47760,47761,47762,null,null,null,null,null,null,47763,47764,47765,47766,47767,47768,47769,47770,47771,47772,47773,47774,47775,47776,47777,47778,47779,47780,47781,47782,47783,47786,47789,47790,47791,47793,47795,47796,47797,47798,47799,47802,47804,47806,47807,47808,47809,47810,47811,47813,47814,47815,47817,47818,47819,47820,47821,47822,47823,47824,47825,47826,47827,47828,47829,47830,47831,47834,47835,47836,47837,47838,47839,47840,47841,47842,47843,47844,47845,47846,47847,47848,47849,47850,47851,47852,47853,47854,47855,47856,47857,47858,47859,47860,47861,47862,47863,47864,47865,47866,47867,47869,47870,47871,47873,47874,47875,47877,47878,47879,47880,47881,47882,47883,47884,47886,47888,47890,47891,47892,47893,47894,47895,47897,47898,47899,47901,47902,47903,47905,47906,47907,47908,47909,47910,47911,47912,47914,47916,47917,47918,47919,47920,47921,47922,47923,47927,47929,47930,47935,47936,47937,47938,47939,47942,47944,47946,47947,47948,47950,47953,47954,null,null,null,null,null,null,47955,47957,47958,47959,47961,47962,47963,47964,47965,47966,47967,47968,47970,47972,47973,47974,47975,47976,47977,47978,47979,47981,47982,47983,47984,47985,null,null,null,null,null,null,47986,47987,47988,47989,47990,47991,47992,47993,47994,47995,47996,47997,47998,47999,48000,48001,48002,48003,48004,48005,48006,48007,48009,48010,48011,48013,48014,48015,48017,48018,48019,48020,48021,48022,48023,48024,48025,48026,48027,48028,48029,48030,48031,48032,48033,48034,48035,48037,48038,48039,48041,48042,48043,48045,48046,48047,48048,48049,48050,48051,48053,48054,48056,48057,48058,48059,48060,48061,48062,48063,48065,48066,48067,48069,48070,48071,48073,48074,48075,48076,48077,48078,48079,48081,48082,48084,48085,48086,48087,48088,48089,48090,48091,48092,48093,48094,48095,48096,48097,48098,48099,48100,48101,48102,48103,48104,48105,48106,48107,48108,48109,48110,48111,48112,48113,48114,48115,48116,48117,48118,48119,48122,48123,48125,48126,48129,48131,48132,48133,48134,48135,48138,48142,48144,48146,48147,48153,48154,48160,48161,48162,48163,48166,48168,48170,48171,48172,48174,48175,48178,48179,48181,null,null,null,null,null,null,48182,48183,48185,48186,48187,48188,48189,48190,48191,48194,48198,48199,48200,48202,48203,48206,48207,48209,48210,48211,48212,48213,48214,48215,48216,48217,null,null,null,null,null,null,48218,48219,48220,48222,48223,48224,48225,48226,48227,48228,48229,48230,48231,48232,48233,48234,48235,48236,48237,48238,48239,48240,48241,48242,48243,48244,48245,48246,48247,48248,48249,48250,48251,48252,48253,48254,48255,48256,48257,48258,48259,48262,48263,48265,48266,48269,48271,48272,48273,48274,48275,48278,48280,48283,48284,48285,48286,48287,48290,48291,48293,48294,48297,48298,48299,48300,48301,48302,48303,48306,48310,48311,48312,48313,48314,48315,48318,48319,48321,48322,48323,48325,48326,48327,48328,48329,48330,48331,48332,48334,48338,48339,48340,48342,48343,48345,48346,48347,48349,48350,48351,48352,48353,48354,48355,48356,48357,48358,48359,48360,48361,48362,48363,48364,48365,48366,48367,48368,48369,48370,48371,48375,48377,48378,48379,48381,48382,48383,48384,48385,48386,48387,48390,48392,48394,48395,48396,48397,48398,48399,48401,48402,48403,48405,48406,48407,48408,48409,48410,48411,48412,48413,null,null,null,null,null,null,48414,48415,48416,48417,48418,48419,48421,48422,48423,48424,48425,48426,48427,48429,48430,48431,48432,48433,48434,48435,48436,48437,48438,48439,48440,48441,null,null,null,null,null,null,48442,48443,48444,48445,48446,48447,48449,48450,48451,48452,48453,48454,48455,48458,48459,48461,48462,48463,48465,48466,48467,48468,48469,48470,48471,48474,48475,48476,48477,48478,48479,48480,48481,48482,48483,48485,48486,48487,48489,48490,48491,48492,48493,48494,48495,48496,48497,48498,48499,48500,48501,48502,48503,48504,48505,48506,48507,48508,48509,48510,48511,48514,48515,48517,48518,48523,48524,48525,48526,48527,48530,48532,48534,48535,48536,48539,48541,48542,48543,48544,48545,48546,48547,48549,48550,48551,48552,48553,48554,48555,48556,48557,48558,48559,48561,48562,48563,48564,48565,48566,48567,48569,48570,48571,48572,48573,48574,48575,48576,48577,48578,48579,48580,48581,48582,48583,48584,48585,48586,48587,48588,48589,48590,48591,48592,48593,48594,48595,48598,48599,48601,48602,48603,48605,48606,48607,48608,48609,48610,48611,48612,48613,48614,48615,48616,48618,48619,48620,48621,48622,48623,48625,null,null,null,null,null,null,48626,48627,48629,48630,48631,48633,48634,48635,48636,48637,48638,48639,48641,48642,48644,48646,48647,48648,48649,48650,48651,48654,48655,48657,48658,48659,null,null,null,null,null,null,48661,48662,48663,48664,48665,48666,48667,48670,48672,48673,48674,48675,48676,48677,48678,48679,48680,48681,48682,48683,48684,48685,48686,48687,48688,48689,48690,48691,48692,48693,48694,48695,48696,48697,48698,48699,48700,48701,48702,48703,48704,48705,48706,48707,48710,48711,48713,48714,48715,48717,48719,48720,48721,48722,48723,48726,48728,48732,48733,48734,48735,48738,48739,48741,48742,48743,48745,48747,48748,48749,48750,48751,48754,48758,48759,48760,48761,48762,48766,48767,48769,48770,48771,48773,48774,48775,48776,48777,48778,48779,48782,48786,48787,48788,48789,48790,48791,48794,48795,48796,48797,48798,48799,48800,48801,48802,48803,48804,48805,48806,48807,48809,48810,48811,48812,48813,48814,48815,48816,48817,48818,48819,48820,48821,48822,48823,48824,48825,48826,48827,48828,48829,48830,48831,48832,48833,48834,48835,48836,48837,48838,48839,48840,48841,48842,48843,48844,48845,48846,48847,48850,48851,null,null,null,null,null,null,48853,48854,48857,48858,48859,48860,48861,48862,48863,48865,48866,48870,48871,48872,48873,48874,48875,48877,48878,48879,48880,48881,48882,48883,48884,48885,null,null,null,null,null,null,48886,48887,48888,48889,48890,48891,48892,48893,48894,48895,48896,48898,48899,48900,48901,48902,48903,48906,48907,48908,48909,48910,48911,48912,48913,48914,48915,48916,48917,48918,48919,48922,48926,48927,48928,48929,48930,48931,48932,48933,48934,48935,48936,48937,48938,48939,48940,48941,48942,48943,48944,48945,48946,48947,48948,48949,48950,48951,48952,48953,48954,48955,48956,48957,48958,48959,48962,48963,48965,48966,48967,48969,48970,48971,48972,48973,48974,48975,48978,48979,48980,48982,48983,48984,48985,48986,48987,48988,48989,48990,48991,48992,48993,48994,48995,48996,48997,48998,48999,49000,49001,49002,49003,49004,49005,49006,49007,49008,49009,49010,49011,49012,49013,49014,49015,49016,49017,49018,49019,49020,49021,49022,49023,49024,49025,49026,49027,49028,49029,49030,49031,49032,49033,49034,49035,49036,49037,49038,49039,49040,49041,49042,49043,49045,49046,49047,49048,49049,49050,49051,49052,49053,null,null,null,null,null,null,49054,49055,49056,49057,49058,49059,49060,49061,49062,49063,49064,49065,49066,49067,49068,49069,49070,49071,49073,49074,49075,49076,49077,49078,49079,49080,null,null,null,null,null,null,49081,49082,49083,49084,49085,49086,49087,49088,49089,49090,49091,49092,49094,49095,49096,49097,49098,49099,49102,49103,49105,49106,49107,49109,49110,49111,49112,49113,49114,49115,49117,49118,49120,49122,49123,49124,49125,49126,49127,49128,49129,49130,49131,49132,49133,49134,49135,49136,49137,49138,49139,49140,49141,49142,49143,49144,49145,49146,49147,49148,49149,49150,49151,49152,49153,49154,49155,49156,49157,49158,49159,49160,49161,49162,49163,49164,49165,49166,49167,49168,49169,49170,49171,49172,49173,49174,49175,49176,49177,49178,49179,49180,49181,49182,49183,49184,49185,49186,49187,49188,49189,49190,49191,49192,49193,49194,49195,49196,49197,49198,49199,49200,49201,49202,49203,49204,49205,49206,49207,49208,49209,49210,49211,49213,49214,49215,49216,49217,49218,49219,49220,49221,49222,49223,49224,49225,49226,49227,49228,49229,49230,49231,49232,49234,49235,49236,49237,49238,49239,49241,49242,49243,null,null,null,null,null,null,49245,49246,49247,49249,49250,49251,49252,49253,49254,49255,49258,49259,49260,49261,49262,49263,49264,49265,49266,49267,49268,49269,49270,49271,49272,49273,null,null,null,null,null,null,49274,49275,49276,49277,49278,49279,49280,49281,49282,49283,49284,49285,49286,49287,49288,49289,49290,49291,49292,49293,49294,49295,49298,49299,49301,49302,49303,49305,49306,49307,49308,49309,49310,49311,49314,49316,49318,49319,49320,49321,49322,49323,49326,49329,49330,49335,49336,49337,49338,49339,49342,49346,49347,49348,49350,49351,49354,49355,49357,49358,49359,49361,49362,49363,49364,49365,49366,49367,49370,49374,49375,49376,49377,49378,49379,49382,49383,49385,49386,49387,49389,49390,49391,49392,49393,49394,49395,49398,49400,49402,49403,49404,49405,49406,49407,49409,49410,49411,49413,49414,49415,49417,49418,49419,49420,49421,49422,49423,49425,49426,49427,49428,49430,49431,49432,49433,49434,49435,49441,49442,49445,49448,49449,49450,49451,49454,49458,49459,49460,49461,49463,49466,49467,49469,49470,49471,49473,49474,49475,49476,49477,49478,49479,49482,49486,49487,49488,49489,49490,49491,49494,49495,null,null,null,null,null,null,49497,49498,49499,49501,49502,49503,49504,49505,49506,49507,49510,49514,49515,49516,49517,49518,49519,49521,49522,49523,49525,49526,49527,49529,49530,49531,null,null,null,null,null,null,49532,49533,49534,49535,49536,49537,49538,49539,49540,49542,49543,49544,49545,49546,49547,49551,49553,49554,49555,49557,49559,49560,49561,49562,49563,49566,49568,49570,49571,49572,49574,49575,49578,49579,49581,49582,49583,49585,49586,49587,49588,49589,49590,49591,49592,49593,49594,49595,49596,49598,49599,49600,49601,49602,49603,49605,49606,49607,49609,49610,49611,49613,49614,49615,49616,49617,49618,49619,49621,49622,49625,49626,49627,49628,49629,49630,49631,49633,49634,49635,49637,49638,49639,49641,49642,49643,49644,49645,49646,49647,49650,49652,49653,49654,49655,49656,49657,49658,49659,49662,49663,49665,49666,49667,49669,49670,49671,49672,49673,49674,49675,49678,49680,49682,49683,49684,49685,49686,49687,49690,49691,49693,49694,49697,49698,49699,49700,49701,49702,49703,49706,49708,49710,49712,49715,49717,49718,49719,49720,49721,49722,49723,49724,49725,49726,49727,49728,49729,49730,49731,49732,49733,null,null,null,null,null,null,49734,49735,49737,49738,49739,49740,49741,49742,49743,49746,49747,49749,49750,49751,49753,49754,49755,49756,49757,49758,49759,49761,49762,49763,49764,49766,null,null,null,null,null,null,49767,49768,49769,49770,49771,49774,49775,49777,49778,49779,49781,49782,49783,49784,49785,49786,49787,49790,49792,49794,49795,49796,49797,49798,49799,49802,49803,49804,49805,49806,49807,49809,49810,49811,49812,49813,49814,49815,49817,49818,49820,49822,49823,49824,49825,49826,49827,49830,49831,49833,49834,49835,49838,49839,49840,49841,49842,49843,49846,49848,49850,49851,49852,49853,49854,49855,49856,49857,49858,49859,49860,49861,49862,49863,49864,49865,49866,49867,49868,49869,49870,49871,49872,49873,49874,49875,49876,49877,49878,49879,49880,49881,49882,49883,49886,49887,49889,49890,49893,49894,49895,49896,49897,49898,49902,49904,49906,49907,49908,49909,49911,49914,49917,49918,49919,49921,49922,49923,49924,49925,49926,49927,49930,49931,49934,49935,49936,49937,49938,49942,49943,49945,49946,49947,49949,49950,49951,49952,49953,49954,49955,49958,49959,49962,49963,49964,49965,49966,49967,49968,49969,49970,null,null,null,null,null,null,49971,49972,49973,49974,49975,49976,49977,49978,49979,49980,49981,49982,49983,49984,49985,49986,49987,49988,49990,49991,49992,49993,49994,49995,49996,49997,null,null,null,null,null,null,49998,49999,50000,50001,50002,50003,50004,50005,50006,50007,50008,50009,50010,50011,50012,50013,50014,50015,50016,50017,50018,50019,50020,50021,50022,50023,50026,50027,50029,50030,50031,50033,50035,50036,50037,50038,50039,50042,50043,50046,50047,50048,50049,50050,50051,50053,50054,50055,50057,50058,50059,50061,50062,50063,50064,50065,50066,50067,50068,50069,50070,50071,50072,50073,50074,50075,50076,50077,50078,50079,50080,50081,50082,50083,50084,50085,50086,50087,50088,50089,50090,50091,50092,50093,50094,50095,50096,50097,50098,50099,50100,50101,50102,50103,50104,50105,50106,50107,50108,50109,50110,50111,50113,50114,50115,50116,50117,50118,50119,50120,50121,50122,50123,50124,50125,50126,50127,50128,50129,50130,50131,50132,50133,50134,50135,50138,50139,50141,50142,50145,50147,50148,50149,50150,50151,50154,50155,50156,50158,50159,50160,50161,50162,50163,50166,50167,50169,50170,50171,50172,50173,50174,null,null,null,null,null,null,50175,50176,50177,50178,50179,50180,50181,50182,50183,50185,50186,50187,50188,50189,50190,50191,50193,50194,50195,50196,50197,50198,50199,50200,50201,50202,null,null,null,null,null,null,50203,50204,50205,50206,50207,50208,50209,50210,50211,50213,50214,50215,50216,50217,50218,50219,50221,50222,50223,50225,50226,50227,50229,50230,50231,50232,50233,50234,50235,50238,50239,50240,50241,50242,50243,50244,50245,50246,50247,50249,50250,50251,50252,50253,50254,50255,50256,50257,50258,50259,50260,50261,50262,50263,50264,50265,50266,50267,50268,50269,50270,50271,50272,50273,50274,50275,50278,50279,50281,50282,50283,50285,50286,50287,50288,50289,50290,50291,50294,50295,50296,50298,50299,50300,50301,50302,50303,50305,50306,50307,50308,50309,50310,50311,50312,50313,50314,50315,50316,50317,50318,50319,50320,50321,50322,50323,50325,50326,50327,50328,50329,50330,50331,50333,50334,50335,50336,50337,50338,50339,50340,50341,50342,50343,50344,50345,50346,50347,50348,50349,50350,50351,50352,50353,50354,50355,50356,50357,50358,50359,50361,50362,50363,50365,50366,50367,50368,50369,50370,50371,50372,50373,null,null,null,null,null,null,50374,50375,50376,50377,50378,50379,50380,50381,50382,50383,50384,50385,50386,50387,50388,50389,50390,50391,50392,50393,50394,50395,50396,50397,50398,50399,null,null,null,null,null,null,50400,50401,50402,50403,50404,50405,50406,50407,50408,50410,50411,50412,50413,50414,50415,50418,50419,50421,50422,50423,50425,50427,50428,50429,50430,50434,50435,50436,50437,50438,50439,50440,50441,50442,50443,50445,50446,50447,50449,50450,50451,50453,50454,50455,50456,50457,50458,50459,50461,50462,50463,50464,50465,50466,50467,50468,50469,50470,50471,50474,50475,50477,50478,50479,50481,50482,50483,50484,50485,50486,50487,50490,50492,50494,50495,50496,50497,50498,50499,50502,50503,50507,50511,50512,50513,50514,50518,50522,50523,50524,50527,50530,50531,50533,50534,50535,50537,50538,50539,50540,50541,50542,50543,50546,50550,50551,50552,50553,50554,50555,50558,50559,50561,50562,50563,50565,50566,50568,50569,50570,50571,50574,50576,50578,50579,50580,50582,50585,50586,50587,50589,50590,50591,50593,50594,50595,50596,50597,50598,50599,50600,50602,50603,50604,50605,50606,50607,50608,50609,50610,50611,50614,null,null,null,null,null,null,50615,50618,50623,50624,50625,50626,50627,50635,50637,50639,50642,50643,50645,50646,50647,50649,50650,50651,50652,50653,50654,50655,50658,50660,50662,50663,null,null,null,null,null,null,50664,50665,50666,50667,50671,50673,50674,50675,50677,50680,50681,50682,50683,50690,50691,50692,50697,50698,50699,50701,50702,50703,50705,50706,50707,50708,50709,50710,50711,50714,50717,50718,50719,50720,50721,50722,50723,50726,50727,50729,50730,50731,50735,50737,50738,50742,50744,50746,50748,50749,50750,50751,50754,50755,50757,50758,50759,50761,50762,50763,50764,50765,50766,50767,50770,50774,50775,50776,50777,50778,50779,50782,50783,50785,50786,50787,50788,50789,50790,50791,50792,50793,50794,50795,50797,50798,50800,50802,50803,50804,50805,50806,50807,50810,50811,50813,50814,50815,50817,50818,50819,50820,50821,50822,50823,50826,50828,50830,50831,50832,50833,50834,50835,50838,50839,50841,50842,50843,50845,50846,50847,50848,50849,50850,50851,50854,50856,50858,50859,50860,50861,50862,50863,50866,50867,50869,50870,50871,50875,50876,50877,50878,50879,50882,50884,50886,50887,50888,50889,50890,50891,50894,null,null,null,null,null,null,50895,50897,50898,50899,50901,50902,50903,50904,50905,50906,50907,50910,50911,50914,50915,50916,50917,50918,50919,50922,50923,50925,50926,50927,50929,50930,null,null,null,null,null,null,50931,50932,50933,50934,50935,50938,50939,50940,50942,50943,50944,50945,50946,50947,50950,50951,50953,50954,50955,50957,50958,50959,50960,50961,50962,50963,50966,50968,50970,50971,50972,50973,50974,50975,50978,50979,50981,50982,50983,50985,50986,50987,50988,50989,50990,50991,50994,50996,50998,51000,51001,51002,51003,51006,51007,51009,51010,51011,51013,51014,51015,51016,51017,51019,51022,51024,51033,51034,51035,51037,51038,51039,51041,51042,51043,51044,51045,51046,51047,51049,51050,51052,51053,51054,51055,51056,51057,51058,51059,51062,51063,51065,51066,51067,51071,51072,51073,51074,51078,51083,51084,51085,51087,51090,51091,51093,51097,51099,51100,51101,51102,51103,51106,51111,51112,51113,51114,51115,51118,51119,51121,51122,51123,51125,51126,51127,51128,51129,51130,51131,51134,51138,51139,51140,51141,51142,51143,51146,51147,51149,51151,51153,51154,51155,51156,51157,51158,51159,51161,51162,51163,51164,null,null,null,null,null,null,51166,51167,51168,51169,51170,51171,51173,51174,51175,51177,51178,51179,51181,51182,51183,51184,51185,51186,51187,51188,51189,51190,51191,51192,51193,51194,null,null,null,null,null,null,51195,51196,51197,51198,51199,51202,51203,51205,51206,51207,51209,51211,51212,51213,51214,51215,51218,51220,51223,51224,51225,51226,51227,51230,51231,51233,51234,51235,51237,51238,51239,51240,51241,51242,51243,51246,51248,51250,51251,51252,51253,51254,51255,51257,51258,51259,51261,51262,51263,51265,51266,51267,51268,51269,51270,51271,51274,51275,51278,51279,51280,51281,51282,51283,51285,51286,51287,51288,51289,51290,51291,51292,51293,51294,51295,51296,51297,51298,51299,51300,51301,51302,51303,51304,51305,51306,51307,51308,51309,51310,51311,51314,51315,51317,51318,51319,51321,51323,51324,51325,51326,51327,51330,51332,51336,51337,51338,51342,51343,51344,51345,51346,51347,51349,51350,51351,51352,51353,51354,51355,51356,51358,51360,51362,51363,51364,51365,51366,51367,51369,51370,51371,51372,51373,51374,51375,51376,51377,51378,51379,51380,51381,51382,51383,51384,51385,51386,51387,51390,51391,51392,51393,null,null,null,null,null,null,51394,51395,51397,51398,51399,51401,51402,51403,51405,51406,51407,51408,51409,51410,51411,51414,51416,51418,51419,51420,51421,51422,51423,51426,51427,51429,null,null,null,null,null,null,51430,51431,51432,51433,51434,51435,51436,51437,51438,51439,51440,51441,51442,51443,51444,51446,51447,51448,51449,51450,51451,51454,51455,51457,51458,51459,51463,51464,51465,51466,51467,51470,12288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217,8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304,12305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,65505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,8596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,8835,8746,8745,8743,8744,65506,51472,51474,51475,51476,51477,51478,51479,51481,51482,51483,51484,51485,51486,51487,51488,51489,51490,51491,51492,51493,51494,51495,51496,51497,51498,51499,null,null,null,null,null,null,51501,51502,51503,51504,51505,51506,51507,51509,51510,51511,51512,51513,51514,51515,51516,51517,51518,51519,51520,51521,51522,51523,51524,51525,51526,51527,null,null,null,null,null,null,51528,51529,51530,51531,51532,51533,51534,51535,51538,51539,51541,51542,51543,51545,51546,51547,51548,51549,51550,51551,51554,51556,51557,51558,51559,51560,51561,51562,51563,51565,51566,51567,8658,8660,8704,8707,180,65374,711,728,733,730,729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,9824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,9638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,9837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,51569,51570,51571,51573,51574,51575,51576,51577,51578,51579,51581,51582,51583,51584,51585,51586,51587,51588,51589,51590,51591,51594,51595,51597,51598,51599,null,null,null,null,null,null,51601,51602,51603,51604,51605,51606,51607,51610,51612,51614,51615,51616,51617,51618,51619,51620,51621,51622,51623,51624,51625,51626,51627,51628,51629,51630,null,null,null,null,null,null,51631,51632,51633,51634,51635,51636,51637,51638,51639,51640,51641,51642,51643,51644,51645,51646,51647,51650,51651,51653,51654,51657,51659,51660,51661,51662,51663,51666,51668,51671,51672,51675,65281,65282,65283,65284,65285,65286,65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65339,65510,65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,65507,51678,51679,51681,51683,51685,51686,51688,51689,51690,51691,51694,51698,51699,51700,51701,51702,51703,51706,51707,51709,51710,51711,51713,51714,51715,51716,null,null,null,null,null,null,51717,51718,51719,51722,51726,51727,51728,51729,51730,51731,51733,51734,51735,51737,51738,51739,51740,51741,51742,51743,51744,51745,51746,51747,51748,51749,null,null,null,null,null,null,51750,51751,51752,51754,51755,51756,51757,51758,51759,51760,51761,51762,51763,51764,51765,51766,51767,51768,51769,51770,51771,51772,51773,51774,51775,51776,51777,51778,51779,51780,51781,51782,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,12683,12684,12685,12686,51783,51784,51785,51786,51787,51790,51791,51793,51794,51795,51797,51798,51799,51800,51801,51802,51803,51806,51810,51811,51812,51813,51814,51815,51817,51818,null,null,null,null,null,null,51819,51820,51821,51822,51823,51824,51825,51826,51827,51828,51829,51830,51831,51832,51833,51834,51835,51836,51838,51839,51840,51841,51842,51843,51845,51846,null,null,null,null,null,null,51847,51848,51849,51850,51851,51852,51853,51854,51855,51856,51857,51858,51859,51860,51861,51862,51863,51865,51866,51867,51868,51869,51870,51871,51872,51873,51874,51875,51876,51877,51878,51879,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,null,null,null,null,null,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,null,null,null,null,null,null,null,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,null,null,null,null,null,null,null,null,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,null,null,null,null,null,null,51880,51881,51882,51883,51884,51885,51886,51887,51888,51889,51890,51891,51892,51893,51894,51895,51896,51897,51898,51899,51902,51903,51905,51906,51907,51909,null,null,null,null,null,null,51910,51911,51912,51913,51914,51915,51918,51920,51922,51924,51925,51926,51927,51930,51931,51932,51933,51934,51935,51937,51938,51939,51940,51941,51942,51943,null,null,null,null,null,null,51944,51945,51946,51947,51949,51950,51951,51952,51953,51954,51955,51957,51958,51959,51960,51961,51962,51963,51964,51965,51966,51967,51968,51969,51970,51971,51972,51973,51974,51975,51977,51978,9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490,9489,9498,9497,9494,9493,9486,9485,9502,9503,9505,9506,9510,9511,9513,9514,9517,9518,9521,9522,9525,9526,9529,9530,9533,9534,9536,9537,9539,9540,9541,9542,9543,9544,9545,9546,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,51979,51980,51981,51982,51983,51985,51986,51987,51989,51990,51991,51993,51994,51995,51996,51997,51998,51999,52002,52003,52004,52005,52006,52007,52008,52009,null,null,null,null,null,null,52010,52011,52012,52013,52014,52015,52016,52017,52018,52019,52020,52021,52022,52023,52024,52025,52026,52027,52028,52029,52030,52031,52032,52034,52035,52036,null,null,null,null,null,null,52037,52038,52039,52042,52043,52045,52046,52047,52049,52050,52051,52052,52053,52054,52055,52058,52059,52060,52062,52063,52064,52065,52066,52067,52069,52070,52071,52072,52073,52074,52075,52076,13205,13206,13207,8467,13208,13252,13219,13220,13221,13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13258,13197,13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,13235,13236,13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,13243,13244,13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,13194,13195,13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,13277,13264,13267,13251,13257,13276,13254,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,52077,52078,52079,52080,52081,52082,52083,52084,52085,52086,52087,52090,52091,52092,52093,52094,52095,52096,52097,52098,52099,52100,52101,52102,52103,52104,null,null,null,null,null,null,52105,52106,52107,52108,52109,52110,52111,52112,52113,52114,52115,52116,52117,52118,52119,52120,52121,52122,52123,52125,52126,52127,52128,52129,52130,52131,null,null,null,null,null,null,52132,52133,52134,52135,52136,52137,52138,52139,52140,52141,52142,52143,52144,52145,52146,52147,52148,52149,52150,52151,52153,52154,52155,52156,52157,52158,52159,52160,52161,52162,52163,52164,198,208,170,294,null,306,null,319,321,216,338,186,222,358,330,null,12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,9424,9425,9426,9427,9428,9429,9430,9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446,9447,9448,9449,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,189,8531,8532,188,190,8539,8540,8541,8542,52165,52166,52167,52168,52169,52170,52171,52172,52173,52174,52175,52176,52177,52178,52179,52181,52182,52183,52184,52185,52186,52187,52188,52189,52190,52191,null,null,null,null,null,null,52192,52193,52194,52195,52197,52198,52200,52202,52203,52204,52205,52206,52207,52208,52209,52210,52211,52212,52213,52214,52215,52216,52217,52218,52219,52220,null,null,null,null,null,null,52221,52222,52223,52224,52225,52226,52227,52228,52229,52230,52231,52232,52233,52234,52235,52238,52239,52241,52242,52243,52245,52246,52247,52248,52249,52250,52251,52254,52255,52256,52259,52260,230,273,240,295,305,307,312,320,322,248,339,223,254,359,331,329,12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,12824,12825,12826,12827,9372,9373,9374,9375,9376,9377,9378,9379,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,9395,9396,9397,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,185,178,179,8308,8319,8321,8322,8323,8324,52261,52262,52266,52267,52269,52271,52273,52274,52275,52276,52277,52278,52279,52282,52287,52288,52289,52290,52291,52294,52295,52297,52298,52299,52301,52302,null,null,null,null,null,null,52303,52304,52305,52306,52307,52310,52314,52315,52316,52317,52318,52319,52321,52322,52323,52325,52327,52329,52330,52331,52332,52333,52334,52335,52337,52338,null,null,null,null,null,null,52339,52340,52342,52343,52344,52345,52346,52347,52348,52349,52350,52351,52352,52353,52354,52355,52356,52357,52358,52359,52360,52361,52362,52363,52364,52365,52366,52367,52368,52369,52370,52371,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,null,null,null,null,null,null,null,null,null,null,null,52372,52373,52374,52375,52378,52379,52381,52382,52383,52385,52386,52387,52388,52389,52390,52391,52394,52398,52399,52400,52401,52402,52403,52406,52407,52409,null,null,null,null,null,null,52410,52411,52413,52414,52415,52416,52417,52418,52419,52422,52424,52426,52427,52428,52429,52430,52431,52433,52434,52435,52437,52438,52439,52440,52441,52442,null,null,null,null,null,null,52443,52444,52445,52446,52447,52448,52449,52450,52451,52453,52454,52455,52456,52457,52458,52459,52461,52462,52463,52465,52466,52467,52468,52469,52470,52471,52472,52473,52474,52475,52476,52477,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,null,null,null,null,null,null,null,null,52478,52479,52480,52482,52483,52484,52485,52486,52487,52490,52491,52493,52494,52495,52497,52498,52499,52500,52501,52502,52503,52506,52508,52510,52511,52512,null,null,null,null,null,null,52513,52514,52515,52517,52518,52519,52521,52522,52523,52525,52526,52527,52528,52529,52530,52531,52532,52533,52534,52535,52536,52538,52539,52540,52541,52542,null,null,null,null,null,null,52543,52544,52545,52546,52547,52548,52549,52550,52551,52552,52553,52554,52555,52556,52557,52558,52559,52560,52561,52562,52563,52564,52565,52566,52567,52568,52569,52570,52571,52573,52574,52575,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,null,null,null,null,null,null,null,null,null,null,null,null,null,52577,52578,52579,52581,52582,52583,52584,52585,52586,52587,52590,52592,52594,52595,52596,52597,52598,52599,52601,52602,52603,52604,52605,52606,52607,52608,null,null,null,null,null,null,52609,52610,52611,52612,52613,52614,52615,52617,52618,52619,52620,52621,52622,52623,52624,52625,52626,52627,52630,52631,52633,52634,52635,52637,52638,52639,null,null,null,null,null,null,52640,52641,52642,52643,52646,52648,52650,52651,52652,52653,52654,52655,52657,52658,52659,52660,52661,52662,52663,52664,52665,52666,52667,52668,52669,52670,52671,52672,52673,52674,52675,52677,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,52678,52679,52680,52681,52682,52683,52685,52686,52687,52689,52690,52691,52692,52693,52694,52695,52696,52697,52698,52699,52700,52701,52702,52703,52704,52705,null,null,null,null,null,null,52706,52707,52708,52709,52710,52711,52713,52714,52715,52717,52718,52719,52721,52722,52723,52724,52725,52726,52727,52730,52732,52734,52735,52736,52737,52738,null,null,null,null,null,null,52739,52741,52742,52743,52745,52746,52747,52749,52750,52751,52752,52753,52754,52755,52757,52758,52759,52760,52762,52763,52764,52765,52766,52767,52770,52771,52773,52774,52775,52777,52778,52779,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,52780,52781,52782,52783,52786,52788,52790,52791,52792,52793,52794,52795,52796,52797,52798,52799,52800,52801,52802,52803,52804,52805,52806,52807,52808,52809,null,null,null,null,null,null,52810,52811,52812,52813,52814,52815,52816,52817,52818,52819,52820,52821,52822,52823,52826,52827,52829,52830,52834,52835,52836,52837,52838,52839,52842,52844,null,null,null,null,null,null,52846,52847,52848,52849,52850,52851,52854,52855,52857,52858,52859,52861,52862,52863,52864,52865,52866,52867,52870,52872,52874,52875,52876,52877,52878,52879,52882,52883,52885,52886,52887,52889,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,52890,52891,52892,52893,52894,52895,52898,52902,52903,52904,52905,52906,52907,52910,52911,52912,52913,52914,52915,52916,52917,52918,52919,52920,52921,52922,null,null,null,null,null,null,52923,52924,52925,52926,52927,52928,52930,52931,52932,52933,52934,52935,52936,52937,52938,52939,52940,52941,52942,52943,52944,52945,52946,52947,52948,52949,null,null,null,null,null,null,52950,52951,52952,52953,52954,52955,52956,52957,52958,52959,52960,52961,52962,52963,52966,52967,52969,52970,52973,52974,52975,52976,52977,52978,52979,52982,52986,52987,52988,52989,52990,52991,44032,44033,44036,44039,44040,44041,44042,44048,44049,44050,44051,44052,44053,44054,44055,44057,44058,44059,44060,44061,44064,44068,44076,44077,44079,44080,44081,44088,44089,44092,44096,44107,44109,44116,44120,44124,44144,44145,44148,44151,44152,44154,44160,44161,44163,44164,44165,44166,44169,44170,44171,44172,44176,44180,44188,44189,44191,44192,44193,44200,44201,44202,44204,44207,44208,44216,44217,44219,44220,44221,44225,44228,44232,44236,44245,44247,44256,44257,44260,44263,44264,44266,44268,44271,44272,44273,44275,44277,44278,44284,44285,44288,44292,44294,52994,52995,52997,52998,52999,53001,53002,53003,53004,53005,53006,53007,53010,53012,53014,53015,53016,53017,53018,53019,53021,53022,53023,53025,53026,53027,null,null,null,null,null,null,53029,53030,53031,53032,53033,53034,53035,53038,53042,53043,53044,53045,53046,53047,53049,53050,53051,53052,53053,53054,53055,53056,53057,53058,53059,53060,null,null,null,null,null,null,53061,53062,53063,53064,53065,53066,53067,53068,53069,53070,53071,53072,53073,53074,53075,53078,53079,53081,53082,53083,53085,53086,53087,53088,53089,53090,53091,53094,53096,53098,53099,53100,44300,44301,44303,44305,44312,44316,44320,44329,44332,44333,44340,44341,44344,44348,44356,44357,44359,44361,44368,44372,44376,44385,44387,44396,44397,44400,44403,44404,44405,44406,44411,44412,44413,44415,44417,44418,44424,44425,44428,44432,44444,44445,44452,44471,44480,44481,44484,44488,44496,44497,44499,44508,44512,44516,44536,44537,44540,44543,44544,44545,44552,44553,44555,44557,44564,44592,44593,44596,44599,44600,44602,44608,44609,44611,44613,44614,44618,44620,44621,44622,44624,44628,44630,44636,44637,44639,44640,44641,44645,44648,44649,44652,44656,44664,53101,53102,53103,53106,53107,53109,53110,53111,53113,53114,53115,53116,53117,53118,53119,53121,53122,53123,53124,53126,53127,53128,53129,53130,53131,53133,null,null,null,null,null,null,53134,53135,53136,53137,53138,53139,53140,53141,53142,53143,53144,53145,53146,53147,53148,53149,53150,53151,53152,53154,53155,53156,53157,53158,53159,53161,null,null,null,null,null,null,53162,53163,53164,53165,53166,53167,53169,53170,53171,53172,53173,53174,53175,53176,53177,53178,53179,53180,53181,53182,53183,53184,53185,53186,53187,53189,53190,53191,53192,53193,53194,53195,44665,44667,44668,44669,44676,44677,44684,44732,44733,44734,44736,44740,44748,44749,44751,44752,44753,44760,44761,44764,44776,44779,44781,44788,44792,44796,44807,44808,44813,44816,44844,44845,44848,44850,44852,44860,44861,44863,44865,44866,44867,44872,44873,44880,44892,44893,44900,44901,44921,44928,44932,44936,44944,44945,44949,44956,44984,44985,44988,44992,44999,45000,45001,45003,45005,45006,45012,45020,45032,45033,45040,45041,45044,45048,45056,45057,45060,45068,45072,45076,45084,45085,45096,45124,45125,45128,45130,45132,45134,45139,45140,45141,45143,45145,53196,53197,53198,53199,53200,53201,53202,53203,53204,53205,53206,53207,53208,53209,53210,53211,53212,53213,53214,53215,53218,53219,53221,53222,53223,53225,null,null,null,null,null,null,53226,53227,53228,53229,53230,53231,53234,53236,53238,53239,53240,53241,53242,53243,53245,53246,53247,53249,53250,53251,53253,53254,53255,53256,53257,53258,null,null,null,null,null,null,53259,53260,53261,53262,53263,53264,53266,53267,53268,53269,53270,53271,53273,53274,53275,53276,53277,53278,53279,53280,53281,53282,53283,53284,53285,53286,53287,53288,53289,53290,53291,53292,45149,45180,45181,45184,45188,45196,45197,45199,45201,45208,45209,45210,45212,45215,45216,45217,45218,45224,45225,45227,45228,45229,45230,45231,45233,45235,45236,45237,45240,45244,45252,45253,45255,45256,45257,45264,45265,45268,45272,45280,45285,45320,45321,45323,45324,45328,45330,45331,45336,45337,45339,45340,45341,45347,45348,45349,45352,45356,45364,45365,45367,45368,45369,45376,45377,45380,45384,45392,45393,45396,45397,45400,45404,45408,45432,45433,45436,45440,45442,45448,45449,45451,45453,45458,45459,45460,45464,45468,45480,45516,45520,45524,45532,45533,53294,53295,53296,53297,53298,53299,53302,53303,53305,53306,53307,53309,53310,53311,53312,53313,53314,53315,53318,53320,53322,53323,53324,53325,53326,53327,null,null,null,null,null,null,53329,53330,53331,53333,53334,53335,53337,53338,53339,53340,53341,53342,53343,53345,53346,53347,53348,53349,53350,53351,53352,53353,53354,53355,53358,53359,null,null,null,null,null,null,53361,53362,53363,53365,53366,53367,53368,53369,53370,53371,53374,53375,53376,53378,53379,53380,53381,53382,53383,53384,53385,53386,53387,53388,53389,53390,53391,53392,53393,53394,53395,53396,45535,45544,45545,45548,45552,45561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593,45600,45620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701,45705,45712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738,45740,45744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794,45796,45797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815,45816,45817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844,45845,45852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,53397,53398,53399,53400,53401,53402,53403,53404,53405,53406,53407,53408,53409,53410,53411,53414,53415,53417,53418,53419,53421,53422,53423,53424,53425,53426,null,null,null,null,null,null,53427,53430,53432,53434,53435,53436,53437,53438,53439,53442,53443,53445,53446,53447,53450,53451,53452,53453,53454,53455,53458,53462,53463,53464,53465,53466,null,null,null,null,null,null,53467,53470,53471,53473,53474,53475,53477,53478,53479,53480,53481,53482,53483,53486,53490,53491,53492,53493,53494,53495,53497,53498,53499,53500,53501,53502,53503,53504,53505,53506,53507,53508,45927,45929,45931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964,45968,45972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032,46036,46037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108,46112,46120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181,46188,46208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280,46288,46293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328,46356,46357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385,46388,46392,53509,53510,53511,53512,53513,53514,53515,53516,53518,53519,53520,53521,53522,53523,53524,53525,53526,53527,53528,53529,53530,53531,53532,53533,53534,53535,null,null,null,null,null,null,53536,53537,53538,53539,53540,53541,53542,53543,53544,53545,53546,53547,53548,53549,53550,53551,53554,53555,53557,53558,53559,53561,53563,53564,53565,53566,null,null,null,null,null,null,53567,53570,53574,53575,53576,53577,53578,53579,53582,53583,53585,53586,53587,53589,53590,53591,53592,53593,53594,53595,53598,53600,53602,53603,53604,53605,53606,53607,53609,53610,53611,53613,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428,46429,46431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515,46516,46517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552,46572,46608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749,46752,46756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888,46889,46892,46895,46896,46904,46905,46907,46916,46920,46924,46932,46933,46944,46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,46988,46989,46991,46992,46993,46994,46998,46999,53614,53615,53616,53617,53618,53619,53620,53621,53622,53623,53624,53625,53626,53627,53629,53630,53631,53632,53633,53634,53635,53637,53638,53639,53641,53642,null,null,null,null,null,null,53643,53644,53645,53646,53647,53648,53649,53650,53651,53652,53653,53654,53655,53656,53657,53658,53659,53660,53661,53662,53663,53666,53667,53669,53670,53671,null,null,null,null,null,null,53673,53674,53675,53676,53677,53678,53679,53682,53684,53686,53687,53688,53689,53691,53693,53694,53695,53697,53698,53699,53700,53701,53702,53703,53704,53705,53706,53707,53708,53709,53710,53711,47000,47001,47004,47008,47016,47017,47019,47020,47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,47100,47101,47103,47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,47133,47140,47141,47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,47187,47196,47197,47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,47280,47284,47288,47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,47336,47337,47340,47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,47424,47428,47436,47439,47441,47448,47449,47452,47456,47464,47465,53712,53713,53714,53715,53716,53717,53718,53719,53721,53722,53723,53724,53725,53726,53727,53728,53729,53730,53731,53732,53733,53734,53735,53736,53737,53738,null,null,null,null,null,null,53739,53740,53741,53742,53743,53744,53745,53746,53747,53749,53750,53751,53753,53754,53755,53756,53757,53758,53759,53760,53761,53762,53763,53764,53765,53766,null,null,null,null,null,null,53768,53770,53771,53772,53773,53774,53775,53777,53778,53779,53780,53781,53782,53783,53784,53785,53786,53787,53788,53789,53790,53791,53792,53793,53794,53795,53796,53797,53798,53799,53800,53801,47467,47469,47476,47477,47480,47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,47536,47540,47548,47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,47570,47576,47577,47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,47605,47607,47608,47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,47682,47688,47689,47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,47719,47720,47721,47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,47785,47787,47788,47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,47868,53802,53803,53806,53807,53809,53810,53811,53813,53814,53815,53816,53817,53818,53819,53822,53824,53826,53827,53828,53829,53830,53831,53833,53834,53835,53836,null,null,null,null,null,null,53837,53838,53839,53840,53841,53842,53843,53844,53845,53846,53847,53848,53849,53850,53851,53853,53854,53855,53856,53857,53858,53859,53861,53862,53863,53864,null,null,null,null,null,null,53865,53866,53867,53868,53869,53870,53871,53872,53873,53874,53875,53876,53877,53878,53879,53880,53881,53882,53883,53884,53885,53886,53887,53890,53891,53893,53894,53895,53897,53898,53899,53900,47872,47876,47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,47926,47928,47931,47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,47956,47960,47969,47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,48064,48068,48072,48080,48083,48120,48121,48124,48127,48128,48130,48136,48137,48139,48140,48141,48143,48145,48148,48149,48150,48151,48152,48155,48156,48157,48158,48159,48164,48165,48167,48169,48173,48176,48177,48180,48184,48192,48193,48195,48196,48197,48201,48204,48205,48208,48221,48260,48261,48264,48267,48268,48270,48276,48277,48279,53901,53902,53903,53906,53907,53908,53910,53911,53912,53913,53914,53915,53917,53918,53919,53921,53922,53923,53925,53926,53927,53928,53929,53930,53931,53933,null,null,null,null,null,null,53934,53935,53936,53938,53939,53940,53941,53942,53943,53946,53947,53949,53950,53953,53955,53956,53957,53958,53959,53962,53964,53965,53966,53967,53968,53969,null,null,null,null,null,null,53970,53971,53973,53974,53975,53977,53978,53979,53981,53982,53983,53984,53985,53986,53987,53990,53991,53992,53993,53994,53995,53996,53997,53998,53999,54002,54003,54005,54006,54007,54009,54010,48281,48282,48288,48289,48292,48295,48296,48304,48305,48307,48308,48309,48316,48317,48320,48324,48333,48335,48336,48337,48341,48344,48348,48372,48373,48374,48376,48380,48388,48389,48391,48393,48400,48404,48420,48428,48448,48456,48457,48460,48464,48472,48473,48484,48488,48512,48513,48516,48519,48520,48521,48522,48528,48529,48531,48533,48537,48538,48540,48548,48560,48568,48596,48597,48600,48604,48617,48624,48628,48632,48640,48643,48645,48652,48653,48656,48660,48668,48669,48671,48708,48709,48712,48716,48718,48724,48725,48727,48729,48730,48731,48736,48737,48740,54011,54012,54013,54014,54015,54018,54020,54022,54023,54024,54025,54026,54027,54031,54033,54034,54035,54037,54039,54040,54041,54042,54043,54046,54050,54051,null,null,null,null,null,null,54052,54054,54055,54058,54059,54061,54062,54063,54065,54066,54067,54068,54069,54070,54071,54074,54078,54079,54080,54081,54082,54083,54086,54087,54088,54089,null,null,null,null,null,null,54090,54091,54092,54093,54094,54095,54096,54097,54098,54099,54100,54101,54102,54103,54104,54105,54106,54107,54108,54109,54110,54111,54112,54113,54114,54115,54116,54117,54118,54119,54120,54121,48744,48746,48752,48753,48755,48756,48757,48763,48764,48765,48768,48772,48780,48781,48783,48784,48785,48792,48793,48808,48848,48849,48852,48855,48856,48864,48867,48868,48869,48876,48897,48904,48905,48920,48921,48923,48924,48925,48960,48961,48964,48968,48976,48977,48981,49044,49072,49093,49100,49101,49104,49108,49116,49119,49121,49212,49233,49240,49244,49248,49256,49257,49296,49297,49300,49304,49312,49313,49315,49317,49324,49325,49327,49328,49331,49332,49333,49334,49340,49341,49343,49344,49345,49349,49352,49353,49356,49360,49368,49369,49371,49372,49373,49380,54122,54123,54124,54125,54126,54127,54128,54129,54130,54131,54132,54133,54134,54135,54136,54137,54138,54139,54142,54143,54145,54146,54147,54149,54150,54151,null,null,null,null,null,null,54152,54153,54154,54155,54158,54162,54163,54164,54165,54166,54167,54170,54171,54173,54174,54175,54177,54178,54179,54180,54181,54182,54183,54186,54188,54190,null,null,null,null,null,null,54191,54192,54193,54194,54195,54197,54198,54199,54201,54202,54203,54205,54206,54207,54208,54209,54210,54211,54214,54215,54218,54219,54220,54221,54222,54223,54225,54226,54227,54228,54229,54230,49381,49384,49388,49396,49397,49399,49401,49408,49412,49416,49424,49429,49436,49437,49438,49439,49440,49443,49444,49446,49447,49452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480,49481,49483,49484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513,49520,49524,49528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567,49569,49573,49576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624,49632,49636,49640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679,49681,49688,49689,49692,49695,49696,49704,49705,49707,49709,54231,54233,54234,54235,54236,54237,54238,54239,54240,54242,54244,54245,54246,54247,54248,54249,54250,54251,54254,54255,54257,54258,54259,54261,54262,54263,null,null,null,null,null,null,54264,54265,54266,54267,54270,54272,54274,54275,54276,54277,54278,54279,54281,54282,54283,54284,54285,54286,54287,54288,54289,54290,54291,54292,54293,54294,null,null,null,null,null,null,54295,54296,54297,54298,54299,54300,54302,54303,54304,54305,54306,54307,54308,54309,54310,54311,54312,54313,54314,54315,54316,54317,54318,54319,54320,54321,54322,54323,54324,54325,54326,54327,49711,49713,49714,49716,49736,49744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788,49789,49791,49793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836,49837,49844,49845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901,49903,49905,49910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939,49940,49941,49944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032,50034,50040,50041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143,50144,50146,50152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224,54328,54329,54330,54331,54332,54333,54334,54335,54337,54338,54339,54341,54342,54343,54344,54345,54346,54347,54348,54349,54350,54351,54352,54353,54354,54355,null,null,null,null,null,null,54356,54357,54358,54359,54360,54361,54362,54363,54365,54366,54367,54369,54370,54371,54373,54374,54375,54376,54377,54378,54379,54380,54382,54384,54385,54386,null,null,null,null,null,null,54387,54388,54389,54390,54391,54394,54395,54397,54398,54401,54403,54404,54405,54406,54407,54410,54412,54414,54415,54416,54417,54418,54419,54421,54422,54423,54424,54425,54426,54427,54428,54429,50228,50236,50237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324,50332,50360,50364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444,50448,50452,50460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501,50504,50505,50506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525,50526,50528,50529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560,50564,50567,50572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612,50613,50616,50617,50619,50620,50621,50622,50628,50629,50630,50631,50632,50633,50634,50636,50638,54430,54431,54432,54433,54434,54435,54436,54437,54438,54439,54440,54442,54443,54444,54445,54446,54447,54448,54449,54450,54451,54452,54453,54454,54455,54456,null,null,null,null,null,null,54457,54458,54459,54460,54461,54462,54463,54464,54465,54466,54467,54468,54469,54470,54471,54472,54473,54474,54475,54477,54478,54479,54481,54482,54483,54485,null,null,null,null,null,null,54486,54487,54488,54489,54490,54491,54493,54494,54496,54497,54498,54499,54500,54501,54502,54503,54505,54506,54507,54509,54510,54511,54513,54514,54515,54516,54517,54518,54519,54521,54522,54524,50640,50641,50644,50648,50656,50657,50659,50661,50668,50669,50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,50693,50694,50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,50732,50733,50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,50760,50768,50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,50809,50812,50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,50855,50857,50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,50893,50896,50900,50908,50909,50912,50913,50920,54526,54527,54528,54529,54530,54531,54533,54534,54535,54537,54538,54539,54541,54542,54543,54544,54545,54546,54547,54550,54552,54553,54554,54555,54556,54557,null,null,null,null,null,null,54558,54559,54560,54561,54562,54563,54564,54565,54566,54567,54568,54569,54570,54571,54572,54573,54574,54575,54576,54577,54578,54579,54580,54581,54582,54583,null,null,null,null,null,null,54584,54585,54586,54587,54590,54591,54593,54594,54595,54597,54598,54599,54600,54601,54602,54603,54606,54608,54610,54611,54612,54613,54614,54615,54618,54619,54621,54622,54623,54625,54626,54627,50921,50924,50928,50936,50937,50941,50948,50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,50992,50993,50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,51025,51026,51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,51061,51064,51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,51088,51089,51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,51116,51117,51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,51152,51160,51165,51172,51176,51180,51200,51201,51204,51208,51210,54628,54630,54631,54634,54636,54638,54639,54640,54641,54642,54643,54646,54647,54649,54650,54651,54653,54654,54655,54656,54657,54658,54659,54662,54666,54667,null,null,null,null,null,null,54668,54669,54670,54671,54673,54674,54675,54676,54677,54678,54679,54680,54681,54682,54683,54684,54685,54686,54687,54688,54689,54690,54691,54692,54694,54695,null,null,null,null,null,null,54696,54697,54698,54699,54700,54701,54702,54703,54704,54705,54706,54707,54708,54709,54710,54711,54712,54713,54714,54715,54716,54717,54718,54719,54720,54721,54722,54723,54724,54725,54726,54727,51216,51217,51219,51221,51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,51264,51272,51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,51331,51333,51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,51389,51396,51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,51453,51456,51460,51461,51462,51468,51469,51471,51473,51480,51500,51508,51536,51537,51540,51544,51552,51553,51555,51564,51568,51572,51580,51592,51593,51596,51600,51608,51609,51611,51613,51648,51649,51652,51655,51656,51658,51664,51665,51667,54730,54731,54733,54734,54735,54737,54739,54740,54741,54742,54743,54746,54748,54750,54751,54752,54753,54754,54755,54758,54759,54761,54762,54763,54765,54766,null,null,null,null,null,null,54767,54768,54769,54770,54771,54774,54776,54778,54779,54780,54781,54782,54783,54786,54787,54789,54790,54791,54793,54794,54795,54796,54797,54798,54799,54802,null,null,null,null,null,null,54806,54807,54808,54809,54810,54811,54813,54814,54815,54817,54818,54819,54821,54822,54823,54824,54825,54826,54827,54828,54830,54831,54832,54833,54834,54835,54836,54837,54838,54839,54842,54843,51669,51670,51673,51674,51676,51677,51680,51682,51684,51687,51692,51693,51695,51696,51697,51704,51705,51708,51712,51720,51721,51723,51724,51725,51732,51736,51753,51788,51789,51792,51796,51804,51805,51807,51808,51809,51816,51837,51844,51864,51900,51901,51904,51908,51916,51917,51919,51921,51923,51928,51929,51936,51948,51956,51976,51984,51988,51992,52000,52001,52033,52040,52041,52044,52048,52056,52057,52061,52068,52088,52089,52124,52152,52180,52196,52199,52201,52236,52237,52240,52244,52252,52253,52257,52258,52263,52264,52265,52268,52270,52272,52280,52281,52283,54845,54846,54847,54849,54850,54851,54852,54854,54855,54858,54860,54862,54863,54864,54866,54867,54870,54871,54873,54874,54875,54877,54878,54879,54880,54881,null,null,null,null,null,null,54882,54883,54884,54885,54886,54888,54890,54891,54892,54893,54894,54895,54898,54899,54901,54902,54903,54904,54905,54906,54907,54908,54909,54910,54911,54912,null,null,null,null,null,null,54913,54914,54916,54918,54919,54920,54921,54922,54923,54926,54927,54929,54930,54931,54933,54934,54935,54936,54937,54938,54939,54940,54942,54944,54946,54947,54948,54949,54950,54951,54953,54954,52284,52285,52286,52292,52293,52296,52300,52308,52309,52311,52312,52313,52320,52324,52326,52328,52336,52341,52376,52377,52380,52384,52392,52393,52395,52396,52397,52404,52405,52408,52412,52420,52421,52423,52425,52432,52436,52452,52460,52464,52481,52488,52489,52492,52496,52504,52505,52507,52509,52516,52520,52524,52537,52572,52576,52580,52588,52589,52591,52593,52600,52616,52628,52629,52632,52636,52644,52645,52647,52649,52656,52676,52684,52688,52712,52716,52720,52728,52729,52731,52733,52740,52744,52748,52756,52761,52768,52769,52772,52776,52784,52785,52787,52789,54955,54957,54958,54959,54961,54962,54963,54964,54965,54966,54967,54968,54970,54972,54973,54974,54975,54976,54977,54978,54979,54982,54983,54985,54986,54987,null,null,null,null,null,null,54989,54990,54991,54992,54994,54995,54997,54998,55000,55002,55003,55004,55005,55006,55007,55009,55010,55011,55013,55014,55015,55017,55018,55019,55020,55021,null,null,null,null,null,null,55022,55023,55025,55026,55027,55028,55030,55031,55032,55033,55034,55035,55038,55039,55041,55042,55043,55045,55046,55047,55048,55049,55050,55051,55052,55053,55054,55055,55056,55058,55059,55060,52824,52825,52828,52831,52832,52833,52840,52841,52843,52845,52852,52853,52856,52860,52868,52869,52871,52873,52880,52881,52884,52888,52896,52897,52899,52900,52901,52908,52909,52929,52964,52965,52968,52971,52972,52980,52981,52983,52984,52985,52992,52993,52996,53000,53008,53009,53011,53013,53020,53024,53028,53036,53037,53039,53040,53041,53048,53076,53077,53080,53084,53092,53093,53095,53097,53104,53105,53108,53112,53120,53125,53132,53153,53160,53168,53188,53216,53217,53220,53224,53232,53233,53235,53237,53244,53248,53252,53265,53272,53293,53300,53301,53304,53308,55061,55062,55063,55066,55067,55069,55070,55071,55073,55074,55075,55076,55077,55078,55079,55082,55084,55086,55087,55088,55089,55090,55091,55094,55095,55097,null,null,null,null,null,null,55098,55099,55101,55102,55103,55104,55105,55106,55107,55109,55110,55112,55114,55115,55116,55117,55118,55119,55122,55123,55125,55130,55131,55132,55133,55134,null,null,null,null,null,null,55135,55138,55140,55142,55143,55144,55146,55147,55149,55150,55151,55153,55154,55155,55157,55158,55159,55160,55161,55162,55163,55166,55167,55168,55170,55171,55172,55173,55174,55175,55178,55179,53316,53317,53319,53321,53328,53332,53336,53344,53356,53357,53360,53364,53372,53373,53377,53412,53413,53416,53420,53428,53429,53431,53433,53440,53441,53444,53448,53449,53456,53457,53459,53460,53461,53468,53469,53472,53476,53484,53485,53487,53488,53489,53496,53517,53552,53553,53556,53560,53562,53568,53569,53571,53572,53573,53580,53581,53584,53588,53596,53597,53599,53601,53608,53612,53628,53636,53640,53664,53665,53668,53672,53680,53681,53683,53685,53690,53692,53696,53720,53748,53752,53767,53769,53776,53804,53805,53808,53812,53820,53821,53823,53825,53832,53852,55181,55182,55183,55185,55186,55187,55188,55189,55190,55191,55194,55196,55198,55199,55200,55201,55202,55203,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,53860,53888,53889,53892,53896,53904,53905,53909,53916,53920,53924,53932,53937,53944,53945,53948,53951,53952,53954,53960,53961,53963,53972,53976,53980,53988,53989,54000,54001,54004,54008,54016,54017,54019,54021,54028,54029,54030,54032,54036,54038,54044,54045,54047,54048,54049,54053,54056,54057,54060,54064,54072,54073,54075,54076,54077,54084,54085,54140,54141,54144,54148,54156,54157,54159,54160,54161,54168,54169,54172,54176,54184,54185,54187,54189,54196,54200,54204,54212,54213,54216,54217,54224,54232,54241,54243,54252,54253,54256,54260,54268,54269,54271,54273,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,54280,54301,54336,54340,54364,54368,54372,54381,54383,54392,54393,54396,54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,54492,54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,54551,54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,54629,54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,54665,54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,54757,54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,54803,54804,54805,54812,54816,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,54820,54829,54840,54841,54844,54848,54853,54856,54857,54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,54915,54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,54971,54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,55029,55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,55085,55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,55128,55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,55176,55177,55180,55184,55192,55193,55195,55197,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,20285,20339,20551,20729,21152,21487,21621,21733,22025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292,33499,33540,34903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508,24682,24932,27580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014,24178,24185,25031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487,31777,32925,33390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883,35088,34638,38824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204,28187,29976,30131,30435,30640,32058,37039,37969,37970,40853,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,21283,23724,30002,32987,37440,38296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743,30074,30086,31968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477,40007,20171,20215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117,30342,30422,31623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923,32697,37301,20520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067,36317,36382,63746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967,33137,34388,36423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,30652,37392,40660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608,33160,35233,38548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963,40273,25225,27770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772,20140,20435,20510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950,25004,25806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898,30169,30828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629,36885,37857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760,25106,26690,26800,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336,35489,35903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235,25335,25911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660,32771,32929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678,38599,39015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372,23825,26118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844,20849,21151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002,38799,20018,23521,25096,26524,29916,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,31185,33747,35463,35506,36328,36942,37707,38982,24275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748,29743,29912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866,20362,20809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979,21350,25499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439,32024,32945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657,27211,29409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171,39509,39851,19992,20037,20061,20167,20465,20855,21246,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,21312,21475,21477,21646,22036,22389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472,27590,27628,27714,28317,28792,29399,29590,29699,30655,30697,31350,32127,32777,33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,37476,37558,39378,39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,21531,31384,32676,35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,31406,33422,36524,20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,21413,29527,34152,36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,27512,36020,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,39740,63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,31998,33909,35215,36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,27224,20811,21067,21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,26681,27135,29822,31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,25810,26129,27278,29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,21450,24613,25201,27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,20864,21980,22120,22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,24190,24524,25216,26071,26083,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,26398,26399,26462,26827,26820,27231,27450,27683,27773,27778,28103,29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,31047,31048,31098,31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,36215,37665,37668,39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,26708,37329,21931,20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,63760,63761,63762,63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,63771,63772,26262,63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,26511,26976,28275,63778,30007,63779,63780,63781,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,32013,63782,63783,34930,22218,23064,63784,63785,63786,63787,63788,20035,63789,20839,22856,26608,32784,63790,22899,24180,25754,31178,24565,24684,25288,25467,23527,23511,21162,63791,22900,24361,24594,63792,63793,63794,29785,63795,63796,63797,63798,63799,63800,39377,63801,63802,63803,63804,63805,63806,63807,63808,63809,63810,63811,28611,63812,63813,33215,36786,24817,63814,63815,33126,63816,63817,23615,63818,63819,63820,63821,63822,63823,63824,63825,23273,35365,26491,32016,63826,63827,63828,63829,63830,63831,33021,63832,63833,23612,27877,21311,28346,22810,33590,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,20025,20150,20294,21934,22296,22727,24406,26039,26086,27264,27573,28237,30701,31471,31774,32222,34507,34962,37170,37723,25787,28606,29562,30136,36948,21846,22349,25018,25812,26311,28129,28251,28525,28601,30192,32835,33213,34113,35203,35527,35674,37663,27795,30035,31572,36367,36957,21776,22530,22616,24162,25095,25758,26848,30070,31958,34739,40680,20195,22408,22382,22823,23565,23729,24118,24453,25140,25825,29619,33274,34955,36024,38538,40667,23429,24503,24755,20498,20992,21040,22294,22581,22615,23566,23648,23798,23947,24230,24466,24764,25361,25481,25623,26691,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,26873,27330,28120,28193,28372,28644,29182,30428,30585,31153,31291,33796,35241,36077,36339,36424,36867,36884,36947,37117,37709,38518,38876,27602,28678,29272,29346,29544,30563,31167,31716,32411,35712,22697,24775,25958,26109,26302,27788,28958,29129,35930,38931,20077,31361,20189,20908,20941,21205,21516,24999,26481,26704,26847,27934,28540,30140,30643,31461,33012,33891,37509,20828,26007,26460,26515,30168,31431,33651,63834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471,23965,27225,29128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313,32645,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,34367,34746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226,39409,63838,20098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888,25829,25900,27414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266,26391,28010,29436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504,30053,20142,20486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635,37327,20406,20791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268,34851,38317,39522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722,24976,25088,25891,28451,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,29001,29833,32244,32879,34030,36646,36899,37706,20925,21015,21155,27916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278,22265,63839,23738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646,38728,38936,40801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347,28510,28696,29200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565,30860,31103,32160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903,31840,32894,20769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534,24278,26009,29134,30274,30637,32842,34044,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,36988,39719,40845,22744,23105,23650,27155,28122,28431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611,27060,27969,28316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134,38520,20374,20523,23833,28138,32184,36650,24459,24900,26647,63841,38534,21202,32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,21519,21774,23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,31852,32633,32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,29848,34298,36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,31435,31520,31890,25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,33180,33707,37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,28459,28771,30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,33545,35178,38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,36638,37017,22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,36067,36993,39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,33804,20906,35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,40629,28357,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,33986,34719,37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,25721,26286,26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,33541,35584,35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,22818,26406,33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,33495,37672,21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,28961,29687,30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,20497,21006,21563,21839,25991,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,27766,32010,32011,32862,34442,38272,38639,21247,27797,29289,21619,23194,23614,23883,24396,24494,26410,26806,26979,28220,28228,30473,31859,32654,34183,35598,36855,38753,40692,23735,24758,24845,25003,25935,26107,26108,27665,27887,29599,29641,32225,38292,23494,34588,35600,21085,21338,25293,25615,25778,26420,27192,27850,29632,29854,31636,31893,32283,33162,33334,34180,36843,38649,39361,20276,21322,21453,21467,25292,25644,25856,26001,27075,27886,28504,29677,30036,30242,30436,30460,30928,30971,31020,32070,33324,34784,36820,38930,39151,21187,25300,25765,28196,28497,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,30332,36299,37297,37474,39662,39747,20515,20621,22346,22952,23592,24135,24439,25151,25918,26041,26049,26121,26507,27036,28354,30917,32033,32938,33152,33323,33459,33953,34444,35370,35607,37030,38450,40848,20493,20467,63843,22521,24472,25308,25490,26479,28227,28953,30403,32972,32986,35060,35061,35097,36064,36649,37197,38506,20271,20336,24091,26575,26658,30333,30334,39748,24161,27146,29033,29140,30058,63844,32321,34115,34281,39132,20240,31567,32624,38309,20961,24070,26805,27710,27726,27867,29359,31684,33539,27861,29754,20731,21128,22721,25816,27287,29863,30294,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,30887,34327,38370,38713,63845,21342,24321,35722,36776,36783,37002,21029,30629,40009,40712,19993,20482,20853,23643,24183,26142,26170,26564,26821,28851,29953,30149,31177,31453,36647,39200,39432,20445,22561,22577,23542,26222,27493,27921,28282,28541,29668,29995,33769,35036,35091,35676,36628,20239,20693,21264,21340,23443,24489,26381,31119,33145,33583,34068,35079,35206,36665,36667,39333,39954,26412,20086,20472,22857,23553,23791,23792,25447,26834,28925,29090,29739,32299,34028,34562,36898,37586,40179,19981,20184,20463,20613,21078,21103,21542,21648,22496,22827,23142,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,23386,23413,23500,24220,63846,25206,25975,26023,28014,28325,29238,31526,31807,32566,33104,33105,33178,33344,33433,33705,35331,36000,36070,36091,36212,36282,37096,37340,38428,38468,39385,40167,21271,20998,21545,22132,22707,22868,22894,24575,24996,25198,26128,27774,28954,30406,31881,31966,32027,33452,36033,38640,63847,20315,24343,24447,25282,23849,26379,26842,30844,32323,40300,19989,20633,21269,21290,21329,22915,23138,24199,24754,24970,25161,25209,26000,26503,27047,27604,27606,27607,27608,27832,63848,29749,30202,30738,30865,31189,31192,31875,32203,32737,32933,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,33086,33218,33778,34586,35048,35513,35692,36027,37145,38750,39131,40763,22188,23338,24428,25996,27315,27567,27996,28657,28693,29277,29613,36007,36051,38971,24977,27703,32856,39425,20045,20107,20123,20181,20282,20284,20351,20447,20735,21490,21496,21766,21987,22235,22763,22882,23057,23531,23546,23556,24051,24107,24473,24605,25448,26012,26031,26614,26619,26797,27515,27801,27863,28195,28681,29509,30722,31038,31040,31072,31169,31721,32023,32114,32902,33293,33678,34001,34503,35039,35408,35422,35613,36060,36198,36781,37034,39164,39391,40605,21066,63849,26388,63850,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,20632,21034,23665,25955,27733,29642,29987,30109,31639,33948,37240,38704,20087,25746,27578,29022,34217,19977,63851,26441,26862,28183,33439,34072,34923,25591,28545,37394,39087,19978,20663,20687,20767,21830,21930,22039,23360,23577,23776,24120,24202,24224,24258,24819,26705,27233,28248,29245,29248,29376,30456,31077,31665,32724,35059,35316,35443,35937,36062,38684,22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,31513,22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,26360,26646,26866,29312,29790,31598,32110,32214,32626,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,32997,33298,34223,35199,35475,36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,28101,28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,25159,25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,32680,33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,21352,23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,21089,26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,22995,23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,32854,32882,33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,21484,22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,28040,28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,32057,34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,26463,28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,29575,23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,37782,34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,24101,24833,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,29159,29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,32353,32670,33065,33585,33936,34010,34282,34966,35504,35728,36664,36930,36995,37228,37526,37561,38539,38567,38568,38614,38656,38920,39318,39635,39706,21460,22654,22809,23408,23487,28113,28506,29087,29729,29881,32901,33789,24033,24455,24490,24642,26092,26642,26991,27219,27529,27957,28147,29667,30462,30636,31565,32020,33059,33308,33600,34036,34147,35426,35524,37255,37662,38918,39348,25100,34899,36848,37477,23815,23847,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,23913,29791,33181,34664,28629,25342,32722,35126,35186,19998,20056,20711,21213,21319,25215,26119,32361,34821,38494,20365,21273,22070,22987,23204,23608,23630,23629,24066,24337,24643,26045,26159,26178,26558,26612,29468,30690,31034,32709,33940,33997,35222,35430,35433,35553,35925,35962,22516,23508,24335,24687,25325,26893,27542,28252,29060,31698,34645,35672,36606,39135,39166,20280,20353,20449,21627,23072,23480,24892,26032,26216,29180,30003,31070,32051,33102,33251,33688,34218,34254,34563,35338,36523,36763,63857,36805,22833,23460,23526,24713,23529,23563,24515,27777,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,63858,28145,28683,29978,33455,35574,20160,21313,63859,38617,27663,20126,20420,20818,21854,23077,23784,25105,29273,33469,33706,34558,34905,35357,38463,38597,39187,40201,40285,22538,23731,23997,24132,24801,24853,25569,27138,28197,37122,37716,38990,39952,40823,23433,23736,25353,26191,26696,30524,38593,38797,38996,39839,26017,35585,36555,38332,21813,23721,24022,24245,26263,30284,33780,38343,22739,25276,29390,40232,20208,22830,24591,26171,27523,31207,40230,21395,21696,22467,23830,24859,26326,28079,30861,33406,38552,38724,21380,25212,25494,28082,32266,33099,38989,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,27387,32588,40367,40474,20063,20539,20918,22812,24825,25590,26928,29242,32822,63860,37326,24369,63861,63862,32004,33509,33903,33979,34277,36493,63863,20335,63864,63865,22756,23363,24665,25562,25880,25965,26264,63866,26954,27171,27915,28673,29036,30162,30221,31155,31344,63867,32650,63868,35140,63869,35731,37312,38525,63870,39178,22276,24481,26044,28417,30208,31142,35486,39341,39770,40812,20740,25014,25233,27277,33222,20547,22576,24422,28937,35328,35578,23420,34326,20474,20796,22196,22852,25513,28153,23978,26989,20870,20104,20313,63871,63872,63873,22914,63874,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,63875,27487,27741,63876,29877,30998,63877,33287,33349,33593,36671,36701,63878,39192,63879,63880,63881,20134,63882,22495,24441,26131,63883,63884,30123,32377,35695,63885,36870,39515,22181,22567,23032,23071,23476,63886,24310,63887,63888,25424,25403,63889,26941,27783,27839,28046,28051,28149,28436,63890,28895,28982,29017,63891,29123,29141,63892,30799,30831,63893,31605,32227,63894,32303,63895,34893,36575,63896,63897,63898,37467,63899,40182,63900,63901,63902,24709,28037,63903,29105,63904,63905,38321,21421,63906,63907,63908,26579,63909,28814,28976,29744,33398,33490,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,63910,38331,39653,40573,26308,63911,29121,33865,63912,63913,22603,63914,63915,23992,24433,63916,26144,26254,27001,27054,27704,27891,28214,28481,28634,28699,28719,29008,29151,29552,63917,29787,63918,29908,30408,31310,32403,63919,63920,33521,35424,36814,63921,37704,63922,38681,63923,63924,20034,20522,63925,21000,21473,26355,27757,28618,29450,30591,31330,33454,34269,34306,63926,35028,35427,35709,35947,63927,37555,63928,38675,38928,20116,20237,20425,20658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034,25942,26111,26212,26791,27738,28595,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,28879,29100,29522,31613,34568,35492,39986,40711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800,22725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402,33253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740,30871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505,27754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931,20709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747,25854,63934,26332,63935,27208,63936,29183,29796,63937,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,31368,31407,32327,32350,32768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020,32287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029,28044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854,63940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962,26100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398,36802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020,31286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,36939,38549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290,22435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503,29783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301,20553,20702,21361,22285,22996,23041,23561,24944,26256,28205,29234,29771,32239,32963,33806,33894,34111,34655,34907,35096,35586,36949,38859,39759,20083,20369,20754,20842,63943,21807,21929,23418,23461,24188,24189,24254,24736,24799,24840,24841,25540,25912,26377,63944,26580,26586,63945,26977,26978,27833,27943,63946,28216,63947,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,28641,29494,29495,63948,29788,30001,63949,30290,63950,63951,32173,33278,33848,35029,35480,35547,35565,36400,36418,36938,36926,36986,37193,37321,37742,63952,63953,22537,63954,27603,32905,32946,63955,63956,20801,22891,23609,63957,63958,28516,29607,32996,36103,63959,37399,38287,63960,63961,63962,63963,32895,25102,28700,32104,34701,63964,22432,24681,24903,27575,35518,37504,38577,20057,21535,28139,34093,38512,38899,39150,25558,27875,37009,20957,25033,33210,40441,20381,20506,20736,23452,24847,25087,25836,26885,27589,30097,30691,32681,33380,34191,34811,34915,35516,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,35696,37291,20108,20197,20234,63965,63966,22839,23016,63967,24050,24347,24411,24609,63968,63969,63970,63971,29246,29669,63972,30064,30157,63973,31227,63974,32780,32819,32900,33505,33617,63975,63976,36029,36019,36999,63977,63978,39156,39180,63979,63980,28727,30410,32714,32716,32764,35610,20154,20161,20995,21360,63981,21693,22240,23035,23493,24341,24525,28270,63982,63983,32106,33589,63984,34451,35469,63985,38765,38775,63986,63987,19968,20314,20350,22777,26085,28322,36920,37808,39353,20219,22764,22922,23001,24641,63988,63989,31252,63990,33615,36035,20837,21316,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,63991,63992,63993,20173,21097,23381,33471,20180,21050,21672,22985,23039,23376,23383,23388,24675,24904,28363,28825,29038,29574,29943,30133,30913,32043,32773,33258,33576,34071,34249,35566,36039,38604,20316,21242,22204,26027,26152,28796,28856,29237,32189,33421,37196,38592,40306,23409,26855,27544,28538,30430,23697,26283,28507,31668,31786,34870,38620,19976,20183,21280,22580,22715,22767,22892,23559,24115,24196,24373,25484,26290,26454,27167,27299,27404,28479,29254,63994,29520,29835,31456,31911,33144,33247,33255,33674,33900,34083,34196,34255,35037,36115,37292,38263,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,38556,20877,21705,22312,23472,25165,26448,26685,26771,28221,28371,28797,32289,35009,36001,36617,40779,40782,29229,31631,35533,37658,20295,20302,20786,21632,22992,24213,25269,26485,26990,27159,27822,28186,29401,29482,30141,31672,32053,33511,33785,33879,34295,35419,36015,36487,36889,37048,38606,40799,21219,21514,23265,23490,25688,25973,28404,29380,63995,30340,31309,31515,31821,32318,32735,33659,35627,36042,36196,36321,36447,36842,36857,36969,37841,20291,20346,20659,20840,20856,21069,21098,22625,22652,22880,23560,23637,24283,24731,25136,26643,27583,27656,28593,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,29006,29728,30000,30008,30033,30322,31564,31627,31661,31686,32399,35438,36670,36681,37439,37523,37666,37931,38651,39002,39019,39198,20999,25130,25240,27993,30308,31434,31680,32118,21344,23742,24215,28472,28857,31896,38673,39822,40670,25509,25722,34678,19969,20117,20141,20572,20597,21576,22979,23450,24128,24237,24311,24449,24773,25402,25919,25972,26060,26230,26232,26622,26984,27273,27491,27712,28096,28136,28191,28254,28702,28833,29582,29693,30010,30555,30855,31118,31243,31357,31934,32142,33351,35330,35562,35998,37165,37194,37336,37478,37580,37664,38662,38742,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,38748,38914,40718,21046,21137,21884,22564,24093,24351,24716,25552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500,38555,38717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805,26089,26177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226,29866,30522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299,34468,35412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751,36275,37827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837,28121,29742,31278,32066,32156,32305,33131,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,36394,36405,37758,37912,20304,22352,24038,24231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014,22863,23449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855,29664,30087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659,36913,37198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803,26201,27197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423,33537,20013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366,25327,28893,29969,30151,32338,33976,35657,36104,20043,21482,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,21675,22320,22336,24535,25345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460,30693,30757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996,36100,36286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634,26185,26187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433,30494,30603,31206,32265,32285,33275,34095,34967,35386,36049,36587,36784,36914,37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,29894,30142,31209,31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,28503,32221,36655,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,23919,24046,27425,27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,31364,37679,38015,40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,32408,35738,36106,38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,22649,24920,24921,25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,24288,24432,24884,25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,33081,33369,33750,33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,34081,37319,37365,20874,26613,31574,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,36012,20932,22971,24765,34389,20508,63999,21076,23610,24957,25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,20191,21315,21912,22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,36368,36983,37351,38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,36639,36685,37941,20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,22558,22974,24086,25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,32893,33729,35531,38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,36958,39636,21021,21119,21736,24980,25220,25307,26786,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,26898,26970,27189,28818,28966,30813,30977,30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,37218,37259,37294,20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,21474,22618,23541,24740,24961,25696,32317,32880,34085,37507,25774,20652,23828,26368,22684,25277,25512,26894,27000,27166,28267,30394,31179,33467,33833,35535,36264,36861,37138,37195,37276,37648,37656,37786,38619,39478,39949,19985,30044,31069,31482,31569,31689,32302,33988,36441,36468,36600,36880,26149,26943,29763,20986,26414,40668,20805,24544,27798,34802,34909,34935,24756,33205,33795,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,36101,21462,21561,22068,23094,23601,28810,32736,32858,33030,33261,36259,37257,39519,40434,20596,20164,21408,24827,28204,23652,20360,20516,21988,23769,24159,24677,26772,27835,28100,29118,30164,30196,30305,31258,31305,32199,32251,32622,33268,34473,36636,38601,39347,40786,21063,21189,39149,35242,19971,26578,28422,20405,23522,26517,27784,28024,29723,30759,37341,37756,34756,31204,31281,24555,20182,21668,21822,22702,22949,24816,25171,25302,26422,26965,33333,38464,39345,39389,20524,21331,21828,22396,64001,25176,64002,25826,26219,26589,28609,28655,29730,29752,35351,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,37944,21585,22022,22374,24392,24986,27470,28760,28845,32187,35477,22890,33067,25506,30472,32829,36010,22612,25645,27067,23445,24081,28271,64003,34153,20812,21488,22826,24608,24907,27526,27760,27888,31518,32974,33492,36294,37040,39089,64004,25799,28580,25745,25860,20814,21520,22303,35342,24927,26742,64005,30171,31570,32113,36890,22534,27084,33151,35114,36864,38969,20600,22871,22956,25237,36879,39722,24925,29305,38358,22369,23110,24052,25226,25773,25850,26487,27874,27966,29228,29750,30772,32631,33453,36315,38935,21028,22338,26495,29256,29923,36009,36774,37393,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,38442,20843,21485,25420,20329,21764,24726,25943,27803,28031,29260,29437,31255,35207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255,31687,32232,32745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536,23318,24163,24290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263,21638,21754,22275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770,32990,33071,33502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292,26333,28689,29190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080,34920,35961,39111,39108,39491,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,21697,31263,26963,35575,35914,39080,39342,24444,25259,30130,30382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091,31558,33534,39325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781,33655,34662,36032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680,24717,26097,27735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106,36676,20989,21547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569,21512,21704,30418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658,25239,26477,26689,27782,28207,32568,32923,33322,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,64008,64009,38917,20133,20565,21683,22419,22874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559,36994,39405,39608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190,29670,37141,38911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563,36562,27463,38570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203,27883,28843,29572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010,36066,37449,39023,23377,31348,34880,38913,23244,20448,21332,22846,23805,25406,28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,24418,27842,28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,37026,37795,39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,20114,21628,22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,28111,28246,28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,31946,32286,32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,39013,24785,25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,21700,24344,27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,27194,28779,30069,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,25899,30906,30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,26707,28185,29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,20976,24140,24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,28514,29004,29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,24315,24458,24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,33214,33588,34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,25928,25989,26313,26783,28045,28102,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,29243,32948,37237,39501,20399,20505,21402,21518,21564,21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,22734,28932,29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,21913,27585,24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,30054,34407,24676,35662,40440,20807,20982,21256,27958,33016,40657,26133,27427,28824,30165,21507,23673,32007,35350,27424,27453,27462,21560,24688,27965,32725,33288,20694,20958,21916,22123,22221,23020,23305,24076,24985,24984,25137,26206,26342,29081,29113,29114,29351,31143,31232,32690,35440,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],\n  \"gb18030\":[19970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009,20014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042,20049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075,20076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,20112,20118,20119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150,20151,20152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187,20188,20192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217,20218,20220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236,20242,20243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269,20270,20273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292,20293,20295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326,20328,20330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349,20352,20353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373,20374,20376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400,20401,20402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414,20416,20417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436,20437,20438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466,20468,20469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491,20494,20496,20497,20499,20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,20519,20523,20527,20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20539,20541,20543,20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,20560,20561,20562,20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,20576,20577,20578,20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,20591,20592,20593,20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,20610,20611,20612,20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,20639,20640,20641,20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,20659,20660,20661,20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,20688,20689,20690,20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,20703,20704,20705,20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,20721,20722,20724,20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20744,20745,20746,20748,20749,20750,20751,20752,20753,20755,20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,20768,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,20794,20795,20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,20819,20823,20824,20825,20827,20829,20830,20831,20832,20833,20835,20836,20838,20839,20841,20842,20847,20850,20858,20862,20863,20867,20868,20870,20871,20874,20875,20878,20879,20880,20881,20883,20884,20888,20890,20893,20894,20895,20897,20899,20902,20903,20904,20905,20906,20909,20910,20916,20920,20921,20922,20926,20927,20929,20930,20931,20933,20936,20938,20941,20942,20944,20946,20947,20948,20949,20950,20951,20952,20953,20954,20956,20958,20959,20962,20963,20965,20966,20967,20968,20969,20970,20972,20974,20977,20978,20980,20983,20990,20996,20997,21001,21003,21004,21007,21008,21011,21012,21013,21020,21022,21023,21025,21026,21027,21029,21030,21031,21034,21036,21039,21041,21042,21044,21045,21052,21054,21060,21061,21062,21063,21064,21065,21067,21070,21071,21074,21075,21077,21079,21080,21081,21082,21083,21085,21087,21088,21090,21091,21092,21094,21096,21099,21100,21101,21102,21104,21105,21107,21108,21109,21110,21111,21112,21113,21114,21115,21116,21118,21120,21123,21124,21125,21126,21127,21129,21130,21131,21132,21133,21134,21135,21137,21138,21140,21141,21142,21143,21144,21145,21146,21148,21156,21157,21158,21159,21166,21167,21168,21172,21173,21174,21175,21176,21177,21178,21179,21180,21181,21184,21185,21186,21188,21189,21190,21192,21194,21196,21197,21198,21199,21201,21203,21204,21205,21207,21209,21210,21211,21212,21213,21214,21216,21217,21218,21219,21221,21222,21223,21224,21225,21226,21227,21228,21229,21230,21231,21233,21234,21235,21236,21237,21238,21239,21240,21243,21244,21245,21249,21250,21251,21252,21255,21257,21258,21259,21260,21262,21265,21266,21267,21268,21272,21275,21276,21278,21279,21282,21284,21285,21287,21288,21289,21291,21292,21293,21295,21296,21297,21298,21299,21300,21301,21302,21303,21304,21308,21309,21312,21314,21316,21318,21323,21324,21325,21328,21332,21336,21337,21339,21341,21349,21352,21354,21356,21357,21362,21366,21369,21371,21372,21373,21374,21376,21377,21379,21383,21384,21386,21390,21391,21392,21393,21394,21395,21396,21398,21399,21401,21403,21404,21406,21408,21409,21412,21415,21418,21419,21420,21421,21423,21424,21425,21426,21427,21428,21429,21431,21432,21433,21434,21436,21437,21438,21440,21443,21444,21445,21446,21447,21454,21455,21456,21458,21459,21461,21466,21468,21469,21470,21473,21474,21479,21492,21498,21502,21503,21504,21506,21509,21511,21515,21524,21528,21529,21530,21532,21538,21540,21541,21546,21552,21555,21558,21559,21562,21565,21567,21569,21570,21572,21573,21575,21577,21580,21581,21582,21583,21585,21594,21597,21598,21599,21600,21601,21603,21605,21607,21609,21610,21611,21612,21613,21614,21615,21616,21620,21625,21626,21630,21631,21633,21635,21637,21639,21640,21641,21642,21645,21649,21651,21655,21656,21660,21662,21663,21664,21665,21666,21669,21678,21680,21682,21685,21686,21687,21689,21690,21692,21694,21699,21701,21706,21707,21718,21720,21723,21728,21729,21730,21731,21732,21739,21740,21743,21744,21745,21748,21749,21750,21751,21752,21753,21755,21758,21760,21762,21763,21764,21765,21768,21770,21771,21772,21773,21774,21778,21779,21781,21782,21783,21784,21785,21786,21788,21789,21790,21791,21793,21797,21798,21800,21801,21803,21805,21810,21812,21813,21814,21816,21817,21818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837,21838,21839,21841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854,21855,21856,21858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876,21881,21882,21885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909,21910,21911,21914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928,21929,21930,21931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946,21948,21951,21952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967,21968,21973,21975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997,21998,22000,22001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019,22020,22021,22022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037,22038,22039,22041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057,22058,22059,22062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078,22080,22081,22082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095,22096,22097,22098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113,22115,22117,22118,22119,22125,22126,22127,22128,22130,22131,22132,22133,22135,22136,22137,22138,22141,22142,22143,22144,22145,22146,22147,22148,22151,22152,22153,22154,22155,22156,22157,22160,22161,22162,22164,22165,22166,22167,22168,22169,22170,22171,22172,22173,22174,22175,22176,22177,22178,22180,22181,22182,22183,22184,22185,22186,22187,22188,22189,22190,22192,22193,22194,22195,22196,22197,22198,22200,22201,22202,22203,22205,22206,22207,22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,22224,22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,22248,22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,22272,22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,22291,22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,22306,22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,22332,22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,22356,22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,22386,22388,22389,22392,22393,22394,22397,22398,22399,22400,22401,22407,22408,22409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425,22426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451,22453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468,22469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487,22491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507,22508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527,22529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547,22548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566,22567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,22597,22598,22599,22600,22601,22602,22603,22606,22607,22608,22610,22611,22613,22614,22615,22617,22618,22619,22620,22621,22623,22624,22625,22626,22627,22628,22630,22631,22632,22633,22634,22637,22638,22639,22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,22655,22658,22660,22662,22663,22664,22666,22667,22668,22669,22670,22671,22672,22673,22676,22677,22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,22692,22693,22694,22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,22722,22723,22724,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,22736,22738,22739,22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,22751,22752,22753,22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,22769,22770,22772,22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,22785,22787,22789,22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,22803,22807,22808,22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,22832,22834,22835,22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,22858,22860,22861,22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,22883,22884,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,22897,22898,22901,22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,22924,22926,22927,22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,22944,22945,22946,22950,22951,22956,22957,22960,22961,22963,22964,22965,22966,22967,22968,22970,22972,22973,22975,22976,22977,22978,22979,22980,22981,22983,22984,22985,22988,22989,22990,22991,22997,22998,23001,23003,23006,23007,23008,23009,23010,23012,23014,23015,23017,23018,23019,23021,23022,23023,23024,23025,23026,23027,23028,23029,23030,23031,23032,23034,23036,23037,23038,23040,23042,23050,23051,23053,23054,23055,23056,23058,23060,23061,23062,23063,23065,23066,23067,23069,23070,23073,23074,23076,23078,23079,23080,23082,23083,23084,23085,23086,23087,23088,23091,23093,23095,23096,23097,23098,23099,23101,23102,23103,23105,23106,23107,23108,23109,23111,23112,23115,23116,23117,23118,23119,23120,23121,23122,23123,23124,23126,23127,23128,23129,23131,23132,23133,23134,23135,23136,23137,23139,23140,23141,23142,23144,23145,23147,23148,23149,23150,23151,23152,23153,23154,23155,23160,23161,23163,23164,23165,23166,23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,23180,23181,23182,23183,23184,23185,23187,23188,23189,23190,23191,23192,23193,23196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,23209,23211,23212,23213,23214,23215,23216,23217,23220,23222,23223,23225,23226,23227,23228,23229,23231,23232,23235,23236,23237,23238,23239,23240,23242,23243,23245,23246,23247,23248,23249,23251,23253,23255,23257,23258,23259,23261,23262,23263,23266,23268,23269,23271,23272,23274,23276,23277,23278,23279,23280,23282,23283,23284,23285,23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,23300,23301,23302,23303,23304,23306,23307,23308,23309,23310,23311,23312,23313,23314,23315,23316,23317,23320,23321,23322,23323,23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335,23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23347,23349,23350,23352,23353,23354,23355,23356,23357,23358,23359,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,23375,23378,23382,23390,23392,23393,23399,23400,23403,23405,23406,23407,23410,23412,23414,23415,23416,23417,23419,23420,23422,23423,23426,23430,23434,23437,23438,23440,23441,23442,23444,23446,23455,23463,23464,23465,23468,23469,23470,23471,23473,23474,23479,23482,23483,23484,23488,23489,23491,23496,23497,23498,23499,23501,23502,23503,23505,23508,23509,23510,23511,23512,23513,23514,23515,23516,23520,23522,23523,23526,23527,23529,23530,23531,23532,23533,23535,23537,23538,23539,23540,23541,23542,23543,23549,23550,23552,23554,23555,23557,23559,23560,23563,23564,23565,23566,23568,23570,23571,23575,23577,23579,23582,23583,23584,23585,23587,23590,23592,23593,23594,23595,23597,23598,23599,23600,23602,23603,23605,23606,23607,23619,23620,23622,23623,23628,23629,23634,23635,23636,23638,23639,23640,23642,23643,23644,23645,23647,23650,23652,23655,23656,23657,23658,23659,23660,23661,23664,23666,23667,23668,23669,23670,23671,23672,23675,23676,23677,23678,23680,23683,23684,23685,23686,23687,23689,23690,23691,23694,23695,23698,23699,23701,23709,23710,23711,23712,23713,23716,23717,23718,23719,23720,23722,23726,23727,23728,23730,23732,23734,23737,23738,23739,23740,23742,23744,23746,23747,23749,23750,23751,23752,23753,23754,23756,23757,23758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771,23772,23773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806,23807,23808,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823,23824,23825,23826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840,23841,23842,23843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859,23861,23862,23863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875,23876,23877,23878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892,23893,23894,23895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940,23941,23942,23943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968,23969,23970,23971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,23984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995,23996,23997,23998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009,24010,24011,24012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,24024,24025,24026,24028,24031,24032,24035,24036,24042,24044,24045,24048,24053,24054,24056,24057,24058,24059,24060,24063,24064,24068,24071,24073,24074,24075,24077,24078,24082,24083,24087,24094,24095,24096,24097,24098,24099,24100,24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,24118,24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,24139,24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,24156,24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,24197,24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,24228,24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,24251,24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,24267,24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,24300,24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,24317,24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,24346,24348,24349,24350,24353,24354,24355,24356,24360,24363,24364,24366,24368,24370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386,24387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,24401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424,24427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451,24454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479,24480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497,24498,24499,24500,24502,24504,24505,24506,24507,24510,24511,24512,24513,24514,24519,24520,24522,24523,24526,24531,24532,24533,24538,24539,24540,24542,24543,24546,24547,24549,24550,24552,24553,24556,24559,24560,24562,24563,24564,24566,24567,24569,24570,24572,24583,24584,24585,24587,24588,24592,24593,24595,24599,24600,24602,24606,24607,24610,24611,24612,24620,24621,24622,24624,24625,24626,24627,24628,24630,24631,24632,24633,24634,24637,24638,24640,24644,24645,24646,24647,24648,24649,24650,24652,24654,24655,24657,24659,24660,24662,24663,24664,24667,24668,24670,24671,24672,24673,24677,24678,24686,24689,24690,24692,24693,24695,24702,24704,24705,24706,24709,24710,24711,24712,24714,24715,24718,24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,24737,24738,24740,24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,24761,24762,24765,24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,24780,24781,24782,24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,24801,24802,24803,24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,24829,24830,24831,24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,24850,24851,24852,24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,24869,24872,24873,24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,24899,24900,24901,24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,24918,24919,24920,24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,24933,24934,24937,24938,24939,24940,24941,24942,24943,24945,24946,24947,24948,24950,24952,24953,24954,24955,24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24972,24973,24975,24976,24977,24978,24979,24981,24982,24983,24984,24985,24986,24987,24988,24990,24991,24992,24993,24994,24995,24996,24997,24998,25002,25003,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25016,25017,25018,25019,25020,25021,25023,25024,25025,25027,25028,25029,25030,25031,25033,25036,25037,25038,25039,25040,25043,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25063,25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,25076,25078,25079,25080,25081,25082,25083,25084,25085,25086,25088,25089,25090,25091,25092,25093,25095,25097,25107,25108,25113,25116,25117,25118,25120,25123,25126,25127,25128,25129,25131,25133,25135,25136,25137,25138,25141,25142,25144,25145,25146,25147,25148,25154,25156,25157,25158,25162,25167,25168,25173,25174,25175,25177,25178,25180,25181,25182,25183,25184,25185,25186,25188,25189,25192,25201,25202,25204,25205,25207,25208,25210,25211,25213,25217,25218,25219,25221,25222,25223,25224,25227,25228,25229,25230,25231,25232,25236,25241,25244,25245,25246,25251,25254,25255,25257,25258,25261,25262,25263,25264,25266,25267,25268,25270,25271,25272,25274,25278,25280,25281,25283,25291,25295,25297,25301,25309,25310,25312,25313,25316,25322,25323,25328,25330,25333,25336,25337,25338,25339,25344,25347,25348,25349,25350,25354,25355,25356,25357,25359,25360,25362,25363,25364,25365,25367,25368,25369,25372,25382,25383,25385,25388,25389,25390,25392,25393,25395,25396,25397,25398,25399,25400,25403,25404,25406,25407,25408,25409,25412,25415,25416,25418,25425,25426,25427,25428,25430,25431,25432,25433,25434,25435,25436,25437,25440,25444,25445,25446,25448,25450,25451,25452,25455,25456,25458,25459,25460,25461,25464,25465,25468,25469,25470,25471,25473,25475,25476,25477,25478,25483,25485,25489,25491,25492,25493,25495,25497,25498,25499,25500,25501,25502,25503,25505,25508,25510,25515,25519,25521,25522,25525,25526,25529,25531,25533,25535,25536,25537,25538,25539,25541,25543,25544,25546,25547,25548,25553,25555,25556,25557,25559,25560,25561,25562,25563,25564,25565,25567,25570,25572,25573,25574,25575,25576,25579,25580,25582,25583,25584,25585,25587,25589,25591,25593,25594,25595,25596,25598,25603,25604,25606,25607,25608,25609,25610,25613,25614,25617,25618,25621,25622,25623,25624,25625,25626,25629,25631,25634,25635,25636,25637,25639,25640,25641,25643,25646,25647,25648,25649,25650,25651,25653,25654,25655,25656,25657,25659,25660,25662,25664,25666,25667,25673,25675,25676,25677,25678,25679,25680,25681,25683,25685,25686,25687,25689,25690,25691,25692,25693,25695,25696,25697,25698,25699,25700,25701,25702,25704,25706,25707,25708,25710,25711,25712,25713,25714,25715,25716,25717,25718,25719,25723,25724,25725,25726,25727,25728,25729,25731,25734,25736,25737,25738,25739,25740,25741,25742,25743,25744,25747,25748,25751,25752,25754,25755,25756,25757,25759,25760,25761,25762,25763,25765,25766,25767,25768,25770,25771,25775,25777,25778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796,25798,25799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814,25817,25818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860,25861,25862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875,25876,25877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905,25906,25907,25911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927,25930,25931,25933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951,25952,25953,25956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971,25973,25974,25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,25989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005,26006,26008,26010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030,26033,26034,26035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048,26050,26055,26056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073,26074,26075,26076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099,26100,26101,26104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119,26120,26121,26123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140,26142,26145,26146,26147,26148,26150,26153,26154,26155,26156,26158,26160,26162,26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,26181,26182,26183,26184,26185,26186,26189,26190,26192,26193,26200,26201,26203,26204,26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,26225,26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,26245,26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,26261,26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,26277,26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,26294,26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,26309,26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,26339,26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,26358,26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,26382,26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,26402,26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,26425,26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,26452,26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,26475,26476,26478,26481,26484,26486,26488,26489,26490,26491,26493,26496,26498,26499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516,26518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546,26548,26553,26554,26555,26556,26557,26558,26559,26560,26562,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26581,26582,26583,26587,26591,26593,26595,26596,26598,26599,26600,26602,26603,26605,26606,26610,26613,26614,26615,26616,26617,26618,26619,26620,26622,26625,26626,26627,26628,26630,26637,26640,26642,26644,26645,26648,26649,26650,26651,26652,26654,26655,26656,26658,26659,26660,26661,26662,26663,26664,26667,26668,26669,26670,26671,26672,26673,26676,26677,26678,26682,26683,26687,26695,26699,26701,26703,26706,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26730,26732,26733,26734,26735,26736,26737,26738,26739,26741,26744,26745,26746,26747,26748,26749,26750,26751,26752,26754,26756,26759,26760,26761,26762,26763,26764,26765,26766,26768,26769,26770,26772,26773,26774,26776,26777,26778,26779,26780,26781,26782,26783,26784,26785,26787,26788,26789,26793,26794,26795,26796,26798,26801,26802,26804,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26817,26819,26820,26821,26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,26836,26838,26839,26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,26871,26872,26875,26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,26889,26890,26892,26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,26923,26924,26926,26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,26940,26942,26944,26945,26947,26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959,26960,26961,26962,26963,26965,26966,26968,26969,26971,26972,26975,26977,26978,26980,26981,26983,26984,26985,26986,26988,26989,26991,26992,26994,26995,26996,26997,26998,27002,27003,27005,27006,27007,27009,27011,27013,27018,27019,27020,27022,27023,27024,27025,27026,27027,27030,27031,27033,27034,27037,27038,27039,27040,27041,27042,27043,27044,27045,27046,27049,27050,27052,27054,27055,27056,27058,27059,27061,27062,27064,27065,27066,27068,27069,27070,27071,27072,27074,27075,27076,27077,27078,27079,27080,27081,27083,27085,27087,27089,27090,27091,27093,27094,27095,27096,27097,27098,27100,27101,27102,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,27116,27118,27119,27120,27121,27123,27124,27125,27126,27127,27128,27129,27130,27131,27132,27134,27136,27137,27138,27139,27140,27141,27142,27143,27144,27145,27147,27148,27149,27150,27151,27152,27153,27154,27155,27156,27157,27158,27161,27162,27163,27164,27165,27166,27168,27170,27171,27172,27173,27174,27175,27177,27179,27180,27181,27182,27184,27186,27187,27188,27190,27191,27192,27193,27194,27195,27196,27199,27200,27201,27202,27203,27205,27206,27208,27209,27210,27211,27212,27213,27214,27215,27217,27218,27219,27220,27221,27222,27223,27226,27228,27229,27230,27231,27232,27234,27235,27236,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,27248,27250,27251,27252,27253,27254,27255,27256,27258,27259,27261,27262,27263,27265,27266,27267,27269,27270,27271,27272,27273,27274,27275,27276,27277,27279,27282,27283,27284,27285,27286,27288,27289,27290,27291,27292,27293,27294,27295,27297,27298,27299,27300,27301,27302,27303,27304,27306,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319,27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331,27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343,27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355,27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,27416,27417,27418,27419,27420,27421,27422,27423,27429,27430,27432,27433,27434,27435,27436,27437,27438,27439,27440,27441,27443,27444,27445,27446,27448,27451,27452,27453,27455,27456,27457,27458,27460,27461,27464,27466,27467,27469,27470,27471,27472,27473,27474,27475,27476,27477,27478,27479,27480,27482,27483,27484,27485,27486,27487,27488,27489,27496,27497,27499,27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511,27512,27514,27517,27518,27519,27520,27525,27528,27532,27534,27535,27536,27537,27540,27541,27543,27544,27545,27548,27549,27550,27551,27552,27554,27555,27556,27557,27558,27559,27560,27561,27563,27564,27565,27566,27567,27568,27569,27570,27574,27576,27577,27578,27579,27580,27581,27582,27584,27587,27588,27590,27591,27592,27593,27594,27596,27598,27600,27601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621,27622,27623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639,27640,27642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657,27658,27659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691,27692,27693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715,27716,27717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736,27737,27738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761,27763,27765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787,27789,27790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808,27810,27816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842,27843,27846,27847,27848,27851,27853,27854,27855,27857,27858,27864,27865,27866,27868,27869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897,27903,27904,27906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921,27923,27924,27925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940,27942,27944,27945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967,27968,27970,27972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999,28001,28002,28004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019,28021,28022,28025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038,28039,28042,28043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060,28066,28069,28076,28077,28080,28081,28083,28084,28086,28087,28089,28090,28091,28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,28111,28112,28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,28133,28135,28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,28154,28157,28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,28171,28175,28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,28199,28200,28202,28204,28206,28208,28209,28211,28213,28214,28215,28217,28219,28220,28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,28235,28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,28271,28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,28284,28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,28305,28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,28321,28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,28344,28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,28364,28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,28394,28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,28408,28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,28424,28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,28460,28462,28464,28466,28468,28469,28471,28472,28473,28474,28475,28476,28477,28479,28480,28481,28482,28483,28484,28485,28488,28489,28490,28492,28494,28495,28496,28497,28498,28499,28500,28501,28502,28503,28505,28506,28507,28509,28511,28512,28513,28515,28516,28517,28519,28520,28521,28522,28523,28524,28527,28528,28529,28531,28533,28534,28535,28537,28539,28541,28542,28543,28544,28545,28546,28547,28549,28550,28551,28554,28555,28559,28560,28561,28562,28563,28564,28565,28566,28567,28568,28569,28570,28571,28573,28574,28575,28576,28578,28579,28580,28581,28582,28584,28585,28586,28587,28588,28589,28590,28591,28592,28593,28594,28596,28597,28599,28600,28602,28603,28604,28605,28606,28607,28609,28611,28612,28613,28614,28615,28616,28618,28619,28620,28621,28622,28623,28624,28627,28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28639,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,28652,28653,28656,28657,28658,28659,28660,28661,28662,28663,28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,28688,28690,28691,28692,28693,28694,28695,28696,28697,28700,28701,28702,28703,28704,28705,28706,28708,28709,28710,28711,28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,28726,28727,28728,28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,28755,28756,28757,28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,28769,28770,28771,28772,28773,28774,28775,28776,28777,28778,28782,28785,28786,28787,28788,28791,28793,28794,28795,28797,28801,28802,28803,28804,28806,28807,28808,28811,28812,28813,28815,28816,28817,28819,28823,28824,28826,28827,28830,28831,28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28848,28850,28852,28853,28854,28858,28862,28863,28868,28869,28870,28871,28873,28875,28876,28877,28878,28879,28880,28881,28882,28883,28884,28885,28886,28887,28890,28892,28893,28894,28896,28897,28898,28899,28901,28906,28910,28912,28913,28914,28915,28916,28917,28918,28920,28922,28923,28924,28926,28927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28939,28940,28941,28942,28943,28945,28946,28948,28951,28955,28956,28957,28958,28959,28960,28961,28962,28963,28964,28965,28967,28968,28969,28970,28971,28972,28973,28974,28978,28979,28980,28981,28983,28984,28985,28986,28987,28988,28989,28990,28991,28992,28993,28994,28995,28996,28998,28999,29000,29001,29003,29005,29007,29008,29009,29010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29021,29023,29024,29025,29026,29027,29029,29033,29034,29035,29036,29037,29039,29040,29041,29044,29045,29046,29047,29049,29051,29052,29054,29055,29056,29057,29058,29059,29061,29062,29063,29064,29065,29067,29068,29069,29070,29072,29073,29074,29075,29077,29078,29079,29082,29083,29084,29085,29086,29089,29090,29091,29092,29093,29094,29095,29097,29098,29099,29101,29102,29103,29104,29105,29106,29108,29110,29111,29112,29114,29115,29116,29117,29118,29119,29120,29121,29122,29124,29125,29126,29127,29128,29129,29130,29131,29132,29133,29135,29136,29137,29138,29139,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,29153,29154,29155,29156,29158,29160,29161,29162,29163,29164,29165,29167,29168,29169,29170,29171,29172,29173,29174,29175,29176,29178,29179,29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29191,29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,29210,29211,29212,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,29225,29227,29229,29230,29231,29234,29235,29236,29242,29244,29246,29248,29249,29250,29251,29252,29253,29254,29257,29258,29259,29262,29263,29264,29265,29267,29268,29269,29271,29272,29274,29276,29278,29280,29283,29284,29285,29288,29290,29291,29292,29293,29296,29297,29299,29300,29302,29303,29304,29307,29308,29309,29314,29315,29317,29318,29319,29320,29321,29324,29326,29328,29329,29331,29332,29333,29334,29335,29336,29337,29338,29339,29340,29341,29342,29344,29345,29346,29347,29348,29349,29350,29351,29352,29353,29354,29355,29358,29361,29362,29363,29365,29370,29371,29372,29373,29374,29375,29376,29381,29382,29383,29385,29386,29387,29388,29391,29393,29395,29396,29397,29398,29400,29402,29403,58566,58567,58568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578,58579,58580,58581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591,58592,58593,58594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604,58605,58606,58607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617,58618,58619,58620,58621,58622,58623,58624,58625,58626,58627,58628,58629,58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,58642,58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,58655,58656,58657,58658,58659,58660,58661,12288,12289,12290,183,713,711,168,12291,12293,8212,65374,8214,8230,8216,8217,8220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12310,12311,12304,12305,177,215,247,8758,8743,8744,8721,8719,8746,8745,8712,8759,8730,8869,8741,8736,8978,8857,8747,8750,8801,8780,8776,8765,8733,8800,8814,8815,8804,8805,8734,8757,8756,9794,9792,176,8242,8243,8451,65284,164,65504,65505,8240,167,8470,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,8251,8594,8592,8593,8595,12307,58662,58663,58664,58665,58666,58667,58668,58669,58670,58671,58672,58673,58674,58675,58676,58677,58678,58679,58680,58681,58682,58683,58684,58685,58686,58687,58688,58689,58690,58691,58692,58693,58694,58695,58696,58697,58698,58699,58700,58701,58702,58703,58704,58705,58706,58707,58708,58709,58710,58711,58712,58713,58714,58715,58716,58717,58718,58719,58720,58721,58722,58723,58724,58725,58726,58727,58728,58729,58730,58731,58732,58733,58734,58735,58736,58737,58738,58739,58740,58741,58742,58743,58744,58745,58746,58747,58748,58749,58750,58751,58752,58753,58754,58755,58756,58757,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,59238,59239,59240,59241,59242,59243,9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,9350,9351,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,8364,59245,12832,12833,12834,12835,12836,12837,12838,12839,12840,12841,59246,59247,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,59248,59249,58758,58759,58760,58761,58762,58763,58764,58765,58766,58767,58768,58769,58770,58771,58772,58773,58774,58775,58776,58777,58778,58779,58780,58781,58782,58783,58784,58785,58786,58787,58788,58789,58790,58791,58792,58793,58794,58795,58796,58797,58798,58799,58800,58801,58802,58803,58804,58805,58806,58807,58808,58809,58810,58811,58812,58813,58814,58815,58816,58817,58818,58819,58820,58821,58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,58832,58833,58834,58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,58845,58846,58847,58848,58849,58850,58851,58852,12288,65281,65282,65283,65509,65285,65286,65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65339,65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,65507,58854,58855,58856,58857,58858,58859,58860,58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,58872,58873,58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,58885,58886,58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,58898,58899,58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,58911,58912,58913,58914,58915,58916,58917,58918,58919,58920,58921,58922,58923,58924,58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,58937,58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,59250,59251,59252,59253,59254,59255,59256,59257,59258,59259,59260,58950,58951,58952,58953,58954,58955,58956,58957,58958,58959,58960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971,58972,58973,58974,58975,58976,58977,58978,58979,58980,58981,58982,58983,58984,58985,58986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996,58997,58998,58999,59000,59001,59002,59003,59004,59005,59006,59007,59008,59009,59010,59011,59012,59013,59014,59015,59016,59017,59018,59019,59020,59021,59022,59023,59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,59034,59035,59036,59037,59038,59039,59040,59041,59042,59043,59044,59045,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,59261,59262,59263,59264,59265,59266,59267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055,59056,59057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068,59069,59070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081,59082,59083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094,59095,59096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107,59108,59109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119,59120,59121,59122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132,59133,59134,59135,59136,59137,59138,59139,59140,59141,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,59269,59270,59271,59272,59273,59274,59275,59276,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,59277,59278,59279,59280,59281,59282,59283,65077,65078,65081,65082,65087,65088,65085,65086,65089,65090,65091,65092,59284,59285,65083,65084,65079,65080,65073,59286,65075,65076,59287,59288,59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,59146,59147,59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,59159,59160,59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,59172,59173,59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,59185,59186,59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,59198,59199,59200,59201,59202,59203,59204,59205,59206,59207,59208,59209,59210,59211,59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,59224,59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,59237,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,59296,59297,59298,59299,59300,59301,59302,59303,59304,59305,59306,59307,59308,59309,59310,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,59311,59312,59313,59314,59315,59316,59317,59318,59319,59320,59321,59322,59323,714,715,729,8211,8213,8229,8245,8453,8457,8598,8599,8600,8601,8725,8735,8739,8786,8806,8807,8895,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9601,9602,9603,9604,9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9619,9620,9621,9660,9661,9698,9699,9700,9701,9737,8853,12306,12317,12318,59324,59325,59326,59327,59328,59329,59330,59331,59332,59333,59334,257,225,462,224,275,233,283,232,299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,476,252,234,593,7743,324,328,505,609,59337,59338,59339,59340,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,12584,12585,59341,59342,59343,59344,59345,59346,59347,59348,59349,59350,59351,59352,59353,59354,59355,59356,59357,59358,59359,59360,59361,12321,12322,12323,12324,12325,12326,12327,12328,12329,12963,13198,13199,13212,13213,13214,13217,13252,13262,13265,13266,13269,65072,65506,65508,59362,8481,12849,59363,8208,59364,59365,59366,12540,12443,12444,12541,12542,12294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104,65105,65106,65108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119,65120,65121,65122,65123,65124,65125,65126,65128,65129,65130,65131,12350,12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283,12295,59380,59381,59382,59383,59384,59385,59386,59387,59388,59389,59390,59391,59392,9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,59393,59394,59395,59396,59397,59398,59399,59400,59401,59402,59403,59404,59405,59406,59407,29404,29405,29407,29410,29411,29412,29413,29414,29415,29418,29419,29429,29430,29433,29437,29438,29439,29440,29442,29444,29445,29446,29447,29448,29449,29451,29452,29453,29455,29456,29457,29458,29460,29464,29465,29466,29471,29472,29475,29476,29478,29479,29480,29485,29487,29488,29490,29491,29493,29494,29498,29499,29500,29501,29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,29516,29518,29519,29521,29523,29524,29525,29526,29528,29529,29530,29531,29532,29533,29534,29535,29537,29538,29539,29540,29541,29542,29543,29544,29545,29546,29547,29550,29552,29553,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353,57354,57355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366,57367,57368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379,57380,57381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392,57393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405,57406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418,57419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431,57432,57433,57434,57435,57436,57437,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,29564,29565,29567,29568,29569,29570,29571,29573,29574,29576,29578,29580,29581,29583,29584,29586,29587,29588,29589,29591,29592,29593,29594,29596,29597,29598,29600,29601,29603,29604,29605,29606,29607,29608,29610,29612,29613,29617,29620,29621,29622,29624,29625,29628,29629,29630,29631,29633,29635,29636,29637,29638,29639,29643,29644,29646,29650,29651,29652,29653,29654,29655,29656,29658,29659,29660,29661,29663,29665,29666,29667,29668,29670,29672,29674,29675,29676,29678,29679,29680,29681,29683,29684,29685,29686,29687,57438,57439,57440,57441,57442,57443,57444,57445,57446,57447,57448,57449,57450,57451,57452,57453,57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,57466,57467,57468,57469,57470,57471,57472,57473,57474,57475,57476,57477,57478,57479,57480,57481,57482,57483,57484,57485,57486,57487,57488,57489,57490,57491,57492,57493,57494,57495,57496,57497,57498,57499,57500,57501,57502,57503,57504,57505,57506,57507,57508,57509,57510,57511,57512,57513,57514,57515,57516,57517,57518,57519,57520,57521,57522,57523,57524,57525,57526,57527,57528,57529,57530,57531,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,29698,29700,29703,29704,29707,29708,29709,29710,29713,29714,29715,29716,29717,29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,29732,29735,29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,29757,29758,29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,29806,29807,29809,29810,29811,29812,29813,29816,29817,29818,57532,57533,57534,57535,57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,57548,57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,57561,57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,57574,57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,57587,57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,57600,57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,57613,57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,29819,29820,29821,29823,29826,29828,29829,29830,29832,29833,29834,29836,29837,29839,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,29853,29855,29856,29857,29858,29859,29860,29861,29862,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,29876,29877,29878,29879,29880,29881,29883,29884,29885,29886,29887,29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899,29900,29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,29912,29913,29914,29915,29917,29919,29921,29925,29927,29928,29929,29930,29931,29932,29933,29936,29937,29938,57626,57627,57628,57629,57630,57631,57632,57633,57634,57635,57636,57637,57638,57639,57640,57641,57642,57643,57644,57645,57646,57647,57648,57649,57650,57651,57652,57653,57654,57655,57656,57657,57658,57659,57660,57661,57662,57663,57664,57665,57666,57667,57668,57669,57670,57671,57672,57673,57674,57675,57676,57677,57678,57679,57680,57681,57682,57683,57684,57685,57686,57687,57688,57689,57690,57691,57692,57693,57694,57695,57696,57697,57698,57699,57700,57701,57702,57703,57704,57705,57706,57707,57708,57709,57710,57711,57712,57713,57714,57715,57716,57717,57718,57719,29939,29941,29944,29945,29946,29947,29948,29949,29950,29952,29953,29954,29955,29957,29958,29959,29960,29961,29962,29963,29964,29966,29968,29970,29972,29973,29974,29975,29979,29981,29982,29984,29985,29986,29987,29988,29990,29991,29994,29998,30004,30006,30009,30012,30013,30015,30017,30018,30019,30020,30022,30023,30025,30026,30029,30032,30033,30034,30035,30037,30038,30039,30040,30045,30046,30047,30048,30049,30050,30051,30052,30055,30056,30057,30059,30060,30061,30062,30063,30064,30065,30067,30069,30070,30071,30074,30075,30076,30077,30078,30080,30081,30082,30084,30085,30087,57720,57721,57722,57723,57724,57725,57726,57727,57728,57729,57730,57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,57742,57743,57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,57755,57756,57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,57768,57769,57770,57771,57772,57773,57774,57775,57776,57777,57778,57779,57780,57781,57782,57783,57784,57785,57786,57787,57788,57789,57790,57791,57792,57793,57794,57795,57796,57797,57798,57799,57800,57801,57802,57803,57804,57805,57806,57807,57808,57809,57810,57811,57812,57813,30088,30089,30090,30092,30093,30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,30119,30120,30121,30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,30155,30156,30158,30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,30176,30177,30181,30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,30200,30202,30203,30205,30206,30210,30212,30214,30215,30216,30217,30219,30221,30222,30223,30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,30247,30248,30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,30273,30274,30276,57814,57815,57816,57817,57818,57819,57820,57821,57822,57823,57824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834,57835,57836,57837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847,57848,57849,57850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860,57861,57862,57863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873,57874,57875,57876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886,57887,57888,57889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899,57900,57901,57902,57903,57904,57905,57906,57907,30277,30278,30279,30280,30281,30282,30283,30286,30287,30288,30289,30290,30291,30293,30295,30296,30297,30298,30299,30301,30303,30304,30305,30306,30308,30309,30310,30311,30312,30313,30314,30316,30317,30318,30320,30321,30322,30323,30324,30325,30326,30327,30329,30330,30332,30335,30336,30337,30339,30341,30345,30346,30348,30349,30351,30352,30354,30356,30357,30359,30360,30362,30363,30364,30365,30366,30367,30368,30369,30370,30371,30373,30374,30375,30376,30377,30378,30379,30380,30381,30383,30384,30387,30389,30390,30391,30392,30393,30394,30395,30396,30397,30398,30400,30401,30403,21834,38463,22467,25384,21710,21769,21696,30353,30284,34108,30702,33406,30861,29233,38552,38797,27688,23433,20474,25353,26263,23736,33018,26696,32942,26114,30414,20985,25942,29100,32753,34948,20658,22885,25034,28595,33453,25420,25170,21485,21543,31494,20843,30116,24052,25300,36299,38774,25226,32793,22365,38712,32610,29240,30333,26575,30334,25670,20336,36133,25308,31255,26001,29677,25644,25203,33324,39041,26495,29256,25198,25292,20276,29923,21322,21150,32458,37030,24110,26758,27036,33152,32465,26834,30917,34444,38225,20621,35876,33502,32990,21253,35090,21093,30404,30407,30409,30411,30412,30419,30421,30425,30426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439,30440,30441,30442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459,30461,30463,30464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499,30500,30501,30503,30506,30507,30508,30510,30512,30513,30514,30515,30516,30521,30523,30525,30526,30527,30530,30532,30533,30534,30536,30537,30538,30539,30540,30541,30542,30543,30546,30547,30548,30549,30550,30551,30552,30553,30556,34180,38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,26479,30865,24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,28953,34987,22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,40763,27604,37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,30201,38381,25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,36140,25153,20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,40150,24971,21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,19993,31177,39292,28851,30557,30558,30559,30560,30564,30567,30569,30570,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,30586,30587,30588,30593,30594,30595,30598,30599,30600,30601,30602,30603,30607,30608,30611,30612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,30625,30627,30628,30630,30632,30635,30637,30638,30639,30641,30642,30644,30646,30647,30648,30649,30650,30652,30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,30680,30681,30682,30685,30686,30687,30688,30689,30692,30149,24182,29627,33760,25773,25320,38069,27874,21338,21187,25615,38082,31636,20271,24091,33334,33046,33162,28196,27850,39539,25429,21340,21754,34917,22496,19981,24067,27493,31807,37096,24598,25830,29468,35009,26448,25165,36130,30572,36393,37319,24425,33756,34081,39184,21442,34453,27531,24813,24808,28799,33485,33329,20179,27815,34255,25805,31961,27133,26361,33609,21397,31574,20391,20876,27979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519,23700,24046,35815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130,20135,38416,39076,26124,29462,30694,30696,30698,30703,30704,30705,30706,30708,30709,30711,30713,30714,30715,30716,30723,30724,30725,30726,30727,30728,30730,30731,30734,30735,30736,30739,30741,30745,30747,30750,30752,30753,30754,30756,30760,30762,30763,30766,30767,30769,30770,30771,30773,30774,30781,30783,30785,30786,30787,30788,30790,30792,30793,30794,30795,30797,30799,30801,30803,30804,30808,30809,30810,30811,30812,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,30824,30825,30831,30832,30833,30834,30835,30836,30837,30838,30840,30841,30842,30843,30845,30846,30847,30848,30849,30850,30851,22330,23581,24120,38271,20607,32928,21378,25950,30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,21557,28818,36710,25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,24561,27785,38472,36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,24809,28548,35802,25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,24347,39536,32827,40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,23815,23456,25277,37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,33261,21021,20986,27249,21416,36487,38148,38607,28353,38500,26970,30852,30853,30854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877,30878,30880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895,30901,30902,30903,30904,30906,30907,30908,30909,30911,30912,30914,30915,30916,30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,30934,30935,30936,30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,30948,30949,30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,30965,30966,30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,30982,30983,30984,30985,30986,30987,30988,30784,20648,30679,25616,35302,22788,25571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202,38383,21019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431,34850,25139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050,36176,27425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419,36479,31713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384,23544,30923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823,21574,27513,20643,25140,24102,27526,20195,36151,34955,24453,36910,30989,30990,30991,30992,30993,30994,30996,30997,30998,30999,31000,31001,31002,31003,31004,31005,31007,31008,31009,31010,31011,31013,31014,31015,31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027,31029,31030,31031,31032,31033,31037,31039,31042,31043,31044,31045,31047,31050,31051,31052,31053,31054,31055,31056,31057,31058,31060,31061,31064,31065,31073,31075,31076,31078,31081,31082,31083,31084,31086,31088,31089,31090,31091,31092,31093,31094,31097,31099,31100,31101,31102,31103,31106,31107,31110,31111,31112,31113,31115,31116,31117,31118,31120,31121,31122,24608,32829,25285,20025,21333,37112,25528,32966,26086,27694,20294,24814,28129,35806,24377,34507,24403,25377,20826,33633,26723,20992,25443,36424,20498,23707,31095,23548,21040,31291,24764,36947,30423,24503,24471,30340,36460,28783,30331,31561,30634,20979,37011,22564,20302,28404,36842,25932,31515,29380,28068,32735,23265,25269,24213,22320,33922,31532,24093,24351,36882,32532,39072,25474,28359,30872,28857,20856,38747,22443,30005,20291,30008,24215,24806,22880,28096,27583,30857,21500,38613,20939,20993,25481,21514,38035,35843,36300,29241,30879,34678,36845,35853,21472,31123,31124,31125,31126,31127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138,31139,31140,31141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152,31153,31154,31156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175,31176,31178,31180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195,31196,31197,31198,31200,31201,31202,31205,31208,31210,31212,31214,31217,31218,31219,31220,31221,31222,31223,31225,31226,31228,31230,31231,31233,31236,31237,31239,31240,31241,31242,31244,31247,31248,31249,31250,31251,31253,31254,31256,31257,31259,31260,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908,33891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910,36887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208,32922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431,23545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810,22842,22427,36530,26421,36346,33333,21057,24816,22549,34558,23784,40517,20420,39069,35769,23077,24694,21380,25212,36943,37122,39295,24681,32780,20799,32819,23572,39285,27953,20108,31261,31263,31265,31266,31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,31282,31284,31285,31286,31288,31290,31294,31296,31297,31298,31299,31300,31301,31303,31304,31305,31306,31307,31308,31309,31310,31311,31312,31314,31315,31316,31317,31318,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,31345,31346,31347,31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,31371,31372,31374,31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,36144,21457,32602,31567,20240,20047,38400,27861,29648,34281,24070,30058,32763,27146,30718,38034,32321,20961,28902,21453,36820,33539,36137,29359,39277,27867,22346,33459,26041,32938,25151,38450,22952,20223,35775,32442,25918,33778,38750,21857,39134,32933,21290,35837,21536,32954,24223,27832,36153,33452,37210,21545,27675,20998,32439,22367,28954,27774,31881,22859,20221,24575,24868,31914,20016,23553,26539,34562,23792,38155,39118,30127,28925,36898,20911,32541,35773,22857,20964,20315,21542,22827,25975,32932,23413,25206,25282,36752,24133,27679,31526,20239,20440,26381,31395,31396,31399,31401,31402,31403,31406,31407,31408,31409,31410,31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31447,31448,31450,31451,31452,31453,31457,31458,31460,31463,31464,31465,31466,31467,31468,31470,31472,31473,31474,31475,31476,31477,31478,31479,31480,31483,31484,31486,31488,31489,31490,31493,31495,31497,31500,31501,31502,31504,31506,31507,31510,31511,31512,31514,31516,31517,31519,31521,31522,31523,31527,31529,31533,28014,28074,31119,34993,24343,29995,25242,36741,20463,37340,26023,33071,33105,24220,33104,36212,21103,35206,36171,22797,20613,20184,38428,29238,33145,36127,23500,35747,38468,22919,32538,21648,22134,22030,35813,25913,27010,38041,30422,28297,24178,29976,26438,26577,31487,32925,36214,24863,31174,25954,36195,20872,21018,38050,32568,32923,32434,23703,28207,26464,31705,30347,39640,33167,32660,31957,25630,38224,31295,21578,21733,27468,25601,25096,40509,33011,30105,21106,38761,33883,26684,34532,38401,38548,38124,20010,21508,32473,26681,36319,32789,26356,24218,32697,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549,31551,31552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573,31575,31577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593,31594,31595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613,31615,31617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630,31631,31633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648,31651,31652,31653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674,31675,31676,31677,31678,31679,31680,31682,31683,31684,22466,32831,26775,24037,25915,21151,24685,40858,20379,36524,20844,23467,24339,24041,27742,25329,36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,33735,21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,25925,39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,26874,20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,36891,29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,26588,36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,21704,31685,31688,31689,31690,31691,31693,31694,31695,31696,31698,31700,31701,31702,31703,31704,31707,31708,31710,31711,31712,31714,31715,31716,31719,31720,31721,31723,31724,31725,31727,31728,31730,31731,31732,31733,31734,31736,31737,31738,31739,31741,31743,31744,31745,31746,31747,31748,31749,31750,31752,31753,31754,31757,31758,31760,31761,31762,31763,31764,31765,31767,31768,31769,31770,31771,31772,31773,31774,31776,31777,31778,31779,31780,31781,31784,31785,31787,31788,31789,31790,31791,31792,31793,31794,31795,31796,31797,31798,31799,31801,31802,31803,31804,31805,31806,31810,39608,23401,28023,27686,20133,23475,39559,37219,25000,37039,38889,21547,28085,23506,20989,21898,32597,32752,25788,25421,26097,25022,24717,28938,27735,27721,22831,26477,33322,22741,22158,35946,27627,37085,22909,32791,21495,28009,21621,21917,33655,33743,26680,31166,21644,20309,21512,30418,35977,38402,27827,28088,36203,35088,40548,36154,22079,40657,30165,24456,29408,24680,21756,20136,27178,34913,24658,36720,21700,28888,34425,40511,27946,23439,24344,32418,21897,20399,29492,21564,21402,20505,21518,21628,20046,24573,29786,22774,33899,32993,34676,29392,31946,28246,31811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863,31864,31865,31866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31882,31883,31884,31885,31886,31887,31888,31891,31892,31894,31897,31898,31899,31904,31905,31907,31910,31911,31912,31913,31915,31916,31917,31919,31920,31924,31925,31926,31927,31928,31930,31931,24359,34382,21804,25252,20114,27818,25143,33457,21719,21326,29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,27426,29615,26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,24187,33618,24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,24653,35854,28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,24800,26214,36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,39746,27985,28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,20987,22334,22522,26426,30072,31293,31215,31637,31935,31936,31938,31939,31940,31942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963,31965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980,31981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996,31997,31998,31999,32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32011,32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,32035,32036,32037,32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,32051,32052,32053,32054,32908,39269,36857,28608,35749,40481,23020,32489,32521,21513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363,23241,32423,25380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058,24760,27982,23492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025,26551,22841,20339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215,26550,39550,23233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392,22904,32516,33575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943,33616,27099,37492,36341,36145,35265,38190,31661,20214,32055,32056,32057,32058,32059,32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095,32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107,32108,32109,32111,32112,32113,32114,32115,32116,32117,32118,32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,32144,32145,32146,32147,32148,32149,32150,32151,32152,20581,33328,21073,39279,28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,33931,26728,22870,35762,21280,37233,38477,34121,26898,30977,28966,33014,20132,37066,27975,39556,23047,22204,25605,38128,30699,20389,33050,29409,35282,39290,32564,32478,21119,25945,37237,36735,36739,21483,31382,25581,25509,30342,31224,34903,38454,25130,21163,33410,26708,26480,25463,30571,31469,27905,32467,35299,22992,25106,34249,33445,30028,20511,20171,30117,35819,23626,24062,31563,26020,37329,20170,27941,35167,32039,38182,20165,35880,36827,38771,26187,31105,36817,28908,28024,32153,32154,32155,32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172,32173,32175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215,32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,23613,21170,33606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117,35686,26223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928,28847,31384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937,26087,33276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738,23616,21632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191,20465,21477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733,25899,25225,25496,20500,29237,35273,20915,35776,32477,22343,33740,38055,20891,21531,23803,32251,32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311,32312,32313,32314,32316,32317,32318,32319,32320,32322,32323,32324,32325,32326,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347,32348,32349,20426,31459,27994,37089,39567,21888,21654,21345,21679,24320,25577,26999,20975,24936,21002,22570,21208,22350,30733,30475,24247,24951,31968,25179,25239,20130,28821,32771,25335,28900,38752,22391,33499,26607,26869,30933,39063,31185,22771,21683,21487,28212,20811,21051,23458,35838,32943,21827,22438,24691,22353,21549,31354,24656,23380,25511,25248,21475,25187,23495,26543,21741,31391,33510,37239,24211,35044,22840,22446,25358,36328,33007,22359,31607,20393,24555,23485,27454,21281,31568,29378,26694,30719,30518,26103,20917,20111,30420,23743,31397,33909,22862,39745,20608,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32387,32388,32389,32390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,32408,32409,32410,32412,32413,32414,32430,32436,32443,32444,32470,32484,32492,32505,32522,32528,32542,32567,32569,32571,32572,32573,32574,32575,32576,32577,32579,32582,32583,32584,32585,32586,32587,32588,32589,32590,32591,32594,32595,39304,24871,28291,22372,26118,25414,22256,25324,25193,24275,38420,22403,25289,21895,34593,33098,36771,21862,33713,26469,36182,34013,23146,26639,25318,31726,38417,20848,28572,35888,25597,35272,25042,32518,28866,28389,29701,27028,29436,24266,37070,26391,28010,25438,21171,29282,32769,20332,23013,37226,28889,28061,21202,20048,38647,38253,34174,30922,32047,20769,22418,25794,32907,31867,27882,26865,26974,20919,21400,26792,29313,40654,31729,29432,31163,28435,29702,26446,37324,40100,31036,33673,33620,21519,26647,20029,21385,21169,30782,21382,21033,20616,20363,20432,32598,32601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620,32621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639,32640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656,32657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675,32677,32678,32680,32681,32682,32683,32684,32685,32686,32689,32691,32692,32693,32694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712,32713,32715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731,32732,32733,32734,32738,32739,30178,31435,31890,27813,38582,21147,29827,21737,20457,32852,33714,36830,38256,24265,24604,28063,24088,25947,33080,38142,24651,28860,32451,31918,20937,26753,31921,33391,20004,36742,37327,26238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730,38243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020,37051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278,32666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311,30041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,32740,32743,32744,32746,32747,32748,32749,32751,32754,32756,32757,32758,32759,32760,32761,32762,32765,32766,32767,32770,32775,32776,32777,32778,32782,32783,32785,32787,32794,32795,32797,32798,32799,32801,32803,32804,32811,32812,32813,32814,32815,32816,32818,32820,32825,32826,32828,32830,32832,32833,32836,32837,32839,32840,32841,32846,32847,32848,32849,32851,32853,32854,32855,32857,32859,32860,32861,32862,32863,32864,32865,32866,32867,32868,32869,32870,32871,32872,32875,32876,32877,32878,32879,32880,32882,32883,32884,32885,32886,32887,32888,32889,32890,32891,32892,32893,38534,22404,25314,38471,27004,23044,25602,31699,28431,38475,33446,21346,39045,24208,28809,25523,21348,34383,40065,40595,30860,38706,36335,36162,40575,28510,31108,24405,38470,25134,39540,21525,38109,20387,26053,23653,23649,32533,34385,27695,24459,29575,28388,32511,23782,25371,23402,28390,21365,20081,25504,30053,25249,36718,20262,20177,27814,32438,35770,33821,34746,32599,36923,38179,31657,39585,35064,33853,27931,39558,32476,22920,40635,29595,30721,34434,39532,39554,22043,21527,22475,20080,40614,21334,36808,33033,30610,39314,34542,28385,34067,26364,24930,28459,32894,32897,32898,32901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919,32921,32926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953,32955,32965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980,32981,32984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022,33023,33024,33025,33027,33028,33029,33031,33032,33035,33036,33045,33047,33049,33051,33052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063,33064,33065,33066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082,33083,33084,33085,33087,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,30683,38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,38665,29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,38391,20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,31964,36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,32501,20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,24217,22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,38125,21517,21629,35884,25720,33088,33089,33090,33091,33092,33093,33095,33097,33101,33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,33122,33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,33143,33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,33168,33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,33186,33188,33189,33191,33193,33195,33196,33197,33198,33199,33200,33201,33202,33204,33205,33206,33207,33208,33209,33212,33213,33214,33215,33220,33221,33223,33224,33225,33227,33229,33230,33231,33232,33233,33234,33235,25721,34321,27169,33180,30952,25705,39764,25273,26411,33707,22696,40664,27819,28448,23518,38476,35851,29279,26576,25287,29281,20137,22982,27597,22675,26286,24149,21215,24917,26408,30446,30566,29287,31302,25343,21738,21584,38048,37027,23068,32435,27670,20035,22902,32784,22856,21335,30007,38590,22218,25376,33041,24700,38393,28118,21602,39297,20869,23273,33021,22958,38675,20522,27877,23612,25311,20320,21311,33147,36870,28346,34091,25288,24180,30910,25781,25467,24565,23064,37247,40479,23615,25423,32834,23421,21870,38218,38221,28037,24744,26592,29406,20957,23425,33236,33237,33238,33239,33240,33241,33242,33243,33244,33245,33246,33247,33248,33249,33250,33252,33253,33254,33256,33257,33259,33262,33263,33264,33265,33266,33269,33270,33271,33272,33273,33274,33277,33279,33283,33287,33288,33289,33290,33291,33294,33295,33297,33299,33301,33302,33303,33304,33305,33306,33309,33312,33316,33317,33318,33319,33321,33326,33330,33338,33340,33341,33343,33344,33345,33346,33347,33349,33350,33352,33354,33356,33357,33358,33360,33361,33362,33363,33364,33365,33366,33367,33369,33371,33372,33373,33374,33376,33377,33378,33379,33380,33381,33382,33383,33385,25319,27870,29275,25197,38062,32445,33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,25386,25062,31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,36276,29228,24085,24597,29750,25293,25490,29260,24472,28227,27966,25856,28504,30424,30928,30460,30036,21028,21467,20051,24222,26049,32810,32982,25243,21638,21032,28846,34957,36305,27873,21624,32986,22521,35060,36180,38506,37197,20329,27803,21943,30406,30768,25256,28921,28558,24429,34028,26842,30844,31735,33192,26379,40527,25447,30896,22383,30738,38713,25209,25259,21128,29749,27607,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403,33404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429,33430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467,33468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501,33506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526,33528,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554,33555,33558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573,33574,33577,33578,33582,33584,33586,33591,33595,33597,21860,33086,30130,30382,21305,30174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922,31080,25735,30629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179,20973,29942,35780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078,25169,38138,20166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889,26333,28689,26399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854,26827,22855,27495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682,20062,20225,21551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488,33598,33599,33601,33602,33604,33605,33608,33610,33611,33612,33613,33614,33619,33621,33622,33623,33624,33625,33629,33634,33648,33649,33650,33651,33652,33653,33654,33657,33658,33662,33663,33664,33665,33666,33667,33668,33671,33672,33674,33675,33676,33677,33679,33680,33681,33684,33685,33686,33687,33689,33690,33693,33695,33697,33698,33699,33700,33701,33702,33703,33708,33709,33710,33711,33717,33723,33726,33727,33730,33731,33732,33734,33736,33737,33739,33741,33742,33744,33745,33746,33747,33749,33751,33753,33754,33755,33758,33762,33763,33764,33766,33767,33768,33771,33772,33773,24688,27965,29301,25190,38030,38085,21315,36801,31614,20191,35878,20094,40660,38065,38067,21069,28508,36963,27973,35892,22545,23884,27424,27465,26538,21595,33108,32652,22681,34103,24378,25250,27207,38201,25970,24708,26725,30631,20052,20392,24039,38808,25772,32728,23789,20431,31373,20999,33540,19988,24623,31363,38054,20405,20146,31206,29748,21220,33465,25810,31165,23517,27777,38738,36731,27682,20542,21375,28165,25806,26228,27696,24773,39031,35831,24198,29756,31351,31179,19992,37041,29699,27714,22234,37195,27845,36235,21306,34502,26354,36527,23624,39537,28192,33774,33775,33779,33780,33781,33782,33783,33786,33787,33788,33790,33791,33792,33794,33797,33799,33800,33801,33802,33808,33810,33811,33812,33813,33814,33815,33817,33818,33819,33822,33823,33824,33825,33826,33827,33833,33834,33835,33836,33837,33838,33839,33840,33842,33843,33844,33845,33846,33847,33849,33850,33851,33854,33855,33856,33857,33858,33859,33860,33861,33863,33864,33865,33866,33867,33868,33869,33870,33871,33872,33874,33875,33876,33877,33878,33880,33885,33886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902,33903,33904,33906,33908,33911,33913,33915,33916,21462,23094,40843,36259,21435,22280,39079,26435,37275,27849,20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,40522,27063,30830,38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,22199,35753,39286,25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,35748,20995,22922,32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,28342,23481,32466,20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,20083,27741,20837,35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,25746,27922,33832,33134,40131,22622,36187,19977,21441,33917,33918,33919,33920,33921,33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,33941,33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,33958,33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,33974,33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,33996,33998,33999,34002,34004,34005,34007,34008,34009,34010,34011,34012,34014,34017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034,34035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049,34050,20254,25955,26705,21971,20007,25620,39578,25195,23234,29791,33394,28073,26862,20711,33678,30722,26432,21049,27801,32433,20667,21861,29022,31579,26194,29642,33515,26441,23665,21024,29053,34923,38378,38485,25797,36193,33203,21892,27733,25159,32558,22674,20260,21830,36175,26188,19978,23578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045,32461,22882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774,30775,30003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978,32958,24910,28183,22768,29983,29989,29298,21319,32499,34051,34052,34053,34054,34055,34056,34057,34058,34059,34061,34062,34063,34064,34066,34068,34069,34070,34072,34073,34075,34076,34077,34078,34080,34082,34083,34084,34085,34086,34087,34088,34089,34090,34093,34094,34095,34096,34097,34098,34099,34100,34101,34102,34110,34111,34112,34113,34114,34116,34117,34118,34119,34123,34124,34125,34126,34127,34128,34129,34130,34131,34132,34133,34135,34136,34138,34139,34140,34141,34143,34144,34145,34146,34147,34149,34150,34151,34153,34154,34155,34156,34157,34158,34159,34160,34161,34163,34165,34166,34167,34168,34172,34173,34175,34176,34177,30465,30427,21097,32988,22307,24072,22833,29422,26045,28287,35799,23608,34417,21313,30707,25342,26102,20160,39135,34432,23454,35782,21490,30690,20351,23630,39542,22987,24335,31034,22763,19990,26623,20107,25325,35475,36893,21183,26159,21980,22124,36866,20181,20365,37322,39280,27663,24066,24643,23460,35270,35797,25910,25163,39318,23432,23551,25480,21806,21463,30246,20861,34092,26530,26803,27530,25234,36755,21460,33298,28113,30095,20070,36174,23408,29087,34223,26257,26329,32626,34560,40653,40736,23646,26415,36848,26641,26463,25101,31446,22661,24246,25968,28465,34178,34179,34182,34184,34185,34186,34187,34188,34189,34190,34192,34193,34194,34195,34196,34197,34198,34199,34200,34201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217,34219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236,34237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251,34252,34253,34254,34257,34258,34260,34262,34263,34264,34265,34266,34267,34269,34270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283,34284,34285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,24661,21047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700,30561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070,24605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051,26494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487,37221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948,31639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385,25439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427,22905,22612,34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,34311,34312,34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,34325,34327,34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,34339,34340,34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,34354,34355,34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,34369,34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,34387,34389,34390,34391,34392,34393,34395,34396,34397,34399,34400,34401,34403,34404,34405,34406,34407,34408,34409,34410,29549,25374,36427,36367,32974,33492,25260,21488,27888,37214,22826,24577,27760,22349,25674,36138,30251,28393,22363,27264,30192,28525,35885,35848,22374,27631,34962,30899,25506,21497,28845,27748,22616,25642,22530,26848,33179,21776,31958,20504,36538,28108,36255,28907,25487,28059,28372,32486,33796,26691,36867,28120,38518,35752,22871,29305,34276,33150,30140,35466,26799,21076,36386,38161,25552,39064,36420,21884,20307,26367,22159,24789,28053,21059,23625,22825,28155,22635,30000,29980,24684,33300,33094,25361,26465,36834,30522,36339,36148,38081,24086,21381,21548,28867,34413,34415,34416,34418,34419,34420,34421,34422,34423,34424,34435,34436,34437,34438,34439,34440,34441,34446,34447,34448,34449,34450,34452,34454,34455,34456,34457,34458,34459,34462,34463,34464,34465,34466,34469,34470,34475,34477,34478,34482,34483,34487,34488,34489,34491,34492,34493,34494,34495,34497,34498,34499,34501,34504,34508,34509,34514,34515,34517,34518,34519,34522,34524,34525,34528,34529,34530,34531,34533,34534,34535,34536,34538,34539,34540,34543,34549,34550,34551,34554,34555,34556,34557,34559,34561,34564,34565,34566,34571,34572,34574,34575,34576,34577,34580,34582,27712,24311,20572,20141,24237,25402,33351,36890,26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,20599,25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,21520,20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,25302,25176,33073,40501,38464,39534,39548,26925,22949,25299,21822,25366,21703,34521,27964,23043,29926,34972,27498,22806,35916,24367,28286,29609,39037,20024,28919,23436,30871,25405,26202,30358,24779,23451,23113,19975,33109,27754,29579,20129,26505,32593,24448,26106,26395,24536,22916,23041,34585,34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,34607,34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,34626,34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,34645,34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,34664,34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,34679,34680,34681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703,34704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718,34720,34721,34722,34723,34724,24013,24494,21361,38886,36829,26693,22260,21807,24799,20026,28493,32500,33479,33806,22996,20255,20266,23614,32428,26410,34074,21619,30031,32963,21890,39759,20301,28205,35859,23561,24944,21355,30239,28201,34442,25991,38395,32441,21563,31283,32010,38382,21985,32705,29934,25373,34583,28065,31389,25105,26017,21351,25569,27779,24043,21596,38056,20044,27745,35820,23627,26080,33436,26791,21566,21556,27595,27494,20116,25410,21320,33310,20237,20398,22366,25098,38654,26212,29289,21247,21153,24735,35823,26132,29081,26512,35199,30802,30717,26224,22075,21560,38177,29306,34725,34726,34727,34729,34730,34734,34736,34737,34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,34753,34754,34755,34756,34757,34759,34760,34761,34764,34765,34766,34767,34768,34772,34773,34774,34775,34776,34777,34778,34780,34781,34782,34783,34785,34786,34787,34788,34790,34791,34792,34793,34795,34796,34797,34799,34800,34801,34802,34803,34804,34805,34806,34807,34808,34810,34811,34812,34813,34815,34816,34817,34818,34820,34821,34822,34823,34824,34825,34827,34828,34829,34830,34831,34832,34833,34834,34836,34839,34840,34841,34842,34844,34845,34846,34847,34848,34851,31232,24687,24076,24713,33181,22805,24796,29060,28911,28330,27728,29312,27268,34989,24109,20064,23219,21916,38115,27927,31995,38553,25103,32454,30606,34430,21283,38686,36758,26247,23777,20384,29421,19979,21414,22799,21523,25472,38184,20808,20185,40092,32420,21688,36132,34900,33335,38386,28046,24358,23244,26174,38505,29616,29486,21439,33146,39301,32673,23466,38519,38480,32447,30456,21410,38262,39321,31665,35140,28248,20065,32724,31077,35814,24819,21709,20139,39033,24055,27233,20687,21521,35937,33831,30813,38660,21066,21742,22179,38144,28040,23477,28102,26195,34852,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34867,34868,34869,34870,34871,34872,34874,34875,34877,34878,34879,34881,34882,34883,34886,34887,34888,34889,34890,34891,34894,34895,34896,34897,34898,34899,34901,34902,34904,34906,34907,34908,34909,34910,34911,34912,34918,34919,34922,34925,34927,34929,34931,34932,34933,34934,34936,34937,34938,34939,34940,34944,34947,34950,34951,34953,34954,34956,34958,34959,34960,34961,34963,34964,34965,34967,34968,34969,34970,34971,34973,34974,34975,34976,34977,34979,34981,34982,34983,34984,34985,34986,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,34638,38795,21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,25032,27844,27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,20449,34885,26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,24184,26447,24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,32670,26429,21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,24464,35768,33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,36713,21927,23459,24748,26059,29572,34988,34990,34991,34992,34994,34995,34996,34997,34998,35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,35016,35018,35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,35036,35037,35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,35055,35058,35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,35077,35078,35079,35080,35081,35083,35084,35085,35086,35087,35089,35092,35093,35094,35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,35112,35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,36873,30307,30505,32474,38772,34203,23398,31348,38634,34880,21195,29071,24490,26092,35810,23547,39535,24033,27529,27739,35757,35759,36874,36805,21387,25276,40486,40493,21568,20011,33469,29273,34460,23830,34905,28079,38597,21713,20122,35766,28937,21693,38409,28895,28153,30416,20005,30740,34578,23721,24310,35328,39068,38414,28814,27839,22852,25513,30524,34893,28436,33395,22576,29141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523,22830,40495,31207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162,20859,26679,28478,36992,33136,22934,29814,35128,35129,35130,35131,35132,35133,35134,35135,35136,35138,35139,35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,35151,35152,35153,35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,35164,35165,35168,35169,35170,35171,35172,35173,35175,35176,35177,35178,35179,35180,35181,35182,35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,35193,35194,35196,35197,35198,35200,35202,35204,35205,35207,35208,35209,35210,35211,35212,35213,35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,35224,35225,35226,35227,35228,35229,35230,35231,35232,35233,25671,23591,36965,31377,35875,23002,21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,20918,20063,39029,25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,25558,38129,20381,20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,23452,23016,24413,26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,37009,23673,20159,24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,20041,30410,28322,35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,22240,27575,38899,38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,35234,35235,35236,35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,35247,35248,35249,35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,35260,35261,35262,35263,35264,35267,35277,35283,35284,35285,35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,35305,35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,35321,35322,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334,35336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,35349,35350,35351,35352,35353,35354,35355,35356,35357,21360,33521,27185,23156,40560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433,39062,30828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647,27891,28044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038,38080,29369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188,36802,28132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841,28189,28180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577,22495,33419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465,35358,35359,35360,35361,35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,35372,35373,35374,35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,35385,35386,35387,35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,35399,35401,35402,35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,35413,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,35424,35425,35426,35427,35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,35439,35440,35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,35453,35454,35455,35456,28020,23507,35029,39044,35947,39533,40499,28170,20900,20803,22435,34945,21407,25588,36757,22253,21592,22278,29503,28304,32536,36828,33489,24895,24616,38498,26352,32422,36234,36291,38053,23731,31908,26376,24742,38405,32792,20113,37095,21248,38504,20801,36816,34164,37213,26197,38901,23381,21277,30776,26434,26685,21705,28798,23472,36733,20877,22312,21681,25874,26242,36190,36163,33039,33900,36973,31967,20991,34299,26531,26089,28577,34468,36481,22122,36896,30338,28790,29157,36131,25321,21017,27901,36156,24590,22686,24974,26366,36192,25166,21939,28195,26413,36711,35457,35458,35459,35460,35461,35462,35463,35464,35467,35468,35469,35470,35471,35472,35473,35474,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,35486,35487,35488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,35499,35500,35501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,35512,35513,35514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,35525,35526,35527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,35538,35539,35540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,35551,35552,35553,35554,35555,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688,25995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759,23853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467,24352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157,25214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761,32773,38167,34071,36825,27993,29645,26015,30495,29956,30759,33275,36126,38024,20390,26517,30137,35786,38663,25391,38215,38453,33976,25379,30529,24449,29424,20105,24596,25972,25327,27491,25919,35556,35557,35558,35559,35560,35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,35572,35573,35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,35585,35586,35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,35599,35600,35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,35612,35613,35614,35615,35616,35617,35618,35619,35620,35621,35623,35624,35625,35626,35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,35639,35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,35652,35653,24103,30151,37073,35777,33437,26525,25903,21553,34584,30693,32930,33026,27713,20043,32455,32844,30452,26893,27542,25191,20540,20356,22336,25351,27490,36286,21482,26088,32440,24535,25370,25527,33267,33268,32622,24092,23769,21046,26234,31209,31258,36136,28825,30164,28382,27835,31378,20013,30405,24544,38047,34935,32456,31181,32959,37325,20210,20247,33311,21608,24030,27954,35788,31909,36724,32920,24090,21650,30385,23449,26172,39588,29664,26666,34523,26417,29482,35832,35803,36880,31481,28891,29038,25284,30633,22065,20027,33879,26609,21161,34496,36142,38136,31569,35654,35655,35656,35657,35658,35659,35660,35661,35662,35663,35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,35675,35676,35677,35678,35679,35680,35681,35682,35683,35684,35685,35687,35688,35689,35690,35691,35693,35694,35695,35696,35697,35698,35699,35700,35701,35702,35703,35704,35705,35706,35707,35708,35709,35710,35711,35712,35713,35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,35725,35726,35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,35738,35739,35740,35741,35742,35743,35756,35761,35771,35783,35792,35818,35849,35870,20303,27880,31069,39547,25235,29226,25341,19987,30742,36716,25776,36186,31686,26729,24196,35013,22918,25758,22766,29366,26894,38181,36861,36184,22368,32512,35846,20934,25417,25305,21331,26700,29730,33537,37196,21828,30528,28796,27978,20857,21672,36164,23039,28363,28100,23388,32043,20180,31869,28371,23376,33258,28173,23383,39683,26837,36394,23447,32508,24635,32437,37049,36208,22863,25549,31199,36275,21330,26063,31062,35781,38459,32452,38075,32386,22068,37257,26368,32618,23562,36981,26152,24038,20304,26590,20570,20316,22352,24231,59408,59409,59410,59411,59412,35896,35897,35898,35899,35900,35901,35902,35903,35904,35906,35907,35908,35909,35912,35914,35915,35917,35918,35919,35920,35921,35922,35923,35924,35926,35927,35928,35929,35931,35932,35933,35934,35935,35936,35939,35940,35941,35942,35943,35944,35945,35948,35949,35950,35951,35952,35953,35954,35956,35957,35958,35959,35963,35964,35965,35966,35967,35968,35969,35971,35972,35974,35975,35976,35979,35981,35982,35983,35984,35985,35986,35987,35989,35990,35991,35993,35994,35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,36005,36006,36007,36008,36009,36010,36011,36012,36013,20109,19980,20800,19984,24319,21317,19989,20120,19998,39730,23404,22121,20008,31162,20031,21269,20039,22829,29243,21358,27664,22239,32996,39319,27603,30590,40727,20022,20127,40720,20060,20073,20115,33416,23387,21868,22031,20164,21389,21405,21411,21413,21422,38757,36189,21274,21493,21286,21294,21310,36188,21350,21347,20994,21000,21006,21037,21043,21055,21056,21068,21086,21089,21084,33967,21117,21122,21121,21136,21139,20866,32596,20155,20163,20169,20162,20200,20193,20203,20190,20251,20211,20258,20324,20213,20261,20263,20233,20267,20318,20327,25912,20314,20317,36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,36024,36025,36026,36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,36037,36038,36039,36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,36050,36051,36052,36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,36063,36064,36065,36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,36076,36077,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,36089,36090,36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,36102,36103,36104,36105,36106,36107,36108,36109,20319,20311,20274,20285,20342,20340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372,20454,20456,20458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467,20524,20495,20526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552,20558,20588,20603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718,20743,20747,20189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649,39320,20865,22804,21241,21261,35335,21264,20971,22809,20821,20128,20822,20147,34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,20925,20924,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,36121,36122,36123,36124,36128,36177,36178,36183,36191,36197,36200,36201,36202,36204,36206,36207,36209,36210,36216,36217,36218,36219,36220,36221,36222,36223,36224,36226,36227,36230,36231,36232,36233,36236,36237,36238,36239,36240,36242,36243,36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36256,36257,36258,36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,36272,36274,36278,36279,36281,36283,36285,36288,36289,36290,36293,36295,36296,36297,36298,36301,36304,36306,36307,36308,20935,20886,20898,20901,35744,35750,35751,35754,35764,35765,35767,35778,35779,35787,35791,35790,35794,35795,35796,35798,35800,35801,35804,35807,35808,35812,35816,35817,35822,35824,35827,35830,35833,35836,35839,35840,35842,35844,35847,35852,35855,35857,35858,35860,35861,35862,35865,35867,35864,35869,35871,35872,35873,35877,35879,35882,35883,35886,35887,35890,35891,35893,35894,21353,21370,38429,38434,38433,38449,38442,38461,38460,38466,38473,38484,38495,38503,38508,38514,38516,38536,38541,38551,38576,37015,37019,37021,37017,37036,37025,37044,37043,37046,37050,36309,36312,36313,36316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336,36337,36338,36340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358,36359,36360,36363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376,36377,36378,36379,36380,36384,36385,36388,36389,36390,36391,36392,36395,36397,36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,36415,36419,36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,36440,36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,36455,36456,36458,36459,36462,36465,37048,37040,37071,37061,37054,37072,37060,37063,37075,37094,37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,37155,37169,37167,37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,21200,21206,21232,21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,24047,22348,22441,22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,22318,22319,22364,22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,22390,22387,22445,22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,22490,22489,22482,22456,22516,22511,22520,22500,22493,36467,36469,36471,36472,36473,36474,36475,36477,36478,36480,36482,36483,36484,36486,36488,36489,36490,36491,36492,36493,36494,36497,36498,36499,36501,36502,36503,36504,36505,36506,36507,36509,36511,36512,36513,36514,36515,36516,36517,36518,36519,36520,36521,36522,36525,36526,36528,36529,36531,36532,36533,36534,36535,36536,36537,36539,36540,36541,36542,36543,36544,36545,36546,36547,36548,36549,36550,36551,36552,36553,36554,36555,36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,36567,36568,36569,36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,36580,22539,22541,22525,22509,22528,22558,22553,22596,22560,22629,22636,22657,22665,22682,22656,39336,40729,25087,33401,33405,33407,33423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456,33480,33482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450,33439,33476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490,33496,33548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617,33627,33628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603,33631,33600,33559,33632,33581,33594,33587,33638,33637,36581,36582,36583,36584,36585,36586,36587,36588,36589,36590,36591,36592,36593,36594,36595,36596,36597,36598,36599,36600,36601,36602,36603,36604,36605,36606,36607,36608,36609,36610,36611,36612,36613,36614,36615,36616,36617,36618,36619,36620,36621,36622,36623,36624,36625,36626,36627,36628,36629,36630,36631,36632,36633,36634,36635,36636,36637,36638,36639,36640,36641,36642,36643,36644,36645,36646,36647,36648,36649,36650,36651,36652,36653,36654,36655,36656,36657,36658,36659,36660,36661,36662,36663,36664,36665,36666,36667,36668,36669,36670,36671,36672,36673,36674,36675,36676,33640,33563,33641,33644,33642,33645,33646,33712,33656,33715,33716,33696,33706,33683,33692,33669,33660,33718,33705,33661,33720,33659,33688,33694,33704,33722,33724,33729,33793,33765,33752,22535,33816,33803,33757,33789,33750,33820,33848,33809,33798,33748,33759,33807,33795,33784,33785,33770,33733,33728,33830,33776,33761,33884,33873,33882,33881,33907,33927,33928,33914,33929,33912,33852,33862,33897,33910,33932,33934,33841,33901,33985,33997,34000,34022,33981,34003,33994,33983,33978,34016,33953,33977,33972,33943,34021,34019,34060,29965,34104,34032,34105,34079,34106,36677,36678,36679,36680,36681,36682,36683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,36696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,36709,36714,36736,36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,36778,36780,36781,36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,36796,36799,36800,36803,36806,36809,36810,36811,36812,36813,36815,36818,36822,36823,36826,36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,36858,36859,36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,34134,34107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171,34212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241,34268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869,22874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306,25303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524,25453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550,25682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732,25709,25750,36889,36892,36899,36900,36901,36903,36904,36905,36906,36907,36908,36912,36913,36914,36915,36916,36919,36921,36922,36925,36927,36928,36931,36933,36934,36936,36937,36938,36939,36940,36942,36948,36949,36950,36953,36954,36956,36957,36958,36959,36960,36961,36964,36966,36967,36969,36970,36971,36972,36975,36976,36977,36978,36979,36982,36983,36984,36985,36986,36987,36988,36990,36993,36996,36997,36998,36999,37001,37002,37004,37005,37006,37007,37008,37010,37012,37014,37016,37018,37020,37022,37023,37024,37028,37029,37031,37032,37033,37035,37037,37042,37047,37052,37053,37055,37056,25722,25783,25784,25753,25786,25792,25808,25815,25828,25826,25865,25893,25902,24331,24530,29977,24337,21343,21489,21501,21481,21480,21499,21522,21526,21510,21579,21586,21587,21588,21590,21571,21537,21591,21593,21539,21554,21634,21652,21623,21617,21604,21658,21659,21636,21622,21606,21661,21712,21677,21698,21684,21714,21671,21670,21715,21716,21618,21667,21717,21691,21695,21708,21721,21722,21724,21673,21674,21668,21725,21711,21726,21787,21735,21792,21757,21780,21747,21794,21795,21775,21777,21799,21802,21863,21903,21941,21833,21869,21825,21845,21823,21840,21820,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076,37077,37078,37080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098,37100,37102,37104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116,37119,37120,37121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133,37134,37135,37136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147,37148,37149,37151,37152,37153,37156,37157,37158,37159,37160,37161,37162,37163,37164,37165,37166,37168,37170,37171,37172,37173,37174,37175,37176,37178,37179,37180,37181,37182,37183,37184,37185,37186,37188,21815,21846,21877,21878,21879,21811,21808,21852,21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,21983,21949,21950,21908,21913,21994,22007,21961,22047,21969,21995,21996,21972,21990,21981,21956,21999,21989,22002,22003,21964,21965,21992,22005,21988,36756,22046,22024,22028,22017,22052,22051,22014,22016,22055,22061,22104,22073,22103,22060,22093,22114,22105,22108,22092,22100,22150,22116,22129,22123,22139,22140,22149,22163,22191,22228,22231,22237,22241,22261,22251,22265,22271,22276,22282,22281,22300,24079,24089,24084,24081,24113,24123,24124,37189,37191,37192,37201,37203,37204,37205,37206,37208,37209,37211,37212,37215,37216,37222,37223,37224,37227,37229,37235,37242,37243,37244,37248,37249,37250,37251,37252,37254,37256,37258,37262,37263,37267,37268,37269,37270,37271,37272,37273,37276,37277,37278,37279,37280,37281,37284,37285,37286,37287,37288,37289,37291,37292,37296,37297,37298,37299,37302,37303,37304,37305,37307,37308,37309,37310,37311,37312,37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,37331,37332,37333,37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,37345,37346,37347,37348,37349,24119,24132,24148,24155,24158,24161,23692,23674,23693,23696,23702,23688,23704,23705,23697,23706,23708,23733,23714,23741,23724,23723,23729,23715,23745,23735,23748,23762,23780,23755,23781,23810,23811,23847,23846,23854,23844,23838,23814,23835,23896,23870,23860,23869,23916,23899,23919,23901,23915,23883,23882,23913,23924,23938,23961,23965,35955,23991,24005,24435,24439,24450,24455,24457,24460,24469,24473,24476,24488,24493,24501,24508,34914,24417,29357,29360,29364,29367,29368,29379,29377,29390,29389,29394,29416,29423,29417,29426,29428,29431,29441,29427,29443,29434,37350,37351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,37363,37364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,37376,37377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,37389,37390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,37402,37403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,37415,37416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,37428,37429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,37441,37442,37443,37444,37445,29435,29463,29459,29473,29450,29470,29469,29461,29474,29497,29477,29484,29496,29489,29520,29517,29527,29536,29548,29551,29566,33307,22821,39143,22820,22786,39267,39271,39272,39273,39274,39275,39276,39284,39287,39293,39296,39300,39303,39306,39309,39312,39313,39315,39316,39317,24192,24209,24203,24214,24229,24224,24249,24245,24254,24243,36179,24274,24273,24283,24296,24298,33210,24516,24521,24534,24527,24579,24558,24580,24545,24548,24574,24581,24582,24554,24557,24568,24601,24629,24614,24603,24591,24589,24617,24619,24586,24639,24609,24696,24697,24699,24698,24642,37446,37447,37448,37449,37450,37451,37452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,37464,37465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,37477,37478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,37490,37491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,37504,37505,37506,37507,37508,37509,37510,37511,37512,37513,37514,37515,37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,37528,37529,37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,37541,37542,37543,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,24812,24763,24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,24832,24846,24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,38377,38379,38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,38411,38412,38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,27701,27732,27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,27782,27817,27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,27883,27886,27825,27859,27887,27902,37544,37545,37546,37547,37548,37549,37551,37552,37553,37554,37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,37565,37566,37567,37568,37569,37570,37571,37572,37573,37574,37575,37577,37578,37579,37580,37581,37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,37592,37593,37594,37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,37605,37606,37607,37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,37618,37619,37620,37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,37631,37632,37633,37634,37635,37636,37637,37638,37639,37640,37641,27961,27943,27916,27971,27976,27911,27908,27929,27918,27947,27981,27950,27957,27930,27983,27986,27988,27955,28049,28015,28062,28064,27998,28051,28052,27996,28000,28028,28003,28186,28103,28101,28126,28174,28095,28128,28177,28134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267,28338,28255,28294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461,28386,28325,28327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514,28486,28487,28452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553,28557,28556,28536,28530,28540,28538,28625,37642,37643,37644,37645,37646,37647,37648,37649,37650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,37661,37662,37663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,37674,37675,37676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,37687,37688,37689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700,37701,37702,37703,37704,37705,37706,37707,37708,37709,37710,37711,37712,37713,37714,37715,37716,37717,37718,37719,37720,37721,37722,37723,37724,37725,37726,37727,37728,37729,37730,37731,37732,37733,37734,37735,37736,37737,37739,28617,28583,28601,28598,28610,28641,28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,28766,23424,23428,23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,23536,36423,35591,36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,36869,36868,36875,36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,36945,36946,36944,36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,37003,24400,24407,24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,24362,24361,24365,33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,37740,37741,37742,37743,37744,37745,37746,37747,37748,37749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,37760,37761,37762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,37773,37774,37776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,37787,37788,37789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,37800,37801,37802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,37815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,37828,37829,37830,37831,37832,37833,37835,37836,37837,22935,22986,22955,22942,22948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000,23033,23052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100,23138,23157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224,23264,23267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360,23573,23580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551,39549,39552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580,39581,39583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425,37838,37839,37840,37841,37842,37843,37844,37845,37847,37848,37849,37850,37851,37852,37853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,37864,37865,37866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,37878,37879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,37890,37891,37892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,37903,37904,37905,37906,37907,37908,37909,37910,37911,37912,37913,37914,37915,37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,37927,37928,37929,37930,37931,37932,37933,37934,32429,32432,32446,32448,32449,32450,32457,32459,32460,32464,32468,32471,32475,32480,32481,32488,32491,32494,32495,32497,32498,32525,32502,32506,32507,32510,32513,32514,32515,32519,32520,32523,32524,32527,32529,32530,32535,32537,32540,32539,32543,32545,32546,32547,32548,32549,32550,32551,32554,32555,32556,32557,32559,32560,32561,32562,32563,32565,24186,30079,24027,30014,37013,29582,29585,29614,29602,29599,29647,29634,29649,29623,29619,29632,29641,29640,29669,29657,39036,29706,29673,29671,29662,29626,29682,29711,29738,29787,29734,29733,29736,29744,29742,29740,37935,37936,37937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,37951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,37964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,37977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,37990,37991,37992,37993,37994,37996,37997,37998,37999,38000,38001,38002,38003,38004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,38017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100,38106,38118,38139,38172,38176,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822,29852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882,38890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520,26535,26485,26536,26526,26541,26507,26487,26492,26608,26633,26584,26634,26601,26544,26636,26585,26549,26586,26547,26589,26624,26563,26552,26594,26638,26561,26621,26674,26675,26720,26721,26702,26722,26692,26724,26755,26653,26709,26726,26689,26727,26688,26686,26698,26697,26665,26805,26767,26740,26743,26771,26731,26818,26990,26876,26911,26912,26873,38183,38195,38205,38211,38216,38219,38229,38234,38240,38254,38260,38261,38263,38264,38265,38266,38267,38268,38269,38270,38272,38273,38274,38275,38276,38277,38278,38279,38280,38281,38282,38283,38284,38285,38286,38287,38288,38289,38290,38291,38292,38293,38294,38295,38296,38297,38298,38299,38300,38301,38302,38303,38304,38305,38306,38307,38308,38309,38310,38311,38312,38313,38314,38315,38316,38317,38318,38319,38320,38321,38322,38323,38324,38325,38326,38327,38328,38329,38330,38331,38332,38333,38334,38335,38336,38337,38338,38339,38340,38341,38342,38343,38344,38345,38346,38347,26916,26864,26891,26881,26967,26851,26896,26993,26937,26976,26946,26973,27012,26987,27008,27032,27000,26932,27084,27015,27016,27086,27017,26982,26979,27001,27035,27047,27067,27051,27053,27092,27057,27073,27082,27103,27029,27104,27021,27135,27183,27117,27159,27160,27237,27122,27204,27198,27296,27216,27227,27189,27278,27257,27197,27176,27224,27260,27281,27280,27305,27287,27307,29495,29522,27521,27522,27527,27524,27538,27539,27533,27546,27547,27553,27562,36715,36717,36721,36722,36723,36725,36726,36728,36727,36729,36730,36732,36734,36737,36738,36740,36743,36747,38348,38349,38350,38351,38352,38353,38354,38355,38356,38357,38358,38359,38360,38361,38362,38363,38364,38365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,38380,38399,38407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439,38440,38441,38443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465,38467,38474,38478,38479,38481,38482,38483,38486,38487,38488,38489,38490,38492,38493,38494,38496,38499,38501,38502,38507,38509,38510,38511,38512,38513,38515,38520,38521,38522,38523,38524,38525,38526,38527,38528,38529,38530,38531,38532,38535,38537,38538,36749,36750,36751,36760,36762,36558,25099,25111,25115,25119,25122,25121,25125,25124,25132,33255,29935,29940,29951,29967,29969,29971,25908,26094,26095,26096,26122,26137,26482,26115,26133,26112,28805,26359,26141,26164,26161,26166,26165,32774,26207,26196,26177,26191,26198,26209,26199,26231,26244,26252,26279,26269,26302,26331,26332,26342,26345,36146,36147,36150,36155,36157,36160,36165,36166,36168,36169,36167,36173,36181,36185,35271,35274,35275,35276,35278,35279,35280,35281,29294,29343,29277,29286,29295,29310,29311,29316,29323,29325,29327,29330,25352,25394,25520,38540,38542,38545,38546,38547,38549,38550,38554,38555,38557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570,38571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587,38591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616,38617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630,38631,38635,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650,38651,38652,38653,38655,38658,38659,38661,38666,38667,38668,38672,38673,38674,38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,25663,25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,27672,27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,29270,29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,32948,32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,32989,33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,33054,33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,33148,33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,26406,33226,33211,38689,38690,38691,38692,38693,38694,38695,38696,38697,38699,38700,38702,38703,38705,38707,38708,38709,38710,38711,38714,38715,38716,38717,38719,38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,38732,38733,38734,38735,38736,38737,38740,38741,38743,38744,38746,38748,38749,38751,38755,38756,38758,38759,38760,38762,38763,38764,38765,38766,38767,38768,38769,38770,38773,38775,38776,38777,38778,38779,38781,38782,38783,38784,38785,38786,38787,38788,38790,38791,38792,38793,38794,38796,38798,38799,38800,38803,38805,38806,38807,38809,38810,38811,38812,38813,33217,33190,27428,27447,27449,27459,27462,27481,39121,39122,39123,39125,39129,39130,27571,24384,27586,35315,26000,40785,26003,26044,26054,26052,26051,26060,26062,26066,26070,28800,28828,28822,28829,28859,28864,28855,28843,28849,28904,28874,28944,28947,28950,28975,28977,29043,29020,29032,28997,29042,29002,29048,29050,29080,29107,29109,29096,29088,29152,29140,29159,29177,29213,29224,28780,28952,29030,29113,25150,25149,25155,25160,25161,31035,31040,31046,31049,31067,31068,31059,31066,31074,31063,31072,31087,31079,31098,31109,31114,31130,31143,31155,24529,24528,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825,38826,38828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843,38844,38845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,38857,38858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,38870,38871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,38883,38884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904,38905,38906,38907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,38918,38919,38920,38921,38922,38923,38924,38925,38926,24636,24669,24666,24679,24641,24665,24675,24747,24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,27894,28156,30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,30777,30778,30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,30758,30800,30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,30905,30885,30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,40859,40697,40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,30509,30502,30517,30520,30544,30545,30535,30531,30554,30568,38927,38928,38929,38930,38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,38943,38944,38945,38946,38947,38948,38949,38950,38951,38952,38953,38954,38955,38956,38957,38958,38959,38960,38961,38962,38963,38964,38965,38966,38967,38968,38969,38970,38971,38972,38973,38974,38975,38976,38977,38978,38979,38980,38981,38982,38983,38984,38985,38986,38987,38988,38989,38990,38991,38992,38993,38994,38995,38996,38997,38998,38999,39000,39001,39002,39003,39004,39005,39006,39007,39008,39009,39010,39011,39012,39013,39014,39015,39016,39017,39018,39019,39020,39021,39022,30562,30565,30591,30605,30589,30592,30604,30609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024,30043,30066,30073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641,32638,30413,30437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032,38036,38039,38037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063,38064,38066,38068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088,38089,38090,38091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105,38104,38107,38110,38111,38112,38114,38116,38117,38119,38120,38122,39023,39024,39025,39026,39027,39028,39051,39054,39058,39061,39065,39075,39080,39081,39082,39083,39084,39085,39086,39087,39088,39089,39090,39091,39092,39093,39094,39095,39096,39097,39098,39099,39100,39101,39102,39103,39104,39105,39106,39107,39108,39109,39110,39111,39112,39113,39114,39115,39116,39117,39119,39120,39124,39126,39127,39131,39132,39133,39136,39137,39138,39139,39140,39141,39142,39145,39146,39147,39148,39149,39150,39151,39152,39153,39154,39155,39156,39157,39158,39159,39160,39161,39162,39163,39164,39165,39166,39167,39168,39169,39170,39171,39172,39173,39174,39175,38121,38123,38126,38127,38131,38132,38133,38135,38137,38140,38141,38143,38147,38146,38150,38151,38153,38154,38157,38158,38159,38162,38163,38164,38165,38166,38168,38171,38173,38174,38175,38178,38186,38187,38185,38188,38193,38194,38196,38198,38199,38200,38204,38206,38207,38210,38197,38212,38213,38214,38217,38220,38222,38223,38226,38227,38228,38230,38231,38232,38233,38235,38238,38239,38237,38241,38242,38244,38245,38246,38247,38248,38249,38250,38251,38252,38255,38257,38258,38259,38202,30695,30700,38601,31189,31213,31203,31211,31238,23879,31235,31234,31262,31252,39176,39177,39178,39179,39180,39182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,39196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,39209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222,39223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,39236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,39249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,39264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299,39305,31289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918,29920,29996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504,40503,40505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524,40526,40529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553,40554,40555,40556,40561,40557,40563,30098,30100,30102,30112,30109,30124,30115,30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,30179,30184,30182,30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,30220,30231,30218,30245,30232,30229,30233,39308,39310,39322,39323,39324,39325,39326,39327,39328,39329,39330,39331,39332,39334,39335,39337,39338,39339,39340,39341,39342,39343,39344,39345,39346,39347,39348,39349,39350,39351,39352,39353,39354,39355,39356,39357,39358,39359,39360,39361,39362,39363,39364,39365,39366,39367,39368,39369,39370,39371,39372,39373,39374,39375,39376,39377,39378,39379,39380,39381,39382,39383,39384,39385,39386,39387,39388,39389,39390,39391,39392,39393,39394,39395,39396,39397,39398,39399,39400,39401,39402,39403,39404,39405,39406,39407,39408,39409,39410,39411,39412,39413,39414,39415,39416,39417,30235,30268,30242,30240,30272,30253,30256,30271,30261,30275,30270,30259,30285,30302,30292,30300,30294,30315,30319,32714,31462,31352,31353,31360,31366,31368,31381,31398,31392,31404,31400,31405,31411,34916,34921,34930,34941,34943,34946,34978,35014,34999,35004,35017,35042,35022,35043,35045,35057,35098,35068,35048,35070,35056,35105,35097,35091,35099,35082,35124,35115,35126,35137,35174,35195,30091,32997,30386,30388,30684,32786,32788,32790,32796,32800,32802,32805,32806,32807,32809,32808,32817,32779,32821,32835,32838,32845,32850,32873,32881,35203,39032,39040,39043,39418,39419,39420,39421,39422,39423,39424,39425,39426,39427,39428,39429,39430,39431,39432,39433,39434,39435,39436,39437,39438,39439,39440,39441,39442,39443,39444,39445,39446,39447,39448,39449,39450,39451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,39463,39464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,39476,39477,39478,39479,39480,39481,39482,39483,39484,39485,39486,39487,39488,39489,39490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,39501,39502,39503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,39049,39052,39053,39055,39060,39066,39067,39070,39071,39073,39074,39077,39078,34381,34388,34412,34414,34431,34426,34428,34427,34472,34445,34443,34476,34461,34471,34467,34474,34451,34473,34486,34500,34485,34510,34480,34490,34481,34479,34505,34511,34484,34537,34545,34546,34541,34547,34512,34579,34526,34548,34527,34520,34513,34563,34567,34552,34568,34570,34573,34569,34595,34619,34590,34597,34606,34586,34622,34632,34612,34609,34601,34615,34623,34690,34594,34685,34686,34683,34656,34672,34636,34670,34699,34643,34659,34684,34660,34649,34661,34707,34735,34728,34770,39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,39526,39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,39577,39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,39609,39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,39630,39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,39645,39646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664,39665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679,39680,39681,39682,39684,39685,39686,34758,34696,34693,34733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752,34762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876,32566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531,31503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518,31576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632,31654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697,31681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755,39687,39689,39690,39691,39692,39693,39694,39696,39697,39698,39700,39701,39702,39703,39704,39705,39706,39707,39708,39709,39710,39712,39713,39714,39716,39717,39718,39719,39720,39721,39722,39723,39724,39725,39726,39728,39729,39731,39732,39733,39734,39735,39736,39737,39738,39741,39742,39743,39744,39750,39754,39755,39756,39758,39760,39762,39763,39765,39766,39767,39768,39769,39770,39771,39772,39773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,39785,39786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,39798,39799,39800,39801,39802,39803,31775,31786,31782,31800,31809,31808,33278,33281,33282,33284,33260,34884,33313,33314,33315,33325,33327,33320,33323,33336,33339,33331,33332,33342,33348,33353,33355,33359,33370,33375,33384,34942,34949,34952,35032,35039,35166,32669,32671,32679,32687,32688,32690,31868,25929,31889,31901,31900,31902,31906,31922,31932,31933,31937,31943,31948,31949,31944,31941,31959,31976,33390,26280,32703,32718,32725,32741,32737,32742,32745,32750,32755,31992,32119,32166,32174,32327,32411,40632,40628,36211,36228,36244,36241,36273,36199,36205,35911,35913,37194,37200,37198,37199,37220,39804,39805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,39818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,39831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,39844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,39857,39858,39859,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,39870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,39883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,39896,39897,39898,39899,37218,37217,37232,37225,37231,37245,37246,37234,37236,37241,37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,37300,37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,36292,36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,36345,36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,36416,36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,36476,36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,35992,35988,26011,35286,35294,35290,35292,39900,39901,39902,39903,39904,39905,39906,39907,39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,39919,39920,39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,39932,39933,39934,39935,39936,39937,39938,39939,39940,39941,39942,39943,39944,39945,39946,39947,39948,39949,39950,39951,39952,39953,39954,39955,39956,39957,39958,39959,39960,39961,39962,39963,39964,39965,39966,39967,39968,39969,39970,39971,39972,39973,39974,39975,39976,39977,39978,39979,39980,39981,39982,39983,39984,39985,39986,39987,39988,39989,39990,39991,39992,39993,39994,39995,35301,35307,35311,35390,35622,38739,38633,38643,38639,38662,38657,38664,38671,38670,38698,38701,38704,38718,40832,40835,40837,40838,40839,40840,40841,40842,40844,40702,40715,40717,38585,38588,38589,38606,38610,30655,38624,37518,37550,37576,37694,37738,37834,37775,37950,37995,40063,40066,40069,40070,40071,40072,31267,40075,40078,40080,40081,40082,40084,40085,40090,40091,40094,40095,40096,40097,40098,40099,40101,40102,40103,40104,40105,40107,40109,40110,40112,40113,40114,40115,40116,40117,40118,40119,40122,40123,40124,40125,40132,40133,40134,40135,40138,40139,39996,39997,39998,39999,40000,40001,40002,40003,40004,40005,40006,40007,40008,40009,40010,40011,40012,40013,40014,40015,40016,40017,40018,40019,40020,40021,40022,40023,40024,40025,40026,40027,40028,40029,40030,40031,40032,40033,40034,40035,40036,40037,40038,40039,40040,40041,40042,40043,40044,40045,40046,40047,40048,40049,40050,40051,40052,40053,40054,40055,40056,40057,40058,40059,40061,40062,40064,40067,40068,40073,40074,40076,40079,40083,40086,40087,40088,40089,40093,40106,40108,40111,40121,40126,40127,40128,40129,40130,40136,40137,40145,40146,40154,40155,40160,40161,40140,40141,40142,40143,40144,40147,40148,40149,40151,40152,40153,40156,40157,40159,40162,38780,38789,38801,38802,38804,38831,38827,38819,38834,38836,39601,39600,39607,40536,39606,39610,39612,39617,39616,39621,39618,39627,39628,39633,39749,39747,39751,39753,39752,39757,39761,39144,39181,39214,39253,39252,39647,39649,39654,39663,39659,39675,39661,39673,39688,39695,39699,39711,39715,40637,40638,32315,40578,40583,40584,40587,40594,37846,40605,40607,40667,40668,40669,40672,40671,40674,40681,40679,40677,40682,40687,40738,40748,40751,40761,40759,40765,40766,40772,40163,40164,40165,40166,40167,40168,40169,40170,40171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,40184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,40197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,40210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,40223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,40236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,40249,40250,40251,40252,40253,40254,40255,40256,40257,40258,57908,57909,57910,57911,57912,57913,57914,57915,57916,57917,57918,57919,57920,57921,57922,57923,57924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934,57935,57936,57937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947,57948,57949,57950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960,57961,57962,57963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973,57974,57975,57976,57977,57978,57979,57980,57981,57982,57983,57984,57985,57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,57998,57999,58000,58001,40259,40260,40261,40262,40263,40264,40265,40266,40267,40268,40269,40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,40281,40282,40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,40294,40295,40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,40307,40308,40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,40320,40321,40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,40333,40334,40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,40346,40347,40348,40349,40350,40351,40352,40353,40354,58002,58003,58004,58005,58006,58007,58008,58009,58010,58011,58012,58013,58014,58015,58016,58017,58018,58019,58020,58021,58022,58023,58024,58025,58026,58027,58028,58029,58030,58031,58032,58033,58034,58035,58036,58037,58038,58039,58040,58041,58042,58043,58044,58045,58046,58047,58048,58049,58050,58051,58052,58053,58054,58055,58056,58057,58058,58059,58060,58061,58062,58063,58064,58065,58066,58067,58068,58069,58070,58071,58072,58073,58074,58075,58076,58077,58078,58079,58080,58081,58082,58083,58084,58085,58086,58087,58088,58089,58090,58091,58092,58093,58094,58095,40355,40356,40357,40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,40369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,40382,40383,40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,40395,40396,40397,40398,40399,40400,40401,40402,40403,40404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,40417,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,40429,40430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,40442,40443,40444,40445,40446,40447,40448,40449,40450,58096,58097,58098,58099,58100,58101,58102,58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,58114,58115,58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,58127,58128,58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,58140,58141,58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,58153,58154,58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,58166,58167,58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,58179,58180,58181,58182,58183,58184,58185,58186,58187,58188,58189,40451,40452,40453,40454,40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,40466,40467,40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,40484,40487,40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,40534,40537,40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,40566,40567,40568,40569,40570,40571,40572,40573,40576,40577,40579,40580,40581,40582,40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,40600,40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,40616,40617,40618,58190,58191,58192,58193,58194,58195,58196,58197,58198,58199,58200,58201,58202,58203,58204,58205,58206,58207,58208,58209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,58222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,58235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245,58246,58247,58248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,58261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58273,58274,58275,58276,58277,58278,58279,58280,58281,58282,58283,40619,40620,40621,40622,40623,40624,40625,40626,40627,40629,40630,40631,40633,40634,40636,40639,40640,40641,40642,40643,40645,40646,40647,40648,40650,40651,40652,40656,40658,40659,40661,40662,40663,40665,40666,40670,40673,40675,40676,40678,40680,40683,40684,40685,40686,40688,40689,40690,40691,40692,40693,40694,40695,40696,40698,40701,40703,40704,40705,40706,40707,40708,40709,40710,40711,40712,40713,40714,40716,40719,40721,40722,40724,40725,40726,40728,40730,40731,40732,40733,40734,40735,40737,40739,40740,40741,40742,40743,40744,40745,40746,40747,40749,40750,40752,40753,58284,58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,58295,58296,58297,58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,58308,58309,58310,58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,58321,58322,58323,58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,58334,58335,58336,58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,58347,58348,58349,58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,58360,58361,58362,58363,58364,58365,58366,58367,58368,58369,58370,58371,58372,58373,58374,58375,58376,58377,40754,40755,40756,40757,40758,40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,40777,40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,40792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,40805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,40818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,40833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,40856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975,63985,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,58389,58390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,58402,58403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,58415,58416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,58428,58429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,58441,58442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,58454,58455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,58467,58468,58469,58470,58471,64012,64013,64014,64015,64017,64019,64020,64024,64031,64032,64033,64035,64036,64039,64040,64041,11905,59414,59415,59416,11908,13427,13383,11912,11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,14815,14963,14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,16735,11950,17207,11955,11958,11959,59451,17329,17324,11963,17373,17622,18017,17996,59459,18211,18217,18300,18317,11978,18759,18810,18813,18818,18819,18821,18822,18847,18843,18871,18870,59476,59477,19619,19615,19616,19617,19575,19618,19731,19732,19733,19734,19735,19736,19737,19886,59492,58472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484,58485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58495,58496,58497,58498,58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,58511,58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,58524,58525,58526,58527,58528,58529,58530,58531,58532,58533,58534,58535,58536,58537,58538,58539,58540,58541,58542,58543,58544,58545,58546,58547,58548,58549,58550,58551,58552,58553,58554,58555,58556,58557,58558,58559,58560,58561,58562,58563,58564,58565],\n  \"gb18030-ranges\":[[0,128],[36,165],[38,169],[45,178],[50,184],[81,216],[89,226],[95,235],[96,238],[100,244],[103,248],[104,251],[105,253],[109,258],[126,276],[133,284],[148,300],[172,325],[175,329],[179,334],[208,364],[306,463],[307,465],[308,467],[309,469],[310,471],[311,473],[312,475],[313,477],[341,506],[428,594],[443,610],[544,712],[545,716],[558,730],[741,930],[742,938],[749,962],[750,970],[805,1026],[819,1104],[820,1106],[7922,8209],[7924,8215],[7925,8218],[7927,8222],[7934,8231],[7943,8241],[7944,8244],[7945,8246],[7950,8252],[8062,8365],[8148,8452],[8149,8454],[8152,8458],[8164,8471],[8174,8482],[8236,8556],[8240,8570],[8262,8596],[8264,8602],[8374,8713],[8380,8720],[8381,8722],[8384,8726],[8388,8731],[8390,8737],[8392,8740],[8393,8742],[8394,8748],[8396,8751],[8401,8760],[8406,8766],[8416,8777],[8419,8781],[8424,8787],[8437,8802],[8439,8808],[8445,8816],[8482,8854],[8485,8858],[8496,8870],[8521,8896],[8603,8979],[8936,9322],[8946,9372],[9046,9548],[9050,9588],[9063,9616],[9066,9622],[9076,9634],[9092,9652],[9100,9662],[9108,9672],[9111,9676],[9113,9680],[9131,9702],[9162,9735],[9164,9738],[9218,9793],[9219,9795],[11329,11906],[11331,11909],[11334,11913],[11336,11917],[11346,11928],[11361,11944],[11363,11947],[11366,11951],[11370,11956],[11372,11960],[11375,11964],[11389,11979],[11682,12284],[11686,12292],[11687,12312],[11692,12319],[11694,12330],[11714,12351],[11716,12436],[11723,12447],[11725,12535],[11730,12543],[11736,12586],[11982,12842],[11989,12850],[12102,12964],[12336,13200],[12348,13215],[12350,13218],[12384,13253],[12393,13263],[12395,13267],[12397,13270],[12510,13384],[12553,13428],[12851,13727],[12962,13839],[12973,13851],[13738,14617],[13823,14703],[13919,14801],[13933,14816],[14080,14964],[14298,15183],[14585,15471],[14698,15585],[15583,16471],[15847,16736],[16318,17208],[16434,17325],[16438,17330],[16481,17374],[16729,17623],[17102,17997],[17122,18018],[17315,18212],[17320,18218],[17402,18301],[17418,18318],[17859,18760],[17909,18811],[17911,18814],[17915,18820],[17916,18823],[17936,18844],[17939,18848],[17961,18872],[18664,19576],[18703,19620],[18814,19738],[18962,19887],[19043,40870],[33469,59244],[33470,59336],[33471,59367],[33484,59413],[33485,59417],[33490,59423],[33497,59431],[33501,59437],[33505,59443],[33513,59452],[33520,59460],[33536,59478],[33550,59493],[37845,63789],[37921,63866],[37948,63894],[38029,63976],[38038,63986],[38064,64016],[38065,64018],[38066,64021],[38069,64025],[38075,64034],[38076,64037],[38078,64042],[39108,65074],[39109,65093],[39113,65107],[39114,65112],[39115,65127],[39116,65132],[39265,65375],[39394,65510],[189000,65536]],\n  \"jis0208\":[12288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,65344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,12295,12540,8213,8208,65295,65340,65374,8741,65372,8230,8229,8216,8217,8220,8221,65288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,12301,12302,12303,12304,12305,65291,65293,177,215,247,65309,8800,65308,65310,8806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,65504,65505,65285,65283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8251,12306,8594,8592,8593,8595,12307,null,null,null,null,null,null,null,null,null,null,null,8712,8715,8838,8839,8834,8835,8746,8745,null,null,null,null,null,null,null,null,8743,8744,65506,8658,8660,8704,8707,null,null,null,null,null,null,null,null,null,null,null,8736,8869,8978,8706,8711,8801,8786,8810,8811,8730,8765,8733,8757,8747,8748,null,null,null,null,null,null,null,8491,8240,9839,9837,9834,8224,8225,182,null,null,null,null,9711,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,65296,65297,65298,65299,65300,65301,65302,65303,65304,65305,null,null,null,null,null,null,null,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,null,null,null,null,null,null,65345,65346,65347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,null,null,null,null,12353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,null,null,null,null,null,null,null,null,null,null,null,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,null,null,null,null,null,null,null,null,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,null,null,null,null,null,null,null,null,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,null,null,null,null,null,null,null,null,null,null,null,null,null,9472,9474,9484,9488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,9523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,9312,9313,9314,9315,9316,9317,9318,9319,9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,null,13129,13076,13090,13133,13080,13095,13059,13110,13137,13143,13069,13094,13091,13099,13130,13115,13212,13213,13214,13198,13199,13252,13217,null,null,null,null,null,null,null,null,13179,12317,12319,8470,13261,8481,12964,12965,12966,12967,12968,12849,12850,12857,13182,13181,13180,8786,8801,8747,8750,8721,8730,8869,8736,8735,8895,8757,8745,8746,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,20124,21782,23043,38463,21696,24859,25384,23030,36898,33909,33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,26017,25201,23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,24245,25353,26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,22839,22996,23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,32173,32239,32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,37057,30959,19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,21729,22240,23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,21491,23431,28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,22040,21764,27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,38642,33615,39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,29787,30408,31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,35585,36234,38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,25588,27839,28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,37467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,27178,27431,27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,23627,25014,33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,21270,20206,20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,31185,26247,26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,33499,33540,33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,20420,23784,25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,20250,35299,22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,25913,39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,35997,20977,21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,35442,37799,39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,24275,25313,25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,37101,38307,38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,26806,39949,28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,19988,39993,21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,40232,26658,33541,33841,31909,21000,33477,29926,20094,20355,20896,23506,21002,21208,21223,24059,21914,22570,23014,23436,23448,23515,24178,24185,24739,24863,24931,25022,25563,25954,26577,26707,26874,27454,27475,27735,28450,28567,28485,29872,29976,30435,30475,31487,31649,31777,32233,32566,32752,32925,33382,33694,35251,35532,36011,36996,37969,38291,38289,38306,38501,38867,39208,33304,20024,21547,23736,24012,29609,30284,30524,23721,32747,36107,38593,38929,38996,39000,20225,20238,21361,21916,22120,22522,22855,23305,23492,23696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820,27231,24112,27589,27671,27773,30079,31048,23395,31232,32000,24509,35215,35352,36020,36215,36556,36637,39138,39438,39740,20096,20605,20736,22931,23452,25135,25216,25836,27450,29344,30097,31047,32681,34811,35516,35696,25516,33738,38816,21513,21507,21931,26708,27224,35440,30759,26485,40653,21364,23458,33050,34384,36870,19992,20037,20167,20241,21450,21560,23470,24339,24613,25937,26429,27714,27762,27875,28792,29699,31350,31406,31496,32026,31998,32102,26087,29275,21435,23621,24040,25298,25312,25369,28192,34394,35377,36317,37624,28417,31142,39770,20136,20139,20140,20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932,22659,23777,24375,24394,24623,24656,24685,25375,25945,27211,27841,29378,29421,30703,33016,33029,33288,34126,37111,37857,38911,39255,39514,20208,20957,23597,26241,26989,23616,26354,26997,29577,26704,31873,20677,21220,22343,24062,37670,26020,27427,27453,29748,31105,31165,31563,32202,33465,33740,34943,35167,35641,36817,37329,21535,37504,20061,20534,21477,21306,29399,29590,30697,33510,36527,39366,39368,39378,20855,24858,34398,21936,31354,20598,23507,36935,38533,20018,27355,37351,23633,23624,25496,31391,27795,38772,36705,31402,29066,38536,31874,26647,32368,26705,37740,21234,21531,34219,35347,32676,36557,37089,21350,34952,31041,20418,20670,21009,20804,21843,22317,29674,22411,22865,24418,24452,24693,24950,24935,25001,25522,25658,25964,26223,26690,28179,30054,31293,31995,32076,32153,32331,32619,33550,33610,34509,35336,35427,35686,36605,38938,40335,33464,36814,39912,21127,25119,25731,28608,38553,26689,20625,27424,27770,28500,31348,32080,34880,35363,26376,20214,20537,20518,20581,20860,21048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458,26908,27177,29309,29356,29486,30740,30831,32121,30476,32937,35211,35609,36066,36562,36963,37749,38522,38997,39443,40568,20803,21407,21427,24187,24358,28187,28304,29572,29694,32067,33335,35328,35578,38480,20046,20491,21476,21628,22266,22993,23396,24049,24235,24359,25144,25925,26543,28246,29392,31946,34996,32929,32993,33776,34382,35463,36328,37431,38599,39015,40723,20116,20114,20237,21320,21577,21566,23087,24460,24481,24735,26791,27278,29786,30849,35486,35492,35703,37264,20062,39881,20132,20348,20399,20505,20502,20809,20844,21151,21177,21246,21402,21475,21521,21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184,24195,24218,24247,24344,24658,24908,25239,25304,25511,25915,26114,26179,26356,26477,26657,26775,27083,27743,27946,28009,28207,28317,30002,30343,30828,31295,31968,32005,32024,32094,32177,32789,32771,32943,32945,33108,33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,37628,38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,28640,35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,28425,33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,22718,23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,20123,20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,35039,22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,25165,25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,33756,35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,27018,32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,26613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,25774,25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,19977,20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,34453,35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,21496,21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,24605,25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,31169,31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,36039,36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,26178,27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,36766,27728,40575,24335,35672,40235,31482,36600,23437,38635,19971,21489,22519,22833,23241,23460,24713,28287,28422,30142,36074,23455,34048,31712,20594,26612,33437,23649,34122,32286,33294,20889,23556,25448,36198,26012,29038,31038,32023,32773,35613,36554,36974,34503,37034,20511,21242,23610,26451,28796,29237,37196,37320,37675,33509,23490,24369,24825,20027,21462,23432,25163,26417,27530,29417,29664,31278,33131,36259,37202,39318,20754,21463,21610,23551,25480,27193,32172,38656,22234,21454,21608,23447,23601,24030,20462,24833,25342,27954,31168,31179,32066,32333,32722,33261,33311,33936,34886,35186,35728,36468,36655,36913,37195,37228,38598,37276,20160,20303,20805,21313,24467,25102,26580,27713,28171,29539,32294,37325,37507,21460,22809,23487,28113,31069,32302,31899,22654,29087,20986,34899,36848,20426,23803,26149,30636,31459,33308,39423,20934,24490,26092,26991,27529,28147,28310,28516,30462,32020,24033,36981,37255,38918,20966,21021,25152,26257,26329,28186,24246,32210,32626,26360,34223,34295,35576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767,21213,21280,21319,21484,21736,21830,21809,22039,22888,22974,23100,23477,23558,23567,23569,23578,24196,24202,24288,24432,25215,25220,25307,25484,25463,26119,26124,26157,26230,26494,26786,27167,27189,27836,28040,28169,28248,28988,28966,29031,30151,30465,30813,30977,31077,31216,31456,31505,31911,32057,32918,33750,33931,34121,34909,35059,35359,35388,35412,35443,35937,36062,37284,37478,37758,37912,38556,38808,19978,19976,19998,20055,20887,21104,22478,22580,22732,23330,24120,24773,25854,26465,26454,27972,29366,30067,31331,33976,35698,37304,37664,22065,22516,39166,25325,26893,27542,29165,32340,32887,33394,35302,39135,34645,36785,23611,20280,20449,20405,21767,23072,23517,23529,24515,24910,25391,26032,26187,26862,27035,28024,28145,30003,30137,30495,31070,31206,32051,33251,33455,34218,35242,35386,36523,36763,36914,37341,38663,20154,20161,20995,22645,22764,23563,29978,23613,33102,35338,36805,38499,38765,31525,35535,38920,37218,22259,21416,36887,21561,22402,24101,25512,27700,28810,30561,31883,32736,34928,36930,37204,37648,37656,38543,29790,39620,23815,23913,25968,26530,36264,38619,25454,26441,26905,33733,38935,38592,35070,28548,25722,23544,19990,28716,30045,26159,20932,21046,21218,22995,24449,24615,25104,25919,25972,26143,26228,26866,26646,27491,28165,29298,29983,30427,31934,32854,22768,35069,35199,35488,35475,35531,36893,37266,38738,38745,25993,31246,33030,38587,24109,24796,25114,26021,26132,26512,30707,31309,31821,32318,33034,36012,36196,36321,36447,30889,20999,25305,25509,25666,25240,35373,31363,31680,35500,38634,32118,33292,34633,20185,20808,21315,21344,23459,23554,23574,24029,25126,25159,25776,26643,26676,27849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218,32330,32680,33146,33307,33337,34214,35438,36046,36341,36984,36983,37549,37521,38275,39854,21069,21892,28472,28982,20840,31109,32341,33203,31950,22092,22609,23720,25514,26366,26365,26970,29401,30095,30094,30990,31062,31199,31895,32032,32068,34311,35380,38459,36961,40736,20711,21109,21452,21474,20489,21930,22766,22863,29245,23435,23652,21277,24803,24819,25436,25475,25407,25531,25805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967,32207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783,38684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363,24687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966,20854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409,21822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534,23550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151,33492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261,38988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730,35351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890,33073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022,22374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829,32966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527,20516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933,39347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013,20210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376,27159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115,24193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522,32884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189,25431,30452,26389,27784,29645,36035,37806,38515,27941,22684,26894,27084,36861,37786,30171,36890,22618,26626,25524,27131,20291,28460,26584,36795,34086,32180,37716,26943,28528,22378,22775,23340,32044,29226,21514,37347,40372,20141,20302,20572,20597,21059,35998,21576,22564,23450,24093,24213,24237,24311,24351,24716,25269,25402,25552,26799,27712,30855,31118,31243,32224,33351,35330,35558,36420,36883,37048,37165,37336,40718,27877,25688,25826,25973,28404,30340,31515,36969,37841,28346,21746,24505,25764,36685,36845,37444,20856,22635,22825,23637,24215,28155,32399,29980,36028,36578,39003,28857,20253,27583,28593,30000,38651,20814,21520,22581,22615,22956,23648,24466,26007,26460,28193,30331,33759,36077,36884,37117,37709,30757,30778,21162,24230,22303,22900,24594,20498,20826,20908,20941,20992,21776,22612,22616,22871,23445,23798,23947,24764,25237,25645,26481,26691,26812,26847,30423,28120,28271,28059,28783,29128,24403,30168,31095,31561,31572,31570,31958,32113,21040,33891,34153,34276,35342,35588,35910,36367,36867,36879,37913,38518,38957,39472,38360,20685,21205,21516,22530,23566,24999,25758,27934,30643,31461,33012,33796,36947,37509,23776,40199,21311,24471,24499,28060,29305,30563,31167,31716,27602,29420,35501,26627,27233,20984,31361,26932,23626,40182,33515,23493,37193,28702,22136,23663,24775,25958,27788,35930,36929,38931,21585,26311,37389,22856,37027,20869,20045,20970,34201,35598,28760,25466,37707,26978,39348,32260,30071,21335,26976,36575,38627,27741,20108,23612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837,22914,23615,38894,20219,22922,24525,35469,28641,31152,31074,23527,33905,29483,29105,24180,24565,25467,25754,29123,31896,20035,24316,20043,22492,22178,24745,28611,32013,33021,33075,33215,36786,35223,34468,24052,25226,25773,35207,26487,27874,27966,29750,30772,23110,32629,33453,39340,20467,24259,25309,25490,25943,26479,30403,29260,32972,32954,36649,37197,20493,22521,23186,26757,26995,29028,29437,36023,22770,36064,38506,36889,34687,31204,30695,33833,20271,21093,21338,25293,26575,27850,30333,31636,31893,33334,34180,36843,26333,28448,29190,32283,33707,39361,40614,20989,31665,30834,31672,32903,31560,27368,24161,32908,30033,30048,20843,37474,28300,30330,37271,39658,20240,32624,25244,31567,38309,40169,22138,22617,34532,38588,20276,21028,21322,21453,21467,24070,25644,26001,26495,27710,27726,29256,29359,29677,30036,32321,33324,34281,36009,31684,37318,29033,38930,39151,25405,26217,30058,30436,30928,34115,34542,21290,21329,21542,22915,24199,24444,24754,25161,25209,25259,26000,27604,27852,30130,30382,30865,31192,32203,32631,32933,34987,35513,36027,36991,38750,39131,27147,31800,20633,23614,24494,26503,27608,29749,30473,32654,40763,26570,31255,21305,30091,39661,24422,33181,33777,32920,24380,24517,30050,31558,36924,26727,23019,23195,32016,30334,35628,20469,24426,27161,27703,28418,29922,31080,34920,35413,35961,24287,25551,30149,31186,33495,37672,37618,33948,34541,39981,21697,24428,25996,27996,28693,36007,36051,38971,25935,29942,19981,20184,22496,22827,23142,23500,20904,24067,24220,24598,25206,25975,26023,26222,28014,29238,31526,33104,33178,33433,35676,36000,36070,36212,38428,38468,20398,25771,27494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,24489,24133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826,20998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,25991,32862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,38491,31859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,29255,31687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,37610,22275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,27597,31807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,24214,25265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,33804,34028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,20621,21078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,32033,32938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,22696,25778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,26412,32763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,21737,27097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,26411,27819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,39749,24051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,30496,21209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,21629,26126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,38754,40634,25720,27169,33538,22916,23391,27611,29467,30450,32178,32791,33945,20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,36016,21839,24758,32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,30690,21380,24441,32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,27833,30290,35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,25558,26377,26586,28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,37109,38596,34701,22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,23481,24248,25562,25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,32650,32768,33865,33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,27779,28020,32716,32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,32097,33853,37226,20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,23653,26446,26792,29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,31435,33870,25504,30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,40845,20406,24942,26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,28092,29471,30274,30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,32209,20523,21400,26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,22593,28057,32047,39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,33491,37428,38583,38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,24265,24651,24976,28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,27347,28809,36034,36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,28431,29282,29436,31725,32769,32894,34635,37070,20845,40595,31108,32907,37682,35542,20525,21644,35441,27498,36036,33031,24785,26528,40434,20121,20120,39952,35435,34241,34152,26880,28286,30871,33109,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,24332,19984,19989,20010,20017,20022,20028,20031,20034,20054,20056,20098,20101,35947,20106,33298,24333,20110,20126,20127,20128,20130,20144,20147,20150,20174,20173,20164,20166,20162,20183,20190,20205,20191,20215,20233,20314,20272,20315,20317,20311,20295,20342,20360,20367,20376,20347,20329,20336,20369,20335,20358,20374,20760,20436,20447,20430,20440,20443,20433,20442,20432,20452,20453,20506,20520,20500,20522,20517,20485,20252,20470,20513,20521,20524,20478,20463,20497,20486,20547,20551,26371,20565,20560,20552,20570,20566,20588,20600,20608,20634,20613,20660,20658,20681,20682,20659,20674,20694,20702,20709,20717,20707,20718,20729,20725,20745,20737,20738,20758,20757,20756,20762,20769,20794,20791,20796,20795,20799,20800,20818,20812,20820,20834,31480,20841,20842,20846,20864,20866,22232,20876,20873,20879,20881,20883,20885,20886,20900,20902,20898,20905,20906,20907,20915,20913,20914,20912,20917,20925,20933,20937,20955,20960,34389,20969,20973,20976,20981,20990,20996,21003,21012,21006,21031,21034,21038,21043,21049,21071,21060,21067,21068,21086,21076,21098,21108,21097,21107,21119,21117,21133,21140,21138,21105,21128,21137,36776,36775,21164,21165,21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,21237,21240,21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,21297,21299,21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,22808,21371,21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,38617,21471,26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,21564,21550,21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,21650,21627,21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,21704,21672,21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,21742,21741,21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,21816,21811,21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,21884,21891,21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,22007,22038,22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,22123,22116,22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,22198,22196,22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,22265,22272,22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,22310,22327,22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,22419,22432,22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,22499,22539,22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,22661,22713,22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,22745,22744,22757,22748,22756,22751,22767,22778,22777,22779,22780,22781,22786,22794,22800,22811,26790,22821,22828,22829,22834,22840,22846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889,22904,22913,22941,20318,20395,22947,22962,22982,23016,23004,22925,23001,23002,23077,23071,23057,23068,23049,23066,23104,23148,23113,23093,23094,23138,23146,23194,23228,23230,23243,23234,23229,23267,23255,23270,23273,23254,23290,23291,23308,23307,23318,23346,23248,23338,23350,23358,23363,23365,23360,23377,23381,23386,23387,23397,23401,23408,23411,23413,23416,25992,23418,23424,23427,23462,23480,23491,23495,23497,23508,23504,23524,23526,23522,23518,23525,23531,23536,23542,23539,23557,23559,23560,23565,23571,23584,23586,23592,23608,23609,23617,23622,23630,23635,23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700,22939,23723,23739,23734,23740,23735,23749,23742,23751,23769,23785,23805,23802,23789,23948,23786,23819,23829,23831,23900,23839,23835,23825,23828,23842,23834,23833,23832,23884,23890,23886,23883,23916,23923,23926,23943,23940,23938,23970,23965,23980,23982,23997,23952,23991,23996,24009,24013,24019,24018,24022,24027,24043,24050,24053,24075,24090,24089,24081,24091,24118,24119,24132,24131,24128,24142,24151,24148,24159,24162,24164,24135,24181,24182,24186,40636,24191,24224,24257,24258,24264,24272,24271,24278,24291,24285,24282,24283,24290,24289,24296,24297,24300,24305,24307,24304,24308,24312,24318,24323,24329,24413,24412,24331,24337,24342,24361,24365,24376,24385,24392,24396,24398,24367,24401,24406,24407,24409,24417,24429,24435,24439,24451,24450,24447,24458,24456,24465,24455,24478,24473,24472,24480,24488,24493,24508,24534,24571,24548,24568,24561,24541,24755,24575,24609,24672,24601,24592,24617,24590,24625,24603,24597,24619,24614,24591,24634,24666,24641,24682,24695,24671,24650,24646,24653,24675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730,24708,24731,24726,24727,24722,24743,24715,24801,24760,24800,24787,24756,24560,24765,24774,24757,24792,24909,24853,24838,24822,24823,24832,24820,24826,24835,24865,24827,24817,24845,24846,24903,24894,24872,24871,24906,24895,24892,24876,24884,24893,24898,24900,24947,24951,24920,24921,24922,24939,24948,24943,24933,24945,24927,24925,24915,24949,24985,24982,24967,25004,24980,24986,24970,24977,25003,25006,25036,25034,25033,25079,25032,25027,25030,25018,25035,32633,25037,25062,25059,25078,25082,25076,25087,25085,25084,25086,25088,25096,25097,25101,25100,25108,25115,25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187,25179,25184,25192,25212,25218,25225,25214,25234,25235,25238,25300,25219,25236,25303,25297,25275,25295,25343,25286,25812,25288,25308,25292,25290,25282,25287,25243,25289,25356,25326,25329,25383,25346,25352,25327,25333,25424,25406,25421,25628,25423,25494,25486,25472,25515,25462,25507,25487,25481,25503,25525,25451,25449,25534,25577,25536,25542,25571,25545,25554,25590,25540,25622,25652,25606,25619,25638,25654,25885,25623,25640,25615,25703,25711,25718,25678,25898,25749,25747,25765,25769,25736,25788,25818,25810,25797,25799,25787,25816,25794,25841,25831,33289,25824,25825,25260,25827,25839,25900,25846,25844,25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,25911,25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,25986,25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,26075,26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,26140,26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,26243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,26296,26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,26406,26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,26467,26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,26607,26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,26566,26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,26723,26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,26805,26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,26892,26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,26863,26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,27006,26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,27054,27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,27182,27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,27122,27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,27204,27148,27250,27190,27256,27207,27234,27225,27238,27208,27192,27170,27280,27277,27296,27268,27298,27299,27287,34327,27323,27331,27330,27320,27315,27308,27358,27345,27359,27306,27354,27370,27387,27397,34326,27386,27410,27414,39729,27423,27448,27447,30428,27449,39150,27463,27459,27465,27472,27481,27476,27483,27487,27489,27512,27513,27519,27520,27524,27523,27533,27544,27541,27550,27556,27562,27563,27567,27570,27569,27571,27575,27580,27590,27595,27603,27615,27628,27627,27635,27631,40638,27656,27667,27668,27675,27684,27683,27742,27733,27746,27754,27778,27789,27802,27777,27803,27774,27752,27763,27794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838,27834,27867,27887,27865,27882,27935,34893,27958,27947,27965,27960,27929,27957,27955,27922,27916,28003,28051,28004,27994,28025,27993,28046,28053,28644,28037,28153,28181,28170,28085,28103,28134,28088,28102,28140,28126,28108,28136,28114,28101,28154,28121,28132,28117,28138,28142,28205,28270,28206,28185,28274,28255,28222,28195,28267,28203,28278,28237,28191,28227,28218,28238,28196,28415,28189,28216,28290,28330,28312,28361,28343,28371,28349,28335,28356,28338,28372,28373,28303,28325,28354,28319,28481,28433,28748,28396,28408,28414,28479,28402,28465,28399,28466,28364,28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659,28525,28546,28540,28504,28558,28561,28610,28518,28595,28579,28577,28580,28601,28614,28586,28639,28629,28652,28628,28632,28657,28654,28635,28681,28683,28666,28689,28673,28687,28670,28699,28698,28532,28701,28696,28703,28720,28734,28722,28753,28771,28825,28818,28847,28913,28844,28856,28851,28846,28895,28875,28893,28889,28937,28925,28956,28953,29029,29013,29064,29030,29026,29004,29014,29036,29071,29179,29060,29077,29096,29100,29143,29113,29118,29138,29129,29140,29134,29152,29164,29159,29173,29180,29177,29183,29197,29200,29211,29224,29229,29228,29232,29234,29243,29244,29247,29248,29254,29259,29272,29300,29310,29314,29313,29319,29330,29334,29346,29351,29369,29362,29379,29382,29380,29390,29394,29410,29408,29409,29433,29431,20495,29463,29450,29468,29462,29469,29492,29487,29481,29477,29502,29518,29519,40664,29527,29546,29544,29552,29560,29557,29563,29562,29640,29619,29646,29627,29632,29669,29678,29662,29858,29701,29807,29733,29688,29746,29754,29781,29759,29791,29785,29761,29788,29801,29808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681,29920,29923,29927,29929,29934,29938,29936,29937,29944,29943,29956,29955,29957,29964,29966,29965,29973,29971,29982,29990,29996,30012,30020,30029,30026,30025,30043,30022,30042,30057,30052,30055,30059,30061,30072,30070,30086,30087,30068,30090,30089,30082,30100,30106,30109,30117,30115,30146,30131,30147,30133,30141,30136,30140,30129,30157,30154,30162,30169,30179,30174,30206,30207,30204,30209,30192,30202,30194,30195,30219,30221,30217,30239,30247,30240,30241,30242,30244,30260,30256,30267,30279,30280,30278,30300,30296,30305,30306,30312,30313,30314,30311,30316,30320,30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355,30361,30362,30384,30388,30392,30393,30394,30402,30413,30422,30418,30430,30433,30437,30439,30442,34351,30459,30472,30471,30468,30505,30500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,30591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,30653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,30752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,30929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,30983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,31098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,31207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,31294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,31383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,31434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,31490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,31492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,31645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,31692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,31763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805,31820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,31875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,31933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,31994,32006,32002,32028,32021,32010,32069,32075,32046,32050,32063,32053,32070,32115,32086,32078,32114,32104,32110,32079,32099,32147,32137,32091,32143,32125,32155,32186,32174,32163,32181,32199,32189,32171,32317,32162,32175,32220,32184,32159,32176,32216,32221,32228,32222,32251,32242,32225,32261,32266,32291,32289,32274,32305,32287,32265,32267,32290,32326,32358,32315,32309,32313,32323,32311,32306,32314,32359,32349,32342,32350,32345,32346,32377,32362,32361,32380,32379,32387,32213,32381,36782,32383,32392,32393,32396,32402,32400,32403,32404,32406,32398,32411,32412,32568,32570,32581,32588,32589,32590,32592,32593,32597,32596,32600,32607,32608,32616,32617,32615,32632,32642,32646,32643,32648,32647,32652,32660,32670,32669,32666,32675,32687,32690,32697,32686,32694,32696,35697,32709,32710,32714,32725,32724,32737,32742,32745,32755,32761,39132,32774,32772,32779,32786,32792,32793,32796,32801,32808,32831,32827,32842,32838,32850,32856,32858,32863,32866,32872,32883,32882,32880,32886,32889,32893,32895,32900,32902,32901,32923,32915,32922,32941,20880,32940,32987,32997,32985,32989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099,38539,33094,33086,33107,33105,33020,33137,33134,33125,33126,33140,33155,33160,33162,33152,33154,33184,33173,33188,33187,33119,33171,33193,33200,33205,33214,33208,33213,33216,33218,33210,33225,33229,33233,33241,33240,33224,33242,33247,33248,33255,33274,33275,33278,33281,33282,33285,33287,33290,33293,33296,33302,33321,33323,33336,33331,33344,33369,33368,33373,33370,33375,33380,33378,33384,33386,33387,33326,33393,33399,33400,33406,33421,33426,33451,33439,33467,33452,33505,33507,33503,33490,33524,33523,33530,33683,33539,33531,33529,33502,33542,33500,33545,33497,33589,33588,33558,33586,33585,33600,33593,33616,33605,33583,33579,33559,33560,33669,33690,33706,33695,33698,33686,33571,33678,33671,33674,33660,33717,33651,33653,33696,33673,33704,33780,33811,33771,33742,33789,33795,33752,33803,33729,33783,33799,33760,33778,33805,33826,33824,33725,33848,34054,33787,33901,33834,33852,34138,33924,33911,33899,33965,33902,33922,33897,33862,33836,33903,33913,33845,33994,33890,33977,33983,33951,34009,33997,33979,34010,34000,33985,33990,34006,33953,34081,34047,34036,34071,34072,34092,34079,34069,34068,34044,34112,34147,34136,34120,34113,34306,34123,34133,34176,34212,34184,34193,34186,34216,34157,34196,34203,34282,34183,34204,34167,34174,34192,34249,34234,34255,34233,34256,34261,34269,34277,34268,34297,34314,34323,34315,34302,34298,34310,34338,34330,34352,34367,34381,20053,34388,34399,34407,34417,34451,34467,34473,34474,34443,34444,34486,34479,34500,34502,34480,34505,34851,34475,34516,34526,34537,34540,34527,34523,34543,34578,34566,34568,34560,34563,34555,34577,34569,34573,34553,34570,34612,34623,34615,34619,34597,34601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649,34643,34659,34666,34821,34722,34719,34690,34735,34763,34749,34752,34768,38614,34731,34756,34739,34759,34758,34747,34799,34802,34784,34831,34829,34814,34806,34807,34830,34770,34833,34838,34837,34850,34849,34865,34870,34873,34855,34875,34884,34882,34898,34905,34910,34914,34923,34945,34942,34974,34933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,34992,35007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,35048,35058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,35131,35126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,35191,35198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,35258,35261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,35340,35355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,35426,35461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,35522,35546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,35596,35591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,35624,35649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,35700,35709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,35912,35916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,35981,35982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,36040,36033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,36109,36112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,36290,36286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,36348,36360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,36423,36425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,36476,36481,36487,36485,36484,36491,36490,36499,36497,36500,36505,36522,36513,36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,36604,36603,36587,36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,36620,36646,36659,36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,36700,36706,36707,36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,36842,36847,36999,36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,36875,36903,36918,36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,36950,36952,36958,36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,37001,37007,37032,37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,37170,37168,37194,37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,37282,37291,37295,37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,37343,37345,37339,37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,37463,37445,37449,37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,37466,37583,37561,37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,37690,37685,37691,37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,37846,37847,37864,37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,37891,37895,37904,37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,37986,37982,37994,37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,38274,38279,38282,38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,38329,38334,38346,28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,38370,38433,38440,38446,38447,38466,38476,38479,38475,38519,38492,38494,38493,38495,38502,38514,38508,38541,38552,38549,38551,38570,38567,38577,38578,38576,38580,38582,38584,38585,38606,38603,38601,38605,35149,38620,38669,38613,38649,38660,38662,38664,38675,38670,38673,38671,38678,38681,38692,38698,38704,38713,38717,38718,38724,38726,38728,38722,38729,38748,38752,38756,38758,38760,21202,38763,38769,38777,38789,38780,38785,38778,38790,38795,38799,38800,38812,38824,38822,38819,38835,38836,38851,38854,38856,38859,38876,38893,40783,38898,31455,38902,38901,38927,38924,38968,38948,38945,38967,38973,38982,38991,38987,39019,39023,39024,39025,39028,39027,39082,39087,39089,39094,39108,39107,39110,39145,39147,39171,39177,39186,39188,39192,39201,39197,39198,39204,39200,39212,39214,39229,39230,39234,39241,39237,39248,39243,39249,39250,39244,39253,39319,39320,39333,39341,39342,39356,39391,39387,39389,39384,39377,39405,39406,39409,39410,39419,39416,39425,39439,39429,39394,39449,39467,39479,39493,39490,39488,39491,39486,39509,39501,39515,39511,39519,39522,39525,39524,39529,39531,39530,39597,39600,39612,39616,39631,39633,39635,39636,39646,39647,39650,39651,39654,39663,39659,39662,39668,39665,39671,39675,39686,39704,39706,39711,39714,39715,39717,39719,39720,39721,39722,39726,39727,39730,39748,39747,39759,39757,39758,39761,39768,39796,39827,39811,39825,39830,39831,39839,39840,39848,39860,39872,39882,39865,39878,39887,39889,39890,39907,39906,39908,39892,39905,39994,39922,39921,39920,39957,39956,39945,39955,39948,39942,39944,39954,39946,39940,39982,39963,39973,39972,39969,39984,40007,39986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,40201,40200,40171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,40257,40255,40254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,40327,40363,40303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,40390,40399,40386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,40565,40569,40573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,40632,40618,40621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,40677,40680,40687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,40725,40737,40748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,40812,40810,40823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,29081,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,32394,35100,37704,37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,20220,20224,20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,20510,20550,20592,20546,20628,20724,20696,20810,20836,20893,20926,20972,21013,21148,21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,21642,21673,21759,21894,22361,22373,22444,22472,22471,64015,64016,22686,22706,22795,22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,23582,23718,23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,24372,24423,24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,24880,24984,25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,26158,26142,26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,26382,63785,26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,27106,27184,27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,27866,27908,28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,28220,28351,28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,28998,28999,64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,29667,29650,29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,30338,30364,30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,64024,64025,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,32092,32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,33864,33972,34131,34137,34155,64031,34224,64032,64033,34823,35061,35346,35383,35449,35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,64035,36559,64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,37358,37348,37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,37479,37543,37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,37665,37627,64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,37937,37957,37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,38737,38741,38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,39794,39823,39857,39867,39936,40304,40299,64045,40473,40657,null,null,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,65506,65508,65287,65282,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,65506,65508,65287,65282,12849,8470,8481,8757,32394,35100,37704,37512,34012,20425,28859,26161,26824,37625,26363,24389,20008,20193,20220,20224,20227,20281,20310,20370,20362,20378,20372,20429,20544,20514,20479,20510,20550,20592,20546,20628,20724,20696,20810,20836,20893,20926,20972,21013,21148,21158,21184,21211,21248,21255,21284,21362,21395,21426,21469,64014,21660,21642,21673,21759,21894,22361,22373,22444,22472,22471,64015,64016,22686,22706,22795,22867,22875,22877,22883,22948,22970,23382,23488,29999,23512,23532,23582,23718,23738,23797,23847,23891,64017,23874,23917,23992,23993,24016,24353,24372,24423,24503,24542,24669,24709,24714,24798,24789,24864,24818,24849,24887,24880,24984,25107,25254,25589,25696,25757,25806,25934,26112,26133,26171,26121,26158,26142,26148,26213,26199,26201,64018,26227,26265,26272,26290,26303,26362,26382,63785,26470,26555,26706,26560,26625,26692,26831,64019,26984,64020,27032,27106,27184,27243,27206,27251,27262,27362,27364,27606,27711,27740,27782,27759,27866,27908,28039,28015,28054,28076,28111,28152,28146,28156,28217,28252,28199,28220,28351,28552,28597,28661,28677,28679,28712,28805,28843,28943,28932,29020,28998,28999,64021,29121,29182,29361,29374,29476,64022,29559,29629,29641,29654,29667,29650,29703,29685,29734,29738,29737,29742,29794,29833,29855,29953,30063,30338,30364,30366,30363,30374,64023,30534,21167,30753,30798,30820,30842,31024,64024,64025,64026,31124,64027,31131,31441,31463,64028,31467,31646,64029,32072,32092,32183,32160,32214,32338,32583,32673,64030,33537,33634,33663,33735,33782,33864,33972,34131,34137,34155,64031,34224,64032,64033,34823,35061,35346,35383,35449,35495,35518,35551,64034,35574,35667,35711,36080,36084,36114,36214,64035,36559,64036,64037,36967,37086,64038,37141,37159,37338,37335,37342,37357,37358,37348,37349,37382,37392,37386,37434,37440,37436,37454,37465,37457,37433,37479,37543,37495,37496,37607,37591,37593,37584,64039,37589,37600,37587,37669,37665,37627,64040,37662,37631,37661,37634,37744,37719,37796,37830,37854,37880,37937,37957,37960,38290,63964,64041,38557,38575,38707,38715,38723,38733,38735,38737,38741,38999,39013,64042,64043,39207,64044,39326,39502,39641,39644,39797,39794,39823,39857,39867,39936,40304,40299,64045,40473,40657,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],\n  \"jis0212\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,728,711,184,729,733,175,731,730,65374,900,901,null,null,null,null,null,null,null,null,161,166,191,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,186,170,169,174,8482,164,8470,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,902,904,905,906,938,null,908,null,910,939,null,911,null,null,null,null,940,941,942,943,970,912,972,962,973,971,944,974,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1038,1039,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1118,1119,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,198,272,null,294,null,306,null,321,319,null,330,216,338,null,358,222,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,230,273,240,295,305,307,312,322,320,329,331,248,339,223,359,254,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,193,192,196,194,258,461,256,260,197,195,262,264,268,199,266,270,201,200,203,202,282,278,274,280,null,284,286,290,288,292,205,204,207,206,463,304,298,302,296,308,310,313,317,315,323,327,325,209,211,210,214,212,465,336,332,213,340,344,342,346,348,352,350,356,354,218,217,220,219,364,467,368,362,370,366,360,471,475,473,469,372,221,376,374,377,381,379,null,null,null,null,null,null,null,225,224,228,226,259,462,257,261,229,227,263,265,269,231,267,271,233,232,235,234,283,279,275,281,501,285,287,null,289,293,237,236,239,238,464,null,299,303,297,309,311,314,318,316,324,328,326,241,243,242,246,244,466,337,333,245,341,345,343,347,349,353,351,357,355,250,249,252,251,365,468,369,363,371,367,361,472,476,474,470,373,253,255,375,378,382,380,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,19970,19972,19973,19980,19986,19999,20003,20004,20008,20011,20014,20015,20016,20021,20032,20033,20036,20039,20049,20058,20060,20067,20072,20073,20084,20085,20089,20095,20109,20118,20119,20125,20143,20153,20163,20176,20186,20187,20192,20193,20194,20200,20207,20209,20211,20213,20221,20222,20223,20224,20226,20227,20232,20235,20236,20242,20245,20246,20247,20249,20270,20273,20320,20275,20277,20279,20281,20283,20286,20288,20290,20296,20297,20299,20300,20306,20308,20310,20312,20319,20323,20330,20332,20334,20337,20343,20344,20345,20346,20349,20350,20353,20354,20356,20357,20361,20362,20364,20366,20368,20370,20371,20372,20375,20377,20378,20382,20383,20402,20407,20409,20411,20412,20413,20414,20416,20417,20421,20422,20424,20425,20427,20428,20429,20431,20434,20444,20448,20450,20464,20466,20476,20477,20479,20480,20481,20484,20487,20490,20492,20494,20496,20499,20503,20504,20507,20508,20509,20510,20514,20519,20526,20528,20530,20531,20533,20544,20545,20546,20549,20550,20554,20556,20558,20561,20562,20563,20567,20569,20575,20576,20578,20579,20582,20583,20586,20589,20592,20593,20539,20609,20611,20612,20614,20618,20622,20623,20624,20626,20627,20628,20630,20635,20636,20638,20639,20640,20641,20642,20650,20655,20656,20665,20666,20669,20672,20675,20676,20679,20684,20686,20688,20691,20692,20696,20700,20701,20703,20706,20708,20710,20712,20713,20719,20721,20726,20730,20734,20739,20742,20743,20744,20747,20748,20749,20750,20722,20752,20759,20761,20763,20764,20765,20766,20771,20775,20776,20780,20781,20783,20785,20787,20788,20789,20792,20793,20802,20810,20815,20819,20821,20823,20824,20831,20836,20838,20862,20867,20868,20875,20878,20888,20893,20897,20899,20909,20920,20922,20924,20926,20927,20930,20936,20943,20945,20946,20947,20949,20952,20958,20962,20965,20974,20978,20979,20980,20983,20993,20994,20997,21010,21011,21013,21014,21016,21026,21032,21041,21042,21045,21052,21061,21065,21077,21079,21080,21082,21084,21087,21088,21089,21094,21102,21111,21112,21113,21120,21122,21125,21130,21132,21139,21141,21142,21143,21144,21146,21148,21156,21157,21158,21159,21167,21168,21174,21175,21176,21178,21179,21181,21184,21188,21190,21192,21196,21199,21201,21204,21206,21211,21212,21217,21221,21224,21225,21226,21228,21232,21233,21236,21238,21239,21248,21251,21258,21259,21260,21265,21267,21272,21275,21276,21278,21279,21285,21287,21288,21289,21291,21292,21293,21296,21298,21301,21308,21309,21310,21314,21324,21323,21337,21339,21345,21347,21349,21356,21357,21362,21369,21374,21379,21383,21384,21390,21395,21396,21401,21405,21409,21412,21418,21419,21423,21426,21428,21429,21431,21432,21434,21437,21440,21445,21455,21458,21459,21461,21466,21469,21470,21472,21478,21479,21493,21506,21523,21530,21537,21543,21544,21546,21551,21553,21556,21557,21571,21572,21575,21581,21583,21598,21602,21604,21606,21607,21609,21611,21613,21614,21620,21631,21633,21635,21637,21640,21641,21645,21649,21653,21654,21660,21663,21665,21670,21671,21673,21674,21677,21678,21681,21687,21689,21690,21691,21695,21702,21706,21709,21710,21728,21738,21740,21743,21750,21756,21758,21759,21760,21761,21765,21768,21769,21772,21773,21774,21781,21802,21803,21810,21813,21814,21819,21820,21821,21825,21831,21833,21834,21837,21840,21841,21848,21850,21851,21854,21856,21857,21860,21862,21887,21889,21890,21894,21896,21902,21903,21905,21906,21907,21908,21911,21923,21924,21933,21938,21951,21953,21955,21958,21961,21963,21964,21966,21969,21970,21971,21975,21976,21979,21982,21986,21993,22006,22015,22021,22024,22026,22029,22030,22031,22032,22033,22034,22041,22060,22064,22067,22069,22071,22073,22075,22076,22077,22079,22080,22081,22083,22084,22086,22089,22091,22093,22095,22100,22110,22112,22113,22114,22115,22118,22121,22125,22127,22129,22130,22133,22148,22149,22152,22155,22156,22165,22169,22170,22173,22174,22175,22182,22183,22184,22185,22187,22188,22189,22193,22195,22199,22206,22213,22217,22218,22219,22223,22224,22220,22221,22233,22236,22237,22239,22241,22244,22245,22246,22247,22248,22257,22251,22253,22262,22263,22273,22274,22279,22282,22284,22289,22293,22298,22299,22301,22304,22306,22307,22308,22309,22313,22314,22316,22318,22319,22323,22324,22333,22334,22335,22341,22342,22348,22349,22354,22370,22373,22375,22376,22379,22381,22382,22383,22384,22385,22387,22388,22389,22391,22393,22394,22395,22396,22398,22401,22403,22412,22420,22423,22425,22426,22428,22429,22430,22431,22433,22421,22439,22440,22441,22444,22456,22461,22471,22472,22476,22479,22485,22493,22494,22500,22502,22503,22505,22509,22512,22517,22518,22520,22525,22526,22527,22531,22532,22536,22537,22497,22540,22541,22555,22558,22559,22560,22566,22567,22573,22578,22585,22591,22601,22604,22605,22607,22608,22613,22623,22625,22628,22631,22632,22648,22652,22655,22656,22657,22663,22664,22665,22666,22668,22669,22671,22672,22676,22678,22685,22688,22689,22690,22694,22697,22705,22706,22724,22716,22722,22728,22733,22734,22736,22738,22740,22742,22746,22749,22753,22754,22761,22771,22789,22790,22795,22796,22802,22803,22804,34369,22813,22817,22819,22820,22824,22831,22832,22835,22837,22838,22847,22851,22854,22866,22867,22873,22875,22877,22878,22879,22881,22883,22891,22893,22895,22898,22901,22902,22905,22907,22908,22923,22924,22926,22930,22933,22935,22943,22948,22951,22957,22958,22959,22960,22963,22967,22970,22972,22977,22979,22980,22984,22986,22989,22994,23005,23006,23007,23011,23012,23015,23022,23023,23025,23026,23028,23031,23040,23044,23052,23053,23054,23058,23059,23070,23075,23076,23079,23080,23082,23085,23088,23108,23109,23111,23112,23116,23120,23125,23134,23139,23141,23143,23149,23159,23162,23163,23166,23179,23184,23187,23190,23193,23196,23198,23199,23200,23202,23207,23212,23217,23218,23219,23221,23224,23226,23227,23231,23236,23238,23240,23247,23258,23260,23264,23269,23274,23278,23285,23286,23293,23296,23297,23304,23319,23348,23321,23323,23325,23329,23333,23341,23352,23361,23371,23372,23378,23382,23390,23400,23406,23407,23420,23421,23422,23423,23425,23428,23430,23434,23438,23440,23441,23443,23444,23446,23464,23465,23468,23469,23471,23473,23474,23479,23482,23484,23488,23489,23501,23503,23510,23511,23512,23513,23514,23520,23535,23537,23540,23549,23564,23575,23582,23583,23587,23590,23593,23595,23596,23598,23600,23602,23605,23606,23641,23642,23644,23650,23651,23655,23656,23657,23661,23664,23668,23669,23674,23675,23676,23677,23687,23688,23690,23695,23698,23709,23711,23712,23714,23715,23718,23722,23730,23732,23733,23738,23753,23755,23762,23773,23767,23790,23793,23794,23796,23809,23814,23821,23826,23851,23843,23844,23846,23847,23857,23860,23865,23869,23871,23874,23875,23878,23880,23893,23889,23897,23882,23903,23904,23905,23906,23908,23914,23917,23920,23929,23930,23934,23935,23937,23939,23944,23946,23954,23955,23956,23957,23961,23963,23967,23968,23975,23979,23984,23988,23992,23993,24003,24007,24011,24016,24014,24024,24025,24032,24036,24041,24056,24057,24064,24071,24077,24082,24084,24085,24088,24095,24096,24110,24104,24114,24117,24126,24139,24144,24137,24145,24150,24152,24155,24156,24158,24168,24170,24171,24172,24173,24174,24176,24192,24203,24206,24226,24228,24229,24232,24234,24236,24241,24243,24253,24254,24255,24262,24268,24267,24270,24273,24274,24276,24277,24284,24286,24293,24299,24322,24326,24327,24328,24334,24345,24348,24349,24353,24354,24355,24356,24360,24363,24364,24366,24368,24372,24374,24379,24381,24383,24384,24388,24389,24391,24397,24400,24404,24408,24411,24416,24419,24420,24423,24431,24434,24436,24437,24440,24442,24445,24446,24457,24461,24463,24470,24476,24477,24482,24487,24491,24484,24492,24495,24496,24497,24504,24516,24519,24520,24521,24523,24528,24529,24530,24531,24532,24542,24545,24546,24552,24553,24554,24556,24557,24558,24559,24562,24563,24566,24570,24572,24583,24586,24589,24595,24596,24599,24600,24602,24607,24612,24621,24627,24629,24640,24647,24648,24649,24652,24657,24660,24662,24663,24669,24673,24679,24689,24702,24703,24706,24710,24712,24714,24718,24721,24723,24725,24728,24733,24734,24738,24740,24741,24744,24752,24753,24759,24763,24766,24770,24772,24776,24777,24778,24779,24782,24783,24788,24789,24793,24795,24797,24798,24802,24805,24818,24821,24824,24828,24829,24834,24839,24842,24844,24848,24849,24850,24851,24852,24854,24855,24857,24860,24862,24866,24874,24875,24880,24881,24885,24886,24887,24889,24897,24901,24902,24905,24926,24928,24940,24946,24952,24955,24956,24959,24960,24961,24963,24964,24971,24973,24978,24979,24983,24984,24988,24989,24991,24992,24997,25000,25002,25005,25016,25017,25020,25024,25025,25026,25038,25039,25045,25052,25053,25054,25055,25057,25058,25063,25065,25061,25068,25069,25071,25089,25091,25092,25095,25107,25109,25116,25120,25122,25123,25127,25129,25131,25145,25149,25154,25155,25156,25158,25164,25168,25169,25170,25172,25174,25178,25180,25188,25197,25199,25203,25210,25213,25229,25230,25231,25232,25254,25256,25267,25270,25271,25274,25278,25279,25284,25294,25301,25302,25306,25322,25330,25332,25340,25341,25347,25348,25354,25355,25357,25360,25363,25366,25368,25385,25386,25389,25397,25398,25401,25404,25409,25410,25411,25412,25414,25418,25419,25422,25426,25427,25428,25432,25435,25445,25446,25452,25453,25457,25460,25461,25464,25468,25469,25471,25474,25476,25479,25482,25488,25492,25493,25497,25498,25502,25508,25510,25517,25518,25519,25533,25537,25541,25544,25550,25553,25555,25556,25557,25564,25568,25573,25578,25580,25586,25587,25589,25592,25593,25609,25610,25616,25618,25620,25624,25630,25632,25634,25636,25637,25641,25642,25647,25648,25653,25661,25663,25675,25679,25681,25682,25683,25684,25690,25691,25692,25693,25695,25696,25697,25699,25709,25715,25716,25723,25725,25733,25735,25743,25744,25745,25752,25753,25755,25757,25759,25761,25763,25766,25768,25772,25779,25789,25790,25791,25796,25801,25802,25803,25804,25806,25808,25809,25813,25815,25828,25829,25833,25834,25837,25840,25845,25847,25851,25855,25857,25860,25864,25865,25866,25871,25875,25876,25878,25881,25883,25886,25887,25890,25894,25897,25902,25905,25914,25916,25917,25923,25927,25929,25936,25938,25940,25951,25952,25959,25963,25978,25981,25985,25989,25994,26002,26005,26008,26013,26016,26019,26022,26030,26034,26035,26036,26047,26050,26056,26057,26062,26064,26068,26070,26072,26079,26096,26098,26100,26101,26105,26110,26111,26112,26116,26120,26121,26125,26129,26130,26133,26134,26141,26142,26145,26146,26147,26148,26150,26153,26154,26155,26156,26158,26160,26161,26163,26169,26167,26176,26181,26182,26186,26188,26193,26190,26199,26200,26201,26203,26204,26208,26209,26363,26218,26219,26220,26238,26227,26229,26239,26231,26232,26233,26235,26240,26236,26251,26252,26253,26256,26258,26265,26266,26267,26268,26271,26272,26276,26285,26289,26290,26293,26299,26303,26304,26306,26307,26312,26316,26318,26319,26324,26331,26335,26344,26347,26348,26350,26362,26373,26375,26382,26387,26393,26396,26400,26402,26419,26430,26437,26439,26440,26444,26452,26453,26461,26470,26476,26478,26484,26486,26491,26497,26500,26510,26511,26513,26515,26518,26520,26521,26523,26544,26545,26546,26549,26555,26556,26557,26617,26560,26562,26563,26565,26568,26569,26578,26583,26585,26588,26593,26598,26608,26610,26614,26615,26706,26644,26649,26653,26655,26664,26663,26668,26669,26671,26672,26673,26675,26683,26687,26692,26693,26698,26700,26709,26711,26712,26715,26731,26734,26735,26736,26737,26738,26741,26745,26746,26747,26748,26754,26756,26758,26760,26774,26776,26778,26780,26785,26787,26789,26793,26794,26798,26802,26811,26821,26824,26828,26831,26832,26833,26835,26838,26841,26844,26845,26853,26856,26858,26859,26860,26861,26864,26865,26869,26870,26875,26876,26877,26886,26889,26890,26896,26897,26899,26902,26903,26929,26931,26933,26936,26939,26946,26949,26953,26958,26967,26971,26979,26980,26981,26982,26984,26985,26988,26992,26993,26994,27002,27003,27007,27008,27021,27026,27030,27032,27041,27045,27046,27048,27051,27053,27055,27063,27064,27066,27068,27077,27080,27089,27094,27095,27106,27109,27118,27119,27121,27123,27125,27134,27136,27137,27139,27151,27153,27157,27162,27165,27168,27172,27176,27184,27186,27188,27191,27195,27198,27199,27205,27206,27209,27210,27214,27216,27217,27218,27221,27222,27227,27236,27239,27242,27249,27251,27262,27265,27267,27270,27271,27273,27275,27281,27291,27293,27294,27295,27301,27307,27311,27312,27313,27316,27325,27326,27327,27334,27337,27336,27340,27344,27348,27349,27350,27356,27357,27364,27367,27372,27376,27377,27378,27388,27389,27394,27395,27398,27399,27401,27407,27408,27409,27415,27419,27422,27428,27432,27435,27436,27439,27445,27446,27451,27455,27462,27466,27469,27474,27478,27480,27485,27488,27495,27499,27502,27504,27509,27517,27518,27522,27525,27543,27547,27551,27552,27554,27555,27560,27561,27564,27565,27566,27568,27576,27577,27581,27582,27587,27588,27593,27596,27606,27610,27617,27619,27622,27623,27630,27633,27639,27641,27647,27650,27652,27653,27657,27661,27662,27664,27666,27673,27679,27686,27687,27688,27692,27694,27699,27701,27702,27706,27707,27711,27722,27723,27725,27727,27730,27732,27737,27739,27740,27755,27757,27759,27764,27766,27768,27769,27771,27781,27782,27783,27785,27796,27797,27799,27800,27804,27807,27824,27826,27828,27842,27846,27853,27855,27856,27857,27858,27860,27862,27866,27868,27872,27879,27881,27883,27884,27886,27890,27892,27908,27911,27914,27918,27919,27921,27923,27930,27942,27943,27944,27751,27950,27951,27953,27961,27964,27967,27991,27998,27999,28001,28005,28007,28015,28016,28028,28034,28039,28049,28050,28052,28054,28055,28056,28074,28076,28084,28087,28089,28093,28095,28100,28104,28106,28110,28111,28118,28123,28125,28127,28128,28130,28133,28137,28143,28144,28148,28150,28156,28160,28164,28190,28194,28199,28210,28214,28217,28219,28220,28228,28229,28232,28233,28235,28239,28241,28242,28243,28244,28247,28252,28253,28254,28258,28259,28264,28275,28283,28285,28301,28307,28313,28320,28327,28333,28334,28337,28339,28347,28351,28352,28353,28355,28359,28360,28362,28365,28366,28367,28395,28397,28398,28409,28411,28413,28420,28424,28426,28428,28429,28438,28440,28442,28443,28454,28457,28458,28463,28464,28467,28470,28475,28476,28461,28495,28497,28498,28499,28503,28505,28506,28509,28510,28513,28514,28520,28524,28541,28542,28547,28551,28552,28555,28556,28557,28560,28562,28563,28564,28566,28570,28575,28576,28581,28582,28583,28584,28590,28591,28592,28597,28598,28604,28613,28615,28616,28618,28634,28638,28648,28649,28656,28661,28665,28668,28669,28672,28677,28678,28679,28685,28695,28704,28707,28719,28724,28727,28729,28732,28739,28740,28744,28745,28746,28747,28756,28757,28765,28766,28750,28772,28773,28780,28782,28789,28790,28798,28801,28805,28806,28820,28821,28822,28823,28824,28827,28836,28843,28848,28849,28852,28855,28874,28881,28883,28884,28885,28886,28888,28892,28900,28922,28931,28932,28933,28934,28935,28939,28940,28943,28958,28960,28971,28973,28975,28976,28977,28984,28993,28997,28998,28999,29002,29003,29008,29010,29015,29018,29020,29022,29024,29032,29049,29056,29061,29063,29068,29074,29082,29083,29088,29090,29103,29104,29106,29107,29114,29119,29120,29121,29124,29131,29132,29139,29142,29145,29146,29148,29176,29182,29184,29191,29192,29193,29203,29207,29210,29213,29215,29220,29227,29231,29236,29240,29241,29249,29250,29251,29253,29262,29263,29264,29267,29269,29270,29274,29276,29278,29280,29283,29288,29291,29294,29295,29297,29303,29304,29307,29308,29311,29316,29321,29325,29326,29331,29339,29352,29357,29358,29361,29364,29374,29377,29383,29385,29388,29397,29398,29400,29407,29413,29427,29428,29434,29435,29438,29442,29444,29445,29447,29451,29453,29458,29459,29464,29465,29470,29474,29476,29479,29480,29484,29489,29490,29493,29498,29499,29501,29507,29517,29520,29522,29526,29528,29533,29534,29535,29536,29542,29543,29545,29547,29548,29550,29551,29553,29559,29561,29564,29568,29569,29571,29573,29574,29582,29584,29587,29589,29591,29592,29596,29598,29599,29600,29602,29605,29606,29610,29611,29613,29621,29623,29625,29628,29629,29631,29637,29638,29641,29643,29644,29647,29650,29651,29654,29657,29661,29665,29667,29670,29671,29673,29684,29685,29687,29689,29690,29691,29693,29695,29696,29697,29700,29703,29706,29713,29722,29723,29732,29734,29736,29737,29738,29739,29740,29741,29742,29743,29744,29745,29753,29760,29763,29764,29766,29767,29771,29773,29777,29778,29783,29789,29794,29798,29799,29800,29803,29805,29806,29809,29810,29824,29825,29829,29830,29831,29833,29839,29840,29841,29842,29848,29849,29850,29852,29855,29856,29857,29859,29862,29864,29865,29866,29867,29870,29871,29873,29874,29877,29881,29883,29887,29896,29897,29900,29904,29907,29912,29914,29915,29918,29919,29924,29928,29930,29931,29935,29940,29946,29947,29948,29951,29958,29970,29974,29975,29984,29985,29988,29991,29993,29994,29999,30006,30009,30013,30014,30015,30016,30019,30023,30024,30030,30032,30034,30039,30046,30047,30049,30063,30065,30073,30074,30075,30076,30077,30078,30081,30085,30096,30098,30099,30101,30105,30108,30114,30116,30132,30138,30143,30144,30145,30148,30150,30156,30158,30159,30167,30172,30175,30176,30177,30180,30183,30188,30190,30191,30193,30201,30208,30210,30211,30212,30215,30216,30218,30220,30223,30226,30227,30229,30230,30233,30235,30236,30237,30238,30243,30245,30246,30249,30253,30258,30259,30261,30264,30265,30266,30268,30282,30272,30273,30275,30276,30277,30281,30283,30293,30297,30303,30308,30309,30317,30318,30319,30321,30324,30337,30341,30348,30349,30357,30363,30364,30365,30367,30368,30370,30371,30372,30373,30374,30375,30376,30378,30381,30397,30401,30405,30409,30411,30412,30414,30420,30425,30432,30438,30440,30444,30448,30449,30454,30457,30460,30464,30470,30474,30478,30482,30484,30485,30487,30489,30490,30492,30498,30504,30509,30510,30511,30516,30517,30518,30521,30525,30526,30530,30533,30534,30538,30541,30542,30543,30546,30550,30551,30556,30558,30559,30560,30562,30564,30567,30570,30572,30576,30578,30579,30580,30586,30589,30592,30596,30604,30605,30612,30613,30614,30618,30623,30626,30631,30634,30638,30639,30641,30645,30654,30659,30665,30673,30674,30677,30681,30686,30687,30688,30692,30694,30698,30700,30704,30705,30708,30712,30715,30725,30726,30729,30733,30734,30737,30749,30753,30754,30755,30765,30766,30768,30773,30775,30787,30788,30791,30792,30796,30798,30802,30812,30814,30816,30817,30819,30820,30824,30826,30830,30842,30846,30858,30863,30868,30872,30881,30877,30878,30879,30884,30888,30892,30893,30896,30897,30898,30899,30907,30909,30911,30919,30920,30921,30924,30926,30930,30931,30933,30934,30948,30939,30943,30944,30945,30950,30954,30962,30963,30976,30966,30967,30970,30971,30975,30982,30988,30992,31002,31004,31006,31007,31008,31013,31015,31017,31021,31025,31028,31029,31035,31037,31039,31044,31045,31046,31050,31051,31055,31057,31060,31064,31067,31068,31079,31081,31083,31090,31097,31099,31100,31102,31115,31116,31121,31123,31124,31125,31126,31128,31131,31132,31137,31144,31145,31147,31151,31153,31156,31160,31163,31170,31172,31175,31176,31178,31183,31188,31190,31194,31197,31198,31200,31202,31205,31210,31211,31213,31217,31224,31228,31234,31235,31239,31241,31242,31244,31249,31253,31259,31262,31265,31271,31275,31277,31279,31280,31284,31285,31288,31289,31290,31300,31301,31303,31304,31308,31317,31318,31321,31324,31325,31327,31328,31333,31335,31338,31341,31349,31352,31358,31360,31362,31365,31366,31370,31371,31376,31377,31380,31390,31392,31395,31404,31411,31413,31417,31419,31420,31430,31433,31436,31438,31441,31451,31464,31465,31467,31468,31473,31476,31483,31485,31486,31495,31508,31519,31523,31527,31529,31530,31531,31533,31534,31535,31536,31537,31540,31549,31551,31552,31553,31559,31566,31573,31584,31588,31590,31593,31594,31597,31599,31602,31603,31607,31620,31625,31630,31632,31633,31638,31643,31646,31648,31653,31660,31663,31664,31666,31669,31670,31674,31675,31676,31677,31682,31685,31688,31690,31700,31702,31703,31705,31706,31707,31720,31722,31730,31732,31733,31736,31737,31738,31740,31742,31745,31746,31747,31748,31750,31753,31755,31756,31758,31759,31769,31771,31776,31781,31782,31784,31788,31793,31795,31796,31798,31801,31802,31814,31818,31829,31825,31826,31827,31833,31834,31835,31836,31837,31838,31841,31843,31847,31849,31853,31854,31856,31858,31865,31868,31869,31878,31879,31887,31892,31902,31904,31910,31920,31926,31927,31930,31931,31932,31935,31940,31943,31944,31945,31949,31951,31955,31956,31957,31959,31961,31962,31965,31974,31977,31979,31989,32003,32007,32008,32009,32015,32017,32018,32019,32022,32029,32030,32035,32038,32042,32045,32049,32060,32061,32062,32064,32065,32071,32072,32077,32081,32083,32087,32089,32090,32092,32093,32101,32103,32106,32112,32120,32122,32123,32127,32129,32130,32131,32133,32134,32136,32139,32140,32141,32145,32150,32151,32157,32158,32166,32167,32170,32179,32182,32183,32185,32194,32195,32196,32197,32198,32204,32205,32206,32215,32217,32256,32226,32229,32230,32234,32235,32237,32241,32245,32246,32249,32250,32264,32272,32273,32277,32279,32284,32285,32288,32295,32296,32300,32301,32303,32307,32310,32319,32324,32325,32327,32334,32336,32338,32344,32351,32353,32354,32357,32363,32366,32367,32371,32376,32382,32385,32390,32391,32394,32397,32401,32405,32408,32410,32413,32414,32572,32571,32573,32574,32575,32579,32580,32583,32591,32594,32595,32603,32604,32605,32609,32611,32612,32613,32614,32621,32625,32637,32638,32639,32640,32651,32653,32655,32656,32657,32662,32663,32668,32673,32674,32678,32682,32685,32692,32700,32703,32704,32707,32712,32718,32719,32731,32735,32739,32741,32744,32748,32750,32751,32754,32762,32765,32766,32767,32775,32776,32778,32781,32782,32783,32785,32787,32788,32790,32797,32798,32799,32800,32804,32806,32812,32814,32816,32820,32821,32823,32825,32826,32828,32830,32832,32836,32864,32868,32870,32877,32881,32885,32897,32904,32910,32924,32926,32934,32935,32939,32952,32953,32968,32973,32975,32978,32980,32981,32983,32984,32992,33005,33006,33008,33010,33011,33014,33017,33018,33022,33027,33035,33046,33047,33048,33052,33054,33056,33060,33063,33068,33072,33077,33082,33084,33093,33095,33098,33100,33106,33111,33120,33121,33127,33128,33129,33133,33135,33143,33153,33168,33156,33157,33158,33163,33166,33174,33176,33179,33182,33186,33198,33202,33204,33211,33227,33219,33221,33226,33230,33231,33237,33239,33243,33245,33246,33249,33252,33259,33260,33264,33265,33266,33269,33270,33272,33273,33277,33279,33280,33283,33295,33299,33300,33305,33306,33309,33313,33314,33320,33330,33332,33338,33347,33348,33349,33350,33355,33358,33359,33361,33366,33372,33376,33379,33383,33389,33396,33403,33405,33407,33408,33409,33411,33412,33415,33417,33418,33422,33425,33428,33430,33432,33434,33435,33440,33441,33443,33444,33447,33448,33449,33450,33454,33456,33458,33460,33463,33466,33468,33470,33471,33478,33488,33493,33498,33504,33506,33508,33512,33514,33517,33519,33526,33527,33533,33534,33536,33537,33543,33544,33546,33547,33620,33563,33565,33566,33567,33569,33570,33580,33581,33582,33584,33587,33591,33594,33596,33597,33602,33603,33604,33607,33613,33614,33617,33621,33622,33623,33648,33656,33661,33663,33664,33666,33668,33670,33677,33682,33684,33685,33688,33689,33691,33692,33693,33702,33703,33705,33708,33726,33727,33728,33735,33737,33743,33744,33745,33748,33757,33619,33768,33770,33782,33784,33785,33788,33793,33798,33802,33807,33809,33813,33817,33709,33839,33849,33861,33863,33864,33866,33869,33871,33873,33874,33878,33880,33881,33882,33884,33888,33892,33893,33895,33898,33904,33907,33908,33910,33912,33916,33917,33921,33925,33938,33939,33941,33950,33958,33960,33961,33962,33967,33969,33972,33978,33981,33982,33984,33986,33991,33992,33996,33999,34003,34012,34023,34026,34031,34032,34033,34034,34039,34098,34042,34043,34045,34050,34051,34055,34060,34062,34064,34076,34078,34082,34083,34084,34085,34087,34090,34091,34095,34099,34100,34102,34111,34118,34127,34128,34129,34130,34131,34134,34137,34140,34141,34142,34143,34144,34145,34146,34148,34155,34159,34169,34170,34171,34173,34175,34177,34181,34182,34185,34187,34188,34191,34195,34200,34205,34207,34208,34210,34213,34215,34228,34230,34231,34232,34236,34237,34238,34239,34242,34247,34250,34251,34254,34221,34264,34266,34271,34272,34278,34280,34285,34291,34294,34300,34303,34304,34308,34309,34317,34318,34320,34321,34322,34328,34329,34331,34334,34337,34343,34345,34358,34360,34362,34364,34365,34368,34370,34374,34386,34387,34390,34391,34392,34393,34397,34400,34401,34402,34403,34404,34409,34412,34415,34421,34422,34423,34426,34445,34449,34454,34456,34458,34460,34465,34470,34471,34472,34477,34481,34483,34484,34485,34487,34488,34489,34495,34496,34497,34499,34501,34513,34514,34517,34519,34522,34524,34528,34531,34533,34535,34440,34554,34556,34557,34564,34565,34567,34571,34574,34575,34576,34579,34580,34585,34590,34591,34593,34595,34600,34606,34607,34609,34610,34617,34618,34620,34621,34622,34624,34627,34629,34637,34648,34653,34657,34660,34661,34671,34673,34674,34683,34691,34692,34693,34694,34695,34696,34697,34699,34700,34704,34707,34709,34711,34712,34713,34718,34720,34723,34727,34732,34733,34734,34737,34741,34750,34751,34753,34760,34761,34762,34766,34773,34774,34777,34778,34780,34783,34786,34787,34788,34794,34795,34797,34801,34803,34808,34810,34815,34817,34819,34822,34825,34826,34827,34832,34841,34834,34835,34836,34840,34842,34843,34844,34846,34847,34856,34861,34862,34864,34866,34869,34874,34876,34881,34883,34885,34888,34889,34890,34891,34894,34897,34901,34902,34904,34906,34908,34911,34912,34916,34921,34929,34937,34939,34944,34968,34970,34971,34972,34975,34976,34984,34986,35002,35005,35006,35008,35018,35019,35020,35021,35022,35025,35026,35027,35035,35038,35047,35055,35056,35057,35061,35063,35073,35078,35085,35086,35087,35093,35094,35096,35097,35098,35100,35104,35110,35111,35112,35120,35121,35122,35125,35129,35130,35134,35136,35138,35141,35142,35145,35151,35154,35159,35162,35163,35164,35169,35170,35171,35179,35182,35184,35187,35189,35194,35195,35196,35197,35209,35213,35216,35220,35221,35227,35228,35231,35232,35237,35248,35252,35253,35254,35255,35260,35284,35285,35286,35287,35288,35301,35305,35307,35309,35313,35315,35318,35321,35325,35327,35332,35333,35335,35343,35345,35346,35348,35349,35358,35360,35362,35364,35366,35371,35372,35375,35381,35383,35389,35390,35392,35395,35397,35399,35401,35405,35406,35411,35414,35415,35416,35420,35421,35425,35429,35431,35445,35446,35447,35449,35450,35451,35454,35455,35456,35459,35462,35467,35471,35472,35474,35478,35479,35481,35487,35495,35497,35502,35503,35507,35510,35511,35515,35518,35523,35526,35528,35529,35530,35537,35539,35540,35541,35543,35549,35551,35564,35568,35572,35573,35574,35580,35583,35589,35590,35595,35601,35612,35614,35615,35594,35629,35632,35639,35644,35650,35651,35652,35653,35654,35656,35666,35667,35668,35673,35661,35678,35683,35693,35702,35704,35705,35708,35710,35713,35716,35717,35723,35725,35727,35732,35733,35740,35742,35743,35896,35897,35901,35902,35909,35911,35913,35915,35919,35921,35923,35924,35927,35928,35931,35933,35929,35939,35940,35942,35944,35945,35949,35955,35957,35958,35963,35966,35974,35975,35979,35984,35986,35987,35993,35995,35996,36004,36025,36026,36037,36038,36041,36043,36047,36054,36053,36057,36061,36065,36072,36076,36079,36080,36082,36085,36087,36088,36094,36095,36097,36099,36105,36114,36119,36123,36197,36201,36204,36206,36223,36226,36228,36232,36237,36240,36241,36245,36254,36255,36256,36262,36267,36268,36271,36274,36277,36279,36281,36283,36288,36293,36294,36295,36296,36298,36302,36305,36308,36309,36311,36313,36324,36325,36327,36332,36336,36284,36337,36338,36340,36349,36353,36356,36357,36358,36363,36369,36372,36374,36384,36385,36386,36387,36390,36391,36401,36403,36406,36407,36408,36409,36413,36416,36417,36427,36429,36430,36431,36436,36443,36444,36445,36446,36449,36450,36457,36460,36461,36463,36464,36465,36473,36474,36475,36482,36483,36489,36496,36498,36501,36506,36507,36509,36510,36514,36519,36521,36525,36526,36531,36533,36538,36539,36544,36545,36547,36548,36551,36559,36561,36564,36572,36584,36590,36592,36593,36599,36601,36602,36589,36608,36610,36615,36616,36623,36624,36630,36631,36632,36638,36640,36641,36643,36645,36647,36648,36652,36653,36654,36660,36661,36662,36663,36666,36672,36673,36675,36679,36687,36689,36690,36691,36692,36693,36696,36701,36702,36709,36765,36768,36769,36772,36773,36774,36789,36790,36792,36798,36800,36801,36806,36810,36811,36813,36816,36818,36819,36821,36832,36835,36836,36840,36846,36849,36853,36854,36859,36862,36866,36868,36872,36876,36888,36891,36904,36905,36911,36906,36908,36909,36915,36916,36919,36927,36931,36932,36940,36955,36957,36962,36966,36967,36972,36976,36980,36985,36997,37000,37003,37004,37006,37008,37013,37015,37016,37017,37019,37024,37025,37026,37029,37040,37042,37043,37044,37046,37053,37068,37054,37059,37060,37061,37063,37064,37077,37079,37080,37081,37084,37085,37087,37093,37074,37110,37099,37103,37104,37108,37118,37119,37120,37124,37125,37126,37128,37133,37136,37140,37142,37143,37144,37146,37148,37150,37152,37157,37154,37155,37159,37161,37166,37167,37169,37172,37174,37175,37177,37178,37180,37181,37187,37191,37192,37199,37203,37207,37209,37210,37211,37217,37220,37223,37229,37236,37241,37242,37243,37249,37251,37253,37254,37258,37262,37265,37267,37268,37269,37272,37278,37281,37286,37288,37292,37293,37294,37296,37297,37298,37299,37302,37307,37308,37309,37311,37314,37315,37317,37331,37332,37335,37337,37338,37342,37348,37349,37353,37354,37356,37357,37358,37359,37360,37361,37367,37369,37371,37373,37376,37377,37380,37381,37382,37383,37385,37386,37388,37392,37394,37395,37398,37400,37404,37405,37411,37412,37413,37414,37416,37422,37423,37424,37427,37429,37430,37432,37433,37434,37436,37438,37440,37442,37443,37446,37447,37450,37453,37454,37455,37457,37464,37465,37468,37469,37472,37473,37477,37479,37480,37481,37486,37487,37488,37493,37494,37495,37496,37497,37499,37500,37501,37503,37512,37513,37514,37517,37518,37522,37527,37529,37535,37536,37540,37541,37543,37544,37547,37551,37554,37558,37560,37562,37563,37564,37565,37567,37568,37569,37570,37571,37573,37574,37575,37576,37579,37580,37581,37582,37584,37587,37589,37591,37592,37593,37596,37597,37599,37600,37601,37603,37605,37607,37608,37612,37614,37616,37625,37627,37631,37632,37634,37640,37645,37649,37652,37653,37660,37661,37662,37663,37665,37668,37669,37671,37673,37674,37683,37684,37686,37687,37703,37704,37705,37712,37713,37714,37717,37719,37720,37722,37726,37732,37733,37735,37737,37738,37741,37743,37744,37745,37747,37748,37750,37754,37757,37759,37760,37761,37762,37768,37770,37771,37773,37775,37778,37781,37784,37787,37790,37793,37795,37796,37798,37800,37803,37812,37813,37814,37818,37801,37825,37828,37829,37830,37831,37833,37834,37835,37836,37837,37843,37849,37852,37854,37855,37858,37862,37863,37881,37879,37880,37882,37883,37885,37889,37890,37892,37896,37897,37901,37902,37903,37909,37910,37911,37919,37934,37935,37937,37938,37939,37940,37947,37951,37949,37955,37957,37960,37962,37964,37973,37977,37980,37983,37985,37987,37992,37995,37997,37998,37999,38001,38002,38020,38019,38264,38265,38270,38276,38280,38284,38285,38286,38301,38302,38303,38305,38310,38313,38315,38316,38324,38326,38330,38333,38335,38342,38344,38345,38347,38352,38353,38354,38355,38361,38362,38365,38366,38367,38368,38372,38374,38429,38430,38434,38436,38437,38438,38444,38449,38451,38455,38456,38457,38458,38460,38461,38465,38482,38484,38486,38487,38488,38497,38510,38516,38523,38524,38526,38527,38529,38530,38531,38532,38537,38545,38550,38554,38557,38559,38564,38565,38566,38569,38574,38575,38579,38586,38602,38610,23986,38616,38618,38621,38622,38623,38633,38639,38641,38650,38658,38659,38661,38665,38682,38683,38685,38689,38690,38691,38696,38705,38707,38721,38723,38730,38734,38735,38741,38743,38744,38746,38747,38755,38759,38762,38766,38771,38774,38775,38776,38779,38781,38783,38784,38793,38805,38806,38807,38809,38810,38814,38815,38818,38828,38830,38833,38834,38837,38838,38840,38841,38842,38844,38846,38847,38849,38852,38853,38855,38857,38858,38860,38861,38862,38864,38865,38868,38871,38872,38873,38877,38878,38880,38875,38881,38884,38895,38897,38900,38903,38904,38906,38919,38922,38937,38925,38926,38932,38934,38940,38942,38944,38947,38950,38955,38958,38959,38960,38962,38963,38965,38949,38974,38980,38983,38986,38993,38994,38995,38998,38999,39001,39002,39010,39011,39013,39014,39018,39020,39083,39085,39086,39088,39092,39095,39096,39098,39099,39103,39106,39109,39112,39116,39137,39139,39141,39142,39143,39146,39155,39158,39170,39175,39176,39185,39189,39190,39191,39194,39195,39196,39199,39202,39206,39207,39211,39217,39218,39219,39220,39221,39225,39226,39227,39228,39232,39233,39238,39239,39240,39245,39246,39252,39256,39257,39259,39260,39262,39263,39264,39323,39325,39327,39334,39344,39345,39346,39349,39353,39354,39357,39359,39363,39369,39379,39380,39385,39386,39388,39390,39399,39402,39403,39404,39408,39412,39413,39417,39421,39422,39426,39427,39428,39435,39436,39440,39441,39446,39454,39456,39458,39459,39460,39463,39469,39470,39475,39477,39478,39480,39495,39489,39492,39498,39499,39500,39502,39505,39508,39510,39517,39594,39596,39598,39599,39602,39604,39605,39606,39609,39611,39614,39615,39617,39619,39622,39624,39630,39632,39634,39637,39638,39639,39643,39644,39648,39652,39653,39655,39657,39660,39666,39667,39669,39673,39674,39677,39679,39680,39681,39682,39683,39684,39685,39688,39689,39691,39692,39693,39694,39696,39698,39702,39705,39707,39708,39712,39718,39723,39725,39731,39732,39733,39735,39737,39738,39741,39752,39755,39756,39765,39766,39767,39771,39774,39777,39779,39781,39782,39784,39786,39787,39788,39789,39790,39795,39797,39799,39800,39801,39807,39808,39812,39813,39814,39815,39817,39818,39819,39821,39823,39824,39828,39834,39837,39838,39846,39847,39849,39852,39856,39857,39858,39863,39864,39867,39868,39870,39871,39873,39879,39880,39886,39888,39895,39896,39901,39903,39909,39911,39914,39915,39919,39923,39927,39928,39929,39930,39933,39935,39936,39938,39947,39951,39953,39958,39960,39961,39962,39964,39966,39970,39971,39974,39975,39976,39977,39978,39985,39989,39990,39991,39997,40001,40003,40004,40005,40009,40010,40014,40015,40016,40019,40020,40022,40024,40027,40029,40030,40031,40035,40041,40042,40028,40043,40040,40046,40048,40050,40053,40055,40059,40166,40178,40183,40185,40203,40194,40209,40215,40216,40220,40221,40222,40239,40240,40242,40243,40244,40250,40252,40261,40253,40258,40259,40263,40266,40275,40276,40287,40291,40290,40293,40297,40298,40299,40304,40310,40311,40315,40316,40318,40323,40324,40326,40330,40333,40334,40338,40339,40341,40342,40343,40344,40353,40362,40364,40366,40369,40373,40377,40380,40383,40387,40391,40393,40394,40404,40405,40406,40407,40410,40414,40415,40416,40421,40423,40425,40427,40430,40432,40435,40436,40446,40458,40450,40455,40462,40464,40465,40466,40469,40470,40473,40476,40477,40570,40571,40572,40576,40578,40579,40580,40581,40583,40590,40591,40598,40600,40603,40606,40612,40616,40620,40622,40623,40624,40627,40628,40629,40646,40648,40651,40661,40671,40676,40679,40684,40685,40686,40688,40689,40690,40693,40696,40703,40706,40707,40713,40719,40720,40721,40722,40724,40726,40727,40729,40730,40731,40735,40738,40742,40746,40747,40751,40753,40754,40756,40759,40761,40762,40764,40765,40767,40769,40771,40772,40773,40774,40775,40787,40789,40790,40791,40792,40794,40797,40798,40808,40809,40813,40814,40815,40816,40817,40819,40821,40826,40829,40847,40848,40849,40850,40852,40854,40855,40862,40865,40866,40867,40869,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],\n  \"ibm866\":[1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,9617,9618,9619,9474,9508,9569,9570,9558,9557,9571,9553,9559,9565,9564,9563,9488,9492,9524,9516,9500,9472,9532,9566,9567,9562,9556,9577,9574,9568,9552,9580,9575,9576,9572,9573,9561,9560,9554,9555,9579,9578,9496,9484,9608,9604,9612,9616,9600,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1025,1105,1028,1108,1031,1111,1038,1118,176,8729,183,8730,8470,164,9632,160],\n  \"iso-8859-2\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,728,321,164,317,346,167,168,352,350,356,377,173,381,379,176,261,731,322,180,318,347,711,184,353,351,357,378,733,382,380,340,193,194,258,196,313,262,199,268,201,280,203,282,205,206,270,272,323,327,211,212,336,214,215,344,366,218,368,220,221,354,223,341,225,226,259,228,314,263,231,269,233,281,235,283,237,238,271,273,324,328,243,244,337,246,247,345,367,250,369,252,253,355,729],\n  \"iso-8859-3\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,294,728,163,164,null,292,167,168,304,350,286,308,173,null,379,176,295,178,179,180,181,293,183,184,305,351,287,309,189,null,380,192,193,194,null,196,266,264,199,200,201,202,203,204,205,206,207,null,209,210,211,212,288,214,215,284,217,218,219,220,364,348,223,224,225,226,null,228,267,265,231,232,233,234,235,236,237,238,239,null,241,242,243,244,289,246,247,285,249,250,251,252,365,349,729],\n  \"iso-8859-4\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,312,342,164,296,315,167,168,352,274,290,358,173,381,175,176,261,731,343,180,297,316,711,184,353,275,291,359,330,382,331,256,193,194,195,196,197,198,302,268,201,280,203,278,205,206,298,272,325,332,310,212,213,214,215,216,370,218,219,220,360,362,223,257,225,226,227,228,229,230,303,269,233,281,235,279,237,238,299,273,326,333,311,244,245,246,247,248,371,250,251,252,361,363,729],\n  \"iso-8859-5\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,173,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,8470,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,167,1118,1119],\n  \"iso-8859-6\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,null,null,null,164,null,null,null,null,null,null,null,1548,173,null,null,null,null,null,null,null,null,null,null,null,null,null,1563,null,null,null,1567,null,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,null,null,null,null,null,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,null,null,null,null,null,null,null,null,null,null,null,null,null],\n  \"iso-8859-7\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,8216,8217,163,8364,8367,166,167,168,169,890,171,172,173,null,8213,176,177,178,179,900,901,902,183,904,905,906,187,908,189,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,null,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,null],\n  \"iso-8859-8\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,null,162,163,164,165,166,167,168,169,215,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,247,187,188,189,190,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,8215,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,null,null,8206,8207,null],\n  \"iso-8859-10\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,274,290,298,296,310,167,315,272,352,358,381,173,362,330,176,261,275,291,299,297,311,183,316,273,353,359,382,8213,363,331,256,193,194,195,196,197,198,302,268,201,280,203,278,205,206,207,208,325,332,211,212,213,214,360,216,370,218,219,220,221,222,223,257,225,226,227,228,229,230,303,269,233,281,235,279,237,238,239,240,326,333,243,244,245,246,361,248,371,250,251,252,253,254,312],\n  \"iso-8859-13\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,8221,162,163,164,8222,166,167,216,169,342,171,172,173,174,198,176,177,178,179,8220,181,182,183,248,185,343,187,188,189,190,230,260,302,256,262,196,197,280,274,268,201,377,278,290,310,298,315,352,323,325,211,332,213,214,215,370,321,346,362,220,379,381,223,261,303,257,263,228,229,281,275,269,233,378,279,291,311,299,316,353,324,326,243,333,245,246,247,371,322,347,363,252,380,382,8217],\n  \"iso-8859-14\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,7682,7683,163,266,267,7690,167,7808,169,7810,7691,7922,173,174,376,7710,7711,288,289,7744,7745,182,7766,7809,7767,7811,7776,7923,7812,7813,7777,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,372,209,210,211,212,213,214,7786,216,217,218,219,220,221,374,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,373,241,242,243,244,245,246,7787,248,249,250,251,252,253,375,255],\n  \"iso-8859-15\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,8364,165,352,167,353,169,170,171,172,173,174,175,176,177,178,179,381,181,182,183,382,185,186,187,338,339,376,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255],\n  \"iso-8859-16\":[128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,260,261,321,8364,8222,352,167,353,169,536,171,377,173,378,379,176,177,268,322,381,8221,182,183,382,269,537,187,338,339,376,380,192,193,194,258,196,262,198,199,200,201,202,203,204,205,206,207,272,323,210,211,212,336,214,346,368,217,218,219,220,280,538,223,224,225,226,259,228,263,230,231,232,233,234,235,236,237,238,239,273,324,242,243,244,337,246,347,369,249,250,251,252,281,539,255],\n  \"koi8-r\":[9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9600,9604,9608,9612,9616,9617,9618,9619,8992,9632,8729,8730,8776,8804,8805,160,8993,176,178,183,247,9552,9553,9554,1105,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,1025,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,169,1102,1072,1073,1094,1076,1077,1092,1075,1093,1080,1081,1082,1083,1084,1085,1086,1087,1103,1088,1089,1090,1091,1078,1074,1100,1099,1079,1096,1101,1097,1095,1098,1070,1040,1041,1062,1044,1045,1060,1043,1061,1048,1049,1050,1051,1052,1053,1054,1055,1071,1056,1057,1058,1059,1046,1042,1068,1067,1047,1064,1069,1065,1063,1066],\n  \"koi8-u\":[9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9600,9604,9608,9612,9616,9617,9618,9619,8992,9632,8729,8730,8776,8804,8805,160,8993,176,178,183,247,9552,9553,9554,1105,1108,9556,1110,1111,9559,9560,9561,9562,9563,1169,1118,9566,9567,9568,9569,1025,1028,9571,1030,1031,9574,9575,9576,9577,9578,1168,1038,169,1102,1072,1073,1094,1076,1077,1092,1075,1093,1080,1081,1082,1083,1084,1085,1086,1087,1103,1088,1089,1090,1091,1078,1074,1100,1099,1079,1096,1101,1097,1095,1098,1070,1040,1041,1062,1044,1045,1060,1043,1061,1048,1049,1050,1051,1052,1053,1054,1055,1071,1056,1057,1058,1059,1046,1042,1068,1067,1047,1064,1069,1065,1063,1066],\n  \"macintosh\":[196,197,199,201,209,214,220,225,224,226,228,227,229,231,233,232,234,235,237,236,238,239,241,243,242,244,246,245,250,249,251,252,8224,176,162,163,167,8226,182,223,174,169,8482,180,168,8800,198,216,8734,177,8804,8805,165,181,8706,8721,8719,960,8747,170,186,937,230,248,191,161,172,8730,402,8776,8710,171,187,8230,160,192,195,213,338,339,8211,8212,8220,8221,8216,8217,247,9674,255,376,8260,8364,8249,8250,64257,64258,8225,183,8218,8222,8240,194,202,193,203,200,205,206,207,204,211,212,63743,210,218,219,217,305,710,732,175,728,729,730,184,733,731,711],\n  \"windows-874\":[8364,129,130,131,132,8230,134,135,136,137,138,139,140,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,152,153,154,155,156,157,158,159,160,3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,null,null,null,null,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,null,null,null,null],\n  \"windows-1250\":[8364,129,8218,131,8222,8230,8224,8225,136,8240,352,8249,346,356,381,377,144,8216,8217,8220,8221,8226,8211,8212,152,8482,353,8250,347,357,382,378,160,711,728,321,164,260,166,167,168,169,350,171,172,173,174,379,176,177,731,322,180,181,182,183,184,261,351,187,317,733,318,380,340,193,194,258,196,313,262,199,268,201,280,203,282,205,206,270,272,323,327,211,212,336,214,215,344,366,218,368,220,221,354,223,341,225,226,259,228,314,263,231,269,233,281,235,283,237,238,271,273,324,328,243,244,337,246,247,345,367,250,369,252,253,355,729],\n  \"windows-1251\":[1026,1027,8218,1107,8222,8230,8224,8225,8364,8240,1033,8249,1034,1036,1035,1039,1106,8216,8217,8220,8221,8226,8211,8212,152,8482,1113,8250,1114,1116,1115,1119,160,1038,1118,1032,164,1168,166,167,1025,169,1028,171,172,173,174,1031,176,177,1030,1110,1169,181,182,183,1105,8470,1108,187,1112,1029,1109,1111,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103],\n  \"windows-1252\":[8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255],\n  \"windows-1253\":[8364,129,8218,402,8222,8230,8224,8225,136,8240,138,8249,140,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,152,8482,154,8250,156,157,158,159,160,901,902,163,164,165,166,167,168,169,null,171,172,173,174,8213,176,177,178,179,900,181,182,183,904,905,906,187,908,189,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,null,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,null],\n  \"windows-1254\":[8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,158,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,286,209,210,211,212,213,214,215,216,217,218,219,220,304,350,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,287,241,242,243,244,245,246,247,248,249,250,251,252,305,351,255],\n  \"windows-1255\":[8364,129,8218,402,8222,8230,8224,8225,710,8240,138,8249,140,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,154,8250,156,157,158,159,160,161,162,163,8362,165,166,167,168,169,215,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,247,187,188,189,190,191,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1520,1521,1522,1523,1524,null,null,null,null,null,null,null,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512,1513,1514,null,null,8206,8207,null],\n  \"windows-1256\":[8364,1662,8218,402,8222,8230,8224,8225,710,8240,1657,8249,338,1670,1688,1672,1711,8216,8217,8220,8221,8226,8211,8212,1705,8482,1681,8250,339,8204,8205,1722,160,1548,162,163,164,165,166,167,168,169,1726,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,1563,187,188,189,190,1567,1729,1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587,1588,1589,1590,215,1591,1592,1593,1594,1600,1601,1602,1603,224,1604,226,1605,1606,1607,1608,231,232,233,234,235,1609,1610,238,239,1611,1612,1613,1614,244,1615,1616,247,1617,249,1618,251,252,8206,8207,1746],\n  \"windows-1257\":[8364,129,8218,131,8222,8230,8224,8225,136,8240,138,8249,140,168,711,184,144,8216,8217,8220,8221,8226,8211,8212,152,8482,154,8250,156,175,731,159,160,null,162,163,164,null,166,167,216,169,342,171,172,173,174,198,176,177,178,179,180,181,182,183,248,185,343,187,188,189,190,230,260,302,256,262,196,197,280,274,268,201,377,278,290,310,298,315,352,323,325,211,332,213,214,215,370,321,346,362,220,379,381,223,261,303,257,263,228,229,281,275,269,233,378,279,291,311,299,316,353,324,326,243,333,245,246,247,371,322,347,363,252,380,382,729],\n  \"windows-1258\":[8364,129,8218,402,8222,8230,8224,8225,710,8240,138,8249,338,141,142,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,154,8250,339,157,158,376,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,258,196,197,198,199,200,201,202,203,768,205,206,207,272,209,777,211,212,416,214,215,216,217,218,219,220,431,771,223,224,225,226,259,228,229,230,231,232,233,234,235,769,237,238,239,273,241,803,243,244,417,246,247,248,249,250,251,252,432,8363,255],\n  \"x-mac-cyrillic\":[1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,8224,176,1168,163,167,8226,182,1030,174,169,8482,1026,1106,8800,1027,1107,8734,177,8804,8805,1110,181,1169,1032,1028,1108,1031,1111,1033,1113,1034,1114,1112,1029,172,8730,402,8776,8710,171,187,8230,160,1035,1115,1036,1116,1109,8211,8212,8220,8221,8216,8217,247,8222,1038,1118,1039,1119,8470,1025,1105,1103,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,8364]\n};\n\n// For strict environments where `this` inside the global scope\n// is `undefined`, take a pure object instead\n}(this || {}));"
  },
  {
    "path": "lib/text-encoding/lib/encoding.js",
    "content": "// This is free and unencumbered software released into the public domain.\n// See LICENSE.md for more information.\n\n/**\n * @fileoverview Global |this| required for resolving indexes in node.\n * @suppress {globalThis}\n */\n(function(global) {\n  'use strict';\n\n  // If we're in node require encoding-indexes and attach it to the global.\n  if (typeof module !== \"undefined\" && module.exports &&\n    !global[\"encoding-indexes\"]) {\n    global[\"encoding-indexes\"] =\n      require(\"./encoding-indexes.js\")[\"encoding-indexes\"];\n  }\n\n  //\n  // Utilities\n  //\n\n  /**\n   * @param {number} a The number to test.\n   * @param {number} min The minimum value in the range, inclusive.\n   * @param {number} max The maximum value in the range, inclusive.\n   * @return {boolean} True if a >= min and a <= max.\n   */\n  function inRange(a, min, max) {\n    return min <= a && a <= max;\n  }\n\n  /**\n   * @param {!Array.<*>} array The array to check.\n   * @param {*} item The item to look for in the array.\n   * @return {boolean} True if the item appears in the array.\n   */\n  function includes(array, item) {\n    return array.indexOf(item) !== -1;\n  }\n\n  var floor = Math.floor;\n\n  /**\n   * @param {*} o\n   * @return {Object}\n   */\n  function ToDictionary(o) {\n    if (o === undefined) return {};\n    if (o === Object(o)) return o;\n    throw TypeError('Could not convert argument to dictionary');\n  }\n\n  /**\n   * @param {string} string Input string of UTF-16 code units.\n   * @return {!Array.<number>} Code points.\n   */\n  function stringToCodePoints(string) {\n    // https://heycam.github.io/webidl/#dfn-obtain-unicode\n\n    // 1. Let S be the DOMString value.\n    var s = String(string);\n\n    // 2. Let n be the length of S.\n    var n = s.length;\n\n    // 3. Initialize i to 0.\n    var i = 0;\n\n    // 4. Initialize U to be an empty sequence of Unicode characters.\n    var u = [];\n\n    // 5. While i < n:\n    while (i < n) {\n\n      // 1. Let c be the code unit in S at index i.\n      var c = s.charCodeAt(i);\n\n      // 2. Depending on the value of c:\n\n      // c < 0xD800 or c > 0xDFFF\n      if (c < 0xD800 || c > 0xDFFF) {\n        // Append to U the Unicode character with code point c.\n        u.push(c);\n      }\n\n      // 0xDC00 ≤ c ≤ 0xDFFF\n      else if (0xDC00 <= c && c <= 0xDFFF) {\n        // Append to U a U+FFFD REPLACEMENT CHARACTER.\n        u.push(0xFFFD);\n      }\n\n      // 0xD800 ≤ c ≤ 0xDBFF\n      else if (0xD800 <= c && c <= 0xDBFF) {\n        // 1. If i = n−1, then append to U a U+FFFD REPLACEMENT\n        // CHARACTER.\n        if (i === n - 1) {\n          u.push(0xFFFD);\n        }\n        // 2. Otherwise, i < n−1:\n        else {\n          // 1. Let d be the code unit in S at index i+1.\n          var d = s.charCodeAt(i + 1);\n\n          // 2. If 0xDC00 ≤ d ≤ 0xDFFF, then:\n          if (0xDC00 <= d && d <= 0xDFFF) {\n            // 1. Let a be c & 0x3FF.\n            var a = c & 0x3FF;\n\n            // 2. Let b be d & 0x3FF.\n            var b = d & 0x3FF;\n\n            // 3. Append to U the Unicode character with code point\n            // 2^16+2^10*a+b.\n            u.push(0x10000 + (a << 10) + b);\n\n            // 4. Set i to i+1.\n            i += 1;\n          }\n\n          // 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a\n          // U+FFFD REPLACEMENT CHARACTER.\n          else  {\n            u.push(0xFFFD);\n          }\n        }\n      }\n\n      // 3. Set i to i+1.\n      i += 1;\n    }\n\n    // 6. Return U.\n    return u;\n  }\n\n  /**\n   * @param {!Array.<number>} code_points Array of code points.\n   * @return {string} string String of UTF-16 code units.\n   */\n  function codePointsToString(code_points) {\n    var s = '';\n    for (var i = 0; i < code_points.length; ++i) {\n      var cp = code_points[i];\n      if (cp <= 0xFFFF) {\n        s += String.fromCharCode(cp);\n      } else {\n        cp -= 0x10000;\n        s += String.fromCharCode((cp >> 10) + 0xD800,\n                                 (cp & 0x3FF) + 0xDC00);\n      }\n    }\n    return s;\n  }\n\n\n  //\n  // Implementation of Encoding specification\n  // https://encoding.spec.whatwg.org/\n  //\n\n  //\n  // 4. Terminology\n  //\n\n  /**\n   * An ASCII byte is a byte in the range 0x00 to 0x7F, inclusive.\n   * @param {number} a The number to test.\n   * @return {boolean} True if a is in the range 0x00 to 0x7F, inclusive.\n   */\n  function isASCIIByte(a) {\n    return 0x00 <= a && a <= 0x7F;\n  }\n\n  /**\n   * An ASCII code point is a code point in the range U+0000 to\n   * U+007F, inclusive.\n   */\n  var isASCIICodePoint = isASCIIByte;\n\n\n  /**\n   * End-of-stream is a special token that signifies no more tokens\n   * are in the stream.\n   * @const\n   */ var end_of_stream = -1;\n\n  /**\n   * A stream represents an ordered sequence of tokens.\n   *\n   * @constructor\n   * @param {!(Array.<number>|Uint8Array)} tokens Array of tokens that provide\n   * the stream.\n   */\n  function Stream(tokens) {\n    /** @type {!Array.<number>} */\n    this.tokens = [].slice.call(tokens);\n    // Reversed as push/pop is more efficient than shift/unshift.\n    this.tokens.reverse();\n  }\n\n  Stream.prototype = {\n    /**\n     * @return {boolean} True if end-of-stream has been hit.\n     */\n    endOfStream: function() {\n      return !this.tokens.length;\n    },\n\n    /**\n     * When a token is read from a stream, the first token in the\n     * stream must be returned and subsequently removed, and\n     * end-of-stream must be returned otherwise.\n     *\n     * @return {number} Get the next token from the stream, or\n     * end_of_stream.\n     */\n     read: function() {\n      if (!this.tokens.length)\n        return end_of_stream;\n       return this.tokens.pop();\n     },\n\n    /**\n     * When one or more tokens are prepended to a stream, those tokens\n     * must be inserted, in given order, before the first token in the\n     * stream.\n     *\n     * @param {(number|!Array.<number>)} token The token(s) to prepend to the\n     * stream.\n     */\n    prepend: function(token) {\n      if (Array.isArray(token)) {\n        var tokens = /**@type {!Array.<number>}*/(token);\n        while (tokens.length)\n          this.tokens.push(tokens.pop());\n      } else {\n        this.tokens.push(token);\n      }\n    },\n\n    /**\n     * When one or more tokens are pushed to a stream, those tokens\n     * must be inserted, in given order, after the last token in the\n     * stream.\n     *\n     * @param {(number|!Array.<number>)} token The tokens(s) to push to the\n     * stream.\n     */\n    push: function(token) {\n      if (Array.isArray(token)) {\n        var tokens = /**@type {!Array.<number>}*/(token);\n        while (tokens.length)\n          this.tokens.unshift(tokens.shift());\n      } else {\n        this.tokens.unshift(token);\n      }\n    }\n  };\n\n  //\n  // 5. Encodings\n  //\n\n  // 5.1 Encoders and decoders\n\n  /** @const */\n  var finished = -1;\n\n  /**\n   * @param {boolean} fatal If true, decoding errors raise an exception.\n   * @param {number=} opt_code_point Override the standard fallback code point.\n   * @return {number} The code point to insert on a decoding error.\n   */\n  function decoderError(fatal, opt_code_point) {\n    if (fatal)\n      throw TypeError('Decoder error');\n    return opt_code_point || 0xFFFD;\n  }\n\n  /**\n   * @param {number} code_point The code point that could not be encoded.\n   * @return {number} Always throws, no value is actually returned.\n   */\n  function encoderError(code_point) {\n    throw TypeError('The code point ' + code_point + ' could not be encoded.');\n  }\n\n  /** @interface */\n  function Decoder() {}\n  Decoder.prototype = {\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point, or |finished|.\n     */\n    handler: function(stream, bite) {}\n  };\n\n  /** @interface */\n  function Encoder() {}\n  Encoder.prototype = {\n    /**\n     * @param {Stream} stream The stream of code points being encoded.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit, or |finished|.\n     */\n    handler: function(stream, code_point) {}\n  };\n\n  // 5.2 Names and labels\n\n  // TODO: Define @typedef for Encoding: {name:string,labels:Array.<string>}\n  // https://github.com/google/closure-compiler/issues/247\n\n  /**\n   * @param {string} label The encoding label.\n   * @return {?{name:string,labels:Array.<string>}}\n   */\n  function getEncoding(label) {\n    // 1. Remove any leading and trailing ASCII whitespace from label.\n    label = String(label).trim().toLowerCase();\n\n    // 2. If label is an ASCII case-insensitive match for any of the\n    // labels listed in the table below, return the corresponding\n    // encoding, and failure otherwise.\n    if (Object.prototype.hasOwnProperty.call(label_to_encoding, label)) {\n      return label_to_encoding[label];\n    }\n    return null;\n  }\n\n  /**\n   * Encodings table: https://encoding.spec.whatwg.org/encodings.json\n   * @const\n   * @type {!Array.<{\n   *          heading: string,\n   *          encodings: Array.<{name:string,labels:Array.<string>}>\n   *        }>}\n   */\n  var encodings = [\n    {\n      \"encodings\": [\n        {\n          \"labels\": [\n            \"unicode-1-1-utf-8\",\n            \"utf-8\",\n            \"utf8\"\n          ],\n          \"name\": \"UTF-8\"\n        }\n      ],\n      \"heading\": \"The Encoding\"\n    },\n    {\n      \"encodings\": [\n        {\n          \"labels\": [\n            \"866\",\n            \"cp866\",\n            \"csibm866\",\n            \"ibm866\"\n          ],\n          \"name\": \"IBM866\"\n        },\n        {\n          \"labels\": [\n            \"csisolatin2\",\n            \"iso-8859-2\",\n            \"iso-ir-101\",\n            \"iso8859-2\",\n            \"iso88592\",\n            \"iso_8859-2\",\n            \"iso_8859-2:1987\",\n            \"l2\",\n            \"latin2\"\n          ],\n          \"name\": \"ISO-8859-2\"\n        },\n        {\n          \"labels\": [\n            \"csisolatin3\",\n            \"iso-8859-3\",\n            \"iso-ir-109\",\n            \"iso8859-3\",\n            \"iso88593\",\n            \"iso_8859-3\",\n            \"iso_8859-3:1988\",\n            \"l3\",\n            \"latin3\"\n          ],\n          \"name\": \"ISO-8859-3\"\n        },\n        {\n          \"labels\": [\n            \"csisolatin4\",\n            \"iso-8859-4\",\n            \"iso-ir-110\",\n            \"iso8859-4\",\n            \"iso88594\",\n            \"iso_8859-4\",\n            \"iso_8859-4:1988\",\n            \"l4\",\n            \"latin4\"\n          ],\n          \"name\": \"ISO-8859-4\"\n        },\n        {\n          \"labels\": [\n            \"csisolatincyrillic\",\n            \"cyrillic\",\n            \"iso-8859-5\",\n            \"iso-ir-144\",\n            \"iso8859-5\",\n            \"iso88595\",\n            \"iso_8859-5\",\n            \"iso_8859-5:1988\"\n          ],\n          \"name\": \"ISO-8859-5\"\n        },\n        {\n          \"labels\": [\n            \"arabic\",\n            \"asmo-708\",\n            \"csiso88596e\",\n            \"csiso88596i\",\n            \"csisolatinarabic\",\n            \"ecma-114\",\n            \"iso-8859-6\",\n            \"iso-8859-6-e\",\n            \"iso-8859-6-i\",\n            \"iso-ir-127\",\n            \"iso8859-6\",\n            \"iso88596\",\n            \"iso_8859-6\",\n            \"iso_8859-6:1987\"\n          ],\n          \"name\": \"ISO-8859-6\"\n        },\n        {\n          \"labels\": [\n            \"csisolatingreek\",\n            \"ecma-118\",\n            \"elot_928\",\n            \"greek\",\n            \"greek8\",\n            \"iso-8859-7\",\n            \"iso-ir-126\",\n            \"iso8859-7\",\n            \"iso88597\",\n            \"iso_8859-7\",\n            \"iso_8859-7:1987\",\n            \"sun_eu_greek\"\n          ],\n          \"name\": \"ISO-8859-7\"\n        },\n        {\n          \"labels\": [\n            \"csiso88598e\",\n            \"csisolatinhebrew\",\n            \"hebrew\",\n            \"iso-8859-8\",\n            \"iso-8859-8-e\",\n            \"iso-ir-138\",\n            \"iso8859-8\",\n            \"iso88598\",\n            \"iso_8859-8\",\n            \"iso_8859-8:1988\",\n            \"visual\"\n          ],\n          \"name\": \"ISO-8859-8\"\n        },\n        {\n          \"labels\": [\n            \"csiso88598i\",\n            \"iso-8859-8-i\",\n            \"logical\"\n          ],\n          \"name\": \"ISO-8859-8-I\"\n        },\n        {\n          \"labels\": [\n            \"csisolatin6\",\n            \"iso-8859-10\",\n            \"iso-ir-157\",\n            \"iso8859-10\",\n            \"iso885910\",\n            \"l6\",\n            \"latin6\"\n          ],\n          \"name\": \"ISO-8859-10\"\n        },\n        {\n          \"labels\": [\n            \"iso-8859-13\",\n            \"iso8859-13\",\n            \"iso885913\"\n          ],\n          \"name\": \"ISO-8859-13\"\n        },\n        {\n          \"labels\": [\n            \"iso-8859-14\",\n            \"iso8859-14\",\n            \"iso885914\"\n          ],\n          \"name\": \"ISO-8859-14\"\n        },\n        {\n          \"labels\": [\n            \"csisolatin9\",\n            \"iso-8859-15\",\n            \"iso8859-15\",\n            \"iso885915\",\n            \"iso_8859-15\",\n            \"l9\"\n          ],\n          \"name\": \"ISO-8859-15\"\n        },\n        {\n          \"labels\": [\n            \"iso-8859-16\"\n          ],\n          \"name\": \"ISO-8859-16\"\n        },\n        {\n          \"labels\": [\n            \"cskoi8r\",\n            \"koi\",\n            \"koi8\",\n            \"koi8-r\",\n            \"koi8_r\"\n          ],\n          \"name\": \"KOI8-R\"\n        },\n        {\n          \"labels\": [\n            \"koi8-ru\",\n            \"koi8-u\"\n          ],\n          \"name\": \"KOI8-U\"\n        },\n        {\n          \"labels\": [\n            \"csmacintosh\",\n            \"mac\",\n            \"macintosh\",\n            \"x-mac-roman\"\n          ],\n          \"name\": \"macintosh\"\n        },\n        {\n          \"labels\": [\n            \"dos-874\",\n            \"iso-8859-11\",\n            \"iso8859-11\",\n            \"iso885911\",\n            \"tis-620\",\n            \"windows-874\"\n          ],\n          \"name\": \"windows-874\"\n        },\n        {\n          \"labels\": [\n            \"cp1250\",\n            \"windows-1250\",\n            \"x-cp1250\"\n          ],\n          \"name\": \"windows-1250\"\n        },\n        {\n          \"labels\": [\n            \"cp1251\",\n            \"windows-1251\",\n            \"x-cp1251\"\n          ],\n          \"name\": \"windows-1251\"\n        },\n        {\n          \"labels\": [\n            \"ansi_x3.4-1968\",\n            \"ascii\",\n            \"cp1252\",\n            \"cp819\",\n            \"csisolatin1\",\n            \"ibm819\",\n            \"iso-8859-1\",\n            \"iso-ir-100\",\n            \"iso8859-1\",\n            \"iso88591\",\n            \"iso_8859-1\",\n            \"iso_8859-1:1987\",\n            \"l1\",\n            \"latin1\",\n            \"us-ascii\",\n            \"windows-1252\",\n            \"x-cp1252\"\n          ],\n          \"name\": \"windows-1252\"\n        },\n        {\n          \"labels\": [\n            \"cp1253\",\n            \"windows-1253\",\n            \"x-cp1253\"\n          ],\n          \"name\": \"windows-1253\"\n        },\n        {\n          \"labels\": [\n            \"cp1254\",\n            \"csisolatin5\",\n            \"iso-8859-9\",\n            \"iso-ir-148\",\n            \"iso8859-9\",\n            \"iso88599\",\n            \"iso_8859-9\",\n            \"iso_8859-9:1989\",\n            \"l5\",\n            \"latin5\",\n            \"windows-1254\",\n            \"x-cp1254\"\n          ],\n          \"name\": \"windows-1254\"\n        },\n        {\n          \"labels\": [\n            \"cp1255\",\n            \"windows-1255\",\n            \"x-cp1255\"\n          ],\n          \"name\": \"windows-1255\"\n        },\n        {\n          \"labels\": [\n            \"cp1256\",\n            \"windows-1256\",\n            \"x-cp1256\"\n          ],\n          \"name\": \"windows-1256\"\n        },\n        {\n          \"labels\": [\n            \"cp1257\",\n            \"windows-1257\",\n            \"x-cp1257\"\n          ],\n          \"name\": \"windows-1257\"\n        },\n        {\n          \"labels\": [\n            \"cp1258\",\n            \"windows-1258\",\n            \"x-cp1258\"\n          ],\n          \"name\": \"windows-1258\"\n        },\n        {\n          \"labels\": [\n            \"x-mac-cyrillic\",\n            \"x-mac-ukrainian\"\n          ],\n          \"name\": \"x-mac-cyrillic\"\n        }\n      ],\n      \"heading\": \"Legacy single-byte encodings\"\n    },\n    {\n      \"encodings\": [\n        {\n          \"labels\": [\n            \"chinese\",\n            \"csgb2312\",\n            \"csiso58gb231280\",\n            \"gb2312\",\n            \"gb_2312\",\n            \"gb_2312-80\",\n            \"gbk\",\n            \"iso-ir-58\",\n            \"x-gbk\"\n          ],\n          \"name\": \"GBK\"\n        },\n        {\n          \"labels\": [\n            \"gb18030\"\n          ],\n          \"name\": \"gb18030\"\n        }\n      ],\n      \"heading\": \"Legacy multi-byte Chinese (simplified) encodings\"\n    },\n    {\n      \"encodings\": [\n        {\n          \"labels\": [\n            \"big5\",\n            \"big5-hkscs\",\n            \"cn-big5\",\n            \"csbig5\",\n            \"x-x-big5\"\n          ],\n          \"name\": \"Big5\"\n        }\n      ],\n      \"heading\": \"Legacy multi-byte Chinese (traditional) encodings\"\n    },\n    {\n      \"encodings\": [\n        {\n          \"labels\": [\n            \"cseucpkdfmtjapanese\",\n            \"euc-jp\",\n            \"x-euc-jp\"\n          ],\n          \"name\": \"EUC-JP\"\n        },\n        {\n          \"labels\": [\n            \"csiso2022jp\",\n            \"iso-2022-jp\"\n          ],\n          \"name\": \"ISO-2022-JP\"\n        },\n        {\n          \"labels\": [\n            \"csshiftjis\",\n            \"ms932\",\n            \"ms_kanji\",\n            \"shift-jis\",\n            \"shift_jis\",\n            \"sjis\",\n            \"windows-31j\",\n            \"x-sjis\"\n          ],\n          \"name\": \"Shift_JIS\"\n        }\n      ],\n      \"heading\": \"Legacy multi-byte Japanese encodings\"\n    },\n    {\n      \"encodings\": [\n        {\n          \"labels\": [\n            \"cseuckr\",\n            \"csksc56011987\",\n            \"euc-kr\",\n            \"iso-ir-149\",\n            \"korean\",\n            \"ks_c_5601-1987\",\n            \"ks_c_5601-1989\",\n            \"ksc5601\",\n            \"ksc_5601\",\n            \"windows-949\"\n          ],\n          \"name\": \"EUC-KR\"\n        }\n      ],\n      \"heading\": \"Legacy multi-byte Korean encodings\"\n    },\n    {\n      \"encodings\": [\n        {\n          \"labels\": [\n            \"csiso2022kr\",\n            \"hz-gb-2312\",\n            \"iso-2022-cn\",\n            \"iso-2022-cn-ext\",\n            \"iso-2022-kr\"\n          ],\n          \"name\": \"replacement\"\n        },\n        {\n          \"labels\": [\n            \"utf-16be\"\n          ],\n          \"name\": \"UTF-16BE\"\n        },\n        {\n          \"labels\": [\n            \"utf-16\",\n            \"utf-16le\"\n          ],\n          \"name\": \"UTF-16LE\"\n        },\n        {\n          \"labels\": [\n            \"x-user-defined\"\n          ],\n          \"name\": \"x-user-defined\"\n        }\n      ],\n      \"heading\": \"Legacy miscellaneous encodings\"\n    }\n  ];\n\n  // Label to encoding registry.\n  /** @type {Object.<string,{name:string,labels:Array.<string>}>} */\n  var label_to_encoding = {};\n  encodings.forEach(function(category) {\n    category.encodings.forEach(function(encoding) {\n      encoding.labels.forEach(function(label) {\n        label_to_encoding[label] = encoding;\n      });\n    });\n  });\n\n  // Registry of of encoder/decoder factories, by encoding name.\n  /** @type {Object.<string, function({fatal:boolean}): Encoder>} */\n  var encoders = {};\n  /** @type {Object.<string, function({fatal:boolean}): Decoder>} */\n  var decoders = {};\n\n  //\n  // 6. Indexes\n  //\n\n  /**\n   * @param {number} pointer The |pointer| to search for.\n   * @param {(!Array.<?number>|undefined)} index The |index| to search within.\n   * @return {?number} The code point corresponding to |pointer| in |index|,\n   *     or null if |code point| is not in |index|.\n   */\n  function indexCodePointFor(pointer, index) {\n    if (!index) return null;\n    return index[pointer] || null;\n  }\n\n  /**\n   * @param {number} code_point The |code point| to search for.\n   * @param {!Array.<?number>} index The |index| to search within.\n   * @return {?number} The first pointer corresponding to |code point| in\n   *     |index|, or null if |code point| is not in |index|.\n   */\n  function indexPointerFor(code_point, index) {\n    var pointer = index.indexOf(code_point);\n    return pointer === -1 ? null : pointer;\n  }\n\n  /**\n   * @param {string} name Name of the index.\n   * @return {(!Array.<number>|!Array.<Array.<number>>)}\n   *  */\n  function index(name) {\n    if (!('encoding-indexes' in global)) {\n      throw Error(\"Indexes missing.\" +\n                  \" Did you forget to include encoding-indexes.js first?\");\n    }\n    return global['encoding-indexes'][name];\n  }\n\n  /**\n   * @param {number} pointer The |pointer| to search for in the gb18030 index.\n   * @return {?number} The code point corresponding to |pointer| in |index|,\n   *     or null if |code point| is not in the gb18030 index.\n   */\n  function indexGB18030RangesCodePointFor(pointer) {\n    // 1. If pointer is greater than 39419 and less than 189000, or\n    // pointer is greater than 1237575, return null.\n    if ((pointer > 39419 && pointer < 189000) || (pointer > 1237575))\n      return null;\n\n    // 2. If pointer is 7457, return code point U+E7C7.\n    if (pointer === 7457) return 0xE7C7;\n\n    // 3. Let offset be the last pointer in index gb18030 ranges that\n    // is equal to or less than pointer and let code point offset be\n    // its corresponding code point.\n    var offset = 0;\n    var code_point_offset = 0;\n    var idx = index('gb18030-ranges');\n    var i;\n    for (i = 0; i < idx.length; ++i) {\n      /** @type {!Array.<number>} */\n      var entry = idx[i];\n      if (entry[0] <= pointer) {\n        offset = entry[0];\n        code_point_offset = entry[1];\n      } else {\n        break;\n      }\n    }\n\n    // 4. Return a code point whose value is code point offset +\n    // pointer − offset.\n    return code_point_offset + pointer - offset;\n  }\n\n  /**\n   * @param {number} code_point The |code point| to locate in the gb18030 index.\n   * @return {number} The first pointer corresponding to |code point| in the\n   *     gb18030 index.\n   */\n  function indexGB18030RangesPointerFor(code_point) {\n    // 1. If code point is U+E7C7, return pointer 7457.\n    if (code_point === 0xE7C7) return 7457;\n\n    // 2. Let offset be the last code point in index gb18030 ranges\n    // that is equal to or less than code point and let pointer offset\n    // be its corresponding pointer.\n    var offset = 0;\n    var pointer_offset = 0;\n    var idx = index('gb18030-ranges');\n    var i;\n    for (i = 0; i < idx.length; ++i) {\n      /** @type {!Array.<number>} */\n      var entry = idx[i];\n      if (entry[1] <= code_point) {\n        offset = entry[1];\n        pointer_offset = entry[0];\n      } else {\n        break;\n      }\n    }\n\n    // 3. Return a pointer whose value is pointer offset + code point\n    // − offset.\n    return pointer_offset + code_point - offset;\n  }\n\n  /**\n   * @param {number} code_point The |code_point| to search for in the Shift_JIS\n   *     index.\n   * @return {?number} The code point corresponding to |pointer| in |index|,\n   *     or null if |code point| is not in the Shift_JIS index.\n   */\n  function indexShiftJISPointerFor(code_point) {\n    // 1. Let index be index jis0208 excluding all entries whose\n    // pointer is in the range 8272 to 8835, inclusive.\n    shift_jis_index = shift_jis_index ||\n      index('jis0208').map(function(code_point, pointer) {\n        return inRange(pointer, 8272, 8835) ? null : code_point;\n      });\n    var index_ = shift_jis_index;\n\n    // 2. Return the index pointer for code point in index.\n    return index_.indexOf(code_point);\n  }\n  var shift_jis_index;\n\n  /**\n   * @param {number} code_point The |code_point| to search for in the big5\n   *     index.\n   * @return {?number} The code point corresponding to |pointer| in |index|,\n   *     or null if |code point| is not in the big5 index.\n   */\n  function indexBig5PointerFor(code_point) {\n    // 1. Let index be index Big5 excluding all entries whose pointer\n    big5_index_no_hkscs = big5_index_no_hkscs ||\n      index('big5').map(function(code_point, pointer) {\n        return (pointer < (0xA1 - 0x81) * 157) ? null : code_point;\n      });\n    var index_ = big5_index_no_hkscs;\n\n    // 2. If code point is U+2550, U+255E, U+2561, U+256A, U+5341, or\n    // U+5345, return the last pointer corresponding to code point in\n    // index.\n    if (code_point === 0x2550 || code_point === 0x255E ||\n        code_point === 0x2561 || code_point === 0x256A ||\n        code_point === 0x5341 || code_point === 0x5345) {\n      return index_.lastIndexOf(code_point);\n    }\n\n    // 3. Return the index pointer for code point in index.\n    return indexPointerFor(code_point, index_);\n  }\n  var big5_index_no_hkscs;\n\n  //\n  // 8. API\n  //\n\n  /** @const */ var DEFAULT_ENCODING = 'utf-8';\n\n  // 8.1 Interface TextDecoder\n\n  /**\n   * @constructor\n   * @param {string=} label The label of the encoding;\n   *     defaults to 'utf-8'.\n   * @param {Object=} options\n   */\n  function TextDecoder(label, options) {\n    // Web IDL conventions\n    if (!(this instanceof TextDecoder))\n      throw TypeError('Called as a function. Did you forget \\'new\\'?');\n    label = label !== undefined ? String(label) : DEFAULT_ENCODING;\n    options = ToDictionary(options);\n\n    // A TextDecoder object has an associated encoding, decoder,\n    // stream, ignore BOM flag (initially unset), BOM seen flag\n    // (initially unset), error mode (initially replacement), and do\n    // not flush flag (initially unset).\n\n    /** @private */\n    this._encoding = null;\n    /** @private @type {?Decoder} */\n    this._decoder = null;\n    /** @private @type {boolean} */\n    this._ignoreBOM = false;\n    /** @private @type {boolean} */\n    this._BOMseen = false;\n    /** @private @type {string} */\n    this._error_mode = 'replacement';\n    /** @private @type {boolean} */\n    this._do_not_flush = false;\n\n\n    // 1. Let encoding be the result of getting an encoding from\n    // label.\n    var encoding = getEncoding(label);\n\n    // 2. If encoding is failure or replacement, throw a RangeError.\n    if (encoding === null || encoding.name === 'replacement')\n      throw RangeError('Unknown encoding: ' + label);\n    if (!decoders[encoding.name]) {\n      throw Error('Decoder not present.' +\n                  ' Did you forget to include encoding-indexes.js first?');\n    }\n\n    // 3. Let dec be a new TextDecoder object.\n    var dec = this;\n\n    // 4. Set dec's encoding to encoding.\n    dec._encoding = encoding;\n\n    // 5. If options's fatal member is true, set dec's error mode to\n    // fatal.\n    if (Boolean(options['fatal']))\n      dec._error_mode = 'fatal';\n\n    // 6. If options's ignoreBOM member is true, set dec's ignore BOM\n    // flag.\n    if (Boolean(options['ignoreBOM']))\n      dec._ignoreBOM = true;\n\n    // For pre-ES5 runtimes:\n    if (!Object.defineProperty) {\n      this.encoding = dec._encoding.name.toLowerCase();\n      this.fatal = dec._error_mode === 'fatal';\n      this.ignoreBOM = dec._ignoreBOM;\n    }\n\n    // 7. Return dec.\n    return dec;\n  }\n\n  if (Object.defineProperty) {\n    // The encoding attribute's getter must return encoding's name.\n    Object.defineProperty(TextDecoder.prototype, 'encoding', {\n      /** @this {TextDecoder} */\n      get: function() { return this._encoding.name.toLowerCase(); }\n    });\n\n    // The fatal attribute's getter must return true if error mode\n    // is fatal, and false otherwise.\n    Object.defineProperty(TextDecoder.prototype, 'fatal', {\n      /** @this {TextDecoder} */\n      get: function() { return this._error_mode === 'fatal'; }\n    });\n\n    // The ignoreBOM attribute's getter must return true if ignore\n    // BOM flag is set, and false otherwise.\n    Object.defineProperty(TextDecoder.prototype, 'ignoreBOM', {\n      /** @this {TextDecoder} */\n      get: function() { return this._ignoreBOM; }\n    });\n  }\n\n  /**\n   * @param {BufferSource=} input The buffer of bytes to decode.\n   * @param {Object=} options\n   * @return {string} The decoded string.\n   */\n  TextDecoder.prototype.decode = function decode(input, options) {\n    var bytes;\n    if (typeof input === 'object' && input instanceof ArrayBuffer) {\n      bytes = new Uint8Array(input);\n    } else if (typeof input === 'object' && 'buffer' in input &&\n               input.buffer instanceof ArrayBuffer) {\n      bytes = new Uint8Array(input.buffer,\n                             input.byteOffset,\n                             input.byteLength);\n    } else {\n      bytes = new Uint8Array(0);\n    }\n\n    options = ToDictionary(options);\n\n    // 1. If the do not flush flag is unset, set decoder to a new\n    // encoding's decoder, set stream to a new stream, and unset the\n    // BOM seen flag.\n    if (!this._do_not_flush) {\n      this._decoder = decoders[this._encoding.name]({\n        fatal: this._error_mode === 'fatal'});\n      this._BOMseen = false;\n    }\n\n    // 2. If options's stream is true, set the do not flush flag, and\n    // unset the do not flush flag otherwise.\n    this._do_not_flush = Boolean(options['stream']);\n\n    // 3. If input is given, push a copy of input to stream.\n    // TODO: Align with spec algorithm - maintain stream on instance.\n    var input_stream = new Stream(bytes);\n\n    // 4. Let output be a new stream.\n    var output = [];\n\n    /** @type {?(number|!Array.<number>)} */\n    var result;\n\n    // 5. While true:\n    while (true) {\n      // 1. Let token be the result of reading from stream.\n      var token = input_stream.read();\n\n      // 2. If token is end-of-stream and the do not flush flag is\n      // set, return output, serialized.\n      // TODO: Align with spec algorithm.\n      if (token === end_of_stream)\n        break;\n\n      // 3. Otherwise, run these subsubsteps:\n\n      // 1. Let result be the result of processing token for decoder,\n      // stream, output, and error mode.\n      result = this._decoder.handler(input_stream, token);\n\n      // 2. If result is finished, return output, serialized.\n      if (result === finished)\n        break;\n\n      if (result !== null) {\n        if (Array.isArray(result))\n          output.push.apply(output, /**@type {!Array.<number>}*/(result));\n        else\n          output.push(result);\n      }\n\n      // 3. Otherwise, if result is error, throw a TypeError.\n      // (Thrown in handler)\n\n      // 4. Otherwise, do nothing.\n    }\n    // TODO: Align with spec algorithm.\n    if (!this._do_not_flush) {\n      do {\n        result = this._decoder.handler(input_stream, input_stream.read());\n        if (result === finished)\n          break;\n        if (result === null)\n          continue;\n        if (Array.isArray(result))\n          output.push.apply(output, /**@type {!Array.<number>}*/(result));\n        else\n          output.push(result);\n      } while (!input_stream.endOfStream());\n      this._decoder = null;\n    }\n\n    // A TextDecoder object also has an associated serialize stream\n    // algorithm...\n    /**\n     * @param {!Array.<number>} stream\n     * @return {string}\n     * @this {TextDecoder}\n     */\n    function serializeStream(stream) {\n      // 1. Let token be the result of reading from stream.\n      // (Done in-place on array, rather than as a stream)\n\n      // 2. If encoding is UTF-8, UTF-16BE, or UTF-16LE, and ignore\n      // BOM flag and BOM seen flag are unset, run these subsubsteps:\n      if (includes(['UTF-8', 'UTF-16LE', 'UTF-16BE'], this._encoding.name) &&\n          !this._ignoreBOM && !this._BOMseen) {\n        if (stream.length > 0 && stream[0] === 0xFEFF) {\n          // 1. If token is U+FEFF, set BOM seen flag.\n          this._BOMseen = true;\n          stream.shift();\n        } else if (stream.length > 0) {\n          // 2. Otherwise, if token is not end-of-stream, set BOM seen\n          // flag and append token to stream.\n          this._BOMseen = true;\n        } else {\n          // 3. Otherwise, if token is not end-of-stream, append token\n          // to output.\n          // (no-op)\n        }\n      }\n      // 4. Otherwise, return output.\n      return codePointsToString(stream);\n    }\n\n    return serializeStream.call(this, output);\n  };\n\n  // 8.2 Interface TextEncoder\n\n  /**\n   * @constructor\n   * @param {string=} label The label of the encoding. NONSTANDARD.\n   * @param {Object=} options NONSTANDARD.\n   */\n  function TextEncoder(label, options) {\n    // Web IDL conventions\n    if (!(this instanceof TextEncoder))\n      throw TypeError('Called as a function. Did you forget \\'new\\'?');\n    options = ToDictionary(options);\n\n    // A TextEncoder object has an associated encoding and encoder.\n\n    /** @private */\n    this._encoding = null;\n    /** @private @type {?Encoder} */\n    this._encoder = null;\n\n    // Non-standard\n    /** @private @type {boolean} */\n    this._do_not_flush = false;\n    /** @private @type {string} */\n    this._fatal = Boolean(options['fatal']) ? 'fatal' : 'replacement';\n\n    // 1. Let enc be a new TextEncoder object.\n    var enc = this;\n\n    // 2. Set enc's encoding to UTF-8's encoder.\n    if (Boolean(options['NONSTANDARD_allowLegacyEncoding'])) {\n      // NONSTANDARD behavior.\n      label = label !== undefined ? String(label) : DEFAULT_ENCODING;\n      var encoding = getEncoding(label);\n      if (encoding === null || encoding.name === 'replacement')\n        throw RangeError('Unknown encoding: ' + label);\n      if (!encoders[encoding.name]) {\n        throw Error('Encoder not present.' +\n                    ' Did you forget to include encoding-indexes.js first?');\n      }\n      enc._encoding = encoding;\n    } else {\n      // Standard behavior.\n      enc._encoding = getEncoding('utf-8');\n\n      if (label !== undefined && 'console' in global) {\n        console.warn('TextEncoder constructor called with encoding label, '\n                     + 'which is ignored.');\n      }\n    }\n\n    // For pre-ES5 runtimes:\n    if (!Object.defineProperty)\n      this.encoding = enc._encoding.name.toLowerCase();\n\n    // 3. Return enc.\n    return enc;\n  }\n\n  if (Object.defineProperty) {\n    // The encoding attribute's getter must return encoding's name.\n    Object.defineProperty(TextEncoder.prototype, 'encoding', {\n      /** @this {TextEncoder} */\n      get: function() { return this._encoding.name.toLowerCase(); }\n    });\n  }\n\n  /**\n   * @param {string=} opt_string The string to encode.\n   * @param {Object=} options\n   * @return {!Uint8Array} Encoded bytes, as a Uint8Array.\n   */\n  TextEncoder.prototype.encode = function encode(opt_string, options) {\n    opt_string = opt_string === undefined ? '' : String(opt_string);\n    options = ToDictionary(options);\n\n    // NOTE: This option is nonstandard. None of the encodings\n    // permitted for encoding (i.e. UTF-8, UTF-16) are stateful when\n    // the input is a USVString so streaming is not necessary.\n    if (!this._do_not_flush)\n      this._encoder = encoders[this._encoding.name]({\n        fatal: this._fatal === 'fatal'});\n    this._do_not_flush = Boolean(options['stream']);\n\n    // 1. Convert input to a stream.\n    var input = new Stream(stringToCodePoints(opt_string));\n\n    // 2. Let output be a new stream\n    var output = [];\n\n    /** @type {?(number|!Array.<number>)} */\n    var result;\n    // 3. While true, run these substeps:\n    while (true) {\n      // 1. Let token be the result of reading from input.\n      var token = input.read();\n      if (token === end_of_stream)\n        break;\n      // 2. Let result be the result of processing token for encoder,\n      // input, output.\n      result = this._encoder.handler(input, token);\n      if (result === finished)\n        break;\n      if (Array.isArray(result))\n        output.push.apply(output, /**@type {!Array.<number>}*/(result));\n      else\n        output.push(result);\n    }\n    // TODO: Align with spec algorithm.\n    if (!this._do_not_flush) {\n      while (true) {\n        result = this._encoder.handler(input, input.read());\n        if (result === finished)\n          break;\n        if (Array.isArray(result))\n          output.push.apply(output, /**@type {!Array.<number>}*/(result));\n        else\n          output.push(result);\n      }\n      this._encoder = null;\n    }\n    // 3. If result is finished, convert output into a byte sequence,\n    // and then return a Uint8Array object wrapping an ArrayBuffer\n    // containing output.\n    return new Uint8Array(output);\n  };\n\n\n  //\n  // 9. The encoding\n  //\n\n  // 9.1 utf-8\n\n  // 9.1.1 utf-8 decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function UTF8Decoder(options) {\n    var fatal = options.fatal;\n\n    // utf-8's decoder's has an associated utf-8 code point, utf-8\n    // bytes seen, and utf-8 bytes needed (all initially 0), a utf-8\n    // lower boundary (initially 0x80), and a utf-8 upper boundary\n    // (initially 0xBF).\n    var /** @type {number} */ utf8_code_point = 0,\n        /** @type {number} */ utf8_bytes_seen = 0,\n        /** @type {number} */ utf8_bytes_needed = 0,\n        /** @type {number} */ utf8_lower_boundary = 0x80,\n        /** @type {number} */ utf8_upper_boundary = 0xBF;\n\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream and utf-8 bytes needed is not 0,\n      // set utf-8 bytes needed to 0 and return error.\n      if (bite === end_of_stream && utf8_bytes_needed !== 0) {\n        utf8_bytes_needed = 0;\n        return decoderError(fatal);\n      }\n\n      // 2. If byte is end-of-stream, return finished.\n      if (bite === end_of_stream)\n        return finished;\n\n      // 3. If utf-8 bytes needed is 0, based on byte:\n      if (utf8_bytes_needed === 0) {\n\n        // 0x00 to 0x7F\n        if (inRange(bite, 0x00, 0x7F)) {\n          // Return a code point whose value is byte.\n          return bite;\n        }\n\n        // 0xC2 to 0xDF\n        else if (inRange(bite, 0xC2, 0xDF)) {\n          // 1. Set utf-8 bytes needed to 1.\n          utf8_bytes_needed = 1;\n\n          // 2. Set UTF-8 code point to byte & 0x1F.\n          utf8_code_point = bite & 0x1F;\n        }\n\n        // 0xE0 to 0xEF\n        else if (inRange(bite, 0xE0, 0xEF)) {\n          // 1. If byte is 0xE0, set utf-8 lower boundary to 0xA0.\n          if (bite === 0xE0)\n            utf8_lower_boundary = 0xA0;\n          // 2. If byte is 0xED, set utf-8 upper boundary to 0x9F.\n          if (bite === 0xED)\n            utf8_upper_boundary = 0x9F;\n          // 3. Set utf-8 bytes needed to 2.\n          utf8_bytes_needed = 2;\n          // 4. Set UTF-8 code point to byte & 0xF.\n          utf8_code_point = bite & 0xF;\n        }\n\n        // 0xF0 to 0xF4\n        else if (inRange(bite, 0xF0, 0xF4)) {\n          // 1. If byte is 0xF0, set utf-8 lower boundary to 0x90.\n          if (bite === 0xF0)\n            utf8_lower_boundary = 0x90;\n          // 2. If byte is 0xF4, set utf-8 upper boundary to 0x8F.\n          if (bite === 0xF4)\n            utf8_upper_boundary = 0x8F;\n          // 3. Set utf-8 bytes needed to 3.\n          utf8_bytes_needed = 3;\n          // 4. Set UTF-8 code point to byte & 0x7.\n          utf8_code_point = bite & 0x7;\n        }\n\n        // Otherwise\n        else {\n          // Return error.\n          return decoderError(fatal);\n        }\n\n        // Return continue.\n        return null;\n      }\n\n      // 4. If byte is not in the range utf-8 lower boundary to utf-8\n      // upper boundary, inclusive, run these substeps:\n      if (!inRange(bite, utf8_lower_boundary, utf8_upper_boundary)) {\n\n        // 1. Set utf-8 code point, utf-8 bytes needed, and utf-8\n        // bytes seen to 0, set utf-8 lower boundary to 0x80, and set\n        // utf-8 upper boundary to 0xBF.\n        utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;\n        utf8_lower_boundary = 0x80;\n        utf8_upper_boundary = 0xBF;\n\n        // 2. Prepend byte to stream.\n        stream.prepend(bite);\n\n        // 3. Return error.\n        return decoderError(fatal);\n      }\n\n      // 5. Set utf-8 lower boundary to 0x80 and utf-8 upper boundary\n      // to 0xBF.\n      utf8_lower_boundary = 0x80;\n      utf8_upper_boundary = 0xBF;\n\n      // 6. Set UTF-8 code point to (UTF-8 code point << 6) | (byte &\n      // 0x3F)\n      utf8_code_point = (utf8_code_point << 6) | (bite & 0x3F);\n\n      // 7. Increase utf-8 bytes seen by one.\n      utf8_bytes_seen += 1;\n\n      // 8. If utf-8 bytes seen is not equal to utf-8 bytes needed,\n      // continue.\n      if (utf8_bytes_seen !== utf8_bytes_needed)\n        return null;\n\n      // 9. Let code point be utf-8 code point.\n      var code_point = utf8_code_point;\n\n      // 10. Set utf-8 code point, utf-8 bytes needed, and utf-8 bytes\n      // seen to 0.\n      utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0;\n\n      // 11. Return a code point whose value is code point.\n      return code_point;\n    };\n  }\n\n  // 9.1.2 utf-8 encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   */\n  function UTF8Encoder(options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point, return a byte whose\n      // value is code point.\n      if (isASCIICodePoint(code_point))\n        return code_point;\n\n      // 3. Set count and offset based on the range code point is in:\n      var count, offset;\n      // U+0080 to U+07FF, inclusive:\n      if (inRange(code_point, 0x0080, 0x07FF)) {\n        // 1 and 0xC0\n        count = 1;\n        offset = 0xC0;\n      }\n      // U+0800 to U+FFFF, inclusive:\n      else if (inRange(code_point, 0x0800, 0xFFFF)) {\n        // 2 and 0xE0\n        count = 2;\n        offset = 0xE0;\n      }\n      // U+10000 to U+10FFFF, inclusive:\n      else if (inRange(code_point, 0x10000, 0x10FFFF)) {\n        // 3 and 0xF0\n        count = 3;\n        offset = 0xF0;\n      }\n\n      // 4. Let bytes be a byte sequence whose first byte is (code\n      // point >> (6 × count)) + offset.\n      var bytes = [(code_point >> (6 * count)) + offset];\n\n      // 5. Run these substeps while count is greater than 0:\n      while (count > 0) {\n\n        // 1. Set temp to code point >> (6 × (count − 1)).\n        var temp = code_point >> (6 * (count - 1));\n\n        // 2. Append to bytes 0x80 | (temp & 0x3F).\n        bytes.push(0x80 | (temp & 0x3F));\n\n        // 3. Decrease count by one.\n        count -= 1;\n      }\n\n      // 6. Return bytes bytes, in order.\n      return bytes;\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['UTF-8'] = function(options) {\n    return new UTF8Encoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['UTF-8'] = function(options) {\n    return new UTF8Decoder(options);\n  };\n\n  //\n  // 10. Legacy single-byte encodings\n  //\n\n  // 10.1 single-byte decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {!Array.<number>} index The encoding index.\n   * @param {{fatal: boolean}} options\n   */\n  function SingleByteDecoder(index, options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream, return finished.\n      if (bite === end_of_stream)\n        return finished;\n\n      // 2. If byte is an ASCII byte, return a code point whose value\n      // is byte.\n      if (isASCIIByte(bite))\n        return bite;\n\n      // 3. Let code point be the index code point for byte − 0x80 in\n      // index single-byte.\n      var code_point = index[bite - 0x80];\n\n      // 4. If code point is null, return error.\n      if (code_point === null)\n        return decoderError(fatal);\n\n      // 5. Return a code point whose value is code point.\n      return code_point;\n    };\n  }\n\n  // 10.2 single-byte encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {!Array.<?number>} index The encoding index.\n   * @param {{fatal: boolean}} options\n   */\n  function SingleByteEncoder(index, options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point, return a byte whose\n      // value is code point.\n      if (isASCIICodePoint(code_point))\n        return code_point;\n\n      // 3. Let pointer be the index pointer for code point in index\n      // single-byte.\n      var pointer = indexPointerFor(code_point, index);\n\n      // 4. If pointer is null, return error with code point.\n      if (pointer === null)\n        encoderError(code_point);\n\n      // 5. Return a byte whose value is pointer + 0x80.\n      return pointer + 0x80;\n    };\n  }\n\n  (function() {\n    if (!('encoding-indexes' in global))\n      return;\n    encodings.forEach(function(category) {\n      if (category.heading !== 'Legacy single-byte encodings')\n        return;\n      category.encodings.forEach(function(encoding) {\n        var name = encoding.name;\n        var idx = index(name.toLowerCase());\n        /** @param {{fatal: boolean}} options */\n        decoders[name] = function(options) {\n          return new SingleByteDecoder(idx, options);\n        };\n        /** @param {{fatal: boolean}} options */\n        encoders[name] = function(options) {\n          return new SingleByteEncoder(idx, options);\n        };\n      });\n    });\n  }());\n\n  //\n  // 11. Legacy multi-byte Chinese (simplified) encodings\n  //\n\n  // 11.1 gbk\n\n  // 11.1.1 gbk decoder\n  // gbk's decoder is gb18030's decoder.\n  /** @param {{fatal: boolean}} options */\n  decoders['GBK'] = function(options) {\n    return new GB18030Decoder(options);\n  };\n\n  // 11.1.2 gbk encoder\n  // gbk's encoder is gb18030's encoder with its gbk flag set.\n  /** @param {{fatal: boolean}} options */\n  encoders['GBK'] = function(options) {\n    return new GB18030Encoder(options, true);\n  };\n\n  // 11.2 gb18030\n\n  // 11.2.1 gb18030 decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function GB18030Decoder(options) {\n    var fatal = options.fatal;\n    // gb18030's decoder has an associated gb18030 first, gb18030\n    // second, and gb18030 third (all initially 0x00).\n    var /** @type {number} */ gb18030_first = 0x00,\n        /** @type {number} */ gb18030_second = 0x00,\n        /** @type {number} */ gb18030_third = 0x00;\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream and gb18030 first, gb18030\n      // second, and gb18030 third are 0x00, return finished.\n      if (bite === end_of_stream && gb18030_first === 0x00 &&\n          gb18030_second === 0x00 && gb18030_third === 0x00) {\n        return finished;\n      }\n      // 2. If byte is end-of-stream, and gb18030 first, gb18030\n      // second, or gb18030 third is not 0x00, set gb18030 first,\n      // gb18030 second, and gb18030 third to 0x00, and return error.\n      if (bite === end_of_stream &&\n          (gb18030_first !== 0x00 || gb18030_second !== 0x00 ||\n           gb18030_third !== 0x00)) {\n        gb18030_first = 0x00;\n        gb18030_second = 0x00;\n        gb18030_third = 0x00;\n        decoderError(fatal);\n      }\n      var code_point;\n      // 3. If gb18030 third is not 0x00, run these substeps:\n      if (gb18030_third !== 0x00) {\n        // 1. Let code point be null.\n        code_point = null;\n        // 2. If byte is in the range 0x30 to 0x39, inclusive, set\n        // code point to the index gb18030 ranges code point for\n        // (((gb18030 first − 0x81) × 10 + gb18030 second − 0x30) ×\n        // 126 + gb18030 third − 0x81) × 10 + byte − 0x30.\n        if (inRange(bite, 0x30, 0x39)) {\n          code_point = indexGB18030RangesCodePointFor(\n              (((gb18030_first - 0x81) * 10 + gb18030_second - 0x30) * 126 +\n               gb18030_third - 0x81) * 10 + bite - 0x30);\n        }\n\n        // 3. Let buffer be a byte sequence consisting of gb18030\n        // second, gb18030 third, and byte, in order.\n        var buffer = [gb18030_second, gb18030_third, bite];\n\n        // 4. Set gb18030 first, gb18030 second, and gb18030 third to\n        // 0x00.\n        gb18030_first = 0x00;\n        gb18030_second = 0x00;\n        gb18030_third = 0x00;\n\n        // 5. If code point is null, prepend buffer to stream and\n        // return error.\n        if (code_point === null) {\n          stream.prepend(buffer);\n          return decoderError(fatal);\n        }\n\n        // 6. Return a code point whose value is code point.\n        return code_point;\n      }\n\n      // 4. If gb18030 second is not 0x00, run these substeps:\n      if (gb18030_second !== 0x00) {\n\n        // 1. If byte is in the range 0x81 to 0xFE, inclusive, set\n        // gb18030 third to byte and return continue.\n        if (inRange(bite, 0x81, 0xFE)) {\n          gb18030_third = bite;\n          return null;\n        }\n\n        // 2. Prepend gb18030 second followed by byte to stream, set\n        // gb18030 first and gb18030 second to 0x00, and return error.\n        stream.prepend([gb18030_second, bite]);\n        gb18030_first = 0x00;\n        gb18030_second = 0x00;\n        return decoderError(fatal);\n      }\n\n      // 5. If gb18030 first is not 0x00, run these substeps:\n      if (gb18030_first !== 0x00) {\n\n        // 1. If byte is in the range 0x30 to 0x39, inclusive, set\n        // gb18030 second to byte and return continue.\n        if (inRange(bite, 0x30, 0x39)) {\n          gb18030_second = bite;\n          return null;\n        }\n\n        // 2. Let lead be gb18030 first, let pointer be null, and set\n        // gb18030 first to 0x00.\n        var lead = gb18030_first;\n        var pointer = null;\n        gb18030_first = 0x00;\n\n        // 3. Let offset be 0x40 if byte is less than 0x7F and 0x41\n        // otherwise.\n        var offset = bite < 0x7F ? 0x40 : 0x41;\n\n        // 4. If byte is in the range 0x40 to 0x7E, inclusive, or 0x80\n        // to 0xFE, inclusive, set pointer to (lead − 0x81) × 190 +\n        // (byte − offset).\n        if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0x80, 0xFE))\n          pointer = (lead - 0x81) * 190 + (bite - offset);\n\n        // 5. Let code point be null if pointer is null and the index\n        // code point for pointer in index gb18030 otherwise.\n        code_point = pointer === null ? null :\n            indexCodePointFor(pointer, index('gb18030'));\n\n        // 6. If code point is null and byte is an ASCII byte, prepend\n        // byte to stream.\n        if (code_point === null && isASCIIByte(bite))\n          stream.prepend(bite);\n\n        // 7. If code point is null, return error.\n        if (code_point === null)\n          return decoderError(fatal);\n\n        // 8. Return a code point whose value is code point.\n        return code_point;\n      }\n\n      // 6. If byte is an ASCII byte, return a code point whose value\n      // is byte.\n      if (isASCIIByte(bite))\n        return bite;\n\n      // 7. If byte is 0x80, return code point U+20AC.\n      if (bite === 0x80)\n        return 0x20AC;\n\n      // 8. If byte is in the range 0x81 to 0xFE, inclusive, set\n      // gb18030 first to byte and return continue.\n      if (inRange(bite, 0x81, 0xFE)) {\n        gb18030_first = bite;\n        return null;\n      }\n\n      // 9. Return error.\n      return decoderError(fatal);\n    };\n  }\n\n  // 11.2.2 gb18030 encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   * @param {boolean=} gbk_flag\n   */\n  function GB18030Encoder(options, gbk_flag) {\n    var fatal = options.fatal;\n    // gb18030's decoder has an associated gbk flag (initially unset).\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point, return a byte whose\n      // value is code point.\n      if (isASCIICodePoint(code_point))\n        return code_point;\n\n      // 3. If code point is U+E5E5, return error with code point.\n      if (code_point === 0xE5E5)\n        return encoderError(code_point);\n\n      // 4. If the gbk flag is set and code point is U+20AC, return\n      // byte 0x80.\n      if (gbk_flag && code_point === 0x20AC)\n        return 0x80;\n\n      // 5. Let pointer be the index pointer for code point in index\n      // gb18030.\n      var pointer = indexPointerFor(code_point, index('gb18030'));\n\n      // 6. If pointer is not null, run these substeps:\n      if (pointer !== null) {\n\n        // 1. Let lead be floor(pointer / 190) + 0x81.\n        var lead = floor(pointer / 190) + 0x81;\n\n        // 2. Let trail be pointer % 190.\n        var trail = pointer % 190;\n\n        // 3. Let offset be 0x40 if trail is less than 0x3F and 0x41 otherwise.\n        var offset = trail < 0x3F ? 0x40 : 0x41;\n\n        // 4. Return two bytes whose values are lead and trail + offset.\n        return [lead, trail + offset];\n      }\n\n      // 7. If gbk flag is set, return error with code point.\n      if (gbk_flag)\n        return encoderError(code_point);\n\n      // 8. Set pointer to the index gb18030 ranges pointer for code\n      // point.\n      pointer = indexGB18030RangesPointerFor(code_point);\n\n      // 9. Let byte1 be floor(pointer / 10 / 126 / 10).\n      var byte1 = floor(pointer / 10 / 126 / 10);\n\n      // 10. Set pointer to pointer − byte1 × 10 × 126 × 10.\n      pointer = pointer - byte1 * 10 * 126 * 10;\n\n      // 11. Let byte2 be floor(pointer / 10 / 126).\n      var byte2 = floor(pointer / 10 / 126);\n\n      // 12. Set pointer to pointer − byte2 × 10 × 126.\n      pointer = pointer - byte2 * 10 * 126;\n\n      // 13. Let byte3 be floor(pointer / 10).\n      var byte3 = floor(pointer / 10);\n\n      // 14. Let byte4 be pointer − byte3 × 10.\n      var byte4 = pointer - byte3 * 10;\n\n      // 15. Return four bytes whose values are byte1 + 0x81, byte2 +\n      // 0x30, byte3 + 0x81, byte4 + 0x30.\n      return [byte1 + 0x81,\n              byte2 + 0x30,\n              byte3 + 0x81,\n              byte4 + 0x30];\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['gb18030'] = function(options) {\n    return new GB18030Encoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['gb18030'] = function(options) {\n    return new GB18030Decoder(options);\n  };\n\n\n  //\n  // 12. Legacy multi-byte Chinese (traditional) encodings\n  //\n\n  // 12.1 Big5\n\n  // 12.1.1 Big5 decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function Big5Decoder(options) {\n    var fatal = options.fatal;\n    // Big5's decoder has an associated Big5 lead (initially 0x00).\n    var /** @type {number} */ Big5_lead = 0x00;\n\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream and Big5 lead is not 0x00, set\n      // Big5 lead to 0x00 and return error.\n      if (bite === end_of_stream && Big5_lead !== 0x00) {\n        Big5_lead = 0x00;\n        return decoderError(fatal);\n      }\n\n      // 2. If byte is end-of-stream and Big5 lead is 0x00, return\n      // finished.\n      if (bite === end_of_stream && Big5_lead === 0x00)\n        return finished;\n\n      // 3. If Big5 lead is not 0x00, let lead be Big5 lead, let\n      // pointer be null, set Big5 lead to 0x00, and then run these\n      // substeps:\n      if (Big5_lead !== 0x00) {\n        var lead = Big5_lead;\n        var pointer = null;\n        Big5_lead = 0x00;\n\n        // 1. Let offset be 0x40 if byte is less than 0x7F and 0x62\n        // otherwise.\n        var offset = bite < 0x7F ? 0x40 : 0x62;\n\n        // 2. If byte is in the range 0x40 to 0x7E, inclusive, or 0xA1\n        // to 0xFE, inclusive, set pointer to (lead − 0x81) × 157 +\n        // (byte − offset).\n        if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0xA1, 0xFE))\n          pointer = (lead - 0x81) * 157 + (bite - offset);\n\n        // 3. If there is a row in the table below whose first column\n        // is pointer, return the two code points listed in its second\n        // column\n        // Pointer | Code points\n        // --------+--------------\n        // 1133    | U+00CA U+0304\n        // 1135    | U+00CA U+030C\n        // 1164    | U+00EA U+0304\n        // 1166    | U+00EA U+030C\n        switch (pointer) {\n          case 1133: return [0x00CA, 0x0304];\n          case 1135: return [0x00CA, 0x030C];\n          case 1164: return [0x00EA, 0x0304];\n          case 1166: return [0x00EA, 0x030C];\n        }\n\n        // 4. Let code point be null if pointer is null and the index\n        // code point for pointer in index Big5 otherwise.\n        var code_point = (pointer === null) ? null :\n            indexCodePointFor(pointer, index('big5'));\n\n        // 5. If code point is null and byte is an ASCII byte, prepend\n        // byte to stream.\n        if (code_point === null && isASCIIByte(bite))\n          stream.prepend(bite);\n\n        // 6. If code point is null, return error.\n        if (code_point === null)\n          return decoderError(fatal);\n\n        // 7. Return a code point whose value is code point.\n        return code_point;\n      }\n\n      // 4. If byte is an ASCII byte, return a code point whose value\n      // is byte.\n      if (isASCIIByte(bite))\n        return bite;\n\n      // 5. If byte is in the range 0x81 to 0xFE, inclusive, set Big5\n      // lead to byte and return continue.\n      if (inRange(bite, 0x81, 0xFE)) {\n        Big5_lead = bite;\n        return null;\n      }\n\n      // 6. Return error.\n      return decoderError(fatal);\n    };\n  }\n\n  // 12.1.2 Big5 encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   */\n  function Big5Encoder(options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point, return a byte whose\n      // value is code point.\n      if (isASCIICodePoint(code_point))\n        return code_point;\n\n      // 3. Let pointer be the index Big5 pointer for code point.\n      var pointer = indexBig5PointerFor(code_point);\n\n      // 4. If pointer is null, return error with code point.\n      if (pointer === null)\n        return encoderError(code_point);\n\n      // 5. Let lead be floor(pointer / 157) + 0x81.\n      var lead = floor(pointer / 157) + 0x81;\n\n      // 6. If lead is less than 0xA1, return error with code point.\n      if (lead < 0xA1)\n        return encoderError(code_point);\n\n      // 7. Let trail be pointer % 157.\n      var trail = pointer % 157;\n\n      // 8. Let offset be 0x40 if trail is less than 0x3F and 0x62\n      // otherwise.\n      var offset = trail < 0x3F ? 0x40 : 0x62;\n\n      // Return two bytes whose values are lead and trail + offset.\n      return [lead, trail + offset];\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['Big5'] = function(options) {\n    return new Big5Encoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['Big5'] = function(options) {\n    return new Big5Decoder(options);\n  };\n\n\n  //\n  // 13. Legacy multi-byte Japanese encodings\n  //\n\n  // 13.1 euc-jp\n\n  // 13.1.1 euc-jp decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function EUCJPDecoder(options) {\n    var fatal = options.fatal;\n\n    // euc-jp's decoder has an associated euc-jp jis0212 flag\n    // (initially unset) and euc-jp lead (initially 0x00).\n    var /** @type {boolean} */ eucjp_jis0212_flag = false,\n        /** @type {number} */ eucjp_lead = 0x00;\n\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream and euc-jp lead is not 0x00, set\n      // euc-jp lead to 0x00, and return error.\n      if (bite === end_of_stream && eucjp_lead !== 0x00) {\n        eucjp_lead = 0x00;\n        return decoderError(fatal);\n      }\n\n      // 2. If byte is end-of-stream and euc-jp lead is 0x00, return\n      // finished.\n      if (bite === end_of_stream && eucjp_lead === 0x00)\n        return finished;\n\n      // 3. If euc-jp lead is 0x8E and byte is in the range 0xA1 to\n      // 0xDF, inclusive, set euc-jp lead to 0x00 and return a code\n      // point whose value is 0xFF61 − 0xA1 + byte.\n      if (eucjp_lead === 0x8E && inRange(bite, 0xA1, 0xDF)) {\n        eucjp_lead = 0x00;\n        return 0xFF61 - 0xA1 + bite;\n      }\n\n      // 4. If euc-jp lead is 0x8F and byte is in the range 0xA1 to\n      // 0xFE, inclusive, set the euc-jp jis0212 flag, set euc-jp lead\n      // to byte, and return continue.\n      if (eucjp_lead === 0x8F && inRange(bite, 0xA1, 0xFE)) {\n        eucjp_jis0212_flag = true;\n        eucjp_lead = bite;\n        return null;\n      }\n\n      // 5. If euc-jp lead is not 0x00, let lead be euc-jp lead, set\n      // euc-jp lead to 0x00, and run these substeps:\n      if (eucjp_lead !== 0x00) {\n        var lead = eucjp_lead;\n        eucjp_lead = 0x00;\n\n        // 1. Let code point be null.\n        var code_point = null;\n\n        // 2. If lead and byte are both in the range 0xA1 to 0xFE,\n        // inclusive, set code point to the index code point for (lead\n        // − 0xA1) × 94 + byte − 0xA1 in index jis0208 if the euc-jp\n        // jis0212 flag is unset and in index jis0212 otherwise.\n        if (inRange(lead, 0xA1, 0xFE) && inRange(bite, 0xA1, 0xFE)) {\n          code_point = indexCodePointFor(\n            (lead - 0xA1) * 94 + (bite - 0xA1),\n            index(!eucjp_jis0212_flag ? 'jis0208' : 'jis0212'));\n        }\n\n        // 3. Unset the euc-jp jis0212 flag.\n        eucjp_jis0212_flag = false;\n\n        // 4. If byte is not in the range 0xA1 to 0xFE, inclusive,\n        // prepend byte to stream.\n        if (!inRange(bite, 0xA1, 0xFE))\n          stream.prepend(bite);\n\n        // 5. If code point is null, return error.\n        if (code_point === null)\n          return decoderError(fatal);\n\n        // 6. Return a code point whose value is code point.\n        return code_point;\n      }\n\n      // 6. If byte is an ASCII byte, return a code point whose value\n      // is byte.\n      if (isASCIIByte(bite))\n        return bite;\n\n      // 7. If byte is 0x8E, 0x8F, or in the range 0xA1 to 0xFE,\n      // inclusive, set euc-jp lead to byte and return continue.\n      if (bite === 0x8E || bite === 0x8F || inRange(bite, 0xA1, 0xFE)) {\n        eucjp_lead = bite;\n        return null;\n      }\n\n      // 8. Return error.\n      return decoderError(fatal);\n    };\n  }\n\n  // 13.1.2 euc-jp encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   */\n  function EUCJPEncoder(options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point, return a byte whose\n      // value is code point.\n      if (isASCIICodePoint(code_point))\n        return code_point;\n\n      // 3. If code point is U+00A5, return byte 0x5C.\n      if (code_point === 0x00A5)\n        return 0x5C;\n\n      // 4. If code point is U+203E, return byte 0x7E.\n      if (code_point === 0x203E)\n        return 0x7E;\n\n      // 5. If code point is in the range U+FF61 to U+FF9F, inclusive,\n      // return two bytes whose values are 0x8E and code point −\n      // 0xFF61 + 0xA1.\n      if (inRange(code_point, 0xFF61, 0xFF9F))\n        return [0x8E, code_point - 0xFF61 + 0xA1];\n\n      // 6. If code point is U+2212, set it to U+FF0D.\n      if (code_point === 0x2212)\n        code_point = 0xFF0D;\n\n      // 7. Let pointer be the index pointer for code point in index\n      // jis0208.\n      var pointer = indexPointerFor(code_point, index('jis0208'));\n\n      // 8. If pointer is null, return error with code point.\n      if (pointer === null)\n        return encoderError(code_point);\n\n      // 9. Let lead be floor(pointer / 94) + 0xA1.\n      var lead = floor(pointer / 94) + 0xA1;\n\n      // 10. Let trail be pointer % 94 + 0xA1.\n      var trail = pointer % 94 + 0xA1;\n\n      // 11. Return two bytes whose values are lead and trail.\n      return [lead, trail];\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['EUC-JP'] = function(options) {\n    return new EUCJPEncoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['EUC-JP'] = function(options) {\n    return new EUCJPDecoder(options);\n  };\n\n  // 13.2 iso-2022-jp\n\n  // 13.2.1 iso-2022-jp decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function ISO2022JPDecoder(options) {\n    var fatal = options.fatal;\n    /** @enum */\n    var states = {\n      ASCII: 0,\n      Roman: 1,\n      Katakana: 2,\n      LeadByte: 3,\n      TrailByte: 4,\n      EscapeStart: 5,\n      Escape: 6\n    };\n    // iso-2022-jp's decoder has an associated iso-2022-jp decoder\n    // state (initially ASCII), iso-2022-jp decoder output state\n    // (initially ASCII), iso-2022-jp lead (initially 0x00), and\n    // iso-2022-jp output flag (initially unset).\n    var /** @type {number} */ iso2022jp_decoder_state = states.ASCII,\n        /** @type {number} */ iso2022jp_decoder_output_state = states.ASCII,\n        /** @type {number} */ iso2022jp_lead = 0x00,\n        /** @type {boolean} */ iso2022jp_output_flag = false;\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // switching on iso-2022-jp decoder state:\n      switch (iso2022jp_decoder_state) {\n      default:\n      case states.ASCII:\n        // ASCII\n        // Based on byte:\n\n        // 0x1B\n        if (bite === 0x1B) {\n          // Set iso-2022-jp decoder state to escape start and return\n          // continue.\n          iso2022jp_decoder_state = states.EscapeStart;\n          return null;\n        }\n\n        // 0x00 to 0x7F, excluding 0x0E, 0x0F, and 0x1B\n        if (inRange(bite, 0x00, 0x7F) && bite !== 0x0E\n            && bite !== 0x0F && bite !== 0x1B) {\n          // Unset the iso-2022-jp output flag and return a code point\n          // whose value is byte.\n          iso2022jp_output_flag = false;\n          return bite;\n        }\n\n        // end-of-stream\n        if (bite === end_of_stream) {\n          // Return finished.\n          return finished;\n        }\n\n        // Otherwise\n        // Unset the iso-2022-jp output flag and return error.\n        iso2022jp_output_flag = false;\n        return decoderError(fatal);\n\n      case states.Roman:\n        // Roman\n        // Based on byte:\n\n        // 0x1B\n        if (bite === 0x1B) {\n          // Set iso-2022-jp decoder state to escape start and return\n          // continue.\n          iso2022jp_decoder_state = states.EscapeStart;\n          return null;\n        }\n\n        // 0x5C\n        if (bite === 0x5C) {\n          // Unset the iso-2022-jp output flag and return code point\n          // U+00A5.\n          iso2022jp_output_flag = false;\n          return 0x00A5;\n        }\n\n        // 0x7E\n        if (bite === 0x7E) {\n          // Unset the iso-2022-jp output flag and return code point\n          // U+203E.\n          iso2022jp_output_flag = false;\n          return 0x203E;\n        }\n\n        // 0x00 to 0x7F, excluding 0x0E, 0x0F, 0x1B, 0x5C, and 0x7E\n        if (inRange(bite, 0x00, 0x7F) && bite !== 0x0E && bite !== 0x0F\n            && bite !== 0x1B && bite !== 0x5C && bite !== 0x7E) {\n          // Unset the iso-2022-jp output flag and return a code point\n          // whose value is byte.\n          iso2022jp_output_flag = false;\n          return bite;\n        }\n\n        // end-of-stream\n        if (bite === end_of_stream) {\n          // Return finished.\n          return finished;\n        }\n\n        // Otherwise\n        // Unset the iso-2022-jp output flag and return error.\n        iso2022jp_output_flag = false;\n        return decoderError(fatal);\n\n      case states.Katakana:\n        // Katakana\n        // Based on byte:\n\n        // 0x1B\n        if (bite === 0x1B) {\n          // Set iso-2022-jp decoder state to escape start and return\n          // continue.\n          iso2022jp_decoder_state = states.EscapeStart;\n          return null;\n        }\n\n        // 0x21 to 0x5F\n        if (inRange(bite, 0x21, 0x5F)) {\n          // Unset the iso-2022-jp output flag and return a code point\n          // whose value is 0xFF61 − 0x21 + byte.\n          iso2022jp_output_flag = false;\n          return 0xFF61 - 0x21 + bite;\n        }\n\n        // end-of-stream\n        if (bite === end_of_stream) {\n          // Return finished.\n          return finished;\n        }\n\n        // Otherwise\n        // Unset the iso-2022-jp output flag and return error.\n        iso2022jp_output_flag = false;\n        return decoderError(fatal);\n\n      case states.LeadByte:\n        // Lead byte\n        // Based on byte:\n\n        // 0x1B\n        if (bite === 0x1B) {\n          // Set iso-2022-jp decoder state to escape start and return\n          // continue.\n          iso2022jp_decoder_state = states.EscapeStart;\n          return null;\n        }\n\n        // 0x21 to 0x7E\n        if (inRange(bite, 0x21, 0x7E)) {\n          // Unset the iso-2022-jp output flag, set iso-2022-jp lead\n          // to byte, iso-2022-jp decoder state to trail byte, and\n          // return continue.\n          iso2022jp_output_flag = false;\n          iso2022jp_lead = bite;\n          iso2022jp_decoder_state = states.TrailByte;\n          return null;\n        }\n\n        // end-of-stream\n        if (bite === end_of_stream) {\n          // Return finished.\n          return finished;\n        }\n\n        // Otherwise\n        // Unset the iso-2022-jp output flag and return error.\n        iso2022jp_output_flag = false;\n        return decoderError(fatal);\n\n      case states.TrailByte:\n        // Trail byte\n        // Based on byte:\n\n        // 0x1B\n        if (bite === 0x1B) {\n          // Set iso-2022-jp decoder state to escape start and return\n          // continue.\n          iso2022jp_decoder_state = states.EscapeStart;\n          return decoderError(fatal);\n        }\n\n        // 0x21 to 0x7E\n        if (inRange(bite, 0x21, 0x7E)) {\n          // 1. Set the iso-2022-jp decoder state to lead byte.\n          iso2022jp_decoder_state = states.LeadByte;\n\n          // 2. Let pointer be (iso-2022-jp lead − 0x21) × 94 + byte − 0x21.\n          var pointer = (iso2022jp_lead - 0x21) * 94 + bite - 0x21;\n\n          // 3. Let code point be the index code point for pointer in\n          // index jis0208.\n          var code_point = indexCodePointFor(pointer, index('jis0208'));\n\n          // 4. If code point is null, return error.\n          if (code_point === null)\n            return decoderError(fatal);\n\n          // 5. Return a code point whose value is code point.\n          return code_point;\n        }\n\n        // end-of-stream\n        if (bite === end_of_stream) {\n          // Set the iso-2022-jp decoder state to lead byte, prepend\n          // byte to stream, and return error.\n          iso2022jp_decoder_state = states.LeadByte;\n          stream.prepend(bite);\n          return decoderError(fatal);\n        }\n\n        // Otherwise\n        // Set iso-2022-jp decoder state to lead byte and return\n        // error.\n        iso2022jp_decoder_state = states.LeadByte;\n        return decoderError(fatal);\n\n      case states.EscapeStart:\n        // Escape start\n\n        // 1. If byte is either 0x24 or 0x28, set iso-2022-jp lead to\n        // byte, iso-2022-jp decoder state to escape, and return\n        // continue.\n        if (bite === 0x24 || bite === 0x28) {\n          iso2022jp_lead = bite;\n          iso2022jp_decoder_state = states.Escape;\n          return null;\n        }\n\n        // 2. Prepend byte to stream.\n        stream.prepend(bite);\n\n        // 3. Unset the iso-2022-jp output flag, set iso-2022-jp\n        // decoder state to iso-2022-jp decoder output state, and\n        // return error.\n        iso2022jp_output_flag = false;\n        iso2022jp_decoder_state = iso2022jp_decoder_output_state;\n        return decoderError(fatal);\n\n      case states.Escape:\n        // Escape\n\n        // 1. Let lead be iso-2022-jp lead and set iso-2022-jp lead to\n        // 0x00.\n        var lead = iso2022jp_lead;\n        iso2022jp_lead = 0x00;\n\n        // 2. Let state be null.\n        var state = null;\n\n        // 3. If lead is 0x28 and byte is 0x42, set state to ASCII.\n        if (lead === 0x28 && bite === 0x42)\n          state = states.ASCII;\n\n        // 4. If lead is 0x28 and byte is 0x4A, set state to Roman.\n        if (lead === 0x28 && bite === 0x4A)\n          state = states.Roman;\n\n        // 5. If lead is 0x28 and byte is 0x49, set state to Katakana.\n        if (lead === 0x28 && bite === 0x49)\n          state = states.Katakana;\n\n        // 6. If lead is 0x24 and byte is either 0x40 or 0x42, set\n        // state to lead byte.\n        if (lead === 0x24 && (bite === 0x40 || bite === 0x42))\n          state = states.LeadByte;\n\n        // 7. If state is non-null, run these substeps:\n        if (state !== null) {\n          // 1. Set iso-2022-jp decoder state and iso-2022-jp decoder\n          // output state to states.\n          iso2022jp_decoder_state = iso2022jp_decoder_state = state;\n\n          // 2. Let output flag be the iso-2022-jp output flag.\n          var output_flag = iso2022jp_output_flag;\n\n          // 3. Set the iso-2022-jp output flag.\n          iso2022jp_output_flag = true;\n\n          // 4. Return continue, if output flag is unset, and error\n          // otherwise.\n          return !output_flag ? null : decoderError(fatal);\n        }\n\n        // 8. Prepend lead and byte to stream.\n        stream.prepend([lead, bite]);\n\n        // 9. Unset the iso-2022-jp output flag, set iso-2022-jp\n        // decoder state to iso-2022-jp decoder output state and\n        // return error.\n        iso2022jp_output_flag = false;\n        iso2022jp_decoder_state = iso2022jp_decoder_output_state;\n        return decoderError(fatal);\n      }\n    };\n  }\n\n  // 13.2.2 iso-2022-jp encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   */\n  function ISO2022JPEncoder(options) {\n    var fatal = options.fatal;\n    // iso-2022-jp's encoder has an associated iso-2022-jp encoder\n    // state which is one of ASCII, Roman, and jis0208 (initially\n    // ASCII).\n    /** @enum */\n    var states = {\n      ASCII: 0,\n      Roman: 1,\n      jis0208: 2\n    };\n    var /** @type {number} */ iso2022jp_state = states.ASCII;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream and iso-2022-jp encoder\n      // state is not ASCII, prepend code point to stream, set\n      // iso-2022-jp encoder state to ASCII, and return three bytes\n      // 0x1B 0x28 0x42.\n      if (code_point === end_of_stream &&\n          iso2022jp_state !== states.ASCII) {\n        stream.prepend(code_point);\n        iso2022jp_state = states.ASCII;\n        return [0x1B, 0x28, 0x42];\n      }\n\n      // 2. If code point is end-of-stream and iso-2022-jp encoder\n      // state is ASCII, return finished.\n      if (code_point === end_of_stream && iso2022jp_state === states.ASCII)\n        return finished;\n\n      // 3. If ISO-2022-JP encoder state is ASCII or Roman, and code\n      // point is U+000E, U+000F, or U+001B, return error with U+FFFD.\n      if ((iso2022jp_state === states.ASCII ||\n           iso2022jp_state === states.Roman) &&\n          (code_point === 0x000E || code_point === 0x000F ||\n           code_point === 0x001B)) {\n        return encoderError(0xFFFD);\n      }\n\n      // 4. If iso-2022-jp encoder state is ASCII and code point is an\n      // ASCII code point, return a byte whose value is code point.\n      if (iso2022jp_state === states.ASCII &&\n          isASCIICodePoint(code_point))\n        return code_point;\n\n      // 5. If iso-2022-jp encoder state is Roman and code point is an\n      // ASCII code point, excluding U+005C and U+007E, or is U+00A5\n      // or U+203E, run these substeps:\n      if (iso2022jp_state === states.Roman &&\n          ((isASCIICodePoint(code_point) &&\n           code_point !== 0x005C && code_point !== 0x007E) ||\n          (code_point == 0x00A5 || code_point == 0x203E))) {\n\n        // 1. If code point is an ASCII code point, return a byte\n        // whose value is code point.\n        if (isASCIICodePoint(code_point))\n          return code_point;\n\n        // 2. If code point is U+00A5, return byte 0x5C.\n        if (code_point === 0x00A5)\n          return 0x5C;\n\n        // 3. If code point is U+203E, return byte 0x7E.\n        if (code_point === 0x203E)\n          return 0x7E;\n      }\n\n      // 6. If code point is an ASCII code point, and iso-2022-jp\n      // encoder state is not ASCII, prepend code point to stream, set\n      // iso-2022-jp encoder state to ASCII, and return three bytes\n      // 0x1B 0x28 0x42.\n      if (isASCIICodePoint(code_point) &&\n          iso2022jp_state !== states.ASCII) {\n        stream.prepend(code_point);\n        iso2022jp_state = states.ASCII;\n        return [0x1B, 0x28, 0x42];\n      }\n\n      // 7. If code point is either U+00A5 or U+203E, and iso-2022-jp\n      // encoder state is not Roman, prepend code point to stream, set\n      // iso-2022-jp encoder state to Roman, and return three bytes\n      // 0x1B 0x28 0x4A.\n      if ((code_point === 0x00A5 || code_point === 0x203E) &&\n          iso2022jp_state !== states.Roman) {\n        stream.prepend(code_point);\n        iso2022jp_state = states.Roman;\n        return [0x1B, 0x28, 0x4A];\n      }\n\n      // 8. If code point is U+2212, set it to U+FF0D.\n      if (code_point === 0x2212)\n        code_point = 0xFF0D;\n\n      // 9. Let pointer be the index pointer for code point in index\n      // jis0208.\n      var pointer = indexPointerFor(code_point, index('jis0208'));\n\n      // 10. If pointer is null, return error with code point.\n      if (pointer === null)\n        return encoderError(code_point);\n\n      // 11. If iso-2022-jp encoder state is not jis0208, prepend code\n      // point to stream, set iso-2022-jp encoder state to jis0208,\n      // and return three bytes 0x1B 0x24 0x42.\n      if (iso2022jp_state !== states.jis0208) {\n        stream.prepend(code_point);\n        iso2022jp_state = states.jis0208;\n        return [0x1B, 0x24, 0x42];\n      }\n\n      // 12. Let lead be floor(pointer / 94) + 0x21.\n      var lead = floor(pointer / 94) + 0x21;\n\n      // 13. Let trail be pointer % 94 + 0x21.\n      var trail = pointer % 94 + 0x21;\n\n      // 14. Return two bytes whose values are lead and trail.\n      return [lead, trail];\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['ISO-2022-JP'] = function(options) {\n    return new ISO2022JPEncoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['ISO-2022-JP'] = function(options) {\n    return new ISO2022JPDecoder(options);\n  };\n\n  // 13.3 Shift_JIS\n\n  // 13.3.1 Shift_JIS decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function ShiftJISDecoder(options) {\n    var fatal = options.fatal;\n    // Shift_JIS's decoder has an associated Shift_JIS lead (initially\n    // 0x00).\n    var /** @type {number} */ Shift_JIS_lead = 0x00;\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream and Shift_JIS lead is not 0x00,\n      // set Shift_JIS lead to 0x00 and return error.\n      if (bite === end_of_stream && Shift_JIS_lead !== 0x00) {\n        Shift_JIS_lead = 0x00;\n        return decoderError(fatal);\n      }\n\n      // 2. If byte is end-of-stream and Shift_JIS lead is 0x00,\n      // return finished.\n      if (bite === end_of_stream && Shift_JIS_lead === 0x00)\n        return finished;\n\n      // 3. If Shift_JIS lead is not 0x00, let lead be Shift_JIS lead,\n      // let pointer be null, set Shift_JIS lead to 0x00, and then run\n      // these substeps:\n      if (Shift_JIS_lead !== 0x00) {\n        var lead = Shift_JIS_lead;\n        var pointer = null;\n        Shift_JIS_lead = 0x00;\n\n        // 1. Let offset be 0x40, if byte is less than 0x7F, and 0x41\n        // otherwise.\n        var offset = (bite < 0x7F) ? 0x40 : 0x41;\n\n        // 2. Let lead offset be 0x81, if lead is less than 0xA0, and\n        // 0xC1 otherwise.\n        var lead_offset = (lead < 0xA0) ? 0x81 : 0xC1;\n\n        // 3. If byte is in the range 0x40 to 0x7E, inclusive, or 0x80\n        // to 0xFC, inclusive, set pointer to (lead − lead offset) ×\n        // 188 + byte − offset.\n        if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0x80, 0xFC))\n          pointer = (lead - lead_offset) * 188 + bite - offset;\n\n        // 4. If pointer is in the range 8836 to 10715, inclusive,\n        // return a code point whose value is 0xE000 − 8836 + pointer.\n        if (inRange(pointer, 8836, 10715))\n          return 0xE000 - 8836 + pointer;\n\n        // 5. Let code point be null, if pointer is null, and the\n        // index code point for pointer in index jis0208 otherwise.\n        var code_point = (pointer === null) ? null :\n              indexCodePointFor(pointer, index('jis0208'));\n\n        // 6. If code point is null and byte is an ASCII byte, prepend\n        // byte to stream.\n        if (code_point === null && isASCIIByte(bite))\n          stream.prepend(bite);\n\n        // 7. If code point is null, return error.\n        if (code_point === null)\n          return decoderError(fatal);\n\n        // 8. Return a code point whose value is code point.\n        return code_point;\n      }\n\n      // 4. If byte is an ASCII byte or 0x80, return a code point\n      // whose value is byte.\n      if (isASCIIByte(bite) || bite === 0x80)\n        return bite;\n\n      // 5. If byte is in the range 0xA1 to 0xDF, inclusive, return a\n      // code point whose value is 0xFF61 − 0xA1 + byte.\n      if (inRange(bite, 0xA1, 0xDF))\n        return 0xFF61 - 0xA1 + bite;\n\n      // 6. If byte is in the range 0x81 to 0x9F, inclusive, or 0xE0\n      // to 0xFC, inclusive, set Shift_JIS lead to byte and return\n      // continue.\n      if (inRange(bite, 0x81, 0x9F) || inRange(bite, 0xE0, 0xFC)) {\n        Shift_JIS_lead = bite;\n        return null;\n      }\n\n      // 7. Return error.\n      return decoderError(fatal);\n    };\n  }\n\n  // 13.3.2 Shift_JIS encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   */\n  function ShiftJISEncoder(options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point or U+0080, return a\n      // byte whose value is code point.\n      if (isASCIICodePoint(code_point) || code_point === 0x0080)\n        return code_point;\n\n      // 3. If code point is U+00A5, return byte 0x5C.\n      if (code_point === 0x00A5)\n        return 0x5C;\n\n      // 4. If code point is U+203E, return byte 0x7E.\n      if (code_point === 0x203E)\n        return 0x7E;\n\n      // 5. If code point is in the range U+FF61 to U+FF9F, inclusive,\n      // return a byte whose value is code point − 0xFF61 + 0xA1.\n      if (inRange(code_point, 0xFF61, 0xFF9F))\n        return code_point - 0xFF61 + 0xA1;\n\n      // 6. If code point is U+2212, set it to U+FF0D.\n      if (code_point === 0x2212)\n        code_point = 0xFF0D;\n\n      // 7. Let pointer be the index Shift_JIS pointer for code point.\n      var pointer = indexShiftJISPointerFor(code_point);\n\n      // 8. If pointer is null, return error with code point.\n      if (pointer === null)\n        return encoderError(code_point);\n\n      // 9. Let lead be floor(pointer / 188).\n      var lead = floor(pointer / 188);\n\n      // 10. Let lead offset be 0x81, if lead is less than 0x1F, and\n      // 0xC1 otherwise.\n      var lead_offset = (lead < 0x1F) ? 0x81 : 0xC1;\n\n      // 11. Let trail be pointer % 188.\n      var trail = pointer % 188;\n\n      // 12. Let offset be 0x40, if trail is less than 0x3F, and 0x41\n      // otherwise.\n      var offset = (trail < 0x3F) ? 0x40 : 0x41;\n\n      // 13. Return two bytes whose values are lead + lead offset and\n      // trail + offset.\n      return [lead + lead_offset, trail + offset];\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['Shift_JIS'] = function(options) {\n    return new ShiftJISEncoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['Shift_JIS'] = function(options) {\n    return new ShiftJISDecoder(options);\n  };\n\n  //\n  // 14. Legacy multi-byte Korean encodings\n  //\n\n  // 14.1 euc-kr\n\n  // 14.1.1 euc-kr decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function EUCKRDecoder(options) {\n    var fatal = options.fatal;\n\n    // euc-kr's decoder has an associated euc-kr lead (initially 0x00).\n    var /** @type {number} */ euckr_lead = 0x00;\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream and euc-kr lead is not 0x00, set\n      // euc-kr lead to 0x00 and return error.\n      if (bite === end_of_stream && euckr_lead !== 0) {\n        euckr_lead = 0x00;\n        return decoderError(fatal);\n      }\n\n      // 2. If byte is end-of-stream and euc-kr lead is 0x00, return\n      // finished.\n      if (bite === end_of_stream && euckr_lead === 0)\n        return finished;\n\n      // 3. If euc-kr lead is not 0x00, let lead be euc-kr lead, let\n      // pointer be null, set euc-kr lead to 0x00, and then run these\n      // substeps:\n      if (euckr_lead !== 0x00) {\n        var lead = euckr_lead;\n        var pointer = null;\n        euckr_lead = 0x00;\n\n        // 1. If byte is in the range 0x41 to 0xFE, inclusive, set\n        // pointer to (lead − 0x81) × 190 + (byte − 0x41).\n        if (inRange(bite, 0x41, 0xFE))\n          pointer = (lead - 0x81) * 190 + (bite - 0x41);\n\n        // 2. Let code point be null, if pointer is null, and the\n        // index code point for pointer in index euc-kr otherwise.\n        var code_point = (pointer === null)\n              ? null : indexCodePointFor(pointer, index('euc-kr'));\n\n        // 3. If code point is null and byte is an ASCII byte, prepend\n        // byte to stream.\n        if (pointer === null && isASCIIByte(bite))\n          stream.prepend(bite);\n\n        // 4. If code point is null, return error.\n        if (code_point === null)\n          return decoderError(fatal);\n\n        // 5. Return a code point whose value is code point.\n        return code_point;\n      }\n\n      // 4. If byte is an ASCII byte, return a code point whose value\n      // is byte.\n      if (isASCIIByte(bite))\n        return bite;\n\n      // 5. If byte is in the range 0x81 to 0xFE, inclusive, set\n      // euc-kr lead to byte and return continue.\n      if (inRange(bite, 0x81, 0xFE)) {\n        euckr_lead = bite;\n        return null;\n      }\n\n      // 6. Return error.\n      return decoderError(fatal);\n    };\n  }\n\n  // 14.1.2 euc-kr encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   */\n  function EUCKREncoder(options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point, return a byte whose\n      // value is code point.\n      if (isASCIICodePoint(code_point))\n        return code_point;\n\n      // 3. Let pointer be the index pointer for code point in index\n      // euc-kr.\n      var pointer = indexPointerFor(code_point, index('euc-kr'));\n\n      // 4. If pointer is null, return error with code point.\n      if (pointer === null)\n        return encoderError(code_point);\n\n      // 5. Let lead be floor(pointer / 190) + 0x81.\n      var lead = floor(pointer / 190) + 0x81;\n\n      // 6. Let trail be pointer % 190 + 0x41.\n      var trail = (pointer % 190) + 0x41;\n\n      // 7. Return two bytes whose values are lead and trail.\n      return [lead, trail];\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['EUC-KR'] = function(options) {\n    return new EUCKREncoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['EUC-KR'] = function(options) {\n    return new EUCKRDecoder(options);\n  };\n\n\n  //\n  // 15. Legacy miscellaneous encodings\n  //\n\n  // 15.1 replacement\n\n  // Not needed - API throws RangeError\n\n  // 15.2 Common infrastructure for utf-16be and utf-16le\n\n  /**\n   * @param {number} code_unit\n   * @param {boolean} utf16be\n   * @return {!Array.<number>} bytes\n   */\n  function convertCodeUnitToBytes(code_unit, utf16be) {\n    // 1. Let byte1 be code unit >> 8.\n    var byte1 = code_unit >> 8;\n\n    // 2. Let byte2 be code unit & 0x00FF.\n    var byte2 = code_unit & 0x00FF;\n\n    // 3. Then return the bytes in order:\n        // utf-16be flag is set: byte1, then byte2.\n    if (utf16be)\n      return [byte1, byte2];\n    // utf-16be flag is unset: byte2, then byte1.\n    return [byte2, byte1];\n  }\n\n  // 15.2.1 shared utf-16 decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {boolean} utf16_be True if big-endian, false if little-endian.\n   * @param {{fatal: boolean}} options\n   */\n  function UTF16Decoder(utf16_be, options) {\n    var fatal = options.fatal;\n    var /** @type {?number} */ utf16_lead_byte = null,\n        /** @type {?number} */ utf16_lead_surrogate = null;\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream and either utf-16 lead byte or\n      // utf-16 lead surrogate is not null, set utf-16 lead byte and\n      // utf-16 lead surrogate to null, and return error.\n      if (bite === end_of_stream && (utf16_lead_byte !== null ||\n                                utf16_lead_surrogate !== null)) {\n        return decoderError(fatal);\n      }\n\n      // 2. If byte is end-of-stream and utf-16 lead byte and utf-16\n      // lead surrogate are null, return finished.\n      if (bite === end_of_stream && utf16_lead_byte === null &&\n          utf16_lead_surrogate === null) {\n        return finished;\n      }\n\n      // 3. If utf-16 lead byte is null, set utf-16 lead byte to byte\n      // and return continue.\n      if (utf16_lead_byte === null) {\n        utf16_lead_byte = bite;\n        return null;\n      }\n\n      // 4. Let code unit be the result of:\n      var code_unit;\n      if (utf16_be) {\n        // utf-16be decoder flag is set\n        //   (utf-16 lead byte << 8) + byte.\n        code_unit = (utf16_lead_byte << 8) + bite;\n      } else {\n        // utf-16be decoder flag is unset\n        //   (byte << 8) + utf-16 lead byte.\n        code_unit = (bite << 8) + utf16_lead_byte;\n      }\n      // Then set utf-16 lead byte to null.\n      utf16_lead_byte = null;\n\n      // 5. If utf-16 lead surrogate is not null, let lead surrogate\n      // be utf-16 lead surrogate, set utf-16 lead surrogate to null,\n      // and then run these substeps:\n      if (utf16_lead_surrogate !== null) {\n        var lead_surrogate = utf16_lead_surrogate;\n        utf16_lead_surrogate = null;\n\n        // 1. If code unit is in the range U+DC00 to U+DFFF,\n        // inclusive, return a code point whose value is 0x10000 +\n        // ((lead surrogate − 0xD800) << 10) + (code unit − 0xDC00).\n        if (inRange(code_unit, 0xDC00, 0xDFFF)) {\n          return 0x10000 + (lead_surrogate - 0xD800) * 0x400 +\n              (code_unit - 0xDC00);\n        }\n\n        // 2. Prepend the sequence resulting of converting code unit\n        // to bytes using utf-16be decoder flag to stream and return\n        // error.\n        stream.prepend(convertCodeUnitToBytes(code_unit, utf16_be));\n        return decoderError(fatal);\n      }\n\n      // 6. If code unit is in the range U+D800 to U+DBFF, inclusive,\n      // set utf-16 lead surrogate to code unit and return continue.\n      if (inRange(code_unit, 0xD800, 0xDBFF)) {\n        utf16_lead_surrogate = code_unit;\n        return null;\n      }\n\n      // 7. If code unit is in the range U+DC00 to U+DFFF, inclusive,\n      // return error.\n      if (inRange(code_unit, 0xDC00, 0xDFFF))\n        return decoderError(fatal);\n\n      // 8. Return code point code unit.\n      return code_unit;\n    };\n  }\n\n  // 15.2.2 shared utf-16 encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {boolean} utf16_be True if big-endian, false if little-endian.\n   * @param {{fatal: boolean}} options\n   */\n  function UTF16Encoder(utf16_be, options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1. If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is in the range U+0000 to U+FFFF, inclusive,\n      // return the sequence resulting of converting code point to\n      // bytes using utf-16be encoder flag.\n      if (inRange(code_point, 0x0000, 0xFFFF))\n        return convertCodeUnitToBytes(code_point, utf16_be);\n\n      // 3. Let lead be ((code point − 0x10000) >> 10) + 0xD800,\n      // converted to bytes using utf-16be encoder flag.\n      var lead = convertCodeUnitToBytes(\n        ((code_point - 0x10000) >> 10) + 0xD800, utf16_be);\n\n      // 4. Let trail be ((code point − 0x10000) & 0x3FF) + 0xDC00,\n      // converted to bytes using utf-16be encoder flag.\n      var trail = convertCodeUnitToBytes(\n        ((code_point - 0x10000) & 0x3FF) + 0xDC00, utf16_be);\n\n      // 5. Return a byte sequence of lead followed by trail.\n      return lead.concat(trail);\n    };\n  }\n\n  // 15.3 utf-16be\n  // 15.3.1 utf-16be decoder\n  /** @param {{fatal: boolean}} options */\n  encoders['UTF-16BE'] = function(options) {\n    return new UTF16Encoder(true, options);\n  };\n  // 15.3.2 utf-16be encoder\n  /** @param {{fatal: boolean}} options */\n  decoders['UTF-16BE'] = function(options) {\n    return new UTF16Decoder(true, options);\n  };\n\n  // 15.4 utf-16le\n  // 15.4.1 utf-16le decoder\n  /** @param {{fatal: boolean}} options */\n  encoders['UTF-16LE'] = function(options) {\n    return new UTF16Encoder(false, options);\n  };\n  // 15.4.2 utf-16le encoder\n  /** @param {{fatal: boolean}} options */\n  decoders['UTF-16LE'] = function(options) {\n    return new UTF16Decoder(false, options);\n  };\n\n  // 15.5 x-user-defined\n\n  // 15.5.1 x-user-defined decoder\n  /**\n   * @constructor\n   * @implements {Decoder}\n   * @param {{fatal: boolean}} options\n   */\n  function XUserDefinedDecoder(options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream The stream of bytes being decoded.\n     * @param {number} bite The next byte read from the stream.\n     * @return {?(number|!Array.<number>)} The next code point(s)\n     *     decoded, or null if not enough data exists in the input\n     *     stream to decode a complete code point.\n     */\n    this.handler = function(stream, bite) {\n      // 1. If byte is end-of-stream, return finished.\n      if (bite === end_of_stream)\n        return finished;\n\n      // 2. If byte is an ASCII byte, return a code point whose value\n      // is byte.\n      if (isASCIIByte(bite))\n        return bite;\n\n      // 3. Return a code point whose value is 0xF780 + byte − 0x80.\n      return 0xF780 + bite - 0x80;\n    };\n  }\n\n  // 15.5.2 x-user-defined encoder\n  /**\n   * @constructor\n   * @implements {Encoder}\n   * @param {{fatal: boolean}} options\n   */\n  function XUserDefinedEncoder(options) {\n    var fatal = options.fatal;\n    /**\n     * @param {Stream} stream Input stream.\n     * @param {number} code_point Next code point read from the stream.\n     * @return {(number|!Array.<number>)} Byte(s) to emit.\n     */\n    this.handler = function(stream, code_point) {\n      // 1.If code point is end-of-stream, return finished.\n      if (code_point === end_of_stream)\n        return finished;\n\n      // 2. If code point is an ASCII code point, return a byte whose\n      // value is code point.\n      if (isASCIICodePoint(code_point))\n        return code_point;\n\n      // 3. If code point is in the range U+F780 to U+F7FF, inclusive,\n      // return a byte whose value is code point − 0xF780 + 0x80.\n      if (inRange(code_point, 0xF780, 0xF7FF))\n        return code_point - 0xF780 + 0x80;\n\n      // 4. Return error with code point.\n      return encoderError(code_point);\n    };\n  }\n\n  /** @param {{fatal: boolean}} options */\n  encoders['x-user-defined'] = function(options) {\n    return new XUserDefinedEncoder(options);\n  };\n  /** @param {{fatal: boolean}} options */\n  decoders['x-user-defined'] = function(options) {\n    return new XUserDefinedDecoder(options);\n  };\n\n  if (!global['TextEncoder'])\n    global['TextEncoder'] = TextEncoder;\n  if (!global['TextDecoder'])\n    global['TextDecoder'] = TextDecoder;\n\n  if (typeof module !== \"undefined\" && module.exports) {\n    module.exports = {\n      TextEncoder: global['TextEncoder'],\n      TextDecoder: global['TextDecoder'],\n      EncodingIndexes: global[\"encoding-indexes\"]\n    };\n  }\n\n// For strict environments where `this` inside the global scope\n// is `undefined`, take a pure object instead\n}(this || {}));"
  },
  {
    "path": "lib/text-encoding/package.json",
    "content": "{\n  \"_from\": \"text-encoding@^0.7.0\",\n  \"_id\": \"text-encoding@0.7.0\",\n  \"_inBundle\": false,\n  \"_integrity\": \"sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==\",\n  \"_location\": \"/text-encoding\",\n  \"_phantomChildren\": {},\n  \"_requested\": {\n    \"type\": \"range\",\n    \"registry\": true,\n    \"raw\": \"text-encoding@^0.7.0\",\n    \"name\": \"text-encoding\",\n    \"escapedName\": \"text-encoding\",\n    \"rawSpec\": \"^0.7.0\",\n    \"saveSpec\": null,\n    \"fetchSpec\": \"^0.7.0\"\n  },\n  \"_requiredBy\": [\n    \"/\",\n    \"/emailjs-mime-codec\"\n  ],\n  \"_resolved\": \"https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz\",\n  \"_shasum\": \"f895e836e45990624086601798ea98e8f36ee643\",\n  \"_spec\": \"text-encoding@^0.7.0\",\n  \"_where\": \"/Users/alive\",\n  \"author\": {\n    \"name\": \"Joshua Bell\",\n    \"email\": \"inexorabletash@gmail.com\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/inexorabletash/text-encoding/issues\"\n  },\n  \"bundleDependencies\": false,\n  \"contributors\": [\n    {\n      \"name\": \"Joshua Bell\",\n      \"email\": \"inexorabletash@gmail.com\"\n    },\n    {\n      \"name\": \"Rick Eyre\",\n      \"email\": \"rick.eyre@outlook.com\"\n    },\n    {\n      \"name\": \"Eugen Podaru\",\n      \"email\": \"eugen.podaru@live.com\"\n    },\n    {\n      \"name\": \"Filip Dupanović\",\n      \"email\": \"filip.dupanovic@gmail.com\"\n    },\n    {\n      \"name\": \"Anne van Kesteren\",\n      \"email\": \"annevk@annevk.nl\"\n    },\n    {\n      \"name\": \"Author: Francis Avila\",\n      \"email\": \"francisga@gmail.com\"\n    },\n    {\n      \"name\": \"Michael J. Ryan\",\n      \"email\": \"tracker1@gmail.com\"\n    },\n    {\n      \"name\": \"Pierre Queinnec\",\n      \"email\": \"pierre@queinnec.org\"\n    },\n    {\n      \"name\": \"Zack Weinberg\",\n      \"email\": \"zackw@panix.com\"\n    }\n  ],\n  \"deprecated\": \"no longer maintained\",\n  \"description\": \"Polyfill for the Encoding Living Standard's API.\",\n  \"files\": [\n    \"index.js\",\n    \"lib/encoding.js\",\n    \"lib/encoding-indexes.js\"\n  ],\n  \"homepage\": \"https://github.com/inexorabletash/text-encoding\",\n  \"keywords\": [\n    \"encoding\",\n    \"decoding\",\n    \"living standard\"\n  ],\n  \"license\": \"(Unlicense OR Apache-2.0)\",\n  \"main\": \"index.js\",\n  \"name\": \"text-encoding\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/inexorabletash/text-encoding.git\"\n  },\n  \"version\": \"0.7.0\"\n}\n"
  },
  {
    "path": "lib/then.d.ts",
    "content": "import { GunDataNode, IGunChain } from '..';\n\nimport {} from '../types/gun/IGunChain';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * Could be buggy until official!\n     *\n     * Note: a gun chain is not promises! You must include and call `.then()` to promisify a gun\n     *  chain!\n     */\n    then(): Promise<GunDataNode<TNode>>;\n\n    /**\n     * Could be buggy until official!\n     *\n     * `.then()` has a cousin of `.promise()` which behaves the same way except that resolved\n     *  is an object in case you need more context or metadata\n     */\n    promise(): Promise<{\n      put: GunDataNode<TNode>;\n      get: TKey;\n      gun: IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n    }>;\n  }\n}\n"
  },
  {
    "path": "lib/then.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\n// Returns a gun reference in a promise and then calls a callback if specified\nGun.chain.promise = function(cb) {\n  var gun = this, cb = cb || function(ctx) { return ctx };\n  return (new Promise(function(res, rej) {\n    gun.once(function(data, key){\n    \tres({put: data, get: key, gun: this}); // gun reference is returned by promise\n    });\n  })).then(cb); //calling callback with resolved data\n};\n\n// Returns a promise for the data, key of the gun call\nGun.chain.then = function(cb) {\n\tvar gun = this;\n  var p = (new Promise((res, rej)=>{\n    gun.once(function (data, key) {\n      res(data, key); //call resolve when data is returned\n    })\n  }))\n  return cb ? p.then(cb) : p;\n};\n"
  },
  {
    "path": "lib/time.js",
    "content": ";(function(){\n\tvar Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\tvar ify = Gun.node.ify, u;\n\tGun.chain.time = function(data, a, b){\n\t\tif(data instanceof Function){\n\t\t\treturn travel(data, a, b, this);\n\t\t}\n\t\tvar gun = this, root = gun.back(-1);\n\t\tvar cb = (a instanceof Function && a) || (b instanceof Function && b);\n\t\tif(Gun.is(data)){\n\t\t\tdata.get(function(soul){\n\t\t\t\tif(!soul){\n\t\t\t\t\treturn cb && cb({err: \"Timegraph cannot link `undefined`!\"});\n\t\t\t\t}\n\t\t\t\tgun.time(Gun.val.link.ify(soul), a, b);\n\t\t\t}, true);\n\t\t\treturn gun;\n\t\t}\n\t\topt = (cb === a)? b : a;\n\t\topt = Gun.text.is(opt)? {key: opt} : opt || {};\n\t\tvar t = new Date(Gun.state()).toISOString().split(/[\\-t\\:\\.z]/ig);\n\t\tvar p, tmp = t.pop();\n\t\tgun.get(function(soul){\n\t\t\tvar id = soul;\n\t\t\tp = id;\n\t\t\tif(!p){ id = p = (gun.back('opt.uuid') || Gun.text.random)(9) }\n\t\t\t// could shrink this into a loop. Do later?\n\t\t\tt = [p].concat(t);\n\t\t\tvar rid = opt.key || (gun.back('opt.uuid') || Gun.text.random)(9);\n\t\t\tvar milli = ify({}, t.join(':'));\n\t\t\tmilli[rid] = data;\n\t\t\ttmp = t.pop();\n\t\t\tvar sec = ify({}, t.join(':'));\n\t\t\tsec[tmp] = milli;\n\t\t\ttmp = t.pop();\n\t\t\tvar min = ify({}, t.join(':'));\n\t\t\tmin[tmp] = sec;\n\t\t\ttmp = t.pop();\n\t\t\tvar hour = ify({}, t.join(':'));\n\t\t\thour[tmp] = min;\n\t\t\ttmp = t.pop();\n\t\t\tvar day = ify({}, t.join(':'));\n\t\t\tday[tmp] = hour;\n\t\t\ttmp = t.pop();\n\t\t\tvar month = ify({}, t.join(':'));\n\t\t\tmonth[tmp] = day;\n\t\t\ttmp = t.pop();\n\t\t\tvar year = ify({}, t.join(':'));\n\t\t\tyear[tmp] = month;\n\t\t\ttmp = t.pop();\n\t\t\tvar time = ify({}, t.join(':') || id);\n\t\t\ttime[tmp] = year;\n\t\t\tgun.put(time, cb);\n\t\t}, true);\n\t\treturn gun;\n\t}\n\tfunction travel(cb, opt, b, gun){\n\t\tvar root = gun.back(-1), tmp;\n\t\t(opt = Gun.num.is(opt)? {last: opt} : opt || {}).seen = opt.seen || {};\n\t\tvar t = now(opt.start);\n\t\tgun.on(function(data, key, msg, eve){\n\t\t\tvar at = msg.$._, id = at.link || at.soul || Gun.node.soul(data);\n\t\t\tif(!id){ return }\n\t\t\tif(false === opt.next){ eve.off() }\n\t\t\telse { opt.next = true }\n\t\t\topt.start = [opt.id = id].concat(t);\n\t\t\topt.low = opt.low || opt.start;\n\t\t\topt.top = opt.top || opt.start;\n\t\t\topt.now = [id].concat(now());\n\t\t\t//console.log(\"UPDATE\");\n\t\t\tfind(opt, cb, root, opt.at? opt.now : opt.at = opt.start);\n\t\t});\n\t\treturn gun;\n\t}\n\tfunction now(t){\n\t\treturn new Date(t || Gun.state()).toISOString().split(/[\\-t\\:\\.z]/ig).slice(0,-1);\n\t}\n\tfunction find(o, cb, root, at, off){\n\t\tvar at = at || o.at, t = at.join(':'), tmp;\n\t\tif(!off){\n\t\t\tif(o.seen[t]){ return }\n\t\t\to.seen[t] = true;\n\t\t}\n\t\tvar next = (o.low || o.start)[at.length];\n\t\troot.get(t).get(function(msg, ev){\n\t\t\tif(off){ ev.off() }\n\t\t\tvar g = this;\n\t\t\t//console.log(at, msg.put);\n\t\t\tif(u === msg.put){\n\t\t\t\tfind(o, cb, root, at.slice(0,-1), off);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(7 < at.length){\n\t\t\t\tvar l = Object.keys(msg.put).length;\n\t\t\t\tif(l === o.seen[t]){ return }\n\t\t\t\tvar when = +(toDate(at));\n\t\t\t\tGun.node.is(msg.put, function(v, k){\n\t\t\t\t\tcb(v, k, when, ev);\n\t\t\t\t\tif(o.last){ --o.last }\n\t\t\t\t});\n\t\t\t\to.seen[t] = l;\n\t\t\t\tif(!o.last){ return }\n\t\t\t\tif(o.last <= 0){ return }\n\t\t\t\to.low = at;\n\t\t\t\tvar tmp = at.slice(0,-1);\n\t\t\t\tfind(o, cb, root, tmp, true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(o.last && false !== off){\n\t\t\t\tvar keys = Object.keys(msg.put).sort().reverse();\n\t\t\t\tvar less = Gun.list.map(keys, function(k){\n\t\t\t\t\tif(parseFloat(k) < parseFloat(next)){ return k }\n\t\t\t\t});\n\t\t\t\tif(!less){\n\t\t\t\t\tfind(o, cb, root, at.slice(0,-1), true);\n\t\t\t\t} else {\n\t\t\t\t\tvar tmp = (at || o.at).slice();\n\t\t\t\t\ttmp.push(less);\n\t\t\t\t\t(o.low = tmp.slice()).push(Infinity);\n\t\t\t\t\tfind(o, cb, root, tmp, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(off){ return }\n\t\t\tif(!o.next){ return }\n\t\t\tif(at < o.start.slice(0, at.length)){ return }\n\t\t\tvar n = [o.id].concat(now()), top = n[at.length];\n\t\t\tGun.node.is(msg.put, function(v, k){\n\t\t\t\tif(k > top){ return }\n\t\t\t\t(v = at.slice()).push(k);\n\t\t\t\tfind(o, cb, root, v, false);\n\t\t\t});\n\t\t})\n\t}\n\tfunction toDate(at){\n\t\tat = at.slice(-7);\n\t\treturn new Date(Date.UTC(at[0], parseFloat(at[1])-1, at[2], at[3], at[4], at[5], at[6]));\n\t}\n}());"
  },
  {
    "path": "lib/unbuild.js",
    "content": "var fs = require('fs');\nvar nodePath = require('path');\n\nvar dir = __dirname + '/../';\n\nvar read = function(path){\n\treturn fs.readFileSync(nodePath.join(dir, path)).toString();\n}\n\nvar write = function(path, data){\n\treturn fs.writeFileSync(nodePath.join(dir, path), data);\n}\n\nvar rm = require('./fsrm');\n\nvar mk = function(path){\n\tpath = nodePath.join(dir, path);\n  if(fs.existsSync(path)){ return }\n\tfs.mkdirSync(path);\n}\n\nvar rn = function(path, newPath){\n\tpath = nodePath.join(dir, path)\n\tnewPath = nodePath.join(dir, newPath)\n  if(fs.existsSync(newPath)){ return }\n\tfs.renameSync(path, newPath);\n}\n\nvar between = function(text, start, end){\n\tend = end || start;\n\tvar s = text.indexOf(start);\n\tif(s < 0){ return ''}\n\ts += start.length;\n\tvar e = text.indexOf(end, s);\n\tif(e < 0){ return '' }\n\tvar code = text.slice(s, e);\n\treturn {s: s, t: code, e: e};\n}\n\nvar next = function(start, end){\n\tend = end || start;\n\tif(!next.text){\n\t\tnext.text = start;\n\t\treturn;\n\t}\n\tvar code = between(next.text, start, end);\n\tnext.text = next.text.slice(code.e + end.length);\n\treturn code.t;\n}\n\nvar path = function(p){\n\tvar code = next(',', ')');\n\tvar path;\n\ttry{path = eval(code);\n\t}catch(e){console.log(\"fail\", e)};\n\tif(!path){ return }\n\tif('.js' !== path.slice(-3)){\n\t\tpath += '.js';\n\t}\n\treturn nodePath.join('./'+(p||'src'), path);\n}\n\nvar undent = function(code, n){\n\tvar regex = /\\n\\t\\t/g;\n\tif(1 === n){\n\t\tregex = /\\n\\t/g;\n\t}\n\treturn code.replace(regex, '\\n');\n}\n\n;(function(){\n\n\tvar arg = process.argv[2] || 'gun';\n\n\tvar g;\n\tif('gun' === arg){\n\t\tg = 'gun';\n\t\trn('./src','./old_src');\n\t\tmk('./src');\n\t\tmk('./src/polyfill');\n\t\tmk('./src/adapters');\n\t} else {\n\t\tg = arg;\n\t\trn('./'+arg,'./old_'+arg);\n\t\tmk('./'+arg);\n\t}\n\tconsole.log(\"unbuild:\", arg+'.js')\n\n\tvar f = read(arg+'.js');\n\tvar code = next(f);\n\n\n\tcode = next(\"/* UNBUILD */\");\n\t\n\tif('gun' === g){\n\t\twrite('src/polyfill/unbuild.js', undent(code, 1));\n\t\targ = '';\n\t}\n\n\t(function recurse(c){\n\t\tcode = next(\";USE(function(module){\", \"})(USE\");\n\t\tif(!code){ return }\n\t\tvar file = path(arg);\n\t\tif(!file){ return }\n\t\tcode = code.replace(/\\bUSE\\(/g, 'require(');\n\t\tcode = undent(code);\n\t\tvar rcode;\n\t\ttry{ rcode = read('old_'+file); } catch(e){}\n\t\t// console.log(rcode);\n\t\tif(rcode != code){\n\t\t\tconsole.log(\"unbuild:\",\"update\",file);\n\t\t}\n\t\tcode = \";(function(){\\n\"+code+\"\\n}());\";\n\t\twrite(file, code);\n\t\trecurse();\n\t}());\n\tif('gun' === g){\n\t\trm('./old_src');\n\t}else{\n\t\trm('./old_'+g);\n\t}\n\t\n}());\n"
  },
  {
    "path": "lib/unset.d.ts",
    "content": "import { GunSchema, GunSoul, IGunChain } from '..';\n\nimport {} from '../types/gun/IGunChain';\nimport { IGunChain2TNode } from '../types/utils';\ndeclare module '../types/gun/IGunChain' {\n  export interface IGunChain<TNode, TChainParent, TGunInstance, TKey> {\n    /**\n     * After you save some data in an unordered list, you may need to remove it\n     */\n    unset<\n      T extends Partial<V> | GunSoul<V> | IGunChain<V, any, any, any>,\n      K extends keyof TNode & string,\n      V extends TNode[K] & Record<string, GunSchema>\n    >(\n      node: IGunChain<\n        IGunChain2TNode<T>,\n        IGunChain<TNode, TChainParent, TGunInstance, TKey>,\n        TGunInstance,\n        K\n      >\n    ): IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n  }\n}\n"
  },
  {
    "path": "lib/unset.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\nconst rel_ = '#';  // '#'\nconst node_ = '_';  // '_'\n\nGun.chain.unset = function(node){\n\tif( this && node && node[node_] && node[node_].put && node[node_].put[node_] && node[node_].put[node_][rel_] ){\n\t\tthis.put( { [node[node_].put[node_][rel_]]:null} );\n\t}\n\treturn this;\n}\n"
  },
  {
    "path": "lib/untitled.js",
    "content": "function input(msg){\n\tvar ev = this, cat = this.as, gun = msg.gun, at = gun._, change = msg.put, rel, tmp;\n\t// dispatch to chain listeners.\n\t// dispatch to children.\n\t// dispatch to echoes.\n\tif(u === change){\n\t\t// Here are the possible options:\n\t\t// 1. We think the data does not exist because peers/disk cannot find it.\n\t\t// 2. We know the data does not exist because a parent is or was changed to a primitive.\n\t\t// Souls can only (1) because they have no parent.\n\t\t// Has can be (1) or (2).\n\t\t// Gets and chains can be (1) or (2).\n\t\tif(cat.soul || cat.has){\n\t\t\t// a soul can never become undefined.\n\t\t\t// a soul can only not be found.\n\t\t\tif(cat.soul && u !== cat.put){\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// a key may sometimes might not be found.\n\t\t\t// a key on a soul can not become undefined,\n\t\t\t// but the chain might be on a chain that\n\t\t\t// does not exist, and therefore can be undefined.\n\t\t\tev.to.next(msg); // ex, notify val and stuff.\n\t\t\techo(cat, msg, ev); // ex, notify a sub-object pointer like `mark.pet`! // TODO: BUG ON VAL, it will still not get called because it checks !node when it should also check ack.\n\t\t\tif(cat.soul){ return }\n\t\t\tobj_map(cat.next, unknown); // notify children.\n\t\t}\n\t\tif(cat.has){\n\t\t\tif()\n\t\t}\n\t\treturn;\n\t}\n\tif(cat.soul){\n\t\treturn;\n\t}\n\tif(cat.has){\n\t\treturn;\n\t}\n\tif(cat.get){\n\t\treturn;\n\t}\n\tev.to.next(msg);\n}\n\nfunction unknown(ref, key){\n\t(ref = (ref._)).put = u;\n\tref.on('in', {get: key, put: u, gun: ref.gun});\n}\n\ngun.get('users').map().map().get('who').get('say').map().on(cb);"
  },
  {
    "path": "lib/upload.js",
    "content": ";(function(){\n\tfunction upload(cb, opt){\n\t\tvar el = $(this); cb = cb || function(){};\n\t\topt = $.isPlainObject(opt)? opt : {input: opt}; \n\t\tel.on('drop', function(e){\n\t\t\te.preventDefault();\n\t\t\tupload.drop(((e.originalEvent||e).dataTransfer||{}).files||[], 0);\n\t\t}).on('dragover', function(e){\n\t\t\te.preventDefault();\n\t\t});\n\t\t$(opt.input||el).on('change', function(e){\n\t\t\tif(!(e = (e.target||this||{}).files)){ return }\n\t\t\tupload.drop(e, 0);\n\t\t});\n\t\tupload.drop = function(files,i){\n\t\t\tif(opt.max && (files[i].fileSize > opt.max || files[i].size > opt.max)){\n\t\t\t\tcb({err: \"File size is too large.\", file: file[i]}, upload);\n\t\t\t\tif(files[++i]){ upload.drop(files,i) }\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar reader = new FileReader();\n\t\t\treader.onload = function(e){\n\t\t\t\tcb({file: files[i], event: e, id: i}, upload);\n\t\t\t\tif(files[++i]){ upload.drop(files,i) }\n\t\t\t};\n\t\t\tif(files[i]){ reader.readAsDataURL(files[i]) }\n\t\t}\n\t\treturn this;\n\t}\n\tupload.shrink = function(e, cb, w, h){ // via stackoverflow\n\t\tif(!e){ return cb && cb({err: \"No file!\"}) }\n\t\tif(e.err){ return }\n\t\tvar file = (((e.event || e).target || e).result || e), img = new Image();\n\t\tif(!((file||'').split(';')[0].indexOf('image') + 1)){ e.err = \"Not an image!\"; return cb(e) }\n    img.crossOrigin = \"Anonymous\";\n    img.src = file;\n    img.onload = function(){\n    \tif(img.width < (w = w || 1000) && img.height < (h||Infinity) && \"data:\" == file.slice(0,5)){\n    \t\te.base64 = file;\n    \t\treturn cb(e || file);\n    \t}\n      if(!h){ h = img.height * (w / img.width) }\n\t\t\tvar canvas = document.createElement('canvas'), ctx = canvas.getContext('2d');\n\t    canvas.width = w;\n\t    canvas.height = h;\n\t    ctx.drawImage(img, 0, 0, w, h); // draw source image to canvas.\n\t    var b64 = e.base64 = canvas.toDataURL(); // base64 the shrunk image.\n\t    cb((e.base64 && e) || b64); \n    };\n\t}\n\t$.fn.upload = upload;\n}());"
  },
  {
    "path": "lib/utils.js",
    "content": ";(function(){\n\tvar u;\n\tif(''+u == typeof Gun){ return }\n\tvar DEP = function(n){ console.log(\"Warning! Deprecated internal utility will break in next version:\", n) }\n\t// Generic javascript utilities.\n\tvar Type = Gun;\n\t//Type.fns = Type.fn = {is: function(fn){ return (!!fn && fn instanceof Function) }}\n\tType.fn = Type.fn || {is: function(fn){ DEP('fn'); return (!!fn && 'function' == typeof fn) }}\n\tType.bi = Type.bi || {is: function(b){ DEP('bi');return (b instanceof Boolean || typeof b == 'boolean') }}\n\tType.num = Type.num || {is: function(n){ DEP('num'); return !list_is(n) && ((n - parseFloat(n) + 1) >= 0 || Infinity === n || -Infinity === n) }}\n\tType.text = Type.text || {is: function(t){ DEP('text'); return (typeof t == 'string') }}\n\tType.text.ify = Type.text.ify || function(t){ DEP('text.ify');\n\t\tif(Type.text.is(t)){ return t }\n\t\tif(typeof JSON !== \"undefined\"){ return JSON.stringify(t) }\n\t\treturn (t && t.toString)? t.toString() : t;\n\t}\n\tType.text.random = Type.text.random || function(l, c){ DEP('text.random');\n\t\tvar s = '';\n\t\tl = l || 24; // you are not going to make a 0 length random number, so no need to check type\n\t\tc = c || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz';\n\t\twhile(l > 0){ s += c.charAt(Math.floor(Math.random() * c.length)); l-- }\n\t\treturn s;\n\t}\n\tType.text.match = Type.text.match || function(t, o){ var tmp, u; DEP('text.match');\n\t\tif('string' !== typeof t){ return false }\n\t\tif('string' == typeof o){ o = {'=': o} }\n\t\to = o || {};\n\t\ttmp = (o['='] || o['*'] || o['>'] || o['<']);\n\t\tif(t === tmp){ return true }\n\t\tif(u !== o['=']){ return false }\n\t\ttmp = (o['*'] || o['>'] || o['<']);\n\t\tif(t.slice(0, (tmp||'').length) === tmp){ return true }\n\t\tif(u !== o['*']){ return false }\n\t\tif(u !== o['>'] && u !== o['<']){\n\t\t\treturn (t >= o['>'] && t <= o['<'])? true : false;\n\t\t}\n\t\tif(u !== o['>'] && t >= o['>']){ return true }\n\t\tif(u !== o['<'] && t <= o['<']){ return true }\n\t\treturn false;\n\t}\n\tType.text.hash = Type.text.hash || function(s, c){ // via SO\n\t\tDEP('text.hash');\n\t\tif(typeof s !== 'string'){ return }\n\t  c = c || 0;\n\t  if(!s.length){ return c }\n\t  for(var i=0,l=s.length,n; i<l; ++i){\n\t    n = s.charCodeAt(i);\n\t    c = ((c<<5)-c)+n;\n\t    c |= 0;\n\t  }\n\t  return c;\n\t}\n\tType.list = Type.list || {is: function(l){ DEP('list'); return (l instanceof Array) }}\n\tType.list.slit = Type.list.slit || Array.prototype.slice;\n\tType.list.sort = Type.list.sort || function(k){ // creates a new sort function based off some key\n\t\tDEP('list.sort');\n\t\treturn function(A,B){\n\t\t\tif(!A || !B){ return 0 } A = A[k]; B = B[k];\n\t\t\tif(A < B){ return -1 }else if(A > B){ return 1 }\n\t\t\telse { return 0 }\n\t\t}\n\t}\n\tType.list.map = Type.list.map || function(l, c, _){ DEP('list.map'); return obj_map(l, c, _) }\n\tType.list.index = 1; // change this to 0 if you want non-logical, non-mathematical, non-matrix, non-convenient array notation\n\tType.obj = Type.boj || {is: function(o){ DEP('obj'); return o? (o instanceof Object && o.constructor === Object) || Object.prototype.toString.call(o).match(/^\\[object (\\w+)\\]$/)[1] === 'Object' : false }}\n\tType.obj.put = Type.obj.put || function(o, k, v){ DEP('obj.put'); return (o||{})[k] = v, o }\n\tType.obj.has = Type.obj.has || function(o, k){ DEP('obj.has'); return o && Object.prototype.hasOwnProperty.call(o, k) }\n\tType.obj.del = Type.obj.del || function(o, k){ DEP('obj.del'); \n\t\tif(!o){ return }\n\t\to[k] = null;\n\t\tdelete o[k];\n\t\treturn o;\n\t}\n\tType.obj.as = Type.obj.as || function(o, k, v, u){ DEP('obj.as'); return o[k] = o[k] || (u === v? {} : v) }\n\tType.obj.ify = Type.obj.ify || function(o){ DEP('obj.ify'); \n\t\tif(obj_is(o)){ return o }\n\t\ttry{o = JSON.parse(o);\n\t\t}catch(e){o={}};\n\t\treturn o;\n\t}\n\t;(function(){ var u;\n\t\tfunction map(v,k){\n\t\t\tif(obj_has(this,k) && u !== this[k]){ return }\n\t\t\tthis[k] = v;\n\t\t}\n\t\tType.obj.to = Type.obj.to || function(from, to){ DEP('obj.to'); \n\t\t\tto = to || {};\n\t\t\tobj_map(from, map, to);\n\t\t\treturn to;\n\t\t}\n\t}());\n\tType.obj.copy = Type.obj.copy || function(o){ DEP('obj.copy'); // because http://web.archive.org/web/20140328224025/http://jsperf.com/cloning-an-object/2\n\t\treturn !o? o : JSON.parse(JSON.stringify(o)); // is shockingly faster than anything else, and our data has to be a subset of JSON anyways!\n\t}\n\t;(function(){\n\t\tfunction empty(v,i){ var n = this.n, u;\n\t\t\tif(n && (i === n || (obj_is(n) && obj_has(n, i)))){ return }\n\t\t\tif(u !== i){ return true }\n\t\t}\n\t\tType.obj.empty = Type.obj.empty || function(o, n){ DEP('obj.empty'); \n\t\t\tif(!o){ return true }\n\t\t\treturn obj_map(o,empty,{n:n})? false : true;\n\t\t}\n\t}());\n\t;(function(){\n\t\tfunction t(k,v){\n\t\t\tif(2 === arguments.length){\n\t\t\t\tt.r = t.r || {};\n\t\t\t\tt.r[k] = v;\n\t\t\t\treturn;\n\t\t\t} t.r = t.r || [];\n\t\t\tt.r.push(k);\n\t\t};\n\t\tvar keys = Object.keys, map, u;\n\t\tObject.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) }\n\t\tType.obj.map = map = Type.obj.map || function(l, c, _){ DEP('obj.map'); \n\t\t\tvar u, i = 0, x, r, ll, lle, f = 'function' == typeof c;\n\t\t\tt.r = u;\n\t\t\tif(keys && obj_is(l)){\n\t\t\t\tll = keys(l); lle = true;\n\t\t\t}\n\t\t\t_ = _ || {};\n\t\t\tif(list_is(l) || ll){\n\t\t\t\tx = (ll || l).length;\n\t\t\t\tfor(;i < x; i++){\n\t\t\t\t\tvar ii = (i + Type.list.index);\n\t\t\t\t\tif(f){\n\t\t\t\t\t\tr = lle? c.call(_, l[ll[i]], ll[i], t) : c.call(_, l[i], ii, t);\n\t\t\t\t\t\tif(r !== u){ return r }\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//if(Type.test.is(c,l[i])){ return ii } // should implement deep equality testing!\n\t\t\t\t\t\tif(c === l[lle? ll[i] : i]){ return ll? ll[i] : ii } // use this for now\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor(i in l){\n\t\t\t\t\tif(f){\n\t\t\t\t\t\tif(obj_has(l,i)){\n\t\t\t\t\t\t\tr = _? c.call(_, l[i], i, t) : c(l[i], i, t);\n\t\t\t\t\t\t\tif(r !== u){ return r }\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//if(a.test.is(c,l[i])){ return i } // should implement deep equality testing!\n\t\t\t\t\t\tif(c === l[i]){ return i } // use this for now\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn f? t.r : Type.list.index? 0 : -1;\n\t\t}\n\t}());\n\tType.time = Type.time || {};\n\tType.time.is = Type.time.is || function(t){ DEP('time'); return t? t instanceof Date : (+new Date().getTime()) }\n\n\tvar fn_is = Type.fn.is;\n\tvar list_is = Type.list.is;\n\tvar obj = Type.obj, obj_is = obj.is, obj_has = obj.has, obj_map = obj.map;\n\n\tvar Val = {};\n\t// Valid values are a subset of JSON: null, binary, number (!Infinity), text,\n\t// or a soul relation. Arrays need special algorithms to handle concurrency,\n\t// so they are not supported directly. Use an extension that supports them if\n\t// needed but research their problems first.\n\tVal.is = function (v) {\n\t  DEP(\"val.is\");\n\t  // \"deletes\", nulling out keys.\n\t  return v === null ||\n\t\t\"string\" === typeof v ||\n\t\t\"boolean\" === typeof v ||\n\t\t// we want +/- Infinity to be, but JSON does not support it, sad face.\n\t\t// can you guess what v === v checks for? ;)\n\t\t(\"number\" === typeof v && v != Infinity && v != -Infinity && v === v) ||\n\t\t(!!v && \"string\" == typeof v[\"#\"] && Object.keys(v).length === 1 && v[\"#\"]);\n\t};\n\tVal.link = Val.rel = {_: '#'};\n\t;(function(){\n\t\tVal.link.is = function(v){ DEP('val.link.is'); // this defines whether an object is a soul relation or not, they look like this: {'#': 'UUID'}\n\t\t\tif(v && v[rel_] && !v._ && obj_is(v)){ // must be an object.\n\t\t\t\tvar o = {};\n\t\t\t\tobj_map(v, map, o);\n\t\t\t\tif(o.id){ // a valid id was found.\n\t\t\t\t\treturn o.id; // yay! Return it.\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false; // the value was not a valid soul relation.\n\t\t}\n\t\tfunction map(s, k){ var o = this; // map over the object...\n\t\t\tif(o.id){ return o.id = false } // if ID is already defined AND we're still looping through the object, it is considered invalid.\n\t\t\tif(k == rel_ && text_is(s)){ // the key should be '#' and have a text value.\n\t\t\t\to.id = s; // we found the soul!\n\t\t\t} else {\n\t\t\t\treturn o.id = false; // if there exists anything else on the object that isn't the soul, then it is considered invalid.\n\t\t\t}\n\t\t}\n\t}());\n\tVal.link.ify = function(t){ DEP('val.link.ify'); return obj_put({}, rel_, t) } // convert a soul into a relation and return it.\n\tType.obj.has._ = '.';\n\tvar rel_ = Val.link._, u;\n\tvar bi_is = Type.bi.is;\n\tvar num_is = Type.num.is;\n\tvar text_is = Type.text.is;\n\tvar obj = Type.obj, obj_is = obj.is, obj_put = obj.put, obj_map = obj.map;\n\n\tType.val = Type.val || Val;\n\n\tvar Node = {_: '_'};\n\tNode.soul = function(n, o){ DEP('node.soul'); return (n && n._ && n._[o || soul_]) } // convenience function to check to see if there is a soul on a node and return it.\n\tNode.soul.ify = function(n, o){ DEP('node.soul.ify'); // put a soul on an object.\n\t\to = (typeof o === 'string')? {soul: o} : o || {};\n\t\tn = n || {}; // make sure it exists.\n\t\tn._ = n._ || {}; // make sure meta exists.\n\t\tn._[soul_] = o.soul || n._[soul_] || text_random(); // put the soul on it.\n\t\treturn n;\n\t}\n\tNode.soul._ = Val.link._;\n\t;(function(){\n\t\tNode.is = function(n, cb, as){ DEP('node.is'); var s; // checks to see if an object is a valid node.\n\t\t\tif(!obj_is(n)){ return false } // must be an object.\n\t\t\tif(s = Node.soul(n)){ // must have a soul on it.\n\t\t\t\treturn !obj_map(n, map, {as:as,cb:cb,s:s,n:n});\n\t\t\t}\n\t\t\treturn false; // nope! This was not a valid node.\n\t\t}\n\t\tfunction map(v, k){ // we invert this because the way we check for this is via a negation.\n\t\t\tif(k === Node._){ return } // skip over the metadata.\n\t\t\tif(!Val.is(v)){ return true } // it is true that this is an invalid node.\n\t\t\tif(this.cb){ this.cb.call(this.as, v, k, this.n, this.s) } // optionally callback each key/value.\n\t\t}\n\t}());\n\t;(function(){\n\t\tNode.ify = function(obj, o, as){ DEP('node.ify'); // returns a node from a shallow object.\n\t\t\tif(!o){ o = {} }\n\t\t\telse if(typeof o === 'string'){ o = {soul: o} }\n\t\t\telse if('function' == typeof o){ o = {map: o} }\n\t\t\tif(o.map){ o.node = o.map.call(as, obj, u, o.node || {}) }\n\t\t\tif(o.node = Node.soul.ify(o.node || {}, o)){\n\t\t\t\tobj_map(obj, map, {o:o,as:as});\n\t\t\t}\n\t\t\treturn o.node; // This will only be a valid node if the object wasn't already deep!\n\t\t}\n\t\tfunction map(v, k){ var o = this.o, tmp, u; // iterate over each key/value.\n\t\t\tif(o.map){\n\t\t\t\ttmp = o.map.call(this.as, v, ''+k, o.node);\n\t\t\t\tif(u === tmp){\n\t\t\t\t\tobj_del(o.node, k);\n\t\t\t\t} else\n\t\t\t\tif(o.node){ o.node[k] = tmp }\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(Val.is(v)){\n\t\t\t\to.node[k] = v;\n\t\t\t}\n\t\t}\n\t}());\n\tvar obj = Type.obj, obj_is = obj.is, obj_del = obj.del, obj_map = obj.map;\n\tvar text = Type.text, text_random = text.random;\n\tvar soul_ = Node.soul._;\n\tvar u;\n\tType.node = Type.node || Node;\n\n\tvar State = Type.state;\n\tState.lex = function(){ DEP('state.lex'); return State().toString(36).replace('.','') }\n\tState.to = function(from, k, to){ DEP('state.to'); \n\t\tvar val = (from||{})[k];\n\t\tif(obj_is(val)){\n\t\t\tval = obj_copy(val);\n\t\t}\n\t\treturn State.ify(to, k, State.is(from, k), val, Node.soul(from));\n\t}\n\t;(function(){\n\t\tState.map = function(cb, s, as){ DEP('state.map'); var u; // for use with Node.ify\n\t\t\tvar o = obj_is(o = cb || s)? o : null;\n\t\t\tcb = fn_is(cb = cb || s)? cb : null;\n\t\t\tif(o && !cb){\n\t\t\t\ts = num_is(s)? s : State();\n\t\t\t\to[N_] = o[N_] || {};\n\t\t\t\tobj_map(o, map, {o:o,s:s});\n\t\t\t\treturn o;\n\t\t\t}\n\t\t\tas = as || obj_is(s)? s : u;\n\t\t\ts = num_is(s)? s : State();\n\t\t\treturn function(v, k, o, opt){\n\t\t\t\tif(!cb){\n\t\t\t\t\tmap.call({o: o, s: s}, v,k);\n\t\t\t\t\treturn v;\n\t\t\t\t}\n\t\t\t\tcb.call(as || this || {}, v, k, o, opt);\n\t\t\t\tif(obj_has(o,k) && u === o[k]){ return }\n\t\t\t\tmap.call({o: o, s: s}, v,k);\n\t\t\t}\n\t\t}\n\t\tfunction map(v,k){\n\t\t\tif(N_ === k){ return }\n\t\t\tState.ify(this.o, k, this.s) ;\n\t\t}\n\t}());\n\tvar obj = Type.obj, obj_as = obj.as, obj_has = obj.has, obj_is = obj.is, obj_map = obj.map, obj_copy = obj.copy;\n\tvar num = Type.num, num_is = num.is;\n\tvar fn = Type.fn, fn_is = fn.is;\n\tvar N_ = Node._, u;\n\n\tvar Graph = {};\n\t;(function(){\n\t\tGraph.is = function(g, cb, fn, as){ DEP('graph.is'); // checks to see if an object is a valid graph.\n\t\t\tif(!g || !obj_is(g) || obj_empty(g)){ return false } // must be an object.\n\t\t\treturn !obj_map(g, map, {cb:cb,fn:fn,as:as}); // makes sure it wasn't an empty object.\n\t\t}\n\t\tfunction map(n, s){ // we invert this because the way'? we check for this is via a negation.\n\t\t\tif(!n || s !== Node.soul(n) || !Node.is(n, this.fn, this.as)){ return true } // it is true that this is an invalid graph.\n\t\t\tif(!this.cb){ return }\n\t\t\tnf.n = n; nf.as = this.as; // sequential race conditions aren't races.\n\t\t\tthis.cb.call(nf.as, n, s, nf);\n\t\t}\n\t\tfunction nf(fn){ // optional callback for each node.\n\t\t\tif(fn){ Node.is(nf.n, fn, nf.as) } // where we then have an optional callback for each key/value.\n\t\t}\n\t}());\n\t;(function(){\n\t\tGraph.ify = function(obj, env, as){ DEP('graph.ify'); \n\t\t\tvar at = {path: [], obj: obj};\n\t\t\tif(!env){\n\t\t\t\tenv = {};\n\t\t\t} else\n\t\t\tif(typeof env === 'string'){\n\t\t\t\tenv = {soul: env};\n\t\t\t} else\n\t\t\tif('function' == typeof env){\n\t\t\t\tenv.map = env;\n\t\t\t}\n\t\t\tif(typeof as === 'string'){\n\t\t\t\tenv.soul = env.soul || as;\n\t\t\t\tas = u;\n\t\t\t}\n\t\t\tif(env.soul){\n\t\t\t\tat.link = Val.link.ify(env.soul);\n\t\t\t}\n\t\t\tenv.shell = (as||{}).shell;\n\t\t\tenv.graph = env.graph || {};\n\t\t\tenv.seen = env.seen || [];\n\t\t\tenv.as = env.as || as;\n\t\t\tnode(env, at);\n\t\t\tenv.root = at.node;\n\t\t\treturn env.graph;\n\t\t}\n\t\tfunction node(env, at){ var tmp;\n\t\t\tif(tmp = seen(env, at)){ return tmp }\n\t\t\tat.env = env;\n\t\t\tat.soul = soul;\n\t\t\tif(Node.ify(at.obj, map, at)){\n\t\t\t\tat.link = at.link || Val.link.ify(Node.soul(at.node));\n\t\t\t\tif(at.obj !== env.shell){\n\t\t\t\t\tenv.graph[Val.link.is(at.link)] = at.node;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn at;\n\t\t}\n\t\tfunction map(v,k,n){\n\t\t\tvar at = this, env = at.env, is, tmp;\n\t\t\tif(Node._ === k && obj_has(v,Val.link._)){\n\t\t\t\treturn n._; // TODO: Bug?\n\t\t\t}\n\t\t\tif(!(is = valid(v,k,n, at,env))){ return }\n\t\t\tif(!k){\n\t\t\t\tat.node = at.node || n || {};\n\t\t\t\tif(obj_has(v, Node._) && Node.soul(v)){ // ? for safety ?\n\t\t\t\t\tat.node._ = obj_copy(v._);\n\t\t\t\t}\n\t\t\t\tat.node = Node.soul.ify(at.node, Val.link.is(at.link));\n\t\t\t\tat.link = at.link || Val.link.ify(Node.soul(at.node));\n\t\t\t}\n\t\t\tif(tmp = env.map){\n\t\t\t\ttmp.call(env.as || {}, v,k,n, at);\n\t\t\t\tif(obj_has(n,k)){\n\t\t\t\t\tv = n[k];\n\t\t\t\t\tif(u === v){\n\t\t\t\t\t\tobj_del(n, k);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(!(is = valid(v,k,n, at,env))){ return }\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!k){ return at.node }\n\t\t\tif(true === is){\n\t\t\t\treturn v;\n\t\t\t}\n\t\t\ttmp = node(env, {obj: v, path: at.path.concat(k)});\n\t\t\tif(!tmp.node){ return }\n\t\t\treturn tmp.link; //{'#': Node.soul(tmp.node)};\n\t\t}\n\t\tfunction soul(id){ var at = this;\n\t\t\tvar prev = Val.link.is(at.link), graph = at.env.graph;\n\t\t\tat.link = at.link || Val.link.ify(id);\n\t\t\tat.link[Val.link._] = id;\n\t\t\tif(at.node && at.node[Node._]){\n\t\t\t\tat.node[Node._][Val.link._] = id;\n\t\t\t}\n\t\t\tif(obj_has(graph, prev)){\n\t\t\t\tgraph[id] = graph[prev];\n\t\t\t\tobj_del(graph, prev);\n\t\t\t}\n\t\t}\n\t\tfunction valid(v,k,n, at,env){ var tmp;\n\t\t\tif(Val.is(v)){ return true }\n\t\t\tif(obj_is(v)){ return 1 }\n\t\t\tif(tmp = env.invalid){\n\t\t\t\tv = tmp.call(env.as || {}, v,k,n);\n\t\t\t\treturn valid(v,k,n, at,env);\n\t\t\t}\n\t\t\tenv.err = \"Invalid value at '\" + at.path.concat(k).join('.') + \"'!\";\n\t\t\tif(Type.list.is(v)){ env.err += \" Use `.set(item)` instead of an Array.\" }\n\t\t}\n\t\tfunction seen(env, at){\n\t\t\tvar arr = env.seen, i = arr.length, has;\n\t\t\twhile(i--){ has = arr[i];\n\t\t\t\tif(at.obj === has.obj){ return has }\n\t\t\t}\n\t\t\tarr.push(at);\n\t\t}\n\t}());\n\tGraph.node = function(node){ DEP('graph.node'); \n\t\tvar soul = Node.soul(node);\n\t\tif(!soul){ return }\n\t\treturn obj_put({}, soul, node);\n\t}\n\t;(function(){\n\t\tGraph.to = function(graph, root, opt){ DEP('graph.to'); \n\t\t\tif(!graph){ return }\n\t\t\tvar obj = {};\n\t\t\topt = opt || {seen: {}};\n\t\t\tobj_map(graph[root], map, {obj:obj, graph: graph, opt: opt});\n\t\t\treturn obj;\n\t\t}\n\t\tfunction map(v,k){ var tmp, obj;\n\t\t\tif(Node._ === k){\n\t\t\t\tif(obj_empty(v, Val.link._)){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.obj[k] = obj_copy(v);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(!(tmp = Val.link.is(v))){\n\t\t\t\tthis.obj[k] = v;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(obj = this.opt.seen[tmp]){\n\t\t\t\tthis.obj[k] = obj;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.obj[k] = this.opt.seen[tmp] = Graph.to(this.graph, tmp, this.opt);\n\t\t}\n\t}());\n\tvar fn_is = Type.fn.is;\n\tvar obj = Type.obj, obj_is = obj.is, obj_del = obj.del, obj_has = obj.has, obj_empty = obj.empty, obj_put = obj.put, obj_map = obj.map, obj_copy = obj.copy;\n\tvar u;\n\tType.graph = Type.graph || Graph;\n}());\n"
  },
  {
    "path": "lib/uws.js",
    "content": "var Gun = require('../gun');\n\nvar WebSocket = require('uws');\n\nvar url = require('url');\n\nconsole.log(\"Experimental high performance uWS server is being used.\");\n\nGun.on('opt', function mount(ctx){\n\tthis.to.next(ctx);\n\tvar opt = ctx.opt;\n\tif(ctx.once){ return }\n\tif(!opt.web){ return }\n\tvar ws = opt.uws || opt.ws || (opt.uws = {}), batch;\n\n\tws.server = ws.server || opt.web;\n\tws.path = ws.path || '/gun';\n\n\tws.web = new WebSocket.Server(ws);\n\n\tws.web.on('connection', function(wire){\n\t\twire.upgradeReq = wire.upgradeReq || {};\n\t\twire.url = url.parse(wire.upgradeReq.url||'', true);\n\t\twire.id = wire.id || Gun.text.random(6);\n\t\tvar peer = opt.peers[wire.id] = {wire: wire};\n\t\tpeer.wire = function(){ return peer };\n\t\tctx.on('hi', peer);\n\t\twire.on('message', function(msg){\n\t\t\t//console.log(\"MESSAGE\", msg);\n\t\t\treceive(msg, wire, ctx); // diff: wire is wire.\n\t\t});\n\t\twire.on('close', function(){\n\t\t\tctx.on('bye', peer);\n\t\t\tGun.obj.del(opt.peers, wire.id);\n\t\t});\n\t\twire.on('error', function(e){});\n\t});\t\n\n\tctx.on('out', function(at){\n\t\tthis.to.next(at);\n\t\tbatch = JSON.stringify(at);\n\t\tif(ws.drain){\n\t\t\tws.drain.push(batch);\n\t\t\treturn;\n\t\t}\n\t\tws.drain = [];\n\t\tsetTimeout(function(){\n\t\t\tif(!ws.drain){ return }\n\t\t\tvar tmp = ws.drain;\n\t\t\tws.drain = null;\n\t\t\tif(!tmp.length){ return }\n\t\t\tbatch = JSON.stringify(tmp);\n\t\t\tGun.obj.map(opt.peers, send, ctx);\n\t\t}, opt.gap || opt.wait || 1);\n\t\tGun.obj.map(opt.peers, send, ctx);\n\t});\n\n\t// EVERY message taken care of. The \"extra\" ones are from in-memory not having \"asked\" for it yet - which we won't want it to do for foreign requests. Likewise, lots of chattyness because the put/ack replies happen before the `get` syncs so everybody now has it in-memory already to reply with.\n\tfunction send(peer){\n\t\tvar ctx = this, msg = batch;\n\t\tvar wire = peer.wire || open(peer, ctx);\n\t\tif(!wire){ return }\n\t\tif(wire.readyState === wire.OPEN){\n\t\t\twire.send(msg);\n\t\t\treturn;\n\t\t}\n\t\t(peer.queue = peer.queue || []).push(msg);\n\t}\n\tfunction receive(msg, wire, ctx){\n\t\tif(!ctx){ return }\n\t\ttry{msg = JSON.parse(msg.data || msg);\n\t\t}catch(e){}\n\t\tif(msg instanceof Array){\n\t\t\tvar i = 0, m;\n\t\t\twhile(m = msg[i++]){\n\t\t\t\treceive(m, wire, ctx); // wire not peer!\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tmsg.peer = wire.peer;\n\t\tctx.on('in', msg);\n\t}\n\tfunction open(peer, as){\n\t\tif(!peer || !peer.url){ return }\n\t\tvar url = peer.url.replace('http', 'ws');\n\t\tvar wire = peer.wire = new WebSocket(url);\n\t\twire.on('close', function(){\n\t\t\treconnect(peer, as);\n\t\t});\n\t\twire.on('error', function(error){\n\t\t\tif(!error){ return }\n\t\t\tif(error.code === 'ECONNREFUSED'){\n\t\t\t\treconnect(peer, as); // placement?\n\t\t\t}\n\t\t});\n\t\twire.on('open', function(){\n\t\t\tvar queue = peer.queue;\n\t\t\tpeer.queue = [];\n\t\t\tGun.obj.map(queue, function(msg){\n\t\t\t\tbatch = msg;\n\t\t\t\tsend.call(as, peer);\n\t\t\t});\n\t\t});\n\t\twire.on('message', function(msg){\n\t\t\treceive(msg, wire, as); // diff: wire not peer!\n\t\t});\n\t\treturn wire;\n\t}\n\n\tfunction reconnect(peer, as){\n\t\tclearTimeout(peer.defer);\n\t\tpeer.defer = setTimeout(function(){\n\t\t\topen(peer, as);\n\t\t}, 2 * 1000);\n\t}\n});"
  },
  {
    "path": "lib/verify.js",
    "content": "var url = require('url');\nvar Gun = require('../gun');\n\n/**\n * Verify the origin\n * \n * @param  {RegExp|Array|String|Function} allowed   The allowed origins\n * @param  {String}              origin    String representation of the request URL\n * @return {Boolean}             Whether or not the origin is valid\n */\nvar verifyOrigin = function(allowed, origin) {\n    var isValid = false;\n    if (allowed instanceof RegExp) {\n        isValid = allowed.test(origin);\n    } else if (allowed instanceof Array) {\n        isValid = allowed.indexOf(origin) !== -1;\n    } else if (allowed instanceof Function) {\n        isValid = allowed(origin);\n    } else {\n        isValid = allowed === origin;\n    }\n    return isValid;\n};\n\n/**\n * Verify the authentication header\n *\n * @todo  make this callback based\n * \n * @param  {Function|String} check       Check option passed in\n * @param  {String}          authToken   The auth token passed in query string\n * @param  {Object}          query       Full query string as an object\n * @return {Boolean}         Whether or not the auth header is valid\n */\nvar verifyAuth = function(check, authToken, query) {\n    var isValid = false;\n    if (check instanceof Function) {\n        isValid = check(authToken, query);\n    } else {\n        isValid = check === authToken;\n    }\n    return isValid === true;\n};\n\nGun.on('opt', function(context) {\n    var opt = context.opt || {};\n    var ws = opt.ws || {};\n\n    if (!opt.verify) {\n        this.to.next(context);\n        return;\n    }\n\n    /**\n     *  verify when instantiating Gun can contain the following keys:\n     *      allowOrigins: Array|RegExp|String\n     *      auth:         String|Function\n     *      authKey:      String\n     *      check:        Function\n     */\n    var verify = opt.verify;\n    if (ws.verifyClient && !verify.override) {\n        throw Error('Cannot override existing verifyClient option in `ws` configuration.');\n    }\n\n    /**\n     * Attach a verifyClient to the WS configuration.\n     * \n     * @param  {Object}   info      Request information\n     * @param  {Function} callback  Called when verification is complete\n     */\n    ws.verifyClient = function(info, callback) {\n\n        // Callback Definitions\n        var errorCallback = (errorCode, message) => {\n            callback(false, errorCode, message);\n        };\n        var successCallback = () => {\n            callback(true);\n        };\n\n        // 0. Verify security\n        if (verify.requireSecure && !info.secure) {\n            errorCallback(400, 'Insecure connection');\n            return;\n        }\n\n        // 1. Verify request origin\n        if (verify.allowOrigins && !verifyOrigin(verify.allowOrigins, info.origin)) {\n            errorCallback(403, 'Origin forbidden');\n            return;\n        }\n\n        // 2. Check authentication\n        if (verify.auth) {\n\n            // Retrieve parameters from the query string\n            // and convert into an object\n            var queryUrl = url.parse(info.req.url, true);\n            queryUrl.query = queryUrl.query || {};\n\n            // Get the header defined by the user\n            // Or use authorization by default.\n            var token = (verify.authKey)\n                            ? queryUrl.query[verify.authKey]\n                                : queryUrl.query.authorization;\n\n            // Check the token against the verification function\n            if (!token || !verifyAuth(verify.auth, token, queryUrl.query)) {\n                errorCallback(403, 'Forbidden');\n                return;\n            }\n        }\n\n        // If no additional verification check is provided, \n        // simply return true at this point since all \n        // provided verifications have passed.\n        if (!verify.check) {\n            successCallback();\n            return;\n        }\n\n        // 3. Pass to generic check handler\n        // This can return a value; alternatively, this can use the\n        // callback functionality\n        var isValid = verify.check(info, successCallback, errorCallback); \n\n        // Check returned a response, pass this to the callback\n        // If not, assume the user will call\n        if (typeof isValid !== 'undefined') {\n            if (typeof isValid === 'boolean') {\n                if (isValid === true) {\n                    successCallback();\n                } else {\n                    errorCallback(400);\n                }\n            }\n        }          \n    };\n    context.opt.ws = ws;\n\n    // Pass to next plugins\n    this.to.next(context);\n});\n\nmodule.exports = Gun;\n"
  },
  {
    "path": "lib/wave.js",
    "content": "/**\n * Create music from text.\n * examples/wave.html\n *\n * Music Makers is an application using the same libraries as Wave:\n * https://github.com/jussiry/musicmakers\n * http://edide.xyz/musicmakers.app\n * https://edide.io/musicmakers.app\n */\n\n\"use strict\";\n(function(){\nvar MODSELF, edide = {};\nedide.global = (function (edide, mod_global) {\n\n  return typeof global !== 'undefined' ? global : window;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.set = (function (edide, set) {Object.defineProperty(this, 'module_name', {value:'set'});\n\n  set = (...args) => new Set(args)\n\n  set.addArr = (s, arr) => {\n    var i, len\n    for (i = 0, len = arr.length; i < len; i++) {\n      s.add(arr[i])\n    }\n  }\n\n  set.map = (s, func) => Array.from(s).map(func)\nreturn set;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.membrameSynth = (function (edide, membrameSynth) {Object.defineProperty(this, 'module_name', {value:'membrameSynth'});\n  this.startNote = 'A0';\n\n  this.init = () => {\n    var bd, compressor, distortion, gain, reverb;\n    distortion = new Tone.Distortion({\n      distortion: 0.1,\n      oversample: \"4x\" // none, 2x, 4x\n    });\n    reverb = new Tone.Freeverb(0.75, 1000);\n    gain = new Tone.Gain(0.5);\n    compressor = new Tone.Compressor({\n      ratio: 12,\n      threshold: -24,\n      release: 0.05,\n      attack: 0.003,\n      knee: 1\n    });\n    bd = new Tone.MembraneSynth({\n      pitchDecay: 0.05,\n      octaves: 4,\n      envelope: {\n        attack: 0.01,\n        decay: 0.74,\n        sustain: 0.71,\n        release: 0.05,\n        attackCurve: \"exponential\"\n      }\n    });\n    bd.chain(gain, distortion, reverb, compressor);\n    return [bd, compressor];\n  };\n\nreturn membrameSynth;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.toneSynth = (function (edide, toneSynth) {Object.defineProperty(this, 'module_name', {value:'toneSynth'});\n  this.startNote = 'C3';\n\n  this.init = () => {\n    var ss;\n    return ss = new Tone.PolySynth(12, Tone.Synth, {\n      oscillator: {\n        type: 'sine'\n      },\n      envelope: {\n        attack: 0.005,\n        decay: 0.1,\n        sustain: 0.3,\n        release: 1\n      }\n    });\n  };\n\nreturn toneSynth;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.instrumentConfigs = (function (edide, instrumentConfigs) {\n\n  var configs = {\n    'bass-electric': {\n      startNote: 'C#2',\n      notes: 8, // 16\n      step: 3\n    },\n    'cello': {\n      startNote: 'C2',\n      notes: 11,\n      step: 2,\n      skipNotes: edide.set('F#2', 'C4')\n    },\n    'drum-electric': edide.membrameSynth,\n    'guitar-acoustic': {\n      startNote:  'D1',\n      notes: 26, // 36\n      step: 2,\n      skipNotes: edide.set('E4', 'F#4', 'G#4', 'A#4', 'C5', 'D5', 'E5')\n    },\n    'guitar-electric': {\n      startNote: 'F#2',\n      notes: 15, // 15\n      step: 3,\n    },\n    'piano': {\n      startNote: 'A1',\n      notes: 30, // 29\n      step: 2,\n      baseUrl: \"https://tonejs.github.io/examples/audio/salamander/\"\n    },\n    'synth-simple': edide.toneSynth,\n    'xylophone': {\n      startNote: 'G3',\n      notes: ['G3', 'C4', 'G4', 'C5', 'G5', 'C6', 'G6', 'C7']\n    }\n  }\n\n  for (let inst in configs) {\n    configs[inst].name = inst\n  }\n  return configs\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.objectFromArray = (function (edide, objectFromArray) {\n  var identity;\n\n  identity = function(el) {\n    return el;\n  };\n\n  return (array, valFromEl, keyFromEl) => {\n    var el, i, ind, len, obj;\n    if (valFromEl == null) {\n      valFromEl = identity;\n    }\n    if (keyFromEl == null) {\n      keyFromEl = identity;\n    }\n    obj = {};\n    for (ind = i = 0, len = array.length; i < len; ind = ++i) {\n      el = array[ind];\n      obj[keyFromEl(el, ind)] = valFromEl(el, ind);\n    }\n    return obj;\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.noteFreq = (function (edide, noteFreq) {Object.defineProperty(this, 'module_name', {value:'noteFreq'});\n  var a4, noteMap, notesObj;\n\n  this.notes = [['C0', 16.35, 2109.89], ['C#0', 17.32, 1991.47], ['D0', 18.35, 1879.69], ['D#0', 19.45, 1774.20], ['E0', 20.60, 1674.62], ['F0', 21.83, 1580.63], ['F#0', 23.12, 1491.91], ['G0', 24.50, 1408.18], ['G#0', 25.96, 1329.14], ['A0', 27.50, 1254.55], ['A#0', 29.14, 1184.13], ['B0', 30.87, 1117.67], ['C1', 32.70, 1054.94], ['C#1', 34.65, 995.73], ['D1', 36.71, 939.85], ['D#1', 38.89, 887.10], ['E1', 41.20, 837.31], ['F1', 43.65, 790.31], ['F#1', 46.25, 745.96], ['G1', 49.00, 704.09], ['G#1', 51.91, 664.57], ['A1', 55.00, 627.27], ['A#1', 58.27, 592.07], ['B1', 61.74, 558.84], ['C2', 65.41, 527.47], ['C#2', 69.30, 497.87], ['D2', 73.42, 469.92], ['D#2', 77.78, 443.55], ['E2', 82.41, 418.65], ['F2', 87.31, 395.16], ['F#2', 92.50, 372.98], ['G2', 98.00, 352.04], ['G#2', 103.83, 332.29], ['A2', 110.00, 313.64], ['A#2', 116.54, 296.03], ['B2', 123.47, 279.42], ['C3', 130.81, 263.74], ['C#3', 138.59, 248.93], ['D3', 146.83, 234.96], ['D#3', 155.56, 221.77], ['E3', 164.81, 209.33], ['F3', 174.61, 197.58], ['F#3', 185.00, 186.49], ['G3', 196.00, 176.02], ['G#3', 207.65, 166.14], ['A3', 220.00, 156.82], ['A#3', 233.08, 148.02], ['B3', 246.94, 139.71], ['C4', 261.63, 131.87], ['C#4', 277.18, 124.47], ['D4', 293.66, 117.48], ['D#4', 311.13, 110.89], ['E4', 329.63, 104.66], ['F4', 349.23, 98.79], ['F#4', 369.99, 93.24], ['G4', 392.00, 88.01], ['G#4', 415.30, 83.07], ['A4', 440.00, 78.41], ['A#4', 466.16, 74.01], ['B4', 493.88, 69.85], ['C5', 523.25, 65.93], ['C#5', 554.37, 62.23], ['D5', 587.33, 58.74], ['D#5', 622.25, 55.44], ['E5', 659.25, 52.33], ['F5', 698.46, 49.39], ['F#5', 739.99, 46.62], ['G5', 783.99, 44.01], ['G#5', 830.61, 41.54], ['A5', 880.00, 39.20], ['A#5', 932.33, 37.00], ['B5', 987.77, 34.93], ['C6', 1046.50, 32.97], ['C#6', 1108.73, 31.12], ['D6', 1174.66, 29.37], ['D#6', 1244.51, 27.72], ['E6', 1318.51, 26.17], ['F6', 1396.91, 24.70], ['F#6', 1479.98, 23.31], ['G6', 1567.98, 22.00], ['G#6', 1661.22, 20.77], ['A6', 1760.00, 19.60], ['A#6', 1864.66, 18.50], ['B6', 1975.53, 17.46], ['C7', 2093.00, 16.48], ['C#7', 2217.46, 15.56], ['D7', 2349.32, 14.69], ['D#7', 2489.02, 13.86], ['E7', 2637.02, 13.08], ['F7', 2793.83, 12.35], ['F#7', 2959.96, 11.66], ['G7', 3135.96, 11.00], ['G#7', 3322.44, 10.38], ['A7', 3520.00, 9.80], ['A#7', 3729.31, 9.25], ['B7', 3951.07, 8.73], ['C8', 4186.01, 8.24], ['C#8', 4434.92, 7.78], ['D8', 4698.63, 7.34], ['D#8', 4978.03, 6.93], ['E8', 5274.04, 6.54], ['F8', 5587.65, 6.17], ['F#8', 5919.91, 5.83], ['G8', 6271.93, 5.50], ['G#8', 6644.88, 5.19], ['A8', 7040.00, 4.90], ['A#8', 7458.62, 4.63], ['B8', 7902.13, 4.37]];\n\n  notesObj = null;\n\n  noteMap = () => {\n    if (notesObj) {\n      return notesObj;\n    }\n    return notesObj = edide.objectFromArray(this.notes, (val, ind) => {\n      return [ind, ...val];\n    }, (key) => {\n      return key[0];\n    });\n  };\n\n  this.findNote = (name) => {\n    return noteMap()[name];\n  };\n\n  a4 = this.findNote('A4');\n\n  this.diffToA4 = (name) => {\n    var note;\n    note = this.findNote(name);\n    return note[0] - a4[0];\n  };\n\n  this.diff = (n1, n2) => {\n    return this.findNote(n2)[0] - this.findNote(n1)[0];\n  };\n\nreturn noteFreq;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.strRandom = (function (edide, strRandom) {\n  return (limit = 20) => {\n    return (Math.random() + '').slice(2, +(limit + 1) + 1 || 9e9);\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.inEditor = (function (edide, inEditor) {Object.defineProperty(this, 'module_name', {value:'inEditor'});\n  inEditor = (inEditor === true) || false\nreturn inEditor;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.edideNamespace = (function (edide, edideNamespace) {\n\n  return 'edide'\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.edideNs = (function (edide, edideNs) {\n  var base, name;\n\n  return (base = edide.global)[name = edide.edideNamespace] != null ? base[name] : base[name] = {};\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.editorModule = (function (edide, editorModule) {\n  var editorModule;\n\n  editorModule = edide.inEditor ? edide.edideNs : null;\n\nreturn editorModule;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.keep = (function (edide, keep) {Object.defineProperty(this, 'module_name', {value:'keep'});\n  var keep;\n\n  keep = (prop) => {\n    return prop;\n  };\n\nreturn keep;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.logProd = (function (edide, logProd) {\n  return (...args) => {\n    var console, ref, ref1;\n    console = (ref = (ref1 = edide.editorModule) != null ? ref1.console : void 0) != null ? ref : edide.global.console;\n    return console.log(...args);\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.onUnload = (function (edide, onUnload) {\n  var ref, ref1;\n\n  return (ref = (ref1 = edide.editorModule) != null ? ref1.unload.add : void 0) != null ? ref : () => {};\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.var = (function (edide, mod_var) {\n  var clearVar, currentReact, debugging, dependees, dependsOn, depsRequired, inInitCall, infinityCheck, initSetter, loopLimit, newVar, parent, setLinks, setters, updateVar, values;\n\n  values = edide.keep(new Map); // #edide.keep if clearVar added again..\n\n  setters = edide.keep(new Map); // varName => setter:func\n\n  dependees = edide.keep(new Map); // varName => deps:\n\n  setLinks = edide.keep(new Map); // for reactiveGraph, show setters inside reactive/setter:s\n\n  debugging = false; //edide.editorModule?\n\n  depsRequired = new Map; // varName : dependsOn\n\n  inInitCall = false; // TODO use dependsOn? instead\n\n  dependsOn = new Set(); // remove\n\n  initSetter = (name, setter) => {\n    var debugName, err, parent, ref, val;\n    debugName = (ref = setter.type) != null ? ref : name;\n    if ((setters.get(name)) != null) {\n      throw Error(`Reactive for '${debugName}' already exists`);\n    }\n    setters.set(name, setter);\n    if (inInitCall) {\n      throw Error(`can't create reactive setter (for '${debugName}') inside reactive context`);\n    }\n    inInitCall = name;\n    dependsOn.clear(); // TODO clear => new Set\n    try {\n      val = setter(); // TODO: some day add revar and unvar as params; helps with multiple reactives to keep the separated\n    } catch (error) {\n      err = error;\n      inInitCall = false;\n      err.message = `Reactive initialization of '${debugName}' failed: ${err.message}`;\n      throw err;\n    }\n    parent = null;\n    dependsOn.forEach((depName) => {\n      var deps;\n      if ((deps = dependees.get(depName)) == null) {\n        dependees.set(depName, deps = new Set);\n      }\n      return deps.add(name);\n    });\n    inInitCall = false;\n    return val;\n  };\n\n  loopLimit = 0;\n\n  infinityCheck = new Map; //edide.keep\n\n  parent = null;\n\n  updateVar = function(name, val) {\n    var ref, ref1, type;\n    if (arguments.length === 1) { //unless val?\n      val = setters.get(name)();\n      if (debugging && (type = setters.get(name).type)) {\n        edide.logProd(`running ${(setters.get(name).type)}`);\n      }\n    }\n    if (typeof name !== 'string') { // symbol ~ react function\n      return;\n    }\n    if (values.get(name) === val && typeof val !== 'object') {\n      return;\n    }\n    if (infinityCheck.get(name) > loopLimit) {\n      infinityCheck.forEach((k) => {\n        return edide.logProd(k);\n      });\n      edide.logProd(name);\n      if ((ref = edide.editorModule) != null) {\n        if (typeof ref.reactiveGraph === \"function\") {\n          ref.reactiveGraph();\n        }\n      }\n      throw Error(\"Infinite loop in \\:var dependencies\");\n    }\n    if (debugging) {\n      edide.logProd(`updating ${name}`);\n    }\n    values.set(name, val);\n    if (!inInitCall) {\n      infinityCheck.set(name, (infinityCheck.get(name) || 0) + 1);\n      if ((ref1 = dependees.get(name)) != null) {\n        ref1.forEach((depName) => {\n          return updateVar(depName);\n        });\n      }\n      infinityCheck.delete(name);\n    }\n    return val;\n  };\n\n  currentReact = [];\n\n  newVar = function(name, setter) {\n    var context, contextSet, err;\n    if (arguments.length === 1) {\n      if (typeof name === 'string') {\n        if (inInitCall) {\n          dependsOn.add(name);\n          edide.onUnload(() => {\n            return clearVar(name); // TODO make specific clear?\n          });\n        }\n        return values.get(name);\n      } else {\n        setter = name;\n        name = Symbol();\n        values.set(name, name); // for debugging (showing react/dom funcs in graph)\n        edide.onUnload(() => {\n          return clearVar(name); // TODO make specific clear?\n        });\n      }\n    }\n    if (currentReact.length) { // and debugging\n      context = currentReact[currentReact.length - 1];\n      if (!(contextSet = setLinks.get(context))) {\n        setLinks.set(context, contextSet = new Set);\n      }\n      contextSet.add(name);\n    }\n    currentReact.push(name);\n    if (values.get(name) == null) {\n      edide.onUnload(() => {\n        return clearVar(name);\n      });\n    }\n    if (typeof setter === 'function') {\n      setter = initSetter(name, setter); // setter becomes value\n    }\n    if (typeof name === 'string') {\n      try {\n        updateVar(name, setter);\n      } catch (error) {\n        err = error;\n        infinityCheck.clear();\n        throw err;\n      }\n    }\n    currentReact.pop();\n    return setter;\n  };\n\n  clearVar = (name) => {\n    var i, len, map, ref;\n    ref = [values, setters, dependees, setLinks];\n    for (i = 0, len = ref.length; i < len; i++) {\n      map = ref[i];\n      map.delete(name);\n    }\n  };\n\n  Object.assign(newVar, {dependees, values, setters, setLinks});\n\n  return newVar;\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.reactiveWithFilters = (function (edide, reactiveWithFilters) {\n  return (initialVars = {}, filters = {}) => {\n    var handler, id, key, react, revar, todoMap, unvar, val;\n    id = edide.strRandom();\n    handler = {\n      get: (map, prop) => {\n        var ref;\n        if ((ref = edide.editorModule) != null ? ref.editor_inspector.inspectingNow : void 0) {\n          console.log('IN inspector? Find out is it possible to end up here form inside setter');\n          return edide.var.values.get(`${id}.${prop}`);\n        }\n        return edide.var(`${id}.${prop}`);\n      },\n      set: (map, prop, value) => {\n        if ((filters[prop] != null) && !filters[prop](value)) {\n          throw Error(`Illegal reactive (${prop}: ${value})`);\n        }\n        edide.var(`${id}.${prop}`, value);\n        return true; // Proxy set must return true if set is successful; In the future use Reflect.set, which returns true automatically?\n      }\n    };\n    revar = new Proxy((todoMap = new Map), handler); // NOTE: map is not used yet\n    unvar = new Proxy(todoMap, {\n      get: (map, prop) => {\n        return edide.var.values.get(`${id}.${prop}`);\n      },\n      set: (map, prop, value) => {\n        return edide.var.values.set(`${id}.${prop}`, value);\n      }\n    });\n    for (key in initialVars) {\n      val = initialVars[key];\n      revar[key] = val;\n    }\n    react = (nameOrFunc, func) => {\n      if (func != null) {\n        func.type = nameOrFunc;\n      } else {\n        func = nameOrFunc;\n        func.type = 'react'; // for debugging\n      }\n      return edide.var(func);\n    };\n    return {\n      react,\n      revar,\n      unvar,\n      un: unvar,\n      re: revar // , dom\n    };\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmState = (function (edide, mmState) {Object.defineProperty(this, 'module_name', {value:'mmState'});\n  var filters, instruments;\n\n  this.defaults = {\n    playing: false,\n    recorderOn: false,\n    fullSheet: '',\n    sheet: '', // selected/play part of fullSheet\n    diffText: '',\n    note: null, // currently playing note\n    // state properties\n    pace: 400, // -> bpm -> beatDelay\n    bpm: 400, // deprecate\n    beatDelay: (1 / 400) * 60 * 1000, // silly! unify with pace as one statestate variable\n    balance: 0,\n    volume: 0,\n    detune: 0,\n    blur: 0,\n    itch: 0,\n    instrumentsLoading: 0,\n    // dropdowns\n    instrument: 'guitar-electric',\n    scale: 'pentatonic',\n    root: 'C3',\n    highlight: null,\n    keyboardInd: 0 // TODO --> keyboard\n  };\n\n  instruments = Object.keys(edide.instrumentConfigs);\n\n  filters = {\n    scale: (val) => {\n      return ['pentatonic', 'minor', 'major'].includes(val);\n    },\n    instrument: (val) => {\n      return instruments.includes(val);\n    },\n    root: (val) => {\n      return edide.noteFreq.findNote(val);\n    }\n  };\n\n  this.react = null;\n\n  this.init = (startingProps = {}) => {\n    var props;\n    if (this.react != null) {\n      return this;\n    }\n    props = Object.assign({}, this.defaults, startingProps);\n    ({react: this.react, revar: this.revar, unvar: this.unvar} = edide.reactiveWithFilters(props, filters));\n    return this;\n  };\n\nreturn mmState;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmEffects = (function (edide, mmEffects) {Object.defineProperty(this, 'module_name', {value:'mmEffects'});\n  ({revar: this.revar} = edide.mmState.init());\n\n  this.maxLowpass = 10000;\n\n  this.maxDistortion = 3;\n\n  this.revar.lowpass = () => {\n    var blur;\n    ({blur} = this.revar);\n    return this.maxLowpass - blur * (this.maxLowpass - 200);\n  };\n\n  this.revar.distortion = () => {\n    var itch;\n    ({itch} = this.revar);\n    return this.maxDistortion * itch;\n  };\n\nreturn mmEffects;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.clone = (function (edide, clone) {\n  return (...objects) => {\n    if (Array.isArray(objects[0])) {\n      return Object.assign([], ...objects);\n    } else {\n      return Object.assign({}, ...objects);\n    }\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.strParsesToNumber = (function (edide, strParsesToNumber) {Object.defineProperty(this, 'module_name', {value:'strParsesToNumber'});\n  var strParsesToNumber;\n\n  strParsesToNumber = (str) => {\n    return !Number.isNaN(parseInt(str));\n  };\n\nreturn strParsesToNumber;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmConfigs = (function (edide, mmConfigs) {Object.defineProperty(this, 'module_name', {value:'mmConfigs'});\n  var defaultVars, mutatingProp, mutatingVars, stateVars, vars;\n\n  vars = {}; // varName: config object\n\n  mutatingVars = {};\n\n  stateVars = edide.set('itch', 'blur', 'instrument', 'bpm', 'pace', 'beatDelay', 'scale', 'root', 'balance', 'detune', 'volume');\n\n  this.hasVar = (varName) => {\n    var ref, ref1;\n    return !!((ref = (ref1 = vars[varName]) != null ? ref1 : mutatingVars[varName]) != null ? ref : stateVars.has(varName));\n  };\n\n  this.activateVar = (name, value) => {\n    var configs;\n    if (value != null) {\n      configs = stateVars.has(name) ? {\n        [`${name}`]: value\n      } : mutatingVars[name] != null ? edide.clone(mutatingVars[name]) : void 0;\n      if (edide.strParsesToNumber(value)) {\n        value = parseFloat(value);\n      }\n      configs[mutatingProp(configs)] = value;\n      return this.activate(configs);\n    } else {\n      return this.activate(vars[name]);\n    }\n  };\n\n  mutatingProp = (configs) => {\n    var name, val;\n    for (name in configs) {\n      val = configs[name];\n      if (val === '*') {\n        return name;\n      }\n    }\n    return false;\n  };\n\n  this.activate = (conf) => {\n    if (conf.name != null) {\n      return; // throw warning?\n    }\n    return Object.assign(edide.mmState.revar, conf);\n  };\n\n  this.reset = () => {\n    stateVars.forEach((name) => {\n      return edide.mmState.revar[name] = edide.mmState.defaults[name];\n    });\n  };\n\n  this.addVar = (varName, config) => { // , activate=true\n    if (mutatingProp(config)) {\n      return mutatingVars[varName] = config;\n    } else {\n      return vars[varName] = config;\n    }\n  };\n\n  defaultVars = {\n    bass: {\n      \"instrument\": \"bass-electric\"\n    },\n    cello: {\n      \"instrument\": \"cello\"\n    },\n    guitar: {\n      \"instrument\": \"guitar-acoustic\"\n    },\n    eguitar: {\n      \"instrument\": \"guitar-electric\"\n    },\n    piano: {\n      \"instrument\": \"piano\"\n    },\n    synth: {\n      \"instrument\": \"synth-simple\"\n    },\n    xylophone: {\n      \"instrument\": \"xylophone\"\n    },\n    pentatonic: {\n      \"scale\": \"pentatonic\"\n    },\n    major: {\n      \"scale\": \"major\"\n    },\n    minor: {\n      \"scale\": \"minor\"\n    }\n  };\n\n  this.init = () => {\n    var conf, name;\n    vars = {};\n    for (name in defaultVars) {\n      conf = defaultVars[name];\n      this.addVar(name, conf, false);\n    }\n  };\n\n  this.init();\n\nreturn mmConfigs;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.setTimeout = (function (edide, mod_setTimeout) {\n  var nativeSetTimeout, ref;\n\n  nativeSetTimeout = edide.global.nativeSetTimeout = (ref = edide.global.nativeSetTimeout) != null ? ref : edide.global.setTimeout;\n\n  return function(arg1, arg2) {\n    var fun, id, num;\n    [fun, num] = typeof arg2 === 'function' ? [arg2, arg1] : [arg1, arg2];\n    id = nativeSetTimeout(fun, num);\n    edide.onUnload(() => {\n      return clearTimeout(id);\n    });\n    return id;\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.musicScales = (function (edide, musicScales) {Object.defineProperty(this, 'module_name', {value:'musicScales'});\n  this.full = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];\n\n  this.scaleSteps = {\n    // rock\n    // 0, 3,      2, 2, 3,    (2)\n    pentatonic: [\n      0,\n      3,\n      2,\n      2,\n      3 // hidden 2 # \"pentatonicMinor\"\n    ],\n    //pentatonicMajor: ['C, D, E, G, A']\n    // blues: minor penta +\n    // whole – whole – half – whole – whole – whole – half\n    major: [\n      0,\n      2,\n      2,\n      1,\n      2,\n      2,\n      2 // hidden to beginning: 1 # \"naturalMajor\"\n    ],\n    // whole – half – whole – whole – half – whole – whole\n    minor: [\n      0,\n      2,\n      1,\n      2,\n      2,\n      1,\n      2 // hidden to beginning: 2 # \"naturalMinor\"\n    ]\n  };\n  // http://whatmusicreallyis.com/papers/sacred_sounds_scale.html\n  this.triadSteps = {\n    major: [\n      0,\n      4,\n      3 // positive valence\n    ],\n    minor: [0, 3, 4]\n  };\n\n  // M = major triad\n  // m = minor triar\n  // i = number of (half) steps from first triad to second\n  // (source: https://www.youtube.com/watch?v=YSKAt3pmYBs)\n  this.triadCombinations = {\n    protagonism: 'M2M',\n    outerSpace: 'M6M',\n    fantastical: 'M8M',\n    sadness: 'M4m',\n    romantic: 'M5m', // and middle eastern\n    wonder: 'm5M', // and transcendence\n    mystery: 'm2M', // and dark comedy\n    dramatic: 'm11M',\n    antagonismDanger: 'm6m', // less character based\n    antagonismEvil: 'm8m' // character based\n  };\n\nreturn musicScales;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mathOp = (function (edide, mathOp) {Object.defineProperty(this, 'module_name', {value:'mathOp'});\n  this.sum = function(a, b) {\n    return a + b;\n  };\n\n  this.multiply = function(a, b) {\n    return a * b;\n  };\n\nreturn mathOp;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmKeyboard = (function (edide, mmKeyboard) {Object.defineProperty(this, 'module_name', {value:'mmKeyboard'});\n  var A, a, char, chari, i, j, len, len1, noncaps, qwertyChar, qwertyRows, revar, row, rowi, space, unvar;\n\n  ({revar, unvar} = edide.mmState.init());\n\n  revar.scaleSteps = () => {\n    return edide.musicScales.scaleSteps[revar.scale];\n  };\n\n  this.special = {\n    rest: '.',\n    long: '=',\n    comment: '#',\n    var: ':',\n    confStart: '{',\n    confEnd: '}'\n  };\n\n  this.specialKeyCodes = new Set(Object.values(this.special).map((s) => {\n    return s.charCodeAt(0);\n  }));\n\n  this.specialChars = new Set(Object.values(this.special));\n\n  this.isPauseKey = (keyCode) => {\n    return this.specialKeyCodes.has(keyCode);\n  };\n\n  this.isSpecialChar = (char) => {\n    return this.specialChars.has(char);\n  };\n\n  this.isPauseChar = this.isSpecialChar; // not really...\n\n  this.keyboards = ['qwerty', 'abc'];\n\n  a = 'a'.charCodeAt(0);\n\n  A = 'A'.charCodeAt(0);\n\n  space = ' '.charCodeAt(0);\n\n  this.isCaps = (key) => {\n    return A <= key && key < a;\n  };\n\n  this.capsDiff = a - A;\n\n  noncaps = (key) => {\n    if (this.isCaps(key)) {\n      return key + this.capsDiff;\n    } else {\n      return key;\n    }\n  };\n\n  this.getNoteInd = (key) => {\n    var maxInstrumentNoteInd, noteBaseInd, noteInd, notes, startNote, step;\n    ({startNote, notes, step} = unvar.instrumentConf);\n    startNote = unvar.root;\n    noteBaseInd = edide.noteFreq.findNote(startNote)[0];\n    noteInd = this[this.keyboards[unvar.keyboardInd]](noncaps(key), noteBaseInd);\n    maxInstrumentNoteInd = noteBaseInd + notes * step;\n    while (noteInd > maxInstrumentNoteInd) {\n      noteInd -= 2 * 12;\n    }\n    return noteInd;\n  };\n\n  this.abc = (key, baseInd) => {\n    var fromLowest, noteInd, stepsFromClosestOctave;\n    fromLowest = key - a;\n    stepsFromClosestOctave = fromLowest % revar.scaleSteps.length;\n    noteInd = 0;\n    noteInd += revar.scaleSteps.slice(0, +stepsFromClosestOctave + 1 || 9e9).reduce(edide.mathOp.sum);\n    noteInd += 12 * Math.floor(fromLowest / revar.scaleSteps.length);\n    return baseInd + noteInd;\n  };\n\n  qwertyRows = ['qwertyuiop', 'asdfghjkl', 'zxcvbnm'];\n\n  qwertyChar = {};\n\n  for (rowi = i = 0, len = qwertyRows.length; i < len; rowi = ++i) {\n    row = qwertyRows[rowi];\n    for (chari = j = 0, len1 = row.length; j < len1; chari = ++j) {\n      char = row[chari];\n      qwertyChar[char.charCodeAt(0)] = [rowi, chari];\n    }\n  }\n\n  this.qwerty = (key, baseInd) => {\n    var charSteps, halfSteps, noteInd, octave, rowchar;\n    if (!(rowchar = qwertyChar[key])) {\n      return;\n    }\n    [row, char] = rowchar;\n    octave = qwertyRows.length - 1 - row + Math.floor(char / unvar.scaleSteps.length);\n    char = char % revar.scaleSteps.length;\n    charSteps = revar.scaleSteps.slice(0, +char + 1 || 9e9).reduce((a, b) => {\n      return a + b;\n    });\n    halfSteps = 12 * octave + charSteps;\n    return noteInd = baseInd + halfSteps;\n  };\n\nreturn mmKeyboard;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.chars = (function (edide, chars) {Object.defineProperty(this, 'module_name', {value:'chars'});\n  this.space = ' ';\n\n  this.nonBreakingSpace = ' ';\n\n  this.enter = \"\\n\";\n\nreturn chars;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.showError = (function (edide, showError) {\n  var error;\n\n  error = (err) => {\n    if (edide.inEditor) {\n      return edide.editorModule.editor_error.show(err);\n    } else if (typeof edide.global.require === 'object' && (edide.global[edide.edideNamespace].prodErrorPrinter != null)) {\n      return edide.global[edide.edideNamespace].prodErrorPrinter.showError(err);\n    } else {\n      return console.error(err);\n    }\n  };\n\n  return (err) => {\n    var err2;\n    if (err != null ? err.stack : void 0) {\n      return error(err); // create error to capture stack trace\n    } else {\n      try {\n        throw Error(err);\n      } catch (error1) {\n        err2 = error1;\n        return error(err2);\n      }\n    }\n  };\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmParserSpecial = (function (edide, mmParserSpecial) {Object.defineProperty(this, 'module_name', {value:'mmParserSpecial'});\n  // parse config { .. } and variable : .. : syntaxes\n  this.config = (trackStr, ts = {}) => {\n    var endInd, err, name;\n    endInd = trackStr.search('}') || trackStr.length;\n    try {\n      ts.conf = JSON.parse(trackStr.slice(0, +endInd + 1 || 9e9));\n      if (ts.conf.name != null) {\n        ({name} = ts.conf);\n        delete ts.conf.name;\n        edide.mmConfigs.addVar(name, ts.conf);\n      } else {\n        edide.mmConfigs.activate(ts.conf); // add variable if exists\n      }\n    } catch (error) {\n      err = error;\n      ts.skip = true; // could be used to show error highlighting in editor\n      edide.showError(err); // remove this if error highlighting implemented\n    }\n    return endInd;\n  };\n\n  // parse variable from current track row\n  // returns false if parsing fails\n  this.var = (track, trackState) => {\n    var err, i, value, varLength, varName, varStr;\n    ({i} = trackState);\n    varLength = track.slice(i + 1).indexOf(edide.mmKeyboard.special.var);\n    if (varLength === -1) {\n      return false;\n    }\n    varStr = track.slice(i + 1, +(i + varLength) + 1 || 9e9);\n    [varName, value] = varStr.split(' ');\n    if (!edide.mmConfigs.hasVar(varName)) {\n      // TODO: with errors shown in UI the following check could be removed:\n      return false;\n    }\n    try {\n      edide.mmConfigs.activateVar(varName, value);\n      trackState.i += varLength + 2;\n      return true;\n    } catch (error) {\n      err = error;\n      //throw err if edide.inEditor\n      return false;\n    }\n  };\n\nreturn mmParserSpecial;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmNote = (function (edide, mmNote) {Object.defineProperty(this, 'module_name', {value:'mmNote'});\n  this.fromChar = (char) => {\n    return this.fromKeyCode(char.charCodeAt(0));\n  };\n\n  this.fromKeyCode = (key) => {\n    var noteInd, ref;\n    if (typeof (noteInd = edide.mmKeyboard.getNoteInd(key)) === 'number') {\n      return (ref = edide.noteFreq.notes[noteInd]) != null ? ref[0] : void 0;\n    }\n  };\n\nreturn mmNote;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmParser = (function (edide, mmParser) {Object.defineProperty(this, 'module_name', {value:'mmParser'});\n  var getNoteLength, nonBreakingSpace, processTrack, revar, space, unvar;\n\n  ({revar, unvar} = edide.mmState);\n\n  getNoteLength = (row, noteInd) => {\n    var char, length;\n    length = 1;\n    while (char = row[++noteInd]) {\n      if (char === edide.mmKeyboard.special.long) {\n        length++;\n      } else {\n        break;\n      }\n    }\n    return length;\n  };\n\n  ({space, nonBreakingSpace} = edide.chars);\n\n  // Processes one char in a track, and iteratively calls itself if needed.\n  // ccs - \"current column state\" - inline chord + played?\n  // ts - track state: char index, configs\n  processTrack = (track, ccs, ts) => {\n    var bef, chord, groupingChars, keyCode, lastSpace, note, repeat, repeatStart;\n    if (!track[ts.i]) {\n      return;\n    }\n    if (ts.skip) { // comment or erroneous chars\n      return;\n    }\n    // bracket chords\n    switch (track[ts.i]) {\n      case '{':\n        return ts.i += edide.mmParserSpecial.config(track.slice(ts.i), ts); //  parseConfigs\n      case '*':\n        if (ts.repeat != null) {\n          // inside a repeating pattern\n          ts.repeat--;\n          if (ts.repeat > 0) {\n            // still repeats left to do, start from the beginning\n            ts.i = ts.iStart = ts.repeatStart; // repeats done\n          } else {\n            ts.repeat = ts.repeatStart = null;\n            ts.i++; // step over '*' so won't end up starting repeats again\n          }\n        } else {\n          if (isNaN(repeat = parseInt(track.slice(ts.i + 1)))) {\n            ts.i++; // unable to parse number of repeats, skip them\n          } else {\n            // initialize new repeating pattern (-1 because repeat pattern already played once)\n            ts.repeat = repeat - 1;\n            // search for beginning of repeat group\n            bef = track.slice(0, ts.i);\n            groupingChars = ['(', space, nonBreakingSpace, '*'];\n            lastSpace = Math.max(...groupingChars.map((c) => {\n              return bef.lastIndexOf(c);\n            }));\n            repeatStart = lastSpace !== -1 ? lastSpace + 1 : 0; // beginning of row if no grouping char found\n            // set track state at the beginning of repeats\n            ts.i = ts.iStart = ts.repeatStart = repeatStart;\n          }\n        }\n        return processTrack(track, ccs, ts);\n      case '[':\n        ccs.chord = [];\n        ts.i++;\n        return processTrack(track, ccs, ts);\n      case ']':\n        ts.i++;\n        ({chord} = ccs);\n        if (!chord) { // illegal - missing beginning [\n          return processTrack(track, ccs, ts);\n        }\n        ccs.chord = null;\n        if (chord.length) {\n          if (!unvar.preprocessing) {\n            revar.playNote = [chord, getNoteLength(track, ts.i)];\n          }\n          //edide.mmInstrument.playNote chord, getNoteLength track, ts.i\n          ccs.played = true;\n        } else {\n          processTrack(track, ccs, ts);\n        }\n        return;\n      case edide.mmKeyboard.special.var:\n        if (edide.mmParserSpecial.var(track, ts)) {\n          processTrack(track, ccs, ts); // recursive, since next char could be another var, e.g. \\:bass::minor:\n        } else {\n          ts.skip = true; // parse error\n        }\n        return;\n      case edide.mmKeyboard.special.comment:\n        return ts.skip = true;\n    }\n    // TODO: merge switch and bottom code OR put them in a different functions\n    if (!(keyCode = track.charCodeAt(ts.i))) {\n      return;\n    }\n    ts.i++;\n    if (note = edide.mmNote.fromKeyCode(keyCode)) {\n      if (ccs.chord) {\n        ccs.chord.push(note);\n        processTrack(track, ccs, ts);\n      } else {\n        if (!unvar.preprocessing) {\n          revar.playNote = [note, getNoteLength(track, ts.i)];\n        }\n        //edide.mmInstrument.playNote note, getNoteLength track, ts.i\n        ccs.played = true;\n      }\n    } else if (edide.mmKeyboard.isPauseKey(keyCode)) {\n      ccs.played = true; // \"play silence\"\n  // meaningless char\n    } else {\n      processTrack(track, ccs, ts);\n    }\n  };\n\n  // TODO figure sheetStart != 0  --  maybe makes more sense to remove textarea first\n  this.splitSections = (str) => {\n    var i, j, prevInd, ref, row, section, sections;\n    str = str.replace('&\\n', ''); // TODO fix row tracking with &\\n\n    sections = [];\n    section = null;\n    row = 0;\n    prevInd = 0;\n    for (i = j = 0, ref = str.length; (0 <= ref ? j <= ref : j >= ref); i = 0 <= ref ? ++j : --j) {\n      if (!(str[i] === '\\n' || i === str.length)) {\n        continue;\n      }\n      if (str[i - 1] === '\\n') {\n        if (section != null) {\n          sections.push(section);\n        }\n        section = null;\n      }\n      if (i > prevInd) {\n        if (section == null) {\n          section = {\n            row: row,\n            tracks: []\n          };\n        }\n        section.tracks.push(str.slice(prevInd, i));\n      }\n      row++;\n      prevInd = i + 1;\n    }\n    if (section != null) {\n      sections.push(section);\n    }\n    sections.row = 0;\n    return sections;\n  };\n\n  this.play = (song, sectionInd, trackStates) => {\n    var ccs, section;\n    if (!unvar.playing) {\n      return;\n    }\n    revar.highlight = null;\n    sectionInd = sectionInd || 0;\n    if (typeof song === 'string') {\n      song = this.splitSections(song);\n    }\n    section = song[sectionInd];\n    if (!section) { // song finished\n      if (!unvar.preprocessing) {\n        revar.playing = false;\n      }\n      return;\n    }\n    if (!Array.isArray(trackStates)) {\n      trackStates = section.tracks.map(() => {\n        return {\n          i: 0 // initi track indices on first call to section\n        };\n      });\n    }\n    // init @play ccs\n    ccs = {}; // chord, played  # TODO change back to chord: [C3, D3] and [].played = true\n    // OR: why not just ts.chord?\n    section.tracks.forEach((track, tInd) => {\n      var conf, i, iStart;\n      if (conf = trackStates[tInd].conf) {\n        // config row and already parsed (NOTE: config row can only have one config object and nothing else)\n        return edide.mmConfigs.activate(conf);\n      } else {\n        trackStates[tInd].iStart = trackStates[tInd].i;\n        processTrack(track, ccs, trackStates[tInd]);\n        ({iStart, i} = trackStates[tInd]);\n        if (i > iStart) {\n          return revar.highlight = [section.row + tInd, iStart, i - 1];\n        }\n      }\n    });\n    if (ccs.played) {\n      if (unvar.preprocessing) {\n        this.play(song, sectionInd, trackStates);\n      } else {\n        edide.setTimeout(() => {\n          return this.play(song, sectionInd, trackStates);\n        }, unvar.beatDelay);\n      }\n    } else {\n      // using timeout fixes bug where revar.playing is set false in same exec where it's set true (infinite loop)\n      this.play(song, sectionInd + 1);\n    }\n  };\n\nreturn mmParser;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.moduleGate = (function (edide, moduleGate) {Object.defineProperty(this, 'module_name', {value:'moduleGate'});\n  if (!edide.inEditor) {\n    return this;\n  }\n\n  this.root; // module that is edited in root\n\n  this.rootName;\n\n  this.active; // module that is currently being edited (can be root or in window)\n\n  this.activeName;\n\n  this.executing;\n\n  this.executingName;\n\nreturn moduleGate;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.rejectIfRecompiled = (function (edide, rejectIfRecompiled) {\n  if (!edide.inEditor) {\n    return () => {};\n  }\n\n  return (promise) => {\n    var recompiled, rootName;\n    ({rootName} = edide.moduleGate);\n    recompiled = false;\n    edide.editorModule.editor_events.on('before_recompile', () => {\n      return recompiled = true;\n    });\n    return promise.then(function(arg) {\n      if (recompiled || rootName !== edide.moduleGate.rootName) { // root module changed\n        return Promise.reject(); // quiet rejection; no need to show error\n      } else {\n        return arg; // arg get wrapped in promise\n      }\n    });\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.promise = (function (edide, promise) {Object.defineProperty(this, 'module_name', {value:'promise'});\n  var localPromise, ref;\n\n  localPromise = edide.global.origPromise = (ref = edide.global.origPromise) != null ? ref : edide.global.Promise;\n\n  this.new = function(cb) {\n    if (edide.inEditor) {\n      return edide.rejectIfRecompiled(new Promise(cb)); // don't fire cb if code has been re-executed in the meantime\n    } else {\n      return new Promise(cb);\n    }\n  };\n\n  this.all = function(cbArray) {\n    if (edide.inEditor) { // check that after resolved, still editing same module\n      return edide.rejectIfRecompiled(Promise.all(cbArray));\n    } else {\n      return Promise.all(cbArray);\n    }\n  };\n\n  this.resolve = Promise.resolve.bind(Promise);\n\n  this.reject = Promise.reject.bind(Promise);\n\nreturn promise;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.qs = (function (edide, qs) {\n  return (selector, el = document) => {\n    return el.querySelector(selector);\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.scriptContainer = (function (edide, scriptContainer) {\n  var createContainer, ref;\n\n  createContainer = () => {\n    var s;\n    s = document.createElement('div');\n    s.id = 'scripts';\n    return s;\n  };\n  return (ref = edide.qs('#scripts')) != null ? ref : document.body.appendChild(createContainer());\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.scriptAdd = (function (edide, scriptAdd) {\n  return (src, cb) => {\n    var el;\n    el = document.createElement('script');\n    edide.scriptContainer.appendChild(el);\n    if (cb) {\n      el.onload = cb;\n    }\n    el.type = 'application/javascript';\n    el.src = src;\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.requireScript = (function (edide, requireScript) {\n  var base;\n\n  if ((base = edide.global).requireScriptPromises == null) {\n    base.requireScriptPromises = new Map;\n  }\n\n  return (scriptSrc) => {\n    var promise;\n    if (promise = requireScriptPromises.get(scriptSrc)) {\n      return promise;\n    } else {\n      requireScriptPromises.set(scriptSrc, promise = edide.promise.new((resolve) => {\n        return edide.scriptAdd(scriptSrc, resolve);\n      }));\n      return promise.catch((err) => {\n        edide.showError(err);\n        return requireScriptPromises.delete(scriptSrc);\n      });\n    }\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmPipe = (function (edide, mmPipe) {Object.defineProperty(this, 'module_name', {value:'mmPipe'});\n  var dist, lowpass, panner, react, revar, reverber, unvar;\n\n  ({revar, unvar, react} = edide.mmState.init());\n\n  dist = lowpass = reverber = panner = null;\n\n  this.initPipe = () => {\n    lowpass = new Tone.Filter(unvar.lowpass, 'lowpass', -12);\n    dist = new Tone.Distortion(unvar.distortion);\n    panner = new Tone.Panner();\n    panner.connect(dist);\n    dist.connect(lowpass);\n    lowpass.toMaster();\n    this.output = lowpass;\n    revar.pipeReady = true;\n    return edide.onUnload(() => {\n      if (dist != null) {\n        if (typeof dist.dispose === \"function\") {\n          dist.dispose();\n        }\n      }\n      if (lowpass != null) {\n        if (typeof lowpass.dispose === \"function\") {\n          lowpass.dispose();\n        }\n      }\n      return panner != null ? typeof panner.dispose === \"function\" ? panner.dispose() : void 0 : void 0;\n    });\n  };\n\n  this.initInstrument = (instrument) => {\n    instrument.connect(panner);\n    edide.onUnload(() => {\n      return instrument != null ? instrument.disconnect() : void 0;\n    });\n    return instrument;\n  };\n\n  revar.panner = () => {\n    return revar.balance;\n  };\n\n  react('panner', () => {\n    revar.panner;\n    return panner != null ? panner.pan.value = revar.panner : void 0;\n  });\n\n  react('pipe distortion', () => {\n    var ref;\n    revar.distortion;\n    revar.lowpass;\n    if (dist != null) {\n      dist.distortion = revar.distortion;\n    }\n    return lowpass != null ? (ref = lowpass.frequency) != null ? ref.linearRampTo(revar.lowpass, 0) : void 0 : void 0;\n  });\n\nreturn mmPipe;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmInstruments = (function (edide, mmInstruments) {Object.defineProperty(this, 'module_name', {value:'mmInstruments'});\n\n  var defaultUrl = 'https://nbrosowsky.github.io/tonejs-instruments/samples/'\n\n  var { revar, unvar, react } = edide.mmState\n\n  var defaultInstrument = 'electric-guitar'\n\n  this.initInstrument = async (resolve) => {\n    await edide.requireScript('https://cdnjs.cloudflare.com/ajax/libs/tone/13.8.9/Tone.js')\n    edide.mmPipe.initPipe()\n  }\n\n  var instrumentCache = edide.keep({})\n\n  this.createNew = () => {\n\n    var {name} = unvar.instrumentConf\n    var instrument, endOfPipe\n    var instrumentConf = this.instruments[name]\n\n    if (instrumentConf.module_name) {\n      var res = instrumentConf.init()\n      if (Array.isArray(res)) {\n        instrument = res[0]\n        endOfPipe = res[1]\n      } else {\n        instrument = endOfPipe = res\n      }\n    } else if (instrumentCache[name]) {\n      instrument = endOfPipe = instrumentCache[name]\n    } else {\n      var noteFiles = buildNotes(instrumentConf)\n      revar.instrumentsLoading++\n      var inst = new Tone.Sampler(noteFiles, { //edide.mmInstrumentssAll[name]\n        \"release\" : 1,\n        \"baseUrl\" : instrumentConf.url || defaultUrl + name + '/',\n        \"onload\"  : () => revar.instrumentsLoading--\n      })\n      inst.soundFontInstrument = true\n      instrument = endOfPipe = instrumentCache[name] = inst //[inst, inst]\n    }\n\n    edide.mmPipe.initInstrument(endOfPipe)\n\n    return instrument\n  }\n\n  this.isReady = () => {\n    var { current } = this\n    return current && (typeof current.loaded == 'undefined' || current.loaded === true)\n  }\n\n  function buildNotes({startNote, notes, step, skipNotes}) {\n    var [startInd] = edide.noteFreq.findNote(startNote)\n    var noteFiles = {}\n    if (Array.isArray(notes)) {\n      notes.forEach(note => {\n        noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]'\n      })\n    } else {\n      for (let i=0; i < notes*step; i+=step) {\n        let note = edide.noteFreq.notes[startInd + i][0];\n        if (skipNotes && skipNotes.has(note))\n          continue\n        noteFiles[note] = note.replace('#','s') + '.[mp3|ogg]'\n      }\n    }\n    return noteFiles\n  }\n\n  this.instruments = edide.instrumentConfigs\n\n  this.instrumentList = Object.values(this.instruments)\n\n  react('active instrument config', () => {\n    revar.instrumentConf = this.instruments[revar.instrument] // conf\n  })\n\nreturn mmInstruments;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.cloneSibling = (function (edide, cloneSibling) {\n  return (srcObj) => {\n    var o;\n    o = Object.create(Object.getPrototypeOf(srcObj));\n    Object.assign(o, srcObj);\n    return o;\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.times = (function (edide, times) {\n  return (timesNum, action) => {\n    while (timesNum-- > 0) {\n      action(timesNum + 1);\n    }\n  };\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.sleep = (function (edide, sleep) {\n  var sleep;\n\n  sleep = (ms) => {\n    var resolve, timeout;\n    timeout = resolve = null;\n    return edide.promise.new((res) => {\n      resolve = res;\n      return timeout = edide.setTimeout(ms, res);\n    });\n  };\n\n  return sleep;\n\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmInstrument = (function (edide, mmInstrument) {Object.defineProperty(this, 'module_name', {value:'mmInstrument'});\n  var cloneOrCreateInstrument, getInstruments, instruments, play, react, revar, unvar, updateVolAndTune;\n\n  instruments = {}; // name: [instrument instances...]\n\n  ({unvar, revar, react} = edide.mmState);\n\n  revar.bpm = () => {\n    return revar.pace;\n  };\n\n  revar.beatDelay = () => {\n    return (1 / revar.bpm) * 60 * 1000;\n  };\n\n  react(() => {});\n\n  updateVolAndTune = (inst) => {\n    var detune, volume;\n    ({volume, detune} = unvar);\n    if ((detune != null) && (inst.detune != null)) {\n      inst.set(\"detune\", detune);\n    }\n    if ((volume != null) && (inst.volume != null)) {\n      return inst.set(\"volume\", volume);\n    }\n  };\n\n  react(() => {\n    var inst, insts, j, len, name;\n    revar.volume;\n    revar.detune;\n    for (name in instruments) {\n      insts = instruments[name];\n      for (j = 0, len = insts.length; j < len; j++) {\n        inst = insts[j];\n        updateVolAndTune(inst);\n      }\n    }\n  });\n\n  react('create first instrument', () => {\n    var name, ref;\n    if (!(name = (ref = revar.instrumentConf) != null ? ref.name : void 0)) { // e.g. illegal instrument name\n      return edide.showError(`Unknown instrument: ${unvar.instrument}`);\n    }\n    if (revar.pipeReady && !instruments[name]) {\n      return instruments[name] = [edide.mmInstruments.createNew()];\n    }\n  });\n\n  cloneOrCreateInstrument = (name) => {\n    var inst;\n    inst = instruments[name][0].soundFontInstrument ? (inst = edide.cloneSibling(instruments[name][0]), inst.isPlaying = false, inst) : edide.mmInstruments.createNew();\n    updateVolAndTune(inst);\n    return inst;\n  };\n\n  getInstruments = (n) => {\n    var all, free, name;\n    ({name} = unvar.instrumentConf);\n    all = instruments[name];\n    free = all.filter((i) => {\n      return !i.isPlaying;\n    });\n    edide.times(n - free.length, () => {\n      var inst;\n      free.push(inst = cloneOrCreateInstrument(name));\n      return all.push(inst);\n    });\n    return free.slice(0, n);\n  };\n\n  this.playChord = (chord, noteLength = 1) => {};\n\n  this.playNote = (chord, noteLength = 1) => {\n    var ind, inst, insts, j, len, ref;\n    if (!Array.isArray(chord)) {\n      chord = [chord];\n    }\n    ref = insts = getInstruments(chord.length);\n    for (ind = j = 0, len = ref.length; j < len; ind = ++j) {\n      inst = ref[ind];\n      play(inst, chord[ind], noteLength);\n    }\n  };\n\n  play = async(instrument, note, length) => {\n    var err;\n    instrument.isPlaying = note; // true\n    try {\n      instrument.triggerAttackRelease(note, (length * unvar.beatDelay) / 1000);\n    } catch (error) {\n      err = error;\n      err.message = `Error in playing note ${note}, '${unvar.instrumentConf.name}' probably not loaded yet`;\n      edide.showError(err);\n    }\n    revar.note = note;\n    await edide.sleep(unvar.nextDelay);\n    return instrument.isPlaying = false;\n  };\n\nreturn mmInstrument;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.mmPlayer = (function (edide, mmPlayer) {Object.defineProperty(this, 'module_name', {value:'mmPlayer'});\n  var react, revar, unvar;\n\n  ({revar, unvar, react} = edide.mmState.init());\n\n  this.play = (str) => {\n    revar.sheet = str;\n    return revar.playing = true;\n  };\n\n  react('play from sheet', () => {\n    if (!revar.playing) {\n      return;\n    }\n    edide.mmConfigs.init();\n    revar.preprocessing = true;\n    return edide.setTimeout(() => { // infinite revar.playing loop\n      edide.mmParser.play(unvar.sheet);\n      return revar.preprocessing = 'done';\n    });\n  });\n\n  react('play notes/chords', () => {\n    var chord, playNote, playing, preprocessing, time;\n    ({playNote, playing, preprocessing} = revar);\n    if (!(playNote && playing && preprocessing === false)) {\n      return;\n    }\n    [chord, time] = revar.playNote;\n    return edide.mmInstrument.playNote(chord, time);\n  });\n\n  this.toggle = () => {\n    return revar.playing = !unvar.playing;\n  };\n\n  revar.instrumentsLoading;\n\n  react('play after preprocess', () => {\n    var instrumentsLoading, preprocessing;\n    ({instrumentsLoading, preprocessing} = revar);\n    if (!(preprocessing === 'done' && instrumentsLoading === 0)) {\n      return;\n    }\n    unvar.preprocessing = false;\n    edide.mmConfigs.reset();\n    return edide.mmParser.play(unvar.sheet);\n  });\n\nreturn mmPlayer;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.waves = (function (edide, waves) {Object.defineProperty(this, 'module_name', {value:'waves'});\n\n  edide.global.music = this\n\n  edide.mmEffects\n\n  var { revar, unvar, react } = edide.mmState\n\n  var playQueue = []\n\n  this.play = (str) => {\n    if (!unvar.pipeReady) return playQueue.push(str)\n    revar.playing = true\n\n    edide.mmPlayer.play(str)\n  }\n\n  this.stop = () => revar.playing = false\n\n  edide.mmInstruments.initInstrument()\n\n  react(() => {\n    if(!revar.pipeReady) return\n    edide.mmConfigs.reset()\n    this.play(playQueue.join(\"\\n\\n\")) // JSON.stringify(initialSettings)\n  })\nreturn waves;\n}).call(MODSELF={}, edide, MODSELF);\n\nedide.wave = (function (edide, wave) {\n\n  var parent = {\n    play: function(){\n      edide.waves.play(this.sheet)\n      return this\n    },\n    stop: function(){\n      edide.waves.stop(this.sheet)\n      return this\n    },\n    blur: function(val){\n      this.sheet = `:blur ${val}:` + this.sheet\n      return this\n    },\n    itch: function(val){\n      this.sheet = `:itch ${val}:` + this.sheet\n      return this\n    },\n    long: function(val){ // note delay in seconds\n      this.sheet = `:beatDelay ${val*1000}:` + this.sheet\n      return this\n    },\n    pace: function(val) { // note delay in beats per minute\n      this.sheet = `:pace ${val}:` + this.sheet\n      return this\n    },\n    vary: function(val){\n      this.sheet = `:detune ${val}:` + this.sheet\n      return this\n    },\n    loud: function(val){ // increase (>0) or decrease (<0) amplitude in decibels\n      this.sheet = `:volume ${val}:` + this.sheet\n      return this\n    },\n    balance: function(val){\n      this.sheet = `:balance ${val}:` + this.sheet\n      return this\n    }\n  }\n\n  return edide.global.wave = (str) => {\n    edide.mmConfigs.reset()\n    var obj = Object.create(parent)\n    obj.sheet = str\n    return obj\n  }\n\n}).call(MODSELF={}, edide, MODSELF);\nedide.global.wave = edide.wave;\n})()"
  },
  {
    "path": "lib/webrtc.d.ts",
    "content": "import {} from './webrtc'\ndeclare module './webrtc' {}\n"
  },
  {
    "path": "lib/webrtc.js",
    "content": ";(function(){\n\tvar GUN = (typeof window !== \"undefined\")? window.Gun : require('../gun');\n\tGUN.on('opt', function(root){\n\t\tthis.to.next(root);\n\t\tvar opt = root.opt;\n\t\tif(root.once){ return }\n\t\tif(!GUN.Mesh){ return }\n\t\tif(false === opt.RTCPeerConnection){ return }\n\n\t\tvar env;\n\t\tif(typeof window !== \"undefined\"){ env = window }\n\t\tif(typeof global !== \"undefined\"){ env = global }\n\t\tenv = env || {};\n\n\t\tvar rtcpc = opt.RTCPeerConnection || env.RTCPeerConnection || env.webkitRTCPeerConnection || env.mozRTCPeerConnection;\n\t\tvar rtcsd = opt.RTCSessionDescription || env.RTCSessionDescription || env.webkitRTCSessionDescription || env.mozRTCSessionDescription;\n\t\tvar rtcic = opt.RTCIceCandidate || env.RTCIceCandidate || env.webkitRTCIceCandidate || env.mozRTCIceCandidate;\n\t\tif(!rtcpc || !rtcsd || !rtcic){ return }\n\t\topt.RTCPeerConnection = rtcpc;\n\t\topt.RTCSessionDescription = rtcsd;\n\t\topt.RTCIceCandidate = rtcic;\n\t\topt.rtc = opt.rtc || {'iceServers': [\n      {urls: 'stun:stun.l.google.com:19302'},\n      {urls: 'stun:stun.cloudflare.com:3478'}/*,\n      {urls: \"stun:stun.sipgate.net:3478\"},\n      {urls: \"stun:stun.stunprotocol.org\"},\n      {urls: \"stun:stun.sipgate.net:10000\"},\n      {urls: \"stun:217.10.68.152:10000\"},\n      {urls: 'stun:stun.services.mozilla.com'}*/ \n    ]};\n    // TODO: Select the most appropriate stuns. \n    // FIXME: Find the wire throwing ICE Failed\n    // The above change corrects at least firefox RTC Peer handler where it **throws** on over 6 ice servers, and updates url: to urls: removing deprecation warning \n    opt.rtc.dataChannel = opt.rtc.dataChannel || {ordered: false, maxRetransmits: 2};\n    opt.rtc.sdp = opt.rtc.sdp || {mandatory: {OfferToReceiveAudio: false, OfferToReceiveVideo: false}};\n    opt.rtc.max = opt.rtc.max || 55; // is this a magic number? // For Future WebRTC notes: Chrome 500 max limit, however 256 likely - FF \"none\", webtorrent does 55 per torrent.\n    opt.rtc.room = opt.rtc.room || GUN.window && (location.hash.slice(1) || location.pathname.slice(1));\n    opt.announce = function(to){\n\t\t\topt.rtc.start = +new Date; // handle room logic:\n\t\t\troot.$.get('/RTC/'+opt.rtc.room+'<?99').get('+').put(opt.pid, function(ack){\n\t\t\t\tif(!ack.ok || !ack.ok.rtc){ return }\n\t\t\t\tplan(ack);\n\t\t\t}, {acks: opt.rtc.max}).on(function(last,key, msg){\n\t\t\t\tif(last === opt.pid || opt.rtc.start > msg.put['>']){ return }\n\t\t\t\tplan({'#': ''+msg['#'], ok: {rtc: {id: last}}});\n\t\t\t});\n    };\n\n\t\tvar mesh = opt.mesh = opt.mesh || GUN.Mesh(root), wired = mesh.wire;\n    mesh.hear['rtc'] = plan;\n\t\tmesh.wire = function(media){ try{ wired && wired(media);\n    \tif(!(media instanceof MediaStream)){ return }\n    \t(open.media = open.media||{})[media.id] = media;\n    \tfor(var p in opt.peers){ p = opt.peers[p]||'';\n    \t\tp.addTrack && media.getTracks().forEach(track => {\n\t\t\t    p.addTrack(track, media);\n\t\t\t  });\n    \t\tp.createOffer && p.createOffer(function(offer){\n\t\t\t\t\tp.setLocalDescription(offer);\n\t\t\t\t\tmesh.say({'#': root.ask(plan), dam: 'rtc', ok: {rtc: {offer: offer, id: opt.pid}}}, p);\n\t\t\t\t}, function(){}, opt.rtc.sdp);\n    \t}\n\t\t} catch(e){console.log(e)} }\n\t\troot.on('create', function(at){\n\t\t\tthis.to.next(at);\n\t\t\tsetTimeout(opt.announce, 1);\n\t\t});\n\n\t\tfunction plan(msg){\n\t\t\tif(!msg.ok){ return }\n\t\t\tvar rtc = msg.ok.rtc, peer, tmp;\n\t\t\tif(!rtc || !rtc.id || rtc.id === opt.pid){ return }\n\t\t\tpeer = open(msg, rtc);\n\t\t\tif(tmp = rtc.candidate){\n\t\t\t\treturn peer.addIceCandidate(new opt.RTCIceCandidate(tmp));\n\t\t\t}\n\t\t\tif(tmp = rtc.answer){\n\t\t\t\ttmp.sdp = tmp.sdp.replace(/\\\\r\\\\n/g, '\\r\\n');\n\t\t\t\treturn peer.setRemoteDescription(peer.remoteSet = new opt.RTCSessionDescription(tmp)); \n\t\t\t}\n\t\t\tif(tmp = rtc.offer){\n\t\t\t\trtc.offer.sdp = rtc.offer.sdp.replace(/\\\\r\\\\n/g, '\\r\\n');\n\t\t\t\tpeer.setRemoteDescription(new opt.RTCSessionDescription(tmp));\n\t\t\t\treturn peer.createAnswer(function(answer){\n\t\t\t\t\tpeer.setLocalDescription(answer);\n\t\t\t\t\troot.on('out', {'@': msg['#'], ok: {rtc: {answer: answer, id: opt.pid}}});\n\t\t\t\t}, function(){}, opt.rtc.sdp);\n\t\t\t}\n\t\t}\n\t\tfunction open(msg, rtc, peer){\n\t\t\tif(peer = opt.peers[rtc.id] || open[rtc.id]){ return peer }\n\t\t\t(peer = new opt.RTCPeerConnection(opt.rtc)).id = rtc.id;\n\t\t\tvar wire = peer.wire = peer.createDataChannel('dc', opt.rtc.dataChannel);\n\t\t\tfunction rtceve(eve){ eve.peer = peer; gun.on('rtc', eve) }\n\t\t\tpeer.$ = gun;\n\t\t\topen[rtc.id] = peer;\n\t\t\tpeer.ontrack = rtceve;\n\t\t\tpeer.onremovetrack = rtceve;\n\t\t\tpeer.onconnectionstatechange = rtceve;\n\t\t\twire.to = setTimeout(function(){delete open[rtc.id]},1000*60);\n\t\t\twire.onclose = function(){ mesh.bye(peer) };\n\t\t\twire.onerror = function(err){ };\n\t\t\twire.onopen = function(e){\n\t\t\t\tdelete open[rtc.id];\n\t\t\t\tmesh.hi(peer);\n\t\t\t}\n\t\t\twire.onmessage = function(msg){\n\t\t\t\tif(!msg){ return }\n\t\t\t\tmesh.hear(msg.data || msg, peer);\n\t\t\t};\n\t\t\tpeer.onicecandidate = function(e){ rtceve(e);\n        if(!e.candidate){ return }\n        root.on('out', {'@': (msg||'')['#'], '#': root.ask(plan), ok: {rtc: {candidate: e.candidate, id: opt.pid}}});\n\t\t\t}\n\t\t\tpeer.ondatachannel = function(e){ rtceve(e);\n\t\t\t\tvar rc = e.channel;\n\t\t\t\trc.onmessage = wire.onmessage;\n\t\t\t\trc.onopen = wire.onopen;\n\t\t\t\trc.onclose = wire.onclose;\n\t\t\t}\n\t\t\tif(rtc.offer){ return peer }\n\t\t\tfor(var m in open.media){ m = open.media[m];\n\t\t\t\tm.getTracks().forEach(track => {\n\t\t\t    peer.addTrack(track, m);\n\t\t\t  });\n\t\t\t}\n\t\t\tpeer.createOffer(function(offer){\n\t\t\t\tpeer.setLocalDescription(offer);\n\t\t\t\troot.on('out', {'@': (msg||'')['#'], '#': root.ask(plan), ok: {rtc: {offer: offer, id: opt.pid}}});\n\t\t\t}, function(){}, opt.rtc.sdp);\n\t\t\treturn peer;\n\t\t}\n\t});\n}());\n"
  },
  {
    "path": "lib/wire.js",
    "content": "var Gun = require('../gun');\n\n/*\n\tAn Ad-Hoc Mesh-Network Daisy-Chain\n\tshould work even if humans are\n\tcommunicating with each other blind.\n\n\tTo prevent infinite broadcast loops,\n\twe use a deduplication process\n\tbased on the message's identifier.\n\tThis is currently implemented in core.\n\n\tHowever, because this still creates a\n\tN*2 (where N is the number of connections)\n\tflood, it is not scalable for traditional\n\tservices that have a hub network topology.\n\n\tDoes this mean we have to abandon mesh\n\talgorithms? No, we can simply layer more\n\tefficient optimizations in based on constraints.\n\tIf these constraints exist, it automatically\n\tupgrades, but if not, it falls back to the\n\tbrute-force mesh based robust algorithm.\n\tA simple example is to limit peer connections\n\tand rely upon daisy chaining to relay messages.\n\n\tAnother example, is if peers are willing to\n\tidentify themselves, then we can improve the\n\tefficiency of the network by having each peer\n\tinclude the names of peers it is connected in\n\teach message. Then each subsequent peer will\n\tnot relay it to them, since it is unnecessary.\n\tThis should create N (where N is the number of\n\tpeers) messages (or possibly N+ if there is a\n\tcommon peer of uncommon peers that receives it\n\tand relays at exact latency timings), which is\n\toptimal.\n\n\tSince computer networks aren't actually blind,\n\twe will implement the above method to improve\n\tthe performance of the ad-hoc mesh network.\n\n\tBut why not have every message contain the\n\twhole history of peers that it relayed through?\n\tBecause in sufficiently large enough networks,\n\twith extensive daisy chaining, this will cause\n\tthe message to become prohibitively slow and\n\tincrease indefinitely in size.\n\n*/\n\nGun.on('opt', function (root) {\n\tvar opt = root.opt;\n\tif (false === opt.ws || opt.once) {\n\t\tthis.to.next(root);\n\t\treturn;\n\t}\n\topt.mesh = opt.mesh || Gun.Mesh(root);\n\topt.WebSocket = opt.WebSocket || require('ws');\n\tvar ws = opt.ws = opt.ws || {};\n\tws.path = ws.path || '/gun';\n\t// if we DO need an HTTP server, then choose ws specific one or GUN default one.\n\tif (!opt.web || ws.noServer) {\n\t\tthis.to.next(root);\n\t\treturn;// no server no sockets\n\t}\n\tws.noServer = true;//workaround for ws.path\n\tws.web = ws.web || new opt.WebSocket.Server(ws);\n\topt.web.on('upgrade', (req, socket, head) => {\n\t\topt.web.host = opt.web.host || (req.headers||'').origin || (req.headers||'').host; \n\t\tif (req.url == ws.path) {\n\t\t\tws.web.handleUpgrade(req, socket, head, function done(ws) {\n\t\t\t\topen(ws, req);\n\t\t\t});\n\t\t}\n\t});\n\tfunction open(wire, req) {\n\t\tvar peer;\n\t\twire.headers = wire.headers || (req || '').headers || '';\n\t\tconsole.STAT && ((console.STAT.sites || (console.STAT.sites = {}))[wire.headers.origin] = 1);\n\t\topt.mesh.hi(peer = { wire: wire });\n\t\twire.on('message', function (msg) {\n\t\t\topt.mesh.hear(msg.data || msg, peer);\n\t\t});\n\t\twire.on('close', function () {\n\t\t\topt.mesh.bye(peer);\n\t\t});\n\t\twire.on('error', function (e) { });\n\t\tsetTimeout(function heart() { if (!opt.peers[peer.id]) { return } try { wire.send(\"[]\") } catch (e) { }; setTimeout(heart, 1000 * 20) }, 1000 * 20); // Some systems, like Heroku, require heartbeats to not time out. // TODO: Make this configurable? // TODO: PERF: Find better approach than try/timeouts?\n\t}\n\tthis.to.next(root);\n});\n"
  },
  {
    "path": "lib/ws.js",
    "content": "var Gun = require('../gun');\n\nvar WebSocket = require('ws');\n\nvar url = require('url');\n\nGun.on('opt', function mount(ctx){\n\tthis.to.next(ctx);\n\tvar opt = ctx.opt;\n\tif( !opt.peers )\n\t\tif( typeof( opt == \"string\" ) )\n\t\t\topt.peers = [opt];\n\n\tif(ctx.once){ return }\n\tif(false === opt.ws){ return }\n\tvar ws = opt.ws || (opt.ws = {}), batch;\n\n\tif(opt.web){ \n\t\tws.server = ws.server || opt.web;\n\t\tws.path = ws.path || '/gun';\n\n\t\tif (!ws.web) ws.web = new WebSocket.Server(ws);\n\n\t\tws.web.on('connection', function(wire){\n\t\t\twire.upgradeReq = wire.upgradeReq || {};\n\t\t\twire.url = url.parse(wire.upgradeReq.url||'', true);\n\t\t\twire.id = wire.id || Gun.text.random(6);\n\t\t\tvar peer = opt.peers[wire.id] = {wire: wire};\n\t\t\twire.peer = function(){ return peer };\n\t\t\tctx.on('hi', peer);\n\t\t\twire.on('message', function(msg){\n\t\t\t\t//console.log(\"MESSAGE\", msg);\n\t\t\t\treceive(msg, wire, ctx); // diff: wire is wire.\n\t\t\t});\n\t\t\twire.on('close', function(){\n\t\t\t\tctx.on('bye', peer);\n\t\t\t\tGun.obj.del(opt.peers, wire.id);\n\t\t\t});\n\t\t\twire.on('error', function(e){});\n\t\t});\t\n\t}\n\t\n\tctx.on('out', function(at){\n\t\tthis.to.next(at);\n\t\tbatch = JSON.stringify(at);\n\t\tif(ws.drain){\n\t\t\tws.drain.push(batch);\n\t\t\treturn;\n\t\t}\n\t\tws.drain = [];\n\t\tsetTimeout(function(){\n\t\t\tif(!ws.drain){ return }\n\t\t\tvar tmp = ws.drain;\n\t\t\tws.drain = null;\n\t\t\tif(!tmp.length){ return }\n\t\t\tbatch = JSON.stringify(tmp);\n\t\t\tGun.obj.map(opt.peers, send, ctx);\n\t\t}, opt.gap || opt.wait || 1);\n\t\tGun.obj.map(opt.peers, send, ctx);\n\t});\n\n\t// EVERY message taken care of. The \"extra\" ones are from in-memory not having \"asked\" for it yet - which we won't want it to do for foreign requests. Likewise, lots of chattyness because the put/ack replies happen before the `get` syncs so everybody now has it in-memory already to reply with.\n\tfunction send(peer){\n\t\tvar ctx = this, msg = batch;\n\t\tvar wire = peer.wire || open(peer, ctx);\n\t\tif(!wire){ return }\n\t\tif(wire.readyState === wire.OPEN){\n\t\t\twire.send(msg);\n\t\t\treturn;\n\t\t}\n\t\t(peer.queue = peer.queue || []).push(msg);\n\t}\n\tfunction receive(msg, wire, ctx){\n\t\tif(!ctx){ return }\n\t\ttry{msg = JSON.parse(msg.data || msg);\n\t\t}catch(e){}\n\t\tif(msg instanceof Array){\n\t\t\tvar i = 0, m;\n\t\t\twhile(m = msg[i++]){\n\t\t\t\treceive(m, wire, ctx); // wire not peer!\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tmsg.peer = wire.peer;\n\t\tctx.on('in', msg);\n\t}\n\tfunction open(peer, as){\n\t\tif(!peer || !peer.url){ return }\n\t\tvar url = peer.url.replace('http', 'ws');\n\t\tvar wire = peer.wire = new WebSocket(url);\n\t\twire.on('close', function(){\n\t\t\treconnect(peer, as);\n\t\t});\n\t\twire.on('error', function(error){\n\t\t\tif(!error){ return }\n\t\t\tif(error.code === 'ECONNREFUSED'){\n\t\t\t\treconnect(peer, as); // placement?\n\t\t\t}\n\t\t});\n\t\twire.on('open', function(){\n\t\t\tvar queue = peer.queue;\n\t\t\tpeer.queue = [];\n\t\t\tGun.obj.map(queue, function(msg){\n\t\t\t\tbatch = msg;\n\t\t\t\tsend.call(as, peer);\n\t\t\t});\n\t\t});\n\t\twire.on('message', function(msg){\n\t\t\treceive(msg, wire, as); // diff: wire not peer!\n\t\t});\n\t\treturn wire;\n\t}\n\n\tfunction reconnect(peer, as){\n\t\tclearTimeout(peer.defer);\n\t\tpeer.defer = setTimeout(function(){\n\t\t\topen(peer, as);\n\t\t}, 2 * 1000);\n\t}\n});\n"
  },
  {
    "path": "lib/wsp.js",
    "content": ";(function(wsp){\r\n\tvar Gun = require('../gun')\r\n\t, ws = require('ws').Server\r\n\t, http = require('./http')\r\n\t, url = require('url');\r\n\tGun.on('opt').event(function(gun, opt){\r\n\t\tgun.__.opt.ws = opt.ws = gun.__.opt.ws || opt.ws || {};\r\n\t\tfunction start(server, port, app){\r\n\t\t\tif(app && app.use){ app.use(gun.wsp.server) }\r\n\t\t\tserver = gun.__.opt.ws.server = gun.__.opt.ws.server || opt.ws.server || server;\r\n\t\t\trequire('./ws')(gun.wsp.ws = gun.wsp.ws || new ws(gun.__.opt.ws), function(req, res){\r\n\t\t\t\tvar ws = this;\r\n\t\t\t\treq.headers['gun-sid'] = ws.sid = (ws.sid? ws.sid : req.headers['gun-sid']);\r\n\t\t\t\tws.sub = ws.sub || gun.wsp.on('network').event(function(msg){\r\n\t\t\t\t\tif(!ws || !ws.send || !ws._socket || !ws._socket.writable){ return this.off() }\r\n\t\t\t\t\tif(!msg || (ws.sid && msg.headers && msg.headers['gun-sid'] === ws.sid)){ return }\r\n\t\t\t\t\tif(msg && msg.headers){ delete msg.headers['ws-rid'] }\r\n\t\t\t\t\t// TODO: BUG? ^ What if other peers want to ack? Do they use the ws-rid or a gun declared id?\r\n\t\t\t\t\ttry{ws.send(Gun.text.ify(msg));\r\n\t\t\t\t\t}catch(e){} // juuuust in case.\n\t\t\t\t});\r\n\t\t\t\tgun.wsp.wire(req, res);\r\n\t\t\t});\r\n\t\t\tgun.__.opt.ws.port = gun.__.opt.ws.port || opt.ws.port || port || 80;\r\n\t\t}\r\n\t\tvar wsp = gun.wsp = gun.wsp || function(server, auth){\r\n\t\t\tgun.wsp.auth = auth;\r\n\t\t\tif(!server){ return gun }\r\n\t\t\tif(Gun.fns.is(server.address)){\r\n\t\t\t\tif(server.address()){\r\n\t\t\t\t\tstart(server, server.address().port);\r\n\t\t\t\t\treturn gun;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif(Gun.fns.is(server.get) && server.get('port')){\r\n\t\t\t\tstart(server, server.get('port'));\r\n\t\t\t\treturn gun;\r\n\t\t\t}\r\n\t\t\tvar listen = server.listen;\r\n\t\t\tserver.listen = function(port){\r\n\t\t\t\tvar serve = listen.apply(server, arguments);\r\n\t\t\t\tstart(serve, port, server);\r\n\t\t\t\treturn serve;\r\n\t\t\t}\r\n\t\t\treturn gun;\r\n\t\t}\r\n\t\tgun.wsp.on = gun.wsp.on || Gun.on.create();\r\n\t\tgun.wsp.regex = gun.wsp.regex || opt.route || opt.path || /^\\/gun/i;\r\n\t\tgun.wsp.poll = gun.wsp.poll || opt.poll || 1;\r\n\t\tgun.wsp.pull = gun.wsp.pull || opt.pull || gun.wsp.poll * 1000;\r\n\t\tgun.wsp.server = gun.wsp.server || function(req, res, next){ // http\r\n\t\t\tnext = next || function(){};\r\n\t\t\tif(!req || !res){ return next(), false }\r\n\t\t\tif(!req.url){ return next(), false }\r\n\t\t\tif(!req.method){ return next(), false }\r\n\t\t\tvar msg = {};\r\n\t\t\tmsg.url = url.parse(req.url, true);\r\n\t\t\tif(!gun.wsp.regex.test(msg.url.pathname)){ return next(), false } // TODO: BUG! If the option isn't a regex then this will fail!\r\n\t\t\tif(msg.url.pathname.replace(gun.wsp.regex,'').slice(0,3).toLowerCase() === '.js'){\r\n\t\t\t\tres.writeHead(200, {'Content-Type': 'text/javascript'});\r\n\t\t\t\tres.end(gun.wsp.js = gun.wsp.js || require('fs').readFileSync(__dirname + '/../gun.js')); // gun server is caching the gun library for the client\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\treturn http(req, res, function(req, res){\r\n\t\t\t\tif(!req){ return next() }\r\n\t\t\t\tvar stream, cb = res = require('./jsonp')(req, res);\r\n\t\t\t\tif(req.headers && (stream = req.headers['gun-sid'])){\r\n\t\t\t\t\tstream = (gun.wsp.peers = gun.wsp.peers || {})[stream] = gun.wsp.peers[stream] || {sid: stream};\r\n\t\t\t\t\tstream.sub = stream.sub || gun.wsp.on('network').event(function(req){\r\n\t\t\t\t\t\tif(!stream){ return this.off() } // self cleans up after itself!\r\n\t\t\t\t\t\tif(!req || (req.headers && req.headers['gun-sid'] === stream.sid)){ return }\r\n\t\t\t\t\t\t(stream.queue = stream.queue || []).push(req);\r\n\t\t\t\t\t\tstream.drain(stream.reply);\r\n\t\t\t\t\t});\r\n\t\t\t\t\tcb = function(r){ (r.headers||{}).poll = gun.wsp.poll; res(r) }\r\n\t\t\t\t\tstream.drain = stream.drain || function(res){\r\n\t\t\t\t\t\tif(!res || !stream || !stream.queue || !stream.queue.length){ return }\r\n\t\t\t\t\t\tres({headers: {'gun-sid': stream.sid}, body: stream.queue });\r\n\t\t\t\t\t\tstream.off = setTimeout(function(){ stream = null }, gun.wsp.pull);\r\n\t\t\t\t\t\tstream.reply = stream.queue = null;\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tclearTimeout(stream.off);\r\n\t\t\t\t\tif(req.headers.pull){\r\n\t\t\t\t\t\tif(stream.drain(cb)){ return }\r\n\t\t\t\t\t\treturn stream.reply = cb;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tgun.wsp.wire(req, cb);\r\n\t\t\t}), true;\r\n\t\t}\r\n\t\tif((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false){\r\n\t\t\trequire('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = gun.__.opt.maxSockets || Infinity;\r\n\t\t}\r\n\t\tgun.wsp.msg = gun.wsp.msg || function(id){\r\n\t\t\tif(!id){\r\n\t\t\t\treturn gun.wsp.msg.debounce[id = Gun.text.random(9)] = Gun.time.is(), id;\r\n\t\t\t}\r\n\t\t\tclearTimeout(gun.wsp.msg.clear);\r\n\t\t\tgun.wsp.msg.clear = setTimeout(function(){\r\n\t\t\t\tvar now = Gun.time.is();\r\n\t\t\t\tGun.obj.map(gun.wsp.msg.debounce, function(t,id){\r\n\t\t\t\t\tif((now - t) < (1000 * 60 * 5)){ return }\r\n\t\t\t\t\tGun.obj.del(gun.wsp.msg.debounce, id);\r\n\t\t\t\t});\r\n\t\t\t},500);\r\n\t\t\tif(id = gun.wsp.msg.debounce[id]){\n\t\t\t\treturn gun.wsp.msg.debounce[id] = Gun.time.is(), id;\r\n\t\t\t}\r\n\t\t};\r\n\t\tgun.wsp.msg.debounce = gun.wsp.msg.debounce || {};\r\n\t\tgun.wsp.wire = gun.wsp.wire || (function(){\r\n\t\t\t// all streams, technically PATCH but implemented as PUT or POST, are forwarded to other trusted peers\r\n\t\t\t// except for the ones that are listed in the message as having already been sending to.\r\n\t\t\t// all states, implemented with GET, are replied to the source that asked for it.\r\n\t\t\tfunction flow(req, res){\n\t\t\t\tif (!req.auth || req.headers.broadcast) {\n\t\t\t\t\tgun.wsp.on('network').emit(Gun.obj.copy(req));\n\t\t\t\t}\n\t\t\t\tif(req.headers.rid){ return } // no need to process.\n\t\t\t\tif(Gun.is.lex(req.body)){ return tran.get(req, res) }\r\n\t\t\t\telse { return tran.put(req, res) }\r\n\t\t\t}\r\n\t\t\tfunction tran(req, res){\r\n\t\t\t\tif(!req || !res || !req.body || !req.headers || !req.headers.id){ return }\r\n\t\t\t\tif(gun.wsp.msg(req.headers.id)){ return }\r\n\t\t\t\treq.method = (req.body && !Gun.is.lex(req.body))? 'put' : 'get';\r\n\t\t\t\tif(gun.wsp.auth){ return gun.wsp.auth(req, function(reply){\r\n\t\t\t\t\tif(!reply.headers){ reply.headers = {} }\r\n\t\t\t\t\tif(!reply.headers['Content-Type']){ reply.headers['Content-Type'] = tran.json }\r\n\t\t\t\t\tif(!reply.rid){ reply.headers.rid = req.headers.id }\r\n\t\t\t\t\tif(!reply.id){ reply.headers.id = gun.wsp.msg() }\r\n\t\t\t\t\tres(reply);\r\n\t\t\t\t}, flow) }\r\n\t\t\t\telse { return flow(req, res) }\r\n\t\t\t}\r\n\t\t\ttran.get = function(req, cb){\r\n\t\t\t\tvar key = req.url.key\r\n\t\t\t\t, reply = {headers: {'Content-Type': tran.json, rid: req.headers.id, id: gun.wsp.msg()}};\r\n\t\t\t\t//Gun.log(req);\r\n\t\t\t\t// NTS HACK! SHOULD BE ITS OWN ISOLATED MODULE! //\r\n\t\t\t\tif(req && req.url && req.url.pathname && req.url.pathname.indexOf('gun.nts') >= 0){\r\n\t\t\t\t\treturn cb({headers: reply.headers, body: {time: Gun.time.is() }});\r\n\t\t\t\t}\r\n\t\t\t\t// NTS END! SHOULD HAVE BEEN ITS OWN MODULE //\r\n\t\t\t\t// ALL HACK! SHOULD BE ITS OWN MODULE OR CORE? //\r\n\t\t\t\tif(req && req.url && Gun.obj.has(req.url.query, '*')){\r\n\t\t\t\t\treturn gun.all(req.url.key + req.url.search, function(err, list){\r\n\t\t\t\t\t\tcb({headers: reply.headers, body: (err? (err.err? err : {err: err || \"Unknown error.\"}) : list || null ) })\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\t//Gun.log(\"GET!\", req);\r\n\t\t\t\tkey = req.body;\r\n\t\t\t\t//Gun.log(\"tran.get\", key);\r\n\t\t\t\tvar opt = {key: false, local: true};\r\n\t\t\t\t//gun.get(key, function(err, node){\r\n\t\t\t\t(gun.__.opt.wire.get||function(key, cb){cb(null,null)})(key, function(err, node){\r\n\t\t\t\t\t//Gun.log(\"tran.get\", key, \"<---\", err, node);\r\n\t\t\t\t\treply.headers.id = gun.wsp.msg();\r\n\t\t\t\t\tif(err || !node){\r\n\t\t\t\t\t\tif(opt.on && opt.on.off){ opt.on.off() }\r\n\t\t\t\t\t\treturn cb({headers: reply.headers, body: (err? (err.err? err : {err: err || \"Unknown error.\"}) : null)});\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif(Gun.obj.empty(node)){\n\t\t\t\t\t\tif(opt.on && opt.on.off){ opt.on.off() }\r\n\t\t\t\t\t\treturn cb({headers: reply.headers, body: node});\r\n\t\t\t\t\t} // we're out of stuff!\r\n\t\t\t\t\t/*\r\n\t\t\t\t\t(function(chunks){ // FEATURE! Stream chunks if the nodes are large!\r\n\t\t\t\t\t\tvar max = 10, count = 0, soul = Gun.is.node.soul(node);\r\n\t\t\t\t\t\tif(Object.keys(node).length > max){\r\n\t\t\t\t\t\t\tvar n = Gun.is.node.soul.ify({}, soul);\r\n\t\t\t\t\t\t\tGun.obj.map(node, function(val, field){\r\n\t\t\t\t\t\t\t\tif(!(++count % max)){\r\n\t\t\t\t\t\t\t\t\tcb({headers: reply.headers, chunk: n}); // send node chunks\r\n\t\t\t\t\t\t\t\t\tn = Gun.is.node.soul.ify({}, soul);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tGun.is.node.state.ify([n, node], field, val);\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\tif(count % max){ // finish off the last chunk\r\n\t\t\t\t\t\t\t\tcb({headers: reply.headers, chunk: n});\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tcb({headers: reply.headers, chunk: node}); // send full node\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}([]));\r\n\t\t\t\t\t*/\r\n\t\t\t\t\tcb({headers: reply.headers, chunk: node }); // Use this if you don't want streaming chunks feature.\r\n\t\t\t\t}, opt);\r\n\t\t\t}\r\n\t\t\ttran.put = function(req, cb){\r\n\t\t\t\t// NOTE: It is highly recommended you do your own PUT/POSTs through your own API that then saves to gun manually.\r\n\t\t\t\t// This will give you much more fine-grain control over security, transactions, and what not.\r\n\t\t\t\tvar reply = {headers: {'Content-Type': tran.json, rid: req.headers.id, id: gun.wsp.msg()}};\r\n\t\t\t\tif(!req.body){ return cb({headers: reply.headers, body: {err: \"No body\"}}) }\r\n\t\t\t\t//Gun.log(\"\\n\\ntran.put ----------------->\", req.body);\n\t\t\t\tif(Gun.is.graph(req.body)){\r\n\t\t\t\t\tif(req.err = Gun.union(gun, req.body, function(err, ctx){ // TODO: BUG? Probably should give me ctx.graph\r\n\t\t\t\t\t\tif(err){ return cb({headers: reply.headers, body: {err: err || \"Union failed.\"}}) }\r\n\t\t\t\t\t\tvar ctx = ctx || {}; ctx.graph = {};\r\n\t\t\t\t\t\tGun.is.graph(req.body, function(node, soul){\r\n\t\t\t\t\t\t\tctx.graph[soul] = gun.__.graph[soul];\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\t(gun.__.opt.wire.put || function(g,cb){cb(\"No save.\")})(ctx.graph, function(err, ok){\r\n\t\t\t\t\t\t\tif(err){ return cb({headers: reply.headers, body: {err: err || \"Failed.\"}}) } // TODO: err should already be an error object?\r\n\t\t\t\t\t\t\tcb({headers: reply.headers, body: {ok: ok || \"Persisted.\"}});\r\n\t\t\t\t\t\t\t//Gun.log(\"tran.put <------------------------\", ok);\r\n\t\t\t\t\t\t}, {local: true});\r\n\t\t\t\t\t}).err){ cb({headers: reply.headers, body: {err: req.err || \"Union failed.\"}}) }\r\n\t\t\t\t} else {\r\n\t\t\t\t\tcb({headers: reply.headers, body: {err: \"Not a valid graph!\"}});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tgun.wsp.on('network').event(function(req){\r\n\t\t\t\t// TODO: MARK! You should move the networking events to here, not in WSS only.\r\n\t\t\t});\r\n\t\t\ttran.json = 'application/json';\r\n\t\t\treturn tran;\r\n\t\t}());\r\n\t\tif(opt.server){\r\n\t\t\twsp(opt.server);\r\n\t\t}\r\n\r\n\t\tif(gun.wsp.driver){ return }\r\n\t\tvar driver = gun.wsp.driver = {};\r\n\t\tvar noop = function(){};\r\n\t\tvar get = gun.__.opt.wire.get || noop;\r\n\t\tvar put = gun.__.opt.wire.put || noop;\r\n\t\tvar driver = {\r\n\t\t\tput: function(graph, cb, opt){\r\n\t\t\t\tput(graph, cb, opt);\r\n\t\t\t\topt = opt || {};\r\n\t\t\t\tif(opt.local){ return }\r\n\t\t\t\tvar id = gun.wsp.msg();\r\n\t\t\t\tgun.wsp.on('network').emit({ // sent to dynamic peers!\r\n\t\t\t\t\theaders: {'Content-Type': 'application/json', id: id},\r\n\t\t\t\t\tbody: graph\r\n\t\t\t\t});\r\n\t\t\t\tvar ropt = {headers:{}, WebSocket: WebSocket};\r\n\t\t\t\tropt.headers.id = id;\r\n\t\t\t\tGun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){\r\n\t\t\t\t\tGun.request(url, graph, function(err, reply){\r\n\t\t\t\t\t\treply.body = reply.body || reply.chunk || reply.end || reply.write;\r\n\t\t\t\t\t\tif(err || !reply || (err = reply.body && reply.body.err)){\r\n\t\t\t\t\t\t\treturn cb({err: Gun.log(err || \"Put failed.\") });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcb(null, reply.body);\r\n\t\t\t\t\t}, ropt);\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\tget: function(lex, cb, opt){\r\n\t\t\t\tget(lex, cb, opt);\r\n\t\t\t\topt = opt || {};\r\n\t\t\t\tif(opt.local){ return }\r\n\t\t\t\tif(!Gun.request){ return console.log(\"Server could not find default network abstraction.\") }\r\n\t\t\t\tvar ropt = {headers:{}};\r\n\t\t\t\tropt.headers.id = gun.wsp.msg();\r\n\t\t\t\tGun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){\r\n\t\t\t\t\tGun.request(url, lex, function(err, reply){\r\n\t\t\t\t\t\treply.body = reply.body || reply.chunk || reply.end || reply.write;\r\n\t\t\t\t\t\tif(err || !reply || (err = reply.body && reply.body.err)){\r\n\t\t\t\t\t\t\treturn cb({err: Gun.log(err || \"Get failed.\") });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcb(null, reply.body);\r\n\t\t\t\t\t}, ropt);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t\tvar WebSocket = require('ws');\r\n\t\tGun.request.WebSocket = WebSocket;\r\n\t\tGun.request.createServer(gun.wsp.wire);\r\n\t\tgun.__.opt.wire = driver;\r\n\t\tgun.opt({wire: driver}, true);\r\n\t});\r\n}({}));\n"
  },
  {
    "path": "lib/wsproto.js",
    "content": ";(function(){\n\t/*\n\t\tHOW TO USE:\n\t\t1. On your HTML include gun and this file:\n\t\t<script src=\"gun.js\"></script>\n\t\t<script src=\"lib/wsproto.js\"></script>\n\t\t2. Initiate GUN with default WebSocket turned off:\n\t\tvar gun = Gun({WebSocket: false});\n\t*/\n\tvar WebSocket;\n\tif(typeof window !== 'undefined'){\n\t\tWebSocket = window.WebSocket || window.webkitWebSocket || window.mozWebSocket;\n\t} else {\n\t\treturn;\n\t}\n\tGun.on('opt', function(ctx){\n\t\tthis.to.next(ctx);\n\t\tvar opt = ctx.opt;\n\t\tif(ctx.once){ return }\n\t\topt.wsc = opt.wsc || {protocols:[]}; // for d3x0r!\n\t\tvar ws = opt.ws || (opt.ws = {}); ws.who = 0;\n\t\tGun.obj.map(opt.peers, function(){ ++ws.who });\n\t\tif(ctx.once){ return }\n\t\tvar batch;\n\n\t\tctx.on('out', function(at){\n\t\t\tthis.to.next(at);\n\t\t\tif(at.ws && 1 == ws.who){ return } // performance hack for reducing echoes.\n\t\t\tbatch = JSON.stringify(at);\n\t\t\tif(ws.drain){\n\t\t\t\tws.drain.push(batch);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tws.drain = [];\n\t\t\tsetTimeout(function(){\n\t\t\t\tif(!ws.drain){ return }\n\t\t\t\tvar tmp = ws.drain;\n\t\t\t\tws.drain = null;\n\t\t\t\tif(!tmp.length){ return }\n\t\t\t\tbatch = JSON.stringify(tmp);\n\t\t\t\tGun.obj.map(opt.peers, send, ctx);\n\t\t\t}, opt.wait || 1);\n\t\t\tGun.obj.map(opt.peers, send, ctx);\n\t\t});\n\t\tfunction send(peer){\n\t\t\tvar ctx = this, msg = batch;\n\t\t\tvar wire = peer.wire || open(peer, ctx);\n\t\t\tif(!wire){ return }\n\t\t\tif(wire.readyState === wire.OPEN){\n\t\t\t\twire.send(msg);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t(peer.queue = peer.queue || []).push(msg);\n\t\t}\n\t\tfunction receive(msg, peer, ctx){\n\t\t\tif(!ctx || !msg){ return }\n\t\t\ttry{msg = JSON.parse(msg.data || msg);\n\t\t\t}catch(e){}\n\t\t\tif(msg instanceof Array){\n\t\t\t\tvar i = 0, m;\n\t\t\t\twhile(m = msg[i++]){\n\t\t\t\t\treceive(m, peer, ctx);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(1 == ws.who){ msg.ws = noop } // If there is only 1 client, just use noop since it doesn't matter.\n\t\t\tctx.on('in', msg);\n\t\t}\n\t\tfunction open(peer, as){\n\t\t\tif(!peer || !peer.url){ return }\n\t\t\tvar url = peer.url.replace('http', 'ws');\n\t\t\tvar wire = peer.wire = new WebSocket(url, as.opt.wsc.protocols, as.opt.wsc);\n\t\t\twire.onclose = function(){\n\t\t\t\treconnect(peer, as);\n\t\t\t};\n\t\t\twire.onerror = function(error){\n\t\t\t\treconnect(peer, as); // placement?\n\t\t\t\tif(!error){ return }\n\t\t\t\tif(error.code === 'ECONNREFUSED'){\n\t\t\t\t\t//reconnect(peer, as);\n\t\t\t\t}\n\t\t\t};\n\t\t\twire.onopen = function(){\n\t\t\t\tvar queue = peer.queue;\n\t\t\t\tpeer.queue = [];\n\t\t\t\tGun.obj.map(queue, function(msg){\n\t\t\t\t\tbatch = msg;\n\t\t\t\t\tsend.call(as, peer);\n\t\t\t\t});\n\t\t\t}\n\t\t\twire.onmessage = function(msg){\n\t\t\t\treceive(msg, peer, as); // diff: peer not wire!\n\t\t\t};\n\t\t\treturn wire;\n\t\t}\n\t\tfunction reconnect(peer, as){\n\t\t\tclearTimeout(peer.defer);\n\t\t\tpeer.defer = setTimeout(function(){\n\t\t\t\topen(peer, as);\n\t\t\t}, 2 * 1000);\n\t\t}\n\t});\n\tvar noop = function(){};\n}());"
  },
  {
    "path": "lib/yson.js",
    "content": ";(function(){\n// JSON: JavaScript Object Notation\n// YSON: Yielding javaScript Object Notation\nvar yson = {}, u, sI = setTimeout.turn || (typeof setImmediate != ''+u && setImmediate) || setTimeout;\n\nyson.parseAsync = function(text, done, revive, M){\n\tif('string' != typeof text){ try{ done(u,JSON.parse(text)) }catch(e){ done(e) } return }\n\tvar ctx = {i: 0, text: text, done: done, l: text.length, up: []};\n\t//M = 1024 * 1024 * 100;\n\t//M = M || 1024 * 64;\n\tM = M || 1024 * 32;\n\tparse();\n\tfunction parse(){\n\t\t//var S = +new Date;\n\t\tvar s = ctx.text;\n\t\tvar i = ctx.i, l = ctx.l, j = 0;\n\t\tvar w = ctx.w, b, tmp;\n\t\twhile(j++ < M){\n\t\t\tvar c = s[i++];\n\t\t\tif(i > l){\n\t\t\t\tctx.end = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(w){\n\t\t\t\ti = s.indexOf('\"', i-1); c = s[i];\n\t\t\t\ttmp = 0; while('\\\\' == s[i-(++tmp)]){}; tmp = !(tmp % 2);//tmp = ('\\\\' == s[i-1]); // json is stupid\n\t\t\t\tb = b || tmp;\n\t\t\t\tif('\"' == c && !tmp){\n\t\t\t\t\tw = u;\n\t\t\t\t\ttmp = ctx.s;\n\t\t\t\t\tif(ctx.a){\n\t\t\t\t\t\ttmp = s.slice(ctx.sl, i);\n\t\t\t\t\t\tif(b || (1+tmp.indexOf('\\\\'))){ tmp = JSON.parse('\"'+tmp+'\"') } // escape + unicode :( handling\n\t\t\t\t\t\tif(ctx.at instanceof Array){\n\t\t\t\t\t\t\tctx.at.push(ctx.s = tmp);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif(!ctx.at){ ctx.end = j = M; tmp = u }\n\t\t\t\t\t\t\t(ctx.at||{})[ctx.s] = ctx.s = tmp;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.s = u;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.s = s.slice(ctx.sl, i);\n\t\t\t\t\t\tif(b || (1+ctx.s.indexOf('\\\\'))){ ctx.s = JSON.parse('\"'+ctx.s+'\"'); } // escape + unicode :( handling\n\t\t\t\t\t}\n\t\t\t\t\tctx.a = b = u;\n\t\t\t\t}\n\t\t\t\t++i;\n\t\t\t} else {\n\t\t\t\tswitch(c){\n\t\t\t\tcase '\"':\n\t\t\t\t\tctx.sl = i;\n\t\t\t\t\tw = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ':':\n\t\t\t\t\tctx.ai = i;\n\t\t\t\t\tctx.a = true;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ',':\n\t\t\t\t\tif(ctx.a || ctx.at instanceof Array){\n\t\t\t\t\t\tif(tmp = s.slice(ctx.ai, i-1)){\n\t\t\t\t\t\t\tif(u !== (tmp = value(tmp))){\n\t\t\t\t\t\t\t\tif(ctx.at instanceof Array){\n\t\t\t\t\t\t\t\t\tctx.at.push(tmp);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tctx.at[ctx.s] = tmp;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tctx.a = u;\n\t\t\t\t\tif(ctx.at instanceof Array){\n\t\t\t\t\t\tctx.a = true;\n\t\t\t\t\t\tctx.ai = i;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase '{':\n\t\t\t\t\tctx.up.push(ctx.at||(ctx.at = {}));\n\t\t\t\t\tif(ctx.at instanceof Array){\n\t\t\t\t\t\tctx.at.push(ctx.at = {});\n\t\t\t\t\t} else\n\t\t\t\t\tif(u !== (tmp = ctx.s)){\n\t\t\t\t\t\tctx.at[tmp] = ctx.at = {};\n\t\t\t\t\t}\n\t\t\t\t\tctx.a = u;\n\t\t\t\t\tbreak;\n\t\t\t\tcase '}':\n\t\t\t\t\tif(ctx.a){\n\t\t\t\t\t\tif(tmp = s.slice(ctx.ai, i-1)){\n\t\t\t\t\t\t\tif(u !== (tmp = value(tmp))){\n\t\t\t\t\t\t\t\tif(ctx.at instanceof Array){\n\t\t\t\t\t\t\t\t\tctx.at.push(tmp);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tif(!ctx.at){ ctx.end = j = M; tmp = u }\n\t\t\t\t\t\t\t\t\t(ctx.at||{})[ctx.s] = tmp;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tctx.a = u;\n\t\t\t\t\tctx.at = ctx.up.pop();\n\t\t\t\t\tbreak;\n\t\t\t\tcase '[':\n\t\t\t\t\tif(u !== (tmp = ctx.s)){\n\t\t\t\t\t\tctx.up.push(ctx.at);\n\t\t\t\t\t\tctx.at[tmp] = ctx.at = [];\n\t\t\t\t\t} else\n\t\t\t\t\tif(!ctx.at){\n\t\t\t\t\t\tctx.up.push(ctx.at = []);\n\t\t\t\t\t}\n\t\t\t\t\tctx.a = true;\n\t\t\t\t\tctx.ai = i;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ']':\n\t\t\t\t\tif(ctx.a){\n\t\t\t\t\t\tif(tmp = s.slice(ctx.ai, i-1)){\n\t\t\t\t\t\t\tif(u !== (tmp = value(tmp))){\n\t\t\t\t\t\t\t\tif(ctx.at instanceof Array){\n\t\t\t\t\t\t\t\t\tctx.at.push(tmp);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tctx.at[ctx.s] = tmp;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tctx.a = u;\n\t\t\t\t\tctx.at = ctx.up.pop();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tctx.s = u;\n\t\tctx.i = i;\n\t\tctx.w = w;\n\t\tif(ctx.end){\n\t\t\ttmp = ctx.at;\n\t\t\tif(u === tmp){\n\t\t\t\ttry{ tmp = JSON.parse(text)\n\t\t\t\t}catch(e){ return ctx.done(e) }\n\t\t\t}\n\t\t\tctx.done(u, tmp);\n\t\t} else {\n\t\t\tsI(parse);\n\t\t}\n\t}\n}\nfunction value(s){\n\tvar n = parseFloat(s);\n\tif(!isNaN(n)){\n\t\treturn n;\n\t}\n\ts = s.trim();\n\tif('true' == s){\n\t\treturn true;\n\t}\n\tif('false' == s){\n\t\treturn false;\n\t}\n\tif('null' == s){\n\t\treturn null;\n\t}\n}\n\nyson.stringifyAsync = function(data, done, replacer, space, ctx){\n\t//try{done(u, JSON.stringify(data, replacer, space))}catch(e){done(e)}return;\n\tctx = ctx || {};\n\tctx.text = ctx.text || \"\";\n\tctx.up = [ctx.at = {d: data}];\n\tctx.done = done;\n\tctx.i = 0;\n\tvar j = 0;\n\tify();\n\tfunction ify(){\n\t\tvar at = ctx.at, data = at.d, add = '', tmp;\n\t\tif(at.i && (at.i - at.j) > 0){ add += ',' }\n\t\tif(u !== (tmp = at.k)){ add += JSON.stringify(tmp) + ':' } //'\"'+tmp+'\":' } // only if backslash\n\t\tswitch(typeof data){\n\t\tcase 'boolean':\n\t\t\tadd += ''+data;\n\t\t\tbreak;\n\t\tcase 'string':\n\t\t\tadd += JSON.stringify(data); //ctx.text += '\"'+data+'\"';//JSON.stringify(data); // only if backslash\n\t\t\tbreak;\n\t\tcase 'number':\n\t\t\tadd += (isNaN(data)? 'null' : data);\n\t\t\tbreak;\n\t\tcase 'object':\n\t\t\tif(!data){\n\t\t\t\tadd += 'null';\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(data instanceof Array){\t\n\t\t\t\tadd += '[';\n\t\t\t\tat = {i: -1, as: data, up: at, j: 0};\n\t\t\t\tat.l = data.length;\n\t\t\t\tctx.up.push(ctx.at = at);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif('function' != typeof (data||'').toJSON){\n\t\t\t\tadd += '{';\n\t\t\t\tat = {i: -1, ok: Object.keys(data).sort(), as: data, up: at, j: 0};\n\t\t\t\tat.l = at.ok.length;\n\t\t\t\tctx.up.push(ctx.at = at);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(tmp = data.toJSON()){\n\t\t\t\tadd += tmp;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// let this & below pass into default case...\n\t\tcase 'function':\n\t\t\tif(at.as instanceof Array){\n\t\t\t\tadd += 'null';\n\t\t\t\tbreak;\n\t\t\t}\n\t\tdefault: // handle wrongly added leading `,` if previous item not JSON-able.\n\t\t\tadd = '';\n\t\t\tat.j++;\n\t\t}\n\t\tctx.text += add;\n\t\twhile(1+at.i >= at.l){\n\t\t\tctx.text += (at.ok? '}' : ']');\n\t\t\tat = ctx.at = at.up;\n\t\t}\n\t\tif(++at.i < at.l){\n\t\t\tif(tmp = at.ok){\n\t\t\t\tat.d = at.as[at.k = tmp[at.i]];\n\t\t\t} else {\n\t\t\t\tat.d = at.as[at.i];\n\t\t\t}\n\t\t\tif(++j < 9){ return ify() } else { j = 0 }\n\t\t\tsI(ify);\n\t\t\treturn;\n\t\t}\n\t\tctx.done(u, ctx.text);\n\t}\n}\nif(typeof window != ''+u){ window.YSON = yson }\ntry{ if(typeof module != ''+u){ module.exports = yson } }catch(e){}\nif(typeof JSON != ''+u){\n\tJSON.parseAsync = yson.parseAsync;\n\tJSON.stringifyAsync = yson.stringifyAsync;\n}\n\n}());"
  },
  {
    "path": "nts.js",
    "content": ";(function(){\n  var Gun  = (typeof window !== \"undefined\")? window.Gun : require('./gun');\n  var dam  = 'nts';\n  var smooth = 2;\n\n  Gun.on('create', function(root){ // switch to DAM, deprecated old\n    Gun.log.once(\"nts\", \"gun/nts is removed deprecated old\");\n    this.to.next(root);\n  \treturn ; // stub out for now. TODO: IMPORTANT! re-add back in later.\n    var opt = root.opt, mesh = opt.mesh;\n    if(!mesh) return;\n\n    // Track connections\n    var connections = [];\n    root.on('hi', function(peer) {\n      this.to.next(peer);\n      connections.push({peer, latency: 0, offset: 0, next: 0});\n    });\n    root.on('bye', function(peer) {\n      this.to.next(peer);\n      var found = connections.find(connection => connection.peer.id == peer.id);\n      if (!found) return;\n      connections.splice(connections.indexOf(found), 1);\n    });\n\n    function response(msg, connection) {\n      var now            = Date.now(); // Lack of drift intentional, provides more accurate RTT\n      connection.latency = (now - msg.nts[0]) / 2;\n      connection.offset  = (msg.nts[1] + connection.latency) - (now + Gun.state.drift);\n      console.log(connection.offset);\n      Gun.state.drift   += connection.offset / (connections.length + smooth);\n      console.log(`Update time by local: ${connection.offset} / ${connections.length + smooth}`);\n    }\n\n    // Handle echo & setting based on known connection latency as well\n    mesh.hear[dam] = function(msg, peer) {\n      console.log('MSG', msg);\n      var now   = Date.now() + Gun.state.drift;\n      var connection = connections.find(connection => connection.peer.id == peer.id);\n      if (!connection) return;\n      if (msg.nts.length >= 2) return response(msg, connection);\n      mesh.say({dam, '@': msg['#'], nts: msg.nts.concat(now)}, peer);\n      connection.offset = msg.nts[0] + connection.latency - now;\n      Gun.state.drift  += connection.offset / (connections.length + smooth);\n      console.log(`Update time by remote: ${connection.offset} / ${connections.length + smooth}`);\n    };\n\n    // Handle ping transmission\n    setTimeout(function trigger() {\n      console.log('TRIGGER');\n      if (!connections.length) return setTimeout(trigger, 100);\n      var now = Date.now(); // Lack of drift intentional, provides more accurate RTT & NTP reference\n\n      // Send pings\n      connections.forEach(function(connection) {\n        if (connection.next > now) return;\n        mesh.say({\n          dam,\n          '#': String.random(3),\n          nts: [now],\n        });\n      });\n\n      // Plan next round of pings\n      connections.forEach(function(connection) {\n        if (connection.next > now) return;\n        // https://discord.com/channels/612645357850984470/612645357850984473/755334349699809300\n        var delay = Math.min(2e4, Math.max(250, 150000 / Math.abs((connection.offset)||1)));\n        connection.next = now + delay;\n      });\n\n      // Plan next trigger round\n      // May overshoot by runtime of this function\n      var nextRound = Infinity;\n      connections.forEach(function(connection) {\n        nextRound = Math.min(nextRound, connection.next);\n      });\n      setTimeout(trigger, nextRound - now);\n      console.log(`Next sync round in ${(nextRound - now) / 1000} seconds`);\n    }, 1);\n  });\n\n}());\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"gun\",\n  \"version\": \"0.2020.1239\",\n  \"description\": \"A realtime, decentralized, offline-first, graph data synchronization engine.\",\n  \"types\": \"index.d.ts\",\n  \"main\": \"index.js\",\n  \"browser\": \"browser.js\",\n  \"ios\": \"browser.ios.js\",\n  \"android\": \"browser.android.js\",\n  \"scripts\": {\n    \"start\": \"node --prof examples/http.js\",\n    \"debug\": \"node --prof-process --preprocess -j isolate*.log > v8data.json && rm isolate*.log && echo 'drag & drop ./v8data.json into https://mapbox.github.io/flamebearer/'\",\n    \"https\": \"HTTPS_KEY=test/https/server.key HTTPS_CERT=test/https/server.crt npm start\",\n    \"prepublishOnly\": \"npm run unbuild\",\n    \"test\": \"echo 'Did you run PANIC holy-grail, 1~X, on-recover, etc.?' && mocha\",\n    \"testsea\": \"mocha test/sea/sea.js\",\n    \"e2e\": \"mocha e2e/distributed.js\",\n    \"docker\": \"hooks/build\",\n    \"minify\": \"uglifyjs gun.js -o gun.min.js -c -m\",\n    \"unbuild\": \"node lib/unbuild.js & npm run minify\",\n    \"unbuildSea\": \"node lib/unbuild.js sea\",\n    \"unbuildMeta\": \"node lib/unbuild.js lib/meta\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/amark/gun.git\"\n  },\n  \"keywords\": [\n    \"gun\",\n    \"gunDB\",\n    \"graph\",\n    \"document\",\n    \"key\",\n    \"value\",\n    \"relational\",\n    \"datastore\",\n    \"database\",\n    \"engine\",\n    \"realtime\",\n    \"decentralized\",\n    \"peer-to-peer\",\n    \"distributed\",\n    \"P2P\",\n    \"OSS\",\n    \"embedded\",\n    \"localstorage\",\n    \"S3\"\n  ],\n  \"author\": \"Mark Nadal\",\n  \"license\": \"(Zlib OR MIT OR Apache-2.0)\",\n  \"bugs\": {\n    \"url\": \"https://github.com/amark/gun/issues\"\n  },\n  \"homepage\": \"https://github.com/amark/gun#readme\",\n  \"engines\": {\n    \"node\": \">=0.8.4\"\n  },\n  \"tsd\": {\n    \"directory\": \"types\"\n  },\n  \"dependencies\": {\n    \"ws\": \"^7.2.1\"\n  },\n  \"optionalDependencies\": {\n    \"@peculiar/webcrypto\": \"^1.1.1\"\n  },\n  \"devDependencies\": {\n    \"mocha\": \"^6.2.0\",\n    \"ip\": \"^1.1.5\",\n    \"aws-sdk\": \"^2.528.0\",\n    \"emailjs\": \"^2.2.0\",\n    \"uglify-js\": \"^3.6.0\"\n  }\n}\n"
  },
  {
    "path": "rad.js",
    "content": ";(function(){ // RAD\n\tconsole.log(\"Warning: Experimental rewrite of RAD to use Book. It is not API compatible with RAD yet and is very alpha.\");\n\tvar sT = setTimeout, Book = sT.Book || require('gun/src/book'), RAD = sT.RAD || (sT.RAD = function(opt){\n\t\topt = opt || {};\n\t\topt.file = String(opt.file || 'radata');\n\t\tvar log = opt.log || console.log\n\n\t\tvar has = (sT.RAD.has || (sT.RAD.has = {}))[opt.file];\n\t\tif(has){ return has } // TODO: BUG? Not reuses same instance?\n\t\tvar r = function rad(word, is, reply){ r.word = word;\n\t\t\tif(!b){ start(word, is, reply); return r }\n\t\t\tif(is === undefined || 'function' == typeof is){ // THIS IS A READ:\n\t\t\t\tvar page = b.page(word);\n\t\t\t\tif(page.from){ return is && is(page, null), r }\n\t\t\t\treturn read(word, is, page), r; // get from disk\n\t\t\t}\n\t\t\t//console.log(\"OFF\");return;\n\t\t\t// ON WRITE:\n\t\t\t// batch until read from disk is done (and if a write was going, do that first)\n\t\t\t//if(!valid(word, is, reply)){ return }\n\t\t\tb(word, is);\n\t\t\twrite(word, reply);\n\t\t\treturn r;\n\t\t}, /** @param b the book */ b;\n\t\tr.then = function(cb, p){ return p = (new Promise(function(yes, no){ r(r.word, yes) })), cb? p.then(cb) : p }\n\t\tr.read = r.results = function(cb){ return (new Promise(async function(yes, no){ yes((await r(r.word)).read(cb)) })) }\n\n\t\tasync function read(word, reply, page){ // TODO: this function doesn't do much, inline it???\n\t\t\tif(!reply){ return }\n\t\t\tvar p = page || b.page(word);\n\t\t\tget(p, function(err, disk){\n\t\t\t\tif(err){ log(\"ERR! in read() get() cb\", err); reply(p.no, err); return }\n\t\t\t\tp.from = disk || p.from;\n\t\t\t\treply(p, null, b);\n\t\t\t})\n\t\t}\n\n\t\tfunction write(word, reply){\n\t\t\tvar p = b.page(word), tmp;\n\t\t\tif(tmp=p.saving){(reply||!tmp.length)&&(p.saving=tmp.concat(reply));return} // TODO: PERF! Rogowski points out concat is slow. BUG??? I HAVE NO clue how/why this if statement being called from recursion yet not set to 0.\n\t\t\tp.saving = ('function' == typeof reply)? [reply] : reply || [];\n\t\t\tget(p, function(err, disk){\n\t\t\t\tif(err){ log(\"ERR! in write() get() cb \", err); return } // TODO: BUG!!! Unhandled, no callbacks called.\n\t\t\t\tp.from = disk || p.from;\n\t\t\t\ttmp = p.saving; p.saving = [];\n\t\t\t\tput(p, ''+p, function(err, ok){\n\t\t\t\t\tsT.each(tmp, function(cb){ cb && cb(err, ok) });\n\t\t\t\t\ttmp = p.saving; p.saving = 0;\n\t\t\t\t\tif(tmp.length){ write(word, tmp) }\n\t\t\t\t});\n\t\t\t}, p);\n\t\t}\n\t\tfunction put(file, data, cb){\n\t\t\tput[file = fname(file)] = { data: data };\n\t\t\tRAD.put(file, data, function(err, ok){\n\t\t\t\tdelete put[file];\n\t\t\t\tcb && cb(err, ok);\n\t\t\t}, opt);\n\t\t};\n\t\tfunction get(file, cb){\n\t\t\tvar tmp;\n\t\t\tif(!file){ return } // TODO: HANDLE ERROR!!\n\t\t\tif(file.from){ cb(null, file.from); return }\n\t\t\tif(b&&1==b.list.length){ file.first = (file.first < '!')? file.first : '!'; } // TODO: BUG!!!! This cleanly makes for a common first file, but SAVING INVISIBLE ASCII KEYS IS COMPLETELY UNTESTED and guaranteed to have bugs/corruption issues.\n\t\t\tif(tmp = put[file = fname(file)]){ cb(u, tmp.data); return }\n\t\t\tif(tmp = get[file]){ tmp.push(cb); return } get[file] = [cb];\n\t\t\tRAD.get(file, function(err, data){\n\t\t\t\ttmp = get[file]||''; delete get[file];\n\t\t\t\tsT.each(tmp, function(cb){ cb && cb(err, data) });\n\t\t\t}, opt);\n\t\t};\n\n\t\tfunction start(word, is, reply){\n\t\t\tif(b){ r(word, is, reply); return }\n\t\t\tget(' ', function(err, d){\n\t\t\t\tif(err){ log('ERR! in start() get()', err); reply && reply(err); return }\n\t\t\t\tif(b){ r(word, is, reply); return }\n\t\t\t\tb = r.book = Book();\n\t\t\t\tif((d = Book.slot(d)).length){ b.list = d } // TODO: BUG! Add some other sort of corrupted/error check here?\n\t\t\t\twatch(b).parse = function(t){ return ('string' == typeof t)? Book.decode(Book.slot(t)[0]) : t } // TODO: This was ugly temporary, but is necessary, and is logically correct, but is there a cleaner, nicer, less assumptiony way to do it? // TODO: SOLUTION?! I think this needs to be in Book, not RAD.\n\t\t\t\tr(word, is, reply);\n\t\t\t})\n\t\t}\n\t\tfunction watch(b){ // SPLIT LOGIC!\n\t\t\tvar split = b.split;\n\t\t\tb.list.toString = function(){\n\t\t\t\t//console.time();\n\t\t\t\tvar i = -1, t = '', p; while (p = this[++i]){\n\t\t\t\t\tt += \"|\" +\"`\"+Book.encode(p.substring())+\"`\"+Book.encode(p.meta||null)+\"`\"\n\t\t\t\t}\n\t\t\t\tt += \"|\";\n\t\t\t\t//console.timeEnd();\n\t\t\t\treturn t;\n\t\t\t}\n\t\t\tb.split = function(next, page){\n\t\t\t\tput(' ', '' + b.list, function(err, ok){\n\t\t\t\t\tif(err){ console.log(\"ERR!\"); return }\n\t\t\t\t\t// ??\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn b;\n\t\t}\n\n\t\tfunction ename(t){ return encodeURIComponent(t).replace(/\\*/g, '%2A').slice(0, 250) }\n\t\t//function fname(p){ return opt.file + '/' + ename(p.substring()) }\n\t\tfunction fname(p){ return ename(p.substring()) }\n\n\t\tfunction valid(word, is, reply){\n\t\t\tif(is !== is){ reply(word +\" cannot be NaN!\"); return }\n\t\t\treturn true;\n\t\t}\n\n\t\treturn r;\n\t}), MAX = 1000/* 300000000 */;\n\tsT.each = sT.each || function(l,f){l.forEach(f)};\n\n\ttry { module.exports = RAD } catch (e){ }\n/*\n\t// junk below that needs to be cleaned up and corrected for the actual correct RAD API.\n\tvar env = {}, nope = function(){ }, nah = function(){ return nope }, u;\n\tenv.require = (typeof require !== '' + u && require) || nope;\n\tenv.process = (typeof process != '' + u && process) || { memoryUsage: nah };\n\tenv.os = env.require('os') || { totalmem: nope, freemem: nope };\n\tenv.v8 = env.require('v8') || { getHeapStatistics: nah };\n\tenv.fs = env.require('fs') || { writeFile: nope, readFile: nope };\n\n\n\tenv.max = env.v8.getHeapStatistics().total_available_size / (2 ** 12);\n\n\tenv.count = env.last = 0;\n\treturn;\n\n\t//if(err && 'ENOENT' === (err.code||'').toUpperCase()){ err = null }\n\n\tsetInterval(function(){\n\t\tvar stats = { memory: {} };\n\n\t\tstats.memory.total = env.os.totalmem() / 1024 / 1024; // in MB\n\t\tstats.memory.free = env.os.freemem() / 1024 / 1024; // in MB\n\t\tstats.memory.hused = env.v8.getHeapStatistics().used_heap_size / 1024 / 1024; // in MB\n\t\tstats.memory.used = env.process.memoryUsage().rss / 1024 / 1024; // in MB\n\t\tconsole.log(stats.memory);\n\t}, 9);\n*/\n}());\n\n\n; (function(){ // temporary fs storage plugin, needs to be refactored to use the actual RAD plugin interface.\n\tvar fs;\n\ttry { fs = require('fs') } catch (e){ };\n\tif(!fs){ return }\n\n\tvar sT = setTimeout, RAD = sT.RAD;\n\tRAD.put = function(file, data, cb, opt){\n\t\tfs.writeFile(opt.file+'/'+file, data, cb);\n\t}\n\tRAD.get = function(file, cb, opt){\n\t\tfs.readFile(opt.file+'/'+file, function(err, data){\n\t\t\tif(err && 'ENOENT' === (err.code||'').toUpperCase()){ return cb() }\n\t\t\tcb(err, (data||'').toString()||data);\n\t\t});\n\t}\n}());\n\n\n;(function(){ // temporary fs storage plugin, needs to be refactored to use the actual RAD plugin interface.\n\tvar lS;\n\ttry { lS = localStorage } catch (e){ };\n\tif(!lS){ return }\n\n\tvar sT = setTimeout, RAD = sT.RAD;\n\tRAD.put = function(file, data, cb, opt){\n\t\tsetTimeout(function(){\n\t\tlS[opt.file+'/'+file] = data;\n\t\tcb(null, 1);\n\t\t},1);\n\t}\n\tRAD.get = function(file, cb, opt){\n\t\tsetTimeout(function(){\n\t\tcb(null, lS[opt.file+'/'+file]);\n\t\t},1);\n\t}\n}());\n\n;(function(){ return;\n\tvar get;\n\ttry { get = fetch } catch (e){ console.log(\"WARNING! need `npm install node-fetch@2.6`\"); get = fetch = require('node-fetch') };\n\tif(!get){ return }\n\n\tvar sT = setTimeout, RAD = sT.RAD, put = RAD.put, get = RAD.get;\n\tRAD.put = function(file, data, cb, opt){ put && put(file, data, cb, opt);\n\t\tcb(401)\n\t}\n\tRAD.get = async function(file, cb, opt){ get && get(file, cb, opt);\n\t\tvar t = (await (await fetch('http://localhost:8765/gun/authorsData/'+file)).text());\n\t\tif('404' == t){ cb(); return }\n\t\tcb(null, t);\n\t}\n}());"
  },
  {
    "path": "sea/aeskey.js",
    "content": ";(function(){\n\n    var shim = require('./shim');\n    var S = require('./settings');\n    var sha256hash = require('./sha256');\n\n    const importGen = async (key, salt, opt) => {\n      //const combo = shim.Buffer.concat([shim.Buffer.from(key, 'utf8'), salt || shim.random(8)]).toString('utf8') // old\n      opt = opt || {};\n      const combo = key + (salt || shim.random(8)).toString('utf8'); // new\n      const hash = shim.Buffer.from(await sha256hash(combo), 'binary')\n      \n      const jwkKey = S.keyToJwk(hash)      \n      return await shim.subtle.importKey('jwk', jwkKey, {name:'AES-GCM'}, false, ['encrypt', 'decrypt'])\n    }\n    module.exports = importGen;\n  \n}());"
  },
  {
    "path": "sea/array.js",
    "content": ";(function(){\n\n    require('./base64');\n    // This is Array extended to have .toString(['utf8'|'hex'|'base64'])\n    function SeaArray() {}\n    Object.assign(SeaArray, { from: Array.from })\n    SeaArray.prototype = Object.create(Array.prototype)\n    SeaArray.prototype.toString = function(enc, start, end) { enc = enc || 'utf8'; start = start || 0;\n      const length = this.length\n      if (enc === 'hex') {\n        const buf = new Uint8Array(this)\n        return [ ...Array(((end && (end + 1)) || length) - start).keys()]\n        .map((i) => buf[ i + start ].toString(16).padStart(2, '0')).join('')\n      }\n      if (enc === 'utf8') {\n        return Array.from(\n          { length: (end || length) - start },\n          (_, i) => String.fromCharCode(this[ i + start])\n        ).join('')\n      }\n      if (enc === 'base64') {\n        return btoa(this)\n      }\n    }\n    module.exports = SeaArray;\n  \n}());"
  },
  {
    "path": "sea/auth.js",
    "content": ";(function(){\n\n    var User = require('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};\n    // now that we have created a user, we want to authenticate them!\n    User.prototype.auth = function(...args){ // TODO: this PR with arguments need to be cleaned up / refactored.\n      var pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;\n      var alias = !pair && typeof args[0] === 'string' ? args[0] : null;\n      var pass = (alias || (pair && !(pair.priv && pair.epriv))) && typeof args[1] === 'string' ? args[1] : null;\n      var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair\n      var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb\n      var retries = typeof opt.retries === 'number' ? opt.retries : 9;\n\n      var gun = this, cat = (gun._), root = gun.back(-1);\n      \n      if(cat.ing){\n        (cb || noop)({err: Gun.log(\"User is already being created or authenticated!\"), wait: true});\n        return gun;\n      }\n      cat.ing = true;\n      \n      var act = {}, u;\n      act.a = function(data){\n        if(!data){ return act.b() }\n        if(!data.pub){\n          var tmp = []; Object.keys(data).forEach(function(k){ if('_'==k){ return } tmp.push(data[k]) })\n          return act.b(tmp);\n        }\n        if(act.name){ return act.f(data) }\n        act.c((act.data = data).auth);\n      }\n      act.b = function(list){\n        var get = (act.list = (act.list||[]).concat(list||[])).shift();\n        if(u === get){\n          if(act.name){ return act.err('Your user account is not published for dApps to access, please consider syncing it online, or allowing local access by adding your device as a peer.') }\n          if(alias && retries--){\n            root.get('~@'+alias).once(act.a);\n            return;\n          }\n          return act.err('Wrong user or password.') \n        }\n        root.get(get).once(act.a);\n      }\n      act.c = function(auth){\n        if(u === auth){ return act.b() }\n        if('string' == typeof auth){ return act.c(obj_ify(auth)) } // in case of legacy\n        SEA.work(pass, (act.auth = auth).s, act.d, act.enc); // the proof of work is evidence that we've spent some time/effort trying to log in, this slows brute force.\n      }\n      act.d = function(proof){\n        SEA.decrypt(act.auth.ek, proof, act.e, act.enc);\n      }\n      act.e = function(half){\n        if(u === half){\n          if(!act.enc){ // try old format\n            act.enc = {encode: 'utf8'};\n            return act.c(act.auth);\n          } act.enc = null; // end backwards\n          return act.b();\n        }\n        act.half = half;\n        act.f(act.data);\n      }\n      act.f = function(pair){\n        var half = act.half || {}, data = act.data || {};\n        act.g(act.lol = {pub: pair.pub || data.pub, epub: pair.epub || data.epub, priv: pair.priv || half.priv, epriv: pair.epriv || half.epriv});\n      }\n      act.g = function(pair){\n        if(!pair || !pair.pub || !pair.epub){ return act.b() }\n        act.pair = pair;\n        var user = (root._).user, at = (user._);\n        var tmp = at.tag;\n        var upt = at.opt;\n        at = user._ = root.get('~'+pair.pub)._;\n        at.opt = upt;\n        // add our credentials in-memory only to our root user instance\n        user.is = {pub: pair.pub, epub: pair.epub, alias: alias || pair.pub};\n        at.sea = act.pair;\n        cat.ing = false;\n        try{if(pass && u == (obj_ify(cat.root.graph['~'+pair.pub].auth)||'')[':']){ opt.shuffle = opt.change = pass; } }catch(e){} // migrate UTF8 & Shuffle!\n        opt.change? act.z() : (cb || noop)(at);\n        if(SEA.window && ((gun.back('user')._).opt||opt).remember){\n          // TODO: this needs to be modular.\n          try{var sS = {};\n          sS = SEA.window.sessionStorage; // TODO: FIX BUG putting on `.is`!\n          sS.recall = true;\n          sS.pair = JSON.stringify(pair); // auth using pair is more reliable than alias/pass\n          }catch(e){}\n        }\n        try{\n          if(root._.tag.auth){ // auth handle might not be registered yet\n          (root._).on('auth', at) // TODO: Deprecate this, emit on user instead! Update docs when you do.\n          } else { setTimeout(function(){ (root._).on('auth', at) },1) } // if not, hackily add a timeout.\n          //at.on('auth', at) // Arrgh, this doesn't work without event \"merge\" code, but \"merge\" code causes stack overflow and crashes after logging in & trying to write data.\n        }catch(e){\n          Gun.log(\"Your 'auth' callback crashed with:\", e);\n        }\n      }\n      act.h = function(data){\n        if(!data){ return act.b() }\n        alias = data.alias\n        if(!alias)\n          alias = data.alias = \"~\" + pair.pub        \n        if(!data.auth){\n          return act.g(pair);\n        }\n        pair = null;\n        act.c((act.data = data).auth);\n      }\n      act.z = function(){\n        // password update so encrypt private key using new pwd + salt\n        act.salt = String.random(64); // pseudo-random\n        SEA.work(opt.change, act.salt, act.y);\n      }\n      act.y = function(proof){\n        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, proof, act.x, {raw:1});\n      }\n      act.x = function(auth){\n        act.w(JSON.stringify({ek: auth, s: act.salt}));\n      }\n      act.w = function(auth){\n        if(opt.shuffle){ // delete in future!\n          console.log('migrate core account from UTF8 & shuffle');\n          var tmp = {}; Object.keys(act.data).forEach(function(k){ tmp[k] = act.data[k] });\n          delete tmp._;\n          tmp.auth = auth;\n          root.get('~'+act.pair.pub).put(tmp);\n        } // end delete\n        root.get('~'+act.pair.pub).get('auth').put(auth, cb || noop);\n      }\n      act.err = function(e){\n        var ack = {err: Gun.log(e || 'User cannot be found!')};\n        cat.ing = false;\n        (cb || noop)(ack);\n      }\n      act.plugin = function(name){\n        if(!(act.name = name)){ return act.err() }\n        var tmp = [name];\n        if('~' !== name[0]){\n          tmp[1] = '~'+name;\n          tmp[2] = '~@'+name;\n        }\n        act.b(tmp);\n      }\n      if(pair){\n        if(pair.priv && pair.epriv)\n          act.g(pair);\n        else\n          root.get('~'+pair.pub).once(act.h);\n      } else\n      if(alias){\n        root.get('~@'+alias).once(act.a);\n      } else\n      if(!alias && !pass){\n        SEA.name(act.plugin);\n      }\n      return gun;\n    }\n    function obj_ify(o){\n      if('string' != typeof o){ return o }\n      try{o = JSON.parse(o);\n      }catch(e){o={}};\n      return o;\n    }\n  \n}());"
  },
  {
    "path": "sea/base64.js",
    "content": ";(function(){\n\n    var u;\n    if(u+''== typeof btoa){\n      if(u+'' == typeof Buffer){\n        try{ global.Buffer = require(\"buffer\", 1).Buffer }catch(e){ console.log(\"Please `npm install buffer` or add it to your package.json !\") }\n      }\n      global.btoa = function(data){ return Buffer.from(data, \"binary\").toString(\"base64\") };\n      global.atob = function(data){ return Buffer.from(data, \"base64\").toString(\"binary\") };\n    }\n  \n}());"
  },
  {
    "path": "sea/buffer.js",
    "content": ";(function(){\n\n    require('./base64');\n    // This is Buffer implementation used in SEA. Functionality is mostly\n    // compatible with NodeJS 'safe-buffer' and is used for encoding conversions\n    // between binary and 'hex' | 'utf8' | 'base64'\n    // See documentation and validation for safe implementation in:\n    // https://github.com/feross/safe-buffer#update\n    var SeaArray = require('./array');\n    function SafeBuffer(...props) {\n      console.warn('new SafeBuffer() is depreciated, please use SafeBuffer.from()')\n      return SafeBuffer.from(...props)\n    }\n    SafeBuffer.prototype = Object.create(Array.prototype)\n    Object.assign(SafeBuffer, {\n      // (data, enc) where typeof data === 'string' then enc === 'utf8'|'hex'|'base64'\n      from() {\n        if (!Object.keys(arguments).length || arguments[0]==null) {\n          throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n        }\n        const input = arguments[0]\n        let buf\n        if (typeof input === 'string') {\n          const enc = arguments[1] || 'utf8'\n          if (enc === 'hex') {\n            const bytes = input.match(/([\\da-fA-F]{2})/g)\n            .map((byte) => parseInt(byte, 16))\n            if (!bytes || !bytes.length) {\n              throw new TypeError('Invalid first argument for type \\'hex\\'.')\n            }\n            buf = SeaArray.from(bytes)\n          } else if (enc === 'utf8' || 'binary' === enc) { // EDIT BY MARK: I think this is safe, tested it against a couple \"binary\" strings. This lets SafeBuffer match NodeJS Buffer behavior more where it safely btoas regular strings.\n            const length = input.length\n            const words = new Uint16Array(length)\n            Array.from({ length: length }, (_, i) => words[i] = input.charCodeAt(i))\n            buf = SeaArray.from(words)\n          } else if (enc === 'base64') {\n            const dec = atob(input)\n            const length = dec.length\n            const bytes = new Uint8Array(length)\n            Array.from({ length: length }, (_, i) => bytes[i] = dec.charCodeAt(i))\n            buf = SeaArray.from(bytes)\n          } else if (enc === 'binary') { // deprecated by above comment\n            buf = SeaArray.from(input) // some btoas were mishandled.\n          } else {\n            console.info('SafeBuffer.from unknown encoding: '+enc)\n          }\n          return buf\n        }\n        const byteLength = input.byteLength // what is going on here? FOR MARTTI\n        const length = input.byteLength ? input.byteLength : input.length\n        if (length) {\n          let buf\n          if (input instanceof ArrayBuffer) {\n            buf = new Uint8Array(input)\n          }\n          return SeaArray.from(buf || input)\n        }\n      },\n      // This is 'safe-buffer.alloc' sans encoding support\n      alloc(length, fill = 0 /*, enc*/ ) {\n        return SeaArray.from(new Uint8Array(Array.from({ length: length }, () => fill)))\n      },\n      // This is normal UNSAFE 'buffer.alloc' or 'new Buffer(length)' - don't use!\n      allocUnsafe(length) {\n        return SeaArray.from(new Uint8Array(Array.from({ length : length })))\n      },\n      // This puts together array of array like members\n      concat(arr) { // octet array\n        if (!Array.isArray(arr)) {\n          throw new TypeError('First argument must be Array containing ArrayBuffer or Uint8Array instances.')\n        }\n        return SeaArray.from(arr.reduce((ret, item) => ret.concat(Array.from(item)), []))\n      }\n    })\n    SafeBuffer.prototype.from = SafeBuffer.from\n    SafeBuffer.prototype.toString = SeaArray.prototype.toString\n\n    module.exports = SafeBuffer;\n  \n}());"
  },
  {
    "path": "sea/certify.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    // This is to certify that a group of \"certificants\" can \"put\" anything at a group of matched \"paths\" to the certificate authority's graph\n    SEA.certify = SEA.certify || (async (certificants, policy = {}, authority, cb, opt = {}) => { try {\n      /*\n      The Certify Protocol was made out of love by a Vietnamese code enthusiast. Vietnamese people around the world deserve respect!\n      IMPORTANT: A Certificate is like a Signature. No one knows who (authority) created/signed a cert until you put it into their graph.\n      \"certificants\": '*' or a String (Bob.pub) || an Object that contains \"pub\" as a key || an array of [object || string]. These people will have the rights.\n      \"policy\": A string ('inbox'), or a RAD/LEX object {'*': 'inbox'}, or an Array of RAD/LEX objects or strings. RAD/LEX object can contain key \"?\" with indexOf(\"*\") > -1 to force key equals certificant pub. This rule is used to check against soul+'/'+key using Gun.text.match or String.match.\n      \"authority\": Key pair or priv of the certificate authority.\n      \"cb\": A callback function after all things are done.\n      \"opt\": If opt.expiry (a timestamp) is set, SEA won't sync data after opt.expiry. If opt.block is set, SEA will look for block before syncing.\n      */\n      console.log('SEA.certify() is an early experimental community supported method that may change API behavior without warning in any future version.')\n\n      certificants = (() => {\n        var data = []\n        if (certificants) {\n          if ((typeof certificants === 'string' || Array.isArray(certificants)) && certificants.indexOf('*') > -1) return '*'\n          if (typeof certificants === 'string') return certificants\n          if (Array.isArray(certificants)) {\n            if (certificants.length === 1 && certificants[0]) return typeof certificants[0] === 'object' && certificants[0].pub ? certificants[0].pub : typeof certificants[0] === 'string' ? certificants[0] : null\n            certificants.map(certificant => {\n              if (typeof certificant ==='string') data.push(certificant)\n              else if (typeof certificant === 'object' && certificant.pub) data.push(certificant.pub)\n            })\n          }\n\n          if (typeof certificants === 'object' && certificants.pub) return certificants.pub\n          return data.length > 0 ? data : null\n        }\n        return\n      })()\n\n      if (!certificants) return console.log(\"No certificant found.\")\n\n      const expiry = opt.expiry && (typeof opt.expiry === 'number' || typeof opt.expiry === 'string') ? parseFloat(opt.expiry) : null\n      const readPolicy = (policy || {}).read ? policy.read : null\n      const writePolicy = (policy || {}).write ? policy.write : typeof policy === 'string' || Array.isArray(policy) || policy[\"+\"] || policy[\"#\"] || policy[\".\"] || policy[\"=\"] || policy[\"*\"] || policy[\">\"] || policy[\"<\"] ? policy : null\n      // The \"blacklist\" feature is now renamed to \"block\". Why ? BECAUSE BLACK LIVES MATTER!\n      // We can now use 3 keys: block, blacklist, ban\n      const block = (opt || {}).block || (opt || {}).blacklist || (opt || {}).ban || {}\n      const readBlock = block.read && (typeof block.read === 'string' || (block.read || {})['#']) ? block.read : null\n      const writeBlock = typeof block === 'string' ? block : block.write && (typeof block.write === 'string' || block.write['#']) ? block.write : null\n\n      if (!readPolicy && !writePolicy) return console.log(\"No policy found.\")\n\n      // reserved keys: c, e, r, w, rb, wb\n      const data = JSON.stringify({\n        c: certificants,\n        ...(expiry ? {e: expiry} : {}), // inject expiry if possible\n        ...(readPolicy ? {r: readPolicy }  : {}), // \"r\" stands for read, which means read permission.\n        ...(writePolicy ? {w: writePolicy} : {}), // \"w\" stands for write, which means write permission.\n        ...(readBlock ? {rb: readBlock} : {}), // inject READ block if possible\n        ...(writeBlock ? {wb: writeBlock} : {}), // inject WRITE block if possible\n      })\n\n      const certificate = await SEA.sign(data, authority, null, {raw:1})\n\n      var r = certificate\n      if(!opt.raw){ r = 'SEA'+JSON.stringify(r) }\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.certify;\n  \n}());"
  },
  {
    "path": "sea/create.js",
    "content": ";(function(){\n\n    var User = require('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};\n\n    // Well first we have to actually create a user. That is what this function does.\n    User.prototype.create = function(...args){\n      var pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;\n      var alias = pair && (pair.pub || pair.epub) ? pair.pub : typeof args[0] === 'string' ? args[0] : null;\n      var pass = pair && (pair.pub || pair.epub) ? pair : alias && typeof args[1] === 'string' ? args[1] : null;\n      var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair\n      var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb\n      \n      var gun = this, cat = (gun._), root = gun.back(-1);\n      cb = cb || noop;\n      opt = opt || {};\n      if(false !== opt.check){\n        var err;\n        if(!alias){ err = \"No user.\" }\n        if((pass||'').length < 8){ err = \"Password too short!\" }\n        if(err){\n          cb({err: Gun.log(err)});\n          return gun;\n        }\n      }\n      if(cat.ing){\n        (cb || noop)({err: Gun.log(\"User is already being created or authenticated!\"), wait: true});\n        return gun;\n      }\n      cat.ing = true;\n      var act = {}, u;\n      act.a = function(pubs){\n        act.pubs = pubs;\n        if(pubs && !opt.already){\n          // If we can enforce that a user name is already taken, it might be nice to try, but this is not guaranteed.\n          var ack = {err: Gun.log('User already created!')};\n          cat.ing = false;\n          (cb || noop)(ack);\n          gun.leave();\n          return;\n        }\n        act.salt = String.random(64); // pseudo-randomly create a salt, then use PBKDF2 function to extend the password with it.\n        SEA.work(pass, act.salt, act.b); // this will take some short amount of time to produce a proof, which slows brute force attacks.\n      }\n      act.b = function(proof){\n        act.proof = proof;\n        pair ? act.c(pair) : SEA.pair(act.c) // generate a brand new key pair or use the existing.\n      }\n      act.c = function(pair){\n        var tmp\n        act.pair = pair || {};\n        if(tmp = cat.root.user){\n          tmp._.sea = pair;\n          tmp.is = {pub: pair.pub, epub: pair.epub, alias: alias};\n        }\n        // the user's public key doesn't need to be signed. But everything else needs to be signed with it! // we have now automated it! clean up these extra steps now!\n        act.data = {pub: pair.pub};\n        act.d();\n      }\n      act.d = function(){\n        act.data.alias = alias;\n        act.e();\n      }\n      act.e = function(){\n        act.data.epub = act.pair.epub; \n        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, act.proof, act.f, {raw:1}); // to keep the private key safe, we AES encrypt it with the proof of work!\n      }\n      act.f = function(auth){\n        act.data.auth = JSON.stringify({ek: auth, s: act.salt}); \n        act.g(act.data.auth);\n      }\n      act.g = function(auth){ var tmp;\n        act.data.auth = act.data.auth || auth;\n        root.get(tmp = '~'+act.pair.pub).put(act.data).on(act.h); // awesome, now we can actually save the user with their public key as their ID.\n        var link = {}; link[tmp] = {'#': tmp}; root.get('~@'+alias).put(link).get(tmp).on(act.i); // next up, we want to associate the alias with the public key. So we add it to the alias list.\n      }\n      act.h = function(data, key, msg, eve){\n        eve.off(); act.h.ok = 1; act.i();\n      }\n      act.i = function(data, key, msg, eve){\n        if(eve){ act.i.ok = 1; eve.off() }\n        if(!act.h.ok || !act.i.ok){ return }\n        cat.ing = false;\n        cb({ok: 0, pub: act.pair.pub}); // callback that the user has been created. (Note: ok = 0 because we didn't wait for disk to ack)\n        if(noop === cb){ pair ? gun.auth(pair) : gun.auth(alias, pass) } // if no callback is passed, auto-login after signing up.\n      }\n      root.get('~@'+alias).once(act.a);\n      return gun;\n    }\n    User.prototype.leave = function(opt, cb){\n      var gun = this, user = (gun.back(-1)._).user;\n      if(user){\n        delete user.is;\n        delete user._.is;\n        delete user._.sea;\n      }\n      if(SEA.window){\n        try{var sS = {};\n        sS = SEA.window.sessionStorage;\n        delete sS.recall;\n        delete sS.pair;\n        }catch(e){};\n      }\n      return gun;\n    }\n  \n}());"
  },
  {
    "path": "sea/decrypt.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var S = require('./settings');\n    var aeskey = require('./aeskey');\n\n    SEA.decrypt = SEA.decrypt || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      var key = (pair||opt).epriv || pair;\n      if(!key){\n        if(!SEA.I){ throw 'No decryption key.' }\n        pair = await SEA.I(null, {what: data, how: 'decrypt', why: opt.why});\n        key = pair.epriv || pair;\n      }\n      var json = await S.parse(data);\n      var buf, bufiv, bufct; try{\n        buf = shim.Buffer.from(json.s, opt.encode || 'base64');\n        bufiv = shim.Buffer.from(json.iv, opt.encode || 'base64');\n        bufct = shim.Buffer.from(json.ct, opt.encode || 'base64');\n        var ct = await aeskey(key, buf, opt).then((aes) => (/*shim.ossl ||*/ shim.subtle).decrypt({  // Keeping aesKey scope as private as possible...\n          name: opt.name || 'AES-GCM', iv: new Uint8Array(bufiv), tagLength: 128\n        }, aes, new Uint8Array(bufct)));\n      }catch(e){\n        if('utf8' === opt.encode){ throw \"Could not decrypt\" }\n        if(SEA.opt.fallback){\n          opt.encode = 'utf8';\n          return await SEA.decrypt(data, pair, cb, opt);\n        }\n      }\n      var r = await S.parse(new shim.TextDecoder('utf8').decode(ct));\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.decrypt;\n  \n}());"
  },
  {
    "path": "sea/encrypt.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var S = require('./settings');\n    var aeskey = require('./aeskey');\n    var u;\n\n    SEA.encrypt = SEA.encrypt || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      var key = (pair||opt).epriv || pair;\n      if(u === data){ throw '`undefined` not allowed.' }\n      if(!key){\n        if(!SEA.I){ throw 'No encryption key.' }\n        pair = await SEA.I(null, {what: data, how: 'encrypt', why: opt.why});\n        key = pair.epriv || pair;\n      }\n      var msg = (typeof data == 'string')? data : await shim.stringify(data);\n      var rand = {s: shim.random(9), iv: shim.random(15)}; // consider making this 9 and 15 or 18 or 12 to reduce == padding.\n      var ct = await aeskey(key, rand.s, opt).then((aes) => (/*shim.ossl ||*/ shim.subtle).encrypt({ // Keeping the AES key scope as private as possible...\n        name: opt.name || 'AES-GCM', iv: new Uint8Array(rand.iv)\n      }, aes, new shim.TextEncoder().encode(msg)));\n      var r = {\n        ct: shim.Buffer.from(ct, 'binary').toString(opt.encode || 'base64'),\n        iv: rand.iv.toString(opt.encode || 'base64'),\n        s: rand.s.toString(opt.encode || 'base64')\n      }\n      if(!opt.raw){ r = 'SEA' + await shim.stringify(r) }\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.encrypt;\n  \n}());"
  },
  {
    "path": "sea/https.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    try{ if(SEA.window){\n      if(location.protocol.indexOf('s') < 0\n      && location.host.indexOf('localhost') < 0\n      && ! /^127\\.\\d+\\.\\d+\\.\\d+$/.test(location.hostname)\n      && location.protocol.indexOf('blob:') < 0\n      && location.protocol.indexOf('file:') < 0\n      && location.origin != 'null'){\n        console.warn('HTTPS needed for WebCrypto in SEA, redirecting...');\n        location.protocol = 'https:'; // WebCrypto does NOT work without HTTPS!\n      }\n    } }catch(e){}\n  \n}());"
  },
  {
    "path": "sea/index.js",
    "content": ";(function(){\n\n    var SEA = require('./sea'), S = require('./settings'), noop = function() {}, u;\n    var Gun = (SEA.window||'').GUN || require((''+u === typeof MODULE?'.':'')+'./gun', 1);\n    // After we have a GUN extension to make user registration/login easy, we then need to handle everything else.\n\n    // We do this with a GUN adapter, we first listen to when a gun instance is created (and when its options change)\n    Gun.on('opt', function(at){\n      if(!at.sea){ // only add SEA once per instance, on the \"at\" context.\n        at.sea = {own: {}};\n        at.on('put', check, at); // SEA now runs its firewall on HAM diffs, not all i/o.\n      }\n      this.to.next(at); // make sure to call the \"next\" middleware adapter.\n    });\n\n    // Alright, this next adapter gets run at the per node level in the graph database.\n    // correction: 2020 it gets run on each key/value pair in a node upon a HAM diff.\n    // This will let us verify that every property on a node has a value signed by a public key we trust.\n    // If the signature does not match, the data is just `undefined` so it doesn't get passed on.\n    // If it does match, then we transform the in-memory \"view\" of the data into its plain value (without the signature).\n    // Now NOTE! Some data is \"system\" data, not user data. Example: List of public keys, aliases, etc.\n    // This data is self-enforced (the value can only match its ID), but that is handled in the `security` function.\n    // From the self-enforced data, we can see all the edges in the graph that belong to a public key.\n    // Example: ~ASDF is the ID of a node with ASDF as its public key, signed alias and salt, and\n    // its encrypted private key, but it might also have other signed values on it like `profile = <ID>` edge.\n    // Using that directed edge's ID, we can then track (in memory) which IDs belong to which keys.\n    // Here is a problem: Multiple public keys can \"claim\" any node's ID, so this is dangerous!\n    // This means we should ONLY trust our \"friends\" (our key ring) public keys, not any ones.\n    // I have not yet added that to SEA yet in this alpha release. That is coming soon, but beware in the meanwhile!\n\n    function check(msg){ // REVISE / IMPROVE, NO NEED TO PASS MSG/EVE EACH SUB?\n      var eve = this, at = eve.as, put = msg.put, soul = put['#'], key = put['.'], val = put[':'], state = put['>'], id = msg['#'], tmp;\n      if(!soul || !key){ return }\n      if((msg._||'').faith && (at.opt||'').faith && 'function' == typeof msg._){\n        SEA.opt.pack(put, function(raw){\n        SEA.verify(raw, false, function(data){ // this is synchronous if false\n          put['='] = SEA.opt.unpack(data);\n          eve.to.next(msg);\n        })})\n        return \n      }\n      var no = function(why){ at.on('in', {'@': id, err: msg.err = why}) }; // exploit internal relay stun for now, maybe violates spec, but testing for now. // Note: this may be only the sharded message, not original batch.\n      //var no = function(why){ msg.ack(why) };\n      (msg._||'').DBG && ((msg._||'').DBG.c = +new Date);\n      if(0 <= soul.indexOf('<?')){ // special case for \"do not sync data X old\" forget\n        // 'a~pub.key/b<?9'\n        tmp = parseFloat(soul.split('<?')[1]||'');\n        if(tmp && (state < (Gun.state() - (tmp * 1000)))){ // sec to ms\n          (tmp = msg._) && (tmp.stun) && (tmp.stun--); // THIS IS BAD CODE! It assumes GUN internals do something that will probably change in future, but hacking in now.\n          return; // omit!\n        }\n      }\n      \n      if('~@' === soul){  // special case for shared system data, the list of aliases.\n        check.alias(eve, msg, val, key, soul, at, no); return;\n      }\n      if('~@' === soul.slice(0,2)){ // special case for shared system data, the list of public keys for an alias.\n        check.pubs(eve, msg, val, key, soul, at, no); return;\n      }\n      //if('~' === soul.slice(0,1) && 2 === (tmp = soul.slice(1)).split('.').length){ // special case, account data for a public key.\n      if(tmp = SEA.opt.pub(soul)){ // special case, account data for a public key.\n        check.pub(eve, msg, val, key, soul, at, no, at.user||'', tmp); return;\n      }\n      if(0 <= soul.indexOf('#')){ // special case for content addressing immutable hashed data.\n        check.hash(eve, msg, val, key, soul, at, no); return;\n      } \n      check.any(eve, msg, val, key, soul, at, no, at.user||''); return;\n      eve.to.next(msg); // not handled\n    }\n    check.hash = function(eve, msg, val, key, soul, at, no){ // mark unbuilt @i001962 's epic hex contrib!\n      SEA.work(val, null, function(data){\n        function hexToBase64(hexStr) {\n          let base64 = \"\";\n          for(let i = 0; i < hexStr.length; i++) {\n            base64 += !(i - 1 & 1) ? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16)) : \"\"}\n          return btoa(base64);}  \n        if(data && data === key.split('#').slice(-1)[0]){ return eve.to.next(msg) }\n          else if (data && data === hexToBase64(key.split('#').slice(-1)[0])){ \n          return eve.to.next(msg) }\n        no(\"Data hash not same as hash!\");\n      }, {name: 'SHA-256'});\n    }\n    check.alias = function(eve, msg, val, key, soul, at, no){ // Example: {_:#~@, ~@alice: {#~@alice}}\n      if(!val){ return no(\"Data must exist!\") } // data MUST exist\n      if('~@'+key === link_is(val)){ return eve.to.next(msg) } // in fact, it must be EXACTLY equal to itself\n      no(\"Alias not same!\"); // if it isn't, reject.\n    };\n    check.pubs = function(eve, msg, val, key, soul, at, no){ // Example: {_:#~@alice, ~asdf: {#~asdf}}\n      if(!val){ return no(\"Alias must exist!\") } // data MUST exist\n      if(key === link_is(val)){ return eve.to.next(msg) } // and the ID must be EXACTLY equal to its property\n      no(\"Alias not same!\"); // that way nobody can tamper with the list of public keys.\n    };\n    check.pub = async function(eve, msg, val, key, soul, at, no, user, pub){ var tmp // Example: {_:#~asdf, hello:'world'~fdsa}}\n      const raw = await S.parse(val) || {}\n      const verify = (certificate, certificant, cb) => {\n        if (certificate.m && certificate.s && certificant && pub)\n          // now verify certificate\n          return SEA.verify(certificate, pub, data => { // check if \"pub\" (of the graph owner) really issued this cert\n            if (u !== data && u !== data.e && msg.put['>'] && msg.put['>'] > parseFloat(data.e)) return no(\"Certificate expired.\") // certificate expired\n            // \"data.c\" = a list of certificants/certified users\n            // \"data.w\" = lex WRITE permission, in the future, there will be \"data.r\" which means lex READ permission\n            if (u !== data && data.c && data.w && (data.c === certificant || data.c.indexOf('*' || certificant) > -1)) {\n              // ok, now \"certificant\" is in the \"certificants\" list, but is \"path\" allowed? Check path\n              let path = soul.indexOf('/') > -1 ? soul.replace(soul.substring(0, soul.indexOf('/') + 1), '') : ''\n              String.match = String.match || Gun.text.match\n              const w = Array.isArray(data.w) ? data.w : typeof data.w === 'object' || typeof data.w === 'string' ? [data.w] : []\n              for (const lex of w) {\n                if ((String.match(path, lex['#']) && String.match(key, lex['.'])) || (!lex['.'] && String.match(path, lex['#'])) || (!lex['#'] && String.match(key, lex['.'])) || String.match((path ? path + '/' + key : key), lex['#'] || lex)) {\n                  // is Certificant forced to present in Path\n                  if (lex['+'] && lex['+'].indexOf('*') > -1 && path && path.indexOf(certificant) == -1 && key.indexOf(certificant) == -1) return no(`Path \"${path}\" or key \"${key}\" must contain string \"${certificant}\".`)\n                  // path is allowed, but is there any WRITE block? Check it out\n                  if (data.wb && (typeof data.wb === 'string' || ((data.wb || {})['#']))) { // \"data.wb\" = path to the WRITE block\n                    var root = eve.as.root.$.back(-1)\n                    if (typeof data.wb === 'string' && '~' !== data.wb.slice(0, 1)) root = root.get('~' + pub)\n                    return root.get(data.wb).get(certificant).once(value => { // TODO: INTENT TO DEPRECATE.\n                      if (value && (value === 1 || value === true)) return no(`Certificant ${certificant} blocked.`)\n                      return cb(data)\n                    })\n                  }\n                  return cb(data)\n                }\n              }\n              return no(\"Certificate verification fail.\")\n            }\n          })\n        return\n      }\n      \n      if ('pub' === key && '~' + pub === soul) {\n        if (val === pub) return eve.to.next(msg) // the account MUST match `pub` property that equals the ID of the public key.\n        return no(\"Account not same!\")\n      }\n\n      if ((tmp = user.is) && tmp.pub && !raw['*'] && !raw['+'] && (pub === tmp.pub || (pub !== tmp.pub && ((msg._.msg || {}).opt || {}).cert))){\n        SEA.opt.pack(msg.put, packed => {\n          SEA.sign(packed, (user._).sea, async function(data) {\n            if (u === data) return no(SEA.err || 'Signature fail.')\n            msg.put[':'] = {':': tmp = SEA.opt.unpack(data.m), '~': data.s}\n            msg.put['='] = tmp\n  \n            // if writing to own graph, just allow it\n            if (pub === user.is.pub) {\n              if (tmp = link_is(val)) (at.sea.own[tmp] = at.sea.own[tmp] || {})[pub] = 1\n              JSON.stringifyAsync(msg.put[':'], function(err,s){\n                if(err){ return no(err || \"Stringify error.\") }\n                msg.put[':'] = s;\n                return eve.to.next(msg);\n              })\n              return\n            }\n  \n            // if writing to other's graph, check if cert exists then try to inject cert into put, also inject self pub so that everyone can verify the put\n            if (pub !== user.is.pub && ((msg._.msg || {}).opt || {}).cert) {\n              const cert = await S.parse(msg._.msg.opt.cert)\n              // even if cert exists, we must verify it\n              if (cert && cert.m && cert.s)\n                verify(cert, user.is.pub, _ => {\n                  msg.put[':']['+'] = cert // '+' is a certificate\n                  msg.put[':']['*'] = user.is.pub // '*' is pub of the user who puts\n                  JSON.stringifyAsync(msg.put[':'], function(err,s){\n                    if(err){ return no(err || \"Stringify error.\") }\n                    msg.put[':'] = s;\n                    return eve.to.next(msg);\n                  })\n                  return\n                })\n            }\n          }, {raw: 1})\n        })\n        return;\n      }\n\n      SEA.opt.pack(msg.put, packed => {\n        SEA.verify(packed, raw['*'] || pub, function(data){ var tmp;\n          data = SEA.opt.unpack(data);\n          if (u === data) return no(\"Unverified data.\") // make sure the signature matches the account it claims to be on. // reject any updates that are signed with a mismatched account.\n          if ((tmp = link_is(data)) && pub === SEA.opt.pub(tmp)) (at.sea.own[tmp] = at.sea.own[tmp] || {})[pub] = 1\n          \n          // check if cert ('+') and putter's pub ('*') exist\n          if (raw['+'] && raw['+']['m'] && raw['+']['s'] && raw['*'])\n            // now verify certificate\n            verify(raw['+'], raw['*'], _ => {\n              msg.put['='] = data;\n              return eve.to.next(msg);\n            })\n          else {\n            msg.put['='] = data;\n            return eve.to.next(msg);\n          }\n        });\n      })\n      return\n    };\n    check.any = function(eve, msg, val, key, soul, at, no, user){ var tmp, pub;\n      if(at.opt.secure){ return no(\"Soul missing public key at '\" + key + \"'.\") }\n      // TODO: Ask community if should auto-sign non user-graph data.\n      at.on('secure', function(msg){ this.off();\n        if(!at.opt.secure){ return eve.to.next(msg) }\n        no(\"Data cannot be changed.\");\n      }).on.on('secure', msg);\n      return;\n    }\n\n    var valid = Gun.valid, link_is = function(d,l){ return 'string' == typeof (l = valid(d)) && l }, state_ify = (Gun.state||'').ify;\n\n    var pubcut = /[^\\w_-]/; // anything not alphanumeric or _ -\n    SEA.opt.pub = function(s){\n      if(!s){ return }\n      s = s.split('~');\n      if(!s || !(s = s[1])){ return }\n      s = s.split(pubcut).slice(0,2);\n      if(!s || 2 != s.length){ return }\n      if('@' === (s[0]||'')[0]){ return }\n      s = s.slice(0,2).join('.');\n      return s;\n    }\n    SEA.opt.stringy = function(t){\n      // TODO: encrypt etc. need to check string primitive. Make as breaking change.\n    }\n    SEA.opt.pack = function(d,cb,k, n,s){ var tmp, f; // pack for verifying\n      if(SEA.opt.check(d)){ return cb(d) }\n      if(d && d['#'] && d['.'] && d['>']){ tmp = d[':']; f = 1 }\n      JSON.parseAsync(f? tmp : d, function(err, meta){\n        var sig = ((u !== (meta||'')[':']) && (meta||'')['~']); // or just ~ check?\n        if(!sig){ cb(d); return }\n        cb({m: {'#':s||d['#'],'.':k||d['.'],':':(meta||'')[':'],'>':d['>']||Gun.state.is(n, k)}, s: sig});\n      });\n    }\n    var O = SEA.opt;\n    SEA.opt.unpack = function(d, k, n){ var tmp;\n      if(u === d){ return }\n      if(d && (u !== (tmp = d[':']))){ return tmp }\n      k = k || O.fall_key; if(!n && O.fall_val){ n = {}; n[k] = O.fall_val }\n      if(!k || !n){ return }\n      if(d === n[k]){ return d }\n      if(!SEA.opt.check(n[k])){ return d }\n      var soul = (n && n._ && n._['#']) || O.fall_soul, s = Gun.state.is(n, k) || O.fall_state;\n      if(d && 4 === d.length && soul === d[0] && k === d[1] && fl(s) === fl(d[3])){\n        return d[2];\n      }\n      if(s < SEA.opt.shuffle_attack){\n        return d;\n      }\n    }\n    SEA.opt.shuffle_attack = 1546329600000; // Jan 1, 2019\n    var fl = Math.floor; // TODO: Still need to fix inconsistent state issue.\n    // TODO: Potential bug? If pub/priv key starts with `-`? IDK how possible.\n\n  \n}());"
  },
  {
    "path": "sea/pair.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var S = require('./settings');\n\n    SEA.name = SEA.name || (async (cb, opt) => { try {\n      if(cb){ try{ cb() }catch(e){console.log(e)} }\n      return;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    //SEA.pair = async (data, proof, cb) => { try {\n    SEA.pair = SEA.pair || (async (cb, opt) => { try {\n\n      var ecdhSubtle = shim.ossl || shim.subtle;\n      // First: ECDSA keys for signing/verifying...\n      var sa = await shim.subtle.generateKey({name: 'ECDSA', namedCurve: 'P-256'}, true, [ 'sign', 'verify' ])\n      .then(async (keys) => {\n        // privateKey scope doesn't leak out from here!\n        //const { d: priv } = await shim.subtle.exportKey('jwk', keys.privateKey)\n        var key = {};\n        key.priv = (await shim.subtle.exportKey('jwk', keys.privateKey)).d;\n        var pub = await shim.subtle.exportKey('jwk', keys.publicKey);\n        //const pub = Buff.from([ x, y ].join(':')).toString('base64') // old\n        key.pub = pub.x+'.'+pub.y; // new\n        // x and y are already base64\n        // pub is UTF8 but filename/URL safe (https://www.ietf.org/rfc/rfc3986.txt)\n        // but split on a non-base64 letter.\n        return key;\n      })\n      \n      // To include PGPv4 kind of keyId:\n      // const pubId = await SEA.keyid(keys.pub)\n      // Next: ECDH keys for encryption/decryption...\n\n      try{\n      var dh = await ecdhSubtle.generateKey({name: 'ECDH', namedCurve: 'P-256'}, true, ['deriveKey'])\n      .then(async (keys) => {\n        // privateKey scope doesn't leak out from here!\n        var key = {};\n        key.epriv = (await ecdhSubtle.exportKey('jwk', keys.privateKey)).d;\n        var pub = await ecdhSubtle.exportKey('jwk', keys.publicKey);\n        //const epub = Buff.from([ ex, ey ].join(':')).toString('base64') // old\n        key.epub = pub.x+'.'+pub.y; // new\n        // ex and ey are already base64\n        // epub is UTF8 but filename/URL safe (https://www.ietf.org/rfc/rfc3986.txt)\n        // but split on a non-base64 letter.\n        return key;\n      })\n      }catch(e){\n        if(SEA.window){ throw e }\n        if(e == 'Error: ECDH is not a supported algorithm'){ console.log('Ignoring ECDH...') }\n        else { throw e }\n      } dh = dh || {};\n\n      var r = { pub: sa.pub, priv: sa.priv, /* pubId, */ epub: dh.epub, epriv: dh.epriv }\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.pair;\n  \n}());"
  },
  {
    "path": "sea/recall.js",
    "content": ";(function(){\n\n    var User = require('./user'), SEA = User.SEA, Gun = User.GUN;\n    User.prototype.recall = function(opt, cb){\n      var gun = this, root = gun.back(-1), tmp;\n      opt = opt || {};\n      if(opt && opt.sessionStorage){\n        if(SEA.window){\n          try{\n            var sS = {};\n            sS = SEA.window.sessionStorage; // TODO: FIX BUG putting on `.is`!\n            if(sS){\n              (root._).opt.remember = true;\n              ((gun.back('user')._).opt||opt).remember = true;\n              if(sS.recall || sS.pair) root.user().auth(JSON.parse(sS.pair), cb); // pair is more reliable than alias/pass\n            }\n          }catch(e){}\n        }\n        return gun;\n      }\n      /*\n        TODO: copy mhelander's expiry code back in.\n        Although, we should check with community,\n        should expiry be core or a plugin?\n      */\n      return gun;\n    }\n  \n}());"
  },
  {
    "path": "sea/root.js",
    "content": ";(function(){\n\n    // Security, Encryption, and Authorization: SEA.js\n    // MANDATORY READING: https://gun.eco/explainers/data/security.html\n    // IT IS IMPLEMENTED IN A POLYFILL/SHIM APPROACH.\n    // THIS IS AN EARLY ALPHA!\n\n    if(typeof self !== \"undefined\"){ module.window = self } // should be safe for at least browser/worker/nodejs, need to check other envs like RN etc.\n    if(typeof window !== \"undefined\"){ module.window = window }\n\n    var tmp = module.window || module, u;\n    var SEA = tmp.SEA || {};\n\n    if(SEA.window = module.window){ SEA.window.SEA = SEA }\n\n    try{ if(u+'' !== typeof MODULE){ MODULE.exports = SEA } }catch(e){}\n    module.exports = SEA;\n  \n}());"
  },
  {
    "path": "sea/sea.js",
    "content": ";(function(){\n\n    var shim = require('./shim');\n    // Practical examples about usage found in tests.\n    var SEA = require('./root');\n    SEA.work = require('./work');\n    SEA.sign = require('./sign');\n    SEA.verify = require('./verify');\n    SEA.encrypt = require('./encrypt');\n    SEA.decrypt = require('./decrypt');\n    SEA.certify = require('./certify');\n    //SEA.opt.aeskey = require('./aeskey'); // not official! // this causes problems in latest WebCrypto.\n\n    SEA.random = SEA.random || shim.random;\n\n    // This is Buffer used in SEA and usable from Gun/SEA application also.\n    // For documentation see https://nodejs.org/api/buffer.html\n    SEA.Buffer = SEA.Buffer || require('./buffer');\n\n    // These SEA functions support now ony Promises or\n    // async/await (compatible) code, use those like Promises.\n    //\n    // Creates a wrapper library around Web Crypto API\n    // for various AES, ECDSA, PBKDF2 functions we called above.\n    // Calculate public key KeyID aka PGPv4 (result: 8 bytes as hex string)\n    SEA.keyid = SEA.keyid || (async (pub) => {\n      try {\n        // base64('base64(x):base64(y)') => shim.Buffer(xy)\n        const pb = shim.Buffer.concat(\n          pub.replace(/-/g, '+').replace(/_/g, '/').split('.')\n          .map((t) => shim.Buffer.from(t, 'base64'))\n        )\n        // id is PGPv4 compliant raw key\n        const id = shim.Buffer.concat([\n          shim.Buffer.from([0x99, pb.length / 0x100, pb.length % 0x100]), pb\n        ])\n        const sha1 = await sha1hash(id)\n        const hash = shim.Buffer.from(sha1, 'binary')\n        return hash.toString('hex', hash.length - 8)  // 16-bit ID as hex\n      } catch (e) {\n        console.log(e)\n        throw e\n      }\n    });\n    // all done!\n    // Obviously it is missing MANY necessary features. This is only an alpha release.\n    // Please experiment with it, audit what I've done so far, and complain about what needs to be added.\n    // SEA should be a full suite that is easy and seamless to use.\n    // Again, scroll naer the top, where I provide an EXAMPLE of how to create a user and sign in.\n    // Once logged in, the rest of the code you just read handled automatically signing/validating data.\n    // But all other behavior needs to be equally easy, like opinionated ways of\n    // Adding friends (trusted public keys), sending private messages, etc.\n    // Cheers! Tell me what you think.\n    ((SEA.window||{}).GUN||{}).SEA = SEA;\n\n    module.exports = SEA\n    // -------------- END SEA MODULES --------------------\n    // -- BEGIN SEA+GUN MODULES: BUNDLED BY DEFAULT UNTIL OTHERS USE SEA ON OWN -------\n  \n}());"
  },
  {
    "path": "sea/secret.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var S = require('./settings');\n    // Derive shared secret from other's pub and my epub/epriv \n    SEA.secret = SEA.secret || (async (key, pair, cb, opt) => { try {\n      opt = opt || {};\n      if(!pair || !pair.epriv || !pair.epub){\n        if(!SEA.I){ throw 'No secret mix.' }\n        pair = await SEA.I(null, {what: key, how: 'secret', why: opt.why});\n      }\n      var pub = key.epub || key;\n      var epub = pair.epub;\n      var epriv = pair.epriv;\n      var ecdhSubtle = shim.ossl || shim.subtle;\n      var pubKeyData = keysToEcdhJwk(pub);\n      var props = Object.assign({ public: await ecdhSubtle.importKey(...pubKeyData, true, []) },{name: 'ECDH', namedCurve: 'P-256'}); // Thanks to @sirpy !\n      var privKeyData = keysToEcdhJwk(epub, epriv);\n      var derived = await ecdhSubtle.importKey(...privKeyData, false, ['deriveBits']).then(async (privKey) => {\n        // privateKey scope doesn't leak out from here!\n        var derivedBits = await ecdhSubtle.deriveBits(props, privKey, 256);\n        var rawBits = new Uint8Array(derivedBits);\n        var derivedKey = await ecdhSubtle.importKey('raw', rawBits,{ name: 'AES-GCM', length: 256 }, true, [ 'encrypt', 'decrypt' ]);\n        return ecdhSubtle.exportKey('jwk', derivedKey).then(({ k }) => k);\n      })\n      var r = derived;\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    // can this be replaced with settings.jwk?\n    var keysToEcdhJwk = (pub, d) => { // d === priv\n      //var [ x, y ] = shim.Buffer.from(pub, 'base64').toString('utf8').split(':') // old\n      var [ x, y ] = pub.split('.') // new\n      var jwk = d ? { d: d } : {}\n      return [  // Use with spread returned value...\n        'jwk',\n        Object.assign(\n          jwk,\n          { x: x, y: y, kty: 'EC', crv: 'P-256', ext: true }\n        ), // ??? refactor\n        {name: 'ECDH', namedCurve: 'P-256'}\n      ]\n    }\n\n    module.exports = SEA.secret;\n  \n}());"
  },
  {
    "path": "sea/settings.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var s = {};\n    s.pbkdf2 = {hash: {name : 'SHA-256'}, iter: 100000, ks: 64};\n    s.ecdsa = {\n      pair: {name: 'ECDSA', namedCurve: 'P-256'},\n      sign: {name: 'ECDSA', hash: {name: 'SHA-256'}}\n    };\n    s.ecdh = {name: 'ECDH', namedCurve: 'P-256'};\n\n    // This creates Web Cryptography API compliant JWK for sign/verify purposes\n    s.jwk = function(pub, d){  // d === priv\n      pub = pub.split('.');\n      var x = pub[0], y = pub[1];\n      var jwk = {kty: \"EC\", crv: \"P-256\", x: x, y: y, ext: true};\n      jwk.key_ops = d ? ['sign'] : ['verify'];\n      if(d){ jwk.d = d }\n      return jwk;\n    };\n    \n    s.keyToJwk = function(keyBytes) {\n      const keyB64 = keyBytes.toString('base64');\n      const k = keyB64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/\\=/g, '');\n      return { kty: 'oct', k: k, ext: false, alg: 'A256GCM' };\n    }\n\n    s.recall = {\n      validity: 12 * 60 * 60, // internally in seconds : 12 hours\n      hook: function(props){ return props } // { iat, exp, alias, remember } // or return new Promise((resolve, reject) => resolve(props)\n    };\n\n    s.check = function(t){ return (typeof t == 'string') && ('SEA{' === t.slice(0,4)) }\n    s.parse = async function p(t){ try {\n      var yes = (typeof t == 'string');\n      if(yes && 'SEA{' === t.slice(0,4)){ t = t.slice(3) }\n      return yes ? await shim.parse(t) : t;\n      } catch (e) {}\n      return t;\n    }\n\n    SEA.opt = s;\n    module.exports = s\n  \n}());"
  },
  {
    "path": "sea/sha1.js",
    "content": ";(function(){\n\n    // This internal func returns SHA-1 hashed data for KeyID generation\n    const __shim = require('./shim')\n    const subtle = __shim.subtle\n    const ossl = __shim.ossl ? __shim.ossl : subtle\n    const sha1hash = (b) => ossl.digest({name: 'SHA-1'}, new ArrayBuffer(b))\n    module.exports = sha1hash\n  \n}());"
  },
  {
    "path": "sea/sha256.js",
    "content": ";(function(){\n\n    var shim = require('./shim');\n    module.exports = async function(d, o){\n      var t = (typeof d == 'string')? d : await shim.stringify(d);\n      var hash = await shim.subtle.digest({name: o||'SHA-256'}, new shim.TextEncoder().encode(t));\n      return shim.Buffer.from(hash);\n    }\n  \n}());"
  },
  {
    "path": "sea/share.js",
    "content": ";(function(){\n\n    var User = require('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};\n    User.prototype.pair = function(){\n      var user = this, proxy; // undeprecated, hiding with proxies.\n      try{ proxy = new Proxy({DANGER:'\\u2620'}, {get: function(t,p,r){\n        if(!user.is || !(user._||'').sea){ return }\n        return user._.sea[p];\n      }})}catch(e){}\n      return proxy;\n    }\n    // If authenticated user wants to delete his/her account, let's support it!\n    User.prototype.delete = async function(alias, pass, cb){\n      console.log(\"user.delete() IS DEPRECATED AND WILL BE MOVED TO A MODULE!!!\");\n      var gun = this, root = gun.back(-1), user = gun.back('user');\n      try {\n        user.auth(alias, pass, function(ack){\n          var pub = (user.is||{}).pub;\n          // Delete user data\n          user.map().once(function(){ this.put(null) });\n          // Wipe user data from memory\n          user.leave();\n          (cb || noop)({ok: 0});\n        });\n      } catch (e) {\n        Gun.log('User.delete failed! Error:', e);\n      }\n      return gun;\n    }\n    User.prototype.alive = async function(){\n      console.log(\"user.alive() IS DEPRECATED!!!\");\n      const gunRoot = this.back(-1)\n      try {\n        // All is good. Should we do something more with actual recalled data?\n        await authRecall(gunRoot)\n        return gunRoot._.user._\n      } catch (e) {\n        const err = 'No session!'\n        Gun.log(err)\n        throw { err }\n      }\n    }\n    User.prototype.trust = async function(user){\n      console.log(\"`.trust` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      // TODO: BUG!!! SEA `node` read listener needs to be async, which means core needs to be async too.\n      //gun.get('alice').get('age').trust(bob);\n      if (Gun.is(user)) {\n        user.get('pub').get((ctx, ev) => {\n          console.log(ctx, ev)\n        })\n      }\n      user.get('trust').get(path).put(theirPubkey);\n\n      // do a lookup on this gun chain directly (that gets bob's copy of the data)\n      // do a lookup on the metadata trust table for this path (that gets all the pubkeys allowed to write on this path)\n      // do a lookup on each of those pubKeys ON the path (to get the collab data \"layers\")\n      // THEN you perform Jachen's mix operation\n      // and return the result of that to...\n    }\n    User.prototype.grant = function(to, cb){\n      console.log(\"`.grant` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      var gun = this, user = gun.back(-1).user(), pair = user._.sea, path = '';\n      gun.back(function(at){ if(at.is){ return } path += (at.get||'') });\n      (async function(){\n      var enc, sec = await user.get('grant').get(pair.pub).get(path).then();\n      sec = await SEA.decrypt(sec, pair);\n      if(!sec){\n        sec = SEA.random(16).toString();\n        enc = await SEA.encrypt(sec, pair);\n        user.get('grant').get(pair.pub).get(path).put(enc);\n      }\n      var pub = to.get('pub').then();\n      var epub = to.get('epub').then();\n      pub = await pub; epub = await epub;\n      var dh = await SEA.secret(epub, pair);\n      enc = await SEA.encrypt(sec, dh);\n      user.get('grant').get(pub).get(path).put(enc, cb);\n      }());\n      return gun;\n    }\n    User.prototype.secret = function(data, cb){\n      console.log(\"`.secret` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = '';\n      gun.back(function(at){ if(at.is){ return } path += (at.get||'') });\n      (async function(){\n      var enc, sec = await user.get('trust').get(pair.pub).get(path).then();\n      sec = await SEA.decrypt(sec, pair);\n      if(!sec){\n        sec = SEA.random(16).toString();\n        enc = await SEA.encrypt(sec, pair);\n        user.get('trust').get(pair.pub).get(path).put(enc);\n      }\n      enc = await SEA.encrypt(data, sec);\n      gun.put(enc, cb);\n      }());\n      return gun;\n    }\n\n    /**\n     * returns the decrypted value, encrypted by secret\n     * @returns {Promise<any>}\n     // Mark needs to review 1st before officially supported\n    User.prototype.decrypt = function(cb) {\n      let gun = this,\n        path = ''\n      gun.back(function(at) {\n        if (at.is) {\n          return\n        }\n        path += at.get || ''\n      })\n      return gun\n        .then(async data => {\n          if (data == null) {\n            return\n          }\n          const user = gun.back(-1).user()\n          const pair = user.pair()\n          let sec = await user\n            .get('trust')\n            .get(pair.pub)\n            .get(path)\n          sec = await SEA.decrypt(sec, pair)\n          if (!sec) {\n            return data\n          }\n          let decrypted = await SEA.decrypt(data, sec)\n          return decrypted\n        })\n        .then(res => {\n          cb && cb(res)\n          return res\n        })\n    }\n    */\n    module.exports = User\n  \n}());"
  },
  {
    "path": "sea/shim.js",
    "content": ";(function(){\n\n    const SEA = require('./root')\n    const api = {Buffer: require('./buffer')}\n    var o = {}, u;\n\n    // ideally we can move away from JSON entirely? unlikely due to compatibility issues... oh well.\n    JSON.parseAsync = JSON.parseAsync || function(t,cb,r){ var u; try{ cb(u, JSON.parse(t,r)) }catch(e){ cb(e) } }\n    JSON.stringifyAsync = JSON.stringifyAsync || function(v,cb,r,s){ var u; try{ cb(u, JSON.stringify(v,r,s)) }catch(e){ cb(e) } }\n\n    api.parse = function(t,r){ return new Promise(function(res, rej){\n      JSON.parseAsync(t,function(err, raw){ err? rej(err) : res(raw) },r);\n    })}\n    api.stringify = function(v,r,s){ return new Promise(function(res, rej){\n      JSON.stringifyAsync(v,function(err, raw){ err? rej(err) : res(raw) },r,s);\n    })}\n\n    if(SEA.window){\n      api.crypto = SEA.window.crypto || SEA.window.msCrypto\n      api.subtle = (api.crypto||o).subtle || (api.crypto||o).webkitSubtle;\n      api.TextEncoder = SEA.window.TextEncoder;\n      api.TextDecoder = SEA.window.TextDecoder;\n      api.random = (len) => api.Buffer.from(api.crypto.getRandomValues(new Uint8Array(api.Buffer.alloc(len))));\n    }\n    if(!api.TextDecoder)\n    {\n      const { TextEncoder, TextDecoder } = require((u+'' == typeof MODULE?'.':'')+'./lib/text-encoding', 1);\n      api.TextDecoder = TextDecoder;\n      api.TextEncoder = TextEncoder;\n    }\n    if(!api.crypto)\n    {\n      try\n      {\n      var crypto = require('crypto', 1);\n      Object.assign(api, {\n        crypto,\n        random: (len) => api.Buffer.from(crypto.randomBytes(len))\n      });      \n      const { Crypto: WebCrypto } = require('@peculiar/webcrypto', 1);\n      api.ossl = api.subtle = new WebCrypto({directory: 'ossl'}).subtle // ECDH\n    }\n    catch(e){\n      console.log(\"Please `npm install @peculiar/webcrypto` or add it to your package.json !\");\n    }}\n\n    module.exports = api\n  \n}());"
  },
  {
    "path": "sea/sign.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var S = require('./settings');\n    var sha = require('./sha256');\n    var u;\n\n    SEA.sign = SEA.sign || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      if(!(pair||opt).priv){\n        if(!SEA.I){ throw 'No signing key.' }\n        pair = await SEA.I(null, {what: data, how: 'sign', why: opt.why});\n      }\n      if(u === data){ throw '`undefined` not allowed.' }\n      var json = await S.parse(data);\n      var check = opt.check = opt.check || json;\n      if(SEA.verify && (SEA.opt.check(check) || (check && check.s && check.m))\n      && u !== await SEA.verify(check, pair)){ // don't sign if we already signed it.\n        var r = await S.parse(check);\n        if(!opt.raw){ r = 'SEA' + await shim.stringify(r) }\n        if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n        return r;\n      }\n      var pub = pair.pub;\n      var priv = pair.priv;\n      var jwk = S.jwk(pub, priv);\n      var hash = await sha(json);\n      var sig = await (shim.ossl || shim.subtle).importKey('jwk', jwk, {name: 'ECDSA', namedCurve: 'P-256'}, false, ['sign'])\n      .then((key) => (shim.ossl || shim.subtle).sign({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, new Uint8Array(hash))) // privateKey scope doesn't leak out from here!\n      var r = {m: json, s: shim.Buffer.from(sig, 'binary').toString(opt.encode || 'base64')}\n      if(!opt.raw){ r = 'SEA' + await shim.stringify(r) }\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.sign;\n  \n}());"
  },
  {
    "path": "sea/then.js",
    "content": ";(function(){\n\n    var u, Gun = (''+u != typeof GUN)? (GUN||{chain:{}}) : require((''+u === typeof MODULE?'.':'')+'./gun', 1);\n    Gun.chain.then = function(cb, opt){\n      var gun = this, p = (new Promise(function(res, rej){\n        gun.once(res, opt);\n      }));\n      return cb? p.then(cb) : p;\n    }\n  \n}());"
  },
  {
    "path": "sea/user.js",
    "content": ";(function(){\n\n    var SEA = require('./sea'), Gun, u;\n    if(SEA.window){\n      Gun = SEA.window.GUN || {chain:{}};\n    } else {\n      Gun = require((u+'' == typeof MODULE?'.':'')+'./gun', 1);\n    }\n    SEA.GUN = Gun;\n\n    function User(root){ \n      this._ = {$: this};\n    }\n    User.prototype = (function(){ function F(){}; F.prototype = Gun.chain; return new F() }()) // Object.create polyfill\n    User.prototype.constructor = User;\n\n    // let's extend the gun chain with a `user` function.\n    // only one user can be logged in at a time, per gun instance.\n    Gun.chain.user = function(pub){\n      var gun = this, root = gun.back(-1), user;\n      if(pub){\n        pub = SEA.opt.pub((pub._||'')['#']) || pub;\n        return root.get('~'+pub);\n      }\n      if(user = root.back('user')){ return user }\n      var root = (root._), at = root, uuid = at.opt.uuid || lex;\n      (at = (user = at.user = gun.chain(new User))._).opt = {};\n      at.opt.uuid = function(cb){\n        var id = uuid(), pub = root.user;\n        if(!pub || !(pub = pub.is) || !(pub = pub.pub)){ return id }\n        id = '~' + pub + '/' + id;\n        if(cb && cb.call){ cb(null, id) }\n        return id;\n      }\n      return user;\n    }\n    function lex(){ return Gun.state().toString(36).replace('.','') }\n    Gun.User = User;\n    User.GUN = Gun;\n    User.SEA = Gun.SEA = SEA;\n    module.exports = User;\n  \n}());"
  },
  {
    "path": "sea/verify.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var S = require('./settings');\n    var sha = require('./sha256');\n    var u;\n\n    SEA.verify = SEA.verify || (async (data, pair, cb, opt) => { try {\n      var json = await S.parse(data);\n      if(false === pair){ // don't verify!\n        var raw = await S.parse(json.m);\n        if(cb){ try{ cb(raw) }catch(e){console.log(e)} }\n        return raw;\n      }\n      opt = opt || {};\n      // SEA.I // verify is free! Requires no user permission.\n      var pub = pair.pub || pair;\n      var key = SEA.opt.slow_leak? await SEA.opt.slow_leak(pub) : await (shim.ossl || shim.subtle).importKey('jwk', S.jwk(pub), {name: 'ECDSA', namedCurve: 'P-256'}, false, ['verify']);\n      var hash = await sha(json.m);\n      var buf, sig, check, tmp; try{\n        buf = shim.Buffer.from(json.s, opt.encode || 'base64'); // NEW DEFAULT!\n        sig = new Uint8Array(buf);\n        check = await (shim.ossl || shim.subtle).verify({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, sig, new Uint8Array(hash));\n        if(!check){ throw \"Signature did not match.\" }\n      }catch(e){\n        if(SEA.opt.fallback){\n          return await SEA.opt.fall_verify(data, pair, cb, opt);\n        }\n      }\n      var r = check? await S.parse(json.m) : u;\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e); // mismatched owner FOR MARTTI\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.verify;\n    // legacy & ossl memory leak mitigation:\n\n    var knownKeys = {};\n    var keyForPair = SEA.opt.slow_leak = pair => {\n      if (knownKeys[pair]) return knownKeys[pair];\n      var jwk = S.jwk(pair);\n      knownKeys[pair] = (shim.ossl || shim.subtle).importKey(\"jwk\", jwk, {name: 'ECDSA', namedCurve: 'P-256'}, false, [\"verify\"]);\n      return knownKeys[pair];\n    };\n\n    var O = SEA.opt;\n    SEA.opt.fall_verify = async function(data, pair, cb, opt, f){\n      if(f === SEA.opt.fallback){ throw \"Signature did not match\" } f = f || 1;\n      var tmp = data||'';\n      data = SEA.opt.unpack(data) || data;\n      var json = await S.parse(data), pub = pair.pub || pair, key = await SEA.opt.slow_leak(pub);\n      var hash = (f <= SEA.opt.fallback)? shim.Buffer.from(await shim.subtle.digest({name: 'SHA-256'}, new shim.TextEncoder().encode(await S.parse(json.m)))) : await sha(json.m); // this line is old bad buggy code but necessary for old compatibility.\n      var buf; var sig; var check; try{\n        buf = shim.Buffer.from(json.s, opt.encode || 'base64') // NEW DEFAULT!\n        sig = new Uint8Array(buf)\n        check = await (shim.ossl || shim.subtle).verify({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, sig, new Uint8Array(hash))\n        if(!check){ throw \"Signature did not match.\" }\n      }catch(e){ try{\n        buf = shim.Buffer.from(json.s, 'utf8') // AUTO BACKWARD OLD UTF8 DATA!\n        sig = new Uint8Array(buf)\n        check = await (shim.ossl || shim.subtle).verify({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, sig, new Uint8Array(hash))\n        }catch(e){\n        if(!check){ throw \"Signature did not match.\" }\n        }\n      }\n      var r = check? await S.parse(json.m) : u;\n      O.fall_soul = tmp['#']; O.fall_key = tmp['.']; O.fall_val = data; O.fall_state = tmp['>'];\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    }\n    SEA.opt.fallback = 2;\n\n  \n}());"
  },
  {
    "path": "sea/work.js",
    "content": ";(function(){\n\n    var SEA = require('./root');\n    var shim = require('./shim');\n    var S = require('./settings');\n    var sha = require('./sha256');\n    var u;\n\n    SEA.work = SEA.work || (async (data, pair, cb, opt) => { try { // used to be named `proof`\n      var salt = (pair||{}).epub || pair; // epub not recommended, salt should be random!\n      opt = opt || {};\n      if(salt instanceof Function){\n        cb = salt;\n        salt = u;\n      }\n      data = (typeof data == 'string')? data : await shim.stringify(data);\n      if('sha' === (opt.name||'').toLowerCase().slice(0,3)){\n        var rsha = shim.Buffer.from(await sha(data, opt.name), 'binary').toString(opt.encode || 'base64')\n        if(cb){ try{ cb(rsha) }catch(e){console.log(e)} }\n        return rsha;\n      }\n      salt = salt || shim.random(9);\n      var key = await (shim.ossl || shim.subtle).importKey('raw', new shim.TextEncoder().encode(data), {name: opt.name || 'PBKDF2'}, false, ['deriveBits']);\n      var work = await (shim.ossl || shim.subtle).deriveBits({\n        name: opt.name || 'PBKDF2',\n        iterations: opt.iterations || S.pbkdf2.iter,\n        salt: new shim.TextEncoder().encode(opt.salt || salt),\n        hash: opt.hash || S.pbkdf2.hash,\n      }, key, opt.length || (S.pbkdf2.ks * 8))\n      data = shim.random(data.length)  // Erase data in case of passphrase\n      var r = shim.Buffer.from(work, 'binary').toString(opt.encode || 'base64')\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.work;\n  \n}());"
  },
  {
    "path": "sea.d.ts",
    "content": "import { ISEA } from './types/sea/ISEA';\n\ndeclare const SEA: ISEA;\nexport default SEA;\n\nimport {} from './types/sea/ISEA';\ndeclare module './types/sea/ISEA' {\n  export interface ISEA {\n    window: Window\n  }\n}\n\nimport {} from './types/gun/IGun';\ndeclare module './types/gun/IGun' {\n  export interface IGun {\n    SEA: ISEA;\n  }\n}\n\ndeclare global {\n  interface Window {\n    SEA: ISEA;\n  }\n}\n"
  },
  {
    "path": "sea.js",
    "content": ";(function(){\n\n  /* UNBUILD */\n  function USE(arg, req){\n    return req? require(arg) : arg.slice? USE[R(arg)] : function(mod, path){\n      arg(mod = {exports: {}});\n      USE[R(path)] = mod.exports;\n    }\n    function R(p){\n      return p.split('/').slice(-1).toString().replace('.js','');\n    }\n  }\n  if(typeof module !== \"undefined\"){ var MODULE = module }\n  /* UNBUILD */\n\n  ;USE(function(module){\n    // Security, Encryption, and Authorization: SEA.js\n    // MANDATORY READING: https://gun.eco/explainers/data/security.html\n    // IT IS IMPLEMENTED IN A POLYFILL/SHIM APPROACH.\n    // THIS IS AN EARLY ALPHA!\n\n    if(typeof self !== \"undefined\"){ module.window = self } // should be safe for at least browser/worker/nodejs, need to check other envs like RN etc.\n    if(typeof window !== \"undefined\"){ module.window = window }\n\n    var tmp = module.window || module, u;\n    var SEA = tmp.SEA || {};\n\n    if(SEA.window = module.window){ SEA.window.SEA = SEA }\n\n    try{ if(u+'' !== typeof MODULE){ MODULE.exports = SEA } }catch(e){}\n    module.exports = SEA;\n  })(USE, './root');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    try{ if(SEA.window){\n      if(location.protocol.indexOf('s') < 0\n      && location.host.indexOf('localhost') < 0\n      && ! /^127\\.\\d+\\.\\d+\\.\\d+$/.test(location.hostname)\n      && location.protocol.indexOf('blob:') < 0\n      && location.protocol.indexOf('file:') < 0\n      && location.origin != 'null'){\n        console.warn('HTTPS needed for WebCrypto in SEA, redirecting...');\n        location.protocol = 'https:'; // WebCrypto does NOT work without HTTPS!\n      }\n    } }catch(e){}\n  })(USE, './https');\n\n  ;USE(function(module){\n    var u;\n    if(u+''== typeof btoa){\n      if(u+'' == typeof Buffer){\n        try{ global.Buffer = USE(\"buffer\", 1).Buffer }catch(e){ console.log(\"Please `npm install buffer` or add it to your package.json !\") }\n      }\n      global.btoa = function(data){ return Buffer.from(data, \"binary\").toString(\"base64\") };\n      global.atob = function(data){ return Buffer.from(data, \"base64\").toString(\"binary\") };\n    }\n  })(USE, './base64');\n\n  ;USE(function(module){\n    USE('./base64');\n    // This is Array extended to have .toString(['utf8'|'hex'|'base64'])\n    function SeaArray() {}\n    Object.assign(SeaArray, { from: Array.from })\n    SeaArray.prototype = Object.create(Array.prototype)\n    SeaArray.prototype.toString = function(enc, start, end) { enc = enc || 'utf8'; start = start || 0;\n      const length = this.length\n      if (enc === 'hex') {\n        const buf = new Uint8Array(this)\n        return [ ...Array(((end && (end + 1)) || length) - start).keys()]\n        .map((i) => buf[ i + start ].toString(16).padStart(2, '0')).join('')\n      }\n      if (enc === 'utf8') {\n        return Array.from(\n          { length: (end || length) - start },\n          (_, i) => String.fromCharCode(this[ i + start])\n        ).join('')\n      }\n      if (enc === 'base64') {\n        return btoa(this)\n      }\n    }\n    module.exports = SeaArray;\n  })(USE, './array');\n\n  ;USE(function(module){\n    USE('./base64');\n    // This is Buffer implementation used in SEA. Functionality is mostly\n    // compatible with NodeJS 'safe-buffer' and is used for encoding conversions\n    // between binary and 'hex' | 'utf8' | 'base64'\n    // See documentation and validation for safe implementation in:\n    // https://github.com/feross/safe-buffer#update\n    var SeaArray = USE('./array');\n    function SafeBuffer(...props) {\n      console.warn('new SafeBuffer() is depreciated, please use SafeBuffer.from()')\n      return SafeBuffer.from(...props)\n    }\n    SafeBuffer.prototype = Object.create(Array.prototype)\n    Object.assign(SafeBuffer, {\n      // (data, enc) where typeof data === 'string' then enc === 'utf8'|'hex'|'base64'\n      from() {\n        if (!Object.keys(arguments).length || arguments[0]==null) {\n          throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n        }\n        const input = arguments[0]\n        let buf\n        if (typeof input === 'string') {\n          const enc = arguments[1] || 'utf8'\n          if (enc === 'hex') {\n            const bytes = input.match(/([\\da-fA-F]{2})/g)\n            .map((byte) => parseInt(byte, 16))\n            if (!bytes || !bytes.length) {\n              throw new TypeError('Invalid first argument for type \\'hex\\'.')\n            }\n            buf = SeaArray.from(bytes)\n          } else if (enc === 'utf8' || 'binary' === enc) { // EDIT BY MARK: I think this is safe, tested it against a couple \"binary\" strings. This lets SafeBuffer match NodeJS Buffer behavior more where it safely btoas regular strings.\n            const length = input.length\n            const words = new Uint16Array(length)\n            Array.from({ length: length }, (_, i) => words[i] = input.charCodeAt(i))\n            buf = SeaArray.from(words)\n          } else if (enc === 'base64') {\n            const dec = atob(input)\n            const length = dec.length\n            const bytes = new Uint8Array(length)\n            Array.from({ length: length }, (_, i) => bytes[i] = dec.charCodeAt(i))\n            buf = SeaArray.from(bytes)\n          } else if (enc === 'binary') { // deprecated by above comment\n            buf = SeaArray.from(input) // some btoas were mishandled.\n          } else {\n            console.info('SafeBuffer.from unknown encoding: '+enc)\n          }\n          return buf\n        }\n        const byteLength = input.byteLength // what is going on here? FOR MARTTI\n        const length = input.byteLength ? input.byteLength : input.length\n        if (length) {\n          let buf\n          if (input instanceof ArrayBuffer) {\n            buf = new Uint8Array(input)\n          }\n          return SeaArray.from(buf || input)\n        }\n      },\n      // This is 'safe-buffer.alloc' sans encoding support\n      alloc(length, fill = 0 /*, enc*/ ) {\n        return SeaArray.from(new Uint8Array(Array.from({ length: length }, () => fill)))\n      },\n      // This is normal UNSAFE 'buffer.alloc' or 'new Buffer(length)' - don't use!\n      allocUnsafe(length) {\n        return SeaArray.from(new Uint8Array(Array.from({ length : length })))\n      },\n      // This puts together array of array like members\n      concat(arr) { // octet array\n        if (!Array.isArray(arr)) {\n          throw new TypeError('First argument must be Array containing ArrayBuffer or Uint8Array instances.')\n        }\n        return SeaArray.from(arr.reduce((ret, item) => ret.concat(Array.from(item)), []))\n      }\n    })\n    SafeBuffer.prototype.from = SafeBuffer.from\n    SafeBuffer.prototype.toString = SeaArray.prototype.toString\n\n    module.exports = SafeBuffer;\n  })(USE, './buffer');\n\n  ;USE(function(module){\n    const SEA = USE('./root')\n    const api = {Buffer: USE('./buffer')}\n    var o = {}, u;\n\n    // ideally we can move away from JSON entirely? unlikely due to compatibility issues... oh well.\n    JSON.parseAsync = JSON.parseAsync || function(t,cb,r){ var u; try{ cb(u, JSON.parse(t,r)) }catch(e){ cb(e) } }\n    JSON.stringifyAsync = JSON.stringifyAsync || function(v,cb,r,s){ var u; try{ cb(u, JSON.stringify(v,r,s)) }catch(e){ cb(e) } }\n\n    api.parse = function(t,r){ return new Promise(function(res, rej){\n      JSON.parseAsync(t,function(err, raw){ err? rej(err) : res(raw) },r);\n    })}\n    api.stringify = function(v,r,s){ return new Promise(function(res, rej){\n      JSON.stringifyAsync(v,function(err, raw){ err? rej(err) : res(raw) },r,s);\n    })}\n\n    if(SEA.window){\n      api.crypto = SEA.window.crypto || SEA.window.msCrypto\n      api.subtle = (api.crypto||o).subtle || (api.crypto||o).webkitSubtle;\n      api.TextEncoder = SEA.window.TextEncoder;\n      api.TextDecoder = SEA.window.TextDecoder;\n      api.random = (len) => api.Buffer.from(api.crypto.getRandomValues(new Uint8Array(api.Buffer.alloc(len))));\n    }\n    if(!api.TextDecoder)\n    {\n      const { TextEncoder, TextDecoder } = USE((u+'' == typeof MODULE?'.':'')+'./lib/text-encoding', 1);\n      api.TextDecoder = TextDecoder;\n      api.TextEncoder = TextEncoder;\n    }\n    if(!api.crypto)\n    {\n      try\n      {\n      var crypto = USE('crypto', 1);\n      Object.assign(api, {\n        crypto,\n        random: (len) => api.Buffer.from(crypto.randomBytes(len))\n      });      \n      const { Crypto: WebCrypto } = USE('@peculiar/webcrypto', 1);\n      api.ossl = api.subtle = new WebCrypto({directory: 'ossl'}).subtle // ECDH\n    }\n    catch(e){\n      console.log(\"Please `npm install @peculiar/webcrypto` or add it to your package.json !\");\n    }}\n\n    module.exports = api\n  })(USE, './shim');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var s = {};\n    s.pbkdf2 = {hash: {name : 'SHA-256'}, iter: 100000, ks: 64};\n    s.ecdsa = {\n      pair: {name: 'ECDSA', namedCurve: 'P-256'},\n      sign: {name: 'ECDSA', hash: {name: 'SHA-256'}}\n    };\n    s.ecdh = {name: 'ECDH', namedCurve: 'P-256'};\n\n    // This creates Web Cryptography API compliant JWK for sign/verify purposes\n    s.jwk = function(pub, d){  // d === priv\n      pub = pub.split('.');\n      var x = pub[0], y = pub[1];\n      var jwk = {kty: \"EC\", crv: \"P-256\", x: x, y: y, ext: true};\n      jwk.key_ops = d ? ['sign'] : ['verify'];\n      if(d){ jwk.d = d }\n      return jwk;\n    };\n    \n    s.keyToJwk = function(keyBytes) {\n      const keyB64 = keyBytes.toString('base64');\n      const k = keyB64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/\\=/g, '');\n      return { kty: 'oct', k: k, ext: false, alg: 'A256GCM' };\n    }\n\n    s.recall = {\n      validity: 12 * 60 * 60, // internally in seconds : 12 hours\n      hook: function(props){ return props } // { iat, exp, alias, remember } // or return new Promise((resolve, reject) => resolve(props)\n    };\n\n    s.check = function(t){ return (typeof t == 'string') && ('SEA{' === t.slice(0,4)) }\n    s.parse = async function p(t){ try {\n      var yes = (typeof t == 'string');\n      if(yes && 'SEA{' === t.slice(0,4)){ t = t.slice(3) }\n      return yes ? await shim.parse(t) : t;\n      } catch (e) {}\n      return t;\n    }\n\n    SEA.opt = s;\n    module.exports = s\n  })(USE, './settings');\n\n  ;USE(function(module){\n    var shim = USE('./shim');\n    module.exports = async function(d, o){\n      var t = (typeof d == 'string')? d : await shim.stringify(d);\n      var hash = await shim.subtle.digest({name: o||'SHA-256'}, new shim.TextEncoder().encode(t));\n      return shim.Buffer.from(hash);\n    }\n  })(USE, './sha256');\n\n  ;USE(function(module){\n    // This internal func returns SHA-1 hashed data for KeyID generation\n    const __shim = USE('./shim')\n    const subtle = __shim.subtle\n    const ossl = __shim.ossl ? __shim.ossl : subtle\n    const sha1hash = (b) => ossl.digest({name: 'SHA-1'}, new ArrayBuffer(b))\n    module.exports = sha1hash\n  })(USE, './sha1');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var sha = USE('./sha256');\n    var u;\n\n    SEA.work = SEA.work || (async (data, pair, cb, opt) => { try { // used to be named `proof`\n      var salt = (pair||{}).epub || pair; // epub not recommended, salt should be random!\n      opt = opt || {};\n      if(salt instanceof Function){\n        cb = salt;\n        salt = u;\n      }\n      data = (typeof data == 'string')? data : await shim.stringify(data);\n      if('sha' === (opt.name||'').toLowerCase().slice(0,3)){\n        var rsha = shim.Buffer.from(await sha(data, opt.name), 'binary').toString(opt.encode || 'base64')\n        if(cb){ try{ cb(rsha) }catch(e){console.log(e)} }\n        return rsha;\n      }\n      salt = salt || shim.random(9);\n      var key = await (shim.ossl || shim.subtle).importKey('raw', new shim.TextEncoder().encode(data), {name: opt.name || 'PBKDF2'}, false, ['deriveBits']);\n      var work = await (shim.ossl || shim.subtle).deriveBits({\n        name: opt.name || 'PBKDF2',\n        iterations: opt.iterations || S.pbkdf2.iter,\n        salt: new shim.TextEncoder().encode(opt.salt || salt),\n        hash: opt.hash || S.pbkdf2.hash,\n      }, key, opt.length || (S.pbkdf2.ks * 8))\n      data = shim.random(data.length)  // Erase data in case of passphrase\n      var r = shim.Buffer.from(work, 'binary').toString(opt.encode || 'base64')\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.work;\n  })(USE, './work');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n\n    SEA.name = SEA.name || (async (cb, opt) => { try {\n      if(cb){ try{ cb() }catch(e){console.log(e)} }\n      return;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    //SEA.pair = async (data, proof, cb) => { try {\n    SEA.pair = SEA.pair || (async (cb, opt) => { try {\n\n      var ecdhSubtle = shim.ossl || shim.subtle;\n      // First: ECDSA keys for signing/verifying...\n      var sa = await shim.subtle.generateKey({name: 'ECDSA', namedCurve: 'P-256'}, true, [ 'sign', 'verify' ])\n      .then(async (keys) => {\n        // privateKey scope doesn't leak out from here!\n        //const { d: priv } = await shim.subtle.exportKey('jwk', keys.privateKey)\n        var key = {};\n        key.priv = (await shim.subtle.exportKey('jwk', keys.privateKey)).d;\n        var pub = await shim.subtle.exportKey('jwk', keys.publicKey);\n        //const pub = Buff.from([ x, y ].join(':')).toString('base64') // old\n        key.pub = pub.x+'.'+pub.y; // new\n        // x and y are already base64\n        // pub is UTF8 but filename/URL safe (https://www.ietf.org/rfc/rfc3986.txt)\n        // but split on a non-base64 letter.\n        return key;\n      })\n      \n      // To include PGPv4 kind of keyId:\n      // const pubId = await SEA.keyid(keys.pub)\n      // Next: ECDH keys for encryption/decryption...\n\n      try{\n      var dh = await ecdhSubtle.generateKey({name: 'ECDH', namedCurve: 'P-256'}, true, ['deriveKey'])\n      .then(async (keys) => {\n        // privateKey scope doesn't leak out from here!\n        var key = {};\n        key.epriv = (await ecdhSubtle.exportKey('jwk', keys.privateKey)).d;\n        var pub = await ecdhSubtle.exportKey('jwk', keys.publicKey);\n        //const epub = Buff.from([ ex, ey ].join(':')).toString('base64') // old\n        key.epub = pub.x+'.'+pub.y; // new\n        // ex and ey are already base64\n        // epub is UTF8 but filename/URL safe (https://www.ietf.org/rfc/rfc3986.txt)\n        // but split on a non-base64 letter.\n        return key;\n      })\n      }catch(e){\n        if(SEA.window){ throw e }\n        if(e == 'Error: ECDH is not a supported algorithm'){ console.log('Ignoring ECDH...') }\n        else { throw e }\n      } dh = dh || {};\n\n      var r = { pub: sa.pub, priv: sa.priv, /* pubId, */ epub: dh.epub, epriv: dh.epriv }\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.pair;\n  })(USE, './pair');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var sha = USE('./sha256');\n    var u;\n\n    SEA.sign = SEA.sign || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      if(!(pair||opt).priv){\n        if(!SEA.I){ throw 'No signing key.' }\n        pair = await SEA.I(null, {what: data, how: 'sign', why: opt.why});\n      }\n      if(u === data){ throw '`undefined` not allowed.' }\n      var json = await S.parse(data);\n      var check = opt.check = opt.check || json;\n      if(SEA.verify && (SEA.opt.check(check) || (check && check.s && check.m))\n      && u !== await SEA.verify(check, pair)){ // don't sign if we already signed it.\n        var r = await S.parse(check);\n        if(!opt.raw){ r = 'SEA' + await shim.stringify(r) }\n        if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n        return r;\n      }\n      var pub = pair.pub;\n      var priv = pair.priv;\n      var jwk = S.jwk(pub, priv);\n      var hash = await sha(json);\n      var sig = await (shim.ossl || shim.subtle).importKey('jwk', jwk, {name: 'ECDSA', namedCurve: 'P-256'}, false, ['sign'])\n      .then((key) => (shim.ossl || shim.subtle).sign({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, new Uint8Array(hash))) // privateKey scope doesn't leak out from here!\n      var r = {m: json, s: shim.Buffer.from(sig, 'binary').toString(opt.encode || 'base64')}\n      if(!opt.raw){ r = 'SEA' + await shim.stringify(r) }\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.sign;\n  })(USE, './sign');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var sha = USE('./sha256');\n    var u;\n\n    SEA.verify = SEA.verify || (async (data, pair, cb, opt) => { try {\n      var json = await S.parse(data);\n      if(false === pair){ // don't verify!\n        var raw = await S.parse(json.m);\n        if(cb){ try{ cb(raw) }catch(e){console.log(e)} }\n        return raw;\n      }\n      opt = opt || {};\n      // SEA.I // verify is free! Requires no user permission.\n      var pub = pair.pub || pair;\n      var key = SEA.opt.slow_leak? await SEA.opt.slow_leak(pub) : await (shim.ossl || shim.subtle).importKey('jwk', S.jwk(pub), {name: 'ECDSA', namedCurve: 'P-256'}, false, ['verify']);\n      var hash = await sha(json.m);\n      var buf, sig, check, tmp; try{\n        buf = shim.Buffer.from(json.s, opt.encode || 'base64'); // NEW DEFAULT!\n        sig = new Uint8Array(buf);\n        check = await (shim.ossl || shim.subtle).verify({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, sig, new Uint8Array(hash));\n        if(!check){ throw \"Signature did not match.\" }\n      }catch(e){\n        if(SEA.opt.fallback){\n          return await SEA.opt.fall_verify(data, pair, cb, opt);\n        }\n      }\n      var r = check? await S.parse(json.m) : u;\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e); // mismatched owner FOR MARTTI\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.verify;\n    // legacy & ossl memory leak mitigation:\n\n    var knownKeys = {};\n    var keyForPair = SEA.opt.slow_leak = pair => {\n      if (knownKeys[pair]) return knownKeys[pair];\n      var jwk = S.jwk(pair);\n      knownKeys[pair] = (shim.ossl || shim.subtle).importKey(\"jwk\", jwk, {name: 'ECDSA', namedCurve: 'P-256'}, false, [\"verify\"]);\n      return knownKeys[pair];\n    };\n\n    var O = SEA.opt;\n    SEA.opt.fall_verify = async function(data, pair, cb, opt, f){\n      if(f === SEA.opt.fallback){ throw \"Signature did not match\" } f = f || 1;\n      var tmp = data||'';\n      data = SEA.opt.unpack(data) || data;\n      var json = await S.parse(data), pub = pair.pub || pair, key = await SEA.opt.slow_leak(pub);\n      var hash = (f <= SEA.opt.fallback)? shim.Buffer.from(await shim.subtle.digest({name: 'SHA-256'}, new shim.TextEncoder().encode(await S.parse(json.m)))) : await sha(json.m); // this line is old bad buggy code but necessary for old compatibility.\n      var buf; var sig; var check; try{\n        buf = shim.Buffer.from(json.s, opt.encode || 'base64') // NEW DEFAULT!\n        sig = new Uint8Array(buf)\n        check = await (shim.ossl || shim.subtle).verify({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, sig, new Uint8Array(hash))\n        if(!check){ throw \"Signature did not match.\" }\n      }catch(e){ try{\n        buf = shim.Buffer.from(json.s, 'utf8') // AUTO BACKWARD OLD UTF8 DATA!\n        sig = new Uint8Array(buf)\n        check = await (shim.ossl || shim.subtle).verify({name: 'ECDSA', hash: {name: 'SHA-256'}}, key, sig, new Uint8Array(hash))\n        }catch(e){\n        if(!check){ throw \"Signature did not match.\" }\n        }\n      }\n      var r = check? await S.parse(json.m) : u;\n      O.fall_soul = tmp['#']; O.fall_key = tmp['.']; O.fall_val = data; O.fall_state = tmp['>'];\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    }\n    SEA.opt.fallback = 2;\n\n  })(USE, './verify');\n\n  ;USE(function(module){\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var sha256hash = USE('./sha256');\n\n    const importGen = async (key, salt, opt) => {\n      //const combo = shim.Buffer.concat([shim.Buffer.from(key, 'utf8'), salt || shim.random(8)]).toString('utf8') // old\n      opt = opt || {};\n      const combo = key + (salt || shim.random(8)).toString('utf8'); // new\n      const hash = shim.Buffer.from(await sha256hash(combo), 'binary')\n      \n      const jwkKey = S.keyToJwk(hash)      \n      return await shim.subtle.importKey('jwk', jwkKey, {name:'AES-GCM'}, false, ['encrypt', 'decrypt'])\n    }\n    module.exports = importGen;\n  })(USE, './aeskey');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var aeskey = USE('./aeskey');\n    var u;\n\n    SEA.encrypt = SEA.encrypt || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      var key = (pair||opt).epriv || pair;\n      if(u === data){ throw '`undefined` not allowed.' }\n      if(!key){\n        if(!SEA.I){ throw 'No encryption key.' }\n        pair = await SEA.I(null, {what: data, how: 'encrypt', why: opt.why});\n        key = pair.epriv || pair;\n      }\n      var msg = (typeof data == 'string')? data : await shim.stringify(data);\n      var rand = {s: shim.random(9), iv: shim.random(15)}; // consider making this 9 and 15 or 18 or 12 to reduce == padding.\n      var ct = await aeskey(key, rand.s, opt).then((aes) => (/*shim.ossl ||*/ shim.subtle).encrypt({ // Keeping the AES key scope as private as possible...\n        name: opt.name || 'AES-GCM', iv: new Uint8Array(rand.iv)\n      }, aes, new shim.TextEncoder().encode(msg)));\n      var r = {\n        ct: shim.Buffer.from(ct, 'binary').toString(opt.encode || 'base64'),\n        iv: rand.iv.toString(opt.encode || 'base64'),\n        s: rand.s.toString(opt.encode || 'base64')\n      }\n      if(!opt.raw){ r = 'SEA' + await shim.stringify(r) }\n\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.encrypt;\n  })(USE, './encrypt');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    var aeskey = USE('./aeskey');\n\n    SEA.decrypt = SEA.decrypt || (async (data, pair, cb, opt) => { try {\n      opt = opt || {};\n      var key = (pair||opt).epriv || pair;\n      if(!key){\n        if(!SEA.I){ throw 'No decryption key.' }\n        pair = await SEA.I(null, {what: data, how: 'decrypt', why: opt.why});\n        key = pair.epriv || pair;\n      }\n      var json = await S.parse(data);\n      var buf, bufiv, bufct; try{\n        buf = shim.Buffer.from(json.s, opt.encode || 'base64');\n        bufiv = shim.Buffer.from(json.iv, opt.encode || 'base64');\n        bufct = shim.Buffer.from(json.ct, opt.encode || 'base64');\n        var ct = await aeskey(key, buf, opt).then((aes) => (/*shim.ossl ||*/ shim.subtle).decrypt({  // Keeping aesKey scope as private as possible...\n          name: opt.name || 'AES-GCM', iv: new Uint8Array(bufiv), tagLength: 128\n        }, aes, new Uint8Array(bufct)));\n      }catch(e){\n        if('utf8' === opt.encode){ throw \"Could not decrypt\" }\n        if(SEA.opt.fallback){\n          opt.encode = 'utf8';\n          return await SEA.decrypt(data, pair, cb, opt);\n        }\n      }\n      var r = await S.parse(new shim.TextDecoder('utf8').decode(ct));\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) { \n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.decrypt;\n  })(USE, './decrypt');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    var shim = USE('./shim');\n    var S = USE('./settings');\n    // Derive shared secret from other's pub and my epub/epriv \n    SEA.secret = SEA.secret || (async (key, pair, cb, opt) => { try {\n      opt = opt || {};\n      if(!pair || !pair.epriv || !pair.epub){\n        if(!SEA.I){ throw 'No secret mix.' }\n        pair = await SEA.I(null, {what: key, how: 'secret', why: opt.why});\n      }\n      var pub = key.epub || key;\n      var epub = pair.epub;\n      var epriv = pair.epriv;\n      var ecdhSubtle = shim.ossl || shim.subtle;\n      var pubKeyData = keysToEcdhJwk(pub);\n      var props = Object.assign({ public: await ecdhSubtle.importKey(...pubKeyData, true, []) },{name: 'ECDH', namedCurve: 'P-256'}); // Thanks to @sirpy !\n      var privKeyData = keysToEcdhJwk(epub, epriv);\n      var derived = await ecdhSubtle.importKey(...privKeyData, false, ['deriveBits']).then(async (privKey) => {\n        // privateKey scope doesn't leak out from here!\n        var derivedBits = await ecdhSubtle.deriveBits(props, privKey, 256);\n        var rawBits = new Uint8Array(derivedBits);\n        var derivedKey = await ecdhSubtle.importKey('raw', rawBits,{ name: 'AES-GCM', length: 256 }, true, [ 'encrypt', 'decrypt' ]);\n        return ecdhSubtle.exportKey('jwk', derivedKey).then(({ k }) => k);\n      })\n      var r = derived;\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      console.log(e);\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    // can this be replaced with settings.jwk?\n    var keysToEcdhJwk = (pub, d) => { // d === priv\n      //var [ x, y ] = shim.Buffer.from(pub, 'base64').toString('utf8').split(':') // old\n      var [ x, y ] = pub.split('.') // new\n      var jwk = d ? { d: d } : {}\n      return [  // Use with spread returned value...\n        'jwk',\n        Object.assign(\n          jwk,\n          { x: x, y: y, kty: 'EC', crv: 'P-256', ext: true }\n        ), // ??? refactor\n        {name: 'ECDH', namedCurve: 'P-256'}\n      ]\n    }\n\n    module.exports = SEA.secret;\n  })(USE, './secret');\n\n  ;USE(function(module){\n    var SEA = USE('./root');\n    // This is to certify that a group of \"certificants\" can \"put\" anything at a group of matched \"paths\" to the certificate authority's graph\n    SEA.certify = SEA.certify || (async (certificants, policy = {}, authority, cb, opt = {}) => { try {\n      /*\n      The Certify Protocol was made out of love by a Vietnamese code enthusiast. Vietnamese people around the world deserve respect!\n      IMPORTANT: A Certificate is like a Signature. No one knows who (authority) created/signed a cert until you put it into their graph.\n      \"certificants\": '*' or a String (Bob.pub) || an Object that contains \"pub\" as a key || an array of [object || string]. These people will have the rights.\n      \"policy\": A string ('inbox'), or a RAD/LEX object {'*': 'inbox'}, or an Array of RAD/LEX objects or strings. RAD/LEX object can contain key \"?\" with indexOf(\"*\") > -1 to force key equals certificant pub. This rule is used to check against soul+'/'+key using Gun.text.match or String.match.\n      \"authority\": Key pair or priv of the certificate authority.\n      \"cb\": A callback function after all things are done.\n      \"opt\": If opt.expiry (a timestamp) is set, SEA won't sync data after opt.expiry. If opt.block is set, SEA will look for block before syncing.\n      */\n      console.log('SEA.certify() is an early experimental community supported method that may change API behavior without warning in any future version.')\n\n      certificants = (() => {\n        var data = []\n        if (certificants) {\n          if ((typeof certificants === 'string' || Array.isArray(certificants)) && certificants.indexOf('*') > -1) return '*'\n          if (typeof certificants === 'string') return certificants\n          if (Array.isArray(certificants)) {\n            if (certificants.length === 1 && certificants[0]) return typeof certificants[0] === 'object' && certificants[0].pub ? certificants[0].pub : typeof certificants[0] === 'string' ? certificants[0] : null\n            certificants.map(certificant => {\n              if (typeof certificant ==='string') data.push(certificant)\n              else if (typeof certificant === 'object' && certificant.pub) data.push(certificant.pub)\n            })\n          }\n\n          if (typeof certificants === 'object' && certificants.pub) return certificants.pub\n          return data.length > 0 ? data : null\n        }\n        return\n      })()\n\n      if (!certificants) return console.log(\"No certificant found.\")\n\n      const expiry = opt.expiry && (typeof opt.expiry === 'number' || typeof opt.expiry === 'string') ? parseFloat(opt.expiry) : null\n      const readPolicy = (policy || {}).read ? policy.read : null\n      const writePolicy = (policy || {}).write ? policy.write : typeof policy === 'string' || Array.isArray(policy) || policy[\"+\"] || policy[\"#\"] || policy[\".\"] || policy[\"=\"] || policy[\"*\"] || policy[\">\"] || policy[\"<\"] ? policy : null\n      // The \"blacklist\" feature is now renamed to \"block\". Why ? BECAUSE BLACK LIVES MATTER!\n      // We can now use 3 keys: block, blacklist, ban\n      const block = (opt || {}).block || (opt || {}).blacklist || (opt || {}).ban || {}\n      const readBlock = block.read && (typeof block.read === 'string' || (block.read || {})['#']) ? block.read : null\n      const writeBlock = typeof block === 'string' ? block : block.write && (typeof block.write === 'string' || block.write['#']) ? block.write : null\n\n      if (!readPolicy && !writePolicy) return console.log(\"No policy found.\")\n\n      // reserved keys: c, e, r, w, rb, wb\n      const data = JSON.stringify({\n        c: certificants,\n        ...(expiry ? {e: expiry} : {}), // inject expiry if possible\n        ...(readPolicy ? {r: readPolicy }  : {}), // \"r\" stands for read, which means read permission.\n        ...(writePolicy ? {w: writePolicy} : {}), // \"w\" stands for write, which means write permission.\n        ...(readBlock ? {rb: readBlock} : {}), // inject READ block if possible\n        ...(writeBlock ? {wb: writeBlock} : {}), // inject WRITE block if possible\n      })\n\n      const certificate = await SEA.sign(data, authority, null, {raw:1})\n\n      var r = certificate\n      if(!opt.raw){ r = 'SEA'+JSON.stringify(r) }\n      if(cb){ try{ cb(r) }catch(e){console.log(e)} }\n      return r;\n    } catch(e) {\n      SEA.err = e;\n      if(SEA.throw){ throw e }\n      if(cb){ cb() }\n      return;\n    }});\n\n    module.exports = SEA.certify;\n  })(USE, './certify');\n\n  ;USE(function(module){\n    var shim = USE('./shim');\n    // Practical examples about usage found in tests.\n    var SEA = USE('./root');\n    SEA.work = USE('./work');\n    SEA.sign = USE('./sign');\n    SEA.verify = USE('./verify');\n    SEA.encrypt = USE('./encrypt');\n    SEA.decrypt = USE('./decrypt');\n    SEA.certify = USE('./certify');\n    //SEA.opt.aeskey = USE('./aeskey'); // not official! // this causes problems in latest WebCrypto.\n\n    SEA.random = SEA.random || shim.random;\n\n    // This is Buffer used in SEA and usable from Gun/SEA application also.\n    // For documentation see https://nodejs.org/api/buffer.html\n    SEA.Buffer = SEA.Buffer || USE('./buffer');\n\n    // These SEA functions support now ony Promises or\n    // async/await (compatible) code, use those like Promises.\n    //\n    // Creates a wrapper library around Web Crypto API\n    // for various AES, ECDSA, PBKDF2 functions we called above.\n    // Calculate public key KeyID aka PGPv4 (result: 8 bytes as hex string)\n    SEA.keyid = SEA.keyid || (async (pub) => {\n      try {\n        // base64('base64(x):base64(y)') => shim.Buffer(xy)\n        const pb = shim.Buffer.concat(\n          pub.replace(/-/g, '+').replace(/_/g, '/').split('.')\n          .map((t) => shim.Buffer.from(t, 'base64'))\n        )\n        // id is PGPv4 compliant raw key\n        const id = shim.Buffer.concat([\n          shim.Buffer.from([0x99, pb.length / 0x100, pb.length % 0x100]), pb\n        ])\n        const sha1 = await sha1hash(id)\n        const hash = shim.Buffer.from(sha1, 'binary')\n        return hash.toString('hex', hash.length - 8)  // 16-bit ID as hex\n      } catch (e) {\n        console.log(e)\n        throw e\n      }\n    });\n    // all done!\n    // Obviously it is missing MANY necessary features. This is only an alpha release.\n    // Please experiment with it, audit what I've done so far, and complain about what needs to be added.\n    // SEA should be a full suite that is easy and seamless to use.\n    // Again, scroll naer the top, where I provide an EXAMPLE of how to create a user and sign in.\n    // Once logged in, the rest of the code you just read handled automatically signing/validating data.\n    // But all other behavior needs to be equally easy, like opinionated ways of\n    // Adding friends (trusted public keys), sending private messages, etc.\n    // Cheers! Tell me what you think.\n    ((SEA.window||{}).GUN||{}).SEA = SEA;\n\n    module.exports = SEA\n    // -------------- END SEA MODULES --------------------\n    // -- BEGIN SEA+GUN MODULES: BUNDLED BY DEFAULT UNTIL OTHERS USE SEA ON OWN -------\n  })(USE, './sea');\n\n  ;USE(function(module){\n    var SEA = USE('./sea'), Gun, u;\n    if(SEA.window){\n      Gun = SEA.window.GUN || {chain:{}};\n    } else {\n      Gun = USE((u+'' == typeof MODULE?'.':'')+'./gun', 1);\n    }\n    SEA.GUN = Gun;\n\n    function User(root){ \n      this._ = {$: this};\n    }\n    User.prototype = (function(){ function F(){}; F.prototype = Gun.chain; return new F() }()) // Object.create polyfill\n    User.prototype.constructor = User;\n\n    // let's extend the gun chain with a `user` function.\n    // only one user can be logged in at a time, per gun instance.\n    Gun.chain.user = function(pub){\n      var gun = this, root = gun.back(-1), user;\n      if(pub){\n        pub = SEA.opt.pub((pub._||'')['#']) || pub;\n        return root.get('~'+pub);\n      }\n      if(user = root.back('user')){ return user }\n      var root = (root._), at = root, uuid = at.opt.uuid || lex;\n      (at = (user = at.user = gun.chain(new User))._).opt = {};\n      at.opt.uuid = function(cb){\n        var id = uuid(), pub = root.user;\n        if(!pub || !(pub = pub.is) || !(pub = pub.pub)){ return id }\n        id = '~' + pub + '/' + id;\n        if(cb && cb.call){ cb(null, id) }\n        return id;\n      }\n      return user;\n    }\n    function lex(){ return Gun.state().toString(36).replace('.','') }\n    Gun.User = User;\n    User.GUN = Gun;\n    User.SEA = Gun.SEA = SEA;\n    module.exports = User;\n  })(USE, './user');\n\n  ;USE(function(module){\n    var u, Gun = (''+u != typeof GUN)? (GUN||{chain:{}}) : USE((''+u === typeof MODULE?'.':'')+'./gun', 1);\n    Gun.chain.then = function(cb, opt){\n      var gun = this, p = (new Promise(function(res, rej){\n        gun.once(res, opt);\n      }));\n      return cb? p.then(cb) : p;\n    }\n  })(USE, './then');\n\n  ;USE(function(module){\n    var User = USE('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};\n\n    // Well first we have to actually create a user. That is what this function does.\n    User.prototype.create = function(...args){\n      var pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;\n      var alias = pair && (pair.pub || pair.epub) ? pair.pub : typeof args[0] === 'string' ? args[0] : null;\n      var pass = pair && (pair.pub || pair.epub) ? pair : alias && typeof args[1] === 'string' ? args[1] : null;\n      var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair\n      var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb\n      \n      var gun = this, cat = (gun._), root = gun.back(-1);\n      cb = cb || noop;\n      opt = opt || {};\n      if(false !== opt.check){\n        var err;\n        if(!alias){ err = \"No user.\" }\n        if((pass||'').length < 8){ err = \"Password too short!\" }\n        if(err){\n          cb({err: Gun.log(err)});\n          return gun;\n        }\n      }\n      if(cat.ing){\n        (cb || noop)({err: Gun.log(\"User is already being created or authenticated!\"), wait: true});\n        return gun;\n      }\n      cat.ing = true;\n      var act = {}, u;\n      act.a = function(pubs){\n        act.pubs = pubs;\n        if(pubs && !opt.already){\n          // If we can enforce that a user name is already taken, it might be nice to try, but this is not guaranteed.\n          var ack = {err: Gun.log('User already created!')};\n          cat.ing = false;\n          (cb || noop)(ack);\n          gun.leave();\n          return;\n        }\n        act.salt = String.random(64); // pseudo-randomly create a salt, then use PBKDF2 function to extend the password with it.\n        SEA.work(pass, act.salt, act.b); // this will take some short amount of time to produce a proof, which slows brute force attacks.\n      }\n      act.b = function(proof){\n        act.proof = proof;\n        pair ? act.c(pair) : SEA.pair(act.c) // generate a brand new key pair or use the existing.\n      }\n      act.c = function(pair){\n        var tmp\n        act.pair = pair || {};\n        if(tmp = cat.root.user){\n          tmp._.sea = pair;\n          tmp.is = {pub: pair.pub, epub: pair.epub, alias: alias};\n        }\n        // the user's public key doesn't need to be signed. But everything else needs to be signed with it! // we have now automated it! clean up these extra steps now!\n        act.data = {pub: pair.pub};\n        act.d();\n      }\n      act.d = function(){\n        act.data.alias = alias;\n        act.e();\n      }\n      act.e = function(){\n        act.data.epub = act.pair.epub; \n        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, act.proof, act.f, {raw:1}); // to keep the private key safe, we AES encrypt it with the proof of work!\n      }\n      act.f = function(auth){\n        act.data.auth = JSON.stringify({ek: auth, s: act.salt}); \n        act.g(act.data.auth);\n      }\n      act.g = function(auth){ var tmp;\n        act.data.auth = act.data.auth || auth;\n        root.get(tmp = '~'+act.pair.pub).put(act.data).on(act.h); // awesome, now we can actually save the user with their public key as their ID.\n        var link = {}; link[tmp] = {'#': tmp}; root.get('~@'+alias).put(link).get(tmp).on(act.i); // next up, we want to associate the alias with the public key. So we add it to the alias list.\n      }\n      act.h = function(data, key, msg, eve){\n        eve.off(); act.h.ok = 1; act.i();\n      }\n      act.i = function(data, key, msg, eve){\n        if(eve){ act.i.ok = 1; eve.off() }\n        if(!act.h.ok || !act.i.ok){ return }\n        cat.ing = false;\n        cb({ok: 0, pub: act.pair.pub}); // callback that the user has been created. (Note: ok = 0 because we didn't wait for disk to ack)\n        if(noop === cb){ pair ? gun.auth(pair) : gun.auth(alias, pass) } // if no callback is passed, auto-login after signing up.\n      }\n      root.get('~@'+alias).once(act.a);\n      return gun;\n    }\n    User.prototype.leave = function(opt, cb){\n      var gun = this, user = (gun.back(-1)._).user;\n      if(user){\n        delete user.is;\n        delete user._.is;\n        delete user._.sea;\n      }\n      if(SEA.window){\n        try{var sS = {};\n        sS = SEA.window.sessionStorage;\n        delete sS.recall;\n        delete sS.pair;\n        }catch(e){};\n      }\n      return gun;\n    }\n  })(USE, './create');\n\n  ;USE(function(module){\n    var User = USE('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};\n    // now that we have created a user, we want to authenticate them!\n    User.prototype.auth = function(...args){ // TODO: this PR with arguments need to be cleaned up / refactored.\n      var pair = typeof args[0] === 'object' && (args[0].pub || args[0].epub) ? args[0] : typeof args[1] === 'object' && (args[1].pub || args[1].epub) ? args[1] : null;\n      var alias = !pair && typeof args[0] === 'string' ? args[0] : null;\n      var pass = (alias || (pair && !(pair.priv && pair.epriv))) && typeof args[1] === 'string' ? args[1] : null;\n      var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair\n      var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb\n      var retries = typeof opt.retries === 'number' ? opt.retries : 9;\n\n      var gun = this, cat = (gun._), root = gun.back(-1);\n      \n      if(cat.ing){\n        (cb || noop)({err: Gun.log(\"User is already being created or authenticated!\"), wait: true});\n        return gun;\n      }\n      cat.ing = true;\n      \n      var act = {}, u;\n      act.a = function(data){\n        if(!data){ return act.b() }\n        if(!data.pub){\n          var tmp = []; Object.keys(data).forEach(function(k){ if('_'==k){ return } tmp.push(data[k]) })\n          return act.b(tmp);\n        }\n        if(act.name){ return act.f(data) }\n        act.c((act.data = data).auth);\n      }\n      act.b = function(list){\n        var get = (act.list = (act.list||[]).concat(list||[])).shift();\n        if(u === get){\n          if(act.name){ return act.err('Your user account is not published for dApps to access, please consider syncing it online, or allowing local access by adding your device as a peer.') }\n          if(alias && retries--){\n            root.get('~@'+alias).once(act.a);\n            return;\n          }\n          return act.err('Wrong user or password.') \n        }\n        root.get(get).once(act.a);\n      }\n      act.c = function(auth){\n        if(u === auth){ return act.b() }\n        if('string' == typeof auth){ return act.c(obj_ify(auth)) } // in case of legacy\n        SEA.work(pass, (act.auth = auth).s, act.d, act.enc); // the proof of work is evidence that we've spent some time/effort trying to log in, this slows brute force.\n      }\n      act.d = function(proof){\n        SEA.decrypt(act.auth.ek, proof, act.e, act.enc);\n      }\n      act.e = function(half){\n        if(u === half){\n          if(!act.enc){ // try old format\n            act.enc = {encode: 'utf8'};\n            return act.c(act.auth);\n          } act.enc = null; // end backwards\n          return act.b();\n        }\n        act.half = half;\n        act.f(act.data);\n      }\n      act.f = function(pair){\n        var half = act.half || {}, data = act.data || {};\n        act.g(act.lol = {pub: pair.pub || data.pub, epub: pair.epub || data.epub, priv: pair.priv || half.priv, epriv: pair.epriv || half.epriv});\n      }\n      act.g = function(pair){\n        if(!pair || !pair.pub || !pair.epub){ return act.b() }\n        act.pair = pair;\n        var user = (root._).user, at = (user._);\n        var tmp = at.tag;\n        var upt = at.opt;\n        at = user._ = root.get('~'+pair.pub)._;\n        at.opt = upt;\n        // add our credentials in-memory only to our root user instance\n        user.is = {pub: pair.pub, epub: pair.epub, alias: alias || pair.pub};\n        at.sea = act.pair;\n        cat.ing = false;\n        try{if(pass && u == (obj_ify(cat.root.graph['~'+pair.pub].auth)||'')[':']){ opt.shuffle = opt.change = pass; } }catch(e){} // migrate UTF8 & Shuffle!\n        opt.change? act.z() : (cb || noop)(at);\n        if(SEA.window && ((gun.back('user')._).opt||opt).remember){\n          // TODO: this needs to be modular.\n          try{var sS = {};\n          sS = SEA.window.sessionStorage; // TODO: FIX BUG putting on `.is`!\n          sS.recall = true;\n          sS.pair = JSON.stringify(pair); // auth using pair is more reliable than alias/pass\n          }catch(e){}\n        }\n        try{\n          if(root._.tag.auth){ // auth handle might not be registered yet\n          (root._).on('auth', at) // TODO: Deprecate this, emit on user instead! Update docs when you do.\n          } else { setTimeout(function(){ (root._).on('auth', at) },1) } // if not, hackily add a timeout.\n          //at.on('auth', at) // Arrgh, this doesn't work without event \"merge\" code, but \"merge\" code causes stack overflow and crashes after logging in & trying to write data.\n        }catch(e){\n          Gun.log(\"Your 'auth' callback crashed with:\", e);\n        }\n      }\n      act.h = function(data){\n        if(!data){ return act.b() }\n        alias = data.alias\n        if(!alias)\n          alias = data.alias = \"~\" + pair.pub        \n        if(!data.auth){\n          return act.g(pair);\n        }\n        pair = null;\n        act.c((act.data = data).auth);\n      }\n      act.z = function(){\n        // password update so encrypt private key using new pwd + salt\n        act.salt = String.random(64); // pseudo-random\n        SEA.work(opt.change, act.salt, act.y);\n      }\n      act.y = function(proof){\n        SEA.encrypt({priv: act.pair.priv, epriv: act.pair.epriv}, proof, act.x, {raw:1});\n      }\n      act.x = function(auth){\n        act.w(JSON.stringify({ek: auth, s: act.salt}));\n      }\n      act.w = function(auth){\n        if(opt.shuffle){ // delete in future!\n          console.log('migrate core account from UTF8 & shuffle');\n          var tmp = {}; Object.keys(act.data).forEach(function(k){ tmp[k] = act.data[k] });\n          delete tmp._;\n          tmp.auth = auth;\n          root.get('~'+act.pair.pub).put(tmp);\n        } // end delete\n        root.get('~'+act.pair.pub).get('auth').put(auth, cb || noop);\n      }\n      act.err = function(e){\n        var ack = {err: Gun.log(e || 'User cannot be found!')};\n        cat.ing = false;\n        (cb || noop)(ack);\n      }\n      act.plugin = function(name){\n        if(!(act.name = name)){ return act.err() }\n        var tmp = [name];\n        if('~' !== name[0]){\n          tmp[1] = '~'+name;\n          tmp[2] = '~@'+name;\n        }\n        act.b(tmp);\n      }\n      if(pair){\n        if(pair.priv && pair.epriv)\n          act.g(pair);\n        else\n          root.get('~'+pair.pub).once(act.h);\n      } else\n      if(alias){\n        root.get('~@'+alias).once(act.a);\n      } else\n      if(!alias && !pass){\n        SEA.name(act.plugin);\n      }\n      return gun;\n    }\n    function obj_ify(o){\n      if('string' != typeof o){ return o }\n      try{o = JSON.parse(o);\n      }catch(e){o={}};\n      return o;\n    }\n  })(USE, './auth');\n\n  ;USE(function(module){\n    var User = USE('./user'), SEA = User.SEA, Gun = User.GUN;\n    User.prototype.recall = function(opt, cb){\n      var gun = this, root = gun.back(-1), tmp;\n      opt = opt || {};\n      if(opt && opt.sessionStorage){\n        if(SEA.window){\n          try{\n            var sS = {};\n            sS = SEA.window.sessionStorage; // TODO: FIX BUG putting on `.is`!\n            if(sS){\n              (root._).opt.remember = true;\n              ((gun.back('user')._).opt||opt).remember = true;\n              if(sS.recall || sS.pair) root.user().auth(JSON.parse(sS.pair), cb); // pair is more reliable than alias/pass\n            }\n          }catch(e){}\n        }\n        return gun;\n      }\n      /*\n        TODO: copy mhelander's expiry code back in.\n        Although, we should check with community,\n        should expiry be core or a plugin?\n      */\n      return gun;\n    }\n  })(USE, './recall');\n\n  ;USE(function(module){\n    var User = USE('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){};\n    User.prototype.pair = function(){\n      var user = this, proxy; // undeprecated, hiding with proxies.\n      try{ proxy = new Proxy({DANGER:'\\u2620'}, {get: function(t,p,r){\n        if(!user.is || !(user._||'').sea){ return }\n        return user._.sea[p];\n      }})}catch(e){}\n      return proxy;\n    }\n    // If authenticated user wants to delete his/her account, let's support it!\n    User.prototype.delete = async function(alias, pass, cb){\n      console.log(\"user.delete() IS DEPRECATED AND WILL BE MOVED TO A MODULE!!!\");\n      var gun = this, root = gun.back(-1), user = gun.back('user');\n      try {\n        user.auth(alias, pass, function(ack){\n          var pub = (user.is||{}).pub;\n          // Delete user data\n          user.map().once(function(){ this.put(null) });\n          // Wipe user data from memory\n          user.leave();\n          (cb || noop)({ok: 0});\n        });\n      } catch (e) {\n        Gun.log('User.delete failed! Error:', e);\n      }\n      return gun;\n    }\n    User.prototype.alive = async function(){\n      console.log(\"user.alive() IS DEPRECATED!!!\");\n      const gunRoot = this.back(-1)\n      try {\n        // All is good. Should we do something more with actual recalled data?\n        await authRecall(gunRoot)\n        return gunRoot._.user._\n      } catch (e) {\n        const err = 'No session!'\n        Gun.log(err)\n        throw { err }\n      }\n    }\n    User.prototype.trust = async function(user){\n      console.log(\"`.trust` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      // TODO: BUG!!! SEA `node` read listener needs to be async, which means core needs to be async too.\n      //gun.get('alice').get('age').trust(bob);\n      if (Gun.is(user)) {\n        user.get('pub').get((ctx, ev) => {\n          console.log(ctx, ev)\n        })\n      }\n      user.get('trust').get(path).put(theirPubkey);\n\n      // do a lookup on this gun chain directly (that gets bob's copy of the data)\n      // do a lookup on the metadata trust table for this path (that gets all the pubkeys allowed to write on this path)\n      // do a lookup on each of those pubKeys ON the path (to get the collab data \"layers\")\n      // THEN you perform Jachen's mix operation\n      // and return the result of that to...\n    }\n    User.prototype.grant = function(to, cb){\n      console.log(\"`.grant` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      var gun = this, user = gun.back(-1).user(), pair = user._.sea, path = '';\n      gun.back(function(at){ if(at.is){ return } path += (at.get||'') });\n      (async function(){\n      var enc, sec = await user.get('grant').get(pair.pub).get(path).then();\n      sec = await SEA.decrypt(sec, pair);\n      if(!sec){\n        sec = SEA.random(16).toString();\n        enc = await SEA.encrypt(sec, pair);\n        user.get('grant').get(pair.pub).get(path).put(enc);\n      }\n      var pub = to.get('pub').then();\n      var epub = to.get('epub').then();\n      pub = await pub; epub = await epub;\n      var dh = await SEA.secret(epub, pair);\n      enc = await SEA.encrypt(sec, dh);\n      user.get('grant').get(pub).get(path).put(enc, cb);\n      }());\n      return gun;\n    }\n    User.prototype.secret = function(data, cb){\n      console.log(\"`.secret` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!\");\n      var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = '';\n      gun.back(function(at){ if(at.is){ return } path += (at.get||'') });\n      (async function(){\n      var enc, sec = await user.get('trust').get(pair.pub).get(path).then();\n      sec = await SEA.decrypt(sec, pair);\n      if(!sec){\n        sec = SEA.random(16).toString();\n        enc = await SEA.encrypt(sec, pair);\n        user.get('trust').get(pair.pub).get(path).put(enc);\n      }\n      enc = await SEA.encrypt(data, sec);\n      gun.put(enc, cb);\n      }());\n      return gun;\n    }\n\n    /**\n     * returns the decrypted value, encrypted by secret\n     * @returns {Promise<any>}\n     // Mark needs to review 1st before officially supported\n    User.prototype.decrypt = function(cb) {\n      let gun = this,\n        path = ''\n      gun.back(function(at) {\n        if (at.is) {\n          return\n        }\n        path += at.get || ''\n      })\n      return gun\n        .then(async data => {\n          if (data == null) {\n            return\n          }\n          const user = gun.back(-1).user()\n          const pair = user.pair()\n          let sec = await user\n            .get('trust')\n            .get(pair.pub)\n            .get(path)\n          sec = await SEA.decrypt(sec, pair)\n          if (!sec) {\n            return data\n          }\n          let decrypted = await SEA.decrypt(data, sec)\n          return decrypted\n        })\n        .then(res => {\n          cb && cb(res)\n          return res\n        })\n    }\n    */\n    module.exports = User\n  })(USE, './share');\n\n  ;USE(function(module){\n    var SEA = USE('./sea'), S = USE('./settings'), noop = function() {}, u;\n    var Gun = (SEA.window||'').GUN || USE((''+u === typeof MODULE?'.':'')+'./gun', 1);\n    // After we have a GUN extension to make user registration/login easy, we then need to handle everything else.\n\n    // We do this with a GUN adapter, we first listen to when a gun instance is created (and when its options change)\n    Gun.on('opt', function(at){\n      if(!at.sea){ // only add SEA once per instance, on the \"at\" context.\n        at.sea = {own: {}};\n        at.on('put', check, at); // SEA now runs its firewall on HAM diffs, not all i/o.\n      }\n      this.to.next(at); // make sure to call the \"next\" middleware adapter.\n    });\n\n    // Alright, this next adapter gets run at the per node level in the graph database.\n    // correction: 2020 it gets run on each key/value pair in a node upon a HAM diff.\n    // This will let us verify that every property on a node has a value signed by a public key we trust.\n    // If the signature does not match, the data is just `undefined` so it doesn't get passed on.\n    // If it does match, then we transform the in-memory \"view\" of the data into its plain value (without the signature).\n    // Now NOTE! Some data is \"system\" data, not user data. Example: List of public keys, aliases, etc.\n    // This data is self-enforced (the value can only match its ID), but that is handled in the `security` function.\n    // From the self-enforced data, we can see all the edges in the graph that belong to a public key.\n    // Example: ~ASDF is the ID of a node with ASDF as its public key, signed alias and salt, and\n    // its encrypted private key, but it might also have other signed values on it like `profile = <ID>` edge.\n    // Using that directed edge's ID, we can then track (in memory) which IDs belong to which keys.\n    // Here is a problem: Multiple public keys can \"claim\" any node's ID, so this is dangerous!\n    // This means we should ONLY trust our \"friends\" (our key ring) public keys, not any ones.\n    // I have not yet added that to SEA yet in this alpha release. That is coming soon, but beware in the meanwhile!\n\n    function check(msg){ // REVISE / IMPROVE, NO NEED TO PASS MSG/EVE EACH SUB?\n      var eve = this, at = eve.as, put = msg.put, soul = put['#'], key = put['.'], val = put[':'], state = put['>'], id = msg['#'], tmp;\n      if(!soul || !key){ return }\n      if((msg._||'').faith && (at.opt||'').faith && 'function' == typeof msg._){\n        SEA.opt.pack(put, function(raw){\n        SEA.verify(raw, false, function(data){ // this is synchronous if false\n          put['='] = SEA.opt.unpack(data);\n          eve.to.next(msg);\n        })})\n        return \n      }\n      var no = function(why){ at.on('in', {'@': id, err: msg.err = why}) }; // exploit internal relay stun for now, maybe violates spec, but testing for now. // Note: this may be only the sharded message, not original batch.\n      //var no = function(why){ msg.ack(why) };\n      (msg._||'').DBG && ((msg._||'').DBG.c = +new Date);\n      if(0 <= soul.indexOf('<?')){ // special case for \"do not sync data X old\" forget\n        // 'a~pub.key/b<?9'\n        tmp = parseFloat(soul.split('<?')[1]||'');\n        if(tmp && (state < (Gun.state() - (tmp * 1000)))){ // sec to ms\n          (tmp = msg._) && (tmp.stun) && (tmp.stun--); // THIS IS BAD CODE! It assumes GUN internals do something that will probably change in future, but hacking in now.\n          return; // omit!\n        }\n      }\n      \n      if('~@' === soul){  // special case for shared system data, the list of aliases.\n        check.alias(eve, msg, val, key, soul, at, no); return;\n      }\n      if('~@' === soul.slice(0,2)){ // special case for shared system data, the list of public keys for an alias.\n        check.pubs(eve, msg, val, key, soul, at, no); return;\n      }\n      //if('~' === soul.slice(0,1) && 2 === (tmp = soul.slice(1)).split('.').length){ // special case, account data for a public key.\n      if(tmp = SEA.opt.pub(soul)){ // special case, account data for a public key.\n        check.pub(eve, msg, val, key, soul, at, no, at.user||'', tmp); return;\n      }\n      if(0 <= soul.indexOf('#')){ // special case for content addressing immutable hashed data.\n        check.hash(eve, msg, val, key, soul, at, no); return;\n      } \n      check.any(eve, msg, val, key, soul, at, no, at.user||''); return;\n      eve.to.next(msg); // not handled\n    }\n    check.hash = function(eve, msg, val, key, soul, at, no){ // mark unbuilt @i001962 's epic hex contrib!\n      SEA.work(val, null, function(data){\n        function hexToBase64(hexStr) {\n          let base64 = \"\";\n          for(let i = 0; i < hexStr.length; i++) {\n            base64 += !(i - 1 & 1) ? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16)) : \"\"}\n          return btoa(base64);}  \n        if(data && data === key.split('#').slice(-1)[0]){ return eve.to.next(msg) }\n          else if (data && data === hexToBase64(key.split('#').slice(-1)[0])){ \n          return eve.to.next(msg) }\n        no(\"Data hash not same as hash!\");\n      }, {name: 'SHA-256'});\n    }\n    check.alias = function(eve, msg, val, key, soul, at, no){ // Example: {_:#~@, ~@alice: {#~@alice}}\n      if(!val){ return no(\"Data must exist!\") } // data MUST exist\n      if('~@'+key === link_is(val)){ return eve.to.next(msg) } // in fact, it must be EXACTLY equal to itself\n      no(\"Alias not same!\"); // if it isn't, reject.\n    };\n    check.pubs = function(eve, msg, val, key, soul, at, no){ // Example: {_:#~@alice, ~asdf: {#~asdf}}\n      if(!val){ return no(\"Alias must exist!\") } // data MUST exist\n      if(key === link_is(val)){ return eve.to.next(msg) } // and the ID must be EXACTLY equal to its property\n      no(\"Alias not same!\"); // that way nobody can tamper with the list of public keys.\n    };\n    check.pub = async function(eve, msg, val, key, soul, at, no, user, pub){ var tmp // Example: {_:#~asdf, hello:'world'~fdsa}}\n      const raw = await S.parse(val) || {}\n      const verify = (certificate, certificant, cb) => {\n        if (certificate.m && certificate.s && certificant && pub)\n          // now verify certificate\n          return SEA.verify(certificate, pub, data => { // check if \"pub\" (of the graph owner) really issued this cert\n            if (u !== data && u !== data.e && msg.put['>'] && msg.put['>'] > parseFloat(data.e)) return no(\"Certificate expired.\") // certificate expired\n            // \"data.c\" = a list of certificants/certified users\n            // \"data.w\" = lex WRITE permission, in the future, there will be \"data.r\" which means lex READ permission\n            if (u !== data && data.c && data.w && (data.c === certificant || data.c.indexOf('*') > -1 || data.c.indexOf(certificant) > -1)) {\n              // ok, now \"certificant\" is in the \"certificants\" list, but is \"path\" allowed? Check path\n              let path = soul.indexOf('/') > -1 ? soul.replace(soul.substring(0, soul.indexOf('/') + 1), '') : ''\n              String.match = String.match || Gun.text.match\n              const w = Array.isArray(data.w) ? data.w : typeof data.w === 'object' || typeof data.w === 'string' ? [data.w] : []\n              for (const lex of w) {\n                if ((String.match(path, lex['#']) && String.match(key, lex['.'])) || (!lex['.'] && String.match(path, lex['#'])) || (!lex['#'] && String.match(key, lex['.'])) || String.match((path ? path + '/' + key : key), lex['#'] || lex)) {\n                  // is Certificant forced to present in Path\n                  if (lex['+'] && lex['+'].indexOf('*') > -1 && path && path.indexOf(certificant) == -1 && key.indexOf(certificant) == -1) return no(`Path \"${path}\" or key \"${key}\" must contain string \"${certificant}\".`)\n                  // path is allowed, but is there any WRITE block? Check it out\n                  if (data.wb && (typeof data.wb === 'string' || ((data.wb || {})['#']))) { // \"data.wb\" = path to the WRITE block\n                    var root = eve.as.root.$.back(-1)\n                    if (typeof data.wb === 'string' && '~' !== data.wb.slice(0, 1)) root = root.get('~' + pub)\n                    return root.get(data.wb).get(certificant).once(value => { // TODO: INTENT TO DEPRECATE.\n                      if (value && (value === 1 || value === true)) return no(`Certificant ${certificant} blocked.`)\n                      return cb(data)\n                    })\n                  }\n                  return cb(data)\n                }\n              }\n              return no(\"Certificate verification fail.\")\n            }\n          })\n        return\n      }\n      \n      if ('pub' === key && '~' + pub === soul) {\n        if (val === pub) return eve.to.next(msg) // the account MUST match `pub` property that equals the ID of the public key.\n        return no(\"Account not same!\")\n      }\n\n      if ((tmp = user.is) && tmp.pub && !raw['*'] && !raw['+'] && (pub === tmp.pub || (pub !== tmp.pub && ((msg._.msg || {}).opt || {}).cert))){\n        SEA.opt.pack(msg.put, packed => {\n          SEA.sign(packed, (user._).sea, async function(data) {\n            if (u === data) return no(SEA.err || 'Signature fail.')\n            msg.put[':'] = {':': tmp = SEA.opt.unpack(data.m), '~': data.s}\n            msg.put['='] = tmp\n  \n            // if writing to own graph, just allow it\n            if (pub === user.is.pub) {\n              if (tmp = link_is(val)) (at.sea.own[tmp] = at.sea.own[tmp] || {})[pub] = 1\n              JSON.stringifyAsync(msg.put[':'], function(err,s){\n                if(err){ return no(err || \"Stringify error.\") }\n                msg.put[':'] = s;\n                return eve.to.next(msg);\n              })\n              return\n            }\n  \n            // if writing to other's graph, check if cert exists then try to inject cert into put, also inject self pub so that everyone can verify the put\n            if (pub !== user.is.pub && ((msg._.msg || {}).opt || {}).cert) {\n              const cert = await S.parse(msg._.msg.opt.cert)\n              // even if cert exists, we must verify it\n              if (cert && cert.m && cert.s)\n                verify(cert, user.is.pub, _ => {\n                  msg.put[':']['+'] = cert // '+' is a certificate\n                  msg.put[':']['*'] = user.is.pub // '*' is pub of the user who puts\n                  JSON.stringifyAsync(msg.put[':'], function(err,s){\n                    if(err){ return no(err || \"Stringify error.\") }\n                    msg.put[':'] = s;\n                    return eve.to.next(msg);\n                  })\n                  return\n                })\n            }\n          }, {raw: 1})\n        })\n        return;\n      }\n\n      SEA.opt.pack(msg.put, packed => {\n        SEA.verify(packed, raw['*'] || pub, function(data){ var tmp;\n          data = SEA.opt.unpack(data);\n          if (u === data) return no(\"Unverified data.\") // make sure the signature matches the account it claims to be on. // reject any updates that are signed with a mismatched account.\n          if ((tmp = link_is(data)) && pub === SEA.opt.pub(tmp)) (at.sea.own[tmp] = at.sea.own[tmp] || {})[pub] = 1\n          \n          // check if cert ('+') and putter's pub ('*') exist\n          if (raw['+'] && raw['+']['m'] && raw['+']['s'] && raw['*'])\n            // now verify certificate\n            verify(raw['+'], raw['*'], _ => {\n              msg.put['='] = data;\n              return eve.to.next(msg);\n            })\n          else {\n            msg.put['='] = data;\n            return eve.to.next(msg);\n          }\n        });\n      })\n      return\n    };\n    check.any = function(eve, msg, val, key, soul, at, no, user){ var tmp, pub;\n      if(at.opt.secure){ return no(\"Soul missing public key at '\" + key + \"'.\") }\n      // TODO: Ask community if should auto-sign non user-graph data.\n      at.on('secure', function(msg){ this.off();\n        if(!at.opt.secure){ return eve.to.next(msg) }\n        no(\"Data cannot be changed.\");\n      }).on.on('secure', msg);\n      return;\n    }\n\n    var valid = Gun.valid, link_is = function(d,l){ return 'string' == typeof (l = valid(d)) && l }, state_ify = (Gun.state||'').ify;\n\n    var pubcut = /[^\\w_-]/; // anything not alphanumeric or _ -\n    SEA.opt.pub = function(s){\n      if(!s){ return }\n      s = s.split('~');\n      if(!s || !(s = s[1])){ return }\n      s = s.split(pubcut).slice(0,2);\n      if(!s || 2 != s.length){ return }\n      if('@' === (s[0]||'')[0]){ return }\n      s = s.slice(0,2).join('.');\n      return s;\n    }\n    SEA.opt.stringy = function(t){\n      // TODO: encrypt etc. need to check string primitive. Make as breaking change.\n    }\n    SEA.opt.pack = function(d,cb,k, n,s){ var tmp, f; // pack for verifying\n      if(SEA.opt.check(d)){ return cb(d) }\n      if(d && d['#'] && d['.'] && d['>']){ tmp = d[':']; f = 1 }\n      JSON.parseAsync(f? tmp : d, function(err, meta){\n        var sig = ((u !== (meta||'')[':']) && (meta||'')['~']); // or just ~ check?\n        if(!sig){ cb(d); return }\n        cb({m: {'#':s||d['#'],'.':k||d['.'],':':(meta||'')[':'],'>':d['>']||Gun.state.is(n, k)}, s: sig});\n      });\n    }\n    var O = SEA.opt;\n    SEA.opt.unpack = function(d, k, n){ var tmp;\n      if(u === d){ return }\n      if(d && (u !== (tmp = d[':']))){ return tmp }\n      k = k || O.fall_key; if(!n && O.fall_val){ n = {}; n[k] = O.fall_val }\n      if(!k || !n){ return }\n      if(d === n[k]){ return d }\n      if(!SEA.opt.check(n[k])){ return d }\n      var soul = (n && n._ && n._['#']) || O.fall_soul, s = Gun.state.is(n, k) || O.fall_state;\n      if(d && 4 === d.length && soul === d[0] && k === d[1] && fl(s) === fl(d[3])){\n        return d[2];\n      }\n      if(s < SEA.opt.shuffle_attack){\n        return d;\n      }\n    }\n    SEA.opt.shuffle_attack = 1546329600000; // Jan 1, 2019\n    var fl = Math.floor; // TODO: Still need to fix inconsistent state issue.\n    // TODO: Potential bug? If pub/priv key starts with `-`? IDK how possible.\n\n  })(USE, './index');\n}());\n"
  },
  {
    "path": "src/ask.js",
    "content": ";(function(){\n\n// request / response module, for asking and acking messages.\nrequire('./onto'); // depends upon onto!\nmodule.exports = function ask(cb, as){\n\tif(!this.on){ return }\n\tvar lack = (this.opt||{}).lack || 9000;\n\tif(!('function' == typeof cb)){\n\t\tif(!cb){ return }\n\t\tvar id = cb['#'] || cb, tmp = (this.tag||'')[id];\n\t\tif(!tmp){ return }\n\t\tif(as){\n\t\t\ttmp = this.on(id, as);\n\t\t\tclearTimeout(tmp.err);\n\t\t\ttmp.err = setTimeout(function(){ tmp.off() }, lack);\n\t\t}\n\t\treturn true;\n\t}\n\tvar id = (as && as['#']) || random(9);\n\tif(!cb){ return id }\n\tvar to = this.on(id, cb, as);\n\tto.err = to.err || setTimeout(function(){ to.off();\n\t\tto.next({err: \"Error: No ACK yet.\", lack: true});\n\t}, lack);\n\treturn id;\n}\nvar random = String.random || function(){ return Math.random().toString(36).slice(2) }\n\t\n}());"
  },
  {
    "path": "src/back.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nGun.chain.back = function(n, opt){ var tmp;\n\tn = n || 1;\n\tif(-1 === n || Infinity === n){\n\t\treturn this._.root.$;\n\t} else\n\tif(1 === n){\n\t\treturn (this._.back || this._).$;\n\t}\n\tvar gun = this, at = gun._;\n\tif(typeof n === 'string'){\n\t\tn = n.split('.');\n\t}\n\tif(n instanceof Array){\n\t\tvar i = 0, l = n.length, tmp = at;\n\t\tfor(i; i < l; i++){\n\t\t\ttmp = (tmp||empty)[n[i]];\n\t\t}\n\t\tif(u !== tmp){\n\t\t\treturn opt? gun : tmp;\n\t\t} else\n\t\tif((tmp = at.back)){\n\t\t\treturn tmp.$.back(n, opt);\n\t\t}\n\t\treturn;\n\t}\n\tif('function' == typeof n){\n\t\tvar yes, tmp = {back: at};\n\t\twhile((tmp = tmp.back)\n\t\t&& u === (yes = n(tmp, opt))){}\n\t\treturn yes;\n\t}\n\tif('number' == typeof n){\n\t\treturn (at.back || at).$.back(n - 1);\n\t}\n\treturn this;\n}\nvar empty = {}, u;\n\t\n}());"
  },
  {
    "path": "src/book.js",
    "content": ";(function(){\n\n// TODO: BUG! Unbuild will make these globals... CHANGE unbuild to wrap files in a function.\n// Book is a replacement for JS objects, maps, dictionaries.\nvar sT = setTimeout, B = sT.Book || (sT.Book = function(text){\n\tvar b = function book(word, is){\n\t\tvar has = b.all[word], p;\n\t\tif(is === undefined){ return (has && has.is) || b.get(has || word) }\n\t\tif(has){\n\t\t\tif(p = has.page){\n\t\t\t\tp.size += size(is) - size(has.is);\n\t\t\t\tp.text = '';\n\t\t\t}\n\t\t\thas.text = '';\n\t\t\thas.is = is;\n\t\t\treturn b;\n\t\t}\n\t\t//b.all[word] = {is: word}; return b;\n\t\treturn b.set(word, is);\n\t};\n\t// TODO: if from text, preserve the separator symbol.\n\tb.list = [{from: text, size: (text||'').length, substring: sub, toString: to, book: b, get: b, read: list}];\n\tb.page = page;\n\tb.set = set;\n\tb.get = get;\n\tb.all = {};\n\treturn b;\n}), PAGE = 2**12;\n\nfunction page(word){\n\tvar b = this, l = b.list, i = spot(word, l, b.parse), p = l[i];\n\tif('string' == typeof p){ l[i] = p = {size: -1, first: b.parse? b.parse(p) : p, substring: sub, toString: to, book: b, get: b, read: list} } // TODO: test, how do we arrive at this condition again?\n\t//p.i = i;\n\treturn p;\n\t// TODO: BUG! What if we get the page, it turns out to be too big & split, we must then RE get the page!\n}\nfunction get(word){\n\tif(!word){ return }\n\tif(undefined !== word.is){ return word.is } // JS falsey values!\n\tvar b = this, has = b.all[word];\n\tif(has){ return has.is }\n\t// get does an exact match, so we would have found it already, unless parseless page:\n\tvar page = b.page(word), l, has, a, i;\n\tif(!page || !page.from){ return } // no parseless data\n\treturn got(word, page);\n}\nfunction got(word, page){\n\tvar b = page.book, l, has, a, i;\n\tif(l = from(page)){ has = l[got.i = i = spot(word, l, B.decode)]; } // TODO: POTENTIAL BUG! This assumes that each word on a page uses the same serializer/formatter/structure. // TOOD: BUG!!! Not actually, but if we want to do non-exact radix-like closest-word lookups on a page, we need to check limbo & potentially sort first.\n\t// parseless may return -1 from actual value, so we may need to test both. // TODO: Double check? I think this is correct.\n\tif(has && word == has.word){ return (b.all[word] = has).is }\n\tif('string' != typeof has){ has = l[got.i = i+=1] }\n\tif(has && word == has.word){ return (b.all[word] = has).is }\n\ta = slot(has) // Escape!\n\tif(word != B.decode(a[0])){\n\t\thas = l[got.i = i+=1]; // edge case bug?\n\t\ta = slot(has); // edge case bug?\n\t\tif(word != B.decode(a[0])){ return }\n\t}\n\thas = l[i] = b.all[word] = {word: ''+word, is: B.decode(a[1]), page: page, substring: subt, toString: tot}; // TODO: convert to a JS value!!! Maybe index! TODO: BUG word needs a page!!!! TODO: Check for other types!!!\n\treturn has.is;\n}\n\nfunction spot(word, sorted, parse){ parse = parse || spot.no || (spot.no = function(t){ return t }); // TODO: BUG???? Why is there substring()||0 ? // TODO: PERF!!! .toString() is +33% faster, can we combine it with the export?\n\tvar L = sorted, min = 0, page, found, l = (word=''+word).length, max = L.length, i = max/2;\n\twhile(((word < (page = (parse(L[i=i>>0])||'').substring())) || ((parse(L[i+1])||'').substring() <= word)) && i != min){ // L[i] <= word < L[i+1]\n\t\ti += (page <= word)? (max - (min = i))/2 : -((max = i) - min)/2;\n\t}\n\treturn i;\n}\n\nfunction from(a, t, l){\n\tif('string' != typeof a.from){ return a.from }\n\t//(l = a.from = (t = a.from||'').substring(1, t.length-1).split(t[0])); // slot\n\t(l = a.from = slot(t = t||a.from||''));\n\treturn l;\n}\nfunction list(each){ each = each || function(x){return x} \n\tvar i = 0, l = sort(this), w, r = [], p = this.book.parse || function(){};\n\t//while(w = l[i++]){ r.push(each(slot(w)[1], p(w)||w, this)) }\n\twhile(w = l[i++]){ r.push(each(this.get(w = w.word||p(w)||w), w, this)) } // TODO: BUG! PERF?\n\treturn r;\n}\n\nfunction set(word, is){\n\tvar b = this, has = b.all[word];\n\tif(has){ return b(word, is) } // updates to in-memory items will always match exactly.\n\tvar page = b.page(word=''+word), tmp; // before we assume this is an insert tho, we need to check\n\tif(page && page.from){ // if it could be an update to an existing word from parseless.\n\t\tb.get(word);\n\t\tif(b.all[word]){ return b(word, is) }\n\t}\n\t// MUST be an insert:\n\thas = b.all[word] = {word: word, is: is, page: page, substring: subt, toString: tot};\n\tpage.first = (page.first < word)? page.first : word;\n\tif(!page.limbo){ (page.limbo = []) }\n\tpage.limbo.push(has);\n\tb(word, is);\n\tpage.size += size(word) + size(is);\n\tif((b.PAGE || PAGE) < page.size){ split(page, b) }\n\treturn b;\n}\n\nfunction split(p, b){ // TODO: use closest hash instead of half.\n\t//console.time();\n\tvar L = sort(p), l = L.length, i = l/2 >> 0, j = i, half = L[j], tmp;\n\t//console.timeEnd();\n\tvar next = {first: half.substring(), size: 0, substring: sub, toString: to, book: b, get: b, read: list}, f = next.from = [];\n\t//console.time();\n\twhile(tmp = L[i++]){\n\t\tf.push(tmp);\n\t\tnext.size += (tmp.is||'').length||1;\n\t\ttmp.page = next;\n\t}\n\t//console.timeEnd(); console.time();\n\tp.from = p.from.slice(0, j);\n\tp.size -= next.size;\n\tb.list.splice(spot(next.first, b.list)+1, 0, next); // TODO: BUG! Make sure next.first is decoded text. // TODO: BUG! spot may need parse too?\n\t//console.timeEnd();\n\tif(b.split){ b.split(next, p) }\n}\n\nfunction slot(t){ return heal((t=t||'').substring(1, t.length-1).split(t[0]), t[0]) } B.slot = slot; // TODO: check first=last & pass `s`.\nfunction heal(l, s){ var i, e;\n\tif(0 > (i = l.indexOf(''))){ return l } // ~700M ops/sec on 4KB of Math.random()s, even faster if escape does exist.\n\tif('' == l[0] && 1 == l.length){ return [] } // annoying edge cases! how much does this slow us down?\n\t//if((c=i+2+parseInt(l[i+1])) != c){ return [] } // maybe still faster than below?\n\tif((e=i+2+parseInt((e=l[i+1]).substring(0, e.indexOf('\"'))||e)) != e){ return [] } // NaN check in JS is weird.\n\tl[i] = l.slice(i, e).join(s||'|'); // rejoin the escaped value\n\treturn l.slice(0,i+1).concat(heal(l.slice(e), s)); // merge left with checked right.\n}\n\nfunction size(t){ return (t||'').length||1 } // bits/numbers less size? Bug or feature?\nfunction subt(i,j){ return this.word }\n//function tot(){ return this.text = this.text || \"'\"+(this.word)+\"'\"+(this.is)+\"'\" }\nfunction tot(){ var tmp = {};\n\t//if((tmp = this.page) && tmp.saving){ delete tmp.book.all[this.word]; } // TODO: BUG! Book can't know about RAD, this was from RAD, so this MIGHT be correct but we need to refactor. Make sure to add tests that will re-trigger this.\n\treturn this.text = this.text || \":\"+B.encode(this.word)+\":\"+B.encode(this.is)+\":\";\n\ttmp[this.word] = this.is;\n\treturn this.text = this.text || B.encode(tmp,'|',':').slice(1,-1);\n\t//return this.text = this.text || \"'\"+(this.word)+\"'\"+(this.is)+\"'\";\n}\nfunction sub(i,j){ return (this.first||this.word||B.decode((from(this)||'')[0]||'')).substring(i,j) }\nfunction to(){ return this.text = this.text || text(this) }\nfunction text(p){ // PERF: read->[*] : text->\"*\" no edit waste 1 time perf.\n\tif(p.limbo){ sort(p) } // TODO: BUG? Empty page meaning? undef, '', '||'?\n\treturn ('string' == typeof p.from)? p.from : '|'+(p.from||[]).join('|')+'|';\n}\n\nfunction sort(p, l){\n\tvar f = p.from = ('string' == typeof p.from)? slot(p.from) : p.from||[];\n\tif(!(l = l || p.limbo)){ return f }\n\treturn mix(p).sort(function(a,b){\n\t\treturn (a.word||B.decode(''+a)) < (b.word||B.decode(''+b))? -1:1;\n\t});\n}\nfunction mix(p, l){ // TODO: IMPROVE PERFORMANCE!!!! l[j] = i is 5X+ faster than .push(\n\tl = l || p.limbo || []; p.limbo = null;\n\tvar j = 0, i, f = p.from;\n\twhile(i = l[j++]){\n\t\tif(got(i.word, p)){\n\t\t\tf[got.i] = i; // TODO: Trick: allow for a GUN'S HAM CRDT hook here.\n\t\t} else {\n\t\t\tf.push(i); \n\t\t}\n\t}\n\treturn f;\n}\n\nB.encode = function(d, s, u){ s = s || \"|\"; u = u || String.fromCharCode(32);\n\tswitch(typeof d){\n\t\tcase 'string': // text\n\t\t\tvar i = d.indexOf(s), c = 0;\n\t\t\twhile(i != -1){ c++; i = d.indexOf(s, i+1) }\n\t\t\treturn (c?s+c:'')+ '\"' + d;\n\t\tcase 'number': return (d < 0)? ''+d : '+'+d;\n\t\tcase 'boolean': return d? '+' : '-';\n\t\tcase 'object': if(!d){ return ' ' } // TODO: BUG!!! Nested objects don't slot correctly\n\t\t\tvar l = Object.keys(d).sort(), i = 0, t = s, k, v;\n\t\t\twhile(k = l[i++]){ t += u+B.encode(k,s,u)+u+B.encode(d[k],s,u)+u+s }\n\t\t\treturn t;\n\t}\n}\nB.decode = function(t, s){ s = s || \"|\";\n\tif('string' != typeof t){ return }\n\tswitch(t){ case ' ': return null; case '-': return false; case '+': return true; }\n\tswitch(t[0]){\n\t\tcase '-': case '+': return parseFloat(t);\n\t\tcase '\"': return t.slice(1);\n\t}\n\treturn t.slice(t.indexOf('\"')+1);\n}\n\nB.hash = function(s, c){ // via SO\n\tif(typeof s !== 'string'){ return }\n  c = c || 0; // CPU schedule hashing by\n  if(!s.length){ return c }\n  for(var i=0,l=s.length,n; i<l; ++i){\n    n = s.charCodeAt(i);\n    c = ((c<<5)-c)+n;\n    c |= 0;\n  }\n  return c;\n}\n\nfunction record(key, val){ return key+B.encode(val)+\"%\"+key.length }\nfunction decord(t){\n\tvar o = {}, i = t.lastIndexOf(\"%\"), c = parseFloat(t.slice(i+1));\n\to[t.slice(0,c)] = B.decode(t.slice(c,i));\n\treturn o;\n}\n\ntry{module.exports=B}catch(e){}\n\t\n}());"
  },
  {
    "path": "src/chain.js",
    "content": ";(function(){\n\n// WARNING: GUN is very simple, but the JavaScript chaining API around GUN\n// is complicated and was extremely hard to build. If you port GUN to another\n// language, consider implementing an easier API to build.\nvar Gun = require('./root');\nGun.chain.chain = function(sub){\n\tvar gun = this, at = gun._, chain = new (sub || gun).constructor(gun), cat = chain._, root;\n\tcat.root = root = at.root;\n\tcat.id = ++root.once;\n\tcat.back = gun._;\n\tcat.on = Gun.on;\n\tcat.on('in', Gun.on.in, cat); // For 'in' if I add my own listeners to each then I MUST do it before in gets called. If I listen globally for all incoming data instead though, regardless of individual listeners, I can transform the data there and then as well.\n\tcat.on('out', Gun.on.out, cat); // However for output, there isn't really the global option. I must listen by adding my own listener individually BEFORE this one is ever called.\n\treturn chain;\n}\n\nfunction output(msg){\n\tvar put, get, at = this.as, back = at.back, root = at.root, tmp;\n\tif(!msg.$){ msg.$ = at.$ }\n\tthis.to.next(msg);\n\tif(at.err){ at.on('in', {put: at.put = u, $: at.$}); return }\n\tif(get = msg.get){\n\t\t/*if(u !== at.put){\n\t\t\tat.on('in', at);\n\t\t\treturn;\n\t\t}*/\n\t\tif(root.pass){ root.pass[at.id] = at; } // will this make for buggy behavior elsewhere?\n\t\tif(at.lex){ Object.keys(at.lex).forEach(function(k){ tmp[k] = at.lex[k] }, tmp = msg.get = msg.get || {}) }\n\t\tif(get['#'] || at.soul){\n\t\t\tget['#'] = get['#'] || at.soul;\n\t\t\t//root.graph[get['#']] = root.graph[get['#']] || {_:{'#':get['#'],'>':{}}};\n\t\t\tmsg['#'] || (msg['#'] = text_rand(9)); // A3120 ?\n\t\t\tback = (root.$.get(get['#'])._);\n\t\t\tif(!(get = get['.'])){ // soul\n\t\t\t\ttmp = back.ask && back.ask['']; // check if we have already asked for the full node\n\t\t\t\t(back.ask || (back.ask = {}))[''] = back; // add a flag that we are now.\n\t\t\t\tif(u !== back.put){ // if we already have data,\n\t\t\t\t\tback.on('in', back); // send what is cached down the chain\n\t\t\t\t\tif(tmp){ return } // and don't ask for it again.\n\t\t\t\t}\n\t\t\t\tmsg.$ = back.$;\n\t\t\t} else\n\t\t\tif(obj_has(back.put, get)){ // TODO: support #LEX !\n\t\t\t\ttmp = back.ask && back.ask[get];\n\t\t\t\t(back.ask || (back.ask = {}))[get] = back.$.get(get)._;\n\t\t\t\tback.on('in', {get: get, put: {'#': back.soul, '.': get, ':': back.put[get], '>': state_is(root.graph[back.soul], get)}});\n\t\t\t\tif(tmp){ return }\n\t\t\t}\n\t\t\t\t/*put = (back.$.get(get)._);\n\t\t\t\tif(!(tmp = put.ack)){ put.ack = -1 }\n\t\t\t\tback.on('in', {\n\t\t\t\t\t$: back.$,\n\t\t\t\t\tput: Gun.state.ify({}, get, Gun.state(back.put, get), back.put[get]),\n\t\t\t\t\tget: back.get\n\t\t\t\t});\n\t\t\t\tif(tmp){ return }\n\t\t\t} else\n\t\t\tif('string' != typeof get){\n\t\t\t\tvar put = {}, meta = (back.put||{})._;\n\t\t\t\tGun.obj.map(back.put, function(v,k){\n\t\t\t\t\tif(!Gun.text.match(k, get)){ return }\n\t\t\t\t\tput[k] = v;\n\t\t\t\t})\n\t\t\t\tif(!Gun.obj.empty(put)){\n\t\t\t\t\tput._ = meta;\n\t\t\t\t\tback.on('in', {$: back.$, put: put, get: back.get})\n\t\t\t\t}\n\t\t\t\tif(tmp = at.lex){\n\t\t\t\t\ttmp = (tmp._) || (tmp._ = function(){});\n\t\t\t\t\tif(back.ack < tmp.ask){ tmp.ask = back.ack }\n\t\t\t\t\tif(tmp.ask){ return }\n\t\t\t\t\ttmp.ask = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\t*/\n\t\t\troot.ask(ack, msg); // A3120 ?\n\t\t\treturn root.on('in', msg);\n\t\t}\n\t\t//if(root.now){ root.now[at.id] = root.now[at.id] || true; at.pass = {} }\n\t\tif(get['.']){\n\t\t\tif(at.get){\n\t\t\t\tmsg = {get: {'.': at.get}, $: at.$};\n\t\t\t\t(back.ask || (back.ask = {}))[at.get] = msg.$._; // TODO: PERFORMANCE? More elegant way?\n\t\t\t\treturn back.on('out', msg);\n\t\t\t}\n\t\t\tmsg = {get: at.lex? msg.get : {}, $: at.$};\n\t\t\treturn back.on('out', msg);\n\t\t}\n\t\t(at.ask || (at.ask = {}))[''] = at;\t //at.ack = at.ack || -1;\n\t\tif(at.get){\n\t\t\tget['.'] = at.get;\n\t\t\t(back.ask || (back.ask = {}))[at.get] = msg.$._; // TODO: PERFORMANCE? More elegant way?\n\t\t\treturn back.on('out', msg);\n\t\t}\n\t}\n\treturn back.on('out', msg);\n}; Gun.on.out = output;\n\nfunction input(msg, cat){ cat = cat || this.as; // TODO: V8 may not be able to optimize functions with different parameter calls, so try to do benchmark to see if there is any actual difference.\n\tvar root = cat.root, gun = msg.$ || (msg.$ = cat.$), at = (gun||'')._ || empty, tmp = msg.put||'', soul = tmp['#'], key = tmp['.'], change = (u !== tmp['='])? tmp['='] : tmp[':'], state = tmp['>'] || -Infinity, sat; // eve = event, at = data at, cat = chain at, sat = sub at (children chains).\n\tif(u !== msg.put && (u === tmp['#'] || u === tmp['.'] || (u === tmp[':'] && u === tmp['=']) || u === tmp['>'])){ // convert from old format\n\t\tif(!valid(tmp)){\n\t\t\tif(!(soul = ((tmp||'')._||'')['#'])){ console.log(\"chain not yet supported for\", tmp, '...', msg, cat); return; }\n\t\t\tgun = cat.root.$.get(soul);\n\t\t\treturn setTimeout.each(Object.keys(tmp).sort(), function(k){ // TODO: .keys( is slow // BUG? ?Some re-in logic may depend on this being sync?\n\t\t\t\tif('_' == k || u === (state = state_is(tmp, k))){ return }\n\t\t\t\tcat.on('in', {$: gun, put: {'#': soul, '.': k, '=': tmp[k], '>': state}, VIA: msg});\n\t\t\t});\n\t\t}\n\t\tcat.on('in', {$: at.back.$, put: {'#': soul = at.back.soul, '.': key = at.has || at.get, '=': tmp, '>': state_is(at.back.put, key)}, via: msg}); // TODO: This could be buggy! It assumes/approxes data, other stuff could have corrupted it.\n\t\treturn;\n\t}\n\tif((msg.seen||'')[cat.id]){ return } (msg.seen || (msg.seen = function(){}))[cat.id] = cat; // help stop some infinite loops\n\n\tif(cat !== at){ // don't worry about this when first understanding the code, it handles changing contexts on a message. A soul chain will never have a different context.\n\t\tObject.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {}); // make copy of message\n\t\ttmp.get = cat.get || tmp.get;\n\t\tif(!cat.soul && !cat.has){ // if we do not recognize the chain type\n\t\t\ttmp.$$$ = tmp.$$$ || cat.$; // make a reference to wherever it came from.\n\t\t} else\n\t\tif(at.soul){ // a has (property) chain will have a different context sometimes if it is linked (to a soul chain). Anything that is not a soul or has chain, will always have different contexts.\n\t\t\ttmp.$ = cat.$;\n\t\t\ttmp.$$ = tmp.$$ || at.$;\n\t\t}\n\t\tmsg = tmp; // use the message with the new context instead;\n\t}\n\tunlink(msg, cat);\n\n\tif(((cat.soul/* && (cat.ask||'')['']*/) || msg.$$) && state >= state_is(root.graph[soul], key)){ // The root has an in-memory cache of the graph, but if our peer has asked for the data then we want a per deduplicated chain copy of the data that might have local edits on it.\n\t\t(tmp = root.$.get(soul)._).put = state_ify(tmp.put, key, state, change, soul);\n\t}\n\tif(!at.soul /*&& (at.ask||'')['']*/ && state >= state_is(root.graph[soul], key) && (sat = (root.$.get(soul)._.next||'')[key])){ // Same as above here, but for other types of chains. // TODO: Improve perf by preventing echoes recaching.\n\t\tsat.put = change; // update cache\n\t\tif('string' == typeof (tmp = valid(change))){\n\t\t\tsat.put = root.$.get(tmp)._.put || change; // share same cache as what we're linked to.\n\t\t}\n\t}\n\n\tthis.to && this.to.next(msg); // 1st API job is to call all chain listeners.\n\t// TODO: Make input more reusable by only doing these (some?) calls if we are a chain we recognize? This means each input listener would be responsible for when listeners need to be called, which makes sense, as they might want to filter.\n\tcat.any && setTimeout.each(Object.keys(cat.any), function(any){ (any = cat.any[any]) && any(msg) },0,99); // 1st API job is to call all chain listeners. // TODO: .keys( is slow // BUG: Some re-in logic may depend on this being sync.\n\tcat.echo && setTimeout.each(Object.keys(cat.echo), function(lat){ (lat = cat.echo[lat]) && lat.on('in', msg) },0,99); // & linked at chains // TODO: .keys( is slow // BUG: Some re-in logic may depend on this being sync.\n\n\tif(((msg.$$||'')._||at).soul){ // comments are linear, but this line of code is non-linear, so if I were to comment what it does, you'd have to read 42 other comments first... but you can't read any of those comments until you first read this comment. What!? // shouldn't this match link's check?\n\t\t// is there cases where it is a $$ that we do NOT want to do the following? \n\t\tif((sat = cat.next) && (sat = sat[key])){ // TODO: possible trick? Maybe have `ionmap` code set a sat? // TODO: Maybe we should do `cat.ask` instead? I guess does not matter.\n\t\t\ttmp = {}; Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] });\n\t\t\ttmp.$ = (msg.$$||msg.$).get(tmp.get = key); delete tmp.$$; delete tmp.$$$;\n\t\t\tsat.on('in', tmp);\n\t\t}\n\t}\n\n\tlink(msg, cat);\n}; Gun.on.in = input;\n\nfunction link(msg, cat){ cat = cat || this.as || msg.$._;\n\tif(msg.$$ && this !== Gun.on){ return } // $$ means we came from a link, so we are at the wrong level, thus ignore it unless overruled manually by being called directly.\n\tif(!msg.put || cat.soul){ return } // But you cannot overrule being linked to nothing, or trying to link a soul chain - that must never happen.\n\tvar put = msg.put||'', link = put['=']||put[':'], tmp;\n\tvar root = cat.root, tat = root.$.get(put['#']).get(put['.'])._;\n\tif('string' != typeof (link = valid(link))){\n\t\tif(this === Gun.on){ (tat.echo || (tat.echo = {}))[cat.id] = cat } // allow some chain to explicitly force linking to simple data.\n\t\treturn; // by default do not link to data that is not a link.\n\t}\n\tif((tat.echo || (tat.echo = {}))[cat.id] // we've already linked ourselves so we do not need to do it again. Except... (annoying implementation details)\n\t\t&& !(root.pass||'')[cat.id]){ return } // if a new event listener was added, we need to make a pass through for it. The pass will be on the chain, not always the chain passed down. \n\tif(tmp = root.pass){ if(tmp[link+cat.id]){ return } tmp[link+cat.id] = 1 } // But the above edge case may \"pass through\" on a circular graph causing infinite passes, so we hackily add a temporary check for that.\n\n\t(tat.echo||(tat.echo={}))[cat.id] = cat; // set ourself up for the echo! // TODO: BUG? Echo to self no longer causes problems? Confirm.\n\n\tif(cat.has){ cat.link = link }\n\tvar sat = root.$.get(tat.link = link)._; // grab what we're linking to.\n\t(sat.echo || (sat.echo = {}))[tat.id] = tat; // link it.\n\tvar tmp = cat.ask||''; // ask the chain for what needs to be loaded next!\n\tif(tmp[''] || cat.lex){ // we might need to load the whole thing // TODO: cat.lex probably has edge case bugs to it, need more test coverage.\n\t\tsat.on('out', {get: {'#': link}});\n\t}\n\tsetTimeout.each(Object.keys(tmp), function(get, sat){ // if sub chains are asking for data. // TODO: .keys( is slow // BUG? ?Some re-in logic may depend on this being sync?\n\t\tif(!get || !(sat = tmp[get])){ return }\n\t\tsat.on('out', {get: {'#': link, '.': get}}); // go get it.\n\t},0,99);\n}; Gun.on.link = link;\n\nfunction unlink(msg, cat){ // ugh, so much code for seemingly edge case behavior.\n\tvar put = msg.put||'', change = (u !== put['='])? put['='] : put[':'], root = cat.root, link, tmp;\n\tif(u === change){ // 1st edge case: If we have a brand new database, no data will be found.\n\t\t// TODO: BUG! because emptying cache could be async from below, make sure we are not emptying a newer cache. So maybe pass an Async ID to check against?\n\t\t// TODO: BUG! What if this is a map? // Warning! Clearing things out needs to be robust against sync/async ops, or else you'll see `map val get put` test catastrophically fail because map attempts to link when parent graph is streamed before child value gets set. Need to differentiate between lack acks and force clearing.\n\t\tif(cat.soul && u !== cat.put){ return } // data may not be found on a soul, but if a soul already has data, then nothing can clear the soul as a whole.\n\t\t//if(!cat.has){ return }\n\t\ttmp = (msg.$$||msg.$||'')._||'';\n\t\tif(msg['@'] && (u !== tmp.put || u !== cat.put)){ return } // a \"not found\" from other peers should not clear out data if we have already found it.\n\t\t//if(cat.has && u === cat.put && !(root.pass||'')[cat.id]){ return } // if we are already unlinked, do not call again, unless edge case. // TODO: BUG! This line should be deleted for \"unlink deeply nested\".\n\t\tif(link = cat.link || msg.linked){\n\t\t\tdelete (root.$.get(link)._.echo||'')[cat.id];\n\t\t}\n\t\tif(cat.has){ // TODO: Empty out links, maps, echos, acks/asks, etc.?\n\t\t\tcat.link = null;\n\t\t}\n\t\tcat.put = u; // empty out the cache if, for example, alice's car's color no longer exists (relative to alice) if alice no longer has a car.\n\t\t// TODO: BUG! For maps, proxy this so the individual sub is triggered, not all subs.\n\t\tsetTimeout.each(Object.keys(cat.next||''), function(get, sat){ // empty out all sub chains. // TODO: .keys( is slow // BUG? ?Some re-in logic may depend on this being sync? // TODO: BUG? This will trigger deeper put first, does put logic depend on nested order? // TODO: BUG! For map, this needs to be the isolated child, not all of them.\n\t\t\tif(!(sat = cat.next[get])){ return }\n\t\t\t//if(cat.has && u === sat.put && !(root.pass||'')[sat.id]){ return } // if we are already unlinked, do not call again, unless edge case. // TODO: BUG! This line should be deleted for \"unlink deeply nested\".\n\t\t\tif(link){ delete (root.$.get(link).get(get)._.echo||'')[sat.id] }\n\t\t\tsat.on('in', {get: get, put: u, $: sat.$}); // TODO: BUG? Add recursive seen check?\n\t\t},0,99);\n\t\treturn;\n\t}\n\tif(cat.soul){ return } // a soul cannot unlink itself.\n\tif(msg.$$){ return } // a linked chain does not do the unlinking, the sub chain does. // TODO: BUG? Will this cancel maps?\n\tlink = valid(change); // need to unlink anytime we are not the same link, though only do this once per unlink (and not on init).\n\ttmp = msg.$._||'';\n\tif(link === tmp.link || (cat.has && !tmp.link)){\n\t\tif((root.pass||'')[cat.id] && 'string' !== typeof link){\n\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\t}\n\tdelete (tmp.echo||'')[cat.id];\n\tunlink({get: cat.get, put: u, $: msg.$, linked: msg.linked = msg.linked || tmp.link}, cat); // unlink our sub chains.\n}; Gun.on.unlink = unlink;\n\nfunction ack(msg, ev){\n\t//if(!msg['%'] && (this||'').off){ this.off() } // do NOT memory leak, turn off listeners! Now handled by .ask itself\n\t// manhattan:\n\tvar as = this.as, at = as.$._, root = at.root, get = as.get||'', tmp = (msg.put||'')[get['#']]||'';\n\tif(!msg.put || ('string' == typeof get['.'] && u === tmp[get['.']])){\n\t\tif(u !== at.put){ return }\n\t\tif(!at.soul && !at.has){ return } // TODO: BUG? For now, only core-chains will handle not-founds, because bugs creep in if non-core chains are used as $ but we can revisit this later for more powerful extensions.\n\t\tat.ack = (at.ack || 0) + 1;\n\t\tat.on('in', {\n\t\t\tget: at.get,\n\t\t\tput: at.put = u,\n\t\t\t$: at.$,\n\t\t\t'@': msg['@']\n\t\t});\n\t\t/*(tmp = at.Q) && setTimeout.each(Object.keys(tmp), function(id){ // TODO: Temporary testing, not integrated or being used, probably delete.\n\t\t\tObject.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {}); tmp['@'] = id; // copy message\n\t\t\troot.on('in', tmp);\n\t\t}); delete at.Q;*/\n\t\treturn;\n\t}\n\t(msg._||{}).miss = 1;\n\tGun.on.put(msg);\n\treturn; // eom\n}\n\nvar empty = {}, u, text_rand = String.random, valid = Gun.valid, obj_has = function(o, k){ return o && Object.prototype.hasOwnProperty.call(o, k) }, state = Gun.state, state_is = state.is, state_ify = state.ify;\n\t\n}());"
  },
  {
    "path": "src/core.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nrequire('./chain');\nrequire('./back');\nrequire('./put');\nrequire('./get');\nmodule.exports = Gun;\n\t\n}());"
  },
  {
    "path": "src/dup.js",
    "content": ";(function(){\n\nrequire('./shim');\nfunction Dup(opt){\n\tvar dup = {s:{}}, s = dup.s;\n\topt = opt || {max: 999, age: 1000 * 9};//*/ 1000 * 9 * 3};\n\tdup.check = function(id){\n\t\tif(!s[id]){ return false }\n\t\treturn dt(id);\n\t}\n\tvar dt = dup.track = function(id){\n\t\tvar it = s[id] || (s[id] = {});\n\t\tit.was = dup.now = +new Date;\n\t\tif(!dup.to){ dup.to = setTimeout(dup.drop, opt.age + 9) }\n\t\tif(dt.ed){ dt.ed(id) }\n\t\treturn it;\n\t}\n\tdup.drop = function(age){\n\t\tdup.to = null;\n\t\tdup.now = +new Date;\n\t\tvar l = Object.keys(s);\n\t\tconsole.STAT && console.STAT(dup.now, +new Date - dup.now, 'dup drop keys'); // prev ~20% CPU 7% RAM 300MB // now ~25% CPU 7% RAM 500MB\n\t\tsetTimeout.each(l, function(id){ var it = s[id]; // TODO: .keys( is slow?\n\t\t\tif(it && (age || opt.age) > (dup.now - it.was)){ return }\n\t\t\tdelete s[id];\n\t\t},0,99);\n\t}\n\treturn dup;\n}\nmodule.exports = Dup;\n\t\n}());"
  },
  {
    "path": "src/get.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nGun.chain.get = function(key, cb, as){\n\tvar gun, tmp;\n\tif(typeof key === 'string'){\n\t\tif(key.length == 0) {\t\n\t\t\t(gun = this.chain())._.err = {err: Gun.log('0 length key!', key)};\n\t\t\tif(cb){ cb.call(gun, gun._.err) }\n\t\t\treturn gun;\n\t\t}\n\t\tvar back = this, cat = back._;\n\t\tvar next = cat.next || empty;\n\t\tif(!(gun = next[key])){\n\t\t\tgun = key && cache(key, back);\n\t\t}\n\t\tgun = gun && gun.$;\n\t} else\n\tif('function' == typeof key){\n\t\tif(true === cb){ return soul(this, key, cb, as), this }\n\t\tgun = this;\n\t\tvar cat = gun._, opt = cb || {}, root = cat.root, id;\n\t\topt.at = cat;\n\t\topt.ok = key;\n\t\tvar wait = {}; // can we assign this to the at instead, like in once?\n\t\t//var path = []; cat.$.back(at => { at.get && path.push(at.get.slice(0,9))}); path = path.reverse().join('.');\n\t\tfunction any(msg, eve, f){\n\t\t\tif(any.stun){ return }\n\t\t\tif((tmp = root.pass) && !tmp[id]){ return }\n\t\t\tvar at = msg.$._, sat = (msg.$$||'')._, data = (sat||at).put, odd = (!at.has && !at.soul), test = {}, link, tmp;\n\t\t\tif(odd || u === data){ // handles non-core\n\t\t\t\tdata = (u === ((tmp = msg.put)||'')['='])? (u === (tmp||'')[':'])? tmp : tmp[':'] : tmp['='];\n\t\t\t}\n\t\t\tif(link = ('string' == typeof (tmp = Gun.valid(data)))){\n\t\t\t\tdata = (u === (tmp = root.$.get(tmp)._.put))? opt.not? u : data : tmp;\n\t\t\t}\n\t\t\tif(opt.not && u === data){ return }\n\t\t\tif(u === opt.stun){\n\t\t\t\tif((tmp = root.stun) && tmp.on){\n\t\t\t\t\tcat.$.back(function(a){ // our chain stunned?\n\t\t\t\t\t\ttmp.on(''+a.id, test = {});\n\t\t\t\t\t\tif((test.run || 0) < any.id){ return test } // if there is an earlier stun on gapless parents/self.\n\t\t\t\t\t});\n\t\t\t\t\t!test.run && tmp.on(''+at.id, test = {}); // this node stunned?\n\t\t\t\t\t!test.run && sat && tmp.on(''+sat.id, test = {}); // linked node stunned?\n\t\t\t\t\tif(any.id > test.run){\n\t\t\t\t\t\tif(!test.stun || test.stun.end){\n\t\t\t\t\t\t\ttest.stun = tmp.on('stun');\n\t\t\t\t\t\t\ttest.stun = test.stun && test.stun.last;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(test.stun && !test.stun.end){\n\t\t\t\t\t\t\t//if(odd && u === data){ return }\n\t\t\t\t\t\t\t//if(u === msg.put){ return } // \"not found\" acks will be found if there is stun, so ignore these.\n\t\t\t\t\t\t\t(test.stun.add || (test.stun.add = {}))[id] = function(){ any(msg,eve,1) } // add ourself to the stun callback list that is called at end of the write.\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(/*odd &&*/ u === data){ f = 0 } // if data not found, keep waiting/trying.\n\t\t\t\t/*if(f && u === data){\n\t\t\t\t\tcat.on('out', opt.out);\n\t\t\t\t\treturn;\n\t\t\t\t}*/\n\t\t\t\tif((tmp = root.hatch) && !tmp.end && u === opt.hatch && !f){ // quick hack! // What's going on here? Because data is streamed, we get things one by one, but a lot of developers would rather get a callback after each batch instead, so this does that by creating a wait list per chain id that is then called at the end of the batch by the hatch code in the root put listener.\n\t\t\t\t\tif(wait[at.$._.id]){ return } wait[at.$._.id] = 1;\n\t\t\t\t\ttmp.push(function(){any(msg,eve,1)});\n\t\t\t\t\treturn;\n\t\t\t\t}; wait = {}; // end quick hack.\n\t\t\t}\n\t\t\t// call:\n\t\t\tif(root.pass){ if(root.pass[id+at.id]){ return } root.pass[id+at.id] = 1 }\n\t\t\tif(opt.on){ opt.ok.call(at.$, data, at.get, msg, eve || any); return } // TODO: Also consider breaking `this` since a lot of people do `=>` these days and `.call(` has slower performance.\n\t\t\tif(opt.v2020){ opt.ok(msg, eve || any); return }\n\t\t\tObject.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {}); msg = tmp; msg.put = data; // 2019 COMPATIBILITY! TODO: GET RID OF THIS!\n\t\t\topt.ok.call(opt.as, msg, eve || any); // is this the right\n\t\t};\n\t\tany.at = cat;\n\t\t//(cat.any||(cat.any=function(msg){ setTimeout.each(Object.keys(cat.any||''), function(act){ (act = cat.any[act]) && act(msg) },0,99) }))[id = String.random(7)] = any; // maybe switch to this in future?\n\t\t(cat.any||(cat.any={}))[id = String.random(7)] = any;\n\t\tany.off = function(){ any.stun = 1; if(!cat.any){ return } delete cat.any[id] }\n\t\tany.rid = rid; // logic from old version, can we clean it up now?\n\t\tany.id = opt.run || ++root.once; // used in callback to check if we are earlier than a write. // will this ever cause an integer overflow?\n\t\ttmp = root.pass; (root.pass = {})[id] = 1; // Explanation: test trade-offs want to prevent recursion so we add/remove pass flag as it gets fulfilled to not repeat, however map map needs many pass flags - how do we reconcile?\n\t\topt.out = opt.out || {get: {}};\n\t\tcat.on('out', opt.out);\n\t\troot.pass = tmp;\n\t\treturn gun;\n\t} else\n\tif('number' == typeof key){\n\t\treturn this.get(''+key, cb, as);\n\t} else\n\tif('string' == typeof (tmp = valid(key))){\n\t\treturn this.get(tmp, cb, as);\n\t} else\n\tif(tmp = this.get.next){\n\t\tgun = tmp(this, key);\n\t}\n\tif(!gun){\n\t\t(gun = this.chain())._.err = {err: Gun.log('Invalid get request!', key)}; // CLEAN UP\n\t\tif(cb){ cb.call(gun, gun._.err) }\n\t\treturn gun;\n\t}\n\tif(cb && 'function' == typeof cb){\n\t\tgun.get(cb, as);\n\t}\n\treturn gun;\n}\nfunction cache(key, back){\n\tvar cat = back._, next = cat.next, gun = back.chain(), at = gun._;\n\tif(!next){ next = cat.next = {} }\n\tnext[at.get = key] = at;\n\tif(back === cat.root.$){\n\t\tat.soul = key;\n\t\t//at.put = {};\n\t} else\n\tif(cat.soul || cat.has){\n\t\tat.has = key;\n\t\t//if(obj_has(cat.put, key)){\n\t\t\t//at.put = cat.put[key];\n\t\t//}\n\t}\n\treturn at;\n}\nfunction soul(gun, cb, opt, as){\n\tvar cat = gun._, acks = 0, tmp;\n\tif(tmp = cat.soul || cat.link){ return cb(tmp, as, cat) }\n\tif(cat.jam){ return cat.jam.push([cb, as]) }\n\tcat.jam = [[cb,as]];\n\tgun.get(function go(msg, eve){\n\t\tif(u === msg.put && !cat.root.opt.super && (tmp = Object.keys(cat.root.opt.peers).length) && ++acks <= tmp){ // TODO: super should not be in core code, bring AXE up into core instead to fix? // TODO: .keys( is slow\n\t\t\treturn;\n\t\t}\n\t\teve.rid(msg);\n\t\tvar at = ((at = msg.$) && at._) || {}, i = 0, as;\n\t\ttmp = cat.jam; delete cat.jam; // tmp = cat.jam.splice(0, 100);\n\t\t//if(tmp.length){ process.nextTick(function(){ go(msg, eve) }) }\n\t\twhile(as = tmp[i++]){ //Gun.obj.map(tmp, function(as, cb){\n\t\t\tvar cb = as[0], id; as = as[1];\n\t\t\tcb && cb(id = at.link || at.soul || Gun.valid(msg.put) || ((msg.put||{})._||{})['#'], as, msg, eve);\n\t\t} //);\n\t}, {out: {get: {'.':true}}});\n\treturn gun;\n}\nfunction rid(at){\n\tvar cat = this.at || this.on;\n\tif(!at || cat.soul || cat.has){ return this.off() }\n\tif(!(at = (at = (at = at.$ || at)._ || at).id)){ return }\n\tvar map = cat.map, tmp, seen;\n\t//if(!map || !(tmp = map[at]) || !(tmp = tmp.at)){ return }\n\tif(tmp = (seen = this.seen || (this.seen = {}))[at]){ return true }\n\tseen[at] = true;\n\treturn;\n\t//tmp.echo[cat.id] = {}; // TODO: Warning: This unsubscribes ALL of this chain's listeners from this link, not just the one callback event.\n\t//obj.del(map, at); // TODO: Warning: This unsubscribes ALL of this chain's listeners from this link, not just the one callback event.\n\treturn;\n}\nvar empty = {}, valid = Gun.valid, u;\n\t\n}());"
  },
  {
    "path": "src/index.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nrequire('./shim');\nrequire('./onto');\nrequire('./book');\nrequire('./valid');\nrequire('./state');\nrequire('./dup');\nrequire('./ask');\nrequire('./core');\nrequire('./on');\nrequire('./map');\nrequire('./set');\nrequire('./mesh');\nrequire('./websocket');\nrequire('./localStorage');\nmodule.exports = Gun;\n\t\n}());"
  },
  {
    "path": "src/localStorage.js",
    "content": ";(function(){\n\nif(typeof Gun === 'undefined'){ return }\n\nvar noop = function(){}, store, u;\ntry{store = (Gun.window||noop).localStorage}catch(e){}\nif(!store){\n\tGun.log(\"Warning: No localStorage exists to persist data to!\");\n\tstore = {setItem: function(k,v){this[k]=v}, removeItem: function(k){delete this[k]}, getItem: function(k){return this[k]}};\n}\n\nvar parse = JSON.parseAsync || function(t,cb,r){ var u; try{ cb(u, JSON.parse(t,r)) }catch(e){ cb(e) } }\nvar json = JSON.stringifyAsync || function(v,cb,r,s){ var u; try{ cb(u, JSON.stringify(v,r,s)) }catch(e){ cb(e) } }\n\nGun.on('create', function lg(root){\n\tthis.to.next(root);\n\tvar opt = root.opt, graph = root.graph, acks = [], disk, to, size, stop;\n\tif(false === opt.localStorage){ return }\n\topt.prefix = opt.file || 'gun/';\n\ttry{ disk = lg[opt.prefix] = lg[opt.prefix] || JSON.parse(size = store.getItem(opt.prefix)) || {}; // TODO: Perf! This will block, should we care, since limited to 5MB anyways?\n\t}catch(e){ disk = lg[opt.prefix] = {}; }\n\tsize = (size||'').length;\n\n\troot.on('get', function(msg){\n\t\tthis.to.next(msg);\n\t\tvar lex = msg.get, soul, data, tmp, u;\n\t\tif(!lex || !(soul = lex['#'])){ return }\n\t\tdata = disk[soul] || u;\n\t\tif(data && (tmp = lex['.']) && !Object.plain(tmp)){ // pluck!\n\t\t\tdata = Gun.state.ify({}, tmp, Gun.state.is(data, tmp), data[tmp], soul);\n\t\t}\n\t\t//if(data){ (tmp = {})[soul] = data } // back into a graph.\n\t\t//setTimeout(function(){\n\t\tGun.on.get.ack(msg, data); //root.on('in', {'@': msg['#'], put: tmp, lS:1});// || root.$});\n\t\t//}, Math.random() * 10); // FOR TESTING PURPOSES!\n\t});\n\n\troot.on('put', function(msg){\n\t\tthis.to.next(msg); // remember to call next middleware adapter\n\t\tvar put = msg.put, soul = put['#'], key = put['.'], id = msg['#'], ok = msg.ok||'', tmp; // pull data off wire envelope\n\t\tdisk[soul] = Gun.state.ify(disk[soul], key, put['>'], put[':'], soul); // merge into disk object\n\t\tif(stop && size > (4999880)){ root.on('in', {'@': id, err: \"localStorage max!\"}); return; }\n\t\t//if(!msg['@']){ acks.push(id) } // then ack any non-ack write. // TODO: use batch id.\n\t\tif(!msg['@'] && (!msg._.via || Math.random() < (ok['@'] / ok['/']))){ acks.push(id) } // then ack any non-ack write. // TODO: use batch id.\n\t\tif(to){ return }\n\t\tto = setTimeout(flush, 9+(size / 333)); // 0.1MB = 0.3s, 5MB = 15s \n\t});\n\tfunction flush(){\n\t\tif(!acks.length && ((setTimeout.turn||'').s||'').length){ setTimeout(flush,99); return; } // defer if \"busy\" && no saves.\n\t\tvar err, ack = acks; clearTimeout(to); to = false; acks = [];\n\t\tjson(disk, function(err, tmp){\n\t\t\ttry{!err && store.setItem(opt.prefix, tmp);\n\t\t\t}catch(e){ err = stop = e || \"localStorage failure\" }\n\t\t\tif(err){\n\t\t\t\tGun.log(err + \" Consider using GUN's IndexedDB plugin for RAD for more storage space, https://gun.eco/docs/RAD#install\");\n\t\t\t\troot.on('localStorage:error', {err: err, get: opt.prefix, put: disk});\n\t\t\t}\n\t\t\tsize = tmp.length;\n\n\t\t\t//if(!err && !Object.empty(opt.peers)){ return } // only ack if there are no peers. // Switch this to probabilistic mode\n\t\t\tsetTimeout.each(ack, function(id){\n\t\t\t\troot.on('in', {'@': id, err: err, ok: 0}); // localStorage isn't reliable, so make its `ok` code be a low number.\n\t\t\t},0,99);\n\t\t})\n\t}\n\n});\n\t\n}());"
  },
  {
    "path": "src/map.js",
    "content": ";(function(){\n\nvar Gun = require('./root'), next = Gun.chain.get.next;\nGun.chain.get.next = function(gun, lex){ var tmp;\n\tif(!Object.plain(lex)){ return (next||noop)(gun, lex) }\n\tif(tmp = ((tmp = lex['#'])||'')['='] || tmp){ return gun.get(tmp) }\n\t(tmp = gun.chain()._).lex = lex; // LEX!\n\tgun.on('in', function(eve){\n\t\tif(String.match(eve.get|| (eve.put||'')['.'], lex['.'] || lex['#'] || lex)){\n\t\t\ttmp.on('in', eve);\n\t\t}\n\t\tthis.to.next(eve);\n\t});\n\treturn tmp.$;\n}\nGun.chain.map = function(cb, opt, t){\n\tvar gun = this, cat = gun._, lex, chain;\n\tif(Object.plain(cb)){ lex = cb['.']? cb : {'.': cb}; cb = u }\n\tif(!cb){\n\t\tif(chain = cat.each){ return chain }\n\t\t(cat.each = chain = gun.chain())._.lex = lex || chain._.lex || cat.lex;\n\t\tchain._.nix = gun.back('nix');\n\t\tgun.on('in', map, chain._);\n\t\treturn chain;\n\t}\n\tGun.log.once(\"mapfn\", \"Map functions are experimental, their behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it.\");\n\tchain = gun.chain();\n\tgun.map().on(function(data, key, msg, eve){\n\t\tvar next = (cb||noop).call(this, data, key, msg, eve);\n\t\tif(u === next){ return }\n\t\tif(data === next){ return chain._.on('in', msg) }\n\t\tif(Gun.is(next)){ return chain._.on('in', next._) }\n\t\tvar tmp = {}; Object.keys(msg.put).forEach(function(k){ tmp[k] = msg.put[k] }, tmp); tmp['='] = next; \n\t\tchain._.on('in', {get: key, put: tmp});\n\t});\n\treturn chain;\n}\nfunction map(msg){ this.to.next(msg);\n\tvar cat = this.as, gun = msg.$, at = gun._, put = msg.put, tmp;\n\tif(!at.soul && !msg.$$){ return } // this line took hundreds of tries to figure out. It only works if core checks to filter out above chains during link tho. This says \"only bother to map on a node\" for this layer of the chain. If something is not a node, map should not work.\n\tif((tmp = cat.lex) && !String.match(msg.get|| (put||'')['.'], tmp['.'] || tmp['#'] || tmp)){ return }\n\tGun.on.link(msg, cat);\n}\nvar noop = function(){}, event = {stun: noop, off: noop}, u;\n\t\n}());"
  },
  {
    "path": "src/mesh.js",
    "content": ";(function(){\n\nrequire('./shim');\n\nvar noop = function(){}\nvar parse = JSON.parseAsync || function(t,cb,r){ var u, d = +new Date; try{ cb(u, JSON.parse(t,r), json.sucks(+new Date - d)) }catch(e){ cb(e) } }\nvar json = JSON.stringifyAsync || function(v,cb,r,s){ var u, d = +new Date; try{ cb(u, JSON.stringify(v,r,s), json.sucks(+new Date - d)) }catch(e){ cb(e) } }\njson.sucks = function(d){ if(d > 99){ console.log(\"Warning: JSON blocking CPU detected. Add `gun/lib/yson.js` to fix.\"); json.sucks = noop } }\n\nfunction Mesh(root){\n\tvar mesh = function(){};\n\tvar opt = root.opt || {};\n\topt.log = opt.log || console.log;\n\topt.gap = opt.gap || opt.wait || 0;\n\topt.max = opt.max || (opt.memory? (opt.memory * 999 * 999) : 300000000) * 0.3;\n\topt.pack = opt.pack || (opt.max * 0.01 * 0.01);\n\topt.puff = opt.puff || 9; // IDEA: do a start/end benchmark, divide ops/result.\n\tvar puff = setTimeout.turn || setTimeout;\n\n\tvar dup = root.dup, dup_check = dup.check, dup_track = dup.track;\n\n\tvar ST = +new Date, LT = ST;\n\n\tvar hear = mesh.hear = function(raw, peer){\n\t\tif(!raw){ return }\n\t\tif(opt.max <= raw.length){ return mesh.say({dam: '!', err: \"Message too big!\"}, peer) }\n\t\tif(mesh === this){\n\t\t\t/*if('string' == typeof raw){ try{\n\t\t\t\tvar stat = console.STAT || {};\n\t\t\t\t//console.log('HEAR:', peer.id, (raw||'').slice(0,250), ((raw||'').length / 1024 / 1024).toFixed(4));\n\t\t\t\t\n\t\t\t\t//console.log(setTimeout.turn.s.length, 'stacks', parseFloat((-(LT - (LT = +new Date))/1000).toFixed(3)), 'sec', parseFloat(((LT-ST)/1000 / 60).toFixed(1)), 'up', stat.peers||0, 'peers', stat.has||0, 'has', stat.memhused||0, stat.memused||0, stat.memax||0, 'heap mem max');\n\t\t\t}catch(e){ console.log('DBG err', e) }}*/\n\t\t\thear.d += raw.length||0 ; ++hear.c } // STATS!\n\t\tvar S = peer.SH = +new Date;\n\t\tvar tmp = raw[0], msg;\n\t\t//raw && raw.slice && console.log(\"hear:\", ((peer.wire||'').headers||'').origin, raw.length, raw.slice && raw.slice(0,50)); //tc-iamunique-tc-package-ds1\n\t\tif('[' === tmp){\n\t\t\tparse(raw, function(err, msg){\n\t\t\t\tif(err || !msg){ return mesh.say({dam: '!', err: \"DAM JSON parse error.\"}, peer) }\n\t\t\t\tconsole.STAT && console.STAT(+new Date, msg.length, '# on hear batch');\n\t\t\t\tvar P = opt.puff;\n\t\t\t\t(function go(){\n\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\tvar i = 0, m; while(i < P && (m = msg[i++])){ mesh.hear(m, peer) }\n\t\t\t\t\tmsg = msg.slice(i); // slicing after is faster than shifting during.\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'hear loop');\n\t\t\t\t\tflush(peer); // force send all synchronously batched acks.\n\t\t\t\t\tif(!msg.length){ return }\n\t\t\t\t\tpuff(go, 0);\n\t\t\t\t}());\n\t\t\t});\n\t\t\traw = ''; // \n\t\t\treturn;\n\t\t}\n\t\tif('{' === tmp || ((raw['#'] || Object.plain(raw)) && (msg = raw))){\n\t\t\tif(msg){ return hear.one(msg, peer, S) }\n\t\t\tparse(raw, function(err, msg){\n\t\t\t\tif(err || !msg){ return mesh.say({dam: '!', err: \"DAM JSON parse error.\"}, peer) }\n\t\t\t\thear.one(msg, peer, S);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t}\n\thear.one = function(msg, peer, S){ // S here is temporary! Undo.\n\t\tvar id, hash, tmp, ash, DBG;\n\t\tif(msg.DBG){ msg.DBG = DBG = {DBG: msg.DBG} }\n\t\tDBG && (DBG.h = S);\n\t\tDBG && (DBG.hp = +new Date);\n\t\tif(!(id = msg['#'])){ id = msg['#'] = String.random(9) }\n\t\tif(tmp = dup_check(id)){ return }\n\t\t// DAM logic:\n\t\tif(!(hash = msg['##']) && false && u !== msg.put){ /*hash = msg['##'] = Type.obj.hash(msg.put)*/ } // disable hashing for now // TODO: impose warning/penalty instead (?)\n\t\tif(hash && (tmp = msg['@'] || (msg.get && id)) && dup.check(ash = tmp+hash)){ return } // Imagine A <-> B <=> (C & D), C & D reply with same ACK but have different IDs, B can use hash to dedup. Or if a GET has a hash already, we shouldn't ACK if same.\n\t\t(msg._ = function(){}).via = mesh.leap = peer;\n\t\tif((tmp = msg['><']) && 'string' == typeof tmp){ tmp.slice(0,99).split(',').forEach(function(k){ this[k] = 1 }, (msg._).yo = {}) } // Peers already sent to, do not resend.\n\t\t// DAM ^\n\t\tif(tmp = msg.dam){\n\t\t\tif(tmp = mesh.hear[tmp]){\n\t\t\t\ttmp(msg, peer, root);\n\t\t\t}\n\t\t\tdup_track(id);\n\t\t\treturn;\n\t\t}\n\t\tif(tmp = msg.ok){ msg._.near = tmp['/'] }\n\t\tvar S = +new Date;\n\t\tDBG && (DBG.is = S); peer.SI = id;\n\t\tdup_track.ed = function(d){\n\t\t\tif(id !== d){ return }\n\t\t\tdup_track.ed = 0;\n\t\t\tif(!(d = dup.s[id])){ return }\n\t\t\td.via = peer;\n\t\t\tif(msg.get){ d.it = msg }\n\t\t}\n\t\troot.on('in', mesh.last = msg);\n\t\tDBG && (DBG.hd = +new Date);\n\t\tconsole.STAT && console.STAT(S, +new Date - S, msg.get? 'msg get' : msg.put? 'msg put' : 'msg');\n\t\tdup_track(id); // in case 'in' does not call track.\n\t\tif(ash){ dup_track(ash) } //dup.track(tmp+hash, true).it = it(msg);\n\t\tmesh.leap = mesh.last = null; // warning! mesh.leap could be buggy.\n\t}\n\tvar tomap = function(k,i,m){m(k,true)};\n\thear.c = hear.d = 0;\n\n\t;(function(){\n\t\tvar SMIA = 0;\n\t\tvar loop;\n\t\tmesh.hash = function(msg, peer){ var h, s, t;\n\t\t\tvar S = +new Date;\n\t\t\tjson(msg.put, function hash(err, text){\n\t\t\t\tvar ss = (s || (s = t = text||'')).slice(0, 32768); // 1024 * 32\n\t\t\t  h = String.hash(ss, h); s = s.slice(32768);\n\t\t\t  if(s){ puff(hash, 0); return }\n\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'say json+hash');\n\t\t\t  msg._.$put = t;\n\t\t\t  msg['##'] = h;\n\t\t\t  mesh.say(msg, peer);\n\t\t\t  delete msg._.$put;\n\t\t\t}, sort);\n\t\t}\n\t\tfunction sort(k, v){ var tmp;\n\t\t\tif(!(v instanceof Object)){ return v }\n\t\t\tObject.keys(v).sort().forEach(sorta, {to: tmp = {}, on: v});\n\t\t\treturn tmp;\n\t\t} function sorta(k){ this.to[k] = this.on[k] }\n\n\t\tvar say = mesh.say = function(msg, peer){ var tmp;\n\t\t\tif((tmp = this) && (tmp = tmp.to) && tmp.next){ tmp.next(msg) } // compatible with middleware adapters.\n\t\t\tif(!msg){ return false }\n\t\t\tvar id, hash, raw, ack = msg['@'];\n//if(opt.super && (!ack || !msg.put)){ return } // TODO: MANHATTAN STUB //OBVIOUSLY BUG! But squelch relay. // :( get only is 100%+ CPU usage :(\n\t\t\tvar meta = msg._||(msg._=function(){});\n\t\t\tvar DBG = msg.DBG, S = +new Date; meta.y = meta.y || S; if(!peer){ DBG && (DBG.y = S) }\n\t\t\tif(!(id = msg['#'])){ id = msg['#'] = String.random(9) }\n\t\t\t!loop && dup_track(id);//.it = it(msg); // track for 9 seconds, default. Earth<->Mars would need more! // always track, maybe move this to the 'after' logic if we split function.\n\t\t\t//if(msg.put && (msg.err || (dup.s[id]||'').err)){ return false } // TODO: in theory we should not be able to stun a message, but for now going to check if it can help network performance preventing invalid data to relay.\n\t\t\tif(!(hash = msg['##']) && u !== msg.put && !meta.via && ack){ mesh.hash(msg, peer); return } // TODO: Should broadcasts be hashed?\n\t\t\tif(!peer && ack){ peer = ((tmp = dup.s[ack]) && (tmp.via || ((tmp = tmp.it) && (tmp = tmp._) && tmp.via))) || ((tmp = mesh.last) && ack === tmp['#'] && mesh.leap) } // warning! mesh.leap could be buggy! mesh last check reduces this. // TODO: CLEAN UP THIS LINE NOW? `.it` should be reliable.\n\t\t\tif(!peer && ack){ // still no peer, then ack daisy chain 'tunnel' got lost.\n\t\t\t\tif(dup.s[ack]){ return } // in dups but no peer hints that this was ack to ourself, ignore.\n\t\t\t\tconsole.STAT && console.STAT(+new Date, ++SMIA, 'total no peer to ack to'); // TODO: Delete this now. Dropping lost ACKs is protocol fine now.\n\t\t\t\treturn false;\n\t\t\t} // TODO: Temporary? If ack via trace has been lost, acks will go to all peers, which trashes browser bandwidth. Not relaying the ack will force sender to ask for ack again. Note, this is technically wrong for mesh behavior.\n\t\t\tif(ack && !msg.put && !hash && ((dup.s[ack]||'').it||'')['##']){ return false } // If we're saying 'not found' but a relay had data, do not bother sending our not found. // Is this correct, return false? // NOTE: ADD PANIC TEST FOR THIS!\n\t\t\tif(!peer && mesh.way){ return mesh.way(msg) }\n\t\t\tDBG && (DBG.yh = +new Date);\n\t\t\tif(!(raw = meta.raw)){ mesh.raw(msg, peer); return }\n\t\t\tDBG && (DBG.yr = +new Date);\n\t\t\tif(!peer || !peer.id){\n\t\t\t\tif(!Object.plain(peer || opt.peers)){ return false }\n\t\t\t\tvar S = +new Date;\n\t\t\t\tvar P = opt.puff, ps = opt.peers, pl = Object.keys(peer || opt.peers || {}); // TODO: .keys( is slow\n\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'peer keys');\n\t\t\t\t;(function go(){\n\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\t//Type.obj.map(peer || opt.peers, each); // in case peer is a peer list.\n\t\t\t\t\tloop = 1; var wr = meta.raw; meta.raw = raw; // quick perf hack\n\t\t\t\t\tvar i = 0, p; while(i < 9 && (p = (pl||'')[i++])){\n\t\t\t\t\t\tif(!(p = ps[p] || (peer||'')[p])){ continue }\n\t\t\t\t\t\tmesh.say(msg, p);\n\t\t\t\t\t}\n\t\t\t\t\tmeta.raw = wr; loop = 0;\n\t\t\t\t\tpl = pl.slice(i); // slicing after is faster than shifting during.\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'say loop');\n\t\t\t\t\tif(!pl.length){ return }\n\t\t\t\t\tpuff(go, 0);\n\t\t\t\t\tack && dup_track(ack); // keep for later\n\t\t\t\t}());\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// TODO: PERF: consider splitting function here, so say loops do less work.\n\t\t\tif(!peer.wire && mesh.wire){ mesh.wire(peer) }\n\t\t\tif(id === peer.last){ return } peer.last = id;  // was it just sent?\n\t\t\tif(peer === meta.via){ return false } // don't send back to self.\n\t\t\tif((tmp = meta.yo) && (tmp[peer.url] || tmp[peer.pid] || tmp[peer.id]) /*&& !o*/){ return false }\n\t\t\tconsole.STAT && console.STAT(S, ((DBG||meta).yp = +new Date) - (meta.y || S), 'say prep');\n\t\t\t!loop && ack && dup_track(ack); // streaming long responses needs to keep alive the ack.\n\t\t\tif(peer.batch){\n\t\t\t\tpeer.tail = (tmp = peer.tail || 0) + raw.length;\n\t\t\t\tif(peer.tail <= opt.pack){\n\t\t\t\t\tpeer.batch += (tmp?',':'')+raw;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tflush(peer);\n\t\t\t}\n\t\t\tpeer.batch = '['; // Prevents double JSON!\n\t\t\tvar ST = +new Date;\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.STAT && console.STAT(ST, +new Date - ST, '0ms TO');\n\t\t\t\tflush(peer);\n\t\t\t}, opt.gap); // TODO: queuing/batching might be bad for low-latency video game performance! Allow opt out?\n\t\t\tsend(raw, peer);\n\t\t\tconsole.STAT && (ack === peer.SI) && console.STAT(S, +new Date - peer.SH, 'say ack');\n\t\t}\n\t\tmesh.say.c = mesh.say.d = 0;\n\t\t// TODO: this caused a out-of-memory crash!\n\t\tmesh.raw = function(msg, peer){ // TODO: Clean this up / delete it / move logic out!\n\t\t\tif(!msg){ return '' }\n\t\t\tvar meta = (msg._) || {}, put, tmp;\n\t\t\tif(tmp = meta.raw){ return tmp }\n\t\t\tif('string' == typeof msg){ return msg }\n\t\t\tvar hash = msg['##'], ack = msg['@'];\n\t\t\tif(hash && ack){\n\t\t\t\tif(!meta.via && dup_check(ack+hash)){ return false } // for our own out messages, memory & storage may ack the same thing, so dedup that. Tho if via another peer, we already tracked it upon hearing, so this will always trigger false positives, so don't do that!\n\t\t\t\tif(tmp = (dup.s[ack]||'').it){\n\t\t\t\t\tif(hash === tmp['##']){ return false } // if ask has a matching hash, acking is optional.\n\t\t\t\t\tif(!tmp['##']){ tmp['##'] = hash } // if none, add our hash to ask so anyone we relay to can dedup. // NOTE: May only check against 1st ack chunk, 2nd+ won't know and still stream back to relaying peers which may then dedup. Any way to fix this wasted bandwidth? I guess force rate limiting breaking change, that asking peer has to ask for next lexical chunk.\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(!msg.dam && !msg['@']){\n\t\t\t\tvar i = 0, to = []; tmp = opt.peers;\n\t\t\t\tfor(var k in tmp){ var p = tmp[k]; // TODO: Make it up peers instead!\n\t\t\t\t\tto.push(p.url || p.pid || p.id);\n\t\t\t\t\tif(++i > 6){ break }\n\t\t\t\t}\n\t\t\t\tif(i > 1){ msg['><'] = to.join() } // TODO: BUG! This gets set regardless of peers sent to! Detect?\n\t\t\t}\n\t\t\tif(msg.put && (tmp = msg.ok)){ msg.ok = {'@':(tmp['@']||1)-1, '/': (tmp['/']==msg._.near)? mesh.near : tmp['/']}; }\n\t\t\tif(put = meta.$put){\n\t\t\t\ttmp = {}; Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] });\n\t\t\t\ttmp.put = ':])([:';\n\t\t\t\tjson(tmp, function(err, raw){\n\t\t\t\t\tif(err){ return } // TODO: Handle!!\n\t\t\t\t\tvar S = +new Date;\n\t\t\t\t\ttmp = raw.indexOf('\"put\":\":])([:\"');\n\t\t\t\t\tres(u, raw = raw.slice(0, tmp+6) + put + raw.slice(tmp + 14));\n\t\t\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'say slice');\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tjson(msg, res);\n\t\t\tfunction res(err, raw){\n\t\t\t\tif(err){ return } // TODO: Handle!!\n\t\t\t\tmeta.raw = raw; //if(meta && (raw||'').length < (999 * 99)){ meta.raw = raw } // HNPERF: If string too big, don't keep in memory.\n\t\t\t\tmesh.say(msg, peer);\n\t\t\t}\n\t\t}\n\t}());\n\n\tfunction flush(peer){\n\t\tvar tmp = peer.batch, t = 'string' == typeof tmp, l;\n\t\tif(t){ tmp += ']' }// TODO: Prevent double JSON!\n\t\tpeer.batch = peer.tail = null;\n\t\tif(!tmp){ return }\n\t\tif(t? 3 > tmp.length : !tmp.length){ return } // TODO: ^\n\t\tif(!t){try{tmp = (1 === tmp.length? tmp[0] : JSON.stringify(tmp));\n\t\t}catch(e){return opt.log('DAM JSON stringify error', e)}}\n\t\tif(!tmp){ return }\n\t\tsend(tmp, peer);\n\t}\n\t// for now - find better place later.\n\tfunction send(raw, peer){ try{\n\t\tvar wire = peer.wire;\n\t\tif(peer.say){\n\t\t\tpeer.say(raw);\n\t\t} else\n\t\tif(wire.send){\n\t\t\twire.send(raw);\n\t\t}\n\t\tmesh.say.d += raw.length||0; ++mesh.say.c; // STATS!\n\t}catch(e){\n\t\t(peer.queue = peer.queue || []).push(raw);\n\t}}\n\n\tmesh.near = 0;\n\tmesh.hi = function(peer){\n\t\tvar wire = peer.wire, tmp;\n\t\tif(!wire){ mesh.wire((peer.length && {url: peer, id: peer}) || peer); return }\n\t\tif(peer.id){\n\t\t\topt.peers[peer.url || peer.id] = peer;\n\t\t} else {\n\t\t\ttmp = peer.id = peer.id || peer.url || String.random(9);\n\t\t\tmesh.say({dam: '?', pid: root.opt.pid}, opt.peers[tmp] = peer);\n\t\t\tdelete dup.s[peer.last]; // IMPORTANT: see https://gun.eco/docs/DAM#self\n\t\t}\n\t\tif(!peer.met){\n\t\t\tmesh.near++;\n\t\t\tpeer.met = +(new Date);\n\t\t\troot.on('hi', peer)\n\t\t}\n\t\t// @rogowski I need this here by default for now to fix go1dfish's bug\n\t\ttmp = peer.queue; peer.queue = [];\n\t\tsetTimeout.each(tmp||[],function(msg){\n\t\t\tsend(msg, peer);\n\t\t},0,9);\n\t\t//Type.obj.native && Type.obj.native(); // dirty place to check if other JS polluted.\n\t}\n\tmesh.bye = function(peer){\n\t\tpeer.met && --mesh.near;\n\t\tdelete peer.met;\n\t\troot.on('bye', peer);\n\t\tvar tmp = +(new Date); tmp = (tmp - (peer.met||tmp));\n\t\tmesh.bye.time = ((mesh.bye.time || tmp) + tmp) / 2;\n\t}\n\tmesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) }\n\tmesh.hear['?'] = function(msg, peer){\n\t\tif(msg.pid){\n\t\t\tif(!peer.pid){ peer.pid = msg.pid }\n\t\t\tif(msg['@']){ return }\n\t\t}\n\t\tmesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer);\n\t\tdelete dup.s[peer.last]; // IMPORTANT: see https://gun.eco/docs/DAM#self\n\t}\n\tmesh.hear['mob'] = function(msg, peer){ // NOTE: AXE will overload this with better logic.\n\t\tif(!msg.peers){ return }\n\t\tvar peers = Object.keys(msg.peers), one = peers[(Math.random()*peers.length) >> 0];\n\t\tif(!one){ return }\n\t\tmesh.bye(peer);\n\t\tmesh.hi(one);\n\t}\n\n\troot.on('create', function(root){\n\t\troot.opt.pid = root.opt.pid || String.random(9);\n\t\tthis.to.next(root);\n\t\troot.on('out', mesh.say);\n\t});\n\n\troot.on('bye', function(peer, tmp){\n\t\tpeer = opt.peers[peer.id || peer] || peer;\n\t\tthis.to.next(peer);\n\t\tpeer.bye? peer.bye() : (tmp = peer.wire) && tmp.close && tmp.close();\n\t\tdelete opt.peers[peer.id];\n\t\tpeer.wire = null;\n\t});\n\n\tvar gets = {};\n\troot.on('bye', function(peer, tmp){ this.to.next(peer);\n\t\tif(tmp = console.STAT){ tmp.peers = mesh.near; }\n\t\tif(!(tmp = peer.url)){ return } gets[tmp] = true;\n\t\tsetTimeout(function(){ delete gets[tmp] },opt.lack || 9000);\n\t});\n\troot.on('hi', function(peer, tmp){ this.to.next(peer);\n\t\tif(tmp = console.STAT){ tmp.peers = mesh.near }\n\t\tif(opt.super){ return } // temporary (?) until we have better fix/solution?\n\t\tvar souls = Object.keys(root.next||''); // TODO: .keys( is slow\n\t\tif(souls.length > 9999 && !console.SUBS){ console.log(console.SUBS = \"Warning: You have more than 10K live GETs, which might use more bandwidth than your screen can show - consider `.off()`.\") }\n\t\tsetTimeout.each(souls, function(soul){ var node = root.next[soul];\n\t\t\tif(opt.super || (node.ask||'')['']){ mesh.say({get: {'#': soul}}, peer); return }\n\t\t\tsetTimeout.each(Object.keys(node.ask||''), function(key){ if(!key){ return }\n\t\t\t\t// is the lack of ## a !onion hint?\n\t\t\t\tmesh.say({'##': String.hash((root.graph[soul]||'')[key]), get: {'#': soul, '.': key}}, peer);\n\t\t\t\t// TODO: Switch this so Book could route?\n\t\t\t})\n\t\t});\n\t});\n\n\treturn mesh;\n}\n\t  var empty = {}, ok = true, u;\n\n\t  try{ module.exports = Mesh }catch(e){}\n\n\t\n}());"
  },
  {
    "path": "src/on.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nGun.chain.on = function(tag, arg, eas, as){ // don't rewrite!\n\tvar gun = this, cat = gun._, root = cat.root, act, off, id, tmp;\n\tif(typeof tag === 'string'){\n\t\tif(!arg){ return cat.on(tag) }\n\t\tact = cat.on(tag, arg, eas || cat, as);\n\t\tif(eas && eas.$){\n\t\t\t(eas.subs || (eas.subs = [])).push(act);\n\t\t}\n\t\treturn gun;\n\t}\n\tvar opt = arg;\n\t(opt = (true === opt)? {change: true} : opt || {}).not = 1; opt.on = 1;\n\t//opt.at = cat;\n\t//opt.ok = tag;\n\t//opt.last = {};\n\tvar wait = {}; // can we assign this to the at instead, like in once?\n\tgun.get(tag, opt);\n\t/*gun.get(function on(data,key,msg,eve){ var $ = this;\n\t\tif(tmp = root.hatch){ // quick hack!\n\t\t\tif(wait[$._.id]){ return } wait[$._.id] = 1;\n\t\t\ttmp.push(function(){on.call($, data,key,msg,eve)});\n\t\t\treturn;\n\t\t}; wait = {}; // end quick hack.\n\t\ttag.call($, data,key,msg,eve);\n\t}, opt); // TODO: PERF! Event listener leak!!!?*/\n\t/*\n\tfunction one(msg, eve){\n\t\tif(one.stun){ return }\n\t\tvar at = msg.$._, data = at.put, tmp;\n\t\tif(tmp = at.link){ data = root.$.get(tmp)._.put }\n\t\tif(opt.not===u && u === data){ return }\n\t\tif(opt.stun===u && (tmp = root.stun) && (tmp = tmp[at.id] || tmp[at.back.id]) && !tmp.end){ // Remember! If you port this into `.get(cb` make sure you allow stun:0 skip option for `.put(`.\n\t\t\ttmp[id] = function(){one(msg,eve)};\n\t\t\treturn;\n\t\t}\n\t\t//tmp = one.wait || (one.wait = {}); console.log(tmp[at.id] === ''); if(tmp[at.id] !== ''){ tmp[at.id] = tmp[at.id] || setTimeout(function(){tmp[at.id]='';one(msg,eve)},1); return } delete tmp[at.id];\n\t\t// call:\n\t\tif(opt.as){\n\t\t\topt.ok.call(opt.as, msg, eve || one);\n\t\t} else {\n\t\t\topt.ok.call(at.$, data, msg.get || at.get, msg, eve || one);\n\t\t}\n\t};\n\tone.at = cat;\n\t(cat.act||(cat.act={}))[id = String.random(7)] = one;\n\tone.off = function(){ one.stun = 1; if(!cat.act){ return } delete cat.act[id] }\n\tcat.on('out', {get: {}});*/\n\treturn gun;\n}\n// Rules:\n// 1. If cached, should be fast, but not read while write.\n// 2. Should not retrigger other listeners, should get triggered even if nothing found.\n// 3. If the same callback passed to many different once chains, each should resolve - an unsubscribe from the same callback should not effect the state of the other resolving chains, if you do want to cancel them all early you should mutate the callback itself with a flag & check for it at top of callback\nGun.chain.once = function(cb, opt){ opt = opt || {}; // avoid rewriting\n\tif(!cb){ return none(this,opt) }\n\tvar gun = this, cat = gun._, root = cat.root, data = cat.put, id = String.random(7), one, tmp;\n\tgun.get(function(data,key,msg,eve){\n\t\tvar $ = this, at = $._, one = (at.one||(at.one={}));\n\t\tif(eve.stun){ return } if('' === one[id]){ return }\n\t\tif(true === (tmp = Gun.valid(data))){ once(); return }\n\t\tif('string' == typeof tmp){ return } // TODO: BUG? Will this always load?\n\t\tclearTimeout((cat.one||'')[id]); // clear \"not found\" since they only get set on cat.\n\t\tclearTimeout(one[id]); one[id] = setTimeout(once, opt.wait||99); // TODO: Bug? This doesn't handle plural chains.\n\t\tfunction once(f){\n\t\t\tif(!at.has && !at.soul){ at = {put: data, get: key} } // handles non-core messages.\n\t\t\tif(u === (tmp = at.put)){ tmp = ((msg.$$||'')._||'').put }\n\t\t\tif('string' == typeof Gun.valid(tmp)){\n\t\t\t\ttmp = root.$.get(tmp)._.put;\n\t\t\t\tif(tmp === u && !f){\n\t\t\t\t\tone[id] = setTimeout(function(){ once(1) }, opt.wait||99); // TODO: Quick fix. Maybe use ack count for more predictable control?\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\t//console.log(\"AND VANISHED\", data);\n\t\t\tif(eve.stun){ return } if('' === one[id]){ return } one[id] = '';\n\t\t\tif(cat.soul || cat.has){ eve.off() } // TODO: Plural chains? // else { ?.off() } // better than one check?\n\t\t\tcb.call($, tmp, at.get);\n\t\t\tclearTimeout(one[id]); // clear \"not found\" since they only get set on cat. // TODO: This was hackily added, is it necessary or important? Probably not, in future try removing this. Was added just as a safety for the `&& !f` check.\n\t\t};\n\t}, {on: 1});\n\treturn gun;\n}\nfunction none(gun,opt,chain){\n\tGun.log.once(\"valonce\", \"Chainable val is experimental, its behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it.\");\n\t(chain = gun.chain())._.nix = gun.once(function(data, key){ chain._.on('in', this._) });\n\tchain._.lex = gun._.lex; // TODO: Better approach in future? This is quick for now.\n\treturn chain;\n}\n\nGun.chain.off = function(){\n\t// make off more aggressive. Warning, it might backfire!\n\tvar gun = this, at = gun._, tmp;\n\tvar cat = at.back;\n\tif(!cat){ return }\n\tat.ack = 0; // so can resubscribe.\n\tif(tmp = cat.next){\n\t\tif(tmp[at.get]){\n\t\t\tdelete tmp[at.get];\n\t\t} else {\n\n\t\t}\n\t}\n\t// TODO: delete cat.one[map.id]?\n\tif (tmp = cat.any) {\n\t\tdelete cat.any;\n\t\tcat.any = {};\n\t}\n\tif(tmp = cat.ask){\n\t\tdelete tmp[at.get];\n\t}\n\tif(tmp = cat.put){\n\t\tdelete tmp[at.get];\n\t}\n\tif(tmp = at.soul){\n\t\tdelete cat.root.graph[tmp];\n\t}\n\tif(tmp = at.map){\n\t\tObject.keys(tmp).forEach(function(i,at){ at = tmp[i]; //obj_map(tmp, function(at){\n\t\t\tif(at.link){\n\t\t\t\tcat.root.$.get(at.link).off();\n\t\t\t}\n\t\t});\n\t}\n\tif(tmp = at.next){\n\t\tObject.keys(tmp).forEach(function(i,neat){ neat = tmp[i]; //obj_map(tmp, function(neat){\n\t\t\tneat.$.off();\n\t\t});\n\t}\n\tat.on('off', {});\n\treturn gun;\n}\nvar empty = {}, noop = function(){}, u;\n\t\n}());"
  },
  {
    "path": "src/onto.js",
    "content": ";(function(){\n\n// On event emitter generic javascript utility.\nmodule.exports = function onto(tag, arg, as){\n\tif(!tag){ return {to: onto} }\n\tvar u, f = 'function' == typeof arg, tag = (this.tag || (this.tag = {}))[tag] || f && (\n\t\tthis.tag[tag] = {tag: tag, to: onto._ = { next: function(arg){ var tmp;\n\t\t\tif(tmp = this.to){ tmp.next(arg) }\n\t}}});\n\tif(f){\n\t\tvar be = {\n\t\t\toff: onto.off ||\n\t\t\t(onto.off = function(){\n\t\t\t\tif(this.next === onto._.next){ return !0 }\n\t\t\t\tif(this === this.the.last){\n\t\t\t\t\tthis.the.last = this.back;\n\t\t\t\t}\n\t\t\t\tthis.to.back = this.back;\n\t\t\t\tthis.next = onto._.next;\n\t\t\t\tthis.back.to = this.to;\n\t\t\t\tif(this.the.last === this.the){\n\t\t\t\t\tdelete this.on.tag[this.the.tag];\n\t\t\t\t}\n\t\t\t}),\n\t\t\tto: onto._,\n\t\t\tnext: arg,\n\t\t\tthe: tag,\n\t\t\ton: this,\n\t\t\tas: as,\n\t\t};\n\t\t(be.back = tag.last || tag).to = be;\n\t\treturn tag.last = be;\n\t}\n\tif((tag = tag.to) && u !== arg){ tag.next(arg) }\n\treturn tag;\n};\n\t\n}());"
  },
  {
    "path": "src/polyfill/unbuild.js",
    "content": "\n  function USE(arg, req){\n    return req? require(arg) : arg.slice? USE[R(arg)] : function(mod, path){\n      arg(mod = {exports: {}});\n      USE[R(path)] = mod.exports;\n    }\n    function R(p){\n      return p.split('/').slice(-1).toString().replace('.js','');\n    }\n  }\n  if(typeof module !== \"undefined\"){ var MODULE = module }\n  "
  },
  {
    "path": "src/put.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nGun.chain.put = function(data, cb, as){ // I rewrote it :)\n\tvar gun = this, at = gun._, root = at.root;\n\tas = as || {};\n\tas.root = at.root;\n\tas.run || (as.run = root.once);\n\tstun(as, at.id); // set a flag for reads to check if this chain is writing.\n\tas.ack = as.ack || cb;\n\tas.via = as.via || gun;\n\tas.data = as.data || data;\n\tas.soul || (as.soul = at.soul || ('string' == typeof cb && cb));\n\tvar s = as.state = as.state || Gun.state();\n\tif('function' == typeof data){ data(function(d){ as.data = d; gun.put(u,u,as) }); return gun }\n\tif(!as.soul){ return get(as), gun }\n\tas.$ = root.$.get(as.soul); // TODO: This may not allow user chaining and similar?\n\tas.todo = [{it: as.data, ref: as.$}];\n\tas.turn = as.turn || turn;\n\tas.ran = as.ran || ran;\n\t//var path = []; as.via.back(at => { at.get && path.push(at.get.slice(0,9)) }); path = path.reverse().join('.');\n\t// TODO: Perf! We only need to stun chains that are being modified, not necessarily written to.\n\t(function walk(){\n\t\tvar to = as.todo, at = to.pop(), d = at.it, cid = at.ref && at.ref._.id, v, k, cat, tmp, g;\n\t\tstun(as, at.ref);\n\t\tif(tmp = at.todo){\n\t\t\tk = tmp.pop(); d = d[k];\n\t\t\tif(tmp.length){ to.push(at) }\n\t\t}\n\t\tk && (to.path || (to.path = [])).push(k);\n\t\tif(!(v = valid(d)) && !(g = Gun.is(d))){\n\t\t\tif(!Object.plain(d)){ ran.err(as, \"Invalid data: \"+ check(d) +\" at \" + (as.via.back(function(at){at.get && tmp.push(at.get)}, tmp = []) || tmp.join('.'))+'.'+(to.path||[]).join('.')); return }\n\t\t\tvar seen = as.seen || (as.seen = []), i = seen.length;\n\t\t\twhile(i--){ if(d === (tmp = seen[i]).it){ v = d = tmp.link; break } }\n\t\t}\n\t\tif(k && v){ at.node = state_ify(at.node, k, s, d) } // handle soul later.\n\t\telse {\n\t\t\tif(!as.seen){ ran.err(as, \"Data at root of graph must be a node (an object).\"); return }\n\t\t\tas.seen.push(cat = {it: d, link: {}, todo: g? [] : Object.keys(d).sort().reverse(), path: (to.path||[]).slice(), up: at}); // Any perf reasons to CPU schedule this .keys( ?\n\t\t\tat.node = state_ify(at.node, k, s, cat.link);\n\t\t\t!g && cat.todo.length && to.push(cat);\n\t\t\t// ---------------\n\t\t\tvar id = as.seen.length;\n\t\t\t(as.wait || (as.wait = {}))[id] = '';\n\t\t\ttmp = (cat.ref = (g? d : k? at.ref.get(k) : at.ref))._;\n\t\t\t(tmp = (d && (d._||'')['#']) || tmp.soul || tmp.link)? resolve({soul: tmp}) : cat.ref.get(resolve, {run: as.run, /*hatch: 0,*/ v2020:1, out:{get:{'.':' '}}}); // TODO: BUG! This should be resolve ONLY soul to prevent full data from being loaded. // Fixed now?\n\t\t\t//setTimeout(function(){ if(F){ return } console.log(\"I HAVE NOT BEEN CALLED!\", path, id, cat.ref._.id, k) }, 9000); var F; // MAKE SURE TO ADD F = 1 below!\n\t\t\tfunction resolve(msg, eve){\n\t\t\t\tvar end = cat.link['#'];\n\t\t\t\tif(eve){ eve.off(); eve.rid(msg) } // TODO: Too early! Check all peers ack not found.\n\t\t\t\t// TODO: BUG maybe? Make sure this does not pick up a link change wipe, that it uses the changign link instead.\n\t\t\t\tvar soul = end || msg.soul || (tmp = (msg.$$||msg.$)._||'').soul || tmp.link || ((tmp = tmp.put||'')._||'')['#'] || tmp['#'] || (((tmp = msg.put||'') && msg.$$)? tmp['#'] : (tmp['=']||tmp[':']||'')['#']);\n\t\t\t\t!end && stun(as, msg.$);\n\t\t\t\tif(!soul && !at.link['#']){ // check soul link above us\n\t\t\t\t\t(at.wait || (at.wait = [])).push(function(){ resolve(msg, eve) }) // wait\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(!soul){\n\t\t\t\t\tsoul = [];\n\t\t\t\t\t(msg.$$||msg.$).back(function(at){\n\t\t\t\t\t\tif(tmp = at.soul || at.link){ return soul.push(tmp) }\n\t\t\t\t\t\tsoul.push(at.get);\n\t\t\t\t\t});\n\t\t\t\t\tsoul = soul.reverse().join('/');\n\t\t\t\t}\n\t\t\t\tcat.link['#'] = soul;\n\t\t\t\t!g && (((as.graph || (as.graph = {}))[soul] = (cat.node || (cat.node = {_:{}})))._['#'] = soul);\n\t\t\t\tdelete as.wait[id];\n\t\t\t\tcat.wait && setTimeout.each(cat.wait, function(cb){ cb && cb() });\n\t\t\t\tas.ran(as);\n\t\t\t};\n\t\t\t// ---------------\n\t\t}\n\t\tif(!to.length){ return as.ran(as) }\n\t\tas.turn(walk);\n\t}());\n\treturn gun;\n}\n\nfunction stun(as, id){\n\tif(!id){ return } id = (id._||'').id||id;\n\tvar run = as.root.stun || (as.root.stun = {on: Gun.on}), test = {}, tmp;\n\tas.stun || (as.stun = run.on('stun', function(){ }));\n\tif(tmp = run.on(''+id)){ tmp.the.last.next(test) }\n\tif(test.run >= as.run){ return }\n\trun.on(''+id, function(test){\n\t\tif(as.stun.end){\n\t\t\tthis.off();\n\t\t\tthis.to.next(test);\n\t\t\treturn;\n\t\t}\n\t\ttest.run = test.run || as.run;\n\t\ttest.stun = test.stun || as.stun; return;\n\t\tif(this.to.to){\n\t\t\tthis.the.last.next(test);\n\t\t\treturn;\n\t\t}\n\t\ttest.stun = as.stun;\n\t});\n}\n\nfunction ran(as){\n\tif(as.err){ ran.end(as.stun, as.root); return } // move log handle here.\n\tif(as.todo.length || as.end || !Object.empty(as.wait)){ return } as.end = 1;\n\t//(as.retry = function(){ as.acks = 0;\n\tvar cat = (as.$.back(-1)._), root = cat.root, ask = cat.ask(function(ack){\n\t\troot.on('ack', ack);\n\t\tif(ack.err && !ack.lack){ Gun.log(ack) }\n\t\tif(++acks > (as.acks || 0)){ this.off() } // Adjustable ACKs! Only 1 by default.\n\t\tif(!as.ack){ return }\n\t\tas.ack(ack, this);\n\t}, as.opt), acks = 0, stun = as.stun, tmp;\n\t(tmp = function(){ // this is not official yet, but quick solution to hack in for now.\n\t\tif(!stun){ return }\n\t\tran.end(stun, root);\n\t\tsetTimeout.each(Object.keys(stun = stun.add||''), function(cb){ if(cb = stun[cb]){cb()} }); // resume the stunned reads // Any perf reasons to CPU schedule this .keys( ?\n\t}).hatch = tmp; // this is not official yet ^\n\t//console.log(1, \"PUT\", as.run, as.graph);\n\tif(as.ack && !as.ok){ as.ok = as.acks || 9 } // TODO: In future! Remove this! This is just old API support.\n\t(as.via._).on('out', {put: as.out = as.graph, ok: as.ok && {'@': as.ok+1}, opt: as.opt, '#': ask, _: tmp});\n\t//})();\n}; ran.end = function(stun,root){\n\tstun.end = noop; // like with the earlier id, cheaper to make this flag a function so below callbacks do not have to do an extra type check.\n\tif(stun.the.to === stun && stun === stun.the.last){ delete root.stun }\n\tstun.off();\n}; ran.err = function(as, err){\n\t(as.ack||noop).call(as, as.out = { err: as.err = Gun.log(err) });\n\tas.ran(as);\n}\n\nfunction get(as){\n\tvar at = as.via._, tmp;\n\tas.via = as.via.back(function(at){\n\t\tif(at.soul || !at.get){ return at.$ }\n\t\ttmp = as.data; (as.data = {})[at.get] = tmp;\n\t});\n\tif(!as.via || !as.via._.soul){\n\t\tas.via = at.root.$.get(((as.data||'')._||'')['#'] || at.$.back('opt.uuid')())\n\t}\n\tas.via.put(as.data, as.ack, as);\n\t\n\n\treturn;\n\tif(at.get && at.back.soul){\n\t\ttmp = as.data;\n\t\tas.via = at.back.$;\n\t\t(as.data = {})[at.get] = tmp; \n\t\tas.via.put(as.data, as.ack, as);\n\t\treturn;\n\t}\n}\nfunction check(d, tmp){ return ((d && (tmp = d.constructor) && tmp.name) || typeof d) }\n\nvar u, empty = {}, noop = function(){}, turn = setTimeout.turn, valid = Gun.valid, state_ify = Gun.state.ify;\nvar iife = function(fn,as){fn.call(as||empty)}\n\t\n}());"
  },
  {
    "path": "src/root.js",
    "content": ";(function(){\n\n\nfunction Gun(o){\n\tif(o instanceof Gun){ return (this._ = {$: this}).$ }\n\tif(!(this instanceof Gun)){ return new Gun(o) }\n\treturn Gun.create(this._ = {$: this, opt: o});\n}\n\nGun.is = function($){ return ($ instanceof Gun) || ($ && $._ && ($ === $._.$)) || false }\n\nGun.version = 0.2020;\n\nGun.chain = Gun.prototype;\nGun.chain.toJSON = function(){};\n\nrequire('./shim');\nGun.valid = require('./valid');\nGun.state = require('./state');\nGun.on = require('./onto');\nGun.dup = require('./dup');\nGun.ask = require('./ask');\n\n;(function(){\n\tGun.create = function(at){\n\t\tat.root = at.root || at;\n\t\tat.graph = at.graph || {};\n\t\tat.on = at.on || Gun.on;\n\t\tat.ask = at.ask || Gun.ask;\n\t\tat.dup = at.dup || Gun.dup();\n\t\tvar gun = at.$.opt(at.opt);\n\t\tif(!at.once){\n\t\t\tat.on('in', universe, at);\n\t\t\tat.on('out', universe, at);\n\t\t\tat.on('put', map, at);\n\t\t\tGun.on('create', at);\n\t\t\tat.on('create', at);\n\t\t}\n\t\tat.once = 1;\n\t\treturn gun;\n\t}\n\tfunction universe(msg){\n\t\t// TODO: BUG! msg.out = null being set!\n\t\t//if(!F){ var eve = this; setTimeout(function(){ universe.call(eve, msg,1) },Math.random() * 100);return; } // ADD F TO PARAMS!\n\t\tif(!msg){ return }\n\t\tif(msg.out === universe){ this.to.next(msg); return }\n\t\tvar eve = this, as = eve.as, at = as.at || as, gun = at.$, dup = at.dup, tmp, DBG = msg.DBG;\n\t\t(tmp = msg['#']) || (tmp = msg['#'] = text_rand(9));\n\t\tif(dup.check(tmp)){ return } dup.track(tmp);\n\t\ttmp = msg._; msg._ = ('function' == typeof tmp)? tmp : function(){};\n\t\t(msg.$ && (msg.$ === (msg.$._||'').$)) || (msg.$ = gun);\n\t\tif(msg['@'] && !msg.put){ ack(msg) }\n\t\tif(!at.ask(msg['@'], msg)){ // is this machine listening for an ack?\n\t\t\tDBG && (DBG.u = +new Date);\n\t\t\tif(msg.put){ put(msg); return } else\n\t\t\tif(msg.get){ Gun.on.get(msg, gun) }\n\t\t}\n\t\tDBG && (DBG.uc = +new Date);\n\t\teve.to.next(msg);\n\t\tDBG && (DBG.ua = +new Date);\n\t\tif(msg.nts || msg.NTS){ return } // TODO: This shouldn't be in core, but fast way to prevent NTS spread. Delete this line after all peers have upgraded to newer versions.\n\t\tmsg.out = universe; at.on('out', msg);\n\t\tDBG && (DBG.ue = +new Date);\n\t}\n\tfunction put(msg){\n\t\tif(!msg){ return }\n\t\tvar ctx = msg._||'', root = ctx.root = ((ctx.$ = msg.$||'')._||'').root;\n\t\tif(msg['@'] && ctx.faith && !ctx.miss){ // TODO: AXE may split/route based on 'put' what should we do here? Detect @ in AXE? I think we don't have to worry, as DAM will route it on @.\n\t\t\tmsg.out = universe;\n\t\t\troot.on('out', msg);\n\t\t\treturn;\n\t\t}\n\t\tctx.latch = root.hatch; ctx.match = root.hatch = [];\n\t\tvar put = msg.put;\n\t\tvar DBG = ctx.DBG = msg.DBG, S = +new Date; CT = CT || S;\n\t\tif(put['#'] && put['.']){ /*root && root.on('put', msg);*/ return } // TODO: BUG! This needs to call HAM instead.\n\t\tDBG && (DBG.p = S);\n\t\tctx['#'] = msg['#'];\n\t\tctx.msg = msg;\n\t\tctx.all = 0;\n\t\tctx.stun = 1;\n\t\tvar nl = Object.keys(put);//.sort(); // TODO: This is unbounded operation, large graphs will be slower. Write our own CPU scheduled sort? Or somehow do it in below? Keys itself is not O(1) either, create ES5 shim over ?weak map? or custom which is constant.\n\t\tconsole.STAT && console.STAT(S, ((DBG||ctx).pk = +new Date) - S, 'put sort');\n\t\tvar ni = 0, nj, kl, soul, node, states, err, tmp;\n\t\t(function pop(o){\n\t\t\tif(nj != ni){ nj = ni;\n\t\t\t\tif(!(soul = nl[ni])){\n\t\t\t\t\tconsole.STAT && console.STAT(S, ((DBG||ctx).pd = +new Date) - S, 'put');\n\t\t\t\t\tfire(ctx);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(!(node = put[soul])){ err = ERR+cut(soul)+\"no node.\" } else\n\t\t\t\tif(!(tmp = node._)){ err = ERR+cut(soul)+\"no meta.\" } else\n\t\t\t\tif(soul !== tmp['#']){ err = ERR+cut(soul)+\"soul not same.\" } else\n\t\t\t\tif(!(states = tmp['>'])){ err = ERR+cut(soul)+\"no state.\" }\n\t\t\t\tkl = Object.keys(node||{}); // TODO: .keys( is slow\n\t\t\t}\n\t\t\tif(err){\n\t\t\t\tmsg.err = ctx.err = err; // invalid data should error and stun the message.\n\t\t\t\tfire(ctx);\n\t\t\t\t//console.log(\"handle error!\", err) // handle!\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar i = 0, key; o = o || 0;\n\t\t\twhile(o++ < 9 && (key = kl[i++])){\n\t\t\t\tif('_' === key){ continue }\n\t\t\t\tvar val = node[key], state = states[key];\n\t\t\t\tif(u === state){ err = ERR+cut(key)+\"on\"+cut(soul)+\"no state.\"; break }\n\t\t\t\tif(!valid(val)){ err = ERR+cut(key)+\"on\"+cut(soul)+\"bad \"+(typeof val)+cut(val); break }\n\t\t\t\t//ctx.all++; //ctx.ack[soul+key] = '';\n\t\t\t\tham(val, key, soul, state, msg);\n\t\t\t\t++C; // courtesy count;\n\t\t\t}\n\t\t\tif((kl = kl.slice(i)).length){ turn(pop); return }\n\t\t\t++ni; kl = null; pop(o);\n\t\t}());\n\t} Gun.on.put = put;\n\t// TODO: MARK!!! clock below, reconnect sync, SEA certify wire merge, User.auth taking multiple times, // msg put, put, say ack, hear loop...\n\t// WASIS BUG! local peer not ack. .off other people: .open\n\tfunction ham(val, key, soul, state, msg){\n\t\tvar ctx = msg._||'', root = ctx.root, graph = root.graph, lot, tmp;\n\t\tvar vertex = graph[soul] || empty, was = state_is(vertex, key, 1), known = vertex[key];\n\t\t\n\t\tvar DBG = ctx.DBG; if(tmp = console.STAT){ if(!graph[soul] || !known){ tmp.has = (tmp.has || 0) + 1 } }\n\n\t\tvar now = State(), u;\n\t\tif(state > now){\n\t\t\tsetTimeout(function(){ ham(val, key, soul, state, msg) }, (tmp = state - now) > MD? MD : tmp); // Max Defer 32bit. :(\n\t\t\tconsole.STAT && console.STAT(((DBG||ctx).Hf = +new Date), tmp, 'future');\n\t\t\treturn;\n\t\t}\n\t\tif(state < was){ /*old;*/ if(true || !ctx.miss){ return } } // but some chains have a cache miss that need to re-fire. // TODO: Improve in future. // for AXE this would reduce rebroadcast, but GUN does it on message forwarding. // TURNS OUT CACHE MISS WAS NOT NEEDED FOR NEW CHAINS ANYMORE!!! DANGER DANGER DANGER, ALWAYS RETURN! (or am I missing something?)\n\t\tif(!ctx.faith){ // TODO: BUG? Can this be used for cache miss as well? // Yes this was a bug, need to check cache miss for RAD tests, but should we care about the faith check now? Probably not.\n\t\t\tif(state === was && (val === known || L(val) <= L(known))){ /*console.log(\"same\");*/ /*same;*/ if(!ctx.miss){ return } } // same\n\t\t}\n\t\tctx.stun++; // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.\n\t\tvar aid = msg['#']+ctx.all++, id = {toString: function(){ return aid }, _: ctx}; id.toJSON = id.toString; // this *trick* makes it compatible between old & new versions.\n\t\troot.dup.track(id)['#'] = msg['#']; // fixes new OK acks for RPC like RTC.\n\t\tDBG && (DBG.ph = DBG.ph || +new Date);\n\t\troot.on('put', {'#': id, '@': msg['@'], put: {'#': soul, '.': key, ':': val, '>': state}, ok: msg.ok, _: ctx});\n\t}\n\tfunction map(msg){\n\t\tvar DBG; if(DBG = (msg._||'').DBG){ DBG.pa = +new Date; DBG.pm = DBG.pm || +new Date}\n      \tvar eve = this, root = eve.as, graph = root.graph, ctx = msg._, put = msg.put, soul = put['#'], key = put['.'], val = put[':'], state = put['>'], id = msg['#'], tmp;\n      \tif((tmp = ctx.msg) && (tmp = tmp.put) && (tmp = tmp[soul])){ state_ify(tmp, key, state, val, soul) } // necessary! or else out messages do not get SEA transforms.\n      \t//var bytes = ((graph[soul]||'')[key]||'').length||1;\n\t\tgraph[soul] = state_ify(graph[soul], key, state, val, soul);\n\t\tif(tmp = (root.next||'')[soul]){\n\t\t\t//tmp.bytes = (tmp.bytes||0) + ((val||'').length||1) - bytes;\n\t\t\t//if(tmp.bytes > 2**13){ Gun.log.once('byte-limit', \"Note: In the future, GUN peers will enforce a ~4KB query limit. Please see https://gun.eco/docs/Page\") }\n\t\t\ttmp.on('in', msg)\n\t\t}\n\t\tfire(ctx);\n\t\teve.to.next(msg);\n\t}\n\tfunction fire(ctx, msg){ var root;\n\t\tif(ctx.stop){ return }\n\t\tif(!ctx.err && 0 < --ctx.stun){ return } // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.\n\t\tctx.stop = 1;\n\t\tif(!(root = ctx.root)){ return }\n\t\tvar tmp = ctx.match; tmp.end = 1;\n\t\tif(tmp === root.hatch){ if(!(tmp = ctx.latch) || tmp.end){ delete root.hatch } else { root.hatch = tmp } }\n\t\tctx.hatch && ctx.hatch(); // TODO: rename/rework how put & this interact.\n\t\tsetTimeout.each(ctx.match, function(cb){cb && cb()}); \n\t\tif(!(msg = ctx.msg) || ctx.err || msg.err){ return }\n\t\tmsg.out = universe;\n\t\tctx.root.on('out', msg);\n\n\t\tCF(); // courtesy check;\n\t}\n\tfunction ack(msg){ // aggregate ACKs.\n\t\tvar id = msg['@'] || '', ctx, ok, tmp;\n\t\tif(!(ctx = id._)){\n\t\t\tvar dup = (dup = msg.$) && (dup = dup._) && (dup = dup.root) && (dup = dup.dup);\n\t\t\tif(!(dup = dup.check(id))){ return }\n\t\t\tmsg['@'] = dup['#'] || msg['@']; // This doesn't do anything anymore, backtrack it to something else?\n\t\t\treturn;\n\t\t}\n\t\tctx.acks = (ctx.acks||0) + 1;\n\t\tif(ctx.err = msg.err){\n\t\t\tmsg['@'] = ctx['#'];\n\t\t\tfire(ctx); // TODO: BUG? How it skips/stops propagation of msg if any 1 item is error, this would assume a whole batch/resync has same malicious intent.\n\t\t}\n\t\tctx.ok = msg.ok || ctx.ok;\n\t\tif(!ctx.stop && !ctx.crack){ ctx.crack = ctx.match && ctx.match.push(function(){back(ctx)}) } // handle synchronous acks. NOTE: If a storage peer ACKs synchronously then the PUT loop has not even counted up how many items need to be processed, so ctx.STOP flags this and adds only 1 callback to the end of the PUT loop.\n\t\tback(ctx);\n\t}\n\tfunction back(ctx){\n\t\tif(!ctx || !ctx.root){ return }\n\t\tif(ctx.stun || ctx.acks !== ctx.all){ return }\n\t\tctx.root.on('in', {'@': ctx['#'], err: ctx.err, ok: ctx.err? u : ctx.ok || {'':1}});\n\t}\n\n\tvar ERR = \"Error: Invalid graph!\";\n\tvar cut = function(s){ return \" '\"+(''+s).slice(0,9)+\"...' \" }\n\tvar L = JSON.stringify, MD = 2147483647, State = Gun.state;\n\tvar C = 0, CT, CF = function(){if(C>999 && (C/-(CT - (CT = +new Date))>1)){Gun.window && console.log(\"Warning: You're syncing 1K+ records a second, faster than DOM can update - consider limiting query.\");CF=function(){C=0}}};\n\n}());\n\n;(function(){\n\tGun.on.get = function(msg, gun){\n\t\tvar root = gun._, get = msg.get, soul = get['#'], node = root.graph[soul], has = get['.'];\n\t\tvar next = root.next || (root.next = {}), at = next[soul];\n\n\t\t// TODO: Azarattum bug, what is in graph is not same as what is in next. Fix!\n\n\t\t// queue concurrent GETs?\n\t\t// TODO: consider tagging original message into dup for DAM.\n\t\t// TODO: ^ above? In chat app, 12 messages resulted in same peer asking for `#user.pub` 12 times. (same with #user GET too, yipes!) // DAM note: This also resulted in 12 replies from 1 peer which all had same ##hash but none of them deduped because each get was different.\n\t\t// TODO: Moving quick hacks fixing these things to axe for now.\n\t\t// TODO: a lot of GET #foo then GET #foo.\"\" happening, why?\n\t\t// TODO: DAM's ## hash check, on same get ACK, producing multiple replies still, maybe JSON vs YSON?\n\t\t// TMP note for now: viMZq1slG was chat LEX query #.\n\t\t/*if(gun !== (tmp = msg.$) && (tmp = (tmp||'')._)){\n\t\t\tif(tmp.Q){ tmp.Q[msg['#']] = ''; return } // chain does not need to ask for it again.\n\t\t\ttmp.Q = {};\n\t\t}*/\n\t\t/*if(u === has){\n\t\t\tif(at.Q){\n\t\t\t\t//at.Q[msg['#']] = '';\n\t\t\t\t//return;\n\t\t\t}\n\t\t\tat.Q = {};\n\t\t}*/\n\t\tvar ctx = msg._||{}, DBG = ctx.DBG = msg.DBG;\n\t\tDBG && (DBG.g = +new Date);\n\t\t//console.log(\"GET:\", get, node, has, at);\n\t\t//if(!node && !at){ return root.on('get', msg) }\n\t\t//if(has && node){ // replace 2 below lines to continue dev?\n\t\tif(!node){ return root.on('get', msg) }\n\t\tif(has){\n\t\t\tif('string' != typeof has || u === node[has]){\n\t\t\t\tif(!((at||'').next||'')[has]){ root.on('get', msg); return }\n\t\t\t}\n\t\t\tnode = state_ify({}, has, state_is(node, has), node[has], soul);\n\t\t\t// If we have a key in-memory, do we really need to fetch?\n\t\t\t// Maybe... in case the in-memory key we have is a local write\n\t\t\t// we still need to trigger a pull/merge from peers.\n\t\t}\n\t\t//Gun.window? Gun.obj.copy(node) : node; // HNPERF: If !browser bump Performance? Is this too dangerous to reference root graph? Copy / shallow copy too expensive for big nodes. Gun.obj.to(node); // 1 layer deep copy // Gun.obj.copy(node); // too slow on big nodes\n\t\tnode && ack(msg, node);\n\t\troot.on('get', msg); // send GET to storage adapters.\n\t}\n\tfunction ack(msg, node){\n\t\tvar S = +new Date, ctx = msg._||{}, DBG = ctx.DBG = msg.DBG;\n\t\tvar to = msg['#'], id = text_rand(9), keys = Object.keys(node||'').sort(), soul = ((node||'')._||'')['#'], kl = keys.length, j = 0, root = msg.$._.root, F = (node === root.graph[soul]);\n\t\tconsole.STAT && console.STAT(S, ((DBG||ctx).gk = +new Date) - S, 'got keys');\n\t\t// PERF: Consider commenting this out to force disk-only reads for perf testing? // TODO: .keys( is slow\n\t\tnode && (function go(){\n\t\t\tS = +new Date;\n\t\t\tvar i = 0, k, put = {}, tmp;\n\t\t\twhile(i < 9 && (k = keys[i++])){\n\t\t\t\tstate_ify(put, k, state_is(node, k), node[k], soul);\n\t\t\t}\n\t\t\tkeys = keys.slice(i);\n\t\t\t(tmp = {})[soul] = put; put = tmp;\n\t\t\tvar faith; if(F){ faith = function(){}; faith.ram = faith.faith = true; } // HNPERF: We're testing performance improvement by skipping going through security again, but this should be audited.\n\t\t\ttmp = keys.length;\n\t\t\tconsole.STAT && console.STAT(S, -(S - (S = +new Date)), 'got copied some');\n\t\t\tDBG && (DBG.ga = +new Date);\n\t\t\troot.on('in', {'@': to, '#': id, put: put, '%': (tmp? (id = text_rand(9)) : u), $: root.$, _: faith, DBG: DBG});\n\t\t\tconsole.STAT && console.STAT(S, +new Date - S, 'got in');\n\t\t\tif(!tmp){ return }\n\t\t\tsetTimeout.turn(go);\n\t\t}());\n\t\tif(!node){ root.on('in', {'@': msg['#']}) } // TODO: I don't think I like this, the default lS adapter uses this but \"not found\" is a sensitive issue, so should probably be handled more carefully/individually.\n\t} Gun.on.get.ack = ack;\n}());\n\n;(function(){\n\tGun.chain.opt = function(opt){\n\t\topt = opt || {};\n\t\tvar gun = this, at = gun._, tmp = opt.peers || opt;\n\t\tif(!Object.plain(opt)){ opt = {} }\n\t\tif(!Object.plain(at.opt)){ at.opt = opt }\n\t\tif('string' == typeof tmp){ tmp = [tmp] }\n\t\tif(!Object.plain(at.opt.peers)){ at.opt.peers = {}}\n\t\tif(tmp instanceof Array){\n\t\t\topt.peers = {};\n\t\t\ttmp.forEach(function(url){\n\t\t\t\tvar p = {}; p.id = p.url = url;\n\t\t\t\topt.peers[url] = at.opt.peers[url] = at.opt.peers[url] || p;\n\t\t\t})\n\t\t}\n\t\tobj_each(opt, function each(k){ var v = this[k];\n\t\t\tif((this && this.hasOwnProperty(k)) || 'string' == typeof v || Object.empty(v)){ this[k] = v; return }\n\t\t\tif(v && v.constructor !== Object && !(v instanceof Array)){ return }\n\t\t\tobj_each(v, each);\n\t\t});\n\t\tat.opt.from = opt;\n\t\tGun.on('opt', at);\n\t\tat.opt.uuid = at.opt.uuid || function uuid(l){ return Gun.state().toString(36).replace('.','') + String.random(l||12) }\n\t\treturn gun;\n\t}\n}());\n\nvar obj_each = function(o,f){ Object.keys(o).forEach(f,o) }, text_rand = String.random, turn = setTimeout.turn, valid = Gun.valid, state_is = Gun.state.is, state_ify = Gun.state.ify, u, empty = {}, C;\n\nGun.log = function(){ return (!Gun.log.off && C.log.apply(C, arguments)), [].slice.call(arguments).join(' ') };\nGun.log.once = function(w,s,o){ return (o = Gun.log.once)[w] = o[w] || 0, o[w]++ || Gun.log(s) };\n\nif(typeof window !== \"undefined\"){ (window.GUN = window.Gun = Gun).window = window }\ntry{ if(typeof MODULE !== \"undefined\"){ MODULE.exports = Gun } }catch(e){}\nmodule.exports = Gun;\n\n(Gun.window||{}).console = (Gun.window||{}).console || {log: function(){}};\n(C = console).only = function(i, s){ return (C.only.i && i === C.only.i && C.only.i++) && (C.log.apply(C, arguments) || s) };\n\n;\"Please do not remove welcome log unless you are paying for a monthly sponsorship, thanks!\";\nGun.log.once(\"welcome\", \"Hello wonderful person! :) Thanks for using GUN, please ask for help on http://chat.gun.eco if anything takes you longer than 5min to figure out!\");\n\t\n}());"
  },
  {
    "path": "src/set.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nGun.chain.set = function(item, cb, opt){\n\tvar gun = this, root = gun.back(-1), soul, tmp;\n\tcb = cb || function(){};\n\topt = opt || {}; opt.item = opt.item || item;\n\tif(soul = ((item||'')._||'')['#']){ (item = {})['#'] = soul } // check if node, make link.\n\tif('string' == typeof (tmp = Gun.valid(item))){ return gun.get(soul = tmp).put(item, cb, opt) } // check if link\n\tif(!Gun.is(item)){\n\t\tif(Object.plain(item)){\n\t\t\titem = root.get(soul = gun.back('opt.uuid')()).put(item);\n\t\t}\n\t\treturn gun.get(soul || root.back('opt.uuid')(7)).put(item, cb, opt);\n\t}\n\tgun.put(function(go){\n\t\titem.get(function(soul, o, msg){ // TODO: BUG! We no longer have this option? & go error not handled?\n\t\t\tif(!soul){ return cb.call(gun, {err: Gun.log('Only a node can be linked! Not \"' + msg.put + '\"!')}) }\n\t\t\t(tmp = {})[soul] = {'#': soul}; go(tmp);\n\t\t},true);\n\t})\n\treturn item;\n}\n\t\n}());"
  },
  {
    "path": "src/shim.js",
    "content": ";(function(){\n\n// Shim for generic javascript utilities.\nString.random = function(l, c){\n\tvar s = '';\n\tl = l || 24; // you are not going to make a 0 length random number, so no need to check type\n\tc = c || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz';\n\twhile(l-- > 0){ s += c.charAt(Math.floor(Math.random() * c.length)) }\n\treturn s;\n}\nString.match = function(t, o){ var tmp, u;\n\tif('string' !== typeof t){ return false }\n\tif('string' == typeof o){ o = {'=': o} }\n\to = o || {};\n\ttmp = (o['='] || o['*'] || o['>'] || o['<']);\n\tif(t === tmp){ return true }\n\tif(u !== o['=']){ return false }\n\ttmp = (o['*'] || o['>']);\n\tif(t.slice(0, (tmp||'').length) === tmp){ return true }\n\tif(u !== o['*']){ return false }\n\tif(u !== o['>'] && u !== o['<']){\n\t\treturn (t >= o['>'] && t <= o['<'])? true : false;\n\t}\n\tif(u !== o['>'] && t >= o['>']){ return true }\n\tif(u !== o['<'] && t <= o['<']){ return true }\n\treturn false;\n}\nString.hash = function(s, c){ // via SO\n\tif(typeof s !== 'string'){ return }\n\t    c = c || 0; // CPU schedule hashing by\n\t    if(!s.length){ return c }\n\t    for(var i=0,l=s.length,n; i<l; ++i){\n\t      n = s.charCodeAt(i);\n\t      c = ((c<<5)-c)+n;\n\t      c |= 0;\n\t    }\n\t    return c;\n\t  }\nvar has = Object.prototype.hasOwnProperty;\nObject.plain = function(o){ return o? (o instanceof Object && o.constructor === Object) || Object.prototype.toString.call(o).match(/^\\[object (\\w+)\\]$/)[1] === 'Object' : false }\nObject.empty = function(o, n){\n\tfor(var k in o){ if(has.call(o, k) && (!n || -1==n.indexOf(k))){ return false } }\n\treturn true;\n}\nObject.keys = Object.keys || function(o){\n\tvar l = [];\n\tfor(var k in o){ if(has.call(o, k)){ l.push(k) } }\n\treturn l;\n}\n;(function(){\n\tvar u, sT = setTimeout, l = 0, c = 0\n\t, sI = (typeof setImmediate !== ''+u && setImmediate) || (function(c,f){\n\t\tif(typeof MessageChannel == ''+u){ return sT }\n\t\t(c = new MessageChannel()).port1.onmessage = function(e){ ''==e.data && f() }\n\t\treturn function(q){ f=q;c.port2.postMessage('') }\n\t}()), check = sT.check = sT.check || (typeof performance !== ''+u && performance)\n\t|| {now: function(){ return +new Date }};\n\tsT.hold = sT.hold || 9; // half a frame benchmarks faster than < 1ms?\n\tsT.poll = sT.poll || function(f){\n\t\tif((sT.hold >= (check.now() - l)) && c++ < 3333){ f(); return }\n\t\tsI(function(){ l = check.now(); f() },c=0)\n\t}\n}());\n;(function(){ // Too many polls block, this \"threads\" them in turns over a single thread in time.\n\tvar sT = setTimeout, t = sT.turn = sT.turn || function(f){ 1 == s.push(f) && p(T) }\n\t, s = t.s = [], p = sT.poll, i = 0, f, T = function(){\n\t\tif(f = s[i++]){ f() }\n\t\tif(i == s.length || 99 == i){\n\t\t\ts = t.s = s.slice(i);\n\t\t\ti = 0;\n\t\t}\n\t\tif(s.length){ p(T) }\n\t}\n}());\n;(function(){\n\tvar u, sT = setTimeout, T = sT.turn;\n\t(sT.each = sT.each || function(l,f,e,S){ S = S || 9; (function t(s,L,r){\n\t  if(L = (s = (l||[]).splice(0,S)).length){\n\t  \tfor(var i = 0; i < L; i++){\n\t  \t\tif(u !== (r = f(s[i]))){ break }\n\t  \t}\n\t  \tif(u === r){ T(t); return }\n\t  } e && e(r);\n\t}())})();\n}());\n\t\n}());"
  },
  {
    "path": "src/state.js",
    "content": ";(function(){\n\nrequire('./shim');\nfunction State(){\n\tvar t = +new Date;\n\tif(last < t){\n\t\treturn N = 0, last = t + State.drift;\n\t}\n\treturn last = t + ((N += 1) / D) + State.drift;\n}\nState.drift = 0;\nvar NI = -Infinity, N = 0, D = 999, last = NI, u; // WARNING! In the future, on machines that are D times faster than 2016AD machines, you will want to increase D by another several orders of magnitude so the processing speed never out paces the decimal resolution (increasing an integer effects the state accuracy).\nState.is = function(n, k, o){ // convenience function to get the state on a key on a node and return it.\n\tvar tmp = (k && n && n._ && n._['>']) || o;\n\tif(!tmp){ return }\n\treturn ('number' == typeof (tmp = tmp[k]))? tmp : NI;\n}\nState.ify = function(n, k, s, v, soul){ // put a key's state on a node.\n\t(n = n || {})._ = n._ || {}; // safety check or init.\n\tif(soul){ n._['#'] = soul } // set a soul if specified.\n\tvar tmp = n._['>'] || (n._['>'] = {}); // grab the states data.\n\tif(u !== k && k !== '_'){\n\t\tif('number' == typeof s){ tmp[k] = s } // add the valid state.\n\t\tif(u !== v){ n[k] = v } // Note: Not its job to check for valid values!\n\t}\n\treturn n;\n}\nmodule.exports = State;\n\t\n}());"
  },
  {
    "path": "src/valid.js",
    "content": ";(function(){\n\n// Valid values are a subset of JSON: null, binary, number (!Infinity), text,\n// or a soul relation. Arrays need special algorithms to handle concurrency,\n// so they are not supported directly. Use an extension that supports them if\n// needed but research their problems first.\nmodule.exports = function(v){\n  // \"deletes\", nulling out keys.\n  return v === null ||\n\t\"string\" === typeof v ||\n\t\"boolean\" === typeof v ||\n\t// we want +/- Infinity to be, but JSON does not support it, sad face.\n\t// can you guess what v === v checks for? ;)\n\t(\"number\" === typeof v && v != Infinity && v != -Infinity && v === v) ||\n\t(!!v && \"string\" == typeof v[\"#\"] && Object.keys(v).length === 1 && v[\"#\"]);\n}\n\t\n}());"
  },
  {
    "path": "src/websocket.js",
    "content": ";(function(){\n\nvar Gun = require('./root');\nGun.Mesh = require('./mesh');\n\n// TODO: resync upon reconnect online/offline\n//window.ononline = window.onoffline = function(){ console.log('online?', navigator.onLine) }\n\nGun.on('opt', function(root){\n\tthis.to.next(root);\n\tif(root.once){ return }\n\tvar opt = root.opt;\n\tif(false === opt.WebSocket){ return }\n\n\tvar env = Gun.window || {};\n\tvar websocket = opt.WebSocket || env.WebSocket || env.webkitWebSocket || env.mozWebSocket;\n\tif(!websocket){ return }\n\topt.WebSocket = websocket;\n\n\tvar mesh = opt.mesh = opt.mesh || Gun.Mesh(root);\n\n\tvar wire = mesh.wire || opt.wire;\n\tmesh.wire = opt.wire = open;\n\tfunction open(peer){ try{\n\t\tif(!peer || !peer.url){ return wire && wire(peer) }\n\t\tvar url = peer.url.replace(/^http/, 'ws');\n\t\tvar wire = peer.wire = new opt.WebSocket(url);\n\t\twire.onclose = function(){\n\t\t\treconnect(peer);\n\t\t\topt.mesh.bye(peer);\n\t\t};\n\t\twire.onerror = function(err){\n\t\t\treconnect(peer);\n\t\t};\n\t\twire.onopen = function(){\n\t\t\topt.mesh.hi(peer);\n\t\t}\n\t\twire.onmessage = function(msg){\n\t\t\tif(!msg){ return }\n\t\t\topt.mesh.hear(msg.data || msg, peer);\n\t\t};\n\t\treturn wire;\n\t}catch(e){ opt.mesh.bye(peer) }}\n\n\tsetTimeout(function(){ !opt.super && root.on('out', {dam:'hi'}) },1); // it can take a while to open a socket, so maybe no longer lazy load for perf reasons?\n\n\tvar wait = 2 * 999;\n\tfunction reconnect(peer){\n\t\tclearTimeout(peer.defer);\n\t\tif(!opt.peers[peer.url]){ return }\n\t\tif(doc && peer.retry <= 0){ return }\n\t\tpeer.retry = (peer.retry || opt.retry+1 || 60) - ((-peer.tried + (peer.tried = +new Date) < wait*4)?1:0);\n\t\tpeer.defer = setTimeout(function to(){\n\t\t\tif(doc && doc.hidden){ return setTimeout(to,wait) }\n\t\t\topen(peer);\n\t\t}, wait);\n\t}\n\tvar doc = (''+u !== typeof document) && document;\n});\nvar noop = function(){}, u;\n\t\n}());"
  },
  {
    "path": "test/abc.js",
    "content": "var expect = global.expect = require(\"./expect\");\nrequire('./common');"
  },
  {
    "path": "test/bug/121.js",
    "content": "/// bug-121\ndescribe('Gun', function(){\n\tvar root;\n\t(function(){\n\t\tvar env;\n\t\tif(typeof global !== 'undefined'){ env = global }\n\t\tif(typeof window !== 'undefined'){ env = window }\n\t\troot = env.window? env.window : global;\n\t\ttry{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n\t\ttry{ localStorage.clear() }catch(e){}\n\t\ttry{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n\t\ttry{ require('fs').unlinkSync('data.json') }catch(e){}\n \t\ttry{ require('../../lib/fsrm')('radatatest') }catch(e){}\n\t\ttry{ var expect = global.expect = require(\"../expect\") }catch(e){}\n\n\t\t//root.Gun = root.Gun || require('../gun');\n\t\tif(root.Gun){\n\t\t\troot.Gun = root.Gun;\n\t\t\troot.Gun.TESTING = true;\n\t\t} else {\n\t\t\troot.Gun = require('../../gun');\n\t\t\troot.Gun.TESTING = true;\n\t\t\tGun.serve = require('../../lib/serve');\n\t\t\t//require('../lib/file');\n\t\t\trequire('../../lib/store');\n\t\t\trequire('../../lib/rfs');\n//\t\t\trequire('../../sea.js');\n\t\t}\n\t}(this));\n\n\tdescribe('API - map', function(){\n\t\tit('map and put', function(done) {\n\t\t\tvar gun = Gun();\n\t\t\tvar ref = gun.get('test');\n\t\t\tvar value = {1:{v:11},2:{v:22},3:{v:33},4:{v:44},5:{v:55}};\n\t\t\tref.put(value, function(ack) {\n\t\t\t\tif (ack.err) { expect(!ack.err).to.be(true); done(); return; }\n\t\t\t\tvar vput = 100;\n\t\t\t\tref.map().get('v').put(vput /*, function(ack) { console.log('MAP ACK:!!!!!!! ', ack); }*/);\n\t\t\t\tvar total = 0;\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\tref.map().get('v').once(function(v, k) {\n\t\t\t\t\t\texpect(v === vput).to.be(true);\n\t\t\t\t\t\tif (++total === 5) { done(); }\n\t\t\t\t\t});\n\t\t\t\t}, 1000); \n\t\t\t});\n\t\t});\n\t});\n});\n\n"
  },
  {
    "path": "test/bug/1243.js",
    "content": "/**\n * Heroku CLI REQUIRED!\n * \n * NOTE: Does not work with npm installed heroku-cli\n *  - Uninstall with: npm uninstall heroku -g\n *  - Install Heroku with: curl https://cli-assets.heroku.com/install.sh | sh\n * \n * 1. Login Heroku with: heroku login\n * 2. After login you can run test\n *    like: $ mocha test/bug/1243.js \n * \n*/\n\nconst expect = require('../expect');\nconst path = require('path');\nconst http = require(\"https\");\n\nconst outputData = false;\n\nfunction request(hostname, done){\n  http.get('https://'+hostname+'/',{\n    timeout: 1000 * 60 * 5\n  }, (res) => {\n    done(res.statusCode);\n  });\n}\n \nfunction spawn(cmd, done) {\n\n  const spawn = require('child_process').spawn;\n  let args = cmd.split(\" \");\n  cmd = args.shift();\n\n  const s = spawn(cmd, args);\n  let stderrOUT = \"\";\n\n  s.stdout.on('data', (data) => {\n    saveData(data.toString());\n  });\n\n  s.stderr.on('data', (data) => {\n    saveData(data.toString());\n  });\n\n  function saveData(out){\n    stderrOUT += out.toString();\n    if(outputData) console.log(out.toString());\n  }\n\n  s.on('exit', (code) => {\n    done(stderrOUT);\n  });\n}\n  \n function makeid(length) {\n   let result = '';\n   let characters = 'abcdefghijklmnopqrstuvwxyz';\n   let charactersLength = characters.length;\n   for (let i = 0; i < length; i++) {\n    result += characters.charAt(Math.floor(Math.random() *\n      charactersLength));\n   }\n   return result;\n }\n \n describe('Heroku deploy', function() {\n   const heroku_name = 'test-gun-' + makeid(5);\n   const dir_cwd = path.join(__dirname, \"../..\");\n\n  it('create herokuapp '+ heroku_name, function(done) {\n    this.timeout(15 * 1000);\n    let c = 'heroku create ' + heroku_name;\n    spawn(c, (stdout) => {\n      if (stdout.indexOf(\"done\") > -1) {\n        done();\n    }\n    })\n  })\n \n  it('add git remote', function(done) {\n    this.timeout(15 * 1000);\n    let c = 'heroku git:remote -a '+ heroku_name;\n    spawn(c, (stdout) => {            \n      if (stdout.indexOf(\"set git\") > -1) {\n          done();\n      }\n    })\n  })\n \n  it('git push heroku', function(done) {\n    this.timeout(1000 * 60 * 2); // 2 min\n    let c = 'git push heroku master --force';\n    spawn(c, (stdout) => {\n      if (stdout.indexOf(\"deployed to Heroku\") > -1) {\n        done();\n      }\n    })\n  })  \n\n  it('fetch heroku app https', function(done) {\n    this.timeout(1000 * 60 * 5); // 2 min\n    request(heroku_name+\".herokuapp.com\",( statusCode )=>{\n      expect(statusCode).to.be(200);\n      done();\n    })\n  })  \n \n   it('destroy herokuapp ' + heroku_name, function(done) {\n    this.timeout(15 * 1000);\n\n    let c = 'heroku apps:destroy ' + heroku_name + ' --confirm=' + heroku_name;\n    spawn(c, (stdout) => {\n      if (stdout.indexOf(\"done\") > -1) {\n        done();\n      }\n    })\n   })\n })"
  },
  {
    "path": "test/bug/322.js",
    "content": "describe('Gun', function(){\n\tvar root;\n\t(function(){\n\t\tvar env;\n\t\tif(typeof global !== 'undefined'){ env = global }\n\t\tif(typeof window !== 'undefined'){ env = window }\n\t\troot = env.window? env.window : global;\n\t\ttry{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n\t\ttry{ localStorage.clear() }catch(e){}\n\t\ttry{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n\t\ttry{ require('fs').unlinkSync('data.json') }catch(e){}\n \t\ttry{ require('../../lib/fsrm')('radatatest') }catch(e){}\n\t\ttry{ var expect = global.expect = require(\"../expect\") }catch(e){}\n\n\t\t//root.Gun = root.Gun || require('../gun');\n\t\tif(root.Gun){\n\t\t\troot.Gun = root.Gun;\n\t\t\troot.Gun.TESTING = true;\n\t\t} else {\n\t\t\troot.Gun = require('../../gun');\n\t\t\troot.Gun.TESTING = true;\n\t\t\tGun.serve = require('../../lib/serve');\n//\t\t\trequire('../../lib/file');\n\t\t\trequire('../../lib/store');\n\t\t\trequire('../../lib/rfs');\n//\t\t\trequire('../../sea.js');\n\t\t}\n\t}(this));\n\n    var opt = { file: 'radatatest' };\n\n\tdescribe('API - map', function(){\n\t\tit('Save example data', function(done) {\n\t\t\tvar gun = Gun(opt);\n\t\t\tgun.get('users').set({u:1});\n\t\t\tgun.get('users').set({u:2});\n\t\t\tgun.get('users').set({u:2});\n\t\t\tgun.get('users').map().on(function(user) { user.index = 'someIndex'; });\n\t\t\tsetTimeout(function() { done(); }, 200);\n\t\t});\n\t\tit('Make sure the value \"someIndex\" not be saved in storage', function(done) {\n\t\t\tvar gun = Gun(opt), values=[];\n\t\t\tgun.get('users').map().once(function(v) { values.push(v.index); });\n\t\t\tsetTimeout(function() {\n\t\t\t\texpect(values.indexOf('someIndex')===-1).to.be(true);\n\t\t\t\tdone();\n\t\t\t}, 200);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/bug/686.js",
    "content": "describe('Gun', function(){\r\n\tvar root;\r\n\t(function(){\r\n\t\tvar env;\r\n\t\tif(typeof global !== 'undefined'){ env = global }\r\n\t\tif(typeof window !== 'undefined'){ env = window }\r\n\t\troot = env.window? env.window : global;\r\n\t\ttry{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\r\n\t\ttry{ localStorage.clear() }catch(e){}\r\n\t\ttry{ indexedDB.deleteDatabase('radatatest') }catch(e){}\r\n\t\ttry{ require('fs').unlinkSync('data.json') }catch(e){}\r\n \t\ttry{ require('../../lib/fsrm')('radatatest') }catch(e){}\r\n\t\ttry{ var expect = global.expect = require(\"../expect\") }catch(e){}\r\n\r\n\t\t//root.Gun = root.Gun || require('../gun');\r\n\t\tif(root.Gun){\r\n\t\t\troot.Gun = root.Gun;\r\n\t\t\troot.Gun.TESTING = true;\r\n\t\t} else {\r\n\t\t\troot.Gun = require('../../gun');\r\n\t\t\troot.Gun.TESTING = true;\r\n\t\t\tGun.serve = require('../../lib/serve');\r\n\t\t\t//require('../lib/file');\r\n\t\t\trequire('../../lib/store');\r\n\t\t\trequire('../../lib/rfs');\r\n\t\t\trequire('../../sea.js');\r\n\t\t}\r\n\t}(this));\r\n\tvar opt = { file: 'radatatest' };\r\n\tdescribe('SEA', function() {\r\n\t\tit('put null string', function(done) {\r\n\t\t\tvar gun = Gun(opt);\r\n\t\t\tgun.get('test').get('key').put('null', function(ack) {\r\n\t\t\t\tif (ack.err) { expect(!ack.err).to.be(true); done(); }\r\n\t\t\t\tgun.get('test').get('key').once(function(v) {\r\n\t\t\t\t\texpect(v === 'null').to.be(true);\r\n\t\t\t\t\tdone();\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\t\tit('put null string in user land', function(done) {\r\n\t\t\tvar gun = Gun(opt);\r\n\t\t\tvar user = gun.user();\r\n\t\t\tvar u={a:'usr', p:'pass'};\r\n\t\t\tvar value = 'null';\r\n\t\t\tuser.create(u.a, u.p, function(ack) {\r\n\t\t\t\tusr = user.auth(u.a, u.p, function() {\r\n\t\t\t\t\tusr.get('test').get('key').put(value, function(ack) {\r\n\t\t\t\t\t\tif (ack.err) { expect(!ack.err).to.be(true); done(); }\r\n\t\t\t\t\t\tusr.get('test').get('key').once(function(v) {\r\n\t\t\t\t\t\t\texpect(v === value).to.be(true); /// must be null string.\r\n\t\t\t\t\t\t\tdone();\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t});\r\n\t});\r\n});\r\n"
  },
  {
    "path": "test/bug/783.js",
    "content": "\n///// bug-783\n\ndescribe('Gun', function(){\n\tvar root;\n\t(function(){\n\t\tvar env;\n\t\tif(typeof global !== 'undefined'){ env = global }\n\t\tif(typeof window !== 'undefined'){ env = window }\n\t\troot = env.window? env.window : global;\n\t\ttry{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n\t\ttry{ localStorage.clear() }catch(e){}\n\t\ttry{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n\t\ttry{ require('fs').unlinkSync('data.json') }catch(e){}\n \t\ttry{ require('../../lib/fsrm')('radatatest') }catch(e){}\n\t\ttry{ var expect = global.expect = require(\"../expect\") }catch(e){}\n\n\t\t//root.Gun = root.Gun || require('../gun');\n\t\tif(root.Gun){\n\t\t\troot.Gun = root.Gun;\n\t\t\troot.Gun.TESTING = true;\n\t\t} else {\n\t\t\troot.Gun = require('../../gun');\n\t\t\troot.Gun.TESTING = true;\n\t\t\tGun.serve = require('../../lib/serve');\n\t\t\t//require('../lib/file');\n\t\t\trequire('../../lib/store');\n\t\t\trequire('../../lib/rfs');\n\t\t\trequire('../../sea.js');\n\t\t}\n\t}(this));\n\n\tdescribe('erro sea', function(){\n\t\tit('verbose console.log debugging', function(done) {\n\t\t\tvar gun = Gun({multicast:false, axe:false});\n\t\t\tvar ref = gun.get('test').get('1');\n\t\t\tvar vput = 'SEA{}';\n\t\t\tref.put(vput, function(ack, yay){ console.log('ACK: ', ack); /// must ack all\n\t\t          ref.once(function(v,k) { console.log('SALVOU k:%s, v:', k, v);\n                            expect(v===vput).to.be(true);\n\t\t\t    done();\n\t\t\t});\n\t            });\n\t\t});\n\t} );\n});\n"
  },
  {
    "path": "test/common.js",
    "content": "describe('Gun', function(){\n\tvar root;\n\t(function(){\n\t\tvar env;\n\t\tif(typeof global !== 'undefined'){ env = global }\n\t\tif(typeof window !== 'undefined'){ env = window }\n\t\troot = env.window? env.window : global;\n\t\ttry{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n\t\ttry{ localStorage.clear() }catch(e){}\n\t\ttry{ require('fs').unlinkSync('data.json') }catch(e){}\n  \ttry{ require('../lib/fsrm')('radatatest') }catch(e){}\n\t\t//root.Gun = root.Gun || require('../gun');\n\t\tif(root.Gun){\n\t\t\troot.Gun = root.Gun;\n\t\t\troot.Gun.TESTING = true;\n\t\t} else {\n\t\t\trequire('../lib/yson');\n\t\t\troot.Gun = require('../gun');\n\t\t\troot.Gun.TESTING = true;\n\t    require('../lib/store');\n\t    require('../lib/rfs');\n\t\t\t//console.log(\"UNDO THIS SO RAD & SEA RUN!\");\n\t\t\trequire('./rad/rad.js');\n\t\t\trequire('./sea/sea.js');\n\t\t}\n\t}(this));\n\t//Gun.log.squelch = true;\n\tvar gleak = {globals: {}, check: function(){ // via tobyho\n\t  var leaked = []\n\t  for (var key in gleak.globe){ if (!(key in gleak.globals)){ leaked.push(key)} }\n\t  if (leaked.length > 0){ console.log(\"GLOBAL LEAK!\", leaked); return leaked }\n\t}};\n\t(function(env){\n\t\tfor (var key in (gleak.globe = env)){ gleak.globals[key] = true }\n\t}(this));\n\n\tvar t = {};\n\n\tdescribe('Utility', function(){\n\t\tit('deleting old GUN tests (may take long time)', function(done){\n        done(); // Mocha doesn't print test until after its done, so show this first.\n    });\n    it('deleted', function(done){\n        this.timeout(60 * 1000);\n        if(!Gun.window){ return done() }\n        indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ done() }\n    });\n\t\tvar u;\n\t\t/* // causes logger to no longer log.\n\t\tit('verbose console.log debugging', function(done) {\n\n\t\t\tvar gun = Gun();\n\t\t\tvar log = root.console.log, counter = 1;\n\t\t\troot.console.log = function(a,b,c){\n\t\t\t\t--counter;\n\t\t\t\t//log(a,b,c);\n\t\t\t}\n\t\t\tGun.log.verbose = true;\n\t\t\tgun.put('bar', function(err, yay){ // intentionally trigger an error that will get logged.\n\t\t\t\texpect(counter).to.be(0);\n\n\t\t\t\tGun.log.verbose = false;\n\t\t\t\tgun.put('bar', function(err, yay){ // intentionally trigger an error that will get logged.\n\t\t\t\t\texpect(counter).to.be(0);\n\n\t\t\t\t\troot.console.log = log;\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t} );\n\t\t*/\n\n\t\tdescribe('YSON', function(){\n\t\t\tit('parse', function(){\n\t\t\t\t//var json = require('fs').readFileSync('./radix.json').toString();\n\t\t\t\t//var json = require('fs').readFileSync('./data.json').toString();\n\t\t\t\t//var json = require('fs').readFileSync('./big.json').toString();\n\t\t\t\t//var json = require('fs').readFileSync('./stats.json').toString();\n\t\t\t\t//var json = require('fs').readFileSync('./video.json').toString();\n\t\t\t});\n\t\t\tit('backslash', function(done){\n\t\t\t\tvar o = {z:\"test\\\"wow\\\\\"};\n\t\t\t\tJSON.stringifyAsync(o, function(err,t){\n\t\t\t\t\tJSON.parseAsync(t, function(err,data){\n\t\t\t\t\t\texpect(data).to.be.eql(o);\n\t\t\t\t\t\tnext();\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\tfunction next(){\n\t\t\t\t\tJSON.parseAsync('{\"webRTCsdp\":\"v=0\\r\\no=-\"}', function(err,data){\n\t\t\t\t\t\tvar o = {webRTCsdp: 'v=0\\r\\no=-'};\n\t\t\t\t\t\texpect(data).to.be.eql(o);\n\t\t\t\t\t\tJSON.stringifyAsync(o, function(err,t){\n\t\t\t\t\t\t\texpect(JSON.parse(t)).to.be.eql(o);\n\t\t\t\t\t\t\texpect(t).to.be(JSON.stringify(o));\n\t\t\t\t\t\t\texpect(t).to.be('{\"webRTCsdp\":\"v=0\\\\r\\\\no=-\"}');\n\t\t\t\t\t\t\tJSON.parseAsync(t, function(err,d){\n\t\t\t\t\t\t\t\texpect(d).to.be.eql(o);\n\t\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t});\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t});\n\t\t\tit('stringify', function(done){\n\t\t\t\tfunction Foo(){}; Foo.prototype.toJSON = function(){};\n\t\t\t\t//var obj = {\"what\\\"lol\": {\"a\": 1, \"b\": true, \"c\": false, \"d\": null, \"wow\": [{\"z\": 9}, true, \"hi\", 3.3]}};\n\t\t\t\tvar obj = {\"what\": {\"a\": 1, \"b\": true, \"c\": false, \"d\": null, \"wow\": [{\"z\": 9}, true, \"hi\", 3.3]}};\n\t\t\t\tvar obj = [{x:\"test 😎\\\\😄🔥\",z:\"test\\\\\",\"what\\\"lol\": {\"0\": 1.01},a:true,b: new Foo,c:3,y:\"yes\",\"get\":{\"#\":\"chat\"},wow:undefined,foo:[1,function(){}, function(){}, 'go'],blah:{a:5,toJSON:function(){ return 9 }}}, {webRTCsdp: \"v=0\\r\\no=-\"}, [[]], 10e9, NaN];\n\t\t\t\tJSON.stringifyAsync(obj, function(err, text){\n\t\t\t\t\tJSON.parseAsync(text, function(err, data){\n\t\t\t\t\t\texpect(data).to.be.eql([{x:\"test 😎\\\\😄🔥\",z:\"test\\\\\",\"what\\\"lol\": {\"0\": 1.01},a:true,c:3,y:\"yes\",\"get\":{\"#\":\"chat\"},foo:[1,null,null,'go'],blah:9}, {webRTCsdp: \"v=0\\r\\no=-\"}, [[]], 10e9, null]);\n\t\t\t\t\t\tvar obj = {a: [], b: [\"\"], c: [\"\", 1], d: [1, \"\"], e: {\"\":[]}, \"a\\\"b\": {0: 1}, wow: {'': {cool: 1}}};obj.lol = {0: {sweet: 9}};obj.wat = {\"\": 'cool'};obj.oh = {phew: {}, \"\": {}};\n\t\t\t\t\t\tJSON.stringifyAsync(obj, function(err, text2){\n\t\t\t\t\t\t\tJSON.parseAsync(text2, function(err, data){\n\t\t\t\t\t\t\t\texpect(data).to.be.eql(obj);\n\t\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tdescribe('Type Check', function(){\n\t\t\tit('random text',function(){\n\t\t\t\texpect(String.random().length).to.be(24);\n\t\t\t\texpect(String.random(11).length).to.be(11);\n\t\t\t\texpect(String.random(4).length).to.be(4);\n\t\t\t\tt.tr = String.random(2,'as'); expect((t.tr=='as'||t.tr=='aa'||t.tr=='sa'||t.tr=='ss')).to.be.ok();\n\t\t\t});\n\t\t\tit('match text',function(){\n\t\t\t\texpect(String.match(\"user/mark\", 'user/mark')).to.be.ok();\n\t\t\t\texpect(String.match(\"user/mark/nadal\", {'=': 'user/mark'})).to.not.be.ok();\n\t\t\t\texpect(String.match(\"user/mark/nadal\", {'*': 'user/'})).to.be.ok();\n\t\t\t\texpect(String.match(\"email/mark@gunDB.io\", {'*': 'user/'})).to.not.be.ok();\n\t\t\t\texpect(String.match(\"user/mark/nadal\", {'>': 'user/j', '<': 'user/o'})).to.be.ok();\n\t\t\t\texpect(String.match(\"user/timber/nadal\", {'>': 'user/c', '<': 'user/j'})).to.not.be.ok();\n\t\t\t\texpect(String.match(\"user/timber/nadal\", {'>': 'user/m', '<': 'user/u'})).to.be.ok();\n\t\t\t\texpect(String.match(\"user/mark/nadal\", {'>': 'user/a', '<': 'user/c'})).to.not.be.ok();\n\t\t\t\texpect(String.match(\"mary\", {'<': 'm'})).to.not.be.ok();\n\t\t\t\texpect(String.match(\"mary\", {'>': 'm'})).to.be.ok();\n\t\t\t\texpect(String.match(\"m\", {'>': 'm'})).to.be.ok(); // lex is inclusive because it evaluates stricter (=) to looser (>) comparisons, see docs.\n\t\t\t\texpect(String.match(\"m\", {'<': 'm'})).to.be.ok();  // lex is inclusive because it evaluates stricter (=) to looser (<) comparisons, see docs.\n\t\t\t\treturn; // below is OLD bloat, still available in lib/match.js\n\t\t\t});\n\t\t\tit('plain object',function(){\n\t\t\t\texpect(Object.plain({})).to.be(true);\n\t\t\t\texpect(Object.plain({a:1})).to.be(true);\n\t\t\t\texpect(Object.plain(u)).to.be(false);\n\t\t\t\texpect(Object.plain()).to.be(false);\n\t\t\t\texpect(Object.plain(undefined)).to.be(false);\n\t\t\t\texpect(Object.plain(null)).to.be(false);\n\t\t\t\texpect(Object.plain(NaN)).to.be(false);\n\t\t\t\texpect(Object.plain(0)).to.be(false);\n\t\t\t\texpect(Object.plain(1)).to.be(false);\n\t\t\t\texpect(Object.plain('')).to.be(false);\n\t\t\t\texpect(Object.plain('a')).to.be(false);\n\t\t\t\texpect(Object.plain([])).to.be(false);\n\t\t\t\texpect(Object.plain([1])).to.be(false);\n\t\t\t\texpect(Object.plain(false)).to.be(false);\n\t\t\t\texpect(Object.plain(true)).to.be(false);\n\t\t\t\texpect(Object.plain(function(){})).to.be(false);\n\t\t\t\texpect(Object.plain(new Date())).to.be(false);\n\t\t\t\texpect(Object.plain(/regex/)).to.be(false);\n\t\t\t\tthis.document && expect(Object.plain(document.createElement('div'))).to.be(false);\n\t\t\t\texpect(Object.plain(new (function Class(){ this.x = 1; this.y = 2 })())).to.be(true);\n\t\t\t});\n\t\t\tit('empty',function(){\n\t\t\t\texpect(Object.empty()).to.be(true);\n\t\t\t\texpect(Object.empty({a:false})).to.be(false);\n\t\t\t\texpect(Object.empty({a:false},['a'])).to.be(true);\n\t\t\t\texpect(Object.empty({a:false},['a'])).to.be(true);\n\t\t\t\texpect(Object.empty({a:false,b:1},['a'])).to.be(false);\n\t\t\t\texpect(Object.empty({a:false,b:1},['a'])).to.be(false);\n\t\t\t\texpect(Object.empty({a:false,b:1},['a','b'])).to.be(true);\n\t\t\t\texpect(Object.empty({a:false,b:1,c:3},['a','b'])).to.be(false);\n\t\t\t\texpect(Object.empty({1:1},'danger')).to.be(false);\n\t\t\t});\n\t\t});\n\t\tdescribe('Functions', function(){\n\t\t\t/*\n\t\t\tit.skip('sum',function(done){ // deprecate?\n\t\t\t\tvar obj = {a:2, b:2, c:3, d: 9};\n\t\t\t\tGun.obj.map(obj, function(num, key){\n\t\t\t\t\tsetTimeout(this.add(function(){\n\t\t\t\t\t\tthis.done(null, num * num);\n\t\t\t\t\t}, key), parseInt((\"\"+Math.random()).substring(2,5)));\n\t\t\t\t}, Gun.fn.sum(function(err, val){\n\t\t\t\t\texpect(val.a).to.eql(4);\n\t\t\t\t\texpect(val.b).to.eql(4);\n\t\t\t\t\texpect(val.c).to.eql(9);\n\t\t\t\t\texpect(val.d).to.eql(81);\n\t\t\t\t\tdone();\n\t\t\t\t}));\n\t\t\t});\n\t\t\t*/\n\t\t});\n\t\tdescribe('On', function(){\n\t\t\tit('subscribe', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tdone.first = true;\n\t\t\t\t\texpect(a).to.be(1);\n\t\t\t\t\tthis.to.next(a);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\texpect(a).to.be(1);\n\t\t\t\t\texpect(done.first).to.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t\te.on('foo', 1);\n\t\t\t});\n\t\t\tit('unsubscribe', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tthis.off();\n\t\t\t\t\tdone.first = a;\n\t\t\t\t\texpect(a).to.be(1);\n\t\t\t\t\tthis.to.next(a);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tvar to = this;\n\t\t\t\t\texpect(a).to.be(done.second? 2 : 1);\n\t\t\t\t\texpect(done.first).to.be(1);\n\t\t\t\t\tdone.second = true;\n\t\t\t\t\tif(a === 2){\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\texpect(e.tag.foo.to === to).to.be.ok();\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t}, 10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\te.on('foo', 1);\n\t\t\t\te.on('foo', 2);\n\t\t\t});\n\t\t\tit('stun', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tif(2 === a){\n\t\t\t\t\t\tdone.first2 = true;\n\t\t\t\t\t\tthis.to.next(a);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\texpect(done.second).to.not.be.ok();\n\t\t\t\t\t\texpect(done.second2).to.be.ok();\n\t\t\t\t\t\texpect(done.first2).to.be.ok();\n\t\t\t\t\t\tdone();\n\t\t\t\t\t},10);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tif(2 === a){\n\t\t\t\t\t\tdone.second2 = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone.second = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\te.on('foo', 1);\n\t\t\t\te.on('foo', 2);\n\t\t\t});\n\t\t\tit('resume', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\texpect(done.second).to.not.be.ok();\n\t\t\t\t\t\tto.next(a);\n\t\t\t\t\t},10);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tdone.second = true;\n\t\t\t\t\texpect(a).to.be(1);\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t\te.on('foo', 1);\n\t\t\t});\n\t\t\tit('double resume', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tif(1 === a){\n\t\t\t\t\t\t\tdone.first1 = true;\n\t\t\t\t\t\t\texpect(done.second).to.not.be.ok();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(2 === a){\n\t\t\t\t\t\t\tdone.first2 = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tto.next(a);\n\t\t\t\t\t},10);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tdone.second = true;\n\t\t\t\t\tif(1 === a){\n\t\t\t\t\t\texpect(done.first2).to.not.be.ok();\n\t\t\t\t\t\tdone.second1 = true;\n\t\t\t\t\t}\n\t\t\t\t\tif(2 === a){\n\t\t\t\t\t\texpect(done.first2).to.be.ok();\n\t\t\t\t\t\tif(done.second1){\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\te.on('foo', 1);\n\t\t\t\te.on('foo', 2);\n\t\t\t});\n\t\t\tit('double resume different event', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tdone.first1 = true;\n\t\t\t\t\t\tto.next(a);\n\t\t\t\t\t},10);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tif(1 === a){\n\t\t\t\t\t\texpect(done.first1).to.be.ok();\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\te.on('foo', 1);\n\t\t\t\te.on('bar', 2);\n\t\t\t});\n\t\t\tit('resume params', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\texpect(done.second).to.not.be.ok();\n\t\t\t\t\t\tto.next(0);\n\t\t\t\t\t},10);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tdone.second = true;\n\t\t\t\t\texpect(a).to.be(0);\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t\te.on('foo', 1);\n\t\t\t});\n\t\t\tit('map', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tObject.keys(a.it).forEach(function(f){var v = a.it[f];\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\tvar emit = {field: 'where', soul: f};\n\t\t\t\t\t\t\tto.next(emit);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tto.next({node: a.soul});\n\t\t\t\t\t},100);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tif('a' == a.node){\n\t\t\t\t\t\tdone.a = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\texpect(done.a).to.be.ok();\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\te.on('foo', {field: 'where', it: {a: 1, b: 2}});\n\t\t\t});\n\t\t\tit('map synchronous', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tObject.keys(a.node).forEach(function(f){var v = a.node[f];\n\t\t\t\t\t\t//setTimeout(function(){\n\t\t\t\t\t\t\tvar emit = {field: 'where', soul: f};\n\t\t\t\t\t\t\tto.next(emit);\n\t\t\t\t\t\t//},10);\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tto.next({node: a.soul});\n\t\t\t\t\t},100);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\texpect(this.as.hi).to.be(1);\n\t\t\t\t\tif('a' == a.node){\n\t\t\t\t\t\tdone.a = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\texpect(done.a).to.be.ok();\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t}, {hi: 1}).on.on('foo', {field: 'where', node: {a: 1, b: 2}});\n\t\t\t});\n\t\t\tit('synchronous async', function(done){\n\t\t\t\tvar e = {on: Gun.on};\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\texpect(a.b).to.be(5);\n\t\t\t\t\tdone.first = true;\n\t\t\t\t\tthis.to.next(a);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a, ev){\n\t\t\t\t\texpect(a.b).to.be(5);\n\t\t\t\t\tdone.second = true;\n\t\t\t\t\tvar to = this.to;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tto.next({c: 9, again: a.again});\n\t\t\t\t\t},100);\n\t\t\t\t});\n\t\t\t\te.on('foo', function(a){\n\t\t\t\t\tthis.off();\n\t\t\t\t\texpect(a.again).to.not.be.ok();\n\t\t\t\t\texpect(a.c).to.be(9);\n\t\t\t\t\texpect(done.first).to.be.ok();\n\t\t\t\t\texpect(done.second).to.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t}).on.on('foo', {b: 5}).on.on('foo', {b:5, again: true});\n\t\t\t});\n\t\t});\n\t\tdescribe('flow', function(){\n\t\t\tvar i = 0;\n\t\t\tfunction flow(){\n\t\t\t\tvar f = function(arg){\n\t\t\t\t\tvar cb = f.cb? f.cb.fn : f.fn;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tf.cb = cb;\n\t\t\t\t\t\tvar ff = flow();\n\t\t\t\t\t\tff.f = f;\n\t\t\t\t\t\tcb(ff);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(f.f){\n\t\t\t\t\t\tf.f(arg);\n\t\t\t\t\t\tf.cb = 0;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}, cb;\n\t\t\t\tf.flow = function(fn){\n\t\t\t\t\tcb = (cb || f).fn = fn;\n\t\t\t\t\treturn f;\n\t\t\t\t};\n\t\t\t\treturn f;\n\t\t\t}\n\t\t\tit('intermittent interruption', function(done){\n\t\t\t\tvar f = flow();\n\t\t\t\t//var f = {flow: flow}\n\t\t\t\tf.flow(function(f){\n\t\t\t\t\t//console.log(1);\n\t\t\t\t\tf.flow(function(f){\n\t\t\t\t\t\t//console.log(2);\n\t\t\t\t\t\tf({yes: 'please'});\n\t\t\t\t\t});\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tf.flow(function(f){\n\t\t\t\t\t\t\t//console.log(2.1);\n\t\t\t\t\t\t\tf({forever: 'there'});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tf({strange: 'places'});\n\t\t\t\t\t\t//console.log(\"-----\");\n\t\t\t\t\t\tf({earlier: 'location'});\n\t\t\t\t\t},100);\n\t\t\t\t});\n\t\t\t\tf.flow(function(f){\n\t\t\t\t\t//console.log(3);\n\t\t\t\t\tf({ok: 'now'});\n\t\t\t\t});\n\t\t\t\tf.flow(function(f){\n\t\t\t\t\t//console.log(4);\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tf({hello: 'world'});\n\t\t\t\t}, 100);\n\t\t\t});\n\t\t\tvar i = 0;\n\t\t\t;(function(exports){\n\t\t\t\tfunction next(arg){ var n = this;\n\t\t\t\t\tif(arg instanceof Function){\n\t\t\t\t\t\tif(!n.fn){ return n.fn = arg, n }\n\t\t\t\t\t\tvar f = {next: next, fn: arg, first: n.first || n};\n\t\t\t\t\t\tn.last = (n.last || n).to = f;\n\t\t\t\t\t\treturn n;\n\t\t\t\t\t}\n\t\t\t\t\tif(n.fn){\n\t\t\t\t\t\tvar sub = {next: next, from: n.to || (n.first || {}).from};\n\t\t\t\t\t\tn.fn(sub);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(n.from){\n\t\t\t\t\t\tn.from.next(arg);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\texports.next = next;\n\t\t\t}(Gun));\n\t\t\tit('intermittent interruptions', function(done){\n\t\t\t\t//var f = flow();\n\t\t\t\tvar f = {next: Gun.next}; // for now\n\t\t\t\tf.next(function(f){\n\t\t\t\t\t//console.log(1, f);\n\t\t\t\t\tf.next(function(f){\n\t\t\t\t\t\t//console.log(2, f);\n\t\t\t\t\t\tf.next({yes: 'please'});\n\t\t\t\t\t});\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tf.next(function(f){\n\t\t\t\t\t\t\t//console.log(2.1, f);\n\t\t\t\t\t\t\tf.next({forever: 'there'});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tf.next({strange: 'places'});\n\t\t\t\t\t\t//console.log(\"-----\");\n\t\t\t\t\t\tf.next({earlier: 'location'});\n\t\t\t\t\t},100);\n\t\t\t\t});\n\t\t\t\tf.next(function(f){\n\t\t\t\t\t//console.log(3);\n\t\t\t\t\tf.next({ok: 'now'});\n\t\t\t\t});\n\t\t\t\tf.next(function(f){\n\t\t\t\t\t//console.log(4);\n\t\t\t\t\tif(!done.a){ return done.a = true }\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tf.next({hello: 'world'});\n\t\t\t\t}, 100);\n\t\t\t});\n\t\t});\n\t\tdescribe('Gun Safety', function(){\n\t\t\t/* WARNING NOTE: Internal API has significant breaking changes! */\n\n\t\t\tvar gun = Gun();\n\t\t\tit('is',function(){\n\t\t\t\texpect(Gun.is(gun)).to.be(true);\n\t\t\t\texpect(Gun.is(true)).to.be(false);\n\t\t\t\texpect(Gun.is(false)).to.be(false);\n\t\t\t\texpect(Gun.is(0)).to.be(false);\n\t\t\t\texpect(Gun.is(1)).to.be(false);\n\t\t\t\texpect(Gun.is('')).to.be(false);\n\t\t\t\texpect(Gun.is('a')).to.be(false);\n\t\t\t\texpect(Gun.is(Infinity)).to.be(false);\n        expect(Gun.is(-Infinity)).to.be(false);\n\t\t\t\texpect(Gun.is(NaN)).to.be(false);\n\t\t\t\texpect(Gun.is([])).to.be(false);\n\t\t\t\texpect(Gun.is([1])).to.be(false);\n\t\t\t\texpect(Gun.is({})).to.be(false);\n\t\t\t\texpect(Gun.is({a:1})).to.be(false);\n\t\t\t\texpect(Gun.is(function(){})).to.be(false);\n\t\t\t});\n\t\t\tit('valid',function(){\n\t\t\t\texpect(Gun.valid(false)).to.be(true);\n\t\t\t\texpect(Gun.valid(true)).to.be(true);\n\t\t\t\texpect(Gun.valid(0)).to.be(true);\n\t\t\t\texpect(Gun.valid(1)).to.be(true);\n\t\t\t\texpect(Gun.valid('')).to.be(true);\n\t\t\t\texpect(Gun.valid('a')).to.be(true);\n\t\t\t\texpect(Gun.valid({'#':'somesoulidhere'})).to.be('somesoulidhere');\n\t\t\t\texpect(Gun.valid({'#':'somesoulidhere', and: 'nope'})).to.be(false);\n\t\t\t\texpect(Gun.valid(Infinity)).to.be(false); // boohoo :(\n        expect(Gun.valid(-Infinity)).to.be(false); // boohoo :(\n\t\t\t\texpect(Gun.valid(NaN)).to.be(false);\n\t\t\t\texpect(Gun.valid([])).to.be(false);\n\t\t\t\texpect(Gun.valid([1])).to.be(false);\n\t\t\t\texpect(Gun.valid({})).to.be(false);\n\t\t\t\texpect(Gun.valid({a:1})).to.be(false);\n\t\t\t\texpect(Gun.valid(function(){})).to.be(false);\n\t\t\t});\n\t\t\tit('is link',function(){\n\t\t\t\texpect(Gun.valid({'#':'somesoulidhere'})).to.be('somesoulidhere');\n\t\t\t\texpect(Gun.valid({'#':'somethingelsehere'})).to.be('somethingelsehere');\n\t\t\t\texpect('string' == typeof Gun.valid({'#':'somesoulidhere', and: 'nope'})).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid({or: 'nope', '#':'somesoulidhere'})).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid(false)).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid(true)).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid('')).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid('a')).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid(0)).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid(1)).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid(Infinity)).to.be(false); // boohoo :(\n        expect('string' == typeof Gun.valid(-Infinity)).to.be(false); // boohoo :(\n\t\t\t\texpect('string' == typeof Gun.valid(NaN)).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid([])).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid([1])).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid({})).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid({a:1})).to.be(false);\n\t\t\t\texpect('string' == typeof Gun.valid(function(){})).to.be(false);\n\t\t\t});\n\t\t\tit.skip('is lex',function(){\n\t\t\t\texpect(Gun.is.lex({'#': 'soul'})).to.eql({soul: 'soul'});\n\t\t\t\texpect(Gun.is.lex({'.': 'field'})).to.eql({field: 'field'});\n\t\t\t\texpect(Gun.is.lex({'=': 'value'})).to.eql({value: 'value'});\n\t\t\t\texpect(Gun.is.lex({'>': 'state'})).to.eql({state: 'state'});\n\t\t\t\texpect(Gun.is.lex({'#': {'=': 'soul'}})).to.eql({soul: {'=': 'soul'}});\n\t\t\t\texpect(Gun.is.lex({'#': {'=': 'soul'}, '.': []})).to.be(false);\n\t\t\t\texpect(Gun.is.lex({'#': {'=': 'soul'}, 'asdf': 'oye'})).to.be(false);\n\t\t\t\texpect(Gun.is.lex()).to.be(false);\n\t\t\t\texpect(Gun.is.lex('')).to.be(false);\n\t\t\t});\n\t\t\tit.skip('is lex ify',function(){\n\t\t\t\texpect(Gun.is.lex.ify({'#': 'soul', '.': 'field', soul: 'foo', field: 'field', state: 0})).to.eql({'#': 'soul', '.': 'field', '>': 0});\n\t\t\t});\n\t\t});\n\t});\n\tdescribe('ify', function(){\n\t\tconsole.log(\"TODO: BUG! Upgrade IFY tests to new internal API!\");\n\t\treturn;\n\n\t\tvar test, gun = Gun();\n\n\t\tit('null', function(done){\n\t\t\tGun.ify(null, function(err, ctx){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('basic', function(done){\n\t\t\tvar data = {a: false, b: true, c: 0, d: 1, e: '', f: 'g', h: null};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(ctx.err).to.not.be.ok();\n\t\t\t\texpect(ctx.root).to.eql(data);\n\t\t\t\texpect(ctx.root === data).to.not.ok();\n\t\t\t\tdone();\n\t\t\t}, {pure: true});\n\t\t});\n\n\t\tit('basic soul', function(done){\n\t\t\tvar data = {_: {'#': 'SOUL'}, a: false, b: true, c: 0, d: 1, e: '', f: 'g', h: null};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(ctx.err).to.not.be.ok();\n\n\t\t\t\texpect(ctx.root).to.eql(data);\n\t\t\t\texpect(ctx.root === data).to.not.be.ok();\n\t\t\t\texpect(Gun.node.soul(ctx.root) === Gun.node.soul(data));\n\t\t\t\tdone();\n\t\t\t}, {pure: true});\n\t\t});\n\n\t\tit('arrays', function(done){\n\t\t\tvar data = {before: {path: 'kill'}, one: {two: {lol: 'troll', three: [9, 8, 7, 6, 5]}}};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\texpect((err.err || err).indexOf(\"one.two.three\")).to.not.be(-1);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('undefined', function(done){\n\t\t\tvar data = {z: undefined, x: 'bye'};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('NaN', function(done){\n\t\t\tvar data = {a: NaN, b: 2};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('Infinity', function(done){ // SAD DAY PANDA BEAR :( :( :(... Mark wants Infinity. JSON won't allow.\n\t\t\tvar data = {a: 1, b: Infinity};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('function', function(done){\n\t\t\tvar data = {c: function(){}, d: 'hi'};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('extraneous', function(done){\n\t\t\tvar data = {_: {'#': 'shhh', meta: {yay: 1}}, sneak: true};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\texpect(err).to.not.be.ok(); // extraneous metadata needs to be stored, but it can't be used for data.\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('document', function(done){\n\t\t\tvar data = {users: {1: {where: {lat: Math.random(), lng: Math.random(), i: 1}}}};\n\t\t\tGun.ify(data, function(err, ctx){\n\t\t\t\tvar soul, node;\n\t\t\t\texpect(soul = Gun.val.link.is(ctx.root.users)).to.be.ok();\n\t\t\t\tnode = ctx.graph[soul];\n\t\t\t\texpect(soul = Gun.val.link.is(node[1])).to.be.ok();\n\t\t\t\tnode = ctx.graph[soul];\n\t\t\t\texpect(soul = Gun.val.link.is(node.where)).to.be.ok();\n\t\t\t\tnode = ctx.graph[soul];\n\t\t\t\texpect(node.lat).to.be.ok();\n\t\t\t\texpect(node.lng).to.be.ok();\n\t\t\t\texpect(node.i).to.be(1);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\treturn; // TODO! Fix GUN to handle this!\n\t\tdata = {};\n\t\tdata.sneak = false;\n\t\tdata.both = {inside: 'meta data'};\n\t\tdata._ = {'#': 'shhh', data: {yay: 1}, spin: data.both};\n\t\ttest = Gun.ify(data);\n\t\texpect(test.err.meta).to.be.ok(); // TODO: Fail: this passes, somehow? Fix ify code!\n\t});\n\n\tdescribe('Schedule', function(){\n\t\tconsole.log(\"TODO: BUG! Upgrade SCHEDULE tests to new internal API!\");\n\t\treturn;\n\t\tit('one', function(done){\n\t\t\tGun.schedule(Gun.time.is(), function(){\n\t\t\t\texpect(true).to.be(true);\n\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t});\n\t\t});\n\n\t\tit('many', function(done){\n\t\t\tGun.schedule(Gun.time.is() + 50, function(){\n\t\t\t\tdone.first = true;\n\t\t\t});\n\t\t\tGun.schedule(Gun.time.is() + 100, function(){\n\t\t\t\tdone.second = true;\n\t\t\t});\n\t\t\tGun.schedule(Gun.time.is() + 200, function(){\n\t\t\t\tdone.third = true;\n\t\t\t\texpect(done.first).to.be(true);\n\t\t\t\texpect(done.second).to.be(true);\n\t\t\t\texpect(done.third).to.be(true);\n\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('Union', function(){\n\t\tconsole.log(\"TODO: BUG! Upgrade UNION tests to new internal API!\");\n\t\treturn;\n\t\tvar gun = Gun();\n\n\t\tit('fail', function(){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\ta: 'cheating'\n\t\t\t\t\t}},\n\t\t\t\t\ta: 0\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf']).to.not.be.ok();\n\t\t\tvar ctx = Gun.HAM.graph(gun, prime);\n\t\t\texpect(ctx).to.not.be.ok();\n\t\t});return;\n\n\t\tit('basic', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\ta: Gun.time.is()\n\t\t\t\t\t}},\n\t\t\t\t\ta: 0\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf']).to.not.be.ok();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(gun.__.graph['asdf'].a).to.be(0);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('disjoint', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\tb: Gun.time.is()\n\t\t\t\t\t}},\n\t\t\t\t\tb: 'c'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf'].a).to.be(0);\n\t\t\texpect(gun.__.graph['asdf'].b).to.not.be.ok();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(gun.__.graph['asdf'].a).to.be(0);\n\t\t\t\texpect(gun.__.graph['asdf'].b).to.be('c');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('mutate', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\tb: Gun.time.is()\n\t\t\t\t\t}},\n\t\t\t\t\tb: 'd'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf'].b).to.be('c');\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(gun.__.graph['asdf'].b).to.be('d');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('disjoint past', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\tx: 0 // beginning of time!\n\t\t\t\t\t}},\n\t\t\t\t\tx: 'hi'\n\t\t\t\t}\n\t\t\t}\n\t\t\texpect(gun.__.graph['asdf'].x).to.not.be.ok();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(gun.__.graph['asdf'].x).to.be('hi');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('past', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\tx: Gun.time.is() - (60 * 1000) // above lower boundary, below now or upper boundary.\n\t\t\t\t\t}},\n\t\t\t\t\tx: 'hello'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf'].x).to.be('hi');\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(gun.__.graph['asdf'].x).to.be('hello');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('future', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\tx: Gun.time.is() + (200) // above now or upper boundary, aka future.\n\t\t\t\t\t}},\n\t\t\t\t\tx: 'how are you?'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf'].x).to.be('hello');\n\t\t\tvar now = Gun.time.is();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(Gun.time.is() - now).to.be.above(100);\n\t\t\t\texpect(gun.__.graph['asdf'].x).to.be('how are you?');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\t\tvar to = 5000;\n\t\tit('disjoint future', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\ty: Gun.time.is() + (200) // above now or upper boundary, aka future.\n\t\t\t\t\t}},\n\t\t\t\t\ty: 'goodbye'\n\t\t\t\t}\n\t\t\t}\n\t\t\texpect(gun.__.graph['asdf'].y).to.not.be.ok();\n\t\t\tvar now = Gun.time.is();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(Gun.time.is() - now).to.be.above(100);\n\t\t\t\texpect(gun.__.graph['asdf'].y).to.be('goodbye');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('disjoint future max', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\ty: Gun.time.is() + (2), // above now or upper boundary, aka future.\n\t\t\t\t\t\tz: Gun.time.is() + (200) // above now or upper boundary, aka future.\n\t\t\t\t\t}},\n\t\t\t\t\ty: 'bye',\n\t\t\t\t\tz: 'who'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf'].y).to.be('goodbye');\n\t\t\texpect(gun.__.graph['asdf'].z).to.not.be.ok();\n\t\t\tvar now = Gun.time.is();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(Gun.time.is() - now).to.be.above(100);\n\t\t\t\texpect(gun.__.graph['asdf'].y).to.be('bye');\n\t\t\t\texpect(gun.__.graph['asdf'].z).to.be('who');\n\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t});\n\t\t});\n\n\t\tit('future max', function(done){\n\t\t\tvar prime = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>':{\n\t\t\t\t\t\tw: Gun.time.is() + (2), // above now or upper boundary, aka future.\n\t\t\t\t\t\tx: Gun.time.is() - (60 * 1000), // above now or upper boundary, aka future.\n\t\t\t\t\t\ty: Gun.time.is() + (200), // above now or upper boundary, aka future.\n\t\t\t\t\t\tz: Gun.time.is() + (50) // above now or upper boundary, aka future.\n\t\t\t\t\t}},\n\t\t\t\t\tw: true,\n\t\t\t\t\tx: 'nothing',\n\t\t\t\t\ty: 'farewell',\n\t\t\t\t\tz: 'doctor who'\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['asdf'].w).to.not.be.ok();\n\t\t\texpect(gun.__.graph['asdf'].x).to.be('how are you?');\n\t\t\texpect(gun.__.graph['asdf'].y).to.be('bye');\n\t\t\texpect(gun.__.graph['asdf'].z).to.be('who');\n\t\t\tvar now = Gun.time.is();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(Gun.time.is() - now).to.be.above(100);\n\t\t\t\texpect(gun.__.graph['asdf'].w).to.be(true);\n\t\t\t\texpect(gun.__.graph['asdf'].x).to.be('how are you?');\n\t\t\t\texpect(gun.__.graph['asdf'].y).to.be('farewell');\n\t\t\t\texpect(gun.__.graph['asdf'].z).to.be('doctor who');\n\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t});\n\t\t});\n\n\t\tit('two nodes', function(done){ // chat app problem where disk dropped the last data, turns out it was a union problem!\n\t\t\tvar state = Gun.time.is();\n\t\t\tvar prime = {\n\t\t\t\t'sadf': {\n\t\t\t\t\t_: {'#': 'sadf', '>':{\n\t\t\t\t\t\t1: state\n\t\t\t\t\t}},\n\t\t\t\t\t1: {'#': 'fdsa'}\n\t\t\t\t},\n\t\t\t\t'fdsa': {\n\t\t\t\t\t_: {'#': 'fdsa', '>':{\n\t\t\t\t\t\tmsg: state\n\t\t\t\t\t}},\n\t\t\t\t\tmsg: \"Let's chat!\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['sadf']).to.not.be.ok();\n\t\t\texpect(gun.__.graph['fdsa']).to.not.be.ok();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(gun.__.graph['sadf'][1]).to.be.ok();\n\t\t\t\texpect(gun.__.graph['fdsa'].msg).to.be(\"Let's chat!\");\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('append third node', function(done){ // chat app problem where disk dropped the last data, turns out it was a union problem!\n\t\t\tvar state = Gun.time.is();\n\t\t\tvar prime = {\n\t\t\t\t'sadf': {\n\t\t\t\t\t_: {'#': 'sadf', '>':{\n\t\t\t\t\t\t2: state\n\t\t\t\t\t}},\n\t\t\t\t\t2: {'#': 'fads'}\n\t\t\t\t},\n\t\t\t\t'fads': {\n\t\t\t\t\t_: {'#': 'fads', '>':{\n\t\t\t\t\t\tmsg: state\n\t\t\t\t\t}},\n\t\t\t\t\tmsg: \"hi\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\texpect(gun.__.graph['sadf']).to.be.ok();\n\t\t\texpect(gun.__.graph['fdsa']).to.be.ok();\n\t\t\tvar ctx = Gun.union(gun, prime, function(){\n\t\t\t\texpect(gun.__.graph['sadf'][1]).to.be.ok();\n\t\t\t\texpect(gun.__.graph['sadf'][2]).to.be.ok();\n\t\t\t\texpect(gun.__.graph['fads'].msg).to.be(\"hi\");\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('ify null', function(){\n\t\t\t\tvar node = Gun.union.ify(null, 'pseudo');\n\t\t\t\texpect(Gun.node.soul(node)).to.be('pseudo');\n\t\t});\n\n\t\tit('ify node', function(){\n\n\t\t\tvar graph = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>': {\n\t\t\t\t\t\tx: Gun.time.is(),\n\t\t\t\t\t\ty: Gun.time.is()\n\t\t\t\t\t}},\n\t\t\t\t\tx: 1,\n\t\t\t\t\ty: 2\n\t\t\t\t},\n\t\t\t\t'soul': {\n\t\t\t\t\t_: {'#': 'soul', '~': 1, '>': {\n\t\t\t\t\t\t'asdf': Gun.time.is()\n\t\t\t\t\t}},\n\t\t\t\t\t'asdf': {'#': 'asdf'}\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar node = Gun.union.ify(graph, 'soul');\n\t\t\texpect(Gun.node.soul(node)).to.be('soul');\n\t\t\texpect(node.x).to.be(1);\n\t\t\texpect(node.y).to.be(2);\n\t\t});\n\n\t\tit('ify graph', function(){\n\t\t\tvar graph = {\n\t\t\t\t'asdf': {\n\t\t\t\t\t_: {'#': 'asdf', '>': {\n\t\t\t\t\t\ta: Gun.time.is() - 2,\n\t\t\t\t\t\tz: Gun.time.is() - 2\n\t\t\t\t\t}},\n\t\t\t\t\ta: 1,\n\t\t\t\t\tz: 1\n\t\t\t\t},\n\t\t\t\t'fdsa': {\n\t\t\t\t\t_: {'#': 'fdsa', '>': {\n\t\t\t\t\t\tb: Gun.time.is() - 1,\n\t\t\t\t\t\tz: Gun.time.is() - 1\n\t\t\t\t\t}},\n\t\t\t\t\tb: 2,\n\t\t\t\t\tz: 2\n\t\t\t\t},\n\t\t\t\t'sadf': {\n\t\t\t\t\t_: {'#': 'sadf', '>': {\n\t\t\t\t\t\tc: Gun.time.is(),\n\t\t\t\t\t\tz: Gun.time.is() - 100\n\t\t\t\t\t}},\n\t\t\t\t\tc: 3,\n\t\t\t\t\tz: 3\n\t\t\t\t},\n\t\t\t\t'soul': {\n\t\t\t\t\t_: {'#': 'soul', '~': 1, '>': {\n\t\t\t\t\t\t'asdf': Gun.time.is(),\n\t\t\t\t\t\t'fdsa': Gun.time.is(),\n\t\t\t\t\t\t'sadf': Gun.time.is()\n\t\t\t\t\t}},\n\t\t\t\t\t'asdf': {'#': 'asdf'},\n\t\t\t\t\t'fdsa': {'#': 'fdsa'},\n\t\t\t\t\t'sadf': {'#': 'sadf'}\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar node = Gun.union.ify(graph, 'soul');\n\t\t\texpect(Gun.node.soul(node)).to.be('soul');\n\t\t\texpect(node.a).to.be(1);\n\t\t\texpect(node.b).to.be(2);\n\t\t\texpect(node.c).to.be(3);\n\t\t\texpect(node.z).to.be(2);\n\t\t});\n\t});\n\n\tdescribe('API', function(){\n\t\tvar gopt = {wire:{put:function(n,cb){cb()},get:function(k,cb){cb()}}};\n\t\tif(Gun.window && location.search){\n\t\t\t/*console.log(\"LOCALHOST PEER MUST BE ON!\");\n\t\t\tvar peer = {url: 'http://localhost:8765/gun'};\n\t\t\tGun.on('opt', function(root){\n\t\t\t\tif(root.opt.test_no_peer){ return this.to.next(root) }\n\t\t\t\troot.opt.peers = root.opt.peers || {};\n\t\t\t\troot.opt.peers['http://localhost:8765/gun'] = peer;\n\t\t\t\tthis.to.next(root);\n\t\t\t});*/\n\t\t}\n\t\tvar goff = Gun();\n\t\tGun.statedisk = function(o,s,cb){\n\t\t\tgoff.get(s).put(o, cb, {turn: function(fn){fn()}});\n\t\t};\n\t\tvar gun = Gun();\n\n\t\tvar nopasstun = function(done, g){\n\t\t\tg = (g || gun)._.root;\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(g.pass).to.not.be.ok();\n\t\t\t\texpect(g.stun).to.not.be.ok();\n\t\t\t\tdone && done();\n\t\t\t},9);\n\t\t}\n\n\t\tit.skip('gun chain separation', function(done){ // TODO: UNDO!\n\t\t\tvar gun = Gun();\n\n\t\t\tvar c1 = gun.put({hello: 'world'});\n\n\t\t\tvar c2 = gun.put({hi: 'earth'});\n\n\t\t\tc1.on(function(val){\n\t\t\t\texpect(val.hi).to.not.be.ok();\n\t\t\t});\n\n\t\t\tc2.on(function(val){\n\t\t\t\texpect(val.hello).to.not.be.ok();\n\t\t\t\tif(done.c){ return }\n\t\t\t\tdone(); done.c = 1;\n\t\t\t});\n\t\t});\n\n\t\tdescribe.skip('timeywimey', function(){ // TODO: UNDO!\n\n\t\t\tit('kitty', function(done){\n\t\t\t\tvar g1 = gun.put({hey: 'kitty'}).key('timeywimey/kitty');\n\n\t\t\t\tvar g2 = gun.get('timeywimey/kitty').on(function(val){\n\t\t\t\t\tdelete val._;\n\t\t\t\t\t//console.log(\"kitty?\", val);\n\t\t\t\t\texpect(val.hey).to.be('kitty');\n\t\t\t\t\texpect(val.hi).to.not.be.ok();\n\t\t\t\t\texpect(val.hello).to.not.be.ok();\n\t\t\t\t\texpect(val.foo).to.not.be.ok();\n\t\t\t\t\tif(done.c){ return }\n\t\t\t\t\tdone(); done.c = 1;\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('kitty puppy', function(done){\n\t\t\t\tvar g3 = gun.put({hey: 'kitty'}).key('timeywimey/kitty/puppy');\n\n\t\t\t\tvar g4 = gun.put({hi: 'puppy'}).key('timeywimey/kitty/puppy');\n\n\t\t\t\tvar g5 = gun.get('timeywimey/kitty/puppy').on(function(val){\n\t\t\t\t\t//delete val._;\n\t\t\t\t\t//console.log(\"puppy?\", val);\n\t\t\t\t\texpect(val.hey).to.be('kitty');\n\t\t\t\t\texpect(val.hi).to.be('puppy');\n\t\t\t\t\tif(done.c){ return }\n\t\t\t\t\tdone(); done.c = 1;\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('hello', function(done){\n\t\t\t\tgun.get('timeywimey/hello').on(function(val){\n\t\t\t\t\t//delete val._;\n\t\t\t\t\t//console.log(\"hello?\", val);\n\t\t\t\t\texpect(val.hello).to.be('world');\n\t\t\t\t\tif(done.c){ return }\n\t\t\t\t\tdone(); done.c = 1;\n\t\t\t\t});\n\n\t\t\t\tgun.put({hello: 'world'}).key('timeywimey/hello');\n\t\t\t});\n\n\t\t\tit('hello foo', function(done){\n\t\t\t\tgun.get('timeywimey/hello/foo').on(function(val){\n\t\t\t\t\t//delete val._;\n\t\t\t\t\texpect(val.hello).to.be('world');\n\t\t\t\t\tif(val.foo){\n\t\t\t\t\t\texpect(val.foo).to.be('bar');\n\t\t\t\t\t\tif(done.c){ return }\n\t\t\t\t\t\tdone(); done.c = 1;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tgun.put({hello: 'world'}).key('timeywimey/hello/foo');\n\n\t\t\t\tgun.put({foo: 'bar'}).key('timeywimey/hello/foo');\n\t\t\t});\n\n\t\t\tit('all', function(done){\n\t\t\t\tgun.put({hey: 'kitty'}).key('timeywimey/all');\n\n\t\t\t\tgun.put({hi: 'puppy'}).key('timeywimey/all');\n\n\t\t\t\tgun.get('timeywimey/all').on(function(val){\n\t\t\t\t\t// console.log('all', done.c, val);\n\t\t\t\t\texpect(val.hey).to.be('kitty');\n\t\t\t\t\texpect(val.hi).to.be('puppy');\n\t\t\t\t\tif(val.hello){\n\t\t\t\t\t\texpect(val.hello).to.be('world');\n\t\t\t\t\t\tdone.hello = true;\n\t\t\t\t\t}\n\t\t\t\t\tif(val.foo){\n\t\t\t\t\t\texpect(val.foo).to.be('bar');\n\t\t\t\t\t\tif(done.c || !done.hello){ return }\n\t\t\t\t\t\tdone(); done.c = 1;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tgun.put({hello: 'world'}).key('timeywimey/all');\n\n\t\t\t\tgun.put({foo: 'bar'}).key('timeywimey/all');\n\t\t\t});\n\n\t\t});\n\n\t\tdescribe('predictable souls', function(){\n\t\t\tit('public', function(done){\n\t\t\t\tgun.get('z').get('y').get('x').put({c: {b: {a: 1}}}, function(){\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tvar g = gun._.graph;\n\t\t\t\t\texpect(g['z']).to.be.ok();\n\t\t\t\t\texpect(g['z/y']).to.be.ok();\n\t\t\t\t\texpect(g['z/y/x']).to.be.ok();\n\t\t\t\t\texpect(g['z/y/x/c']).to.be.ok();\n\t\t\t\t\texpect(g['z/y/x/c/b']).to.be.ok();\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t});\n\t\t\t});\n\t\t\tit('no not found on incremental write', function(done){\n\t\t\t\tgun.get('nnfoiw').get('y').put({a:1}, function(ack){\n\t\t\t\t\tif(ack.err){ return }\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t})\n\t\t\t});\n\t\t\tit('public mix', function(done){\n\t\t\t\tvar ref = gun.get('zasdf').put({a: 9});\n\t\t\t\tvar at = gun.get('zfdsa').get('y').get('x').get('c').put(ref);\n\t\t\t\tat.get('foo').get('bar').put('yay', function(ack){ done.a = 1; end() });\n\t\t\t\tref.get('foo').get('ah').put(1, function(ack){ done.b = 1; end() });\n\t\t\t\tfunction end(ack){\n\t\t\t\t\tif(!done.a || !done.b){ return }\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tvar g = gun._.graph;\n\t\t\t\t\texpect(Object.keys(g['zasdf']||'').sort()).to.be.eql(['_', 'a', 'foo'].sort());\n\t\t\t\t\texpect(Object.keys(g['zasdf/foo']||'').sort()).to.be.eql(['_', 'bar', 'ah'].sort());\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t};\n\t\t\t\t//setTimeout(function(){ console.log('???', gun._.stun); }, 1700);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('plural chains', function(){\n\t\t\tthis.timeout(9000);\n\t\t\tit('uncached synchronous map on', function(done){\n\t\t\t\t/*\n\t\t\t\t\tBiggest challenges so far:\n\t\t\t\t\t - Unsubscribe individual mapped next. !\n\t\t\t\t\t - Performance deduplication on asking relation's next. !\n\t\t\t\t\t - Replying immediately to parent cached contexts.\n\t\t\t\t\t - Performant read lock on write contexts.\n\t\t\t\t\t - Proxying event across maps.\n\t\t\t\t*/\n\t\t\t\tGun.statedisk({ alice: { age: 26, name: \"Alice\", pet: {a:1, name: \"Fluffy\"} }, bob: { age: 29, name: \"Bob!\", pet: {b:2, name: \"Frisky\"} } }, 'u/m', function(){\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m').map().on(function(v,f){\n\t\t\t\t\tcheck[f] = v;\n\t\t\t\t\tcount[f] = (count[f] || 0) + 1;\n\t\t\t\t\t//console.log(\"***********\", f, v);\n\t\t\t\t\tif(check.alice && check.bob){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice.age).to.be(26);\n\t\t\t\t\t\t\texpect(check.alice.name).to.be('Alice');\n\t\t\t\t\t\t\texpect('string' == typeof Gun.valid(check.alice.pet)).to.be.ok();\n\t\t\t\t\t\t\t//expect(count.alice).to.be(1);\n\t\t\t\t\t\t\texpect(check.bob.age).to.be(29);\n\t\t\t\t\t\t\texpect(check.bob.name).to.be('Bob!');\n\t\t\t\t\t\t\texpect('string' == typeof Gun.valid(check.bob.pet)).to.be.ok();\n\t\t\t\t\t\t\t//expect(count.bob).to.be(1);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map get on', function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\tpet: {a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/p', function(){\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m/p').map().get('name').on(function(v,f){\n\t\t\t\t\t//console.log(\"*****************\", f, v);\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tcount[v] = (count[v] || 0) + 1;\n\t\t\t\t\tif(check.alice && check.bob){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice).to.be('name');\n\t\t\t\t\t\t\texpect(check.bob).to.be('name');\n\t\t\t\t\t\t\t//expect(count.alice).to.be(1);\n\t\t\t\t\t\t\t//expect(count.bob).to.be(1);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map get on node', function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\tpet: {a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/p/n', function() {\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m/p/n').map().get('pet').on(function(v,f){\n\t\t\t\t\t//console.log(\"********************\", f,v);\n\t\t\t\t\tcheck[v.name] = v;\n\t\t\t\t\tcount[v.name] = (count[v.name] || 0) + 1;\n\t\t\t\t\tif(check.Fluffy && check.Frisky){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.Fluffy.a).to.be(1);\n\t\t\t\t\t\t\texpect(check.Frisky.b).to.be(2);\n\t\t\t\t\t\t\t//expect(count.Fluffy).to.be(1);\n\t\t\t\t\t\t\t//expect(count.Frisky).to.be(1);\n\t\t\t\t\t\t\t//expect(count['undefined']).to.not.be.ok();\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map get on node get', function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\tpet: {a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/p/n/p', function() {\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\t//console.debug.i=1;console.log('-------------------');\n\t\t\t\tgun.get('u/m/p/n/p').map().get('pet').get('name').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tcount[v] = (count[v] || 0) + 1;\n\t\t\t\t\t//console.log(\"*****************\", f, v);\n\t\t\t\t\tif(check.Fluffy && check.Frisky){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.Fluffy).to.be('name');\n\t\t\t\t\t\t\texpect(check.Frisky).to.be('name');\n\t\t\t\t\t\t\t//console.log(\"????\", gun._.graph);\n\t\t\t\t\t\t\t//Gun.obj.map(gun._.graph, function(n,s){\n\t\t\t\t\t\t\tObject.keys(gun._.graph).forEach(function(s,n){ n = gun._.graph[s];\n\t\t\t\t\t\t\t\tif('u/m/p/n/p' === s){ return }\n\t\t\t\t\t\t\t\tvar a = Object.keys(n);//Gun.obj.map(n, function(v,f,t){t(v)});\n\t\t\t\t\t\t\t\texpect(a.length).to.be(2); // make sure that ONLY the selected properties were loaded, not the whole node.\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t//expect(count.Fluffy).to.be(1);\n\t\t\t\t\t\t\t//expect(count.Frisky).to.be(1);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map on mutate', function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"Alice\",\n\t\t\t\t\t\tpet: {a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/mutate', function() {\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m/mutate').map().get('name').get(function(at,ev){\n\t\t\t\t\tvar e = at.err, v = at.put, f = at.get;\n\t\t\t\t\t//console.log(\"****************\", f,v);\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tcount[v] = (count[v] || 0) + 1;\n\t\t\t\t\tif(check.Alice && check.Bob && check['undefined']){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\t//expect(count.Alice).to.be(1);\n\t\t\t\t\t\t\t//expect(count.Bob).to.be(1);\n\t\t\t\t\t\t\t//expect(count['undefined']).to.be(1);\n\t\t\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('u/m/mutate').get('alice').put(7);\n\t\t\t\t}, 300);\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map on mutate node', function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {_:{'#':'umaliceo'},\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"Alice\",\n\t\t\t\t\t\tpet: {a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/mutate/n', function() {\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m/mutate/n').map().get('name').get(function(at,ev){\n\t\t\t\t\tvar e = at.err, v = at.put, f = at.get;\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tcount[v] = (count[v] || 0) + 1;\n\t\t\t\t\t//console.log(\"************\", f,v);\n\t\t\t\t\tif(check.Alice && check.Bob && check['undefined'] && check['Alice Zzxyz']){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(done.last).to.be.ok();\n\t\t\t\t\t\t\texpect(check['Alice Aabca']).to.not.be.ok();\n\t\t\t\t\t\t\texpect(count.Alice).to.be(1);\n\t\t\t\t\t\t\texpect(count.Bob).to.be(1);\n\t\t\t\t\t\t\texpect(count['undefined']).to.be(1);\n\t\t\t\t\t\t\texpect(count['Alice Zzxyz']).to.be(1);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},200);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('u/m/mutate/n').get('alice').put({\n\t\t\t\t\t\t_:{'#':'u/m/m/n/soul'},\n\t\t\t\t\t\tname: 'Alice Zzxyz'\n\t\t\t\t\t});\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tgun.get('umaliceo').put({\n\t\t\t\t\t\t\tname: 'Alice Aabca'\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdone.last = true;\n\t\t\t\t\t}, 10);\n\t\t\t\t}, 300);\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map on mutate node uncached', function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {_:{'#':'umaliceo1'},\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"Alice\",\n\t\t\t\t\t\tpet: {a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/mutate/n/u', function() {\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m/mutate/n/u').map().on(function(v,f){\n\t\t\t\t\tcheck[v.name] = f;\n\t\t\t\t\tcount[v.name] = (count[v.name] || 0) + 1;\n\t\t\t\t\tif(check.Alice && check.Bob && check['Alice Zzxyz']){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\t//console.log(\"****\", f, v)\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(done.last).to.be.ok();\n\t\t\t\t\t\t\t//expect(check['Alice Aabca']).to.not.be.ok();\n\t\t\t\t\t\t\t//expect(count['Alice']).to.be(1);\n\t\t\t\t\t\t\t//expect(count['Bob']).to.be(1);\n\t\t\t\t\t\t\t//expect(count['Alice Zzxyz']).to.be(1);\n\t\t\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},200);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tGun.statedisk({ name: 'Alice Zzxyz' }, 'u/m/m/n/u/soul', function() {\n\t\t\t\t\t//console.debug.i=1;console.log(\"---------------\");\n\t\t\t\t\tgun.get('u/m/mutate/n/u').put({\n\t\t\t\t\t\talice: {'#':'u/m/m/n/u/soul'},\n\t\t\t\t\t});\n\t\t\t\t\t/*\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tusers: {_:#users\n\t\t\t\t\t\t\t\talice: {#newalice}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t*/\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tgun.get('umaliceo1').put({\n\t\t\t\t\t\t\tname: 'Alice Aabca'\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdone.last = true;\n\t\t\t\t\t}, 10);\n\t\t\t\t\t}, 1000);\n\t\t\t\t}, 300);\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map on get mutate node uncached', function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {_:{'#':'umaliceo2'},\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"Alice\",\n\t\t\t\t\t\tpet: {a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/p/mutate/n/u', function() {\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m/p/mutate/n/u').map().get('name').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tcount[v] = (count[v] || 0) + 1;\n\t\t\t\t\t//console.log(\"*************\", f,v);\n\t\t\t\t\tif(check.Alice && check.Bob && check['Alice Zzxyz']){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\tvar a = Object.keys(gun._.graph['u/m/p/m/n/u/soul']); //Gun.obj.map(gun._.graph['u/m/p/m/n/u/soul'], function(v,f,t){t(v)});\n\t\t\t\t\t\t\texpect(a.length).to.be(2);\n\t\t\t\t\t\t\texpect(done.last).to.be.ok();\n\t\t\t\t\t\t\texpect(check['Alice Aabca']).to.not.be.ok();\n\t\t\t\t\t\t\t//expect(count.Alice).to.be(1);\n\t\t\t\t\t\t\t//expect(count.Bob).to.be(1);\n\t\t\t\t\t\t\t//expect(count['Alice Zzxyz']).to.be(1);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},200);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tGun.statedisk({ name: 'Alice Zzxyz', age: 34 }, 'u/m/p/m/n/u/soul', function() {\n\t\t\t\t\tgun.get('u/m/p/mutate/n/u').put({\n\t\t\t\t\t\talice: {'#':'u/m/p/m/n/u/soul'},\n\t\t\t\t\t});\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tgun.get('umaliceo2').put({\n\t\t\t\t\t\t\tname: 'Alice Aabca'\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdone.last = true;\n\t\t\t\t\t}, 10);\n\t\t\t\t\t}, 1000);\n\t\t\t\t}, 300);\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit('uncached synchronous map on get node mutate node uncached', function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\talice: {_:{'#':'umaliceo3'},\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"Alice\",\n\t\t\t\t\t\tpet: {_:{'#':'sflufso'},a:1, name: \"Fluffy\"}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tage: 29,\n\t\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\t\tpet: {b:2, name: \"Frisky\"}\n\t\t\t\t\t}\n\t\t\t\t}, 'u/m/p/n/mutate/n/u', function() {\n\t\t\t\tvar check = {}, count = {};\n\t\t\t\tgun.get('u/m/p/n/mutate/n/u').map().get('pet').on(function(v,f){\n\t\t\t\t\tcheck[v.name] = f;\n\t\t\t\t\tcount[v.name] = (count[v.name] || 0) + 1;\n\t\t\t\t\t//console.log(\"*****************\", f,v, check);\n\t\t\t\t\tif(check.Fluffy && check.Frisky && check.Fuzzball){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(done.last).to.be.ok();\n\t\t\t\t\t\t\texpect(check['Fluffs']).to.not.be.ok();\n\t\t\t\t\t\t\texpect(count.Fluffy).to.be(1);\n\t\t\t\t\t\t\texpect(count.Frisky).to.be(1);\n\t\t\t\t\t\t\texpect(count.Fuzzball).to.be(1);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},200);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tGun.statedisk({\n\t\t\t\t\t\tname: 'Alice Zzxyz', age: 34,\n\t\t\t\t\t\tpet: {c:3, name: \"Fuzzball\"}\n\t\t\t\t\t}, 'alice/fuzz/soul', function() {\n\t\t\t\t\tgun.get('u/m/p/n/mutate/n/u').put({\n\t\t\t\t\t\talice: {'#':'alice/fuzz/soul'},\n\t\t\t\t\t});\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tgun.get('sflufso').put({\n\t\t\t\t\t\t\tname: 'Fluffs'\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdone.last = true;\n\t\t\t\t\t}, 10);\n\t\t\t\t\t}, 1000);\n\t\t\t\t}, 300);\n\t\t\t\t}, 1000);\n\t\t\t});\n\n\t\t\tit(\"unlink deeply nested\", function(done){\n\t\t\t\tGun.statedisk({\n\t\t\t\t\ta: {_:{'#':'audn'},\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tname: \"Alice\",\n\t\t\t\t\t\tb: {_:{'#':'budn'}, c: {_:{'#':'cudn'}, id: 'first', level: 3}, level: 2}\n\t\t\t\t\t}\n\t\t\t\t}, 'udn', function() {\n\t\t\t\t\tvar check = {}, count = {};\n\t\t\t\t\tgun.get('udn').get('a').get('b').get('c').on(function(data){\n\t\t\t\t\t\t//console.log(\"udn.a.b.c:\", data);\n\t\t\t\t\t\tcheck[data.id] = 1;\n\t\t\t\t\t\tcount[data.id] = (count[data.id] || 0) + 1;\n\t\t\t\t\t\texpect(data.foo).to.not.be.ok();\n\t\t\t\t\t\t//console.log(\"*****************\", f,v, check);\n\t\t\t\t\t\tif(check.first && check.other){\n\t\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\t\texpect(done.last).to.be.ok();\n\t\t\t\t\t\t\t\texpect(check.firsta).to.not.be.ok();\n\t\t\t\t\t\t\t\texpect(count.first).to.be(1);\n\t\t\t\t\t\t\t\texpect(count.other).to.be(1);\n\t\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t\t},200);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tGun.statedisk({\n\t\t\t\t\t\t\tname: 'Alice2', age: 34,\n\t\t\t\t\t\t\tb: {_:{'#':'2budn'}, c: {_:{'#':'2cudn'}, id: 'other', level: 3}, level: 2}\n\t\t\t\t\t\t}, '2audn', function() {\n\t\t\t\t\t\t\t//console.only.i=1;console.log('=============================');\n\t\t\t\t\t\t\tgun.get('udn').put({\n\t\t\t\t\t\t\t\ta: {'#':'2audn'}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\t\t//console.log(\"- - - - - - - - - - - -\");\n\t\t\t\t\t\t\t\tgun.get('cudn').put({id: 'firsta', foo: 'bar'});\n\t\t\t\t\t\t\t\tdone.last = 1;\n\t\t\t\t\t\t\t}, 50);\n\t\t\t\t\t\t});\n\t\t\t\t\t},50);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit(\"get before put in memory\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tvar count = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/r').map().on(function(v,f){\n\t\t\t\t\t//console.log(\"***********\", f,v);\n\t\t\t\t\tcheck[f] = v;\n\t\t\t\t\tcount[f] = (count[f] || 0) + 1;\n\t\t\t\t\tif(check.alice && check.bob && check.alice.PhD){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice.age).to.be(24);\n\t\t\t\t\t\t\texpect(check.bob.age).to.be(26);\n\t\t\t\t\t\t\texpect(check.alice.PhD).to.be(true);\n\t\t\t\t\t\t\t//expect(count.alice).to.be(2);\n\t\t\t\t\t\t\t//expect(count.bob).to.be(1);\n\t\t\t\t\t\t\tif(done.c){return} done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},50);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/r'},\n\t\t\t\t\talice: {_:{'#':'GALICE1'},\n\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t},\n\t\t\t\t\tbob: {\n\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('GALICE1').put({PhD: true});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get after\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n'},\n\t\t\t\t\t\talice: {_:{'#':'GALICE2'},\n\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tvar check = {};\n\t\t\t\t//gun.get('g/n/m/f/l/n').get('bob.spouse.work').on(function(v,f){ console.log(\"!!!!!!!!!\", f, v);});return;\n\t\t\t\tgun.get('g/n/m/f/l/n').map().on(function(v,f){\n\t\t\t\t\tcheck[f] = v;\n\t\t\t\t\t//console.log(\"*******************\", f, v);\n\t\t\t\t\tif(check.alice && check.bob && check.alice.PhD){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice.age).to.be(24);\n\t\t\t\t\t\t\texpect(check.bob.age).to.be(26);\n\t\t\t\t\t\t\texpect(check.alice.PhD).to.be(true);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('GALICE2').put({PhD: true});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before map get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/p').map().get('name').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\t//console.log(\"****************\", f,v, gun);\n\t\t\t\t\tif(check.alice && check.bob && check.Alice){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice).to.be('name');\n\t\t\t\t\t\t\texpect(check.bob).to.be('name');\n\t\t\t\t\t\t\texpect(check.Alice).to.be('name');\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/p'},\n\t\t\t\t\t\talice: {_:{'#':'GALICE3'},\n\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t//console.debug.i=1;console.log(\"-------------\");\n\t\t\t\t\tgun.get('GALICE3').put({name: 'Alice'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get after map get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/m/p'},\n\t\t\t\t\t\talice: {_:{'#':'GALICE4'},\n\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/m/p').map().get('name').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\t//console.log(\"*****************\", f,v);\n\t\t\t\t\tif(check.alice && check.bob && check.Alice){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice).to.be('name');\n\t\t\t\t\t\t\texpect(check.bob).to.be('name');\n\t\t\t\t\t\t\texpect(check.Alice).to.be('name');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('GALICE4').put({name: 'Alice'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before map get get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/p/p/p').map().get('spouse').get('work').on(function(v,f){\n\t\t\t\t\tcheck[v.name] = f;\n\t\t\t\t\t//console.log(\"*******\", f, v);\n\t\t\t\t\tif(check['GUN INC'] && check['ACME INC'] && check['ACME INC.']){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check['GUN INC']).to.be('work');\n\t\t\t\t\t\t\texpect(check['ACME INC']).to.be('work');\n\t\t\t\t\t\t\texpect(check['ACME INC.']).to.be('work');\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/p/p/p'},\n\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\t\t\twork: {_:{'#':'CCINEMA1'},\n\t\t\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t//console.debug.i=1;console.log(\"----------------\");\n\t\t\t\t\tgun.get('CCINEMA1').put({name: 'ACME INC.'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get after map get get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/p/p/p/a'},\n\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\t\t\twork: {_:{'#':'CCINEMA2'},\n\t\t\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/p/p/p/a').map().get('spouse').get('work').on(function(v,f){\n\t\t\t\t\tcheck[v.name] = f;\n\t\t\t\t\tif(check['GUN INC'] && check['ACME INC'] && check['ACME INC.']){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check['GUN INC']).to.be('work');\n\t\t\t\t\t\t\texpect(check['ACME INC']).to.be('work');\n\t\t\t\t\t\t\texpect(check['ACME INC.']).to.be('work');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('CCINEMA2').put({name: 'ACME INC.'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before map map\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/a/m/m').map().map().on(function(v,f){\n\t\t\t\t\tcheck[f] = v;\n\t\t\t\t\t//console.log(\"****************\", f,v);\n\t\t\t\t\tif(check.alice && check.bob && check.GUN && check.ACME && check.ACME.corp){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice.name).to.be('alice');\n\t\t\t\t\t\t\texpect(check.alice.age).to.be(24);\n\t\t\t\t\t\t\texpect('string' == typeof Gun.valid(check.alice.spouse)).to.be.ok();\n\t\t\t\t\t\t\texpect(check.bob.name).to.be('bob');\n\t\t\t\t\t\t\texpect(check.bob.age).to.be(26);\n\t\t\t\t\t\t\texpect('string' == typeof Gun.valid(check.bob.spouse)).to.be.ok();\n\t\t\t\t\t\t\texpect(check.GUN.name).to.be('GUN');\n\t\t\t\t\t\t\texpect(check.ACME.name).to.be('ACME');\n\t\t\t\t\t\t\texpect(check.ACME.corp).to.be('C');\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t//console.debug.i=1;console.log(\"------------------------\");\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/a/m/m'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {_:{'#':\"CCINEMA3\"},\n\t\t\t\t\t\t\t\tname: \"ACME\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t//console.debug.i=1;console.log(\"-------------\");\n\t\t\t\t\tgun.get('CCINEMA3').put({corp: \"C\"});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get after map map\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/m/m'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {_:{'#':\"CCINEMA4\"},\n\t\t\t\t\t\t\t\tname: \"ACME\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/m/m').map().map().on(function(v,f){\n\t\t\t\t\tcheck[f] = v;\n\t\t\t\t\t//console.log(\"***************\", f,v);\n\t\t\t\t\tif(check.alice && check.bob && check.GUN && check.ACME && check.ACME.corp){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice.name).to.be('alice');\n\t\t\t\t\t\t\texpect(check.alice.age).to.be(24);\n\t\t\t\t\t\t\texpect('string' == typeof Gun.valid(check.alice.spouse)).to.be.ok();\n\t\t\t\t\t\t\texpect(check.bob.name).to.be('bob');\n\t\t\t\t\t\t\texpect(check.bob.age).to.be(26);\n\t\t\t\t\t\t\texpect('string' == typeof Gun.valid(check.bob.spouse)).to.be.ok();\n\t\t\t\t\t\t\texpect(check.GUN.name).to.be('GUN');\n\t\t\t\t\t\t\texpect(check.ACME.name).to.be('ACME');\n\t\t\t\t\t\t\texpect(check.ACME.corp).to.be('C');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('CCINEMA4').put({corp: \"C\"});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before map map get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/m/m/p').map().map().get('name').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\t//console.log(\"***********\", f,v);\n\t\t\t\t\tif(check.alice && check.bob && check.GUN && check.ACME && check.ACMEINC){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice).to.be('name');\n\t\t\t\t\t\t\texpect(check.bob).to.be('name');\n\t\t\t\t\t\t\texpect(check.GUN).to.be('name');\n\t\t\t\t\t\t\texpect(check.ACME).to.be('name');\n\t\t\t\t\t\t\texpect(check.ACMEINC).to.be('name');\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/m/m/p'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {_:{'#':\"CCINEMA5\"},\n\t\t\t\t\t\t\t\tname: \"ACME\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('CCINEMA5').put({name: \"ACMEINC\"});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get after map map get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/a/m/m/p'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\"\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {_:{'#':'CCINEMA6'},\n\t\t\t\t\t\t\t\tname: \"ACME\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.get('g/n/m/f/l/n/b/a/m/m/p').map().map().get('name').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\t//console.log(\"************\", f,v);\n\t\t\t\t\tif(check.alice && check.bob && check.GUN && check.ACME && check.ACMEINC){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.alice).to.be('name');\n\t\t\t\t\t\t\texpect(check.bob).to.be('name');\n\t\t\t\t\t\t\texpect(check.GUN).to.be('name');\n\t\t\t\t\t\t\texpect(check.ACME).to.be('name');\n\t\t\t\t\t\t\texpect(check.ACMEINC).to.be('name');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('CCINEMA6').put({name: \"ACMEINC\"});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before map map get get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/m/m/p/p').map().map().get('address').get('state').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tif(check.QR && check.NY && check.CA && check.TX && check.MA){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.QR).to.be('state');\n\t\t\t\t\t\t\texpect(check.NY).to.be('state');\n\t\t\t\t\t\t\texpect(check.CA).to.be('state');\n\t\t\t\t\t\t\texpect(check.TX).to.be('state');\n\t\t\t\t\t\t\texpect(check.MA).to.be('state');\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/m/m/p/p'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\taddress: {_:{'#':'QUANGO'},\n\t\t\t\t\t\t\t\t\tstate: \"MA\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: \"TX\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: \"CA\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {\n\t\t\t\t\t\t\t\tname: \"ACME\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: \"NY\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('QUANGO').put({state: 'QR'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get after map map get get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/a/m/m/p/p'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\taddress: {_:{'#':'QUANGO1'},\n\t\t\t\t\t\t\t\t\tstate: \"MA\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: \"TX\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: \"CA\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {\n\t\t\t\t\t\t\t\tname: \"ACME\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: \"NY\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/a/m/m/p/p').map().map().get('address').get('state').on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tif(check.QR && check.NY && check.CA && check.TX && check.MA){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.QR).to.be('state');\n\t\t\t\t\t\t\texpect(check.NY).to.be('state');\n\t\t\t\t\t\t\texpect(check.CA).to.be('state');\n\t\t\t\t\t\t\texpect(check.TX).to.be('state');\n\t\t\t\t\t\t\texpect(check.MA).to.be('state');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('QUANGO1').put({state: 'QR'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before map map get get get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/m/m/p/p/p').map().map().get('address').get('state')\n\t\t\t\t\t.get('code')\n\t\t\t\t\t.on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\tif(check.QR && check.NY && check.CA && check.TX && check.MA){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.QR).to.be('code');\n\t\t\t\t\t\t\texpect(check.NY).to.be('code');\n\t\t\t\t\t\t\texpect(check.CA).to.be('code');\n\t\t\t\t\t\t\texpect(check.TX).to.be('code');\n\t\t\t\t\t\t\texpect(check.MA).to.be('code');\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/m/m/p/p/p'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {_:{'#':'HIPPOM'},\n\t\t\t\t\t\t\t\t\t\tcode: \"MA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tMA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"TX\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tTX1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"CA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tCA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {\n\t\t\t\t\t\t\t\tname: \"ACME\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"NY\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tNY1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('HIPPOM').put({code: 'QR'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before after map map get get get\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/a/m/m/p/p/p'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {_:{'#':'HIPPOM1'},\n\t\t\t\t\t\t\t\t\t\tcode: \"MA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tMA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"TX\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tTX1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"CA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tCA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {\n\t\t\t\t\t\t\t\tname: \"ACME\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"NY\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tNY1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.get('g/n/m/f/l/n/b/a/m/m/p/p/p').map().map().get('address').get('state')\n\t\t\t\t\t.get('code')\n\t\t\t\t\t.on(function(v,f){\n\t\t\t\t\tcheck[v] = f;\n\t\t\t\t\t//console.log(\"***********\", f,v);\n\t\t\t\t\tif(check.QR && check.NY && check.CA && check.TX && check.MA){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.QR).to.be('code');\n\t\t\t\t\t\t\texpect(check.NY).to.be('code');\n\t\t\t\t\t\t\texpect(check.CA).to.be('code');\n\t\t\t\t\t\t\texpect(check.TX).to.be('code');\n\t\t\t\t\t\t\texpect(check.MA).to.be('code');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('HIPPOM1').put({code: 'QR'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before map map get get node\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/l/n/b/m/m/p/p/n').map().map().get('address').get('state').on(function(v,f){\n\t\t\t\t\tcheck[v.code] = f;\n\t\t\t\t\t//console.log(\"************\", f, v);\n\t\t\t\t\tif(check.QR && check.NY && check.CA && check.TX && check.MA){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.QR).to.be('state');\n\t\t\t\t\t\t\texpect(check.NY).to.be('state');\n\t\t\t\t\t\t\texpect(check.CA).to.be('state');\n\t\t\t\t\t\t\texpect(check.TX).to.be('state');\n\t\t\t\t\t\t\texpect(check.MA).to.be('state');\n\t\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/m/m/p/p/n'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {_:{'#':'HIPPOM3'},\n\t\t\t\t\t\t\t\t\t\tcode: \"MA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tMA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"TX\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tTX1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"CA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tCA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {\n\t\t\t\t\t\t\t\tname: \"ACME\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"NY\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tNY1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('HIPPOM3').put({code: 'QR'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get before after map map get get node\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/a/m/m/p/p/n'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {_:{'#':'HIPPOM4'},\n\t\t\t\t\t\t\t\t\t\tcode: \"MA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tMA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"TX\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tTX1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"CA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tCA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {\n\t\t\t\t\t\t\t\tname: \"ACME\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"NY\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tNY1: \"First\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.get('g/n/m/f/l/n/b/a/m/m/p/p/n').map().map().get('address').get('state').on(function(v,f){\n\t\t\t\t\tcheck[v.code] = f;\n\t\t\t\t\t//console.log(\"**********\", f, v);\n\t\t\t\t\tif(check.QR && check.NY && check.CA && check.TX && check.MA){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.QR).to.be('state');\n\t\t\t\t\t\t\texpect(check.NY).to.be('state');\n\t\t\t\t\t\t\texpect(check.CA).to.be('state');\n\t\t\t\t\t\t\texpect(check.TX).to.be('state');\n\t\t\t\t\t\t\texpect(check.MA).to.be('state');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('HIPPOM4').put({code: 'QR'});\n\t\t\t\t},300);\n\t\t\t});\n\n\t\t\tit(\"in memory get after map map get get get map\", function(done){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tvar check = {};\n\t\t\t\tgun.put({_:{'#':'g/n/m/f/l/n/b/a/m/m/p/p/p/n'},\n\t\t\t\t\t\tusers: {\n\t\t\t\t\t\t\talice: {\n\t\t\t\t\t\t\t\tname: \"alice\",\n\t\t\t\t\t\t\t\tage: 24,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"MA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tMA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t\t,MA2: \"Second\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\t\t\t\tage: 25\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tbout: {huh:1}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbob: {\n\t\t\t\t\t\t\t\tname: \"bob\",\n\t\t\t\t\t\t\t\tage: 26,\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"TX\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tTX1: \"First\"\n\t\t\t\t\t\t\t\t\t\t\t,TX2: \"Second\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tspouse: {\n\t\t\t\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\t\t\t\tage: 27\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcompanies: {\n\t\t\t\t\t\t\tGUN: {\n\t\t\t\t\t\t\t\tname: \"GUN\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"CA\",\n\t\t\t\t\t\t\t\t\t\tcounty: {\n\t\t\t\t\t\t\t\t\t\t\tCA1: \"First\"\n\t\t\t\t\t\t\t\t\t\t\t,CA2: \"Second\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tACME: {\n\t\t\t\t\t\t\t\tname: \"ACME\",\n\t\t\t\t\t\t\t\taddress: {\n\t\t\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t\t\tcode: \"NY\",\n\t\t\t\t\t\t\t\t\t\tcounty: {_:{'#':'NYCOUNT'},\n\t\t\t\t\t\t\t\t\t\t\tNY1: \"First\"\n\t\t\t\t\t\t\t\t\t\t\t,NY2: \"Second\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tgun.get('g/n/m/f/l/n/b/a/m/m/p/p/p/n').map().map().get('address').get('state').get('county').map().on(function(v,f){\n\t\t\t\t\tcheck[f] = v;\n\t\t\t\t\t//console.log(\"****************\", f,v);\n\t\t\t\t\tif(check.MA1 && check.MA2 && check.TX1 && check.TX2 && check.CA1 && check.CA2 && check.NY1 && check.NY2 && check.NY3){\n\t\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\t\texpect(check.MA1).to.be('First');\n\t\t\t\t\t\t\texpect(check.TX1).to.be('First');\n\t\t\t\t\t\t\texpect(check.CA1).to.be('First');\n\t\t\t\t\t\t\texpect(check.NY1).to.be('First');\n\t\t\t\t\t\t\texpect(check.MA2).to.be('Second');\n\t\t\t\t\t\t\texpect(check.TX2).to.be('Second');\n\t\t\t\t\t\t\texpect(check.CA2).to.be('Second');\n\t\t\t\t\t\t\texpect(check.NY2).to.be('Second');\n\t\t\t\t\t\t\texpect(check.NY3).to.be('Third');\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},10);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('NYCOUNT').put({NY3: \"Third\"});\n\t\t\t\t},300);\n\t\t\t});\n\t\t});\n\n\t\tit('once put once', function(done){\n\t\t\tgun.get('opo').get('a').put('yay!');\n\t\t\tvar ref = gun.get('opo').get('a');\n\t\t\tsetTimeout(function(){\n\t\t\t\tref.once(function(data){\n\t\t\t\t\t//console.log(\"************\", data);\n\t\t\t\t\texpect(data).to.be('yay!');\n\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tconsole.only(3, '.put z');\n\t\t\t\t\t\tgun.get('opo').get('a').put('z');\n\n\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\tref.once(function(data){\n\t\t\t\t\t\t\t\t//console.log(\"*+*+*+*+*+**+*+*\");\n\t\t\t\t\t\t\t\texpect(data).to.be('z');\n\t\t\t\t\t\t\t\tnopasstun(done);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}, 25);\n\t\t\t\t\t}, 25);\n\t\t\t\t})\n\t\t\t}, 25);\n\t\t});\n\n\t\t/*it('get recursive map', function(done){\n\t\t\tvar teams = {red: {}, blue: {}};\n\t\t\tvar alice = {age: 27, name: \"Alice\"};\n\t\t\tvar bob = {age: 29, name: \"Bob\"};\n\t\t\talice.spouse = bob;\n\t\t\tbob.spouse = alice;\n\t\t\tvar carl = {age: 31, name: \"Carl\"};\n\t\t\tteams.blue.alice = alice;\n\t\t\tteams.blue.carl = carl;\n\t\t\tteams.red.bob = bob;\n\t\t\tteams.red.carl = carl;\n\t\t\tconsole.only.i=1;console.log(\"===============\");\n\t\t\tGun.statedisk(teams, 'gerema', function(ack){\n\t\t\t\tconsole.log(\"VVVVVVVVVVVVVVVVVVV\", ack);\n\t\t\t\tsetTimeout(function(){\n\n\t\t\t\tgun.get('gerema').map().map().get('spouse').on(function(data){\n\t\t\t\t\tconsole.only(2,'hi', data);\n\t\t\t\t\tconsole.only(1,'hi', data);\n\t\t\t\t\t\tconsole.log(\"*****************\", data);return;\n\t\t\t\t});\n\t\t\t},500);});\n\t\t});*/\n\n\t\tit('get node after recursive field', function(done){\n\t\t\tvar bob = {age: 29, name: \"Bob!\"};\n\t\t\tvar cat = {name: \"Fluffy\", species: \"kitty\"};\n\t\t\tvar user = {bob: bob};\n\t\t\tbob.pet = cat;\n\t\t\tcat.slave = bob;\n\t\t\tGun.statedisk(user, 'nodecircle', function(){\n\t\t\t//console.only.i=1;console.log(\"=============\", gun);\n\t\t\t//gun.get('nodecircle').get('bob').once(function(data){\n\t\t\tgun.get('nodecircle').get('bob').get('pet').get('slave').once(function(data){\n\t\t\t\t//console.log(\"*****************\", data, done.to);return;\n\t\t\t\texpect(done.to).to.not.be.ok();\n\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\t\texpect(data.name).to.be(\"Bob!\");\n\t\t\t\t\texpect('string' == typeof Gun.valid(data.pet)).to.ok();\n\t\t\t\t\tnopasstun(done);\n\t\t\t\t},300);\n\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('recursive put', function(done){\n\t\t\t//localStorage.clear();\n\t\t\tvar gun = Gun();\n\n\t\t\tvar parent = gun.get('parent');\n\t\t\tvar child = gun.get('child');\n\t\t\t\n\t\t\tchild.put({\n\t\t\t\tway: 'down'\n\t\t\t});\n\t\t\t\n\t\t\tparent.get('sub').put(child);\n\t\t\t//console.only.i=1;console.log(\"============================\");\n\t\t\tparent.get('sub').on(function(data){\n\t\t\t\t//console.log(\"*********sub\", data);\n\t\t\t\tdone.sub = data;\n\t\t\t});\n\t\t\tchild.on(function(data){\n\t\t\t\tdone.child = data;\n\t\t\t\t//console.log(\"*********child\", data);\n\t\t\t});\n\t\t\tparent.on(function(data){\n\t\t\t\tdone.parent = data;\n\t\t\t\t//console.log(\"*********parent\", data);\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun); // TODO: Add more meaningful checks!\n\t\t\t});\n\t\t});\n\n\t\tit('empty val followed', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('val/follow').once(function(data){\n\t\t\t\t//console.log(\"val\", data);\n\t\t\t}).get(function(at){\n\t\t\t\t//console.log(\"?????\", at);\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\n\t\t});\n\n\t\tit('map val get put', function(done){\n\t\t\tvar gun = Gun().get('chat/asdf');\n\n\t\t\tvar check = {}, count = {};\n\t\t\tgun.map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tcount[f] = (count[f] || 0) + 1;\n\t\t\t\t//console.log(\"**************\", f, v);\n\t\t\t\tif(check['1-1'] && check['2-2']){\n\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\texpect(check['1-1'].what).to.be('hi');\n\t\t\t\t\t\texpect(check['2-2'].what).to.be('you.');\n\t\t\t\t\t\texpect(count['1-1']).to.be(1);\n\t\t\t\t\t\texpect(count['2-2']).to.be(1);\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t},50);\n\t\t\t\t}\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('1-1').put({what: \"hi\"});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('2-2').put({what: \"you.\"});\n\t\t\t\t},40);\n\t\t\t},40);\n\t\t});\n\n\t\tit('get list set map simple', function(done){\n\n\t\t\tvar gun = Gun();\n\n\t\t\tvar list = gun.get('list-s');\n\n\t\t\tlist.set(gun.get('alice-s').put({name: \"Alice\", group: \"awesome\", married: true}));\n\t\t\tvar check = {}, count = {};\n\t\t\tlist.map().on(function(data, id){\n\t\t\t\texpect(data.group).to.be('awesome');\n\t\t\t\texpect(data.married).to.be(true);\n\t\t\t\texpect(data.name).to.be('Alice');\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t});\n\n\t\tit('get list set map val', function(done){\n\n\t\t\tvar gun = Gun();\n\n\t\t\tvar list = gun.get('list');\n\n\t\t\tlist.set(gun.get('alice').put({name: \"Alice\", group: \"awesome\", married: true}));\n\t\t\tlist.set(gun.get('bob').put({name: \"Bob\", group: \"cool\", married: true}));\n\t\t\tlist.set(gun.get('carl').put({name: \"Carl\", group: \"cool\", married: false}));\n\t\t\tlist.set(gun.get('dave').put({name: \"Dave\", group: \"awesome\", married: true}));\n\n\t\t\tvar check = {}, count = {};\n\t\t\tlist.map().once(function(data, id){\n\t\t\t\tcheck[id] = data;\n\t\t\t\tcount[id] = (count[id] || 0) + 1;\n\t\t\t\tif(check.alice && check.bob && check.carl && check.dave){\n\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\texpect(count.alice).to.be(1);\n\t\t\t\t\t\texpect(check.alice.name).to.be('Alice');\n\t\t\t\t\t\texpect(check.alice.group).to.be('awesome');\n\t\t\t\t\t\texpect(check.alice.married).to.be(true);\n\t\t\t\t\t\texpect(count.bob).to.be(1);\n\t\t\t\t\t\texpect(check.bob.name).to.be('Bob');\n\t\t\t\t\t\texpect(check.bob.group).to.be('cool');\n\t\t\t\t\t\texpect(check.bob.married).to.be(true);\n\t\t\t\t\t\texpect(count.carl).to.be(1);\n\t\t\t\t\t\texpect(check.carl.name).to.be('Carl');\n\t\t\t\t\t\texpect(check.carl.group).to.be('cool');\n\t\t\t\t\t\texpect(check.carl.married).to.be(false);\n\t\t\t\t\t\texpect(count.dave).to.be(1);\n\t\t\t\t\t\texpect(check.dave.name).to.be('Dave');\n\t\t\t\t\t\texpect(check.dave.group).to.be('awesome');\n\t\t\t\t\t\texpect(check.dave.married).to.be(true);\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t},50);\n\t\t\t\t}\n\t\t\t});\n\t\t\t/*\n\t\t\t\tHave we asked for this yet? No.\n\t\t\t\tDo we have it cached? No.\n\t\t\t\tIs its parent cached? Yes.\n\t\t\t\tReply immediately with that cache for map to process.\n\t\t\t*/\n\n\t\t\t/*\n\t\t\t\tchain has a root // all\n\t\t\t\tan ID // all\n\t\t\t\ta back // all\n\t\t\t\tinputs // all\n\t\t\t\tand outputs // all\n\t\t\t\tacks // any\n\t\t\t\techo // any\n\t\t\t\tnext // any\n\t\t\t\tcache or map of many ones // only a one can have a cache, only a map can have many, and they must be ones. However any chain might have neither. By default a chain is a many, unless it is designated as a one.\n\n\t\t\t\tgun.get('alice').also('bob').path('name').on(cb);\n\t\t\t\tgun.get('users').map().path('friends').map().on(cb);\n\n\t\t\t\tfriends is a map, it has an echo\n\t\t\t\t{name: \"alice\", friends: []}\n\t\t\t\t\t{name: \"xavier\"}\n\t\t\t\t\t{name: \"yara\"}\n\t\t\t\t\t{name: \"zack\"}\n\t\t\t\t{name: \"bob\", friends: []}\n\t\t\t\t\t{name: \"xavier\"}\n\t\t\t\t\t{name: \"yara\"}\n\t\t\t\t\t{name: \"zack\"}\n\t\t\t\t{name: \"carl\", friends: []}\n\t\t\t\t\t{name: \"xavier\"}\n\t\t\t\t\t{name: \"yara\"}\n\t\t\t\t\t{name: \"zack\"}\n\t\t\t*/\n\t\t});\n\n\t\tit('get get get set root get put', function(done){\n\t\t\tvar gun = Gun().get('app');\n\t\t\t//console.only.i=1;console.log('---------------');\n\t\t\tgun.get('alias').get('mark').set(\n\t\t\t\tgun.back(-1).get('pub').put({\n\t\t\t\t\talias: 'mark',\n\t\t\t\t\tauth: 'encrypt', // oops\n\t\t\t\t\tborn: 1,\n\t\t\t\t\tpub: 'pub',\n\t\t\t\t\tsalt: 'random'\n\t\t\t\t})\n\t\t\t);\n\t\t\tsetTimeout(function(){\n\t\t\t\t//console.debug.i=1;console.log('---------------');\n\t\t\t\tgun.get(function(at){\n\t\t\t\t\t//console.log(\"*\", at.put);//return;\n\t\t\t\t\tdone.app = done.app || at.put.alias;\n\t\t\t\t});\n\t\t\t\tgun.back(-1).get('pub').get(function(at){\n\t\t\t\t\t//console.log(\"**\", at.put.auth);\n\t\t\t\t\tdone.pub = done.pub || at.put.auth;\n\t\t\t\t});\n\t\t\t\tgun.get('alias').get(function(at){\n\t\t\t\t\t//console.log(\"***\", at);\n\t\t\t\t\tdone.alias = done.alias || at.put.mark;\n\t\t\t\t\t//!console.debug.i&&(console.debug.i=1)&&console.log(\"---------------------\");\n\t\t\t\t}).get('mark').on(function(data){\n\t\t\t\t\t//console.log(\"************\", data);//return;\n\t\t\t\t\tclearTimeout(done.to);\n\t\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\t\tdone.mark = done.mark || data.pub;\n\t\t\t\t\t\t//console.log('???', done.app, done.pub, done.alias);\n\t\t\t\t\t\texpect(Gun.valid(done.mark)).to.be('pub');\n\t\t\t\t\t\texpect(done.app).to.be.ok();\n\t\t\t\t\t\texpect(done.pub).to.be.ok();\n\t\t\t\t\t\texpect(done.alias).to.be.ok();\n\t\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t},100);\n\t\t\t\t})\n\t\t\t},100);\n\t\t});\n\n\t\tit('get put get get put reload get get then get', function(done){\n\t\t\tthis.timeout(9000);\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('stef').put({name:'Stef'});\n\t\t\tvar address = {\n\t\t\t  country: 'Netherlands',\n\t\t\t  zip:'999999'\n\t\t\t};\n\t\t\tgun.get('stef').get('address').put(address);\n\n\t\t\t// reload\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar gun2 = Gun();\n\t\t\t\t//console.log(require('fs').readFileSync('./radata/!').toString());\n\t\t\t\tgun2.get('stef').get('address').once(function(data){ // Object {_: Object, country: \"Netherlands\", zip: \"1766KP\"} \"address\"\n\t\t\t\t\t//console.log(\"******\", data);return;\n\t\t\t\t\tdone.a = true;\n\t\t\t\t\texpect(data.country).to.be('Netherlands');\n\t\t\t\t\texpect(data.zip).to.be('999999');\n\t\t\t\t\tif(!done.s){ return }\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tnopasstun(done, gun2);\n\t\t\t\t});\n\t\t\t\tgun2.get('stef').once(function(data){ //Object {_: Object, address: Object} \"stef\"\n\t\t\t\t\t//console.log(\"**************\", data);return;\n\t\t\t\t\tdone.s = true;\n\t\t\t\t\texpect(data.name).to.be('Stef');\n\t\t\t\t\texpect(data.address).to.be.ok();\n\t\t\t\t\tif(!done.a){ return }\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tnopasstun(done, gun2);\n\t\t\t\t});\n\t\t\t},1200);\n\t\t});\n\n\t\tit('get get get any parallel', function(done){\n\n\t\t\tGun.statedisk({\n\t\t\t\tbob: {\n\t\t\t\t\tage: 29,\n\t\t\t\t\tname: \"Bob!\"\n\t\t\t\t}\n\t\t\t}, 'parallel', function(){\n\t\t\tgun.get('parallel').get('bob').get('age').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"*****\", field, data);return;\n\t\t\t\texpect(data).to.be(29);\n\t\t\t\texpect(field).to.be('age');\n\t\t\t\tdone.age = true;\n\t\t\t});\n\t\t\t//console.log(\"-----------------------\");\n\t\t\tgun.get('parallel').get('bob').get('name').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"***********\", field, data);return;\n\t\t\t\texpect(data).to.be('Bob!');\n\t\t\t\texpect(field).to.be('name');\n\t\t\t\tdone.name = true;\n\t\t\t\texpect(done.age).to.be.ok();\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('get get get any later', function(done){\n\t\t\tGun.statedisk({\n\t\t\t\tbob: {_:{'#':'ddfsa'},\n\t\t\t\t\tage: 29,\n\t\t\t\t\tname: \"Bob!\"\n\t\t\t\t}\n\t\t\t}, 'parallel/later', function(){\n\t\t\tgun.get('parallel/later').get('bob').get('age').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"*****\", field, data); return;\n\t\t\t\texpect(data).to.be(29);\n\t\t\t\texpect(field).to.be('age');\n\t\t\t\tdone.age = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('parallel/later').get('bob').get('name').get(function(at, ev){\n\t\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t\t//console.log(\"***********\", field, data); return;\n\t\t\t\t\texpect(data).to.be('Bob!');\n\t\t\t\t\texpect(field).to.be('name');\n\t\t\t\t\tdone.name = true;\n\t\t\t\t\texpect(done.age).to.be.ok();\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t});\n\t\t\t},400);\n\t\t\t});\n\t\t});\n\n\t\tit('get get get any not', function(done){\n\t\t\tgun.get('parallel/not').get('bob').get('age').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"***** age\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\texpect(field).to.be('age');\n\t\t\t\tdone.age = true;\n\t\t\t});\n\t\t\tgun.get('parallel/not').get('bob').get('name').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"*********** name\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\texpect(field).to.be('name');\n\t\t\t\tdone.name = true;\n\t\t\t\texpect(done.age).to.be.ok();\n\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t});\n\n\t\tit('get get get any not later', function(done){\n\t\t\tgun.get('parallel/not/later').get('bob').get('age').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"***** age\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\texpect(field).to.be('age');\n\t\t\t\tdone.age = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\t//console.debug.i=1;console.log('---------------');\n\t\t\t\tgun.get('parallel/not/later').get('bob').get('name').get(function(at, ev){\n\t\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t\t//console.log(\"*********** name\", field, data);\n\t\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\t\texpect(field).to.be('name');\n\t\t\t\t\tdone.name = true;\n\t\t\t\t\texpect(done.age).to.be.ok();\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t});\n\t\t\t},400);\n\t\t});\n\n\t\tit('get any any', function(done){\n\t\t\tGun.statedisk({\n\t\t\t\thello: 'world',\n\t\t\t\tgoodbye: 'mars'\n\t\t\t}, 'full', function(){\n\t\t\tgun.get('full').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.$._.put || at.put, field = at.get;\n\t\t\t\t//console.log(\"*****1\", data, field);return;\n\t\t\t\texpect(data.hello).to.be('world');\n\t\t\t\texpect(data.goodbye).to.be('mars');\n\t\t\t});\n\t\t\tgun.get('full').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.$._.put || at.put, field = at.get;\n\t\t\t\t//console.log(\"*****2\", data, field);return;\n\t\t\t\texpect(data.hello).to.be('world');\n\t\t\t\texpect(data.goodbye).to.be('mars');\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('get any any later', function(done){\n\t\t\tGun.statedisk({\n\t\t\t\thello: 'world',\n\t\t\t\tgoodbye: 'mars'\n\t\t\t}, 'full/later', function(){\n\t\t\tgun.get('full/later').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.$._.put || at.put, field = at.get;\n\t\t\t\t//console.log(\"*****\", data);\n\t\t\t\texpect(data.hello).to.be('world');\n\t\t\t\texpect(data.goodbye).to.be('mars');\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('full/later').get(function(at, ev){\n\t\t\t\t\tvar err = at.err, data = at.$._.put || at.put, field = at.get;\n\t\t\t\t\t//console.log(\"*****2\", field, data);\n\t\t\t\t\texpect(data.hello).to.be('world');\n\t\t\t\t\texpect(data.goodbye).to.be('mars');\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t});\n\t\t\t},400);\n\t\t\t});\n\t\t});\n\n\t\tit('multiple times map', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('A').put({\n\t\t\t\t'B': {\n\t\t\t\t\tC: {\n\t\t\t\t\t\tpub: 'fdsa',\n\t\t\t\t\t\ty: \"mark\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'timber': {\n\t\t\t\t\tasdf: {\n\t\t\t\t\t\tpub: 'asdf',\n\t\t\t\t\t\tname: \"timber\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar check = {on: {}, once: {}};\n\t\t\tsetTimeout(function(){\n\t\t\t\t//console.log('A=2, map=7, map.map=8, A.B=3, AB=5, A.B.C=4, ABC=6, AB.C=?', gun);\n\t\t\t\tgun.get('A').map().map().on(function(data, key){\n\t\t\t\t\t//console.log(111111, key, data);\n\t\t\t\t\tcheck.on[data.pub] = true;\n\t\t\t\t})\n\t\t\t}, 900);\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('A').map().map().once(function(data, key){\n\t\t\t\t\t//console.log(22222, key, data);\n\t\t\t\t\tcheck.once[data.pub] = true;\n\t\t\t\t\t//console.log(check);\n\t\t\t\t\tif(check.on['asdf'] && check.on['fdsa'] && check.once['asdf'] && check.once['fdsa']){\n\t\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}, 1200);\n\n\t\t});\n\n\t\tit('many maps with @rogowski!', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar data = {\n\t\t\t\tlevelA2: { levelA3: { levelA4: { levelA5: \"hello\" } } },\n\t\t\t\tlevelB2: { levelB3: { levelB4: { levelB5: \"world\" } } }\n\t\t\t};\n\n\t\t\tGun.statedisk(data, 'level1', function(){\n\t\t\t\tvar check = {}, log = function(){} || console.log;\n\t\t\t\tgun.get('level1').on(function(v,k){ log(1,k,v); check[k] = v });\n\t\t\t\tgun.get('level1').map().on(function(v,k){ log('*',2,k,v); check[k] = v });\n\t\t\t\tgun.get('level1').map().map().on(function(v,k){ log('*',3,k,v); check[k] = v });\n\t\t\t\tgun.get('level1').map().map().map().on(function(v,k){ log('*',4,k,v); check[k] = v;\n\t\t\t\t\tcheck.to = check.to || setTimeout(function(){\n\t\t\t\t\t\texpect(check.level1.levelA2).to.eql({'#':\"level1/levelA2\"});\n\t\t\t\t\t\texpect(check.level1.levelB2).to.eql({'#':\"level1/levelB2\"});\n\n\t\t\t\t\t\texpect(check.levelA2.levelA3).to.eql({'#':\"level1/levelA2/levelA3\"});\n\t\t\t\t\t\texpect(check.levelA3.levelA4).to.eql({'#':\"level1/levelA2/levelA3/levelA4\"});\n\t\t\t\t\t\texpect(check.levelA4.levelA5).to.be(\"hello\");\n\n\t\t\t\t\t\texpect(check.levelB2.levelB3).to.eql({'#':\"level1/levelB2/levelB3\"});\n\t\t\t\t\t\texpect(check.levelB3.levelB4).to.eql({'#':\"level1/levelB2/levelB3/levelB4\"});\n\t\t\t\t\t\texpect(check.levelB4.levelB5).to.be(\"world\");\n\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t}, 250);\n\t\t\t\t});\n\t\t\t\tgun.get('level1').map().map().map().map().on(function(v,k){ log('*',5,k,v); check[k] = v; }); // see test below\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('many maps with @rogowski last value map', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar data = {\n\t\t\t\tlevelA2: { levelA3: { levelA4: { levelA5: \"hello\" } } },\n\t\t\t\tlevelB2: { levelB3: { levelB4: { levelB5: \"world\" } } }\n\t\t\t};\n\n\t\t\tGun.statedisk(data, 'level1p', function(){\n\t\t\t\tvar check = {}, log = function(){} || console.log;\n\t\t\t\t//console.log(\"======================\");\n\t\t\t\tgun.get('level1p').map().map().map().map().on(function(v,k){ log('level5', k,v); check[k] = v;\n\t\t\t\t\tcheck.to = check.to || setTimeout(function(){\n\t\t\t\t\t\texpect(check.levelA5).to.be('hello');\n\t\t\t\t\t\texpect(check.levelB5).to.be('world');\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t}, 20);\n\t\t\t\t});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('multiple map test with @rogowski!', function(done){\n\t\t\tvar check = {};\n\t\t\tvar gun1 = Gun();\n\t\t\tgun1.get('mmA').put({\n\t\t\t\t'B': {\n\t\t\t\t\tC: {\n\t\t\t\t\t\tpub: 'fdsa',\n\t\t\t\t\t\ty: \"mark\"\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t'timber': {\n\t\t\t\t\tasdf: {\n\t\t\t\t\t\tpub: 'asdf',\n\t\t\t\t\t\tname: \"timber\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t//console.only.i=1;console.log(\"--------------------\", gun1._.next);\n\t\t\tgun1.get('mmA').map().map().on(function(data, has){\n\t\t\t\tcheck[has+1] = data;\n\t\t\t\t//console.log('first test ONLY get called with C/asdf = pub:fdsa/pub:asdf......', has, data);\n\t\t\t});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar gun2 = Gun();\n\t\t\t\tgun2.get('2mmA').put({nest: {\n\t\t\t\t\t'B': {\n\t\t\t\t\t\tC: {\n\t\t\t\t\t\t\tpub: 'fdsa',\n\t\t\t\t\t\t\ty: \"mark\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t'timber': {\n\t\t\t\t\t\tasdf: {\n\t\t\t\t\t\t\tpub: 'asdf',\n\t\t\t\t\t\t\tname: \"timber\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}});\n\t\t\t\t//console.only.i=101;console.log(\"------------------\");\n\t\t\t\t//console.log(\"CHAIN ID: 2mma = 2, 2mmA.nest = 3, map=4, map.map=5, 2mmaNBC=17, 2mma.nest.b.c=8, 2mmanest=9, 2mmanest.b=11\", gun2._);\n\n\t\t\t\tgun2.get('2mmA').get('nest').map().map().on(function(data, has){\n\t\t\t\t\tcheck[has+2] = data;\n\t\t\t\t\t//console.log('should log pub=fdsa/asdf....', has, data);\n\t\t\t\t\tcheck.to = check.to || setTimeout(function(){\n\t\t\t\t\t\tif(check.C1.pub === 'fdsa' && check.C1.y === 'mark'\n\t\t\t\t\t\t&& check.asdf1.pub === 'asdf' && check.asdf1.name === 'timber'\n\t\t\t\t\t\t&& check.C2.pub === 'fdsa' && check.C2.y === 'mark'\n\t\t\t\t\t\t&& check.asdf2.pub === 'asdf' && check.asdf2.name === 'timber'){\n\t\t\t\t\t\t\tnopasstun(done, gun2);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 150);\n\t\t\t\t});\n\t\t\t},70);\n\n\t\t});\n\n\t\tit('multiple times', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar app = gun.get('mult/times');\n\n\t\t\tapp.get('alias').get('mark').set(gun.get('ASDF').put({\n\t\t\t\tpub: 'ASDF',\n\t\t\t\talias: 'mark',\n\t\t\t\tborn: 1\n\t\t\t}));\n\n\t\t\tgun.get('mult/times').get('alias').map().map().get('pub').on(foo);\n\t\t\tfunction foo(data){\n\t\t\t\tdone.one = done.one || data;\n\t\t\t\tif(!done.one || !done.two){ return }\n\t\t\t\texpect(done.one).to.be(\"ASDF\");\n\t\t\t\texpect(done.two).to.be(\"mark\");\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t};\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tapp.get('alias').map().map().get('alias').on(function(data){\n\t\t\t\t\tdone.two = data;\n\t\t\t\t\tfoo();\n\t\t\t\t});\n\t\t\t},10);\n\t\t});\n\n\t\tit('multiple times partial', function(done){\n\t\t\tGun.statedisk({ alias: { mark: { pub: {_:{'#':'PUB'}, pub: 'asdf', alias: 'mark', born: 1 } } } }, 'mult/times/part', function(){\n\t\t\tvar gun = Gun();\n\t\t\tvar app = gun.get('mult/times/part');\n\t\t\t\n\t\t\t//console.debug.i=1;console.log(\"===================\");\n// \t\t\tapp.get('alias').get('mark').once(function(alias){\n// \t\t\t\tconsole.log(\"***111 \", alias);\n// \t\t\t\tdone.alias = alias;\n// \t\t\t});\n\t\t\tapp.get('alias').get('mark').map().once(function(alias){\n// \t\t\t\tconsole.log(\"***>>>> \", alias);\n//         if (typeof alias !== 'undefined') {\n          done.alias = alias;\n//         }\n\t\t\t});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tapp.get('alias').map().map().get('born').on(function(data){\n// \t\t\t\t\tconsole.log(\"*******\", data);\n\t\t\t\t\texpect(data).to.be(1);\n\t\t\t\t\texpect(done.alias.pub).to.be(\"asdf\");\n\t\t\t\t\texpect(done.alias.alias).to.be(\"mark\");\n\t\t\t\t\texpect(done.alias.born).to.be(1);\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t});\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('put on a put', function(done){\n\t\t\ttry{\n\t\t\tvar gun = Gun();\n\t\t\tvar foo = gun.get('put/on/put').get('a').get('b');\n\t\t\tvar bar = gun.get('put/on/put/ok').get('a').get('b');\n\n\t\t\tbar.put({a:1});\n\t\t\t//console.log(\"vvvvvvvvv\");\n\t\t\tbar.on(function(data){\n\t\t\t\t//console.log(\"***\", data);\n\t\t\t\tif(1 === data.a && 3 === data.c){\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\t//console.log(\"-------\");\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tfoo.on(function(ack){\n\t\t\t\t//console.log(\"*\", ack);\n\t\t\t\tbar.put({c:3});\n\t\t\t});\n\t\t\tfoo.put({b:2});\n\t\t\t}catch(e){ console.log(\"!!!!!!!!!!!\", e)}\n\t\t});\n\n\t\tit('map with map function', function(done){\n\t\t\tvar gun = Gun(), s = 'map/mapfunc', u;\n\t\t\tvar app = gun.get(s);\n\t\t\tvar list = app.get('list');\n\n\t\t\tvar check = {};\n\t\t\tlist.map(function(user){ /*console.log(\"****\", user);*/ return user.age === 27? user.name + \"thezombie\" : u }).on(function(data){\n\t\t\t\t//console.log('+++++', data);\n\t\t\t\tcheck[data] = true;\n\t\t\t\tif(check.alicethezombie && check.bobthezombie){\n\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\tsetTimeout(function(){ nopasstun(done, gun) },99);\n\t\t\t\t}\n\t\t\t});\n\t\t\t//console.debug.i=1;console.log(\"--------------\");\n\t\t\tlist.set({name: 'alice', age: 27}); // on put, table-scan flag doesn't get set, but is needed for initial!??\n\t\t\tlist.set({name: 'bob', age: 27});\n\t\t\tlist.set({name: 'carl', age: 29});\n\t\t\tlist.set({name: 'dave', age: 25});\n\t\t});\n\n\t\tit('once map function once', function(done){\n\t\t\tvar gun = Gun(), s = 'o/mf/o', u;\n\t\t\tvar app = gun.get(s);\n\t\t\tvar list = app.get('list');\n\n\t\t\tvar check = {};\n\t\t\tgun.get('useromo').get('alice').put({name:'Alice', email:'alice@example.com'})\n\t\t\tgun.get('useromo').get('bob').put({name:'Bob', email:'bob@example.com'})\n\t\t\tgun.get('useromo').get('carl').put({name:'Carl', email:'carl@example.com'})\n\n\t\t\tgun.get('useromo').once().map(v => {\n\t\t\t  //console.log('this gets called', v);\n\t\t\t  return v\n\t\t\t}).once((v, k) => {\n\t\t\t  //console.log('this is never called', k, v);\n\t\t\t  check[k] = (check[k] || 0) + 1;\n\t\t\t  if(1 === check.alice && 1 === check.bob && 1 === check.carl){\n\t\t\t  \tif(done.c){return}done.c=1;\n\t\t\t  \tsetTimeout(function(){ nopasstun(done, gun) },9);\n\t\t\t  }\n\t\t\t});\n\n\t\t});\n\n\t\tit('val and then map', function(done){\n\t\t\tvar gun = Gun(), s = 'val/then/map', u;\n\t\t\tvar list = gun.get(s);\n\n\t\t\tlist.set(gun.get('alice').put({name: 'alice', age: 27}));\n\t\t\tlist.set(gun.get('bob').put({name: 'bob', age: 27}));\n\t\t\tlist.set(gun.get('carl').put({name: 'carl', age: 29}));\n\t\t\tlist.set(gun.get('dave').put({name: 'dave', age: 25}));\n\n\t\t\tvar check = {};\n\t\t\tlist.once().map().on(function(data, key){\n\t\t\t\tcheck[key] = data;\n\t\t\t\tclearTimeout(done.to);\n\t\t\t\t//console.log(\"*****\", key, data);\n\t\t\t\tdone.to = setTimeout(function(){\n\t\t\t\t\tif(check.alice && check.bob && check.carl && check.dave && done.last){\n\t\t\t\t\t\texpect(check.alice.age).to.be(27);\n\t\t\t\t\t\texpect(check.bob.age).to.be(28);\n\t\t\t\t\t\texpect(check.carl.age).to.be(29);\n\t\t\t\t\t\texpect(check.dave.age).to.be(25);\n\t\t\t\t\t\texpect(check.eve).to.not.be.ok();\n\t\t\t\t\t\tif(done.c){return}done.c=1;\n\t\t\t\t\t\tsetTimeout(function(){ nopasstun(done, gun) },9);\n\t\t\t\t\t}\n\t\t\t\t},600);\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tlist.set(gun.get('eve').put({name: 'eve', age: 30}));\n\t\t\t\tgun.get('bob').get('age').put(28);\n\t\t\t\tdone.last = true;\n\t\t\t},300);\n\t\t});\n\n\t\tit('check null on map', function(done){\n\t\t\tvar list = gun.get('myList');\n\t\t\tlist.map(function(value, id){\n\t\t\t\tif(\"hello world\" === value){\n\t\t\t\t\tdone.one = true;\n\t\t\t\t}\n\t\t\t\tif(null === value){\n\t\t\t\t\tdone.two = true;\n\t\t\t\t}\n\t\t\t\tif(done.one && done.two){\n\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t}\n\t\t\t});\n\t\t\tlist.get('message').put('hello world'); // outputs \"message: hello world\"\n\t\t\tlist.get('message').put(null); // throws Uncaught TypeError: Cannot read property '#' of null\n\t\t});\n\n\t\tit('Check multi instance message passing', function(done){\n\t\t\t// NOTICE: The behavior of this test changed from v0.2020.520 to version after.\n\t\t\ttry{ require('fs').unlinkSync('bdata') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync('ddata') }catch(e){}\n\t\t\tGun.on('opt', function(ctx){\n\t\t\t\tctx.on('out', function(msg){\n\t\t\t\t\tthis.to.next(msg);\n\t\t\t\t\tvar onGun = ctx;\n\t\t\t\t\tvar tmp = {}; Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] }); delete tmp.out; delete tmp._; msg = tmp; // copy message.\n\t\t\t\t\tif(onGun.$ === b) {\n\t\t\t\t\t\tif(d){\n\t\t\t\t\t\t\t//console.log(\"b can send to d....\", JSON.parse(JSON.stringify(msg)));\n\t\t\t\t\t\t\tmsg.$ = d;\n\t\t\t\t\t\t\td.on(\"in\", msg);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if(onGun.$ === d){\n\t\t\t\t\t\t//console.log(\"d sends to b....\", JSON.parse(JSON.stringify(msg)));\n\t\t\t\t\t\tmsg.$ = b;\n\t\t\t\t\t\tb.on(\"in\", msg);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tvar b = Gun({file: \"bdata\"});\n\t\t\tvar d = null;\n\n\t\t\tvar bb = b.get(\"key\");\n\t\t\tbb.put({msg: \"hello\"});\n\t\t\t\t\n\t\t\td = Gun({file: \"ddata\"});\n\t\t\tvar db = d.get(\"key\");\n\t\t\tdb.map().on(function(val,field){\n\t\t\t\texpect(val).to.be('hello');\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tnopasstun(0, b);\n\t\t\t\t\tnopasstun(done, d);\n\t\t\t\t},1700);\n\t\t\t});\n\t\t});\n\n\t\tit('val should now get called if no data is found', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('nv/foo').get('bar').get('baz').once(function(val, key){\n\t\t\t\t//console.log('*******', key, val);\n\t\t\t\texpect(val).to.be(undefined);\n\t\t\t\tdone.fbb = true;\n\t\t\t});\n\n\t\t\tgun.get('nv/totesnothing').once(function(val, key){\n\t\t\t\t//console.log('***********', key, val);\n\t\t\t\texpect(val).to.be(undefined);\n\t\t\t\tdone.t = true;\n\t\t\t});\n\n\t\t\tgun.get('nv/bz').get('lul').once(function(val, key){\n\t\t\t\t//console.log('*****************', key, val);\n\t\t\t\texpect(val).to.be(undefined);\n\t\t\t\tdone.bzl = true;\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tif(done.fbb && done.t && done.bzl){\n\t\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t}\n\t\t\t\t},100);\n\t\t\t});\n\t\t});\n\n\t\tit('Callbacks should have database safe data copies', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('ds/safe').put({a: 1});\n\t\t\t\n\t\t\tgun.get('ds/safe').on(function(data){\n\t\t\t\tdata.b = 2;\n\t\t\t});\n\t\t\t\n\t\t\tgun.get('ds/safe').once(function(data){\n\t\t\t\texpect(gun.back(-1)._.graph['ds/safe'].b).to.not.be.ok();\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t});\n\n\t\tit('If chain cannot be called, ack', function(done){\n\t\t\tGun.statedisk({ wat: 1, a: true }, 'nl/app', function(){\n\t\t\tvar gun = Gun(), u;\n\t\t\tvar app = gun.get('nl/app');\n\n\t\t\tapp.get(function(d){\n\t\t\t\tif(done.a){ return }\n\t\t\t\td = (d.$$||d.$)._.put;\n\t\t\t\t//console.log('*', d);\n\t\t\t\texpect(d.wat).to.be(1);\n\t\t\t\texpect(d.a).to.be(true);\n\t\t\t\tdone.a = 1;\n\t\t\t}, {v2020:1});\n\n\t\t\tapp.get('a').get('b').get(function(d){\n\t\t\t\td = (d.$$||d.$)._.put;\n\t\t\t\t//console.log('****', d);\n\t\t\t\texpect(d).to.be(u);\n\t\t\t\texpect(done.a).to.be.ok();\n\t\t\t\tdone.b = (done.b || 0) + 1;\n\t\t\t}, {v2020:1});\n\n\t\t\tsetTimeout(function(){ // adding more rigorous test!\n\t\t\t\t//console.log(\"------------\");\n\t\t\t\tapp.get('a').get('b').get(function(d){\n\t\t\t\t\td = (d.$$||d.$)._.put;\n\t\t\t\t\t//console.log('****::::', d);\n\t\t\t\t\texpect(done.b).to.be(1);\n\t\t\t\t\tdone.c = (done.c || 0) + 1;\n\t\t\t\t});\n\n\t\t\t\tapp.get('a').put('lol');\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\texpect(done.c).to.be(1);\n\t\t\t\t\tif(done.d){ return } done.d = 1;\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t},50);\n\t\t\t}, 50);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('Chain on known nested object should ack', function(done){\n\t\t\tGun.statedisk({ bar: { wat: 1 } }, 'nl/app', function(){\n\t\t\tvar gun = Gun(), u;\n\t\t\tvar app = gun.get('nl/app').get('bar');\n\n\t\t\tapp.get(function(d){\n\t\t\t\t//d = (d.$$||d.$)._.put;\n\t\t\t\tif(!d || !d.put || !d.put.wat){ return }\n\t\t\t\t//console.log('************ should be called: {wat:1}=', d.put);\n\t\t\t\texpect(d.put.wat).to.be(1);\n\t\t\t\tdone.a = 1;\n\t\t\t\tif(!done.u){ return }\n\t\t\t\texpect(done.u).to.be.ok();\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});//, {v2020:1});\n\n\t\t\t//console.log(\"----------\");\n\t\t\tapp.get('a').get('b').get(function(d){\n\t\t\t\t//console.log(\"************ empty/clear: undefined=\", d.put);\n\t\t\t\t//d = (d.$$||d.$)._.put;\n\t\t\t\texpect(d.put).to.be(u);\n\t\t\t\tdone.u = true;\n\t\t\t\tif(!done.a){ return }\n\t\t\t\texpect(done.a).to.be.ok();\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t}, {v2020:1});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('Soul above but not beneath', function(done){\n\t\t\tthis.timeout(5000);\n\t\t\tvar gun = Gun();\n\t\t\tvar a = gun.get('sabnb');\n\t\t\ta.get('profile').put({_:{'#': 'sabnbprofile'}, name: \"Plum\"});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\ta.get('profile').get('said').get('asdf').put('yes');\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ta.once(function(data){\n\t\t\t\t\t\texpect(data.profile).to.be.eql({'#': 'sabnbprofile'});\n\t\t\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t})\n\t\t\t\t}, 100);\n\t\t\t}, 100);\n\n\t\t});\n\n\t\tit('users map map who said map on', function(done){\n\t\t\tthis.timeout(1000 * 9);\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('users/mm').put({\n\t\t\t\talice: {_:{'#':'alias/alice'},\n\t\t\t\t\t'pub/asdf': {_:{'#':'pub/asdf'},\n\t\t\t\t\t\tpub: 'asdf'\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tbob: {_:{'#':'alias/bob'},\n\t\t\t\t\t'pub/fdsa': {_:{'#':'pub/fdsa'},\n\t\t\t\t\t\tpub: 'fdsa'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar check = {}, c = 0, end;\n\t\t\t//console.log(check, gun._.graph);\n\t\t\tgun.get('users/mm').map().map()\n\t\t\t\t.get('who').get('said').map().on(function(msg){\n\t\t\t\t\t//console.log(\"------>\", msg);\n\t\t\t\t\tif(check[msg.num]){\n\t\t\t\t\t\t//console.log(\"!!!!\", msg.num, \"!!!!\");\n\t\t\t\t\t}\n\t\t\t\t\tdelete check[msg.num];\n\t\t\t\t\tc++;\n\t\t\t\t\tclearTimeout(end); end = setTimeout(function(){\n\t\t\t\t\t\t//console.log(\"?\", c, check, Object.keys(check), gun._.graph);\n\t\t\t\t\t\tif(!Object.empty(check)){ return } //if(Gun.obj.map(check, function(v){ if(v){ return v } })){ return }\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t},9);\n\t\t\t});\n\n\t\t\tvar said = gun.get('pub/asdf').get('who').get('said');\n\n\t\t\tfunction run(i){\n\t\t\t\t//if(i > 1){ return } // DEBUGGING!\n\t\t\t\t//console.log(\"----\", i, \"----\");\n\t\t\t\t//2 === i && (console.only.i = 1) && console.only(1, '==========');\n\t\t\t\t//(console.debug.i = console.debug.i || 1);\n\t\t\t\tsaid.set({\n\t\t\t\t\twhat: i + \" Hello world!\",\n\t\t\t\t\tnum: i,\n\t\t\t\t\twho: 'asdf',\n\t\t\t\t\tid: 'alice',\n\t\t\t\t});\n\n\t\t\t}\n\n\t\t\tvar i = 0, m = 9, to = setTimeout(function frame(){\n\t\t\t\tif(m <= i){\n\t\t\t\t\tclearTimeout(to);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t\tcheck[i] = true;\n\t\t\t\trun(i);\n\t\t\t\tsetTimeout(frame, 1);\n\t\t\t}, 1);\n\n\t\t});\n\n\t\tit('get map should not slowdown', function(done){\n\t\t\tthis.timeout(9000);\n\t\t\tvar gun = Gun({test_no_peer:true}).get('g/m/no/slow');\n\t\t\t//console.log(\"---------- setup data done -----------\");\n\t\t\tvar prev, diff, max = 90, total = 500, largest = -1, gone = {}, u;\n\t\t\t//var prev, diff, max = Infinity, total = 10000, largest = -1, gone = {};\n\t\t\t// TODO: It would be nice if we could change these numbers for different platforms/versions of javascript interpreters so we can squeeze as much out of them.\n\t\t\tgun.get('history').map().on(function(time, index){\n\t\t\t\tdiff = +new Date - time;\n\t\t\t\t//console.log(\">>>\", index, time, diff);//return;\n\t\t\t\texpect(gone[index]).to.not.be.ok();\n\t\t\t\tgone[index] = diff;\n\t\t\t  largest = (largest < diff)? diff : largest;\n\t\t\t  expect(diff > max).to.not.be.ok();\n\t\t\t});\n\t\t\t//console.only.i=1;\n\t\t\tvar turns = 0;\n\t\t\tvar many = setTimeout(function go(){ // TODO: NOTE: BUG? using setInterval caused poor CPU scheduling that did fail this test, it is possible actual apps might use that approach even tho for now they should use this adjusted version, so maybe we need to review a test in future for that?\n\t\t\t\tif(turns > total || (diff || 0) > (max + 5)){\n\t\t\t\t\tif(u === diff){ return }\n\t\t\t\t\tclearTimeout(many);\n\t\t\t  \texpect('number' === typeof diff).to.be.ok();\n\t\t\t  \tif(done.c){ return } done.c = 1;\n\t\t\t  \tnopasstun(done, gun);\n\t\t\t  \treturn;\n\t\t\t  }\n\t\t\t  prev = +new Date;\n\t\t\t  var put = {}; put[turns += 1] = prev;\n\t\t\t  //console.log(\"put\", put);\n\t\t\t  //console.log(\"------\", turns, \"-------\");\n\t\t\t  //3 === turns && (console.debug.i = 1);\n\t\t\t  //console.debug(1, 'save', {history: put});\n\t\t\t  gun.put({history: put});\n\t\t\t  many = setTimeout(go, 1); // see above NOTE, increasing total runs to compensate.\n\t\t\t}, 1);\n\t\t});\n\n\t\tit('Check put callback', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('c/p/c').get('a').put('lol', function(ack){\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t});\n\n\t\tit('Resume reads after put error', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.get('r/r/a/p/e').put({a: 1});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('r/r/a/p/e').get('a').get('b').get('c').put([], function(ack){\n\t\t\t\t\texpect(ack.err).to.be.ok();\n\t\t\t\t\texpect(ack.err.toLowerCase().indexOf('array') >= 0).to.be.ok();\n\t\t\t\t\texpect(ack.err.toLowerCase().indexOf('a.b.c') >= 0).to.be.ok();\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tgun.get('r/r/a/p/e').once(function(data){\n\t\t\t\t\t\t\texpect(data.a).to.be(1);\n\t\t\t\t\t\t\t//console.log(\"data!\", data);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t});\n\t\t\t\t\t},50);\n\t\t\t\t});\n\t\t\t},100)\n\t\t});\n\n\t\tit('Multiple subscribes should trigger', function(done){\n\t\t\t// thanks to @ivkan for reporting and providing test.\n\t\t\tvar gun = Gun();\n\t\t\tvar check = {};\n\t\t\tgun.get('m/s/key').put({property: 'value'});\n\n\t\t\tgun.get('m/s/key').on(function(data, key){\n\t\t\t\tcheck['a'+data.property] = 1;\n\t\t\t});\n\n\t\t\tgun.get('m/s/key').on(function(data, key){\n\t\t\t\tcheck['b'+data.property] = 1;\n\t\t\t  if(check.avalue && check.bvalue && check.anewValue && check.bnewValue){\n\t\t\t  \tif(done.c){ return } done.c = true;\n\t\t\t  \tnopasstun(done, gun);\n\t\t\t  }\n\t\t\t});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('m/s/key').put({property: 'newValue'});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('Deep puts with peer should work', function(done){\n\t\t\t// tests in async mode now automatically connect to localhost peer.\n\t\t\t//var gun = Gun('http://localhost:8765/gun');\n\t\t\tvar gun = Gun();\n\t\t\t//var user = gun.user();\n\t\t\t//user.create('alice', 'password', function(){\n\t\t\t\tgun.get('who').get('all').put({what: \"hello world!\", when: Gun.state()}, function(ack){\n\t\t\t\t//user.get('who').get('all').put({what: \"hello world!\", when: Gun.state()}, function(ack){\n\t\t\t\t\tgun.get('who').get('all').once(function(data){\n\t\t\t\t\t\texpect(data.what).to.be.ok();\n\t\t\t\t\t\texpect(data.when).to.be.ok();\n\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t//});\n\t\t});\n\n\t\tit('Set a ref should be found', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar msg = {what: 'hello world'};\n\t\t\t//var ref = user.get('who').get('all').set(msg);\n\t\t\t//user.get('who').get('said').set(ref);\n\t\t\tvar ref = gun.get('s/r/who').get('all').set(msg, function(ack){ /*console.log('@@@', ack)*/ });\n\t\t\tgun.get('s/r/who').get('said').set(ref, function(ack){ /*console.log('###', ack)*/ });\n\t\t\tgun.get('s/r/who').get('said').map().once(function(data){\n\t\t\t\texpect(data.what).to.be.ok();\n\t\t\t\tnopasstun(done, gun);\n\t\t\t})\n\t\t});\n\n\t\t/*describe('talk to live server tests', function(){\n\t\t\tthis.timeout(1000 * 9);\n\t\t\tit.only('Second once on undefined should call', function(done){ // this test is passing when it fails by hand?\n\t\t\t\tvar gun = Gun('https://gunjs.herokuapp.com/gun');\n\t\t\t\tgun.get('~@O8H2BJa4pNfecWamWN7efd888Pg1@hackernoon').once(function(data){\n\t\t\t\t\tconsole.log(1, data);\n\t\t\t\t\texpect(data).to.not.be.ok();\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tgun.get('~@O8H2BJa4pNfecWamWN7efd888Pg1@hackernoon').once(function(data){\n\t\t\t\t\t\t\tconsole.log(2, data);\n\t\t\t\t\t\t\texpect(data).to.not.be.ok();\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t});\n\t\t\t\t\t}, 3000);\n\t\t\t\t});\n\t\t\t});\n\t\t});*/\n\t\tit('Nested listener should be called', function(done){\n\t\t\t\n\t\t\tvar gun = Gun();\n\t\t\t/*\n\t\t\tvar app = gun.get('nl/app').get('bar');\n\n\t\t\tapp.on(function(d){\n\t\t\t\tconsole.log(\"!!\", d);\n\t\t\t})\n\n\t\t\tapp.put({wat: 1});\n\n\t\t\tconsole.debug.i=1;console.log(\"------------\");\n\t\t\tconsole.log(gun._.now);\n\t\t\tapp.put({a: {b:2}});\n\t\t\tconsole.log('_______________________');\n\t\t\treturn;*/\n\n\t\t\tvar app = gun.get('nl/app');\n\t\t\tvar node = app.get('watcher/1').put({\"stats\":{\"num\":3},\"name\":\"trex\"});\n\t\t\tvar C = 0;\n\n\t\t\tapp.get('watcher/1').get('stats').on(function (v, k) {\n\t\t\t\tif(++C === 1){\n\t\t\t\t\texpect(v.num).to.be(3);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(v.num).to.be(4);\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t\t//return;\n\n\t\t\tsetTimeout(function(){\n\t\t\t  \n\t\t\t  app.get('watcher/1').put({\"stats\":{\"num\":4},\"name\":\"trexxx\"});\n\t\t\t  \n\t\t\t},100);\n\t\t});\n\t\t//return;\n\n\t\tit.skip('do not refire', function(done){ // for Wasis @yokowasis ! Thanks for finding.\n\t\t\tvar gun = Gun();\n\n\t\t\tfor (i=0;i<=100;i++) {\n\t\t\t  gun.get(\"something\").get(\"level1\").put({\n\t\t\t    [i]: i\n\t\t\t  })\n\t\t\t}\n\n\t\t\tfor (i=0;i<=100;i++) {\n\t\t\t  gun.get(\"something\").get(\"level1\").get(\"level2\").put({\n\t\t\t    [i]: i\n\t\t\t  })\n\t\t\t}\n\n\t\t\tvar c = 0;\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get(\"something\").get(\"level1\").on(()=>{\n\t\t\t\t\tc++;\n\t\t\t\t});\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get(\"something\").get(\"level1\").once(function(x){\n\t\t\t\t\t\t\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\texpect(c).to.be(1);\n\t\t\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t\t\t},100);\n\t\t\t\t\t});\n\t\t\t\t},100);\n\t\t\t},100);\n\t\t});\n\t\t/*it.skip('Memory management', function(done){\n\t\t\tthis.timeout(9999999);\n\t\t\tvar gun = Gun(), c = 100000, big = \"big\";\n\t\t\twhile(--c){big += \"big\"}\n\t\t\tc = 0;\n\t\t\tsetInterval(function(){\n\t\t\t\tvar key = Gun.text.random(5);\n\t\t\t\tgun.get(key).put({data: big});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get(key).off();\n\t\t\t\t},10);\n\t\t\t\tif(typeof process === 'undefined'){ return }\n\t\t\t\tvar mem = process.memoryUsage();\n\t\t\t\tconsole.log(((mem.heapUsed / mem.heapTotal) * 100).toFixed(0) + '% memory');\n\t\t\t\tconsole.log(Object.keys(gun._.graph).length, 'item in memory graph:', Object.keys(gun._.graph));\n\t\t\t},25);\n\t\t});\n\n\t\tit('Custom extensions are chainable', function(done){\n\t\t\tGun.chain.filter = function(filter){\n\t\t\t  var chain = this.chain();\n\t\t\t  var context = this;\n\t\t\t  var _tags;\n\t\t\t  context.once(function(obj, key){\n\t\t\t    if(!obj.tags){\n\t\t\t      console.warn('Not tagged to anything!');\n\t\t\t      context._.valid = false;\n\t\t\t      chain._.on('in', {get: key, $: this});\n\t\t\t      return false;\n\t\t\t    } else { \n\t\t\t     _tags = Gun.obj.ify(obj.tags);\n\t\t\t      if(Array.isArray(filter)){\n\t\t\t        context._.valid = filter.every(function(f){ return ( _tags[f] && _tags[f]==1) });\n\t\t\t        if(context._.valid){\n\t\t\t          chain._.on('in', {get: key, put: obj, $: this});\n\t\t\t          return context;\n\t\t\t        } else {\n\t\t\t          console.log(\"that was wrong\");\n\t\t\t          chain._.on('in', {get: key, put: undefined, $: this});\n\t\t\t        }\n\t\t\t        return false;\n\t\t\t      } else {\n\t\t\t        console.warn('filter should be an Array');\n\t\t\t        return false;\n\t\t\t      }\n\t\t\t    }\n\t\t\t  });\n\t\t\t  return chain;\n\t\t\t}\n\n\t\t\tvar gun = Gun();\n\n\t\t\tvar fake1 = gun.get('fake1').put({name:'faker1',tags:JSON.stringify({a:1,b:0,c:1})});\n\t\t\tvar fake2 = gun.get('fake2').put({name:'faker2',tags:JSON.stringify({a:1,b:1,c:1})});\n\t\t\tvar list = gun.get('list');\n\t\t\tlist.set(fake1);\n\t\t\tlist.set(fake2);\n\n\t\t\tgun.get('fake1')//.map()\n\t\t\t      .filter(['a','b'])  // Gun.chain.filter = function(tags){ .... }\n\t\t\t      .get(function(no){console.log(\"NO!\", no)})\n\t\t\t      .once(function(yes){console.log(\"YES!\", yes)})\n\t\t}); */\n\n\t\tit('Check that events are called with multiple instances', function(done){\n\t\t\tvar gunA = Gun( { file : \"A.json\" } );\n\t\t\tvar gunB = Gun( { file : \"B.json\" });\n\t\t\tvar gunC = Gun( { file : \"C.json\" });\n\n\t\t\tvar check = {};\n\n\t\t\tgunA.get( \"some path A\" ).map(function(v,f){ check.A = v; /*console.log( \"event on A: \", f, v )*/ } );\n\t\t\tgunB.get( \"some path B\" ).map(function(v,f){ check.B = v; /*console.log( \"event on B: \", f, v )*/ } );\n\t\t\tgunC.get( \"some path C\" ).map(function(v,f){ check.C = v; /*console.log( \"event on C: \", f, v )*/ } );\n\n\t\t\tgunA.get( \"some path A\" ).put( { simple:\"message\" } );\n\t\t\tgunB.get( \"some path B\" ).put( { simple:\"message\" } );\n\t\t\tgunC.get( \"some path C\" ).put( { simple:\"message\" } );\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(check.A).to.be('message');\n\t\t\t\texpect(check.B).to.be('message');\n\t\t\t\texpect(check.C).to.be('message');\n\t\t\t\tnopasstun(0, gunA);\n\t\t\t\tnopasstun(0, gunB);\n\t\t\t\tnopasstun(done, gunC);\n\t\t\t}, 100);\n\t\t});\t\t\n\n\t\tit('ack aggregation bypass', function(done){\n\t\t\tconsole.log(\"WORKS IN BROWSER, NOT SURE WHY NODEJS CONFUSED, CHECK LATER\");\n\t\t\tdone();return;\n\t\t\tvar alice = Gun({localStorage: false, file: false, rad: false, radisk: false});\n\t\t\tvar bob = Gun({localStorage: false, file: false, rad: false, radisk: false});\n\t\t\tvar carl = Gun({localStorage: false, file: false, rad: false, radisk: false});\n\n\t\t\tvar adam = alice.back('opt.mesh');\n\t\t\tvar asay = adam.say;\n\n\t\t\tvar bdam = bob.back('opt.mesh');\n\t\t\tvar bsay = bdam.say;\n\n\t\t\tvar cdam = carl.back('opt.mesh');\n\t\t\tvar csay = cdam.say;\n\n\t\t\t//console.only.i = 1;\n\t\t\tadam.say = function(raw, peer){\n\t\t\t\tconsole.only(2, 'adam says:', raw);\n\t\t\t\tconsole.only(1, '...');\n\t\t\t\tbdam.hear((raw.length && raw) || JSON.stringify(raw), {});\n\t\t\t\tasay(raw, peer);\n\t\t\t}\n\t\t\tbdam.say = function(raw, peer){\n\t\t\t\tconsole.only(7, \"bob the relay is like YO\", raw);\n\t\t\t\tadam.hear((raw.length && raw) || JSON.stringify(raw), {});\n\t\t\t\tcdam.hear((raw.length && raw) || JSON.stringify(raw), {});\n\t\t\t\tbsay(raw, peer);\n\t\t\t}\n\t\t\tcdam.say = function(raw, peer){\n\t\t\t\tconsole.only(4, \"carl speaks out:\", raw);\n\t\t\t\tconsole.only(3, \"...\");\n\t\t\t\tbdam.hear((raw.length && raw) || JSON.stringify(raw), {});\n\t\t\t\tcsay(raw, peer);\n\t\t\t}\n\n\t\t\tcarl.on('put', async function(msg){\n\t\t\t\tthis.to.next(msg);\n\n\t\t\t\tvar tmp = msg.put;\n\t\t\t\t\n\t\t\t\t//if(Math.random() > 0.5){ return; }\n\t\t\t\t//console.log(msg.put);\n\n\t\t\t\t//localStorage[tmp['#']+tmp['.']] = tmp[':'];\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tcarl.on('out', {'@': msg['#']+'', ok: {BANANA: 9}});\n\t\t\t\t}, 10);\n\t\t\t});\n\n\t\t\talice.on('get', function(msg){ setTimeout(function(){ Gun.on.get.ack(msg); },9) })\n\n\n\t\t\tsetTimeout(async function(){\n\t\t\t\tvar pair = await SEA.pair();\n\t\t\t\tvar user = alice.user();\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tvar c = 0;\n\t\t\t\t\t//alice.on('auth', function(){\n\t\t\t\t\talice.get('test').put({a: 1, b: 2, c: 3}, function(ack){\n\t\t\t\t\t\t//console.log(\"my data got saved?\", ack);\n\t\t\t\t\t\t\n\t\t\t\t\t\tif(ack.ok.BANANA && ++c === c){\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, {acks: 99});\n\t\t\t\t\t//}); user.auth(pair);\n\t\t\t\t},10);\n\t\t\t}, 100);\n\t\t});\n\n\t\t/*it.only('Make sure circular contexts are not copied', function(done){\n\t\t\t//let's define an appropriate deep default database...\n\t\t\tvar dfltSansUsers = { 1: { name : \"org1\", sites : { 1: {name : \"site1\"} } } };\n\n\t\t\tvar alice =  {name: \"alice\" }\n\n\t\t\tvar gun = Gun();\n\n\t\t\tvar root = gun.get( \"root\" );\n\t\t\troot.put( dfltSansUsers );\n\n\t\t\tvar alice = gun.get( \"alice\" ).put( { name: \"alice\" } );\n\t\t\tconsole.log( \"Failed after this\" );\n\t\t\troot.get(\"1\").get(\"sites\").get(\"1\").get(\"users\" ).put( { 1: alice } );\n\t\t\tconsole.log( \"Failed before this\" );\n\t\t});*/\n\n\t\tit('get any any none', function(done){\n\t\t\tgun.get('full/none').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"*****\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t});\n\t\t\tgun.get('full/none').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"*****2\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun);\n\t\t\t});\n\t\t});\n\n\t\tit('get any any none later', function(done){\n\t\t\tgun.get('full/none/later').get(function(at, ev){\n\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t//console.log(\"*****\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('full/none/later').get(function(at, ev){\n\t\t\t\t\tvar err = at.err, data = at.put, field = at.get;\n\t\t\t\t\t//console.log(\"*****2\", data);\n\t\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\t\tnopasstun(done, gun);\n\t\t\t\t});\n\t\t\t},400);\n\t\t});\n\n\t\tit('get get any parallel', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\" } }, 'parallel/get/get', function(){\n\t\t\t\tgun.get('parallel/get/get').get('bob').get(function(data){ data = data.put;\n\t\t\t\t//console.log(\"***** 1\", data);\n\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t});\n\t\t\tgun.get('parallel/get/get').get('bob').get(function(data){ data = data.put;\n\t\t\t\t//console.log(\"***** 2\", data);\n\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t\tnopasstun(done, gun); \n\t\t\t});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('once on link to nothing @mimiza', function(done){\n\n\t\t\tgun.get('oltn').put({\"#\": \"this-does-not-exist\"})\n\n\t\t\tgun.get('oltn').once(response => {\n\t\t\t\t//console.log('did we call?', response) ;\n\t\t\t\texpect(response).to.not.be.ok();\n\t\t\t\tnopasstun(done, gun);\n\t\t\t})\n\t\t});\n\n\t\tit('once on link to nothing deep @mimiza', function(done){\n\n\t\t\tgun.get('oltnd').get('deep').put({\"#\": \"this-does-not-exist\"})\n\n\t\t\tgun.get('oltnd').get('deep').once(response => {\n\t\t\t\t//console.log('did we call?', response) ;\n\t\t\t\texpect(response).to.not.be.ok();\n\t\t\t\tnopasstun(done, gun);\n\t\t\t})\n\t\t});\n\n\t\treturn;\n\n\t\tit('get get any parallel later', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\" } }, 'parallel/get/get/later', function(){\n\t\t\tgun.get('parallel/get/get/later').path('bob').any(function(err, data, field, at, ev){\n\t\t\t\t//console.log(\"***** 1\", data);\n\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('parallel/get/get/later').path('bob').any(function(err, data, field, at, ev){\n\t\t\t\t\t//console.log(\"***** 2\", data);\n\t\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('get get any none', function(done){\n\t\t\tGun.statedisk({ alice: { age: 31, name: \"alice\" } }, 'get/get/none', function(){\n\t\t\tvar c = 0, s = 0;\n\t\t\tgun.get('get/get/none').path('bob').any(function(err, data, field, at, ev){\n\t\t\t\t//console.log(\"***** 1\", data);\n\t\t\t\tc++;\n\t\t\t\ts = 0;\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t});\n\t\t\ts = 1;\n\t\t\tgun.get('get/get/none').path('bob').any(function(err, data, field, at, ev){\n\t\t\t\t//console.log(\"***** 2\", data);\n\t\t\t\tc++;\n\t\t\t\t//if(s){ c++ } // TODO: Talk to Jesse about this.\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\tif(2 === c){ // We want 2 replies for each `any`, once from LS replying with the soul (but not the field), and once from WSP replying that the soul couldn't be found.\n\t\t\t\t\t// Wrong! I think we've changed this, such that lS handles it alone and not WSP.\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('get get any none later', function(done){\n\t\t\tGun.statedisk({ alice: { age: 31, name: \"alice\" } }, 'get/get/none/later', function(){\n\t\t\tvar c = 0;\n\t\t\tgun.get('get/get/none/later').path('bob').any(function(err, data, field, at, ev){\n\t\t\t\t//console.log(\"***** 1\", data);\n\t\t\t\tc++;\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('get/get/none/later').path('bob').any(function(err, data, field, at, ev){\n\t\t\t\t\t//console.log(\"***** 2\", data);\n\t\t\t\t\tc++;\n\t\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\t\t//if(3 === c){ // Because we already have active listeners cached waiting for data to pipe in, BUT we have already received multiple responses that the data isn't found, the \"not found\" is cached and so we get an immediate response just from cache. If later data does get piped in, this will still get called.\n\t\t\t\t\t\tdone();\n\t\t\t\t\t//}\n\t\t\t\t});\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('get get primitive get any', function(done){\n\t\t\tGun.statedisk({ bob: \"is awesome\" }, 'get/get/prim', function(){\n\t\t\tgun.get('get/get/prim').path('bob').path('age').any(function(err, data, field, at, ev){\n\t\t\t\t//console.log(\"***** 1\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t});\n\t\t\tgun.get('get/get/prim').path('bob').path('age').any(function(err, data, field, at, ev){\n\t\t\t\t//console.log(\"***** 2\", data);\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\tdone();\n\t\t\t});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('get put any', function(done){\n\t\t\tGun.statedisk({ here: \"we go\" }, 'get/put/any', function(){\n\t\t\t//console.debug.i=1;console.log(\"---------------\");\n\t\t\tgun.get('get/put/any')\n\t\t\t\t.put({})\n\t\t\t\t.any(function(err, data, field, at, ev){\n\t\t\t\t\t//console.log(\"***** 1\", data);\n\t\t\t\t\tdone();\n\t\t\t});\n\t\t\t}, 1000);\n\t\t});\n\t\treturn;\n\t\tit('get any, get put any', function(done){\n\t\t\tGun.statedisk({ here: \"we go\" }, 'get/any/get/put/any', function(){\n\t\t\tgun.get('get/any/get/put/any')\n\t\t\t\t.any(function(err, data, field, at, ev){\n\t\t\t\t\tif(done.first){ return } // it is okay for `any` to get called multiple times.\n\t\t\t\t\t//console.log(\"***** 1\", data);\n\t\t\t\t\texpect(data.here).to.be('we go');\n\t\t\t\t\tif(done.first){\n\t\t\t\t\t\texpect(data.yes).to.be('please');\n\t\t\t\t\t}\n\t\t\t\t\tdone.first=1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('get/any/get/put/any')\n\t\t\t\t\t.put({yes: 'please'})\n\t\t\t\t\t.any(function(err, data, field, at, ev){\n\t\t\t\t\t\tif(done.second){ return } // it is okay for `any` to get called multiple times.\n\t\t\t\t\t\t//console.log(\"***** 2\", data);\n\t\t\t\t\t\texpect(data.here).to.be('we go');\n\t\t\t\t\t\texpect(data.yes).to.be('please');\n\t\t\t\t\t\tdone();\n\t\t\t\t\t\tdone.second = 1;\n\t\t\t\t});\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('mutate pointer to primitive deep on', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\", pet: { name: \"Fluffy\", species: \"kitty\" } } }, 'change/pointer', function(){\n\t\t\tgun.get('change/pointer').path('bob').path('pet').any(function(err, data, f, at, ev){\n\t\t\t\t//console.log(\"***\", data);return setTimeout(function(){asdf},500);\n\t\t\t\tif(done.c){\n\t\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(data.name).to.be('Fluffy');\n\t\t\t\texpect(data.species).to.be('kitty');\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('change/pointer').put({\n\t\t\t\t\tbob: null\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun.get('change/pointer').put({\n\t\t\t\t\t\tbob: \"hello!\"\n\t\t\t\t\t});\n\t\t\t\t},400);\n\t\t\t},400);\n\t\t\tgun.get('change/pointer').any(function(err, data){\n\t\t\t\t//console.log(\"****************\", data);\n\t\t\t\tif(2 <= done.e && data.bob){\n\t\t\t\t\texpect(data.bob).to.be('hello!');\n\t\t\t\t\tdone();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(1 <= done.e){\n\t\t\t\t\texpect(data.bob).to.be(null);\n\t\t\t\t\tdone.e = 2;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(Gun.val.link.is(data.bob)).to.be.ok();\n\t\t\t\tdone.e = 1;\n\t\t\t});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('get only soul', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\", pet: { name: \"Fluffy\", species: \"kitty\" } } }, 'only/soul', function(){\n\t\t\tgun.get('only/soul')/*.path('bob')*/.any(function(err, data){\n\t\t\t\texpect(Gun.obj.empty(data, '_')).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, {'.': null});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('get path only soul', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\", pet: { name: \"Fluffy\", species: \"kitty\" } } }, 'only/p/soul', function(){\n\t\t\tgun.get('only/p/soul').path('bob').any(function(err, data){\n\t\t\t\t//console.log(\"*********\", err, data);\n\t\t\t\texpect(Gun.val.link.is(data)).to.be.ok();\n\t\t\t\t//expect(Gun.obj.empty(data, '_')).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, {'.': null});\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('mutate pointer to self', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\", pet: { name: \"Fluffy\", species: \"kitty\" } } }, 'change/pointer/point', function(){\n\t\t\tgun.get('change/pointer/point').path('bob').any(function(err, data){\n\t\t\t\tif(done.c){\n\t\t\t\t\texpect(data.age).to.be(30);\n\t\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\t\texpect(Gun.val.link.is(data.pet)).to.be.ok();\n\t\t\t\t\texpect(done.c).to.be(1);\n\t\t\t\t\tdone();\n\t\t\t\t\tdone.c = 2;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\texpect(Gun.val.link.is(data.pet)).to.be.ok();\n\t\t\t\tdone.c=1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('change/pointer/point').path('bob').put({age: 30});\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\t\tit('mutate pointer to self deep', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\", pet: { name: \"Fluffy\", species: \"kitty\" } } }, 'change/pointer/point/deep', function(){\n\t\t\tgun.get('change/pointer/point/deep').path('bob').any(function(err, data){\n\t\t\t\t//console.log(\"***\", data);\n\t\t\t\tif(done.c){\n\t\t\t\t\texpect(data.age).to.be(30);\n\t\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\t\texpect(Gun.val.link.is(data.pet)).to.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\texpect(Gun.val.link.is(data.pet)).to.be.ok();\n\t\t\t\tdone.c=1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('change/pointer/point/deep').path('bob').path('age').put(30);\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('mutate pointer to primitive after any', function(done){\n\t\t\tGun.statedisk({ bob: {_: {'#': 'asdffdsa'}, age: 29, name: \"Bob!\", pet: { name: \"Fluffy\", species: \"kitty\" } } }, 'change/pointer/to/prime', function(){\n\t\t\tvar bob = gun.get('asdffdsa').any(function(err, data){\n\t\t\t\t//console.log(\"***\", data);\n\t\t\t});\n\t\t\tgun.get('change/pointer/to/prime').path('bob').any(function(err, data, f, at){\n\t\t\t\t//console.log(\"***********\", data);\n\t\t\t\tif(!Gun.obj.is(data)){\n\t\t\t\t\texpect(data).to.be(3);\n\t\t\t\t\tif(done.c){return}\n\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\texpect(Gun.val.link.is(data.pet)).to.be.ok();\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('change/pointer/to/prime').path('bob').put(3);\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tbob.put({age: 30});\n\t\t\t\t},100);\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('mutate pointer to primitive after any deep', function(done){\n\t\t\tGun.statedisk({ bob: { age: 29, name: \"Bob!\", pet: {_: {'#': 'sadffads'}, name: \"Fluffy\", species: \"kitty\" } } }, 'change/pointer/to/prime/deep', function(){\n\t\t\tvar cat = gun.get('sadffads').any(function(err, data){\n\t\t\t\t//console.log(\"***\", data);\n\t\t\t});\n\t\t\tgun.get('change/pointer/to/prime/deep').path('bob').path('pet').any(function(err, data){\n\t\t\t\t//console.log(\"*********\", data);\n\t\t\t\tif(!Gun.obj.is(data)){\n\t\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\t\tif(done.c){return}\n\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(data.species).to.be('kitty');\n\t\t\t\texpect(data.name).to.be('Fluffy');\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('change/pointer/to/prime/deep').path('bob').put(3);\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tcat.put({laser_eyes: true});\n\t\t\t\t},100);\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\t\treturn;\n\t\tit.only('mutate pointer to another pointer after any', function(done){\n\t\t\tGun.statedisk({ bob: {_: {'#': 'dafssfad'}, age: 29, name: \"Bob!\", pet: { name: \"Fluffy\", species: \"kitty\" } } }, 'change/pointer/to/pointer', function(){\n\t\t\tvar bob = gun.get('dafssfad').any(function(err, data){\n\t\t\t\tconsole.log(\"***\", data);\n\t\t\t});\n\t\t\tconsole.debug.i=1;console.log(\"--------------------\");\n\t\t\tgun.get('change/pointer/to/pointer').path('bob').any(function(err, data){\n\t\t\t\tconsole.log(\"*********\", data);return;\n\t\t\t\tif(done.soul && done.soul !== Gun.node.soul(data)){\n\t\t\t\t\texpect(Gun.node.soul(data)).to.be('fsdaadsf');\n\t\t\t\t\texpect(data.cat).to.be(true);\n\t\t\t\t\texpect(data.age).to.not.be.ok();\n\t\t\t\t\texpect(data.name).to.not.be.ok();\n\t\t\t\t\texpect(data.pet).to.not.be.ok();\n\t\t\t\t\tif(done.c){return}\n\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(done.soul = Gun.node.soul(data)).to.be('dafssfad');\n\t\t\t\texpect(data.age).to.be(29);\n\t\t\t\texpect(data.name).to.be('Bob!');\n\t\t\t\texpect(Gun.val.link.is(data.pet)).to.be.ok();\n\t\t\t});\n\t\t\treturn;\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.get('change/pointer/to/pointer').path('bob').put(Gun.node.ify({cat: true}, 'fsdaadsf'));\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tbob.put({age: 30});\n\t\t\t\t},100);\n\t\t\t},400);\n\t\t\t}, 1000);\n\t\t});\n\t\treturn;\n\t\tit.only('deep freeze put', function(done){\n\t\t\tgun.get('deep/freeze').put({\n\t\t\t\tbob: {\n\t\t\t\t\tage: 29,\n\t\t\t\t\tname: \"Bob!\",\n\t\t\t\t\tpet: {\n\t\t\t\t\t\tname: \"Fluffy\",\n\t\t\t\t\t\tspecies: \"kitty\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tgun.get('deep/freeze').path('bob').path('pet').any(function(err, data){\n\t\t\t\tconsole.log(\"********************\", data);\n\t\t\t\texpect(data.name).to.be('Fluffy');\n\t\t\t\texpect(data.species).to.be('kitty');\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tdone();\n\t\t\t\t},100);\n\t\t\t});\n\t\t});\n\n\t\tit('deep freezing put', function(done){\n\t\t\tgun.get('deep/freeze/ing').put({\n\t\t\t\tbob: {\n\t\t\t\t\tage: 29,\n\t\t\t\t\tname: \"Bob!\",\n\t\t\t\t\tpet: {\n\t\t\t\t\t\tname: \"Fluffy\",\n\t\t\t\t\t\tspecies: \"kitty\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tgun.get('deep/freeze/ing').path('bob').path('pet').any(function(err, data){\n\t\t\t\t//console.log(\"******** bob's pet\", data);\n\t\t\t\tif(done.c){\n\t\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(data.name).to.be('Fluffy');\n\t\t\t\texpect(data.species).to.be('kitty');\n\t\t\t\tdone.c=1;\n\t\t\t});\n\t\t\tgun.get('deep/freeze/ing').put({bob: 'lol'});\n\t\t\tgun.get('deep/freeze/ing').path('bob').path('pet').any(function(err, data){\n\t\t\t\t//console.log(\"********* 2 bob's pet\", data);return;\n\t\t\t\texpect(data).to.be(undefined);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\t\treturn;\n\t\tit('put put put put', function(){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('put/put/put/put');\n\t\t\tget.put({});\n\t\t\tget.put({\n\t\t\t\tall: {\n\t\t\t\t\tthe: {\n\t\t\t\t\t\tway: 'down'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tget.put({foo: 'bar'});\n\t\t\tget.any(function(err,data){\n\t\t\t\t//console.log(\"data\", data);\n\t\t\t\texpect(Gun.val.link.is(data.all)).to.be.ok();\n\t\t\t\texpect(data.foo).to.be('bar');\n\t\t\t});\n\t\t});\n\n\t\tit('perf put', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar hey = gun.get('heylo');\n\t\t\they.put({hello: \"world\"});\n\t\t\they.any(function(err, data){\n\t\t\t\texpect(data.hello).to.be('world');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put', function(done){\n\t\t\tgun.put(\"hello\", function(err, ok){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put NaN', function(done){\n\t\t\tgun.put({num: NaN}, function(err, ok){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put date', function(done){\n\t\t\tgun.put({date: new Date()}, function(err, ok){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put regex', function(done){\n\t\t\tgun.put({reg: /regex/i}, function(err, ok){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put node', function(done){\n\t\t\tgun.put({hello: \"world\"}, function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put node then value', function(done){\n\t\t\tvar ref = gun.put({hello: \"world\"});\n\t\t\t//console.log(\"---------\");\n\t\t\tref.put('hello', function(err, ok){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put node then put', function(done){\n\t\t\tgun.put({hello: \"world\"}).put({goodbye: \"world\"}, function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put node with soul get soul', function(done){\n\t\t\tgun.put({_: {'#': 'foo'}, hello: 'world'})\n\t\t\t\t.get({'#': 'foo'}, function(err, node){\n\t\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\t\texpect(Gun.node.soul(node)).to.be('foo');\n\t\t\t\t\texpect(node.hello).to.be('world');\n\t\t\t\t\tif(done.c){ return }\n\t\t\t\t\tdone(); done.c = 1;\n\t\t\t})\n\t\t});\n\n\t\tit('put node with soul get soul tweak', function(done){\n\t\t\tGun().put({_: {'#': 'foo'}, hello: 'world'});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar gun = Gun();\n\t\t\t\tgun.put({_: {'#': 'foo'}, boo: 'bear'})\n\t\t\t\t\t.get({'#': 'foo'}, function(err, node){\n\t\t\t\t\t\tif(done.c >= 1){ return }\n\t\t\t\t\t\t//console.log(\"**********\", err, node);\n\t\t\t\t\t\texpect(Gun.node.soul(node)).to.be('foo');\n\t\t\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\t\t\texpect(node.boo).to.be('bear');\n\t\t\t\t\t\t//if(!done.c){ return done.c = 1 } done.c = 2;\n\t\t\t\t\t\t//expect(node.hello).to.be('world');\n\t\t\t\t\t\tdone(); done.c = 2;\n\t\t\t\t})\n\t\t\t},100);\n\t\t});\n\n\t\tit('put node key get', function(done){\n\t\t\tgun.put({hello: \"key\"}).key('yes/key', function(err, ok){\n\t\t\t\t//console.log(\"***\", err, ok);\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tdone.w = 1; if(done.c){ return } if(done.r){ done(); done.c = 1 };\n\t\t\t}).get('yes/key', function(err, node){\n\t\t\t\t//console.log(\"*******\", err, node);\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(Gun.node.soul(node)).to.be('yes/key');\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\tdone.r = 1; if(done.c){ return } if(done.w){ done(); done.c = 1 };\n\t\t\t});\n\t\t});\n\n\t\tit('put node key gun get', function(done){\n\t\t\tgun.put({hello: \"a key\"}).key('yes/a/key', function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t});\n\t\t\tgun.get('yes/a/key', function(err, node){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(node.hello).to.be('a key');\n\t\t\t\tif(done.c){ return }\n\t\t\t\tdone(); done.c = 1;\n\t\t\t});\n\t\t});\n\n\t\tit('gun key', function(){ // Revisit this behavior?\n\t\t\ttry{ gun.key('fail/key') }\n\t\t\tcatch(err){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t}\n\t\t});\n\n\t\tit('get key no override', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({cream: 'pie'}).key('cream/pie').get('cream/pie', function(err, node){\n\t\t\t\texpect(Gun.node.soul(node)).to.be('cream/pie');\n\t\t\t\tif(done.c){ return }\n\t\t\t\tif(node.cream && node.pie){\n\t\t\t\t\texpect(node.cream).to.be('pie');\n\t\t\t\t\texpect(node.pie).to.be('cream');\n\t\t\t\t\tdone(); done.c = 1;\n\t\t\t\t} return;\n\t\t\t\tif(done.c >= 2){ return }\n\t\t\t\tif(done.c){ done(); done.c = 2; return; } done.c = 1;\n\t\t\t});\n\t\t\tgun.get('cream/pie').key('pie/cream');\n\t\t\tgun.get('pie/cream').put({pie: 'cream'});\n\t\t});\n\n\t\tit('get key', function(done){\n\t\t\tgun.get('yes/key', function(err, node){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t}).key('hello/key', function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tdone.key = true;\n\t\t\t\tif(!done.c && done.yes){ done();done.c=1; }\n\t\t\t}).key('yes/hello', function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tdone.yes = true;\n\t\t\t\tif(!done.c && done.key){ done();done.c=1; }\n\t\t\t});\n\t\t});\n\n\t\tit('get key null', function(done){\n\t\t\tgun.get('yes/key').key('', function(err, ok){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('key node has no key relations', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({hello: 'world'}).key('hello/earth');\n\t\t\tgun.put({continent: 'africa'}).key('hello/earth');\n\t\t\tgun.put({place: 'asia'}).key('hello/earth');\n\t\t\tgun.put({north: 'america'}).key('hello/galaxy');\n\t\t\tgun.put({south: 'pole'}).key('hello/galaxy');\n\t\t\tgun.get('hello/earth').key('hello/galaxy', function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t});\n\t\t\tvar node = gun.back(-1)._.graph['hello/earth'] || {}; // TODO: IS THIS CORRECT?\n\t\t\texpect(node['hello/galaxy']).to.not.be.ok();\n\t\t\tgun.get('hello/earth', function(err, pseudo){\n\t\t\t\texpect(pseudo.hello).to.be('world');\n\t\t\t\texpect(pseudo.continent).to.be('africa');\n\t\t\t\texpect(pseudo.place).to.be('asia');\n\t\t\t\texpect(pseudo.north).to.not.be.ok();\n\t\t\t});\n\t\t\tvar galaxy = gun.back(-1)._.graph['hello/galaxy'] || {}; // TODO: IS THIS CORRECT?\n\t\t\texpect(galaxy['hello/earth']).to.not.be.ok();\n\t\t\tgun.get('hello/galaxy', function(err, pseudo){\n\t\t\t\tif(done.c || !pseudo.hello || !pseudo.south || !pseudo.place || !pseudo.continent || !pseudo.north){ return }\n\t\t\t\texpect(pseudo.hello).to.be('world');\n\t\t\t\texpect(pseudo.south).to.be('pole');\n\t\t\t\texpect(pseudo.place).to.be('asia');\n\t\t\t\texpect(pseudo.continent).to.be('africa');\n\t\t\t\texpect(pseudo.north).to.be('america');\n\t\t\t\texpect(pseudo['hello/earth']).to.not.be.ok();\n\t\t\t\texpect(pseudo['#hello/earth#']).to.not.be.ok();\n\t\t\t\tdone(); done.c = 1;\n\t\t\t});\n\t\t});\n\n\t\tfunction soulnode(gun, kn, r){ // TODO: WARNING! Key implementation has changed significantly. Tests are somewhat hardcoded, sad day.\n\t\t\tr = r || [];\n\t\t\tkn = Gun.obj.copy(kn);\n\t\t\tdelete kn._;\n\t\t\texpect(Gun.obj.empty(kn, '##')).to.be.ok();\n\t\t\tkn = gun.back(-1)._.graph[Gun.val.link.is(kn['##'])];\n\t\t\tGun.node.is(kn, function(node, s){\n\t\t\t\tvar n = gun.back(-1)._.graph[s];\n\t\t\t\tif(Gun.obj.has(n, '##')){\n\t\t\t\t\tsoulnode(gun, n, r);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tr.push(s);\n\t\t\t});\n\t\t\treturn r;\n\t\t}\n\n\t\tit('get node put node merge', function(done){\n\t\t\tgun.get('hello/key', function(err, node){\n\t\t\t\tif(done.soul){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\tdone.soul = Gun.node.soul(node);\n\t\t\t}).put({hi: 'you'}, function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tvar keynode = gun.back(-1)._.graph[done.soul], soul;\n\t\t\t\texpect(keynode.hi).to.not.be.ok();\n\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\texpect(c.length).to.be(1);\n\t\t\t\tvar node = gun.back(-1)._.graph[soul];\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\texpect(node.hi).to.be('you');\n\t\t\t}).on(function(node){\n\t\t\t\tif(done.c){ return }\n\t\t\t\t//expect(done.soul).to.be(Gun.node.soul(node)); // TODO: DISCUSSION! This has changed?\n\t\t\t\texpect(node.hi).to.be('you');\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\tdone(); done.c = 1;\n\t\t\t});\n\t\t});\n\n\t\tit('get null put node never', function(done){ // TODO: GET returns nothing, and then doing a PUT?\n\t\t\tgun.get(null, function(err, ok){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone.err = true;\n\t\t\t}).put({hi: 'you'}, function(err, ok){\n\t\t\t\tdone.flag = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.err).to.be.ok();\n\t\t\t\texpect(done.flag).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 500);\n\t\t});\n\n\t\tit('get key no data put', function(done){\n\t\t\tvar gun = Gun({init: true});\n\t\t\tgun.get('this/key/definitely/does/not/exist', function(err, data){\n\t\t\t\tdone.gcb = true;\n\t\t\t\tdone.err = err;\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(data).to.not.be.ok();\n\t\t\t}).put({testing: 'stuff'}, function(err, ok){\n\t\t\t\tdone.flag = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.gcb).to.be.ok();\n\t\t\t\texpect(done.err).to.not.be.ok();\n\t\t\t\texpect(done.flag).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 500);\n\t\t});\n\n\t\tit('get node put node merge conflict', function(done){\n\t\t\tgun.get('hello/key', function(err, node){\n\t\t\t\tif(done.soul){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\texpect(node.hi).to.be('you');\n\t\t\t\tdone.soul = Gun.node.soul(node);\n\t\t\t}).put({hi: 'overwritten'}, function(err, ok){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tvar keynode = gun.back(-1)._.graph[done.soul], soul;\n\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\texpect(c.length).to.be(1);\n\t\t\t\tvar node = gun.back(-1)._.graph[soul];\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\texpect(node.hi).to.be('overwritten');\n\t\t\t\tdone.w = 1; if(done.r){ done(); done.c = 1 };\n\t\t\t}).on(function(node){\n\t\t\t\tif(done.c){ return }\n\t\t\t\t//expect(done.soul).to.be(Gun.node.soul(node)); // since put has changed chains, do we keep the pseudomerge key context?\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\texpect(node.hi).to.be('overwritten');\n\t\t\t\tdone.r = 1; if(done.w){ done(); done.c = 1 };\n\t\t\t});\n\t\t});\n\n\t\tit('get key path put', function(done){\n\t\t\tvar gun = Gun().put({foo:'lol', extra: 'yes'}).key('key/path/put');\n\t\t\tvar data = gun.get('key/path/put');\n\t\t\tdata.path('foo').put('epic');\n\t\t\tdata.once(function(val, field){\n\t\t\t\texpect(val.foo).to.be('epic');\n\t\t\t\texpect(Gun.node.soul(val)).to.be('key/path/put');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put node path', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({hello: 'world'}).path('hello', function(err, val, field){\n\t\t\t\tif(done.end){ return } // it is okay for path's callback to be called multiple times.\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(field).to.be('hello');\n\t\t\t\texpect(val).to.be('world');\n\t\t\t\tdone(); done.end = true;\n\t\t\t});\n\t\t});\n\n\t\tit('put node path path', function(done){\n\t\t\tvar gun = Gun();\n\t\t\t//console.debug.i=1;console.log(\"-----------------\");\n\t\t\tvar g = gun.put({hello: {little: 'world'}}).path('hello').path('little', function(err, val, field, cat){\n\t\t\t\tif(done.end){ return } // it is okay for path's callback to be called multiple times.\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(field).to.be('little');\n\t\t\t\texpect(val).to.be('world');\n\t\t\t\tdone(); done.end = true;\n\t\t\t});\n\t\t});\n\n\t\tit('put node path rel', function(done){\n\t\t\tgun.put({foo: {bar: 'lol'}}).path('foo', function(err, val, field){\n\t\t\t\t//console.log(\"*****\", err, val, field);\n\t\t\t\tif(done.end){ return } // it is okay for path's callback to be called multiple times.\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(field).to.be('foo');\n\t\t\t\texpect(val.bar).to.be('lol');\n\t\t\t\tdone(); done.end = true;\n\t\t\t});\n\t\t});\n\n\t\tit('get node path', function(done){\n\t\t\tgun.get('hello/key').path('hi', function(err, val, field){\n\t\t\t\tif(done.end){ return } // it is okay for path's callback to be called multiple times.\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(field).to.be('hi');\n\t\t\t\texpect(val).to.be('overwritten');\n\t\t\t\tdone(); done.end = true;\n\t\t\t});\n\t\t});\n\n\t\tit('put node get field', function(done){ // future feature.\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({_:{'#': 'soul/field'}, hi: 'lol', foo: 'bar'});//.key('key/field');\n\t\t\tgun.get({'#': 'soul/field', '.': 'hi'}, function(err, val){\n\t\t\t\t//expect(val.hi).to.be('lol'); // TODO: REVISE API?\n\t\t\t\texpect(val).to.be('lol');\n\t\t\t\t//expect(Gun.obj.has(val,'foo')).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t})\n\t\t});\n\n\t\tit('get node path put value', function(done){\n\t\t\tgun.get('hello/key', function(err, node){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tif(done.soul){ return }\n\t\t\t\texpect(node.hi).to.be('overwritten');\n\t\t\t\tdone.soul = Gun.node.soul(node);\n\t\t\t}).path('hi').put('again', function(err, ok){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tvar keynode = gun.back(-1)._.graph[done.soul], soul;\n\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\texpect(c.length).to.be(1);\n\t\t\t\tvar node = gun.back(-1)._.graph[done.sub = soul];\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\texpect(node.hi).to.be('again');\n\t\t\t\tdone.w = 1; if(done.r){ done(); done.c = 1 };\n\t\t\t}).on(function(val, field){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(val).to.be('again');\n\t\t\t\texpect(field).to.be('hi');\n\t\t\t\tdone.r = 1; if(done.w){ done(); done.c = 1 };\n\t\t\t});\n\t\t});\n\n\t\tit('get node path put object', function(done){\n\t\t\tvar foo = gun.get('hello/key', function(err, node){\n\t\t\t\tif(done.soul){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(node.hi).to.be('again');\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\tdone.soul = Gun.node.soul(node);\n\t\t\t}).path('hi').put({yay: \"value\"}, function(err, ok){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tvar keynode = gun.back(-1)._.graph[done.soul], soul;\n\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\texpect(c.length).to.be(1);\n\t\t\t\tvar root = gun.back(-1)._.graph[soul];\n\t\t\t\texpect(root.hello).to.be('key');\n\t\t\t\texpect(root.yay).to.not.be.ok();\n\t\t\t\texpect(Gun.val.link.is(root.hi)).to.be.ok();\n\t\t\t\texpect(Gun.val.link.is(root.hi)).to.not.be(soul);\n\t\t\t\tvar node = gun.back(-1)._.graph[Gun.val.link.is(root.hi)];\n\t\t\t\texpect(node.yay).to.be('value');\n\t\t\t\tif(done.sub){ expect(done.sub).to.be(Gun.val.link.is(root.hi)) }\n\t\t\t\telse { done.sub = Gun.val.link.is(root.hi) }\n\t\t\t\tdone.w = 1; if(done.r){ done(); done.c = 1 };\n\t\t\t}).on(function(node, field){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(field).to.be('hi');\n\t\t\t\texpect(node.yay).to.be('value');\n\t\t\t\tif(done.sub){ expect(done.sub).to.be(Gun.node.soul(node)) }\n\t\t\t\telse { done.sub = Gun.node.soul(node) }\n\t\t\t\tdone.r = 1; if(done.w){ done(); done.c = 1 };\n\t\t\t});\n\t\t});\n\n\t\tit('get path wire', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('shallow/path');\n\t\t\tvar path = get.path('one');\n\t\t\tvar put = path.put('good');\n\t\t\tput.once(function(val, field){\n\t\t\t\texpect(val).to.be('good');\n\t\t\t\texpect(field).to.be('one');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get path wire shallow', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('slightly/shallow/path');\n\t\t\tvar path = get.path('one');\n\t\t\tvar put = path.put({you: 'are', here: 1});\n\t\t\tput.once(function(val, field){\n\t\t\t\t//console.log('***********', field, val);\n\t\t\t\texpect(val.you).to.be('are');\n\t\t\t\texpect(val.here).to.be(1);\n\t\t\t\texpect(field).to.be('one');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get put, Gun get path', function(done){ // For testing lazy eval that it works on cb style.\n\t\t\tvar gun = Gun();\n\t\t\tgun.get('test').put({you: {are: 'cool'}});\n\t\t\t// TODO: BUG!? Occasionally has a stack overflow???? :/\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar g = Gun(); // TODO: NOTE! This will not work for in-memory only. This means it might not be viable as a test for core.\n\t\t\t\tg.get('test').path('you', function(e,d){\n\t\t\t\t\tif(!d || done.c){ return }\n\t\t\t\t\texpect(d.are).to.be('cool');\n\t\t\t\t\tdone.c = true;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t},10);\n\t\t\t\t});\n\t\t\t},250);\n\t\t});\n\n\t\tit('get put, Gun get path to path', function(done){ // For testing lazy eval that it works on cb style.\n\t\t\tvar gun = Gun();\n\t\t\tgun.get('test1').put({you: {are: 'cool'}});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar g = Gun(); // TODO: NOTE! This will not work for in-memory only. This means it might not be viable as a test for core.\n\t\t\t\tvar p = g.get('test1').path('you');\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tp.path('are', function(e,d){\n\t\t\t\t\t\tif(!d || done.c){ return }\n\t\t\t\t\t\texpect(d).to.be('cool');\n\t\t\t\t\t\tdone();done.c = true;\n\t\t\t\t\t});\n\t\t\t\t},100);\n\n\t\t\t},100)\n\t\t});\n\n\t\tit('get put, Gun get path path', function(done){ // For testing lazy eval that it works on cb style.\n\t\t\tvar gun = Gun();\n\t\t\tgun.get('test2').put({you: {are: 'cool'}});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar g = Gun(); // TODO: NOTE! This will not work for in-memory only. This means it might not be viable as a test for core.\n\t\t\t\tvar p = g.get('test2').path('you').path('are', function(e,d){\n\t\t\t\t\tif(!d || done.c){ return }\n\t\t\t\t\texpect(d).to.be('cool');\n\t\t\t\t\tdone();done.c=true;\n\t\t\t\t});\n\t\t\t},100);\n\t\t});\n\n\t\tit('get get not', function(done){\n\t\t\tGun.statedisk({ b: 1, c: 2 }, 'a', function(){\n\t\t\tfunction cb(e,d,f,a){\n\t\t\t\tif('b' === f && 1 === d){\n\t\t\t\t\tdone.b = true;\n\t\t\t\t}\n\t\t\t\tif('c' === f && 2 === d){\n\t\t\t\t\tdone.c = true;\n\t\t\t\t}\n\t\t\t\tif('d' === f && !d){\n\t\t\t\t\tdone.d = true;\n\t\t\t\t}\n\t\t\t\tif(done.done){ return }\n\t\t\t\tif(done.b && done.c && done.d){\n\t\t\t\t\tdone.done = true;\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t}\n\t\t\tgun.get('a').path('b').get(cb);//.err(cb).not(cb).on(cb).once(cb);\n\t\t\tgun.get('a').path('c').get(cb);//.err(cb).not(cb).on(cb).once(cb);\n\t\t\tgun.get('a').path('d').get(cb);//.err(cb).not(cb).on(cb).once(cb);\n\t\t\t}, 1000);\n\t\t});\n\n\t\tit('any not any not any not', function(done){\n\t\t\tfunction cb(e,d,f,a){\n\t\t\t\tif('b' === f && !d){\n\t\t\t\t\tdone.b = true;\n\t\t\t\t}\n\t\t\t\tif('c' === f && !d){\n\t\t\t\t\tdone.c = true;\n\t\t\t\t}\n\t\t\t\tif('d' === f && !d){\n\t\t\t\t\tdone.d = true;\n\t\t\t\t}\n\t\t\t\tif(done.b && done.c && done.d){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t}\n\t\t\tgun.get('x').path('b').any(cb);//.err(cb).not(cb).on(cb).once(cb);\n\t\t\tgun.get('x').path('c').any(cb);//.err(cb).not(cb).on(cb).once(cb);\n\t\t\tgun.get('x').path('d').any(cb);//.err(cb).not(cb).on(cb).once(cb);\n\t\t});\n\n\t\tit('get put, put deep', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('put/deep/ish');\n\t\t\tget.put({});\n\t\t\tget.once(function(data){ // TODO: API CHANGE! Empty objects should react.\n\t\t\t\t//console.log(\"...1\", data);\n\t\t\t\texpect(Gun.obj.empty(data, '_')).to.be.ok(); // API CHANGED,\n\t\t\t\t//expect(Gun.val.link.is(data.very)).to.be.ok();\n\t\t\t});//, {wait: 10000});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar put = get.put({\n\t\t\t\t\tvery: {\n\t\t\t\t\t\tdeep: {\n\t\t\t\t\t\t\tly: {\n\t\t\t\t\t\t\t\toriented: true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tget.once(function(data){\n\t\t\t\t\t//console.log(\"...2\", data);\n\t\t\t\t\texpect(Gun.val.link.is(data.very)).to.be.ok();\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tput.once(function(data){\n\t\t\t\t\t\t//console.log(\"...3\", data);\n\t\t\t\t\t\texpect(Gun.val.link.is(data.very)).to.be.ok();\n\t\t\t\t\t\tdone.val = true;\n\t\t\t\t\t});\n\t\t\t\t\tvar p = put.path('very');\n\t\t\t\t\tp.put({we: 'have gone!'});\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tp.once(function(data){\n\t\t\t\t\t\t\t//console.log(\"...4\", data);\n\t\t\t\t\t\t\texpect(data.we).to.be('have gone!');\n\t\t\t\t\t\t\texpect(Gun.val.link.is(data.deep)).to.be.ok();\n\t\t\t\t\t\t});\n\t\t\t\t\t\tp.put('EXPLODE');\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\texpect(done.val).to.be.ok();\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t},5);\n\t\t\t\t\t},150);\n\t\t\t\t},250);\n\t\t\t},110);\n\t\t});\n\n\t\tit('get path wire shallow swoop', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('slightly/shallow/path/swoop');\n\t\t\tvar path = get.path('one.two');\n\t\t\tvar put = path.put({oh: 'okay'});\n\t\t\tput.once(function(val, field){\n\t\t\t\t//console.log(\"****\", field, val);\n\t\t\t\texpect(val.oh).to.be('okay');\n\t\t\t\texpect(field).to.be('two');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get path wiring', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('deep/path');\n\t\t\tvar path = get.path('one.two');\n\t\t\tvar path3 = path.path('three');\n\t\t\tvar put = path3.put({you: 'found', the: 'bottom!'});\n\t\t\tput.once(function(val, field){\n\t\t\t\t//console.log(\"********1********\", field, val);\n\t\t\t\texpect(val.you).to.be('found');\n\t\t\t\texpect(val.the).to.be('bottom!');\n\t\t\t\texpect(field).to.be('three');\n\t\t\t});\n\t\t\tgun.get('deep/path').path('one.two.three.you').put('are').once(function(val, field){\n\t\t\t\t//console.log(\"********2*********\", field, val);return;\n\t\t\t\texpect(val).to.be('are');\n\t\t\t\texpect(field).to.be('you');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get node path put object merge isolated', function(done){\n\t\t\t// MORAL OF THE STORY: in KEY ON.GET check for change as NODE = AT.CHANGE || GUN.__.GRAPH[AT.soul] && Gun.node.soul(NODE, 'KEY') === 1; BAM!\n\t\t\tvar gun = Gun();\n\t\t\tvar put = gun.put({hello: 'key'}).key('hello/key/iso')\n\t\t\tvar get = gun.get('hello/key/iso');\n\t\t\tvar puthi = get.put({hi: 'you'});\n\t\t\tputhi.on(function(node){\n\t\t\t\tif(done.hi){ return }\n\t\t\t\t//console.log(1, node);\n\t\t\t\texpect(node.hello).to.be('key');\n\t\t\t\texpect(node.hi).to.be('you');\n\t\t\t\tdone.hi = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar get2 = gun.get('hello/key/iso');\n\t\t\t\tvar path2 = get2.path('hi');\n\t\t\t\tpath2._.id = 'path2';\n\t\t\t\tvar putyay = path2.put({yay: \"value\"});\n\t\t\t\tputyay.on(function(node, field){\n\t\t\t\t\tif(done.yay){ return }\n\t\t\t\t\texpect(field).to.be('hi');\n\t\t\t\t\texpect(node.yay).to.be('value');\n\t\t\t\t\tdone.yay = true;\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tvar get3 = gun.get('hello/key/iso');\n\t\t\t\t\tvar path3 = get3.path('hi');\n\t\t\t\t\tpath3._.id = 'path3';\n\t\t\t\t\tvar puthappy = path3.put({happy: \"faces\"});\n\t\t\t\t\tputhappy.on(function(node, field){\n\t\t\t\t\t\t//console.log(3, field, node);\n\t\t\t\t\t\texpect(field).to.be('hi');\n\t\t\t\t\t\texpect(node.happy).to.be('faces');\n\t\t\t\t\t\texpect(node.yay).to.be('value');\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\tconsole.log(\"******************************\");\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t},200);\n\t\t\t\t\t});\n\t\t\t\t},100);\n\t\t\t},100);\n\t\t});\n\n\t\tit('get node path put object merge', function(done){\n\t\t\tvar g = gun.get('hello/key', function(err, node){\n\t\t\t\tif(done.soul){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(done.ref = Gun.val.link.is(node.hi)).to.be.ok();\n\t\t\t\tdone.soul = Gun.node.soul(node);\n\t\t\t});\n\t\t\tg.path('hi').put({happy: \"faces\"}, function(err, ok){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tvar keynode = gun.back(-1)._.graph[done.soul], soul;\n\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\texpect(c.length).to.be(1);\n\t\t\t\tvar root = gun.back(-1)._.graph[soul];\n\t\t\t\tvar sub = gun.back(-1)._.graph[done.ref];\n\t\t\t\texpect(root.hello).to.be('key');\n\t\t\t\texpect(root.yay).to.not.be.ok();\n\t\t\t\texpect(Gun.node.soul(sub)).to.be(done.ref);\n\t\t\t\texpect(sub.yay).to.be('value');\n\t\t\t\texpect(sub.happy).to.be('faces');\n\t\t\t\tif(done.sub){ expect(done.sub).to.be(done.ref) }\n\t\t\t\telse { done.sub = done.ref }\n\t\t\t\tdone.w = 1; if(done.r){ done(); done.c = 1 };\n\t\t\t}).on(function(node, field){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(field).to.be('hi');\n\t\t\t\texpect(node.happy).to.be('faces');\n\t\t\t\texpect(node.yay).to.be('value');\n\t\t\t\tif(done.sub){ expect(done.sub).to.be(Gun.node.soul(node)) }\n\t\t\t\telse { done.sub = Gun.node.soul(node) }\n\t\t\t\tdone.r = 1; if(done.w){ done(); done.c = 1 };\n\t\t\t});\n\t\t});\n\n\t\tit('get node path put value conflict relation', function(done){\n\t\t\tgun.get('hello/key', function(err, node){\n\t\t\t\tif(done.soul){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\texpect(done.ref = Gun.val.link.is(node.hi)).to.be.ok();\n\t\t\t\tdone.soul = Gun.node.soul(node);\n\t\t\t}).path('hi').put('crushed', function(err, ok){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tvar keynode = gun.back(-1)._.graph[done.soul], soul;\n\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\texpect(c.length).to.be(1);\n\t\t\t\tvar root = gun.back(-1)._.graph[soul];\n\t\t\t\tvar sub = gun.back(-1)._.graph[done.ref];\n\t\t\t\texpect(root.hello).to.be('key');\n\t\t\t\texpect(root.yay).to.not.be.ok();\n\t\t\t\texpect(Gun.node.soul(sub)).to.be(done.ref);\n\t\t\t\texpect(sub.yay).to.be('value');\n\t\t\t\texpect(sub.happy).to.be('faces');\n\t\t\t\texpect(root.hi).to.be('crushed');\n\t\t\t\tdone.w = 1; if(done.r){ done(); done.c = 1 };\n\t\t\t}).on(function(val, field){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(field).to.be('hi');\n\t\t\t\texpect(val).to.be('crushed');\n\t\t\t\tdone.r = 1; if(done.w){ done(); done.c = 1 };\n\t\t\t});\n\t\t});\n\n\t\tit.skip('put gun node', function(done){\n\t\t\tvar mark = gun.put({age: 23, name: \"Mark Nadal\"});\n\t\t\tvar timber = gun.put({age: 3, name: \"Timber Nadal\"});\n\t\t\tmark.path('boss').put(timber, function(err){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t});\n\t\t\tmark.path('boss.name').once(function(val){\n\t\t\t\texpect(val).to.be(\"timber Nadal\");\n\t\t\t});\n\t\t});\n\n\t\tit('put val', function(done){\n\t\t\tgun.put({hello: \"world\"}).once(function(val){\n\t\t\t\texpect(val.hello).to.be('world');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('put key val', function(done){\n\t\t\tgun.put({hello: \"world\"}).key('hello/world').once(function(val, field){\n\t\t\t\tif(done.c){ return }\n\t\t\t\texpect(val.hello).to.be('world');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('get val', function(done){\n\t\t\tgun.get('hello/world').once(function(val, field){\n\t\t\t\texpect(val.hello).to.be('world');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('get path', function(done){\n\t\t\tgun.get('hello/world').path('hello').once(function(val){\n\t\t\t\t//console.log(\"**************\", val);\n\t\t\t\texpect(val).to.be('world');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 1900);\n\t\t});\n\n\t\tit('get put path', function(done){\n\t\t\tgun.get('hello/world').put({hello: 'Mark'}).path('hello').once(function(val, field){\n\t\t\t\texpect(val).to.be('Mark');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('get path put', function(done){\n\t\t\tgun.get('hello/world').path('hello').put('World').once(function(val){\n\t\t\t\texpect(val).to.be('World');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('get empty put', function(done){\n\t\t\tvar gun = Gun({init: true});\n\t\t\tgun.get('nothing/here').put({far: \"wide\"}, function(err, ok){\n\t\t\t\tdone.put = true;\n\t\t\t});\n\t\t\tgun.get({'#': 'asdfoobar'}).put({far: \"wide\"}, function(err, ok){\n\t\t\t\tdone.put2 = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.put).to.not.be.ok();\n\t\t\t\texpect(done.put2).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100)\n\t\t});\n\n\t\tit('get path empty put val', function(done){\n\t\t\tvar gun = Gun({init: true}).put({hello: \"Mark\"}).key('hello/world/not');\n\t\t\tgun.get('hello/world/not').path('earth').put('mars').once(function(val){\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.not.be.ok(); // CHANGELOG: API 0.3 BREAKING CHANGE, .put is suppose to be dependent on the previous chain, which means it SHOULD NOT PUT on an empty path.\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('get empty put val implicit', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('hello/imp/world');\n\t\t\tvar put = get.put({planet: 'the earth'});\n\t\t\tput.once(function(val){\n\t\t\t\texpect(val.planet).to.be('the earth');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get empty path put val implicit split', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('hello/imp/where');\n\t\t\tvar path = get.path('where');\n\t\t\tvar put = path.put('the mars');\n\t\t\tvar val = put.once(function(val, field){\n\t\t\t\texpect(field).to.be('where');\n\t\t\t\texpect(val).to.be('the mars');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get path empty put val implicit', function(done){\n\t\t\tgun.get('hello/world').path('earth').put('mars').once(function(val, field){\n\t\t\t\texpect(val).to.be('mars');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('get path val', function(done){\n\t\t\tvar gun = Gun({init: true}).put({hello: \"Mark\"}).key('hello/world/not');\n\t\t\tgun.get('hello/world').path('earth').put('mars');\n\t\t\tgun.get('hello/world/not').path('earth').once(function(val){\n\t\t\t\texpect(val).to.be('mars');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('get path val implicit', function(done){\n\t\t\tgun.get('hello/world').path('earth').once(function(val){\n\t\t\t\texpect(val).to.be('mars');\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t}, 100);\n\t\t});\n\n\t\tdescribe('some nots', function(){\n\t\t\tit('get not kick val', function(done){\n\t\t\t\tgun.get(\"some/empty/thing\").not(function(key, kick){ // that if you call not first\n\t\t\t\t\tthis.put({now: 'exists'}).key(key); // you can put stuff\n\t\t\t\t}).once(function(val){ // and THEN still retrieve it.\n\t\t\t\t\texpect(val.now).to.be('exists');\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('get not kick val when it already exists', function(done){\n\t\t\t\tvar foo;\n\t\t\t\tfoo = gun.get(\"some/empty/thing\");\n\t\t\t\tfoo.not(function(key, kick){\n\t\t\t\t\tdone.not = true;\n\t\t\t\t\tthis.put({now: 'THIS SHOULD NOT HAPPEN'}).key(key);\n\t\t\t\t}).once(function(val){\n\t\t\t\t\texpect(val.now).to.be('exists');\n\t\t\t\t\texpect(done.not).to.not.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('put path val sub', function(done){\n\t\t\tgun.put({last: {some: 'object'}}).path('last').once(function(val){\n\t\t\t\texpect(val.some).to.be('object');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\t\t//return;\n\t\tit('chain ordering', function(done){\n\t\t\tvar sec = gun.get('order/second');\n\t\t\tvar res = Gun.on.stun(sec);\n\t\t\tgun.get('order/first', function(){ // this has a race condition against the third get. However if it fulfills first...\n\t\t\t\t//console.log('callback', 0);\n\t\t\t\tdone.zero = true;\n\t\t\t\texpect(done.one).to.not.be.ok();\n\t\t\t\texpect(done.two).to.not.be.ok();\n\t\t\t\tres(function(){\n\t\t\t\t\tsec.any(function(){ // then this guy should be run before the third get, since it is queued first relative to this soul.\n\t\t\t\t\t\t//console.log('callback', 1);\n\t\t\t\t\t\tdone.one = true;\n\t\t\t\t\t\texpect(done.zero).to.be.ok();\n\t\t\t\t\t\texpect(done.one).to.be.ok();\n\t\t\t\t\t\texpect(done.two).to.not.be.ok();\n\t\t\t\t\t\tres();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tgun.get('order/second', function(){\n\t\t\t\t//console.log('callback', 2);\n\t\t\t\tdone.two = true;\n\t\t\t\texpect(done.zero).to.be.ok();\n\t\t\t\texpect(done.one).to.be.ok();\n\t\t\t\texpect(done.two).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get put null', function(done){\n\t\t\tgun.put({last: {some: 'object'}}).path('last').once(function(val, field){\n\t\t\t\t//console.log(\"**\", field, val);\n\t\t\t\texpect(field).to.be('last');\n\t\t\t\texpect(val.some).to.be('object');\n\t\t\t}).put(null).once(function(val, field){\n\t\t\t\t//console.log(\"******\", field, val);\n\t\t\t\texpect(field).to.be('last');\n\t\t\t\texpect(val).to.be(null);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('Gun get put null', function(done){ // flip flop bug\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({last: {some: 'object'}}).path('last').once(function(val, field){\n\t\t\t\t//console.log(\"**\", field, val);\n\t\t\t\tdone.some = true;\n\t\t\t\texpect(val.some).to.be('object');\n\t\t\t}).put(null).once(function(val, field){\n\t\t\t\t//console.log(\"********\", field, val);\n\t\t\t\texpect(val).to.be(null);\n\t\t\t\texpect(done.some).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('var put key path', function(done){ // contexts should be able to be saved to a variable\n\t\t\tvar foo = gun.put({foo: 'bar'}).key('foo/bar');\n\t\t\tfoo.path('hello.world.nowhere'); // this should become a sub-context, that doesn't alter the original\n\t\t\tsetTimeout(function(){\n\t\t\t\tfoo.path('foo').once(function(val){ // and then the original should be able to be reused later\n\t\t\t\t\texpect(val).to.be('bar'); // this should work\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t}, 500);\n\t\t});\n\n\t\tit('var get path', function(done){ // contexts should be able to be saved to a variable\n\t\t\tvar foo = gun.get('foo/bar');\n\t\t\tfoo.path('hello.world.nowhere'); // this should become a sub-context, that doesn't alter the original\n\t\t\tsetTimeout(function(){\n\t\t\t\tfoo.path('foo').once(function(val){ // and then the original should be able to be reused later\n\t\t\t\t\texpect(val).to.be('bar'); // this should work\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t}, 500);\n\t\t});\n\n\t\tit('get not put val path val', function(done){\n\t\t\tvar todos = gun.get(\"examples/list/foobar\").not(function(key){\n\t\t\t\tthis.put({\n\t\t\t\t\tid: 'foobar',\n\t\t\t\t\ttitle: 'awesome title',\n\t\t\t\t\ttodos: {}\n\t\t\t\t}).key(key);\n\t\t\t}).once(function(data){\n\t\t\t\texpect(data.id).to.be('foobar');\n\t\t\t//}).path('todos').once(function(todos, field){\n\t\t\t}).path('todos').once(function(todos, field){\n\t\t\t\texpect(field).to.be('todos');\n\t\t\t\texpect(todos).to.not.have.property('id');\n\t\t\t\tdone();\n\t\t\t}, {empty: true}); // API CHANGED! .val fires on empty by default now.\n\t\t});\n\n\t\tit('put circular ref', function(done){\n\t\t\tvar data = {};\n\t\t\tdata[0] = \"DATA!\";\n\t\t\tdata.a = {c: 'd', e: 1, f: true};\n\t\t\tdata.b = {x: 2, y: 'z'};\n\t\t\tdata.a.kid = data.b;\n\t\t\tdata.b.parent = data.a;\n\t\t\tgun.put(data, function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t}).once(function(val){\n\t\t\t\tsetTimeout(function(){ // TODO: Is this cheating? I don't think so cause we are using things outside of the API!\n\t\t\t\t\tvar a = gun.back(-1)._.graph[Gun.val.link.is(val.a)];\n\t\t\t\t\tvar b = gun.back(-1)._.graph[Gun.val.link.is(val.b)];\n\t\t\t\t\texpect(Gun.val.link.is(val.a)).to.be(Gun.node.soul(a));\n\t\t\t\t\texpect(Gun.val.link.is(val.b)).to.be(Gun.node.soul(b));\n\t\t\t\t\texpect(Gun.val.link.is(a.kid)).to.be(Gun.node.soul(b));\n\t\t\t\t\texpect(Gun.val.link.is(b.parent)).to.be(Gun.node.soul(a));\n\t\t\t\t\tdone();\n\t\t\t\t},10);\n\t\t\t});\n\t\t});\n\n\t\tit('gun put path and some changes node', function(done){ done.c = 0;\n\t\t\tvar ref = gun.put({\n\t\t\t\tfoo: {bar: 'lol'}\n\t\t\t});\n\t\t\tvar sub = ref.path('foo').on(function(val){\n\t\t\t\tdone.c++;\n\t\t\t\tif(val){\n\t\t\t\t\texpect(val.extra).to.not.be.ok();\n\t\t\t\t}\n\t\t\t\tif(done.c === 1){\n\t\t\t\t\texpect(val.bar).to.be('lol');\n\t\t\t\t\tref.put({foo: 'hi'});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(done.c === 2){\n\t\t\t\t\texpect(val).to.be('hi');\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit('gun put two nodes, link one, path and detach', function(done){ done.c = 0;\n\t\t\t// this test is not written yet!\n\t\t\tvar ref = gun.put({\n\t\t\t\tfoo: {bar: 'lol'}\n\t\t\t});\n\t\t\tvar sub = ref.path('foo').on(function(val){\n\t\t\t\tdone.c++;\n\t\t\t\tif(val){\n\t\t\t\t\texpect(val.extra).to.not.be.ok();\n\t\t\t\t}\n\t\t\t\tif(done.c === 1){\n\t\t\t\t\texpect(val.bar).to.be('lol');\n\t\t\t\t\tref.put({foo: 'hi'});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(done.c === 2){\n\t\t\t\t\texpect(val).to.be('hi');\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\t// ref.put({foo: {extra: 'field'}});\n\t\t});\n\n\t\tit('gun put path deep primitive', function(done){\n\t\t\tgun.put({\n\t\t\t\tfoo: {\n\t\t\t\t\tbar: {\n\t\t\t\t\t\tlol: true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}).path('foo.bar.lol').once(function(val){\n\t\t\t\texpect(val).to.be(true);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('gun put path deep node', function(done){\n\t\t\tgun.put({\n\t\t\t\tfoo: {\n\t\t\t\t\tbar: {\n\t\t\t\t\t\tlol: {ok: true}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}).path('foo.bar.lol').once(function(val){\n\t\t\t\texpect(val.ok).to.be(true);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('put circular deep', function(done){\n\t\t\tvar mark = {\n\t\t\t\tage: 23,\n\t\t\t\tname: \"Mark Nadal\"\n\t\t\t}\n\t\t\tvar timber = {\n\t\t\t\tage: 23,\n\t\t\t\tname: \"timber Nadal\",\n\t\t\t\tphd: true\n\t\t\t}\n\t\t\tmark.boss = timber;\n\t\t\ttimber.husband = mark;\n\t\t\tvar cat = {\n\t\t\t\tage: 3,\n\t\t\t\tname: \"Hobbes\"\n\t\t\t}\n\t\t\tmark.pet = cat;\n\t\t\ttimber.pet = cat;\n\t\t\tcat.owner = mark;\n\t\t\tcat.master = timber;\n\t\t\t//console.debug.i=1;console.log(\"------------\");\n\t\t\tgun.put(mark, function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t}).once(function(val){\n\t\t\t\texpect(val.age).to.be(23);\n\t\t\t\texpect(val.name).to.be(\"Mark Nadal\");\n\t\t\t\texpect(Gun.val.link.is(val.boss)).to.be.ok();\n\t\t\t\texpect(Gun.val.link.is(val.pet)).to.be.ok();\n\t\t\t}).path('boss.pet.name').once(function(val){\n\t\t\t\t//console.debug(1, \"*****************\", val);\n\t\t\t\texpect(val).to.be('Hobbes');\n\t\t\t}).back().path('pet.master').once(function(val){\n\t\t\t\t//console.log(\"*****************\", val);\n\t\t\t\texpect(val.name).to.be(\"timber Nadal\");\n\t\t\t\texpect(val.phd).to.be.ok();\n\t\t\t\texpect(val.age).to.be(23);\n\t\t\t\texpect(Gun.val.link.is(val.pet)).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('key get', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tgun.get('key/get').put({yay: 'something'}).key('index/yay');\n\t\t\tgun.get('index/yay', function(err, node){\n\t\t\t\texpect(node.yay).to.be('something');\n\t\t\t\tif(done.c){return}\n\t\t\t\tdone();done.c=1;\n\t\t\t});\n\t\t});\n\n\t\tit('put partial sub merge', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar mark = gun.put({name: \"Mark\", boss: { name: \"timber\" }}).key('person/mark').once(function(mark){\n\t\t\t\t//console.log(\"VAL1\", mark);\n\t\t\t\tdone.marksoul = Gun.node.soul(mark);\n\t\t\t\texpect(mark.name).to.be(\"Mark\");\n\t\t\t});\n\t\t\tmark.put({age: 23, boss: {age: 3}});\n\t\t\tsetTimeout(function(){\n\t\t\t\tmark.put({citizen: \"USA\", boss: {citizen: \"USA\"}}).once(function(mark){\n\t\t\t\t\t//console.log(\"VAL2\", mark, gun);\n\t\t\t\t\texpect(mark.name).to.be(\"Mark\");\n\t\t\t\t\texpect(mark.age).to.be(23);\n\t\t\t\t\texpect(mark.citizen).to.be(\"USA\");\n\t\t\t\t\tthis.path('boss').on(function(timber){ // TODO: turn this .on back into a .val\n\t\t\t\t\t\t//console.log(\"VAL3\", timber);\n\t\t\t\t\t\tif(done.c){ return }\n\t\t\t\t\t\texpect(done.c).to.not.be.ok(); // RELATED TO BELOW #\"CONTEXT NO DOUBLE EMIT\".\n\t\t\t\t\t\texpect(timber.name).to.be(\"timber\");\n\t\t\t\t\t\texpect(timber.age).to.be(23);\n\t\t\t\t\t\texpect(timber.citizen).to.be(\"USA\");\n\t\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}, 500);\n\t\t});\n\n\t\tit('path path', function(done){\n\t\t\tvar deep = gun.put({some: {deeply: {nested: 'value'}}});\n\t\t\tdeep.path('some.deeply.nested').once(function(val){\n\t\t\t\texpect(val).to.be('value');\n\t\t\t});\n\t\t\tdeep.path('some').path('deeply').path('nested').once(function(val){\n\t\t\t\texpect(val).to.be('value');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('context null put value val error', function(done){\n\t\t\tgun.put(\"oh yes\", function(err){\n\t\t\t\texpect(err).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('context no double emit', function(done){ // annoying problem where somehow the gun.path in a put starts subscribing and firing to its context if we let get handle emitting for the chain in put.\n\t\t\tvar c = 0;\n\t\t\tvar gun = Gun();\n\t\t\tvar fo = gun.put({fo: 'bar'});\n\t\t\tGun.log.ba = 1;\n\t\t\tfo.put({ba: {}}).once(function(obj, field){\n\t\t\t\tc += 1;\n\t\t\t\texpect(c).to.be(1);\n\t\t\t\tdone();\n\t\t\t});\n\t\t\tGun.log.ba = 0;\n\t\t\tvar ba = fo.path('ba');\n\t\t\tba.put({co: 'do'});\n\t\t});\n\n\t\tdescribe('random', function(){\n\t\t\tvar foo;\n\t\t\tit('context null put node', function(done){\n\t\t\t\tfoo = gun.put({foo: 'bar'}).once(function(obj){\n\t\t\t\t\texpect(obj.foo).to.be('bar');\n\t\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('context node put val', function(done){\n\t\t\t\t// EFFECTIVELY a TIMEOUT from the previous test. NO LONGER!\n\t\t\t\tfoo.put('banana', function(err){\n\t\t\t\t\texpect(err).to.be.ok();\n\t\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('context node put node', function(done){\n\t\t\t\t// EFFECTIVELY a TIMEOUT from the previous test. NO LONGER!\n\t\t\t\tfoo.put({bar: {zoo: 'who'}}).once(function(obj, field){\n\t\t\t\t\t//console.log(\"terribly terrilby unpleasant\", field, obj);\n\t\t\t\t\texpect(obj.foo).to.be('bar');\n\t\t\t\t\texpect(Gun.val.link.is(obj.bar)).to.ok();\n\t\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tvar bar;\n\t\t\tit('context node and field of relation put node', function(done){\n\t\t\t\t// EFFECTIVELY a TIMEOUT from the previous test. NO LONGER!\n\t\t\t\tbar = foo.path('bar');\n\t\t\t\texpect(gleak.check()).to.not.be.ok();\n\t\t\t\tbar.put({combo: 'double'}).once(function(obj, field){\n\t\t\t\t\t//expect(obj.zoo).to.be('who');\n\t\t\t\t\texpect(obj.combo).to.be('double');\n\t\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('context node and field put value', function(done){\n\t\t\t\t// EFFECTIVELY a TIMEOUT from the previous test. NO LONGER!\n\t\t\t\tvar tar = foo.path('tar');\n\t\t\t\ttar.put('zebra').once(function(val){\n\t\t\t\t\texpect(val).to.be('zebra');\n\t\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('context node and field, put node', function(done){\n\t\t\t\t// EFFECTIVELY a TIMEOUT from the previous test. NO LONGER!\n\t\t\t\tbar.path('combo').put({another: 'node'}).once(function(obj){\n\t\t\t\t\texpect(obj.another).to.be('node');\n\t\t\t\t\t// double .vals here also RELATED to the #\"context no double emit\" but because of a faulty .not or .init system.\n\t\t\t\t\tbar.once(function(node){\n\t\t\t\t\t\texpect(Gun.val.link.is(node.combo)).to.be.ok();\n\t\t\t\t\t\texpect(Gun.val.link.is(node.combo)).to.be(Gun.node.soul(obj));\n\t\t\t\t\t\tdone(); //setTimeout(function(){ done() },1);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('val path put val', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tvar al = gun.put({gender:'m', age:30, name:'alfred'}).key('user/alfred');\n\t\t\tvar beth = gun.put({gender:'f', age:22, name:'beth'}).key('user/beth');\n\n\t\t\tal.once(function(a){\n\t\t\t\tbeth.put({friend: a}, function(err, ok){\n\t\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\t}).path('friend').once(function(aa){\n\t\t\t\t\texpect(Gun.node.soul(a)).to.be(Gun.node.soul(aa));\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\n\t\t});\n\t\t// TODO: Write a test that tests for keysoul has a key meta indicator.\n\t\t// TODO: A soulsoul does not have a key meta indicator.\n\t\t// TODO: Souls match their graph.\n\t\tit('val path put val key', function(done){ // bug discovered from Jose's visualizer\n\t\t\tvar gun = Gun(), s = Gun.time.is(), n = function(){ return Gun.time.is() }\n\t\t\tthis.timeout(5000);\n\n\t\t\tgun.put({gender:'m', age:30, name:'alfred'}).key('user/alfred');\n\t\t\tgun.put({gender:'f', age:22, name:'beth'  }).key('user/beth');\n\t\t\t//gun.get('user/beth').path('friend').put(gun.get('user/alfred')); // ideal format which we have a future test for.\n\t\t\tgun.get('user/alfred').once(function(a){\n\t\t\t\t//console.log(\"*****\", a);\n\t\t\t\t//expect(a['_']['key']).to.be.ok();\n\t\t\t\tgun.get('user/beth').put({friend: a}, function(err, ok){ // b - friend_of -> a\n\t\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\t\tvar keynode = gun.back(-1)._.graph['user/alfred'];\n\t\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\t\texpect(c.length).to.be(1);\n\t\t\t\t});\n\t\t\t\tgun.get('user/beth').once(function(b){\n\t\t\t\t\t//console.log(\"beth\", b);\n\t\t\t\t\tgun.get('user/alfred').put({friend: b}).once(function(al){ // a - friend_of -> b\n\t\t\t\t\t\t//console.log(\"al again\", al);\n\t\t\t\t\t\tgun.get('user/beth').put({cat: {name: \"fluffy\", age: 3, coat: \"tabby\"}}).once(function(bet){\n\t\t\t\t\t\t\tgun.get('user/alfred').path('friend.cat').key('the/cat');\n\t\t\t\t\t\t\tgun.get('the/cat').once(function(c){\n\t\t\t\t\t\t\t\t//console.log(\"cat!!!\", c);\n\t\t\t\t\t\t\t\texpect(c.name).to.be('fluffy');\n\t\t\t\t\t\t\t\texpect(c.age).to.be(3);\n\t\t\t\t\t\t\t\texpect(c.coat).to.be('tabby');\n\t\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('map', function(done){\n\t\t\tvar c = 0, set = gun.put({a: {here: 'you'}, b: {go: 'dear'}, c: {sir: '!'} });\n\t\t\tset.map(function(obj, field){\n\t\t\t\tc++;\n\t\t\t\tif(field === 'a'){\n\t\t\t\t\texpect(obj.here).to.be('you');\n\t\t\t\t}\n\t\t\t\tif(field === 'b'){\n\t\t\t\t\texpect(obj.go).to.be('dear');\n\t\t\t\t}\n\t\t\t\tif(field === 'c'){\n\t\t\t\t\texpect(obj.sir).to.be('!');\n\t\t\t\t}\n\t\t\t\tif(c === 3){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t})\n\t\t});\n\n\t\tit.skip('key soul', function(done){ // TODO: Deprecated? Maybe.\n\t\t\tvar gun = Gun();\n\t\t\tgun.key('me', function(err, ok){\n\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\tvar keynode = gun.back(-1)._.graph['me'];\n\t\t\t\tvar c = soulnode(gun, keynode), soul = c[0];\n\t\t\t\texpect(c.length).to.be(1);\n\n\t\t\t\texpect(soul).to.be('qwertyasdfzxcv');\n\t\t\t\tdone();\n\t\t\t}, 'qwertyasdfzxcv');\n\t\t});\n\n\t\tit.skip('no false positive null emit', function(done){ // TODO: THE API HAS CHANGED! REDO TEHSE!\n\t\t\tvar gun = Gun({wire: {get: function(key, cb){\n\t\t\t\tvar g = {};\n\t\t\t\tg[soul] = {_: {'#': soul, '>': {'a': 0}},\n\t\t\t\t\t'a': 'b'\n\t\t\t\t};\n\t\t\t\tcb(null, g);\n\t\t\t\tg = {};\n\t\t\t\tg[soul] = {_: {'#': soul, '>': {'c': 0}},\n\t\t\t\t\t'c': 'd'\n\t\t\t\t};\n\t\t\t\tcb(null, g);\n\t\t\t\tg = {};\n\t\t\t\tg[soul] = {_: {'#': soul }};\n\t\t\t\tcb(null, g);\n\t\t\t\tcb(); // false trigger!\n\t\t\t}}}), soul = Gun.text.random();\n\t\t\tgun.get(soul).not(function(err, ok){\n\t\t\t\tdone.fail = true;\n\t\t\t}).once(function(val){\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\texpect(val.a).to.be('b');\n\t\t\t\t\texpect(val.c).to.be('d');\n\t\t\t\t\texpect(done.fail).to.not.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t},5);\n\t\t\t});\n\t\t});\n\n\t\tit.skip('unique val on stream', function(done){ // TODO: THE API HAS CHANGED! REDO TEHSE!\n\t\t\tvar gun = Gun({wire: {get: function(key, cb){\n\t\t\t\tif(Gun.obj.has(key, '#')){\n\t\t\t\t\tkey = key['#'];\n\t\t\t\t\tvar node = tmp.graph[key];\n\t\t\t\t\tcb(null, node);\n\t\t\t\t\tcb(null, Gun.is.node.ify({}, key));\n\t\t\t\t\tcb(null, {});\n\t\t\t\t}\n\t\t\t}}}), tmp = {graph: {}};\n\t\t\ttmp.graph[tmp.soul = Gun.text.random()] = tmp.node = {a: 'b', c: 'd'};\n\t\t\tGun.is.node.ify(tmp.node, tmp.soul);\n\n\t\t\ttmp.graph['me'] = tmp.keynode = {};\n\t\t\tGun.obj.put(tmp.rel = {}, '#', tmp.soul);\n\t\t\ttmp.keynode[tmp.soul] = tmp.rel;\n\t\t\tGun.is.node.ify(tmp.keynode, 'me');\n\t\t\ttmp.keynode['#']['key'] = 1;\n\n\t\t\tgun.get('me', function(err, data){\n\n\t\t\t}).once(function(val){\n\t\t\t\tdone.count = (done.count || 0) + 1;\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\texpect(val.a).to.be('b');\n\t\t\t\t\texpect(val.c).to.be('d');\n\t\t\t\t\texpect(done.count).to.be(1);\n\t\t\t\t\tdone();\n\t\t\t\t},5);\n\t\t\t});\n\t\t});\n\n\t\tit.skip('unique path val on stream', function(done){ // TODO: THE API HAS CHANGED! REDO TEHSE!\n\t\t\tvar gun = Gun({wire: {get: function(key, cb){\n\t\t\t\tvar n = {};\n\t\t\t\tn = {_: {'#': soul, '>': {'a': 0}},\n\t\t\t\t\t'a': 'a'\n\t\t\t\t};\n\t\t\t\tcb(null, n);\n\t\t\t\tn = {};\n\t\t\t\tn = {_: {'#': soul, '>': {'a': 1}},\n\t\t\t\t\t'a': 'b'\n\t\t\t\t};\n\t\t\t\tcb(null, n);\n\t\t\t\tn = {};\n\t\t\t\tn = {_: {'#': soul }};\n\t\t\t\tcb(null, n);\n\t\t\t}}}), soul = Gun.text.random();\n\n\t\t\tgun.get(soul).path('a').once(function(val){\n\t\t\t\tdone.count = (done.count || 0) + 1;\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\texpect(val).to.be('b');\n\t\t\t\t\texpect(done.count).to.be(1);\n\t\t\t\t\tdone();\n\t\t\t\t},5);\n\t\t\t});\n\t\t});\n\n\t\tit('double not', function(done){ // from the thought tutorial\n\t\t\tvar gun = Gun(gopt).get('thoughts').not(function(key){\n\t\t\t\tthis.put({}).key(key);\n\t\t\t});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.not(function(){\n\t\t\t\t\tdone.not = true;\n\t\t\t\t}).once(function(){\n\t\t\t\t\texpect(done.not).to.not.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t}, {empty: true});\n\t\t\t}, 10);\n\t\t});\n\n\t\tit('node path node path node path', function(done){\n\t\t\tvar gun = Gun(/*gopt*/);\n\t\t\tvar data = gun.get('data');\n\t\t\tgun.put({\n\t\t\t\ta: 1,\n\t\t\t\tb: 2,\n\t\t\t\tc: 3\n\t\t\t}).key('data');\n\t\t\tdata.path('a', function(e, v, f){\n\t\t\t\t//console.log(\"FIRST\", e,v,f);\n\t\t\t\texpect(done.D).to.not.be.ok();\n\t\t\t\tif(done.a){return}\n\t\t\t\texpect(done.a).to.not.be.ok();\n\t\t\t\texpect(v).to.be(1);\n\t\t\t\tdone.a = true;\n\t\t\t});\n\t\t\tdata.path('b', function(e, v, f){\n\t\t\t\t//console.log(\"SECOND\", e,v,f);\n\t\t\t\texpect(done.D).to.not.be.ok();\n\t\t\t\tif(done.b){return}\n\t\t\t\texpect(done.b).to.not.be.ok();\n\t\t\t\texpect(v).to.be(2);\n\t\t\t\tdone.b = true;\n\t\t\t});\n\t\t\tdata.path('c', function(e, v, f){\n\t\t\t\t//console.log(\"THIRD\", e,v,f);\n\t\t\t\texpect(done.D).to.not.be.ok();\n\t\t\t\tif(done.c){return}\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\texpect(v).to.be(3);\n\t\t\t\tdone.c = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){//return;\n\t\t\t\tdone.D=true;\n\t\t\t\tdata.put({d: 4});\n\t\t\t\texpect(done.a).to.be.ok();\n\t\t\t\texpect(done.b).to.be.ok();\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t},250);\n\t\t});\n\n\t\tit('node path obj node path obj node path obj', function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar data = gun.get('data1');\n\t\t\tgun.put({\n\t\t\t\ta: {v: 1},\n\t\t\t\tb: {v: 2},\n\t\t\t\tc: {v: 3}\n\t\t\t}).key('data1');\n\t\t\tdata.path('a', function(e, v, f){\n\t\t\t\t//console.log(\"FIRST\", f,v);\n\t\t\t\texpect(done.D).to.not.be.ok();\n\t\t\t\tif(done.a){return}\n\t\t\t\texpect(done.a).to.not.be.ok();\n\t\t\t\texpect(v.v).to.be(1);\n\t\t\t\tdone.a = true;\n\t\t\t});\n\t\t\tdata.path('b', function(e, v, f){\n\t\t\t\t//console.log(\"SECOND\", f,v);\n\t\t\t\texpect(done.D).to.not.be.ok();\n\t\t\t\tif(done.b){return}\n\t\t\t\texpect(done.b).to.not.be.ok();\n\t\t\t\texpect(v.v).to.be(2);\n\t\t\t\tdone.b = true;\n\t\t\t});\n\t\t\tdata.path('c', function(e, v, f){\n\t\t\t\t//console.log(\"THIRD\", f,v);\n\t\t\t\texpect(done.D).to.not.be.ok();\n\t\t\t\tif(done.c){return}\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\texpect(v.v).to.be(3);\n\t\t\t\tdone.c = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tdone.D = true;\n\t\t\t\t//data.put({d: {v: 4}});\n\t\t\t\texpect(done.a).to.be.ok();\n\t\t\t\texpect(done.b).to.be.ok();\n\t\t\t\texpect(done.c).to.be.ok();\n\t\t\t\tdone();\n\t\t\t},100);\n\t\t});\n\n\t\tdescribe('prototype crash', function(){\n\t\t\tit('instance.key', function(done){\n\t\t\t\tGun().key('oye', function(err){\n\t\t\t\t\texpect(err).to.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('instance.on', function(done){\n\t\t\t\tGun().on();\n\t\t\t\tdone();\n\t\t\t});\n\n\t\t\tit('instance.path', function(done){\n\t\t\t\tGun().path('oye', function(err){\n\t\t\t\t\texpect(err).to.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('instance.map', function(done){\n\t\t\t\tGun().map();\n\t\t\t\tdone();\n\t\t\t});\n\n\t\t\tit('instance.not', function(done){\n\t\t\t\tGun().not();\n\t\t\t\tdone();\n\t\t\t});\n\n\t\t\tit('instance.val', function(done){\n\t\t\t\tGun().once();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('implicit put on empty get', function(done){\n\t\t\tvar gun = Gun().get('init');\n\t\t\tgun.on(function(val){\n\t\t\t\texpect(val.not).to.be(true);\n\t\t\t\tif(done.c){ return } done(); done.c = 1;\n\t\t\t});\n\t\t\tgun.put({not: true});\n\t\t});\n\n\t\tit.skip('implicit put on empty get explicit not', function(done){ // HUH? This seems like wrong behavior.\n\t\t\tvar gun = Gun().get('init/not').not();\n\t\t\tgun.on(function(val){\n\t\t\t\tconsole.log(\"??\", val);\n\t\t\t\tdone.c = 1;\n\t\t\t});\n\t\t\tgun.put({not: true});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t},1);\n\t\t});\n\n\t\tit('no implicit put on empty get', function(done){\n\t\t\tvar gun = Gun({init: true}).get('not/init');\n\t\t\tgun.on(function(val){\n\t\t\t\tconsole.log(\"hmmm???\", val);\n\t\t\t\texpect(val.not).to.be(true);\n\t\t\t\tif(done.c){ return } done.c = 1;\n\t\t\t});\n\t\t\tgun.put({not: true});\n\t\t\tsetTimeout(function(){\n\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t},1);\n\t\t});\n\n\t\tit('no implicit put on empty get explicit init', function(done){\n\t\t\tvar gun = Gun({init: true}).get('not/init/init').init();\n\t\t\tgun.on(function(val){\n\t\t\t\tif(val.not){\n\t\t\t\t\texpect(val.not).to.be(true);\n\t\t\t\t\tif(done.c){return}\n\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(Gun.obj.empty(val, '_')).to.be.ok();\n\t\t\t});\n\t\t\tgun.put({not: true})\n\t\t});\n\n\t\tit('init', function(done){\n\t\t\tvar gun = Gun().get('init/todo').init();\n\t\t\tgun.on(function(val){\n\t\t\t\tconsole.log(\"*******\", val);\n\t\t\t\tif(done.c){return}\n\t\t\t\tif(val.data){\n\t\t\t\t\texpect(val.data).to.be('initialized!');\n\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\texpect(Gun.obj.empty(val, '_')).to.be.ok();\n\t\t\t});\n\t\t\tgun.put({data: 'initialized!'});\n\t\t});\n\n\t\tdescribe('map able', function(){\n\n\t\t\tit('map chain', function(done){\n\t\t\t\tGun().put({a:1, b:2}).map().on(function(v,f){\n\t\t\t\t\tdone[f] = v;\n\t\t\t\t\tif(done.a && done.b){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('map chain after', function(done){\n\t\t\t\tvar g = Gun().get('m/c/a');\n\t\t\t\tg.map().on(function(v,f){\n\t\t\t\t\tdone[f] = v;\n\t\t\t\t\tif(done.a && done.b){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tg.put({a:1, b:2});\n\t\t\t});\n\n\t\t\tit('map chain map to', function(done){\n\t\t\t\tvar g = Gun().get('m/c/m/to');\n\t\t\t\tvar obj = {\n\t\t\t\t\ta: {x: 1, y: 2, z: 3},\n\t\t\t\t\tb: {u: 4, v: 5, w: 6}\n\t\t\t\t}, check = {x:1,y:1,z:1,u:1,v:1,w:1};\n\t\t\t\tg.map().map().on(function(v,f){\n\t\t\t\t\tcheck[f] = 0;\n\t\t\t\t\tif(Gun.obj.map(check, function(v,f){if(v){return true}})){return}\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tg.put(obj);\n\t\t\t\t},110);\n\t\t\t});\n\n\t\t\tit('map chain map', function(done){\n\t\t\t\tvar g = Gun().get('m/c/m');\n\t\t\t\tvar obj = {\n\t\t\t\t\ta: {x: 1, y: 2, z: 3},\n\t\t\t\t\tb: {u: 4, v: 5, w: 6}\n\t\t\t\t}, check = {x:1,y:1,z:1,u:1,v:1,w:1};\n\t\t\t\tg.map().map().on(function(v,f){\n\t\t\t\t\tcheck[f] = 0;\n\t\t\t\t\tif(Gun.obj.map(check, function(v,f){if(v){return true}})){return}\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t\tg.put(obj);\n\t\t\t});\n\n\t\t\tit('map chain map before', function(done){\n\t\t\t\tvar g = Gun().get('m/c/m/b');\n\t\t\t\tvar obj = {\n\t\t\t\t\ta: {x: 1, y: 2, z: 3},\n\t\t\t\t\tb: {u: 4, v: 5, w: 6}\n\t\t\t\t}, check = {x:1,y:1,z:1,u:1,v:1,w:1};\n\t\t\t\tg.put(obj);\n\t\t\t\tg.map().map().on(function(v,f){\n\t\t\t\t\tcheck[f] = 0;\n\t\t\t\t\tif(Gun.obj.map(check, function(v,f){if(v){return true}})){return}\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit('init todo', function(done){\n\t\t\tvar gun = Gun(), todo = gun.get('init/todo/early');\n\t\t\ttodo.path('random1').put('eat chocolate');\n\t\t\ttodo.map().on(function(val, field){\n\t\t\t\texpect(val).to.be('eat chocolate');\n\t\t\t\texpect(field).to.be('random1');\n\t\t\t\tif(done.c){ return } done(); done.c = 1;\n\t\t\t});\n\t\t});\n\n\t\tit('init todo defer', function(done){\n\t\t\tvar gun = Gun(), todo = gun.get('init/todo/defer');\n\t\t\ttodo.map().on(function(val, field){\n\t\t\t\texpect(val).to.be('eat chocolate');\n\t\t\t\texpect(field).to.be('random1');\n\t\t\t\tif(done.c){ return } done(); done.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\ttodo.path('random1').put('eat chocolate');\n\t\t\t}, 100);\n\t\t});\n\n\t\t/* // CHANGELOG: API 0.3 BREAKING CHANGE, .set has been deprecated!\n\t\tit('set', function(done){\n\t\t\tdone.c = 0;\n\t\t\tvar u, gun = Gun();\n\t\t\tgun.get('set').set().set().once(function(val){\n\t\t\t\tvar keynode = gun.__.graph['set'];\n\t\t\t\texpect(Gun.node.soul.ify(keynode, '.')).to.be.ok();\n\t\t\t\tGun.is.node(keynode, function(rel, soul){\n\t\t\t\t\trel = gun.__.by(soul).node;\n\t\t\t\t\texpect(Gun.obj.empty(rel, Gun._.meta)).to.be.ok();\n\t\t\t\t});\n\t\t\t\tdone.c += 1;\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\texpect(done.c).to.be(1);\n\t\t\t\t\tdone()\n\t\t\t\t},10);\n\t\t\t});\n\t\t});\n\n\t\tit('root set', function(done){\n\t\t\tvar gun = Gun().set();\n\t\t\tgun.on(function(val, field){\n\t\t\t\texpect(Gun.obj.empty(val, Gun._.meta)).to.be.ok();\n\t\t\t\tif(done.c){return} done(); done.c = 1;\n\t\t\t});\n\t\t});\n\n\t\t// TODO: BUG! We need 2 more tests... without .set()... and multiple paths on the same node.\n\t\tit('set multiple', function(done){ // kinda related to flip flop?\n\t\t\tvar gun = Gun().get('sets').set(), i = 0;\n\t\t\tgun.once(function(val){\n\t\t\t\tconsole.log(\"TEST 1\", val);\n\t\t\t\texpect(Gun.obj.empty(val, Gun._.meta)).to.be.ok();\n\t\t\t\texpect(Gun.node.soul(val)).to.be('sets');\n\t\t\t\tvar keynode = gun.__.graph['sets'];\n\t\t\t\texpect(Gun.obj.empty(keynode, Gun._.meta)).to.not.be.ok();\n\t\t\t});\n\t\t\tgun.set(1); //.set(2).set(3).set(4); // if you set an object you'd have to do a `.back`\n\t\t\tgun.map(function(val, field){\n\t\t\t//gun.map().once(function(val, field){ // TODO: SEAN! DON'T LET ME FORGET!\n\t\t\t\tconsole.log(\"\\n TEST 2+\", field, val);\n\t\t\t\treturn;\n\t\t\t\ti += 1;\n\t\t\t\texpect(val).to.be(i);\n\t\t\t\tif(i % 4 === 0){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tdone.i = 0;\n\t\t\t\t\t\tGun.obj.map(gun.__.graph, function(){ done.i++ });\n\t\t\t\t\t\texpect(done.i).to.be(1); // make sure there isn't double.\n\t\t\t\t\t\tGun.log.verbose = false;\n\t\t\t\t\t\tdone()\n\t\t\t\t\t},10);\n\t\t\t\t}\n\t\t\t});\n\t\t\tgun.set(2);\n\t\t});\n\t\t*/\n\n\t\tit('val should not print relation', function(done){ // #132\n\t\t\tvar users = Gun().get('example').path('users');\n\t\t\tusers.path(Gun.text.random()).put('bob');\n\t\t\tusers.path(Gun.text.random()).put('sam');\n\t\t\tsetTimeout(function(){\n\t\t\t\tusers.once(function(v){\n\t\t\t\t\texpect(Gun.val.link.is(v)).to.not.be.ok();\n\t\t\t\t\texpect(Object.keys(v).length).to.be(3);\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t},100);\n\t\t});\n\n\t\tit('peer 1 get key, peer 2 put key, peer 1 val', function(done){\n\t\t\tvar hooks = {get: function(key, cb, opt){\n\t\t\t\tcb();\n\t\t\t}, put: function(nodes, cb, opt){\n\t\t\t\tGun.union(gun1, nodes);\n\t\t\t\tcb();\n\t\t\t}},\n\t\t\tgun1 = Gun({wire: {get: hooks.get}}).get('race')\n\t\t\t, gun2 = Gun({wire: hooks}); //.get('race');\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun2.put({the: 'data'}).key('race');\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tgun1.on(function(val){\n\t\t\t\t\t\texpect(val.the).to.be('data');\n\t\t\t\t\t\tif(done.c){ return } done(); done.c = 1;\n\t\t\t\t\t});\n\t\t\t\t},10);\n\t\t\t},10);\n\t\t});\n\n\t\tit('get pseudo merge', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.put({a: 1, z: -1}).key('pseudo');\n\t\t\tgun.put({b: 2, z: 0}).key('pseudo');\n\n\t\t\tgun.get('pseudo').once(function(val){\n\t\t\t\texpect(val.a).to.be(1);\n\t\t\t\texpect(val.b).to.be(2);\n\t\t\t\texpect(val.z).to.be(0);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get pseudo merge on', function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tgun.put({a: 1, z: -1}).key('pseudon');\n\t\t\tgun.put({b: 2, z: 0}).key('pseudon');\n\n\t\t\tgun.get('pseudon').on(function(val){\n\t\t\t\tif(done.val){ return } // TODO: Maybe prevent repeat ons where there is no diff? (may not happen to after 1.0.0)\n\t\t\t\tdone.val = val;\n\t\t\t\texpect(val.a).to.be(1);\n\t\t\t\texpect(val.b).to.be(2);\n\t\t\t\texpect(val.z).to.be(0);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit.skip('get pseudo merge across peers', function(done){ // TODO: These tests should be replaced with PANIC tests!\n\t\t\t// ctx.halt\n\t\t\tvar acb, bcb, ag, bg;\n\t\t\tGun.on('opt').event(function(gun, o){\n\t\t\t\tif(connect){ return }\n\t\t\t\tgun.__.opt.wire = {get: function(key, cb, opt){\n\t\t\t\t\tkey = key['#'];\n\t\t\t\t\tif(o.alice){ acb = cb; ag = gun.__.graph; } else { bcb = cb; bg = gun.__.graph; }\n\t\t\t\t\tvar other = (o.alice? gun2 : gun1);\n\t\t\t\t\tif(connect){\n\t\t\t\t\t\tvar node = other.__.graph[key];\n\t\t\t\t\t\tcb(null, node);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcb();\n\t\t\t\t\t}\n\t\t\t\t}, put: function(nodes, cb, opt){\n\t\t\t\t\tvar other = (o.alice? gun2 : gun1);\n\t\t\t\t\tif(connect){\n\t\t\t\t\t\tGun.union(other, nodes);\n\t\t\t\t\t}\n\t\t\t\t\tcb();\n\t\t\t\t}}\n\t\t\t});\n\t\t\tfunction pushAtoB(key){\n\t\t\t\tvar node = ag[key];\n\t\t\t\tbcb(null, node);\n\t\t\t}\n\t\t\tfunction pushBtoA(key){\n\t\t\t\tvar node = bg[key];\n\t\t\t\tacb(null, node);\n\t\t\t}\n\t\t\tvar connect, gun1 = Gun({alice: true}).get('pseudo/merge').put({hello: 'world!'})/*.not(function(key){\n\t\t\t\tthis.put({hello: \"world!\"}).key(key);\n\t\t\t})*/, gun2;\n\t\t\tgun1.once(function(val){\n\t\t\t\texpect(val.hello).to.be('world!');\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun2 = Gun({bob: true}).get('pseudo/merge').put({hi: 'mars!'})/*.not(function(key){\n\t\t\t\t\tthis.put({hi: \"mars!\"}).key(key);\n\t\t\t\t});*/\n\t\t\t\tgun2.once(function(val){\n\t\t\t\t\texpect(val.hi).to.be('mars!');\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t// CONNECT THE TWO PEERS\n\t\t\t\t\tconnect = true;\n\t\t\t\t\tpushBtoA('pseudo/merge');\n\t\t\t\t\tpushAtoB('pseudo/merge');\n\t\t\t\t\t//gun1.get('pseudo/merge', null, {force: true}); // fake a browser refersh, in real world we should auto-reconnect\n\t\t\t\t\t//gun2.get('pseudo/merge', null, {force: true}); // fake a browser refersh, in real world we should auto-reconnect\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tgun1.once(function(val){\n\t\t\t\t\t\t\texpect(val.hello).to.be('world!');\n\t\t\t\t\t\t\texpect(val.hi).to.be('mars!');\n\t\t\t\t\t\t\tdone.g1 = true;\n\t\t\t\t\t\t});\n\t\t\t\t\t\t//return;\n\t\t\t\t\t\tgun2.once(function(val){\n\t\t\t\t\t\t\texpect(val.hello).to.be('world!');\n\t\t\t\t\t\t\texpect(val.hi).to.be('mars!');\n\t\t\t\t\t\t\texpect(done.g1).to.be.ok();\n\t\t\t\t\t\t\tGun({});\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t});\n\t\t\t\t\t},10);\n\t\t\t\t},10);\n\t\t\t},10);\n\t\t});\n\n\t\tit(\"get map val -> map val\", function(done){ // Terje's bug\n\t\t\tvar gun = Gun(); // we can test GUN locally.\n\t\t\tvar passengers = gun.get('passengers').not(function(key){\n\t\t\t\tthis.put({'randombob': {\n\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\tlocation: {'lat': '37.6159', 'lng': '-128.5'},\n\t\t\t\t\tdirection: '128.2'\n\t\t\t\t}, 'randomfred': {\n\t\t\t\t\tname: \"Fred\",\n\t\t\t\t\tlocation: {'lat': 'f37.6159', 'lng': 'f-128.5'},\n\t\t\t\t\tdirection: 'f128.2'\n\t\t\t\t}}).key(key);\n\t\t\t}); // this is now a list of passengers that we will map over.\n\t\t\tvar ctx = {n: 0, d: 0, l: 0};\n\t\t\tpassengers.map().once(function(passenger, id){\n\t\t\t\tthis.map().once(function(change, field){\n\t\t\t\t\tif('name' == field){ expect(change).to.be(passenger.name); ctx.n++ }\n\t\t\t\t\tif('direction' == field){ expect(change).to.be(passenger.direction); ctx.d++ }\n\t\t\t\t\tif('location' == field){\n\t\t\t\t\t\tdelete change._; ctx.l++;\n\t\t\t\t\t\tif('Bob' == passenger.name){\n\t\t\t\t\t\t\texpect(change).to.eql({'lat': '37.6159', 'lng': '-128.5'});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\texpect(change).to.eql({'lat': 'f37.6159', 'lng': 'f-128.5'});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(ctx.n == 2 && ctx.d == 2 && ctx.l == 2){ done() }\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit(\"put map update sub\", function(done){\n\t\t\tvar g = Gun();\n\t\t\tvar list = gun.get('map/sub');\n\t\t\tlist.put({a: {x:1}, b: {y: 1}});\n\t\t\tvar check = {};\n\t\t\tlist.map().on(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(done.c){return}\n\t\t\t\tif(check.a && check.b && check.a.w){\n\t\t\t\t\texpect(check.a.x).to.be(1);\n\t\t\t\t\texpect(check.b.y).to.be(1);\n\t\t\t\t\texpect(check.a.w).to.be(2);\n\t\t\t\t\tdone.c=1;\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tlist.path('a').path('w').put(2);\n\t\t});\n\n\t\tit(\"put map update sub val\", function(done){\n\t\t\tvar g = Gun();\n\t\t\tvar list = gun.get('map/sub/val');\n\t\t\tlist.put({a: {x:1}, b: {y: 1}});\n\t\t\tlist.path('a').path('w').put(2);\n\t\t\tvar check = {};\n\t\t\tlist.map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tconsole.log(\"*************************\", f,v);\n\t\t\t\tif(check.a && check.b){\n\t\t\t\t\texpect(check.a.w).to.be(2);\n\t\t\t\t\texpect(check.a.x).to.be(1);\n\t\t\t\t\texpect(check.b.y).to.be(1);\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t}, {wait: 400});\n\t\t});\n\n\t\tit(\"put map update sub val after\", function(done){\n\t\t\tvar g = Gun();\n\t\t\tvar list = gun.get('map/sub/val/after');\n\t\t\tvar check = {};\n\t\t\tlist.map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(check.a && check.b){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\texpect(check.a.x).to.be(1);\n\t\t\t\t\t\texpect(check.b.y).to.be(1);\n\t\t\t\t\t\texpect(check.a.w).to.not.be.ok();\n\t\t\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\t},400);\n\t\t\t\t}\n\t\t\t});\n\t\t\tlist.put({a: {x:1}, b: {y: 1}});\n\t\t\tsetTimeout(function(){\n\t\t\t\tlist.path('a').path('w').put(2);\n\t\t\t},300);\n\t\t});\n\n\t\tit(\"put map update sub val after to\", function(done){\n\t\t\tvar g = Gun();\n\t\t\tvar list = gun.get('map/sub/val/after/to');\n\t\t\tvar check = {};\n\t\t\tlist.map().once(function(v,f){\n\t\t\t\t//console.log(\"*************\", f,v);return;\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(check.a && check.b){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\texpect(check.a.x).to.be(1);\n\t\t\t\t\t\texpect(check.b.y).to.be(1);\n\t\t\t\t\t\texpect(check.a.w).to.be(2);\n\t\t\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\t},200);\n\t\t\t\t}\n\t\t\t});\n\t\t\tlist.put({a: {x:1}, b: {y: 1}});\n\t\t\tlist.path('a').path('w').put(2);\n\t\t});\n\n\t\tit(\"put map simple after\", function(done){\n\t\t\tvar g = Gun();\n\t\t\tvar list = gun.get('map/simple/after');\n\t\t\tvar check = {};\n\t\t\tlist.map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(check.a && check.b){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\texpect(check.a).to.be(2);\n\t\t\t\t\t\texpect(check.b).to.be(1);\n\t\t\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\t},200);\n\t\t\t\t}\n\t\t\t});\n\t\t\tlist.put({a: 1, b: 1});\n\t\t\tlist.path('a').put(2);\n\t\t});\n\n\t\tit(\"put map simple after to\", function(done){\n\t\t\tvar g = Gun();\n\t\t\tvar list = gun.get('map/simple/after/to');\n\t\t\tvar check = {};\n\t\t\tlist.map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(check.a && check.b){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\texpect(check.a).to.be(1);\n\t\t\t\t\t\texpect(check.b).to.be(1);\n\t\t\t\t\t\texpect(done.c).to.not.be.ok();\n\t\t\t\t\t\tdone();done.c=1;\n\t\t\t\t\t},200);\n\t\t\t\t}\n\t\t\t});\n\t\t\tlist.put({a: 1, b: 1});\n\t\t\tsetTimeout(function(){\n\t\t\t\tlist.path('a').put(2);\n\t\t\t},300);\n\t\t});\n\n\t\tit(\"put map\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('map/that');\n\t\t\tvar put = gun.put({a: 1, b: 2, c: 3}).key('map/that');\n\t\t\tget.map(function(v,f){\n\t\t\t\tif(1 === v){ done.a = true }\n\t\t\t\tif(2 === v){ done.b = true }\n\t\t\t\tif(3 === v){ done.c = true }\n\t\t\t\tif(done.a && done.b && done.c){\n\t\t\t\t\tif(done.done){ return }\n\t\t\t\t\tdone(); done.done = 1;\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit(\"put map before\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar get = gun.get('map/that/before');\n\t\t\tget.map(function(v,f){\n\t\t\t\tif(1 === v){ done.a = true }\n\t\t\t\tif(2 === v){ done.b = true }\n\t\t\t\tif(3 === v){ done.c = true }\n\t\t\t\tif(done.a && done.b && done.c){\n\t\t\t\t\tif(done.done){ return }\n\t\t\t\t\tdone(); done.done = 1;\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar put = get.put({a: 1, b: 2, c: 3});\n\t\t});\n\n\t\tit(\"get map map val\", function(done){ // Terje's bug\n\t\t\tvar gun = Gun(/*{init: true}*/); // we can test GUN locally.\n\t\t\tvar passengers = gun.get('passengers/map').not(function(key){\n\t\t\t\tgun.put({randombob: {\n\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\tlocation: {'lat': '37.6159', 'lng': '-128.5'},\n\t\t\t\t\tdirection: '128.2'\n\t\t\t\t}}).key(key);\n\t\t\t}); // this is now a list of passengers that we will map over.\n\t\t\tvar ctx = {n: 0, d: 0, l: 0};\n\t\t\tpassengers.map().map().once(function(val, field){\n\t\t\t\tif('name' == field){ expect(val).to.be(!ctx.n? 'Bob' : 'Fred'); ctx.n++ }\n\t\t\t\tif('direction' == field){ expect(val).to.be(!ctx.d? '128.2' : 'f128.2'); ctx.d++ }\n\t\t\t\tif('location' == field){\n\t\t\t\t\tdelete val._;\n\t\t\t\t\tif(!ctx.l){\n\t\t\t\t\t\texpect(val).to.eql({'lat': '37.6159', 'lng': '-128.5'});\n\t\t\t\t\t} else {\n\t\t\t\t\t\texpect(val).to.eql({'lat': 'f37.6159', 'lng': 'f-128.5'});\n\t\t\t\t\t}\n\t\t\t\t\tctx.l++;\n\t\t\t\t}\n\t\t\t\tif(ctx.n == 2 && ctx.d == 2 && ctx.l == 2){ done() }\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tpassengers.put({randomfred: {\n\t\t\t\t\tname: \"Fred\",\n\t\t\t\t\tlocation: {'lat': 'f37.6159', 'lng': 'f-128.5'},\n\t\t\t\t\tdirection: 'f128.2'\n\t\t\t\t}});\n\t\t\t},400);\n\t\t});\n\n\t\tit(\"not before map deep after conflict\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.get('n/b/l/a/c').not(function(k){\n\t\t\t\tconsole.log(\"not\", k);\n\t\t\t\tgun.put({\n\t\t\t\t\ta: {\n\t\t\t\t\t\tx:1,\n\t\t\t\t\t\ty:1\n\t\t\t\t\t}\n\t\t\t\t}).key('n/b/l/a/c');\n\t\t\t});\n\t\t\tvar check = {a:{},b:{}}, F = 'a';\n\t\t\tg.map().map().once(function(v,f){\n\t\t\t\tvar c = check[F];\n\t\t\t\tc[f] = v;\n\t\t\t\tif(check.b && check.b.x && check.b.y){\n\t\t\t\t\texpect(check.a.x).to.be(1);\n\t\t\t\t\texpect(check.a.y).to.be(1);\n\t\t\t\t\texpect(check.b.x).to.be(1);\n\t\t\t\t\texpect(check.b.y).to.be(1);\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tF = 'b';\n\t\t\t\tg.put({b: {x:1,y:1}});\n\t\t\t},400);\n\t\t});\n\n\t\tit(\"not before map deep after\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.get('n/b/l/a').not(function(k){\n\t\t\t\tconsole.log(\"not\", k);\n\t\t\t\tgun.put({\n\t\t\t\t\ta: {\n\t\t\t\t\t\tx:1,\n\t\t\t\t\t\ty:1\n\t\t\t\t\t}\n\t\t\t\t}).key('n/b/l/a');\n\t\t\t});\n\t\t\tvar check = {};\n\t\t\tg.map().map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(check.x && check.y && check.w && check.u){\n\t\t\t\t\texpect(check.x).to.be(1);\n\t\t\t\t\texpect(check.y).to.be(1);\n\t\t\t\t\texpect(check.w).to.be(1);\n\t\t\t\t\texpect(check.u.deep).to.be(true);\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tg.put({b: {w:1,u:{deep:true}}});\n\t\t\t},400);\n\t\t});\n\n\t\tit(\"before map after\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.get('b/l/a');\n\t\t\tg.put({a: {x:1,y:1}});\n\t\t\tvar check = {};\n\t\t\tg.map().map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(check.x && check.y && check.w && check.u && check.z){\n\t\t\t\t\texpect(check.x).to.be(1);\n\t\t\t\t\texpect(check.w).to.be(1);\n\t\t\t\t\texpect(check.u).to.be(1);\n\t\t\t\t\texpect(check.y).to.be(2);\n\t\t\t\t\texpect(check.z).to.be(1);\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tg.put({b: {w:1,u:1,y:2,z:1}});\n\t\t\t},150);\n\t\t});\n\n\t\tit(\"before map deep after\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.get('b/d/l/a');\n\t\t\tg.put({a: {x:1,y:1}});\n\t\t\tvar check = {};\n\t\t\tg.map().map().once(function(v,f){\n\t\t\t\tcheck[f] = v;\n\t\t\t\tif(check.x && check.y && check.w && check.u){\n\t\t\t\t\texpect(check.x).to.be(1);\n\t\t\t\t\texpect(check.y).to.be(1);\n\t\t\t\t\texpect(check.w).to.be(1);\n\t\t\t\t\texpect(check.u.deep).to.be(true);\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tg.put({b: {w:1,u:{deep:true}}});\n\t\t\t},150);\n\t\t});\n\n\t\tit(\"get map map map map\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.get('m/m/m/m');\n\t\t\tconsole.log(\" // TODO: BUG!!! If you make them have the same fields, they do not both iterate.\");\n\t\t\tg.put({\n\t\t\t\ta: {\n\t\t\t\t\tb: {\n\t\t\t\t\t\tc: {\n\t\t\t\t\t\t\td: 1,\n\t\t\t\t\t\t\te: 2,\n\t\t\t\t\t\t\tf: 3\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tu: {\n\t\t\t\t\tv: {\n\t\t\t\t\t\tw: {\n\t\t\t\t\t\t\td: 1,\n\t\t\t\t\t\t\te: 2,\n\t\t\t\t\t\t\tf: 3\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar check = {};\n\t\t\tg.map().map().map().map().once(function(v,f){\n\t\t\t\tcheck[f] = (check[f] || 0) + 1;\n\t\t\t\tif(check.d === 2 && check.e === 2 && check.f === 2){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit(\"get users map path path any\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar check = {};\n\t\t\tgun.get('g/n/m/f').map().path('spouse').path('work').any(function(e,v,f){\n\t\t\t\tconsole.log(\"********\", f,v, this);\n\t\t\t\tcheck[v.name] = true;\n\t\t\t\tif(check[\"ACME INC\"] && check[\"GUN INC\"]){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tgun.put({_:{'#':'g/n/m/f'},\n\t\t\t\talice: {\n\t\t\t\t\tname: \"alice\",\n\t\t\t\t\tage: 24,\n\t\t\t\t\tspouse: {\n\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbout: {huh:1}\n\t\t\t\t},\n\t\t\t\tbob: {\n\t\t\t\t\tname: \"bob\",\n\t\t\t\t\tage: 26,\n\t\t\t\t\tspouse: {\n\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\n\t\tit(\"get users map path path val after\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({_:{'#':'g/n/m/f/a'},\n\t\t\t\talice: {\n\t\t\t\t\tname: \"alice\",\n\t\t\t\t\tage: 24,\n\t\t\t\t\tspouse: {\n\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbout: {huh:1}\n\t\t\t\t},\n\t\t\t\tbob: {\n\t\t\t\t\tname: \"bob\",\n\t\t\t\t\tage: 26,\n\t\t\t\t\tspouse: {\n\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\t//console.debug.i=1;console.log(\"----------------------\");\n\t\t\t\tvar check = {};\n\t\t\t\tgun.get('g/n/m/f/a').map().path('spouse').path('work').any(function(e,v,f){\n\t\t\t\t\tconsole.log(\"********\", f,v, this);\n\t\t\t\t\tcheck[v.name] = true;\n\t\t\t\t\tif(check[\"ACME INC\"] && check[\"GUN INC\"]){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},100);\n\t\t});\n\n\t\tit(\"get users map path path any later\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tgun.get('g/n/m/f/l').map().path('spouse').path('work');\n\t\t\tgun.put({_:{'#':'g/n/m/f/l'},\n\t\t\t\talice: {\n\t\t\t\t\tname: \"alice\",\n\t\t\t\t\tage: 24,\n\t\t\t\t\tspouse: {\n\t\t\t\t\t\tname: \"carl\",\n\t\t\t\t\t\tage: 25,\n\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\tname: \"GUN INC\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tbout: {huh:1}\n\t\t\t\t},\n\t\t\t\tbob: {\n\t\t\t\t\tname: \"bob\",\n\t\t\t\t\tage: 26,\n\t\t\t\t\tspouse: {\n\t\t\t\t\t\tname: \"diana\",\n\t\t\t\t\t\tage: 27,\n\t\t\t\t\t\twork: {\n\t\t\t\t\t\t\tname: \"ACME INC\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar work = {};\n\t\t\t\tconsole.log(\"..........\", gun);\n\t\t\t\treturn;\n\t\t\t\tgun.get('g/n/m/f').map().path('spouse').path('work').any(function(e,v,f){\n\t\t\t\t\tconsole.log(\"********\", f,v, this);\n\t\t\t\t\treturn;\n\t\t\t\t\tcheck[v.name] = true;\n\t\t\t\t\tif(check[\"ACME INC\"] && check[\"GUN INC\"]){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},100);\n\t\t});\n\n\t\tit(\"get graph node field ref\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({data: {a: 1, b: 2}}, null, 'g/n/f')\n\t\t\tconsole.debug.i=1;console.log(\"-----------------\");\n\t\t\tgun.get('g/n/f').path('data').path('a').any(function(b,a){\n\t\t\t\tconsole.log(\":D\", a,b);\n\t\t\t\texpect(a).to.be(1);\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\treturn;\n\t\tit(\"get map path val\", function(done){ // Terje's bug\n\t\t\tvar gun = Gun();\n\t\t\tvar ctx = {l: -1, d: 0};\n\t\t\tvar passengers = gun.get('passengers/path').not(function(key){\n\t\t\t\tthis.put({randombob: {\n\t\t\t\t\tname: \"Bob\",\n\t\t\t\t\tlocation: {'lat': '37.6159', 'lng': '-128.5'},\n\t\t\t\t\tdirection: '128.2'\n\t\t\t\t}}).key(key);\n\t\t\t});\n\t\t\tpassengers.map().path('location.lng').once(function(val, field){\n\t\t\t//passengers.map().path('location.lng').on(function(val, field){\n\t\t\t\tconsole.log(\"******\", field, val);\n\t\t\t\texpect(field).to.be('lng');\n\t\t\t\tif(ctx.l){\n\t\t\t\t\texpect(val).to.be('-128.5');\n\t\t\t\t} else {\n\t\t\t\t\texpect(val).to.eql('f-128.5');\n\t\t\t\t}\n\t\t\t\tctx.l++;\n\t\t\t\tif(ctx.l){ done() }\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.debug.i=1;console.log(\"-------------------------------------\");\n\t\t\t\tpassengers.put({randomfred: {\n\t\t\t\t\tname: \"Fred\",\n\t\t\t\t\tlocation: {'lat': 'f37.6159', 'lng': 'f-128.5'},\n\t\t\t\t\tdirection: 'f128.2'\n\t\t\t\t}});\n\t\t\t},300);\n\t\t});\n\n\t\tit(\"FILT ER FILTER\", function(done){\n\t\t\tvar g = Gun();\n\t\t\tvar a = gun.put({});\n\t\t\tvar b = gun.put({age: 19, name: \"bob\"});\n\n\t\t\tconsole.debug.i=1;console.log(\"~~~~~~~~~~~~~~~~~~~~~~~~~\");\n\t\t\t(window.ALICE = a.filter()).path('spouse.name').on(function(a,b){\n\t\t\t\tconsole.log(\"1\", b,a);\n\t\t\t});\n\n\t\t\ta.put({age: 24, name: \"alice\", spouse: {name: \"carl\"}});\n\t\t\treturn;\n\t\t\tb.filter().on(function(a,b){\n\t\t\t\tconsole.log(\"2\", b,a);\n\t\t\t});\n\t\t});\n\n\t\tit(\"map path before\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.put({a: {x:1}, b: {x:2}, c: {x:3}});\n\t\t\tvar c = 0;\n\t\t\tvar m = g.map().path('x').on(function(v,f){\n\t\t\t\tconsole.log(\"*********************\", f,v);\n\t\t\t\tif(3 === ++c && 3 === v){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit(\"map path\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.get('map/path/ing');\n\t\t\tvar c = 0;\n\t\t\tvar m = g.map().path('x').on(function(v,f){\n\t\t\t\tif(3 === ++c && 3 === v){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tg.put({a: {x:1}, b: {x:2}, c: {x:3}});\n\t\t});\n\n\t\tit(\"map path path\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar g = gun.get('map/path/path/ing');\n\t\t\tvar c = 0;\n\t\t\tvar m = g.map().path('x.y').on(function(v,f){\n\t\t\t\t//console.log(\"Hmmmm\", f,v);\n\t\t\t\tif(3 === ++c && 3 === v){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tg.put({a: {x:{y:1}}, b: {x:{y:2}}, c: {x:{y:3}}});\n\t\t});\n\n\t\tit(\"put path deep val -> path val\", function(done){ // Terje's bug\n\t\t\tvar gun = Gun();\n\t\t\tgun.put({you: {have: {got: {to: {be: {kidding: \"me!\"}}}}}}).path('you.have.got.to.be').once(function(val, field){\n\t\t\t\texpect(val.kidding).to.be('me!');\n\t\t\t\tthis.path('kidding').once(function(val){\n\t\t\t\t\texpect(val).to.be('me!');\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit(\"get set path put, map path val -> path val\", function(done){ // Terje's bug\n\t\t\tvar gun = Gun();\n\t\t\tvar ctx = {l: -1, d: 0};\n\t\t\tvar passengers = gun; //.get('passengers/set/path');\n\t\t\tpassengers = passengers.put({randombob: {name: 'Bob', direction: {}}});\n\t\t\tpassengers.path('randombob.direction', function(err, ok, field){\n\t\t\t}).put({lol: {just: 'kidding', dude: '!'}});\n\t\t\tpassengers.map().path('direction.lol').once(function(val){\n\t\t\t\tthis.path('just').once(function(val){\n\t\t\t\t\texpect(val).to.be('kidding');\n\t\t\t\t}).back().path('dude').once(function(val){\n\t\t\t\t\texpect(val).to.be('!');\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t})\n\t\t});\n\n\t\tit('path rel should not slowdown', function(done){\n\t\t\tthis.timeout(5000);\n\t\t\tvar gun = Gun(/*gopt*/).put({\n\t\t\t  history: {}\n\t\t\t});\n\t\t\tvar prev, diff, max = 100, total = 20, largest = -1, gone = {};\n\t\t\tvar run = 0;\n\t\t\tgun.path('history').map(function(entry, index){\n\t\t\t\t//if(!entry){ return } // TODO: BUG! KNOWN BUG!!!!!!! FIX!!!!!\n\t\t\t\t++run;\n\t\t\t\tvar i = run+'';\n\t\t\t\texpect(i).to.be(index+'');\n\t\t\t\texpect(i).to.be(entry.x+'');\n\t\t\t\texpect(i).to.be(entry.y+'');\n\t\t\t\texpect(i).to.be(entry.direction+'');\n\t\t\t\texpect(entry.axis).to.be.ok();\n\t\t\t\texpect(entry.direction).to.be.ok();\n\t\t\t\tif(run > total){\n\t\t\t\t\tif(done.c){ return }\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t\tdone.c=true;\n\t\t\t\t\t},20);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t\t//console.log(\"THE GRAPH\\n\", gun.__.graph);\n\t\t\t  //expect(gone[index]).to.not.be.ok();\n\t\t\t\tgone[index] = diff;\n\t\t\t  diff = Gun.time.is() - (entry.time || prev);\n\t\t\t  largest = (largest < diff)? diff : largest;\n\t\t\t  //console.log('turn', turns, 'index', index, 'diff', diff, 'largest', largest);\n\t\t\t  expect(diff > max).to.not.be.ok();\n\t\t\t});\n\n\t\t\tvar turns = 0;\n\t\t\tvar many = setInterval(function(){\n\t\t\t\tif(turns > total || diff > (max + 5)){\n\t\t\t\t\t//console.log(\"was it\", turns > total, 'or', diff > (max + 5));\n\t\t\t\t\tclearTimeout(many);\n\t\t\t  \treturn;\n\t\t\t  \texpect(Gun.num.is(diff)).to.be.ok();\n\t\t\t  \tif(done.c){ return } done(); done.c = 1;\n\t\t\t  \treturn;\n\t\t\t  }\n\t\t\t  prev = Gun.time.is();\n\t\t\t  turns += 1;\n\t\t\t  var val = {\n\t\t\t    x: turns,\n\t\t\t    y: turns,\n\t\t\t    axis: 'y',\n\t\t\t    direction: turns,\n\t\t\t    time: prev\n\t\t\t  }\n\t\t\t  var put = {}; put[turns] = val;\n\t\t\t  gun.put({history: put});\n\t\t\t  //gun.path(['history', turns += 1]).put({\n\t\t\t},1);\n\t\t});\n\n\t\tit.skip('paths rel should not slowdown', function(done){ // TODO: NEED TO ADD THIS NEW TEST!\n\t\t\tthis.timeout(5000);\n\t\t\t//this.timeout(60000);\n\n\t\t\t//Gun.log.debug = 1; console.log(\"~~~~~ START ~~~~~~\");\n\t\t\tvar gun = Gun(gopt).put({\n\t\t\t  history: {}\n\t\t\t});\n\t\t\t//console.log(\"-------- DATA SET UP -----------\");\n\t\t\tvar prev, diff, max = 100, total = 100, largest = -1, gone = {};\n\t\t\tgun.path('history').map(function(entry, index){\n\t\t\t\t//if(!entry){ return } // TODO: BUG! KNOWN BUG!!!!!!! FIX!!!!!\n\t\t\t\t//console.log(\"WAT\", index, entry);\n\t\t\t\t//console.log(\"THE GRAPH\\n\", gun.__.graph);\n\t\t\t  //expect(gone[index]).to.not.be.ok();\n\t\t\t\tgone[index] = diff;\n\t\t\t  diff = Gun.time.is() - (entry.time || prev);\n\t\t\t  largest = (largest < diff)? diff : largest;\n\t\t\t  console.log('turn', turns, 'index', index, 'diff', diff, 'largest', largest);\n\t\t\t  expect(diff > max).to.not.be.ok();\n\t\t\t});\n\n\t\t\tvar turns = 0;\n\t\t\t//console.log(\"------------ PATH MAP SET UP --------------\");\n\t\t\tvar many = setInterval(function(){\n\t\t\t\tif(turns > total || diff > (max + 5)){\n\t\t\t  \tclearTimeout(many);\n\t\t\t  \texpect(Gun.num.is(diff)).to.be.ok();\n\t\t\t  \tif(done.c){ return } done(); done.c = 1;\n\t\t\t  \treturn;\n\t\t\t  }\n\t\t\t  prev = Gun.time.is();\n\t\t\t  Gun.log.base = Gun.log.ref = Gun.log.fer = prev;\n\t\t\t  //if(turns === 0){ Gun.log.debug = 1; console.log(\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\"); }\n\t\t\t  //console.log(\"-------------- \", turns + 1, \"-----------------\");\n\t\t\t  var val = {\n\t\t\t  \tTURN: turns + 1,\n\t\t\t    x: 1,\n\t\t\t    y: 1,\n\t\t\t    axis: 'y',\n\t\t\t    direction: 1,\n\t\t\t    time: prev\n\t\t\t  }\n\t\t\t  //var put = {}; put[turns += 1] = val;\n\t\t\t  //gun.put({history: put});\n\t\t\t  gun.path(['history', turns += 1]).put(val);\n\t\t\t},1);\n\t\t});\n\n\t\tit(\"gun get on, later gun put key\", function(done){\n\t\t\tvar gun = Gun();\n\n\t\t\tvar keyC = gun.get('keyC').on(function(val){\n\t\t\t\texpect(val.hello).to.be('world');\n\t\t\t\tif(done.done){ return }\n\t\t\t\tdone.done = true;\n\t\t\t\tdone();\n\t\t\t});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.put({hello: 'world'}).key('keyC');\n\t\t\t}, 100);\n\t\t});\n\n\t\tit('gun get put, sub path put, original val', function(done){ // bug from Jesse working on Trace //\n\t\t\tvar gun = Gun(gopt).get('players');\n\n\t\t\tgun.put({\n\t\t\t  taken: true,\n\t\t\t  history: {0: {}, 1: {}}\n\t\t\t});\n\n\t\t\tgun\n\t\t\t\t.path('history')\n\t\t\t\t.put(null)\n\t\t\t\t.back()\n\t\t\t\t.path('taken')\n\t\t\t\t.put(false)\n\n\t\t\t// TODO: BUG! There is a variation of this, where we just do `.val` rather than `gun.val` and `.val` by itself (chained off of the sub-paths) doesn't even get called. :(\n\t\t\tgun.on(function(players){ // this val is subscribed to the original put and therefore does not get any of the sub-path listeners, therefore it gets called EARLY with the original/old data rather than waiting for the sub-path data to \"finish\" and then get called.\n\t\t\t\texpect(players.history).to.be(null);\n\t\t\t\texpect(players.taken).to.be(false);\n\t\t\t\tif(done.c){ return } done(); done.c = 1;\n\t\t\t});\n\t\t});\n\n\t\tit(\"gun put recursive path slowdown\", function(done){\n\t\t\tthis.timeout(5000);\n\t\t\tvar gun = Gun();\n\t\t\tgun.__.opt.wire.put = null;\n\t\t\tfunction put(num, t) {\n\t\t\t\tvar now = new Date().getTime();\n\t\t\t\tvar cb;\n\t\t\t\tfor (var i = 1; i <= num; i++) {\n\t\t\t\t\tif (i === num) {\n\t\t\t\t\t\tcb = function (err, ok) {\n\t\t\t\t\t\t\tconsole.log(num + 'ops: ' + (new Date().getTime() - now)/1000 + 's');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tGun.ify({   //hello: 'world'}, cb);\n\t\t\t\t\t\tdeeply: {\n\t\t\t\t\t\t\tnested: i\n\t\t\t\t\t\t}\n\t\t\t\t\t})(cb);\n\t\t\t\t}\n\t\t\t\treturn new Date().getTime() - now;\n\t\t\t}\n\t\t\t/*\n\t\t\tput(1);\n\t\t\tput(2);\n\t\t\tput(10);\n\t\t\tput(50);\n\t\t\tput(100);\n\t\t\tput(1000);\n\t\t\tput(5000);*/\n\t\t\tput(1000, true);\n\n\t\t\tvar gun2 = Gun();\n\t\t\tgun2.__.opt.wire.put = null;\n\t\t\tfunction put2(num, t) {\n\t\t\t\tvar now = new Date().getTime();\n\t\t\t\tvar cb;\n\t\t\t\tfor (var i = 1; i <= num; i++) {\n\t\t\t\t\tif (i === num) {\n\t\t\t\t\t\tcb = function () {\n\t\t\t\t\t\t\tconsole.log(num + ' API ops: ' + (new Date().getTime() - now)/1000 + 's');\n\t\t\t\t\t\t\tt && done();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tgun2.put({  //hello: 'world'}, cb);\n\t\t\t\t\t\tdeeply: {\n\t\t\t\t\t\t\tnested: i\n\t\t\t\t\t\t}\n\t\t\t\t\t}, cb);\n\t\t\t\t}\n\t\t\t\treturn new Date().getTime() - now;\n\t\t\t}\n\t\t\tGun.log.start = Gun.time.is();\n\t\t\tput2(1);\n\t\t\tput2(1000); // TODO: BUG! Interesting! If you add another 0 it causes a stack overflow! If I make Gun.time.now() not recurse then it runs but takes 4x as long. Even on the 10k ops there seems to be about a 4x overhead with the API versus raw serializer.\n\t\t\tput2(1, true);\n\t\t\t//put2(2);\n\t\t\t//put2(10);\n\t\t\t//put2(50);\n\t\t\t//put2(100, true);\n\t\t\t//put2(5000, true);\n\t\t} );\n\n\t\tit('choke time.now by using a while loop', function(){\n\t\t\tvar i = 10; //100000; // causes an overflow.\n\t\t\twhile(--i){\n\t\t\t\tGun.time.now();\n\t\t\t}\n\t\t});\n\t\t/* // TODO: These tests should be deleted.\n\t\tit(\"test timeout\", function(done){ return done();\n\t\t\tvar i = 1000, start = Date.now();\n\t\t\twhile(i--){\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tconsole.log(\"ended in\", (Date.now() - start)/1000);\n\t\t\t\t},0);\n\t\t\t}\n\t\t\treturn;\n\t\t\t\tGun.schedule(start, function(){\n\t\t\t\t\tconsole.log(\"ended in\", (Date.now() - start)/1000);\n\t\t\t\t});\n\t\t\t\tsetImmediate(function(){\n\t\t\t\t\tconsole.log(\"ended in\", (Date.now() - start)/1000);\n\t\t\t\t});\n\t\t\t\tprocess.nextTick(function(){\n\t\t\t\t\tconsole.log(\"ended in\", (Date.now() - start)/1000);\n\t\t\t\t});\n\t\t});\n\t\tit(\"test assignment\", function(done){\n\t\t\tvar env = {graph: {}};\n\t\t\tfunction speed(other){\n\t\t\t\tvar i = 10000;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar $ = {soul: Gun.text.random()};\n\t\t\t\t\tvar at = {node: {_: {}}};\n\t\t\t\t\tvar obj = {\n\t\t\t\t\t\tdeeply: {\n\t\t\t\t\t\t\tnested: 'lol'\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tenv.graph[at.node._['#'] = at.soul = $.soul] = at.node\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar start = Date.now();\n\t\t\tspeed();\n\t\t\tconsole.log('wat', (Date.now() - start)/1000);\n\t\t});\n\t\tit(\"test fn call\", function(done){\n\t\t\tfunction speed(i, cb){\n\t\t\t\tvar r = 0;\n\t\t\t\twhile(i--){\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tcb(i);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tr += i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar start = Date.now();\n\t\t\tspeed(100000000);\n\t\t\tconsole.log('no fn', (Date.now() - start)/1000);\n\t\t\tvar start = Date.now(), r = 0;\n\t\t\tspeed(100000000, function(i){ r += i });\n\t\t\tconsole.log('w/ fn', (Date.now() - start)/1000);\n\t\t\tvar start = Date.now(), r = 0;\n\t\t\tfunction foo(i){ r += i }\n\t\t\tspeed(100000000, foo);\n\t\t\tconsole.log('w/ named fn', (Date.now() - start)/1000);\n\t\t});\n\t\tit(\"gun put recursive path slowdown MUTANT TEST\", function(done){\n\t\t\tthis.timeout(30000);\n\n\t\t\tGun.chain.put = function(val, cb, opt){\n\t\t\t\tvar gun = this.chain(), obj;\n\t\t\t\tvar drift = Gun.time.now(), call = {};\n\t\t\t\tcb = cb || function(){};\n\t\t\t\tgun._.at('soul').event(\n\t\t\t\t//(\n\t\t\t\tfunction($){\n\t\t\t\t\tvar chain = $.$ || gun;\n\t\t\t\t\tvar ctx = {}, obj = val, $ = Gun.obj.copy($);\n\t\t\t\t\tvar hash = $.field? $.soul + $.field : ($.from? $.from + ($.at || '') : $.soul);\n\t\t\t\t\tif(call[hash]){ return }\n\t\t\t\t\tgun.__.meta($.soul).put = true;\n\t\t\t\t\tcall[hash] = true;\n\t\t\t\t\tif(Gun.is.once(obj)){\n\t\t\t\t\t\tif($.from && $.at){\n\t\t\t\t\t\t\t$.soul = $.from;\n\t\t\t\t\t\t\t$.field = $.at;\n\t\t\t\t\t\t} // no else!\n\t\t\t\t\t\tif(!$.field){\n\t\t\t\t\t\t\treturn cb.call(gun, {err: Gun.log(\"No field exists for \" + (typeof obj) + \"!\")});\n\t\t\t\t\t\t} else\n\t\t\t\t\t\tif(gun.__.graph[$.soul]){\n\t\t\t\t\t\t\tctx.tmp = {};\n\t\t\t\t\t\t\tctx.tmp[ctx.field = $.field] = obj;\n\t\t\t\t\t\t\tobj = ctx.tmp;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn cb.call(gun, {err: Gun.log(\"No node exists to put \" + (typeof obj) + \" in!\")});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(Gun.obj.is(obj)){\n\t\t\t\t\t\tif($.field && !ctx.field){\n\t\t\t\t\t\t\tctx.tmp = {};\n\t\t\t\t\t\t\tctx.tmp[ctx.field = $.field] = obj;\n\t\t\t\t\t\t\tobj = ctx.tmp;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tGun.ify(obj || val, function(env, cb){\n\t\t\t\t\t\t\tvar at;\n\t\t\t\t\t\t\tif(!env || !(at = env.at) || !env.at.node){ return }\n\t\t\t\t\t\t\tif(!at.node._){\n\t\t\t\t\t\t\t\tat.node._ = {};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!Gun.node.soul(at.node)){\n\t\t\t\t\t\t\t\tif(obj === at.obj){\n\t\t\t\t\t\t\t\t\tenv.graph[at.node._['#'] = at.soul = $.soul] = at.node;\n\t\t\t\t\t\t\t\t\tcb(at, at.soul);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tfunction path(err, data){\n\t\t\t\t\t\t\t\t\t\tif(at.soul){ return }\n\t\t\t\t\t\t\t\t\t\tat.soul = Gun.node.soul(data) || Gun.node.soul(at.obj) || Gun.roulette.call(gun); // TODO: refactor Gun.roulette!\n\t\t\t\t\t\t\t\t\t\tenv.graph[at.node._['#'] = at.soul] = at.node;\n\t\t\t\t\t\t\t//var start = performance.now();\n\t\t\t\t\t\t\t\t\t\tcb(at, at.soul);\n\t\t\t\t\t\t\t//first = performance.now() - start;(first > .05) && console.log('here');\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t($.empty && !$.field)? path() : chain.back().path(at.path || [], path, {once: true, end: true}); // TODO: clean this up.\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t//var diff1 = (first - start), diff2 = (second - first), diff3 = (third - second);\n\t\t\t\t\t\t\t\t//(diff1 || diff2 || diff3) && console.log(diff1, '    ', diff2,  '    ', diff3);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!at.node._[Gun._.state]){\n\t\t\t\t\t\t\t\tat.node._[Gun._.state] = {};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!at.field){ return }\n\t\t\t\t\t\t\tat.node._[Gun._.state][at.field] = drift;\n\t\t\t\t\t\t})(function(err, ify){\n\t\t\t\t\t\t\t//console.log(\"chain.put PUT <----\", ify.graph, '\\n');\n\t\t\t\t\t\t\tif(err || ify.err){ return cb.call(gun, err || ify.err) }\n\t\t\t\t\t\t\tif(err = Gun.union(gun, ify.graph).err){ return cb.call(gun, err) }\n\t\t\t\t\t\t\tif($.from = Gun.val.link.is(ify.root[$.field])){ $.soul = $.from; $.field = null }\n\t\t\t\t\t\t\tGun.obj.map(ify.graph, function(node, soul){ Gun.union(gun, Gun.union.pseudo(soul)) });\n\t\t\t\t\t\t\tgun._.at('soul').emit({soul: $.soul, field: $.field, key: $.key, PUT: 'SOUL', WAS: 'ON'}); // WAS ON\n\t\t\t\t\t\t\t//return cb(null, true);\n\t\t\t\t\t\t\tif(Gun.fn.is(ctx.hook = gun.__.opt.hooks.put)){\n\t\t\t\t\t\t\t\tctx.hook(ify.graph, function(err, data){ // now iterate through those nodes to a persistence layer and get a callback once all are saved\n\t\t\t\t\t\t\t\t\tif(err){ return cb.call(gun, err) }\n\t\t\t\t\t\t\t\t\treturn cb.call(gun, null, data);\n\t\t\t\t\t\t\t\t}, opt);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t//console.Log(\"Warning! You have no persistence layer to save to!\");\n\t\t\t\t\t\t\t\tcb.call(gun, null); // This is in memory success, hardly \"success\" at all.\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tgun._.at('soul').emit({soul: Gun.roulette.call(gun), field: null, empty: true});\n\t\t\t\treturn gun;\n\t\t\t}\n\n\t\t\tvar gun = Gun(); //.get('bug').put({});\n\t\t\tgun.__.opt.hooks.put = null;\n\t\t\tfunction put(num, t) {\n\t\t\t\tvar now = new Date().getTime();\n\t\t\t\tvar cb;\n\t\t\t\tfor (var i = 1; i <= num; i++) {\n\t\t\t\t\tif (i === num) {\n\t\t\t\t\t\tcb = function (err, ok) {\n\t\t\t\t\t\t\tconsole.log(num + 'MUTANT ops: ' + (new Date().getTime() - now)/1000 + 's');\n\t\t\t\t\t\t\tt && done();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tgun.put({   //hello: 'world'}, cb);\n\t\t\t\t\t\tdeeply: {\n\t\t\t\t\t\t\tnested: i\n\t\t\t\t\t\t}\n\t\t\t\t\t}, cb);\n\t\t\t\t}\n\t\t\t\treturn new Date().getTime() - now;\n\t\t\t}\n\n\t\t\t//put(1, true);\n\t\t\t//put(2);\n\t\t\t//put(10);\n\t\t\t//put(50);\n\t\t\t//put(100);\n\t\t\t//put(1000);\n\t\t\t//put(5000);\n\t\t\tput(10000, true);\n\t\t});\n\t\t*/\n\t\tit(\"gun get empty set, path not -> this put\", function(done){ // Issue #99 #101, bug in survey and trace game.\n\t\t\tvar test = {c: 0}, u;\n\t\t\tvar gun = Gun();\n\t\t\tvar game = gun.get('some/not/yet/set/put/thing').not(function(key){\n\t\t\t\tgun.put({alias: {}}).key(key);\n\t\t\t});//.set();\n\t\t\tvar me = game.path('alias').on(function(val){\n\t\t\t\tif(!done.put){ return }\n\t\t\t\texpect(val).to.not.be(u);\n\t\t\t\texpect(val.a).to.be('b');\n\t\t\t\tvar meid = Gun.node.soul(val);\n\t\t\t\tvar self = this;\n\t\t\t\t/*\n\t\t\t\texpect(self === game).to.not.be.ok();\n\t\t\t\texpect(self === me).to.be.ok();\n\t\t\t\t*/\n\t\t\t\tif(done.c){ return } done(); done.c = 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tdone.put = true;\n\t\t\t\tme.put({a: 'b'});\n\t\t\t},100);\n\t\t});\n\n\t\tit(\"gun get empty set path empty later path put multi\", function(done){ // Issue #99 #101, bug in survey and trace game. // ctx.halt\n\t\t\tdone.c = 0;\n\t\t\tvar gun = Gun();\n\t\t\tvar data = gun.get('some/not/yet/set/put/thing/2');\n\t\t\tvar path = data.path('sub');\n\t\t\tfunction put(d, t, f){\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tpath.put(d, function(err, ok){\n\t\t\t\t\t\texpect(err).to.not.be.ok();\n\t\t\t\t\t\tdone.c++;\n\t\t\t\t\t\tif(f && done.c >= 3){\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t},t || 10);\n\t\t\t};\n\t\t\tput({on: 'bus', not: 'transparent'});\n\t\t\tput({on: null, not: 'torrent'}, 200);\n\t\t\tput({on: 'sub', not: 'parent'}, 250, true);\n\t\t});\n\n\t\tit(\"ToDo\", function(done){ // Simulate ToDo app!\n\t\t\tvar gun = Gun().get('example/todo/data');\n\t\t\tgun.on(function renderToDo(val){\n\t\t\t\tif(done.done){ return }\n\t\t\t\tif(done.clear){\n\t\t\t\t\tdone.done = true;\n\t\t\t\t\texpect(val[done.id]).to.not.be.ok();\n\t\t\t\t\treturn done();\n\t\t\t\t}\n\t\t\t\tdelete val._;\n\t\t\t\tGun.obj.map(val, function(val, field){ return done.id = field; });\n\t\t\t\texpect(val[done.id]).to.be('groceries');\n\t\t\t});\n\t\t\tsetTimeout(function(){ // form submit\n\t\t\t\tgun.path('random1').put(\"groceries\");\n\t\t\t\tsetTimeout(function(){ // clear off element\n\t\t\t\t\tdone.clear = true;\n\t\t\t\t\tgun.path(done.id).put(null);\n\t\t\t\t},100);\n\t\t\t},200);\n\t\t});\n\n\t\tit(\"gun put null path on put sub object\", function(done){ // consensus4's bug\n\t\t\tdone.c = 1;\n\t\t\tvar gun = Gun();\n\t\t\t//Gun.log.verbose = true;\n\t\t\tvar game = gun.put({board: null, teamA: null, teamB: null, turn: null}).key('the/game');\n\t\t\tgame.path('board').on(function(board, field){\n\t\t\t\texpect(field).to.be('board');\n\t\t\t\tif(done.c === 1){\n\t\t\t\t\texpect(board).to.not.be.ok();\n\t\t\t\t}\n\t\t\t\tif(done.c === 2){\n\t\t\t\t\tif(!board[11] || !board[22] || !board[33]){ return }\n\t\t\t\t\tdone.c++;\n\t\t\t\t\tdelete board._;\n\t\t\t\t\texpect(board).to.be.eql({11: ' ', 22: ' ', 33: 'A'});\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tdone.c++;\n\t\t\t\tgame.put({board: {11: ' ', 22: ' ', 33: 'A'}});\n\t\t\t},100);\n\t\t});\n\n\t\tit(\"get init put map -> put, foreach gun path map\", function(done){ // replicate Jesse's Trace game bug\n\t\t\tdone.c = 0;\n\t\t\tvar gun = Gun(gopt).opt({init: true})\n\t\t\t.get('players').init()\n\t\t\t.put({\n\t\t\t\t0: {\n\t\t\t\t\tnum: 0\n\t\t\t\t},\n\t\t\t\t1: {\n\t\t\t\t\tnum: 1\n\t\t\t\t},\n\t\t\t\t2: {\n\t\t\t\t\tnum: 2\n\t\t\t\t},\n\t\t\t\t3: {\n\t\t\t\t\tnum: 3\n\t\t\t\t}\n\t\t\t}, function(err,ok){\n\t\t\t\texpect(done.c++).to.be(0);\n\t\t\t}).once(function(p){\n\t\t\t\tdone.p = Gun.node.soul(p);\n\t\t\t\tdone.m = Gun.val.link.is(p[0]);\n\t\t\t\texpect(Gun.val.link.is(p[0])).to.be.ok();\n\t\t\t\texpect(Gun.val.link.is(p[1])).to.be.ok();\n\t\t\t\texpect(Gun.val.link.is(p[2])).to.be.ok();\n\t\t\t\texpect(Gun.val.link.is(p[3])).to.be.ok();\n\t\t\t})\n\n\t\t\tvar players = [], me;\n\t\t\tgun.map(function (player, number) {\n\t\t\t\tplayers[number] = player;\n\t\t\t\tplayers[number].history = [];\n\t\t\t\tif (!player.taken && !me) {\n\t\t\t\t\tthis.put({\n\t\t\t\t\t\ttaken: true,\n\t\t\t\t\t\thistory: {\n\t\t\t\t\t\t\t0: {x: 1, y: 2}\n\t\t\t\t\t\t}\n\t\t\t\t\t}, function(err,ok){});\n\t\t\t\t\tme = number;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t Gun.list.map([0, 1, 2, 3], function (player, number) {\n\t\t\t\tnumber = number - 1;\n\t\t\t\tgun\n\t\t\t\t\t.path(number + '.history')\n\t\t\t\t\t.map(function (entry, logNum) {\n\t\t\t\t\t\tdone.c++;\n\t\t\t\t\t\tplayers[number].history[logNum] = entry;\n\t\t\t\t\t\texpect(entry.x).to.be(1);\n\t\t\t\t\t\texpect(entry.y).to.be(2);\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\texpect(done.c).to.be(2);\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t},100);\n\t\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tit(\"gun get path empty val\", function(done){ // flip flop bug\n\t\t\tdone.c = 0;\n\t\t\tvar u;\n\t\t\tvar gun = Gun(gopt);\n\t\t\tvar game = gun.get('game1/players');\n\t\t\tvar me = game.path('player1').once(function(val){\n\t\t\t\tif(!done.c){ done.fail = true }\n\t\t\t\texpect(val).to.not.be(u);\n\t\t\t\texpect(val.x).to.be(0);\n\t\t\t\texpect(val.y).to.be(0);\n\t\t\t\texpect(done.fail).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tdone.c++;\n\t\t\t\texpect(done.fail).to.not.be.ok();\n\t\t\t\tme.put({x: 0, y: 0});\n\t\t\t},10);\n\t\t});\n\n\t\tit(\"gun get path empty on\", function(done){\n\t\t\tdone.c = 0;\n\t\t\tvar u;\n\t\t\tvar gun = Gun(gopt);\n\t\t\tvar game = gun.get('game2/players');\n\t\t\tvar me = game.path('player2').on(function(val){\n\t\t\t\tif(!done.c){ done.fail = true }\n\t\t\t\texpect(done.fail).to.not.be.ok();\n\t\t\t\texpect(val).to.not.be(u);\n\t\t\t\tif(done.done || !val.x || !val.y){ return } // it is okay if ON gets called many times, this protects against that.\n\t\t\t\t// TODO: although it would be nice if we could minimize the amount of duplications. (may not happen to after 1.0.0)\n\t\t\t\texpect(val.x).to.be(1);\n\t\t\t\texpect(val.y).to.be(1);\n\t\t\t\tdone.done = true;\n\t\t\t\tdone();\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tdone.c++;\n\t\t\t\texpect(done.fail).to.not.be.ok();\n\t\t\t\tme.put({x: 1, y: 1});\n\t\t\t},10);\n\t\t});\n\n\t\tit(\"gun get path empty not\", function(done){\n\t\t\tvar u;\n\t\t\tvar gun = Gun(gopt).opt({init: true})\n\t\t\tvar game = gun.get('game3/players').init();\n\t\t\tvar me = game.path('player3').not(function(field){\n\t\t\t\texpect(field).to.be('player3');\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit(\"gun get path empty init\", function(done){\n\t\t\tvar u;\n\t\t\tvar gun = Gun(gopt).opt({init: true});\n\t\t\tvar game = gun.get('game4/players').init();\n\t\t\tvar me = game.path('player4').init().path('alias').init().put({oh: 'awesome'}).once(function(val, field){\n\t\t\t\texpect(val.oh).to.be('awesome');\n\t\t\t\texpect(field).to.be('alias');\n\t\t\t\tdone();\n\t\t\t})\n\t\t});\n\n\t\tit(\"no invalid graph\", function(done){\n\t\t\tvar gun = Gun({wire:{\n\t\t\t\tput: function(graph){\n\t\t\t\t\texpect(Gun.is.graph(graph)).to.be.ok();\n\t\t\t\t\tif(done.c){ return } if(done.on){ done(); done.c = 1 }\n\t\t\t\t}\n\t\t\t}}).get('example/todo/data/graph');\n\t\t\tgun.on(function renderToDo(val){\n\t\t\t\tdone.on = true;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tgun.path(Gun.text.random()).put('hoorah');\n\t\t\t},100)\n\t\t});\n\n\t\tit(\"no undefined field\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar chat = gun.get('example/chat/data/graph/field').not(function(key){\n\t\t\t\tgun.put({1: {who: 'Welcome', what: \"to the chat app!\", when: 1}}).key(key);\n\t\t\t});\n\t\t\tchat.map().once(function renderToDo(val, field){\n\t\t\t\texpect(field).to.be.ok();\n\t\t\t\texpect(val.who).to.be.ok();\n\t\t\t\texpect(val.when).to.be.ok();\n\t\t\t\texpect(val.what).to.be.ok();\n\t\t\t\tif(done.c >= 2){ return }\n\t\t\t\tif(done.c === 1){ done() }\n\t\t\t\tdone.c = done.c || 0;\n\t\t\t\tdone.c += 1;\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar msg = {};\n\t\t\t\tmsg.when = Gun.time.is();\n\t\t\t\tmsg.what = \"lol!\";\n\t\t\t\tmsg.who = \"Alice\";\n\t\t\t\tchat.path(msg.when + '_' + Gun.text.random(4)).put(msg);\n\t\t\t},100);\n\t\t});\n\t\t/* // This test didn't work for what I was wanting to test :(, will either remove it or modify it if I think of a clever solution to test what I want to test.\n\t\tit(\"simulate json app\", function(done){\n\t\t\tvar peers = {};\n\t\t\tpeers.server = Gun();\n\t\t\tfunction wipeServer(){\n\t\t\t\tpeers.server = Gun();\n\t\t\t}\n\t\t\tvar gopt = {wire:{\n\t\t\t\tput: function(graph, cb){\n\t\t\t\t\tGun.union(peers.server, graph);\n\t\t\t\t\tcb(null);\n\t\t\t\t}\n\t\t\t\t,get: function(lex, cb){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tvar soul = lex['#'];\n\t\t\t\t\t\tif(peers.localStorage){\n\t\t\t\t\t\t\tvar g = peers.localStorage;\n\t\t\t\t\t\t\tconsole.log(\"VIA LOCALSTORAGE!\", lex, g[soul]);\n\t\t\t\t\t\t\tif(g[soul]){\n\t\t\t\t\t\t\t\tvar n = g[soul];\n\t\t\t\t\t\t\t\tcb(null, n);\n\t\t\t\t\t\t\t\tcb(null, Gun.is.node.ify({}, soul));\n\t\t\t\t\t\t\t\tcb(null, {});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\tvar graph = peers.server.__.graph;\n\t\t\t\t\t\t\tconsole.log(\"VIA the SERVER!!\", lex, graph[soul]);\n\t\t\t\t\t\t\tif(!graph[soul]){\n\t\t\t\t\t\t\t\tcb(null);\n\t\t\t\t\t\t\t\tcb(null, {});\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvar node = graph[soul];\n\t\t\t\t\t\t\tcb(null, node);\n\t\t\t\t\t\t\tcb(null, Gun.is.node.ify({}, soul));\n\t\t\t\t\t\t\tcb(null, {});\n\t\t\t\t\t\t},5);\n\t\t\t\t\t},5);\n\t\t\t\t}\n\t\t\t}}\n\t\t\tpeers.g = Gun(gopt);\n\t\t\tfunction reload(){\n\t\t\t\tpeers.localStorage = Gun.obj.copy(peers.g.__.graph);\n\t\t\t\tpeers.g2 = Gun(gopt);\n\t\t\t}\n\t\t\tvar ref = peers.g.get('example/json/data/test');\n\t\t\tsetTimeout(function(){\n\t\t\t\tref.path('hello').put(\"value\");\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\twipeServer();\n\t\t\t\t\treload();\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tGun.log.debug = 1; console.log(\"~~~~~~~~~~~~~~~~~~~\");\n\t\t\t\t\t\tvar ref = peers.g2.get('example/json/data/test');\n\t\t\t\t\t\tref.on(function(data){\n\t\t\t\t\t\t\tconsole.log(\"on!\", data);\n\t\t\t\t\t\t});\n\t\t\t\t\t},100);\n\t\t\t\t},100);\n\t\t\t},100);\n\t\t});\n\t\t*/\n\t\tit(\"simulate chat app\", function(done){\n\t\t\tvar server = Gun();\n\t\t\tvar gopt = {wire:{\n\t\t\t\tput: function(graph, cb){\n\t\t\t\t\tGun.union(server, graph);\n\t\t\t\t\tcb(null);\n\t\t\t\t}\n\t\t\t\t,get: function(lex, cb){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tvar soul = lex['#'];\n\t\t\t\t\t\tvar graph = server.__.graph;\n\t\t\t\t\t\t//console.log('server replying', soul, graph);\n\t\t\t\t\t\tif(!graph[soul]){\n\t\t\t\t\t\t\t//console.log(\"replying to Alice...\", null);\n\t\t\t\t\t\t\tcb(null);\n\t\t\t\t\t\t\tcb(null, {});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar node = graph[soul];\n\t\t\t\t\t\t//console.log(\"replying to Bob...\", node);\n\t\t\t\t\t\tcb(null, node);\n\t\t\t\t\t\tcb(null, Gun.is.node.ify({}, soul));\n\t\t\t\t\t\tcb(null, {});\n\t\t\t\t\t},5);\n\t\t\t\t}\n\t\t\t}}\n\t\t\tvar gun = Gun(gopt);\n\t\t\tvar chat = gun.get('example/chat/data/graph/field').not(function(key){\n\t\t\t\tgun.put({1: {who: 'Welcome', what: \"to the chat app!\", when: 1}}).key(key);\n\t\t\t});\n\t\t\tchat.map().once(function renderToDo(val, field){\n\t\t\t\t//console.log(\"ALICE\", field, val);\n\t\t\t\texpect(field).to.be.ok();\n\t\t\t\texpect(val.who).to.be.ok();\n\t\t\t\texpect(val.when).to.be.ok();\n\t\t\t\texpect(val.what).to.be.ok();\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tvar gun2 = Gun(gopt);\n\t\t\t\t//Gun.log.debug =1; console.log(\"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\");\n\t\t\t\tvar chat2 = gun2.get('example/chat/data/graph/field').not(function(key){\n\t\t\t\t\t//console.log(\"BOB's key\", key);\n\t\t\t\t\tgun2.put({1: {who: 'Welcome', what: \"to the chat app!\", when: 1}}).key(key);\n\t\t\t\t});\n\t\t\t\tchat2.map().once(function renderToDo(val, field){\n\t\t\t\t\t//console.log(\"BOB\", field, val);\n\t\t\t\t\texpect(field).to.be.ok();\n\t\t\t\t\texpect(val.who).to.be.ok();\n\t\t\t\t\texpect(val.when).to.be.ok();\n\t\t\t\t\texpect(val.what).to.be.ok();\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t},100);\n\t\t});\n\n\t\tit.skip(\"gun path via gun path\", function(done){ // TODO: Future feature?\n\t\t\tvar gun = Gun();\n\t\t\tvar book = gun.put({ name: 'Potato Cooking' });\n\t\t\tvar author = gun.put({ name: 'Bob Bobson' });\n\t\t\tauthor.path(book.path('name')).put(book);\n\t\t});\n\n\t\tit(\"gun set\", function(done){\n\t\t\tvar gun = Gun();\n\t\t\tvar users = gun.get('users/s');\n\t\t\tvar alice = gun.put({name: 'alice', birth: Math.random()}).key('person/alice');\n\t\t\tvar bob = gun.put({name: 'bob', birth: Math.random()}).key('person/bob');\n\t\t\tvar carl = gun.put({name: 'carl', birth: Math.random()}).key('person/carl');\n\t\t\tvar dave = gun.put({name: 'dave', birth: Math.random()}).key('person/dave');\n\n\t\t\t// Test set with new object\n\t\t\tvar alan = users.set({name: 'alan', birth: Math.random()}).key('person/alan');\n\t\t\talan.once(function(alan) {\n\t\t\t\t// Test set with node\n\t\t\t\tdave.path('friends').set(alan);\n\t\t\t});\n\n\t\t\tusers.set(alice);\n\t\t\tusers.set(bob);\n\t\t\tusers.set(carl);\n\t\t\tusers.set(dave);\n\n\t\t\talice.path('friends').set(bob).back().set(carl);\n\t\t\tbob.path('friends').set(alice);\n\t\t\tdave.path('friends').set(alice).back().set(carl);\n\n\t\t\tvar team = gun.get('team/lions').put({name: \"Lions\"});\n\t\t\tteam.path('members').set(alice);\n\t\t\tteam.path('members').set(bob);\n\t\t\tteam.path('members').set(alan); // Test set with set\n\n\t\t\talice.path('team').put(team);\n\t\t\tbob.path('team').put(team);\n\n\t\t\tdave.path('friends').map().path('team.members').map().once(function(member){\n\t\t\t\t//console.log(\"Dave's friend is on a team that has\", member.name, \"on it.\");\n\t\t\t\tif('alice' === member.name){\n\t\t\t\t\tdone.alice = true;\n\t\t\t\t} else\n\t\t\t\tif('bob' === member.name){\n\t\t\t\t\tdone.bob = true;\n\t\t\t\t} else\n\t\t\t\tif('alan' === member.name){\n\t\t\t\t\tdone.alan = true;\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\texpect(member).to.not.be.ok();\n\t\t\t\t}\n\t\t\t\tif(done.alice && done.bob && done.alan){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t},10);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit(\"get context\", function(done){ // TODO: HUH?????? This was randomly causing errors?\n\t\t\tvar gun = Gun();\n\t\t\tvar ref = gun.get('ctx/lol').get('ctx/foo').put({hello: 'world'});\n\t\t\tgun.get('ctx/lol').once(function(implicit){\n\t\t\t\tdone.fail = true;\n\t\t\t\texpect(implicit).to.not.be.ok();\n\t\t\t});\n\t\t\tgun.get('ctx/lol').not(function(){\n\t\t\t\tdone.please = true;\n\t\t\t});\n\t\t\tgun.get('ctx/foo').once(function(data){\n\t\t\t\texpect(data.hello).to.be('world');\n\t\t\t\texpect(done.fail).to.not.be.ok();\n\t\t\t\texpect(done.please).to.be.ok();\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit.skip(\"chaining val\", function(done){ // Not implemented yet!\n\t\t\tvar gun = Gun();\n\t\t\tgun.get('users/cv').set(gun.put({name: 'alice'}));\n\t\t\tgun.get('users/cv').set(gun.put({name: 'bob'}));;\n\t\t\tgun.get('users/cv').once().map(function(person){\n\t\t\t\tif(person.name === 'alice'){\n\t\t\t\t\tdone.alice = true;\n\t\t\t\t}\n\t\t\t\tif(person.name === 'bob'){\n\t\t\t\t\tdone.bob = true;\n\t\t\t\t}\n\t\t\t\tif(person.name === 'carl'){\n\t\t\t\t\tdone.carl = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tgun.get('users/cv').set(gun.put({name: 'carl'}));\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log('wha?', done.alice, done.bob, done.carl);\n\t\t\t\texpect(done.alice).to.be.ok();\n\t\t\t\texpect(done.bob).to.be.ok();\n\t\t\t\texpect(done.carl).to.not.be.ok();\n\t\t\t\tdone();\n\t\t\t},10);\n\t\t});\n\n    it.skip('Deep async change not updating', function (done) { // Issue #167 TODO: NEEDS TO BE ADDED TO 0.5 BRANCH!\n\t\t\t// object nested three layers deep\n\t\t\t// must be at least three layers\n\t\t\tvar obj = { 1: { 2: { data: false } } }\n\n\t\t\t// define gun and place the deep object\n\t\t\tgun = Gun().get('deep change').put(obj)\n\n\t\t\t// listen for changes\n\t\t\tGun.log.debug = 1; console.log(\"------------------\");\n\t\t\tgun.path('1.2.data').on(function (data) {\n\t\t\t\tconsole.log(\"??????\", data);\n\t\t\t  if (data) {\n\t\t\t    // gun will never receive the \"true\" update\n\t\t\t    done();\n\t\t\t  }\n\t\t\t})\n\n\t\t\t// asynchronously set data\n\t\t\t// synchronous deviations will succeed\n\t\t\tsetTimeout(function () {\n\t\t\t  obj[1][2].data = true\n\t\t\t  gun.put(obj);\n\t\t\t}, 50)\n    });\n\n    it('should allow more than 2 items depthwise', function (done) { // Issue #186\n    \t\tvar gun = Gun();\n    \t\tvar list = gun.get('list');\n        // create a list two layers deep\n        list.put({\n            depth: 1,\n            next: {\n                depth: 2\n            }\n        });\n\n        //Gun.log.verbose=true;Gun.log.debug=1;console.log(\"----------------------\");\n        // append a third item\n        list.path('next').put({\n            to: {\n                depth: 3\n            }\n        });\n        setTimeout(function(){\n\n\t        //list.path('next').once('wat');\n\n\t        //console.log(\"!!!!!!\", gun.__.graph);\n\n\t        // try to read the third item\n\t        list.path('next.to').once(function () { // TODO: BUG! If this is 'next.next' as with the data, then it fails.\n\t            done();\n\t        });\n      \t},100);\n    });\n\n    it(\"Batch put status update not save\", function(done){ // TODO: ADD TO 0.5 BRANCH. Stefdv's bug.\n    \tvar obj = {\n\t\t\t\ta: 1,\n\t\t\t\tb: 2,\n\t\t\t\tc: 3,\n\t\t\t\td: 4,\n\t\t\t\te: 5,\n\t\t\t\tf: 6,\n\t\t\t\tg: 7,\n\t\t\t\th: 8,\n\t\t\t\ti: 9,\n\t\t\t\tj: 10,\n\t\t\t\tk: 11,\n\t\t\t\tl: 12,\n\t\t\t\tm: 13,\n\t\t\t\tn: 14,\n\t\t\t\to: 15,\n\t\t\t\tp: 16,\n\t\t\t\tq: 17,\n\t\t\t\tr: 18,\n\t\t\t\ts: 19,\n\t\t\t\tt: 20\n\t\t\t}\n\n\t\t\tvar bsmi = {\n\t\t\t\tgroup1: {\n\t\t\t\t\titem1: {\n\t\t\t\t\t\t10: Gun.obj.copy(obj)\n\t\t\t\t\t}\n\t\t\t\t}/*,\n\t\t\t\tgroup2: {\n\t\t\t\t\titem2: {\n\t\t\t\t\t\t10: Gun.obj.copy(obj)\n\t\t\t\t\t}\n\t\t\t\t}*/\n\t\t\t}\n\n\t\t\tvar gun = Gun();\n\t\t\tvar BSMI = gun.get('bsmi').put(bsmi);\n\n\t\t\t// path is <group><itemId><powerRail>\n\t\t\t//BSMI  is a set  holding all items\n\t\t\t//var allPaths = [\"1116.1116-A7001.10\",\"1354.1354-E1930.10\"]\n\t\t\tvar allPaths = [\"group1.item1.10\"];//,\"group2.item2.10\"]\n\t\t\tallPaths.forEach(function(path) {\n\t\t\t\tBSMI.path(path).put({status:false});\n\t\t\t});\n\t\t\tsetTimeout(function(){\n\t\t\t\tBSMI.path(allPaths[0]).once(function(a,b,c){\n\t\t\t\t\texpect(a.a).to.be(1);\n\t\t\t\t\texpect(a.b).to.be(2);\n\t\t\t\t\texpect(a.c).to.be(3);\n\t\t\t\t\texpect(a.d).to.be(4);\n\t\t\t\t\texpect(a.e).to.be(5);\n\t\t\t\t\texpect(a.f).to.be(6);\n\t\t\t\t\texpect(a.g).to.be(7);\n\t\t\t\t\texpect(a.h).to.be(8);\n\t\t\t\t\texpect(a.i).to.be(9);\n\t\t\t\t\texpect(a.j).to.be(10);\n\t\t\t\t\texpect(a.k).to.be(11);\n\t\t\t\t\texpect(a.l).to.be(12);\n\t\t\t\t\texpect(a.m).to.be(13);\n\t\t\t\t\texpect(a.n).to.be(14);\n\t\t\t\t\texpect(a.o).to.be(15);\n\t\t\t\t\texpect(a.p).to.be(16);\n\t\t\t\t\texpect(a.q).to.be(17);\n\t\t\t\t\texpect(a.r).to.be(18);\n\t\t\t\t\texpect(a.s).to.be(19);\n\t\t\t\t\texpect(a.t).to.be(20);\n\t\t\t\t\texpect(a.status).to.be(false);\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t},100);\n    });\n\n    it(\"Don't put on parents\", function(done){ // TODO: ADD TO 0.5 BRANCH! // Another Stefdv find.\n\t\t\tvar test = gun.get('test');\n\t\t\ttest.path('try.this.at.lvl4').put({msg:'hoi'})\n\t\t\ttest.once(function(node,b){\n\t\t\t\tdelete node._;\n\t\t\t\texpect(Gun.obj.empty(node, 'try')).to.be.ok();\n\t\t\t\tnode = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.try)]);\n\n\t\t\t\tdelete node._;\n\t\t\t\texpect(Gun.obj.empty(node, 'this')).to.be.ok();\n\t\t\t\tnode = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.this)]);\n\n\t\t\t\tdelete node._;\n\t\t\t\texpect(Gun.obj.empty(node, 'at')).to.be.ok();\n\t\t\t\tnode = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.at)]);\n\n\t\t\t\tdelete node._;\n\t\t\t\texpect(Gun.obj.empty(node, 'lvl4')).to.be.ok();\n\t\t\t\tnode = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.lvl4)]);\n\n\t\t\t\tdelete node._;\n\t\t\t\texpect(Gun.obj.empty(node, 'msg')).to.be.ok();\n\t\t\t\texpect(node.msg).to.be('hoi');\n\t\t\t\tdone();\n\t\t\t});\n    });\n\n    it(\"Deep not fails to fire\", function(done){ // @d3x0r's bug!\n    \tvar gun = Gun().get(\"org.d3x0r.voxelarium.local.\" + Gun.text.random());\n\n\t    var player = gun.path( \"player\" );\n\n\t    player.path(\"id\").not(function(){\n    \t\tdone.not = true;\n        //console.log(\"Not is run!\");\n        var id = 'fluffy';\n        var world = 0;\n        player.path(\"id\").put(id);\n        player.path(\"world_id\").put(world);\n\t    }).once(function(data){\n        //console.log(\"we have value!\", data);\n        expect(done.not).to.be.ok();\n        expect(data).to.be('fluffy');\n        done();\n\t    });\n\n  \t});\n\t\t/*\n\t\tdepp.on(log).path('spouse').on(log).path('pet').on(log);\n\t\t// 0) Depp & Heide & dog\n\t\t// 1) dog\n\t\t// 2) cat\n\t\t// 3) cat\n\t\t// 4) Julie & cat\n\n\t\tdepp.path('spouse.pet.name').on(log).put('pearls');\n\t\tdepp.path('spouse.pet.name').put('paws').on(log);\n\t\tdepp.path('spouse.pet.name').on(log).not(log);\n\t\t// 0: fluffy\n\t\t// 1: fluff\n\t\t// 3: bacon\n\t\t// 9: `.not`\n\n\t\tdepp.path('spouse.pet.name').once().on(log);\n\t\t// 0: fluffy\n\t\t// 1: fluff\n\t\t*/\n\t});\n\n\tdescribe('localStorage', function(){\n\t\tit(\"err\", function(done){\n\t\t\tthis.timeout(9000);\n\t\t\tvar localStorage = localStorage || {clear:function(){}};\n\t\t\tlocalStorage.clear();\n\t\t\tvar gun = Gun();\n\t\t\tvar text = String.random(1024 * 1024 * 6);\n\t\t\tgun.put({i: text}, function(ack){\n\t\t\t\tvar err = ack.err, ok = ack.ok;\n\t\t\t\tif(done.c){ return }\n\t\t\t\tif(!err){ return done() }\n\t\t\t\tvar text = \"If you are seeing this message, it means the localStorage error was caught successfully rather than it crashing and stopping replication to peers. Also, the error is now reported back to you via the put callback. Here it is!\";\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tdone(); done.c = 1;\n\t\t\t});\n\t\t});\n\t\tit(\"ack\", function(done){\n\t\t\tthis.timeout(9000);\n\t\t\tvar localStorage = localStorage || {clear:function(){}};\n\t\t\tlocalStorage.clear();\n\t\t\tvar gun = Gun();\n\t\t\tvar i = 999, obj = {}; while(--i){ obj[i] = String.random(99) }\n\t\t\t//console.log(\"save:\", obj);\n\t\t\tgun.get('lSack').put(obj, function(ack){\n\t\t\t\t//console.log(\"ack:\", ack)\n\t\t\t\tdone(); done.c = 1;\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('Streams', function(){\n\t\tconsole.log(\"TODO: BUG! Upgrade UNION tests to new internal API!\");\n\t\treturn;\n\t\tvar gun = Gun(), g = function(){\n\t\t\treturn Gun({wire: {get: ctx.get}});\n\t\t}, ctx = {gen: 9, extra: 100, network: 2};\n\n\t\tit('prep hook', function(done){\n\t\t\tthis.timeout(ctx.gen * ctx.extra);\n\t\t\tvar peer = Gun(), ref;\n\t\t\tctx.get = function(key, cb){\n\t\t\t\tvar c = 0;\n\t\t\t\tcb = cb || function(){};\n\t\t\t\tkey = key['#'];\n\t\t\t\tif('big' !== key){ return cb(null) }\n\t\t\t\tsetTimeout(function badNetwork(){\n\t\t\t\t\tc += 1;\n\t\t\t\t\tvar soul = Gun.node.soul(ref);\n\t\t\t\t\tvar graph = {};\n\t\t\t\t\tvar data = /*graph[soul] = */ {_: {'#': soul, '>': {}}};\n\t\t\t\t\tif(!ref['f' + c]){\n\t\t\t\t\t\treturn cb(null, data), cb(null, {});\n\t\t\t\t\t}\n\t\t\t\t\tdata._[Gun._.state]['f' + c] = ref._[Gun._.state]['f' + c];\n\t\t\t\t\tdata['f' + c] = ref['f' + c];\n\t\t\t\t\tcb(null, data);\n\t\t\t\t\tsetTimeout(badNetwork, ctx.network);\n\t\t\t\t},ctx.network);\n\t\t\t}\n\t\t\tctx.get.fake = {};\n\t\t\tfor(var i = 1; i < (ctx.gen) + 1; i++){\n\t\t\t\tctx.get.fake['f'+i] = i;\n\t\t\t\tctx.length = i;\n\t\t\t}\n\t\t\tctx.get.fake = Gun.is.node.ify(ctx.get.fake, 'big');\n\t\t\tvar big = peer.put(ctx.get.fake).once(function(val){\n\t\t\t\tref = val;\n\t\t\t\tctx.get({'#': 'big'}, function(err, graph){\n\t\t\t\t\tif(Gun.obj.empty(graph)){ done() }\n\t\t\t\t});\n\t\t\t\tgun.opt({wire: {get: ctx.get}});\n\t\t\t});\n\t\t});\n\n\t\tit('map chain', function(done){\n\t\t\tvar set = gun.put({a: {here: 'you'}, b: {go: 'dear'}, c: {sir: '!'} });\n\t\t\tset.map().once(function(obj, field){\n\t\t\t\tif(obj.here){\n\t\t\t\t\tdone.a = obj.here;\n\t\t\t\t\texpect(obj.here).to.be('you');\n\t\t\t\t}\n\t\t\t\tif(obj.go){\n\t\t\t\t\tdone.b = obj.go;\n\t\t\t\t\texpect(obj.go).to.be('dear');\n\t\t\t\t}\n\t\t\t\tif(obj.sir){\n\t\t\t\t\tdone.c = obj.sir;\n\t\t\t\t\texpect(obj.sir).to.be('!');\n\t\t\t\t}\n\t\t\t\tif(done.a && done.b && done.c){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit('map chain path', function(done){\n\t\t\tvar set = gun.put({\n\t\t\t\ta: {name: \"Mark\",\n\t\t\t\t\tpet: {coat: \"tabby\", name: \"Hobbes\"}\n\t\t\t\t}, b: {name: \"Alice\",\n\t\t\t\t\tpet: {coat: \"calico\", name: \"Cali\"}\n\t\t\t\t}, c: {name: \"Bob\",\n\t\t\t\t\tpet: {coat: \"tux\", name: \"Casper\"}\n\t\t\t\t}\n\t\t\t});\n\t\t\tset.map().path('pet').once(function(obj, field){\n\t\t\t\tif(obj.name === 'Hobbes'){\n\t\t\t\t\tdone.hobbes = obj.name;\n\t\t\t\t\texpect(obj.name).to.be('Hobbes');\n\t\t\t\t\texpect(obj.coat).to.be('tabby');\n\t\t\t\t}\n\t\t\t\tif(obj.name === 'Cali'){\n\t\t\t\t\tdone.cali = obj.name;\n\t\t\t\t\texpect(obj.name).to.be('Cali');\n\t\t\t\t\texpect(obj.coat).to.be('calico');\n\t\t\t\t}\n\t\t\t\tif(obj.name === 'Casper'){\n\t\t\t\t\tdone.casper = obj.name;\n\t\t\t\t\texpect(obj.name).to.be('Casper');\n\t\t\t\t\texpect(obj.coat).to.be('tux');\n\t\t\t\t}\n\t\t\t\tif(done.hobbes && done.cali && done.casper){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit('get big on', function(done){\n\t\t\tthis.timeout(ctx.gen * ctx.extra);\n\t\t\tvar test = {c: 0, last: 0};\n\t\t\tg().get('big').on(function(val){\n\t\t\t\tif(test.done){ return console.log(\"hey yo! you got duplication on your ons!\"); }\n\t\t\t\tdelete val._;\n\t\t\t\tif(val['f' + (test.last + 1)]){\n\t\t\t\t\ttest.c += 1;\n\t\t\t\t\ttest.last += 1;\n\t\t\t\t}\n\t\t\t\tvar obj = {};\n\t\t\t\tfor(var i = 1; i < test.c + 1; i++){\n\t\t\t\t\tobj['f'+i] = i;\n\t\t\t\t}\n\t\t\t\texpect(val).to.eql(obj);\n\t\t\t\tif(test.c === ctx.length){\n\t\t\t\t\ttest.done = true;\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit('get big on delta', function(done){\n\t\t\tthis.timeout(ctx.gen * ctx.extra);\n\t\t\tvar test = {c: 0, seen: {}};\n\t\t\tg().get('big').on(function(val){\n\t\t\t\tdelete val._;\n\t\t\t\tif(test.seen['f' + test.c]){ return }\n\t\t\t\ttest.seen['f' + test.c] = true;\n\t\t\t\ttest.c += 1;\n\t\t\t\tvar obj = {};\n\t\t\t\tobj['f' + test.c] = test.c;\n\t\t\t\texpect(val).to.eql(obj);\n\t\t\t\tif(test.c === ctx.length){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t}, true);\n\t\t});\n\n\t\tit('get val', function(done){\n\t\t\tthis.timeout(ctx.gen * ctx.extra);\n\t\t\tg().get('big').once(function(obj){\n\t\t\t\tdelete obj._;\n\t\t\t\texpect(obj.f1).to.be(1);\n\t\t\t\texpect(obj['f' + ctx.length]).to.be(ctx.length);\n\t\t\t\tvar raw = Gun.obj.copy(ctx.get.fake);\n\t\t\t\tdelete raw._;\n\t\t\t\texpect(obj).to.be.eql(raw);\n\t\t\t\tGun.log.debug = 0;\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\tit('get big map val', function(done){\n\t\t\tthis.timeout(ctx.gen * ctx.extra);\n\t\t\tvar test = {c: 0, seen: {}};\n\t\t\tg().get('big').map().once(function(val, field){\n\t\t\t\tif(test.seen[field]){ return }\n\t\t\t\ttest.seen[field] = true;\n\t\t\t\tdelete val._;\n\t\t\t\texpect(field).to.be('f' + (test.c += 1));\n\t\t\t\texpect(val).to.be(test.c);\n\t\t\t\tif(test.c === ctx.length){\n\t\t\t\t\tdone();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\tit('val emits all data', function(done){ // bug in chat app\n\t\t\tvar chat = Gun().get('example/chat/data').not(function(){\n\t\t\t\tthis.put({1: {who: 'Welcome', what: \"to the chat app!\", when: 0}}).key('example/chat/data');\n\t\t\t});\n\t\t\tchat.put({random1: {who: 'mark', what: \"1\", when: 1}});\n\t\t\tchat.put({random2: {who: 'mark', what: \"2\", when: 2}});\n\t\t\tchat.put({random3: {who: 'mark', what: \"3\", when: 3}});\n\t\t\tchat.put({random4: {who: 'mark', what: \"4\", when: 4}});\n\t\t\tchat.put({random5: {who: 'mark', what: \"5\", when: 5}});\n\t\t\tvar seen = {1: false, 2: false, 3: false, 4: false, 5: false}\n\t\t\tsetTimeout(function(){\n\t\t\t\tchat.map(function(m){ }).once(function(msg, field){\n\t\t\t\t\tvar msg = Gun.obj.copy(msg);\n\t\t\t\t\tif(msg.what){\n\t\t\t\t\t\texpect(msg.what).to.be.ok();\n\t\t\t\t\t\tseen[msg.when] = true;\n\t\t\t\t\t}\n\t\t\t\t\tif(!Gun.obj.map(seen, function(boo){ if(!boo){ return true } })){\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 100);\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/debug/deep-set.html",
    "content": "<script src=\"../../gun.js\"></script>\n<script>\n;(function(){\n\t//localStorage.clear();\n\t\n\tvar gun = window.gun = Gun('http://localhost:8765/gun');\n\tvar user = window.user = gun.get('pub/alice');\n\treturn;\n\tuser.put({pub: 'alice'}, write);\n\n\n\tfunction write(data){\n\t\tconsole.log(\"write...\");\n\t\tuser.get('profile').get('said').set({\n\t\t\twhat: \"Hello world! \" + Gun.text.random(3)\n\t\t}, get);\n\t}\n\n\tfunction get(){\n\t\tconsole.log(\"get...\");\n\t\tuser.get('profile').get('said').map().val(function(data){\n\t\t\tconsole.log(\"read...\", data);\n\t\t})\n\t}\n\n}());\n</script>"
  },
  {
    "path": "test/download-log.html",
    "content": "<html>\n<body>\nPaste the log URL into here:\n<input id=\"peer\">\nThen right click save-as here:\n<a id=\"url\">right click not normal click</a>\n<script>\npeer.onkeyup = function(){\n\turl.href = url.download = this.value;\n}\n</script>\n</body>\n</html>"
  },
  {
    "path": "test/expect.js",
    "content": "(function (global, module) {\r\n\r\n  var exports = module.exports;\r\n\r\n  /**\r\n   * Exports.\r\n   */\r\n\r\n  module.exports = expect;\r\n  expect.Assertion = Assertion;\r\n\r\n  /**\r\n   * Exports version.\r\n   */\r\n\r\n  expect.version = '0.1.2';\r\n\r\n  /**\r\n   * Possible assertion flags.\r\n   */\r\n\r\n  var flags = {\r\n      not: ['to', 'be', 'have', 'include', 'only']\r\n    , to: ['be', 'have', 'include', 'only', 'not']\r\n    , only: ['have']\r\n    , have: ['own']\r\n    , be: ['an']\r\n  };\r\n\r\n  function expect (obj) {\r\n    return new Assertion(obj);\r\n  }\r\n\r\n  /**\r\n   * Constructor\r\n   *\r\n   * @api private\r\n   */\r\n\r\n  function Assertion (obj, flag, parent) {\r\n    this.obj = obj;\r\n    this.flags = {};\r\n\r\n    if (undefined != parent) {\r\n      this.flags[flag] = true;\r\n\r\n      for (var i in parent.flags) {\r\n        if (parent.flags.hasOwnProperty(i)) {\r\n          this.flags[i] = true;\r\n        }\r\n      }\r\n    }\r\n\r\n    var $flags = flag ? flags[flag] : keys(flags)\r\n      , self = this;\r\n\r\n    if ($flags) {\r\n      for (var i = 0, l = $flags.length; i < l; i++) {\r\n        // avoid recursion\r\n        if (this.flags[$flags[i]]) continue;\r\n\r\n        var name = $flags[i]\r\n          , assertion = new Assertion(this.obj, name, this)\r\n\r\n        if ('function' == typeof Assertion.prototype[name]) {\r\n          // clone the function, make sure we dont touch the prot reference\r\n          var old = this[name];\r\n          this[name] = function () {\r\n            return old.apply(self, arguments);\r\n          };\r\n\r\n          for (var fn in Assertion.prototype) {\r\n            if (Assertion.prototype.hasOwnProperty(fn) && fn != name) {\r\n              this[name][fn] = bind(assertion[fn], assertion);\r\n            }\r\n          }\r\n        } else {\r\n          this[name] = assertion;\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Performs an assertion\r\n   *\r\n   * @api private\r\n   */\r\n\r\n  Assertion.prototype.assert = function (truth, msg, error, expected) {\r\n    var msg = this.flags.not ? error : msg\r\n      , ok = this.flags.not ? !truth : truth\r\n      , err;\r\n\r\n    if (!ok) {\r\n      err = new Error(msg.call(this));\r\n      if (arguments.length > 3) {\r\n        err.actual = this.obj;\r\n        err.expected = expected;\r\n        err.showDiff = true;\r\n      }\r\n      throw err;\r\n    }\r\n\r\n    this.and = new Assertion(this.obj);\r\n  };\r\n\r\n  /**\r\n   * Check if the value is truthy\r\n   *\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.ok = function () {\r\n    this.assert(\r\n        !!this.obj\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be truthy' }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be falsy' });\r\n  };\r\n\r\n  /**\r\n   * Creates an anonymous function which calls fn with arguments.\r\n   *\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.withArgs = function() {\r\n    expect(this.obj).to.be.a('function');\r\n    var fn = this.obj;\r\n    var args = Array.prototype.slice.call(arguments);\r\n    return expect(function() { fn.apply(null, args); });\r\n  };\r\n\r\n  /**\r\n   * Assert that the function throws.\r\n   *\r\n   * @param {Function|RegExp} callback, or regexp to match error string against\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.throwError =\r\n  Assertion.prototype.throwException = function (fn) {\r\n    expect(this.obj).to.be.a('function');\r\n\r\n    var thrown = false\r\n      , not = this.flags.not;\r\n\r\n    try {\r\n      this.obj();\r\n    } catch (e) {\r\n      if (isRegExp(fn)) {\r\n        var subject = 'string' == typeof e ? e : e.message;\r\n        if (not) {\r\n          expect(subject).to.not.match(fn);\r\n        } else {\r\n          expect(subject).to.match(fn);\r\n        }\r\n      } else if ('function' == typeof fn) {\r\n        fn(e);\r\n      }\r\n      thrown = true;\r\n    }\r\n\r\n    if (isRegExp(fn) && not) {\r\n      // in the presence of a matcher, ensure the `not` only applies to\r\n      // the matching.\r\n      this.flags.not = false;\r\n    }\r\n\r\n    var name = this.obj.name || 'fn';\r\n    this.assert(\r\n        thrown\r\n      , function(){ return 'expected ' + name + ' to throw an exception' }\r\n      , function(){ return 'expected ' + name + ' not to throw an exception' });\r\n  };\r\n\r\n  /**\r\n   * Checks if the array is empty.\r\n   *\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.empty = function () {\r\n    var expectation;\r\n\r\n    if ('object' == typeof this.obj && null !== this.obj && !isArray(this.obj)) {\r\n      if ('number' == typeof this.obj.length) {\r\n        expectation = !this.obj.length;\r\n      } else {\r\n        expectation = !keys(this.obj).length;\r\n      }\r\n    } else {\r\n      if ('string' != typeof this.obj) {\r\n        expect(this.obj).to.be.an('object');\r\n      }\r\n\r\n      expect(this.obj).to.have.property('length');\r\n      expectation = !this.obj.length;\r\n    }\r\n\r\n    this.assert(\r\n        expectation\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be empty' }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to not be empty' });\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Checks if the obj exactly equals another.\r\n   *\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.be =\r\n  Assertion.prototype.equal = function (obj) {\r\n    this.assert(\r\n        obj === this.obj\r\n      , function(){ return 'expected ' + i(this.obj) + ' to equal ' + i(obj) }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to not equal ' + i(obj) });\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Checks if the obj sortof equals another.\r\n   *\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.eql = function (obj) {\r\n    this.assert(\r\n        expect.eql(this.obj, obj)\r\n      , function(){ return 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj) }\r\n      , obj);\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert within start to finish (inclusive).\r\n   *\r\n   * @param {Number} start\r\n   * @param {Number} finish\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.within = function (start, finish) {\r\n    var range = start + '..' + finish;\r\n    this.assert(\r\n        this.obj >= start && this.obj <= finish\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be within ' + range }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to not be within ' + range });\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert typeof / instance of\r\n   *\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.a =\r\n  Assertion.prototype.an = function (type) {\r\n    if ('string' == typeof type) {\r\n      // proper english in error msg\r\n      var n = /^[aeiou]/.test(type) ? 'n' : '';\r\n\r\n      // typeof with support for 'array'\r\n      this.assert(\r\n          'array' == type ? isArray(this.obj) :\r\n            'regexp' == type ? isRegExp(this.obj) :\r\n              'object' == type\r\n                ? 'object' == typeof this.obj && null !== this.obj\r\n                : type == typeof this.obj\r\n        , function(){ return 'expected ' + i(this.obj) + ' to be a' + n + ' ' + type }\r\n        , function(){ return 'expected ' + i(this.obj) + ' not to be a' + n + ' ' + type });\r\n    } else {\r\n      // instanceof\r\n      var name = type.name || 'supplied constructor';\r\n      this.assert(\r\n          this.obj instanceof type\r\n        , function(){ return 'expected ' + i(this.obj) + ' to be an instance of ' + name }\r\n        , function(){ return 'expected ' + i(this.obj) + ' not to be an instance of ' + name });\r\n    }\r\n\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert numeric value above _n_.\r\n   *\r\n   * @param {Number} n\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.greaterThan =\r\n  Assertion.prototype.above = function (n) {\r\n    this.assert(\r\n        this.obj > n\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n });\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert numeric value below _n_.\r\n   *\r\n   * @param {Number} n\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.lessThan =\r\n  Assertion.prototype.below = function (n) {\r\n    this.assert(\r\n        this.obj < n\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n });\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert string value matches _regexp_.\r\n   *\r\n   * @param {RegExp} regexp\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.match = function (regexp) {\r\n    this.assert(\r\n        regexp.exec(this.obj)\r\n      , function(){ return 'expected ' + i(this.obj) + ' to match ' + regexp }\r\n      , function(){ return 'expected ' + i(this.obj) + ' not to match ' + regexp });\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert property \"length\" exists and has value of _n_.\r\n   *\r\n   * @param {Number} n\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.length = function (n) {\r\n    expect(this.obj).to.have.property('length');\r\n    var len = this.obj.length;\r\n    this.assert(\r\n        n == len\r\n      , function(){ return 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to not have a length of ' + len });\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert property _name_ exists, with optional _val_.\r\n   *\r\n   * @param {String} name\r\n   * @param {Mixed} val\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.property = function (name, val) {\r\n    if (this.flags.own) {\r\n      this.assert(\r\n          Object.prototype.hasOwnProperty.call(this.obj, name)\r\n        , function(){ return 'expected ' + i(this.obj) + ' to have own property ' + i(name) }\r\n        , function(){ return 'expected ' + i(this.obj) + ' to not have own property ' + i(name) });\r\n      return this;\r\n    }\r\n\r\n    if (this.flags.not && undefined !== val) {\r\n      if (undefined === this.obj[name]) {\r\n        throw new Error(i(this.obj) + ' has no property ' + i(name));\r\n      }\r\n    } else {\r\n      var hasProp;\r\n      try {\r\n        hasProp = name in this.obj\r\n      } catch (e) {\r\n        hasProp = undefined !== this.obj[name]\r\n      }\r\n\r\n      this.assert(\r\n          hasProp\r\n        , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name) }\r\n        , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name) });\r\n    }\r\n\r\n    if (undefined !== val) {\r\n      this.assert(\r\n          val === this.obj[name]\r\n        , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name)\r\n          + ' of ' + i(val) + ', but got ' + i(this.obj[name]) }\r\n        , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name)\r\n          + ' of ' + i(val) });\r\n    }\r\n\r\n    this.obj = this.obj[name];\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert that the array contains _obj_ or string contains _obj_.\r\n   *\r\n   * @param {Mixed} obj|string\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.string =\r\n  Assertion.prototype.contain = function (obj) {\r\n    if ('string' == typeof this.obj) {\r\n      this.assert(\r\n          ~this.obj.indexOf(obj)\r\n        , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) }\r\n        , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) });\r\n    } else {\r\n      this.assert(\r\n          ~indexOf(this.obj, obj)\r\n        , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) }\r\n        , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) });\r\n    }\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert exact keys or inclusion of keys by using\r\n   * the `.own` modifier.\r\n   *\r\n   * @param {Array|String ...} keys\r\n   * @api public\r\n   */\r\n\r\n  Assertion.prototype.key =\r\n  Assertion.prototype.keys = function ($keys) {\r\n    var str\r\n      , ok = true;\r\n\r\n    $keys = isArray($keys)\r\n      ? $keys\r\n      : Array.prototype.slice.call(arguments);\r\n\r\n    if (!$keys.length) throw new Error('keys required');\r\n\r\n    var actual = keys(this.obj)\r\n      , len = $keys.length;\r\n\r\n    // Inclusion\r\n    ok = every($keys, function (key) {\r\n      return ~indexOf(actual, key);\r\n    });\r\n\r\n    // Strict\r\n    if (!this.flags.not && this.flags.only) {\r\n      ok = ok && $keys.length == actual.length;\r\n    }\r\n\r\n    // Key string\r\n    if (len > 1) {\r\n      $keys = map($keys, function (key) {\r\n        return i(key);\r\n      });\r\n      var last = $keys.pop();\r\n      str = $keys.join(', ') + ', and ' + last;\r\n    } else {\r\n      str = i($keys[0]);\r\n    }\r\n\r\n    // Form\r\n    str = (len > 1 ? 'keys ' : 'key ') + str;\r\n\r\n    // Have / include\r\n    str = (!this.flags.only ? 'include ' : 'only have ') + str;\r\n\r\n    // Assertion\r\n    this.assert(\r\n        ok\r\n      , function(){ return 'expected ' + i(this.obj) + ' to ' + str }\r\n      , function(){ return 'expected ' + i(this.obj) + ' to not ' + str });\r\n\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Assert a failure.\r\n   *\r\n   * @param {String ...} custom message\r\n   * @api public\r\n   */\r\n  Assertion.prototype.fail = function (msg) {\r\n    var error = function() { return msg || \"explicit failure\"; }\r\n    this.assert(false, error, error);\r\n    return this;\r\n  };\r\n\r\n  /**\r\n   * Function bind implementation.\r\n   */\r\n\r\n  function bind (fn, scope) {\r\n    return function () {\r\n      return fn.apply(scope, arguments);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Array every compatibility\r\n   *\r\n   * @see bit.ly/5Fq1N2\r\n   * @api public\r\n   */\r\n\r\n  function every (arr, fn, thisObj) {\r\n    var scope = thisObj || global;\r\n    for (var i = 0, j = arr.length; i < j; ++i) {\r\n      if (!fn.call(scope, arr[i], i, arr)) {\r\n        return false;\r\n      }\r\n    }\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * Array indexOf compatibility.\r\n   *\r\n   * @see bit.ly/a5Dxa2\r\n   * @api public\r\n   */\r\n\r\n  function indexOf (arr, o, i) {\r\n    if (Array.prototype.indexOf) {\r\n      return Array.prototype.indexOf.call(arr, o, i);\r\n    }\r\n\r\n    if (arr.length === undefined) {\r\n      return -1;\r\n    }\r\n\r\n    for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0\r\n        ; i < j && arr[i] !== o; i++);\r\n\r\n    return j <= i ? -1 : i;\r\n  }\r\n\r\n  // https://gist.github.com/1044128/\r\n  var getOuterHTML = function(element) {\r\n    if ('outerHTML' in element) return element.outerHTML;\r\n    var ns = \"http://www.w3.org/1999/xhtml\";\r\n    var container = document.createElementNS(ns, '_');\r\n    var xmlSerializer = new XMLSerializer();\r\n    var html;\r\n    if (document.xmlVersion) {\r\n      return xmlSerializer.serializeToString(element);\r\n    } else {\r\n      container.appendChild(element.cloneNode(false));\r\n      html = container.innerHTML.replace('><', '>' + element.innerHTML + '<');\r\n      container.innerHTML = '';\r\n      return html;\r\n    }\r\n  };\r\n\r\n  // Returns true if object is a DOM element.\r\n  var isDOMElement = function (object) {\r\n    if (typeof HTMLElement === 'object') {\r\n      return object instanceof HTMLElement;\r\n    } else {\r\n      return object &&\r\n        typeof object === 'object' &&\r\n        object.nodeType === 1 &&\r\n        typeof object.nodeName === 'string';\r\n    }\r\n  };\r\n\r\n  /**\r\n   * Inspects an object.\r\n   *\r\n   * @see taken from node.js `util` module (copyright Joyent, MIT license)\r\n   * @api private\r\n   */\r\n\r\n  function i (obj, showHidden, depth) {\r\n    var seen = [];\r\n\r\n    function stylize (str) {\r\n      return str;\r\n    }\r\n\r\n    function format (value, recurseTimes) {\r\n      // Provide a hook for user-specified inspect functions.\r\n      // Check that value is an object with an inspect function on it\r\n      if (value && typeof value.inspect === 'function' &&\r\n          // Filter out the util module, it's inspect function is special\r\n          value !== exports &&\r\n          // Also filter out any prototype objects using the circular check.\r\n          !(value.constructor && value.constructor.prototype === value)) {\r\n        return value.inspect(recurseTimes);\r\n      }\r\n\r\n      // Primitive types cannot have properties\r\n      switch (typeof value) {\r\n        case 'undefined':\r\n          return stylize('undefined', 'undefined');\r\n\r\n        case 'string':\r\n          var simple = '\\'' + json.stringify(value).replace(/^\"|\"$/g, '')\r\n                                                   .replace(/'/g, \"\\\\'\")\r\n                                                   .replace(/\\\\\"/g, '\"') + '\\'';\r\n          return stylize(simple, 'string');\r\n\r\n        case 'number':\r\n          return stylize('' + value, 'number');\r\n\r\n        case 'boolean':\r\n          return stylize('' + value, 'boolean');\r\n      }\r\n      // For some reason typeof null is \"object\", so special case here.\r\n      if (value === null) {\r\n        return stylize('null', 'null');\r\n      }\r\n\r\n      if (isDOMElement(value)) {\r\n        return getOuterHTML(value);\r\n      }\r\n\r\n      // Look up the keys of the object.\r\n      var visible_keys = keys(value);\r\n      var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys;\r\n\r\n      // Functions without properties can be shortcutted.\r\n      if (typeof value === 'function' && $keys.length === 0) {\r\n        if (isRegExp(value)) {\r\n          return stylize('' + value, 'regexp');\r\n        } else {\r\n          var name = value.name ? ': ' + value.name : '';\r\n          return stylize('[Function' + name + ']', 'special');\r\n        }\r\n      }\r\n\r\n      // Dates without properties can be shortcutted\r\n      if (isDate(value) && $keys.length === 0) {\r\n        return stylize(value.toUTCString(), 'date');\r\n      }\r\n      \r\n      // Error objects can be shortcutted\r\n      if (value instanceof Error) {\r\n        return stylize(\"[\"+value.toString()+\"]\", 'Error');\r\n      }\r\n\r\n      var base, type, braces;\r\n      // Determine the object type\r\n      if (isArray(value)) {\r\n        type = 'Array';\r\n        braces = ['[', ']'];\r\n      } else {\r\n        type = 'Object';\r\n        braces = ['{', '}'];\r\n      }\r\n\r\n      // Make functions say that they are functions\r\n      if (typeof value === 'function') {\r\n        var n = value.name ? ': ' + value.name : '';\r\n        base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']';\r\n      } else {\r\n        base = '';\r\n      }\r\n\r\n      // Make dates with properties first say the date\r\n      if (isDate(value)) {\r\n        base = ' ' + value.toUTCString();\r\n      }\r\n\r\n      if ($keys.length === 0) {\r\n        return braces[0] + base + braces[1];\r\n      }\r\n\r\n      if (recurseTimes < 0) {\r\n        if (isRegExp(value)) {\r\n          return stylize('' + value, 'regexp');\r\n        } else {\r\n          return stylize('[Object]', 'special');\r\n        }\r\n      }\r\n\r\n      seen.push(value);\r\n\r\n      var output = map($keys, function (key) {\r\n        var name, str;\r\n        if (value.__lookupGetter__) {\r\n          if (value.__lookupGetter__(key)) {\r\n            if (value.__lookupSetter__(key)) {\r\n              str = stylize('[Getter/Setter]', 'special');\r\n            } else {\r\n              str = stylize('[Getter]', 'special');\r\n            }\r\n          } else {\r\n            if (value.__lookupSetter__(key)) {\r\n              str = stylize('[Setter]', 'special');\r\n            }\r\n          }\r\n        }\r\n        if (indexOf(visible_keys, key) < 0) {\r\n          name = '[' + key + ']';\r\n        }\r\n        if (!str) {\r\n          if (indexOf(seen, value[key]) < 0) {\r\n            if (recurseTimes === null) {\r\n              str = format(value[key]);\r\n            } else {\r\n              str = format(value[key], recurseTimes - 1);\r\n            }\r\n            if (str.indexOf('\\n') > -1) {\r\n              if (isArray(value)) {\r\n                str = map(str.split('\\n'), function (line) {\r\n                  return '  ' + line;\r\n                }).join('\\n').substr(2);\r\n              } else {\r\n                str = '\\n' + map(str.split('\\n'), function (line) {\r\n                  return '   ' + line;\r\n                }).join('\\n');\r\n              }\r\n            }\r\n          } else {\r\n            str = stylize('[Circular]', 'special');\r\n          }\r\n        }\r\n        if (typeof name === 'undefined') {\r\n          if (type === 'Array' && key.match(/^\\d+$/)) {\r\n            return str;\r\n          }\r\n          name = json.stringify('' + key);\r\n          if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\r\n            name = name.substr(1, name.length - 2);\r\n            name = stylize(name, 'name');\r\n          } else {\r\n            name = name.replace(/'/g, \"\\\\'\")\r\n                       .replace(/\\\\\"/g, '\"')\r\n                       .replace(/(^\"|\"$)/g, \"'\");\r\n            name = stylize(name, 'string');\r\n          }\r\n        }\r\n\r\n        return name + ': ' + str;\r\n      });\r\n\r\n      seen.pop();\r\n\r\n      var numLinesEst = 0;\r\n      var length = reduce(output, function (prev, cur) {\r\n        numLinesEst++;\r\n        if (indexOf(cur, '\\n') >= 0) numLinesEst++;\r\n        return prev + cur.length + 1;\r\n      }, 0);\r\n\r\n      if (length > 50) {\r\n        output = braces[0] +\r\n                 (base === '' ? '' : base + '\\n ') +\r\n                 ' ' +\r\n                 output.join(',\\n  ') +\r\n                 ' ' +\r\n                 braces[1];\r\n\r\n      } else {\r\n        output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\r\n      }\r\n\r\n      return output;\r\n    }\r\n    return format(obj, (typeof depth === 'undefined' ? 2 : depth));\r\n  }\r\n\r\n  expect.stringify = i;\r\n\r\n  function isArray (ar) {\r\n    return Object.prototype.toString.call(ar) === '[object Array]';\r\n  }\r\n\r\n  function isRegExp(re) {\r\n    var s;\r\n    try {\r\n      s = '' + re;\r\n    } catch (e) {\r\n      return false;\r\n    }\r\n\r\n    return re instanceof RegExp || // easy case\r\n           // duck-type for context-switching evalcx case\r\n           typeof(re) === 'function' &&\r\n           re.constructor.name === 'RegExp' &&\r\n           re.compile &&\r\n           re.test &&\r\n           re.exec &&\r\n           s.match(/^\\/.*\\/[gim]{0,3}$/);\r\n  }\r\n\r\n  function isDate(d) {\r\n    return d instanceof Date;\r\n  }\r\n\r\n  function keys (obj) {\r\n    if (Object.keys) {\r\n      return Object.keys(obj);\r\n    }\r\n\r\n    var keys = [];\r\n\r\n    for (var i in obj) {\r\n      if (Object.prototype.hasOwnProperty.call(obj, i)) {\r\n        keys.push(i);\r\n      }\r\n    }\r\n\r\n    return keys;\r\n  }\r\n\r\n  function map (arr, mapper, that) {\r\n    if (Array.prototype.map) {\r\n      return Array.prototype.map.call(arr, mapper, that);\r\n    }\r\n\r\n    var other= new Array(arr.length);\r\n\r\n    for (var i= 0, n = arr.length; i<n; i++)\r\n      if (i in arr)\r\n        other[i] = mapper.call(that, arr[i], i, arr);\r\n\r\n    return other;\r\n  }\r\n\r\n  function reduce (arr, fun) {\r\n    if (Array.prototype.reduce) {\r\n      return Array.prototype.reduce.apply(\r\n          arr\r\n        , Array.prototype.slice.call(arguments, 1)\r\n      );\r\n    }\r\n\r\n    var len = +this.length;\r\n\r\n    if (typeof fun !== \"function\")\r\n      throw new TypeError();\r\n\r\n    // no value to return if no initial value and an empty array\r\n    if (len === 0 && arguments.length === 1)\r\n      throw new TypeError();\r\n\r\n    var i = 0;\r\n    if (arguments.length >= 2) {\r\n      var rv = arguments[1];\r\n    } else {\r\n      do {\r\n        if (i in this) {\r\n          rv = this[i++];\r\n          break;\r\n        }\r\n\r\n        // if array contains no values, no initial value to return\r\n        if (++i >= len)\r\n          throw new TypeError();\r\n      } while (true);\r\n    }\r\n\r\n    for (; i < len; i++) {\r\n      if (i in this)\r\n        rv = fun.call(null, rv, this[i], i, this);\r\n    }\r\n\r\n    return rv;\r\n  }\r\n\r\n  /**\r\n   * Asserts deep equality\r\n   *\r\n   * @see taken from node.js `assert` module (copyright Joyent, MIT license)\r\n   * @api private\r\n   */\r\n\r\n  expect.eql = function eql(actual, expected) {\r\n    // 7.1. All identical values are equivalent, as determined by ===.\r\n    if (actual === expected) {\r\n      return true;\r\n    } else if ('undefined' != typeof Buffer\r\n      && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {\r\n      if (actual.length != expected.length) return false;\r\n\r\n      for (var i = 0; i < actual.length; i++) {\r\n        if (actual[i] !== expected[i]) return false;\r\n      }\r\n\r\n      return true;\r\n\r\n      // 7.2. If the expected value is a Date object, the actual value is\r\n      // equivalent if it is also a Date object that refers to the same time.\r\n    } else if (actual instanceof Date && expected instanceof Date) {\r\n      return actual.getTime() === expected.getTime();\r\n\r\n      // 7.3. Other pairs that do not both pass typeof value == \"object\",\r\n      // equivalence is determined by ==.\r\n    } else if (typeof actual != 'object' && typeof expected != 'object') {\r\n      return actual == expected;\r\n    // If both are regular expression use the special `regExpEquiv` method\r\n    // to determine equivalence.\r\n    } else if (isRegExp(actual) && isRegExp(expected)) {\r\n      return regExpEquiv(actual, expected);\r\n    // 7.4. For all other Object pairs, including Array objects, equivalence is\r\n    // determined by having the same number of owned properties (as verified\r\n    // with Object.prototype.hasOwnProperty.call), the same set of keys\r\n    // (although not necessarily the same order), equivalent values for every\r\n    // corresponding key, and an identical \"prototype\" property. Note: this\r\n    // accounts for both named and indexed properties on Arrays.\r\n    } else {\r\n      return objEquiv(actual, expected);\r\n    }\r\n  };\r\n\r\n  function isUndefinedOrNull (value) {\r\n    return value === null || value === undefined;\r\n  }\r\n\r\n  function isArguments (object) {\r\n    return Object.prototype.toString.call(object) == '[object Arguments]';\r\n  }\r\n\r\n  function regExpEquiv (a, b) {\r\n    return a.source === b.source && a.global === b.global &&\r\n           a.ignoreCase === b.ignoreCase && a.multiline === b.multiline;\r\n  }\r\n\r\n  function objEquiv (a, b) {\r\n    if (isUndefinedOrNull(a) || isUndefinedOrNull(b))\r\n      return false;\r\n    // an identical \"prototype\" property.\r\n    if (a.prototype !== b.prototype) return false;\r\n    //~~~I've managed to break Object.keys through screwy arguments passing.\r\n    //   Converting to array solves the problem.\r\n    if (isArguments(a)) {\r\n      if (!isArguments(b)) {\r\n        return false;\r\n      }\r\n      a = pSlice.call(a);\r\n      b = pSlice.call(b);\r\n      return expect.eql(a, b);\r\n    }\r\n    try{\r\n      var ka = keys(a),\r\n        kb = keys(b),\r\n        key, i;\r\n    } catch (e) {//happens when one is a string literal and the other isn't\r\n      return false;\r\n    }\r\n    // having the same number of owned properties (keys incorporates hasOwnProperty)\r\n    if (ka.length != kb.length)\r\n      return false;\r\n    //the same set of keys (although not necessarily the same order),\r\n    ka.sort();\r\n    kb.sort();\r\n    //~~~cheap key test\r\n    for (i = ka.length - 1; i >= 0; i--) {\r\n      if (ka[i] != kb[i])\r\n        return false;\r\n    }\r\n    //equivalent values for every corresponding key, and\r\n    //~~~possibly expensive deep test\r\n    for (i = ka.length - 1; i >= 0; i--) {\r\n      key = ka[i];\r\n      if (!expect.eql(a[key], b[key]))\r\n         return false;\r\n    }\r\n    return true;\r\n  }\r\n\r\n  var json = (function () {\r\n    \"use strict\";\r\n\r\n    if ('object' == typeof JSON && JSON.parse && JSON.stringify) {\r\n      return {\r\n          parse: nativeJSON.parse\r\n        , stringify: nativeJSON.stringify\r\n      }\r\n    }\r\n\r\n    var JSON = {};\r\n\r\n    function f(n) {\r\n        // Format integers to have at least two digits.\r\n        return n < 10 ? '0' + n : n;\r\n    }\r\n\r\n    function date(d, key) {\r\n      return isFinite(d.valueOf()) ?\r\n          d.getUTCFullYear()     + '-' +\r\n          f(d.getUTCMonth() + 1) + '-' +\r\n          f(d.getUTCDate())      + 'T' +\r\n          f(d.getUTCHours())     + ':' +\r\n          f(d.getUTCMinutes())   + ':' +\r\n          f(d.getUTCSeconds())   + 'Z' : null;\r\n    }\r\n\r\n    var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\r\n        escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\r\n        gap,\r\n        indent,\r\n        meta = {    // table of character substitutions\r\n            '\\b': '\\\\b',\r\n            '\\t': '\\\\t',\r\n            '\\n': '\\\\n',\r\n            '\\f': '\\\\f',\r\n            '\\r': '\\\\r',\r\n            '\"' : '\\\\\"',\r\n            '\\\\': '\\\\\\\\'\r\n        },\r\n        rep;\r\n\r\n\r\n    function quote(string) {\r\n\r\n  // If the string contains no control characters, no quote characters, and no\r\n  // backslash characters, then we can safely slap some quotes around it.\r\n  // Otherwise we must also replace the offending characters with safe escape\r\n  // sequences.\r\n\r\n        escapable.lastIndex = 0;\r\n        return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\r\n            var c = meta[a];\r\n            return typeof c === 'string' ? c :\r\n                '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\r\n        }) + '\"' : '\"' + string + '\"';\r\n    }\r\n\r\n\r\n    function str(key, holder) {\r\n\r\n  // Produce a string from holder[key].\r\n\r\n        var i,          // The loop counter.\r\n            k,          // The member key.\r\n            v,          // The member value.\r\n            length,\r\n            mind = gap,\r\n            partial,\r\n            value = holder[key];\r\n\r\n  // If the value has a toJSON method, call it to obtain a replacement value.\r\n\r\n        if (value instanceof Date) {\r\n            value = date(key);\r\n        }\r\n\r\n  // If we were called with a replacer function, then call the replacer to\r\n  // obtain a replacement value.\r\n\r\n        if (typeof rep === 'function') {\r\n            value = rep.call(holder, key, value);\r\n        }\r\n\r\n  // What happens next depends on the value's type.\r\n\r\n        switch (typeof value) {\r\n        case 'string':\r\n            return quote(value);\r\n\r\n        case 'number':\r\n\r\n  // JSON numbers must be finite. Encode non-finite numbers as null.\r\n\r\n            return isFinite(value) ? String(value) : 'null';\r\n\r\n        case 'boolean':\r\n        case 'null':\r\n\r\n  // If the value is a boolean or null, convert it to a string. Note:\r\n  // typeof null does not produce 'null'. The case is included here in\r\n  // the remote chance that this gets fixed someday.\r\n\r\n            return String(value);\r\n\r\n  // If the type is 'object', we might be dealing with an object or an array or\r\n  // null.\r\n\r\n        case 'object':\r\n\r\n  // Due to a specification blunder in ECMAScript, typeof null is 'object',\r\n  // so watch out for that case.\r\n\r\n            if (!value) {\r\n                return 'null';\r\n            }\r\n\r\n  // Make an array to hold the partial results of stringifying this object value.\r\n\r\n            gap += indent;\r\n            partial = [];\r\n\r\n  // Is the value an array?\r\n\r\n            if (Object.prototype.toString.apply(value) === '[object Array]') {\r\n\r\n  // The value is an array. Stringify every element. Use null as a placeholder\r\n  // for non-JSON values.\r\n\r\n                length = value.length;\r\n                for (i = 0; i < length; i += 1) {\r\n                    partial[i] = str(i, value) || 'null';\r\n                }\r\n\r\n  // Join all of the elements together, separated with commas, and wrap them in\r\n  // brackets.\r\n\r\n                v = partial.length === 0 ? '[]' : gap ?\r\n                    '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\r\n                    '[' + partial.join(',') + ']';\r\n                gap = mind;\r\n                return v;\r\n            }\r\n\r\n  // If the replacer is an array, use it to select the members to be stringified.\r\n\r\n            if (rep && typeof rep === 'object') {\r\n                length = rep.length;\r\n                for (i = 0; i < length; i += 1) {\r\n                    if (typeof rep[i] === 'string') {\r\n                        k = rep[i];\r\n                        v = str(k, value);\r\n                        if (v) {\r\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\r\n                        }\r\n                    }\r\n                }\r\n            } else {\r\n\r\n  // Otherwise, iterate through all of the keys in the object.\r\n\r\n                for (k in value) {\r\n                    if (Object.prototype.hasOwnProperty.call(value, k)) {\r\n                        v = str(k, value);\r\n                        if (v) {\r\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n  // Join all of the member texts together, separated with commas,\r\n  // and wrap them in braces.\r\n\r\n            v = partial.length === 0 ? '{}' : gap ?\r\n                '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\r\n                '{' + partial.join(',') + '}';\r\n            gap = mind;\r\n            return v;\r\n        }\r\n    }\r\n\r\n  // If the JSON object does not yet have a stringify method, give it one.\r\n\r\n    JSON.stringify = function (value, replacer, space) {\r\n\r\n  // The stringify method takes a value and an optional replacer, and an optional\r\n  // space parameter, and returns a JSON text. The replacer can be a function\r\n  // that can replace values, or an array of strings that will select the keys.\r\n  // A default replacer method can be provided. Use of the space parameter can\r\n  // produce text that is more easily readable.\r\n\r\n        var i;\r\n        gap = '';\r\n        indent = '';\r\n\r\n  // If the space parameter is a number, make an indent string containing that\r\n  // many spaces.\r\n\r\n        if (typeof space === 'number') {\r\n            for (i = 0; i < space; i += 1) {\r\n                indent += ' ';\r\n            }\r\n\r\n  // If the space parameter is a string, it will be used as the indent string.\r\n\r\n        } else if (typeof space === 'string') {\r\n            indent = space;\r\n        }\r\n\r\n  // If there is a replacer, it must be a function or an array.\r\n  // Otherwise, throw an error.\r\n\r\n        rep = replacer;\r\n        if (replacer && typeof replacer !== 'function' &&\r\n                (typeof replacer !== 'object' ||\r\n                typeof replacer.length !== 'number')) {\r\n            throw new Error('JSON.stringify');\r\n        }\r\n\r\n  // Make a fake root object containing our value under the key of ''.\r\n  // Return the result of stringifying the value.\r\n\r\n        return str('', {'': value});\r\n    };\r\n\r\n  // If the JSON object does not yet have a parse method, give it one.\r\n\r\n    JSON.parse = function (text, reviver) {\r\n    // The parse method takes a text and an optional reviver function, and returns\r\n    // a JavaScript value if the text is a valid JSON text.\r\n\r\n        var j;\r\n\r\n        function walk(holder, key) {\r\n\r\n    // The walk method is used to recursively walk the resulting structure so\r\n    // that modifications can be made.\r\n\r\n            var k, v, value = holder[key];\r\n            if (value && typeof value === 'object') {\r\n                for (k in value) {\r\n                    if (Object.prototype.hasOwnProperty.call(value, k)) {\r\n                        v = walk(value, k);\r\n                        if (v !== undefined) {\r\n                            value[k] = v;\r\n                        } else {\r\n                            delete value[k];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            return reviver.call(holder, key, value);\r\n        }\r\n\r\n\r\n    // Parsing happens in four stages. In the first stage, we replace certain\r\n    // Unicode characters with escape sequences. JavaScript handles many characters\r\n    // incorrectly, either silently deleting them, or treating them as line endings.\r\n\r\n        text = String(text);\r\n        cx.lastIndex = 0;\r\n        if (cx.test(text)) {\r\n            text = text.replace(cx, function (a) {\r\n                return '\\\\u' +\r\n                    ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\r\n            });\r\n        }\r\n\r\n    // In the second stage, we run the text against regular expressions that look\r\n    // for non-JSON patterns. We are especially concerned with '()' and 'new'\r\n    // because they can cause invocation, and '=' because it can cause mutation.\r\n    // But just to be safe, we want to reject all unexpected forms.\r\n\r\n    // We split the second stage into 4 regexp operations in order to work around\r\n    // crippling inefficiencies in IE's and Safari's regexp engines. First we\r\n    // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we\r\n    // replace all simple value tokens with ']' characters. Third, we delete all\r\n    // open brackets that follow a colon or comma or that begin the text. Finally,\r\n    // we look to see that the remaining characters are only whitespace or ']' or\r\n    // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\r\n\r\n        if (/^[\\],:{}\\s]*$/\r\n                .test(text.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')\r\n                    .replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']')\r\n                    .replace(/(?:^|:|,)(?:\\s*\\[)+/g, ''))) {\r\n\r\n    // In the third stage we use the eval function to compile the text into a\r\n    // JavaScript structure. The '{' operator is subject to a syntactic ambiguity\r\n    // in JavaScript: it can begin a block or an object literal. We wrap the text\r\n    // in parens to eliminate the ambiguity.\r\n\r\n            j = eval('(' + text + ')');\r\n\r\n    // In the optional fourth stage, we recursively walk the new structure, passing\r\n    // each name/value pair to a reviver function for possible transformation.\r\n\r\n            return typeof reviver === 'function' ?\r\n                walk({'': j}, '') : j;\r\n        }\r\n\r\n    // If the text is not JSON parseable, then a SyntaxError is thrown.\r\n\r\n        throw new SyntaxError('JSON.parse');\r\n    };\r\n\r\n    return JSON;\r\n  })();\r\n\r\n  if ('undefined' != typeof window) {\r\n    window.expect = module.exports;\r\n  }\r\n\r\n})(\r\n    this\r\n  , 'undefined' != typeof module ? module : {exports: {}}\r\n);"
  },
  {
    "path": "test/gun.html",
    "content": "<script src=\"../examples/jquery.js\"></script>\n<script src=\"../gun.js\"></script>\n<script>\nvar gun = Gun('http://localhost:8765/gun');\n</script>"
  },
  {
    "path": "test/https/ca.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIICjzCCAfgCCQDubvP01FilhzANBgkqhkiG9w0BAQUFADCBizELMAkGA1UEBhMC\nVVMxGTAXBgNVBAgTEENhbGlmb3JuaWEtU3RhdGUxFTATBgNVBAcTDFJlZHdvb2Qg\nQ2l0eTEPMA0GA1UEChMGR1VOSU5DMQwwCgYDVQQLEwN3ZWIxDTALBgNVBAMTBG1h\ncmsxHDAaBgkqhkiG9w0BCQEWDW1hcmtAZ3VuREIuaW8wHhcNMTgwMTI5MjExMjAx\nWhcNMTkwMTI5MjExMjAxWjCBizELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEENhbGlm\nb3JuaWEtU3RhdGUxFTATBgNVBAcTDFJlZHdvb2QgQ2l0eTEPMA0GA1UEChMGR1VO\nSU5DMQwwCgYDVQQLEwN3ZWIxDTALBgNVBAMTBG1hcmsxHDAaBgkqhkiG9w0BCQEW\nDW1hcmtAZ3VuREIuaW8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMLWuNOJ\n1BWGKZtSh1NPAIpfeb7l2tFq7kIFSdxXg/+sb8b8CT5+nZPd+p8PDLR/pGab5dKg\ngjh+Gr4ixAPgXbabLq8aWlKKHUNi5APfUii3qWAvpHTxfDzor1KwHCU0sU6PrMz0\nvKkG8rpCt3nKom8roWChG9NEVdm3tO9Q2SOJAgMBAAEwDQYJKoZIhvcNAQEFBQAD\ngYEAYbPdLZGAbs/boDECu9qxAdlEC8zTXTRQwlBbKgiNsZjJPskczbfvKLgVbcaK\n0FMqzIi/OYSb15XgSu1j4WvitoZqiMr89H05w7N6Et/SnEFxAfDZc+UvlrvsKKeX\n/eTDcEaTl+nNEMuyX3+UzziAa0Pytdmd5tiWNm4gTMPb4AM=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "test/https/ca.csr",
    "content": "-----BEGIN CERTIFICATE REQUEST-----\nMIIB+DCCAWECAQAwgYsxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBDYWxpZm9ybmlh\nLVN0YXRlMRUwEwYDVQQHEwxSZWR3b29kIENpdHkxDzANBgNVBAoTBkdVTklOQzEM\nMAoGA1UECxMDd2ViMQ0wCwYDVQQDEwRtYXJrMRwwGgYJKoZIhvcNAQkBFg1tYXJr\nQGd1bkRCLmlvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC1rjTidQVhimb\nUodTTwCKX3m+5drRau5CBUncV4P/rG/G/Ak+fp2T3fqfDwy0f6Rmm+XSoII4fhq+\nIsQD4F22my6vGlpSih1DYuQD31Iot6lgL6R08Xw86K9SsBwlNLFOj6zM9LypBvK6\nQrd5yqJvK6FgoRvTRFXZt7TvUNkjiQIDAQABoCwwEgYJKoZIhvcNAQkCMQUTA2d1\nbjAWBgkqhkiG9w0BCQcxCRMHY29va2llczANBgkqhkiG9w0BAQUFAAOBgQBoYOzr\ng0wgtICI5XQTVz4uh3fZPpOUwypZO4EGOOrXixoLtMqHUo1Im+3yC8F7QVnWeBB2\nM3eXWCf1E4FthYlVBS1S8nkMxDuG2v1GvmxDa0ZCbG4lhNpUeL31rth7R3vtxBZI\nSc4hRkqz5s/xe3VZ3TJnQYRufNq4Ve95cx7/ow==\n-----END CERTIFICATE REQUEST-----\n"
  },
  {
    "path": "test/https/ca.key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,CC0029B0687E54A1\n\nucowo8yAKtQZMhvRhi5LLPekwsZifKjnW6zEA3OBP1UiNmbppGESmbf2mbRwalic\ne77nC0iUdJjwSjnGcLk05fAP7SoQV1IlWbmk3xhvk/TewWZnwhelwfhYv/NNFJ4K\n8oXtYi0d4KquadxmUlvXssUj2ycbmJ1QPj/xo0fu74O6BO884ssn4BCuCLh34gRQ\nKsEZVIuuB6PHdh5kfzaaFCLYP3rt2t3zFTZ3PpzV52YnxI+dqMcMVB1baMv7Cl4o\nnIap2LZwF6KzCihZx1PiMS1KxWPoylSe66vltbLX+Vu9AY4TS/+15ccpJDMI8FkK\nv3o0sL3Cvd6sXGHjcKehhFnzmfljJPhf0OhhZvEG0y0xjG3nJ85k4BgF4g1v3J5D\nRX3YTUoUeKcMATL6JFn+R38TiQL7COQSf3gsrUxkyD5md8P+I6nW5RNjwI9miVTu\nkAm/m4MsfEf/semzx4DHrm8Qvc01j6nsQ1zKjSVhhn5Utx8UGQgcKMz8GotH/bVY\nPo0Ra5d0zk6pGRD4CEjKZFvwjMyydod8N8EY92X/awwYiY3lcF1L6wyz3d11yfRT\naL+yCuIhMVMU50X0DXTnfHnK59F6gsv7hosLUSV0gksQ6SJaTt9PLKyBblwTGsRa\nZkhM+tBJiJ8C/AFEuCTEjI8Pp2BXW6W4J+mOMwyJzvR4Vs5S5/Qf/Y6JQAt8uRPH\nWTtucevP1DDxayQWwGocbtW148ZSGOVKD9V45L9CbNejilpVi4dGWZoRWd3KXYNy\nNSvVSCA9kWGciJGUpowxvsINzuGO5fvsKIntrhVoumPiphQPTmZFDw==\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "test/https/server.crt",
    "content": "-----BEGIN CERTIFICATE-----\nMIICjzCCAfgCCQCghTkg/FWMvjANBgkqhkiG9w0BAQUFADCBizELMAkGA1UEBhMC\nVVMxGTAXBgNVBAgTEENhbGlmb3JuaWEtU3RhdGUxFTATBgNVBAcTDFJlZHdvb2Qg\nQ2l0eTEPMA0GA1UEChMGR1VOSU5DMQwwCgYDVQQLEwN3ZWIxDTALBgNVBAMTBG1h\ncmsxHDAaBgkqhkiG9w0BCQEWDW1hcmtAZ3VuREIuaW8wHhcNMTgwMTI5MjExNDE1\nWhcNMTkwMTI5MjExNDE1WjCBizELMAkGA1UEBhMCVVMxGTAXBgNVBAgTEENhbGlm\nb3JuaWEtU3RhdGUxFTATBgNVBAcTDFJlZHdvb2QgQ2l0eTEPMA0GA1UEChMGR1VO\nSU5DMQwwCgYDVQQLEwN3ZWIxDTALBgNVBAMTBG1hcmsxHDAaBgkqhkiG9w0BCQEW\nDW1hcmtAZ3VuREIuaW8wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALAQyUjI\noRMInF6q1bevlxUUP/V0wo1TwoE5VG4VyEqoVzcD/idWzMdjDIQ80qUnWFE1LdBs\nxNntWzOi2xq+YgkMIJYVZ3uqU10m2EpKehsBpGHSwkkxNl1btiTd8nzi/cxeMtNs\nPzh7VCOcdOYYcCDpGV1YVBjgbviAaW/3xielAgMBAAEwDQYJKoZIhvcNAQEFBQAD\ngYEAbNm8gaD4Y3/LyeGyMmaFUS0d6bxon2QybpdW9y1gzsMH1eHL/GJZg6DzG1d5\n9VDV+7yym293cyvgd41UTRg2Wdq/ev6D/gPiewEc/OYQsMXWvsMGXNUDFar9W+lB\n2RlwZFfdO55S26lS8RAOrhqkXz7TEprUYXi8+y1vUcXI1i8=\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "test/https/server.csr",
    "content": "-----BEGIN CERTIFICATE REQUEST-----\nMIIB+DCCAWECAQAwgYsxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBDYWxpZm9ybmlh\nLVN0YXRlMRUwEwYDVQQHEwxSZWR3b29kIENpdHkxDzANBgNVBAoTBkdVTklOQzEM\nMAoGA1UECxMDd2ViMQ0wCwYDVQQDEwRtYXJrMRwwGgYJKoZIhvcNAQkBFg1tYXJr\nQGd1bkRCLmlvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwEMlIyKETCJxe\nqtW3r5cVFD/1dMKNU8KBOVRuFchKqFc3A/4nVszHYwyEPNKlJ1hRNS3QbMTZ7Vsz\notsavmIJDCCWFWd7qlNdJthKSnobAaRh0sJJMTZdW7Yk3fJ84v3MXjLTbD84e1Qj\nnHTmGHAg6RldWFQY4G74gGlv98YnpQIDAQABoCwwEgYJKoZIhvcNAQkCMQUTA2d1\nbjAWBgkqhkiG9w0BCQcxCRMHY29va2llczANBgkqhkiG9w0BAQUFAAOBgQBrEA3w\nwaExtouDsYND3oSbCD87jDMh+uRxOuRqfeAky1juGFILslBWY4kXgUrcOOV92XNf\nM2CUePQ136M7oTS2HOajXDu4IVJRhWKqexoQrcWQ3w7+8e75NaXh2/9wg2KqqZfv\n07MlphBb8Si6M3VNTHMmxfYWT0GozfsLezjeww==\n-----END CERTIFICATE REQUEST-----\n"
  },
  {
    "path": "test/https/server.key",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQCwEMlIyKETCJxeqtW3r5cVFD/1dMKNU8KBOVRuFchKqFc3A/4n\nVszHYwyEPNKlJ1hRNS3QbMTZ7VszotsavmIJDCCWFWd7qlNdJthKSnobAaRh0sJJ\nMTZdW7Yk3fJ84v3MXjLTbD84e1QjnHTmGHAg6RldWFQY4G74gGlv98YnpQIDAQAB\nAoGBAJrSF/2tlp5jGwXP2WDNwd/iT5+qzY1zEv2JCSpIczjbMN4K38l99VJ7Ub1S\nsrRRlcLLLX8ytiMgKeuNEHhC43a11nL2XdDN9YpiINWX251ynfJSF6cr7oiMbajy\nJtrk9zLIjRBdA2IBZ+q6APQNWqDD/dZM5sMBZguKokKhVOcdAkEA1Vsnqjda+0c9\n/655PSHYOplktq4fXbumgPW8jLZ2pCY6mASupg1DoRh3FoEbzRQxfoiH25/wklOv\nXUb/hKFlXwJBANNBlB7byF+p3zIPIi1WLRSrM5/RJsj3SPRWePVrWx1aEt/sa+uW\nGfxfLzDvLvLxXboUH0FuW4FaBxeISNqPbXsCQF43s+tyKIZgrptTZAy//mnaRWR6\nvjU5Ycz/N7V3+iqBC00IfEut/diNIkHY3/sPWNAE4OH23ljwBbgOW1Ypo8cCQQCQ\nr2hX3iUUx84yhcTdkhjcAAkiWueaWiqgFZ1QUI+dwbQNoumi9zGi9Dno5Ned0gtk\nRyXE9WU8aUFUL6Xd8r+DAkBoU5tC+1O2knhc7WJgQjHdz4O4ixvcD5n3/2Kmm8u0\nrS1Q5rKi2i5jy+JKCjD6N7ojk5Xy4iRG+71324EWbsmX\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "test/https/server.key.passphrase",
    "content": "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,8F695953B60CC993\n\nELvHJ4C9vhAgsQTUayaAYBLWYaV/BGbltI7f5BYwnc0TDSzWIZHwd06sF43rNPOW\nyfsdIV24MF5mOKG4FztwufME0yIZmkoMILCZvNj5XpyXCYRIsDwdMzd9YcTpqa5Q\nlBU88MNHf+OFVIowAGRMGYeg5lEt6WXSS3DOhLFfdfY/A3Gseb8QLfz+ctYQrXC2\ntRFiN8qf/+VZ0M+auo1eK7VUSqRsf/tQLl01CBM68++SAQzTNczVaftfzHWLavj7\nQyNfAeVWPLfUIhZcZxFT5Y7zcvhkl7Jtts0hSBIGw0ceGYh1rBNcLT+pYWIZv9Nl\nCVhov4d1O6DM4ufOvXem4ywaUd+f15rkqaMHVa3ltQ+pveXgveoJZO2Zl2z4MctS\nolJZmU5PdFSxrajQfze4W0aBB7lF49JpmFow5ZE5xek5A+B//+cCYYbIT4GG8ep2\n6HIiapH2IOgQBxtRYYtWd8FUWpR+GwshxNUvD63d2CJvYxigMP95uD40bZg1SGjp\nup7yqM6s9F66bEpp71Zl5rVo4+eA1u5aQ4E684QT5DWao6bf7UKiP3gFR1iK4AJi\nWXpQNMh39TpETb8BYcHNs6QyP0Wy04g8OKJqjJy6HgIWiwc/6qVuYl6o22+mjenH\nphAEFIOxTSBtPjfldkkCWQ48seDxJQIZ1jSf9c2X/e323PvSohhqjZchr751nRxk\nx+sU/91SDpYw/97vQDYgjOFGPXkf1s+cnaZ1wh68UNxJI3Keqsg65lyvdX4o8/Ho\n0dl8V8SVZbbvYDnS3MuMoL+xXNhPj2lkALDGqvLVjwemiPSg8TBgHA==\n-----END RSA PRIVATE KEY-----\n"
  },
  {
    "path": "test/https/test.js",
    "content": "module.exports = function(port, file, cb, inject){\n\tport = port || process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8765;\n\n\tvar fs = require('fs');\n\tvar Gun = require(__dirname+'/../../');\n\n\tvar server = require('https').createServer({\n\t\tkey: fs.readFileSync(__dirname+'/server.key'),\n\t\tcert: fs.readFileSync(__dirname+'/server.crt'),\n\t\tca: fs.readFileSync(__dirname+'/ca.crt'),\n\t\trequestCert: true,\n\t\trejectUnauthorized: false\n\t},function(req, res){\n\t\tif(Gun.serve(req, res)){ return } // filters gun requests!\n\t\tvar file;\n\t\ttry{file = require('fs').readFileSync(require('path').join(__dirname+'/../../examples', req.url))\n\t\t}catch(e){ file = require('fs').readFileSync(require('path').join(__dirname+'/../../examples', 'index.html')) }\n\t\tif(inject){\n\t\t\tfile = inject(file, req, res) || file;\n\t\t}\n\t\tres.end(file);\n\t});\n\n\tvar gun = Gun({\n\t\tfile: file || 'data',\n\t\tweb: server,\n\t\tlocalStorage: false\n\t});\n\n\tserver.listen(port, cb);\n\n\tconsole.log('Server started on port ' + port + ' with /gun');\n}"
  },
  {
    "path": "test/hub/.hubignore",
    "content": "/whatever/aws-key.txt"
  },
  {
    "path": "test/hub/hub-test.js",
    "content": "const Gun = require('../..');\nconst gun = Gun();\n\ngun.get('hub').on(data => {\n    console.log(data)\n})\n\nconst hub = require('../../lib/hub');\nhub.watch(__dirname, {msg: true, hubignore: true, alias:require('os').userInfo().username})"
  },
  {
    "path": "test/hub/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Document</title>\n</head>\n<body>\n    <div>Hi!</div>\n</body>\n</html>"
  },
  {
    "path": "test/hub/whatever/aws-key.txt",
    "content": "I'M A SUPER SECRET KEY WHICH SHALL NOT BE LEAKED \nFOR YOUR OWN SAKE."
  },
  {
    "path": "test/index.js",
    "content": "/*\n\n// Let's do all old-fashion require stuff before '@std/mjs' steps in...\nconst Gun = require('../gun')\n\nif (process.env.SEA) {\n  Gun.SEA = require('../sea')\n}\nrequire('../lib/file')\n\nconst myDir = __dirname // TODO: where did __dirname go ?\n\n// From here on we're ES6 import compatible...\nrequire = require('@std/esm')(module) // eslint-disable-line no-global-assign\n\nmodule.exports = require('../lib/server.mjs').default(Gun, myDir)\n\n*/"
  },
  {
    "path": "test/json2.js",
    "content": "/*\n    http://www.JSON.org/json2.js\n    2011-02-23\n\n    Public Domain.\n\n    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\n\n    See http://www.JSON.org/js.html\n\n\n    This code should be minified before deployment.\n    See http://javascript.crockford.com/jsmin.html\n\n    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO\n    NOT CONTROL.\n\n\n    This file creates a global JSON object containing two methods: stringify\n    and parse.\n\n        JSON.stringify(value, replacer, space)\n            value       any JavaScript value, usually an object or array.\n\n            replacer    an optional parameter that determines how object\n                        values are stringified for objects. It can be a\n                        function or an array of strings.\n\n            space       an optional parameter that specifies the indentation\n                        of nested structures. If it is omitted, the text will\n                        be packed without extra whitespace. If it is a number,\n                        it will specify the number of spaces to indent at each\n                        level. If it is a string (such as '\\t' or '&nbsp;'),\n                        it contains the characters used to indent at each level.\n\n            This method produces a JSON text from a JavaScript value.\n\n            When an object value is found, if the object contains a toJSON\n            method, its toJSON method will be called and the result will be\n            stringified. A toJSON method does not serialize: it returns the\n            value represented by the name/value pair that should be serialized,\n            or undefined if nothing should be serialized. The toJSON method\n            will be passed the key associated with the value, and this will be\n            bound to the value\n\n            For example, this would serialize Dates as ISO strings.\n\n                Date.prototype.toJSON = function (key) {\n                    function f(n) {\n                        // Format integers to have at least two digits.\n                        return n < 10 ? '0' + n : n;\n                    }\n\n                    return this.getUTCFullYear()   + '-' +\n                         f(this.getUTCMonth() + 1) + '-' +\n                         f(this.getUTCDate())      + 'T' +\n                         f(this.getUTCHours())     + ':' +\n                         f(this.getUTCMinutes())   + ':' +\n                         f(this.getUTCSeconds())   + 'Z';\n                };\n\n            You can provide an optional replacer method. It will be passed the\n            key and value of each member, with this bound to the containing\n            object. The value that is returned from your method will be\n            serialized. If your method returns undefined, then the member will\n            be excluded from the serialization.\n\n            If the replacer parameter is an array of strings, then it will be\n            used to select the members to be serialized. It filters the results\n            such that only members with keys listed in the replacer array are\n            stringified.\n\n            Values that do not have JSON representations, such as undefined or\n            functions, will not be serialized. Such values in objects will be\n            dropped; in arrays they will be replaced with null. You can use\n            a replacer function to replace those with JSON values.\n            JSON.stringify(undefined) returns undefined.\n\n            The optional space parameter produces a stringification of the\n            value that is filled with line breaks and indentation to make it\n            easier to read.\n\n            If the space parameter is a non-empty string, then that string will\n            be used for indentation. If the space parameter is a number, then\n            the indentation will be that many spaces.\n\n            Example:\n\n            text = JSON.stringify(['e', {pluribus: 'unum'}]);\n            // text is '[\"e\",{\"pluribus\":\"unum\"}]'\n\n\n            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\\t');\n            // text is '[\\n\\t\"e\",\\n\\t{\\n\\t\\t\"pluribus\": \"unum\"\\n\\t}\\n]'\n\n            text = JSON.stringify([new Date()], function (key, value) {\n                return this[key] instanceof Date ?\n                    'Date(' + this[key] + ')' : value;\n            });\n            // text is '[\"Date(---current time---)\"]'\n\n\n        JSON.parse(text, reviver)\n            This method parses a JSON text to produce an object or array.\n            It can throw a SyntaxError exception.\n\n            The optional reviver parameter is a function that can filter and\n            transform the results. It receives each of the keys and values,\n            and its return value is used instead of the original value.\n            If it returns what it received, then the structure is not modified.\n            If it returns undefined then the member is deleted.\n\n            Example:\n\n            // Parse the text. Values that look like ISO date strings will\n            // be converted to Date objects.\n\n            myData = JSON.parse(text, function (key, value) {\n                var a;\n                if (typeof value === 'string') {\n                    a =\n/^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*)?)Z$/.exec(value);\n                    if (a) {\n                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],\n                            +a[5], +a[6]));\n                    }\n                }\n                return value;\n            });\n\n            myData = JSON.parse('[\"Date(09/09/2001)\"]', function (key, value) {\n                var d;\n                if (typeof value === 'string' &&\n                        value.slice(0, 5) === 'Date(' &&\n                        value.slice(-1) === ')') {\n                    d = new Date(value.slice(5, -1));\n                    if (d) {\n                        return d;\n                    }\n                }\n                return value;\n            });\n\n\n    This is a reference implementation. You are free to copy, modify, or\n    redistribute.\n*/\n\n/*jslint evil: true, strict: false, regexp: false */\n\n/*members \"\", \"\\b\", \"\\t\", \"\\n\", \"\\f\", \"\\r\", \"\\\"\", JSON, \"\\\\\", apply,\n    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,\n    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,\n    lastIndex, length, parse, prototype, push, replace, slice, stringify,\n    test, toJSON, toString, valueOf\n*/\n\n\n// Create a JSON object only if one does not already exist. We create the\n// methods in a closure to avoid creating global variables.\n\nvar JSON;\nif (!JSON) {\n    JSON = {};\n}\n\n(function () {\n    \"use strict\";\n\n    function f(n) {\n        // Format integers to have at least two digits.\n        return n < 10 ? '0' + n : n;\n    }\n\n    if (typeof Date.prototype.toJSON !== 'function') {\n\n        Date.prototype.toJSON = function (key) {\n\n            return isFinite(this.valueOf()) ?\n                this.getUTCFullYear()     + '-' +\n                f(this.getUTCMonth() + 1) + '-' +\n                f(this.getUTCDate())      + 'T' +\n                f(this.getUTCHours())     + ':' +\n                f(this.getUTCMinutes())   + ':' +\n                f(this.getUTCSeconds())   + 'Z' : null;\n        };\n\n        String.prototype.toJSON      =\n            Number.prototype.toJSON  =\n            Boolean.prototype.toJSON = function (key) {\n                return this.valueOf();\n            };\n    }\n\n    var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n        gap,\n        indent,\n        meta = {    // table of character substitutions\n            '\\b': '\\\\b',\n            '\\t': '\\\\t',\n            '\\n': '\\\\n',\n            '\\f': '\\\\f',\n            '\\r': '\\\\r',\n            '\"' : '\\\\\"',\n            '\\\\': '\\\\\\\\'\n        },\n        rep;\n\n\n    function quote(string) {\n\n// If the string contains no control characters, no quote characters, and no\n// backslash characters, then we can safely slap some quotes around it.\n// Otherwise we must also replace the offending characters with safe escape\n// sequences.\n\n        escapable.lastIndex = 0;\n        return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\n            var c = meta[a];\n            return typeof c === 'string' ? c :\n                '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n        }) + '\"' : '\"' + string + '\"';\n    }\n\n\n    function str(key, holder) {\n\n// Produce a string from holder[key].\n\n        var i,          // The loop counter.\n            k,          // The member key.\n            v,          // The member value.\n            length,\n            mind = gap,\n            partial,\n            value = holder[key];\n\n// If the value has a toJSON method, call it to obtain a replacement value.\n\n        if (value && typeof value === 'object' &&\n                typeof value.toJSON === 'function') {\n            value = value.toJSON(key);\n        }\n\n// If we were called with a replacer function, then call the replacer to\n// obtain a replacement value.\n\n        if (typeof rep === 'function') {\n            value = rep.call(holder, key, value);\n        }\n\n// What happens next depends on the value's type.\n\n        switch (typeof value) {\n        case 'string':\n            return quote(value);\n\n        case 'number':\n\n// JSON numbers must be finite. Encode non-finite numbers as null.\n\n            return isFinite(value) ? String(value) : 'null';\n\n        case 'boolean':\n        case 'null':\n\n// If the value is a boolean or null, convert it to a string. Note:\n// typeof null does not produce 'null'. The case is included here in\n// the remote chance that this gets fixed someday.\n\n            return String(value);\n\n// If the type is 'object', we might be dealing with an object or an array or\n// null.\n\n        case 'object':\n\n// Due to a specification blunder in ECMAScript, typeof null is 'object',\n// so watch out for that case.\n\n            if (!value) {\n                return 'null';\n            }\n\n// Make an array to hold the partial results of stringifying this object value.\n\n            gap += indent;\n            partial = [];\n\n// Is the value an array?\n\n            if (Object.prototype.toString.apply(value) === '[object Array]') {\n\n// The value is an array. Stringify every element. Use null as a placeholder\n// for non-JSON values.\n\n                length = value.length;\n                for (i = 0; i < length; i += 1) {\n                    partial[i] = str(i, value) || 'null';\n                }\n\n// Join all of the elements together, separated with commas, and wrap them in\n// brackets.\n\n                v = partial.length === 0 ? '[]' : gap ?\n                    '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\n                    '[' + partial.join(',') + ']';\n                gap = mind;\n                return v;\n            }\n\n// If the replacer is an array, use it to select the members to be stringified.\n\n            if (rep && typeof rep === 'object') {\n                length = rep.length;\n                for (i = 0; i < length; i += 1) {\n                    if (typeof rep[i] === 'string') {\n                        k = rep[i];\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            } else {\n\n// Otherwise, iterate through all of the keys in the object.\n\n                for (k in value) {\n                    if (Object.prototype.hasOwnProperty.call(value, k)) {\n                        v = str(k, value);\n                        if (v) {\n                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\n                        }\n                    }\n                }\n            }\n\n// Join all of the member texts together, separated with commas,\n// and wrap them in braces.\n\n            v = partial.length === 0 ? '{}' : gap ?\n                '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\n                '{' + partial.join(',') + '}';\n            gap = mind;\n            return v;\n        }\n    }\n\n// If the JSON object does not yet have a stringify method, give it one.\n\n    if (typeof JSON.stringify !== 'function') {\n        JSON.stringify = function (value, replacer, space) {\n\n// The stringify method takes a value and an optional replacer, and an optional\n// space parameter, and returns a JSON text. The replacer can be a function\n// that can replace values, or an array of strings that will select the keys.\n// A default replacer method can be provided. Use of the space parameter can\n// produce text that is more easily readable.\n\n            var i;\n            gap = '';\n            indent = '';\n\n// If the space parameter is a number, make an indent string containing that\n// many spaces.\n\n            if (typeof space === 'number') {\n                for (i = 0; i < space; i += 1) {\n                    indent += ' ';\n                }\n\n// If the space parameter is a string, it will be used as the indent string.\n\n            } else if (typeof space === 'string') {\n                indent = space;\n            }\n\n// If there is a replacer, it must be a function or an array.\n// Otherwise, throw an error.\n\n            rep = replacer;\n            if (replacer && typeof replacer !== 'function' &&\n                    (typeof replacer !== 'object' ||\n                    typeof replacer.length !== 'number')) {\n                throw new Error('JSON.stringify');\n            }\n\n// Make a fake root object containing our value under the key of ''.\n// Return the result of stringifying the value.\n\n            return str('', {'': value});\n        };\n    }\n\n\n// If the JSON object does not yet have a parse method, give it one.\n\n    if (typeof JSON.parse !== 'function') {\n        JSON.parse = function (text, reviver) {\n\n// The parse method takes a text and an optional reviver function, and returns\n// a JavaScript value if the text is a valid JSON text.\n\n            var j;\n\n            function walk(holder, key) {\n\n// The walk method is used to recursively walk the resulting structure so\n// that modifications can be made.\n\n                var k, v, value = holder[key];\n                if (value && typeof value === 'object') {\n                    for (k in value) {\n                        if (Object.prototype.hasOwnProperty.call(value, k)) {\n                            v = walk(value, k);\n                            if (v !== undefined) {\n                                value[k] = v;\n                            } else {\n                                delete value[k];\n                            }\n                        }\n                    }\n                }\n                return reviver.call(holder, key, value);\n            }\n\n\n// Parsing happens in four stages. In the first stage, we replace certain\n// Unicode characters with escape sequences. JavaScript handles many characters\n// incorrectly, either silently deleting them, or treating them as line endings.\n\n            text = String(text);\n            cx.lastIndex = 0;\n            if (cx.test(text)) {\n                text = text.replace(cx, function (a) {\n                    return '\\\\u' +\n                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n                });\n            }\n\n// In the second stage, we run the text against regular expressions that look\n// for non-JSON patterns. We are especially concerned with '()' and 'new'\n// because they can cause invocation, and '=' because it can cause mutation.\n// But just to be safe, we want to reject all unexpected forms.\n\n// We split the second stage into 4 regexp operations in order to work around\n// crippling inefficiencies in IE's and Safari's regexp engines. First we\n// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we\n// replace all simple value tokens with ']' characters. Third, we delete all\n// open brackets that follow a colon or comma or that begin the text. Finally,\n// we look to see that the remaining characters are only whitespace or ']' or\n// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\n\n            if (/^[\\],:{}\\s]*$/\n                    .test(text.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')\n                        .replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']')\n                        .replace(/(?:^|:|,)(?:\\s*\\[)+/g, ''))) {\n\n// In the third stage we use the eval function to compile the text into a\n// JavaScript structure. The '{' operator is subject to a syntactic ambiguity\n// in JavaScript: it can begin a block or an object literal. We wrap the text\n// in parens to eliminate the ambiguity.\n\n                j = eval('(' + text + ')');\n\n// In the optional fourth stage, we recursively walk the new structure, passing\n// each name/value pair to a reviver function for possible transformation.\n\n                return typeof reviver === 'function' ?\n                    walk({'': j}, '') : j;\n            }\n\n// If the text is not JSON parseable, then a SyntaxError is thrown.\n\n            throw new SyntaxError('JSON.parse');\n        };\n    }\n}());"
  },
  {
    "path": "test/mocha.css",
    "content": "\r\nbody {\r\n  font: 20px/1.5 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\r\n  padding: 60px 50px;\r\n}\r\n\r\n#mocha ul, #mocha li {\r\n  margin: 0;\r\n  padding: 0;\r\n}\r\n\r\n#mocha ul {\r\n  list-style: none;\r\n}\r\n\r\n#mocha h1, #mocha h2 {\r\n  margin: 0;\r\n}\r\n\r\n#mocha h1 {\r\n  margin-top: 15px;\r\n  font-size: 1em;\r\n  font-weight: 200;\r\n}\r\n\r\n#mocha h1 a {\r\n  text-decoration: none;\r\n  color: inherit;\r\n}\r\n\r\n#mocha h1 a:hover {\r\n  text-decoration: underline;\r\n}\r\n\r\n#mocha .suite .suite h1 {\r\n  margin-top: 0;\r\n  font-size: .8em;\r\n}\r\n\r\n#mocha h2 {\r\n  font-size: 12px;\r\n  font-weight: normal;\r\n  cursor: pointer;\r\n}\r\n\r\n#mocha .suite {\r\n  margin-left: 15px;\r\n}\r\n\r\n#mocha .test {\r\n  margin-left: 15px;\r\n}\r\n\r\n#mocha .test:hover h2::after {\r\n  position: relative;\r\n  top: 0;\r\n  right: -10px;\r\n  content: '(view source)';\r\n  font-size: 12px;\r\n  font-family: arial;\r\n  color: #888;\r\n}\r\n\r\n#mocha .test.pending:hover h2::after {\r\n  content: '(pending)';\r\n  font-family: arial;\r\n}\r\n\r\n#mocha .test.pass.medium .duration {\r\n  background: #C09853;\r\n}\r\n\r\n#mocha .test.pass.slow .duration {\r\n  background: #B94A48;\r\n}\r\n\r\n#mocha .test.pass::before {\r\n  content: '?';\r\n  font-size: 12px;\r\n  display: block;\r\n  float: left;\r\n  margin-right: 5px;\r\n  color: #00d6b2;\r\n}\r\n\r\n#mocha .test.pass .duration {\r\n  font-size: 9px;\r\n  margin-left: 5px;\r\n  padding: 2px 5px;\r\n  color: white;\r\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\r\n  -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\r\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.2);\r\n  -webkit-border-radius: 5px;\r\n  -moz-border-radius: 5px;\r\n  -ms-border-radius: 5px;\r\n  -o-border-radius: 5px;\r\n  border-radius: 5px;\r\n}\r\n\r\n#mocha .test.pass.fast .duration {\r\n  display: none;\r\n}\r\n\r\n#mocha .test.pending {\r\n  color: #0b97c4;\r\n}\r\n\r\n#mocha .test.pending::before {\r\n  content: '?';\r\n  color: #0b97c4;\r\n}\r\n\r\n#mocha .test.fail {\r\n  color: #c00;\r\n}\r\n\r\n#mocha .test.fail pre {\r\n  color: black;\r\n}\r\n\r\n#mocha .test.fail::before {\r\n  content: '?';\r\n  font-size: 12px;\r\n  display: block;\r\n  float: left;\r\n  margin-right: 5px;\r\n  color: #c00;\r\n}\r\n\r\n#mocha .test pre.error {\r\n  color: #c00;\r\n}\r\n\r\n#mocha .test pre {\r\n  display: inline-block;\r\n  font: 12px/1.5 monaco, monospace;\r\n  margin: 5px;\r\n  padding: 15px;\r\n  border: 1px solid #eee;\r\n  border-bottom-color: #ddd;\r\n  -webkit-border-radius: 3px;\r\n  -webkit-box-shadow: 0 1px 3px #eee;\r\n}\r\n\r\n#error {\r\n  color: #c00;\r\n  font-size: 1.5  em;\r\n  font-weight: 100;\r\n  letter-spacing: 1px;\r\n}\r\n\r\n#stats {\r\n  position: fixed;\r\n  top: 15px;\r\n  right: 10px;\r\n  font-size: 12px;\r\n  margin: 0;\r\n  color: #888;\r\n}\r\n\r\n#stats .progress {\r\n  float: right;\r\n  padding-top: 0;\r\n}\r\n\r\n#stats em {\r\n  color: black;\r\n}\r\n\r\n#stats li {\r\n  display: inline-block;\r\n  margin: 0 5px;\r\n  list-style: none;\r\n  padding-top: 11px;\r\n}\r\n\r\ncode .comment { color: #ddd }\r\ncode .init { color: #2F6FAD }\r\ncode .string { color: #5890AD }\r\ncode .keyword { color: #8A6343 }\r\ncode .number { color: #2F6FAD }\r\n"
  },
  {
    "path": "test/mocha.html",
    "content": "<html>\r\n\t<head>\r\n\t\t<title>Gun Tests</title>\r\n\t\t<link rel=\"stylesheet\" href=\"./mocha.css\"/>\r\n\t\t<style>\r\n\t\t</style>\r\n\t  </head>\r\n\t</head>\r\n\t<body>\r\n\t\tGun Tests\r\n\t\t<div id=\"debug\"></div>\r\n\t\t<div id=\"mocha\"></div>\r\n\t\t\r\n\t\t<script src=\"./json2.js\"></script>\r\n\t\t<script src=\"./mocha.js\"></script>\r\n\t\t<script>mocha.setup({ui:'bdd',globals:[]});</script>\r\n\t\t<script src=\"./expect.js\"></script>\r\n\t\t<script></script>\r\n\t\t<script src=\"../lib/yson.js\"></script>\r\n\t\t<script src=\"../gun.js\"></script>\r\n\t\t<script src=\"../sea.js\"></script>\r\n\t\t\r\n\t\t<script src=\"../lib/radix.js\"></script>\r\n\t\t<script src=\"../lib/radisk.js\"></script>\r\n\t\t<script src=\"../lib/store.js\"></script>\r\n\t\t<script src=\"../lib/rindexed.js\"></script>\r\n\r\n\t\t<script src=\"./rad/rad.js\"></script>\r\n\t\t<script src=\"./sea/sea.js\"></script>\r\n\r\n\t\t<script src=\"./common.js\"></script>\r\n\t\t<script>\r\n\t\tif(location.search){\r\n\t\t\tGun.debug = true;\r\n\t\t\tconsole.log('async?', Gun.debug);\r\n\t\t}\r\n\t\tvar run = mocha.run(function(a,b,c){\r\n\t\t\tdocument.body.prepend(\"TODO: localStorage gun/gap ???\");return;\r\n\t\t\tvar yes = confirm(\"REFRESH BROWSER FOR ASYNC TESTS?\");\r\n\t\t\tif(yes){\r\n\t\t\t\tif(location.search){\r\n\t\t\t\t\tlocation.search = '';\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlocation.search = '?async';\r\n\t\t\t\t}\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\t/*console.log(\"???????????\", a);\r\n\t\t\t//if(a !== 0){ return }\r\n\t\t\tdocument.getElementById('mocha-stats').id = 'mocha-stats2';\r\n\t\t\tdocument.getElementById('mocha-report').style.display = 'none';\r\n\t\t\tdocument.getElementById('mocha-report').id = 'mocha-report2';\r\n\t\t\tGun.debug = false;\r\n\t\t\tmocha.run();*/\r\n\t\t});\r\n\t\trun.on(\"fail\", function(test, err){\r\n\t\t\tconsole.log(\"!!!!!!!!!!!\", test, err);\r\n\t\t\t//alert(5);\r\n\t\t})\r\n\t\t</script>\r\n\t</body>\r\n</html>"
  },
  {
    "path": "test/mocha.js",
    "content": "(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){\r\n(function (process){\r\nmodule.exports = process.env.COV\r\n  ? require('./lib-cov/mocha')\r\n  : require('./lib/mocha');\r\n\r\n}).call(this,require('_process'))\r\n},{\"./lib-cov/mocha\":undefined,\"./lib/mocha\":14,\"_process\":51}],2:[function(require,module,exports){\r\n/* eslint-disable no-unused-vars */\r\nmodule.exports = function(type) {\r\n  return function() {};\r\n};\r\n\r\n},{}],3:[function(require,module,exports){\r\n/**\r\n * Module exports.\r\n */\r\n\r\nexports.EventEmitter = EventEmitter;\r\n\r\n/**\r\n * Object#hasOwnProperty reference.\r\n */\r\nvar objToString = Object.prototype.toString;\r\n\r\n/**\r\n * Check if a value is an array.\r\n *\r\n * @api private\r\n * @param {*} val The value to test.\r\n * @return {boolean} true if the value is a boolean, otherwise false.\r\n */\r\nfunction isArray(val) {\r\n  return objToString.call(val) === '[object Array]';\r\n}\r\n\r\n/**\r\n * Event emitter constructor.\r\n *\r\n * @api public\r\n */\r\nfunction EventEmitter() {}\r\n\r\n/**\r\n * Add a listener.\r\n *\r\n * @api public\r\n * @param {string} name Event name.\r\n * @param {Function} fn Event handler.\r\n * @return {EventEmitter} Emitter instance.\r\n */\r\nEventEmitter.prototype.on = function(name, fn) {\r\n  if (!this.$events) {\r\n    this.$events = {};\r\n  }\r\n\r\n  if (!this.$events[name]) {\r\n    this.$events[name] = fn;\r\n  } else if (isArray(this.$events[name])) {\r\n    this.$events[name].push(fn);\r\n  } else {\r\n    this.$events[name] = [this.$events[name], fn];\r\n  }\r\n\r\n  return this;\r\n};\r\n\r\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\r\n\r\n/**\r\n * Adds a volatile listener.\r\n *\r\n * @api public\r\n * @param {string} name Event name.\r\n * @param {Function} fn Event handler.\r\n * @return {EventEmitter} Emitter instance.\r\n */\r\nEventEmitter.prototype.once = function(name, fn) {\r\n  var self = this;\r\n\r\n  function on() {\r\n    self.removeListener(name, on);\r\n    fn.apply(this, arguments);\r\n  }\r\n\r\n  on.listener = fn;\r\n  this.on(name, on);\r\n\r\n  return this;\r\n};\r\n\r\n/**\r\n * Remove a listener.\r\n *\r\n * @api public\r\n * @param {string} name Event name.\r\n * @param {Function} fn Event handler.\r\n * @return {EventEmitter} Emitter instance.\r\n */\r\nEventEmitter.prototype.removeListener = function(name, fn) {\r\n  if (this.$events && this.$events[name]) {\r\n    var list = this.$events[name];\r\n\r\n    if (isArray(list)) {\r\n      var pos = -1;\r\n\r\n      for (var i = 0, l = list.length; i < l; i++) {\r\n        if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {\r\n          pos = i;\r\n          break;\r\n        }\r\n      }\r\n\r\n      if (pos < 0) {\r\n        return this;\r\n      }\r\n\r\n      list.splice(pos, 1);\r\n\r\n      if (!list.length) {\r\n        delete this.$events[name];\r\n      }\r\n    } else if (list === fn || (list.listener && list.listener === fn)) {\r\n      delete this.$events[name];\r\n    }\r\n  }\r\n\r\n  return this;\r\n};\r\n\r\n/**\r\n * Remove all listeners for an event.\r\n *\r\n * @api public\r\n * @param {string} name Event name.\r\n * @return {EventEmitter} Emitter instance.\r\n */\r\nEventEmitter.prototype.removeAllListeners = function(name) {\r\n  if (name === undefined) {\r\n    this.$events = {};\r\n    return this;\r\n  }\r\n\r\n  if (this.$events && this.$events[name]) {\r\n    this.$events[name] = null;\r\n  }\r\n\r\n  return this;\r\n};\r\n\r\n/**\r\n * Get all listeners for a given event.\r\n *\r\n * @api public\r\n * @param {string} name Event name.\r\n * @return {EventEmitter} Emitter instance.\r\n */\r\nEventEmitter.prototype.listeners = function(name) {\r\n  if (!this.$events) {\r\n    this.$events = {};\r\n  }\r\n\r\n  if (!this.$events[name]) {\r\n    this.$events[name] = [];\r\n  }\r\n\r\n  if (!isArray(this.$events[name])) {\r\n    this.$events[name] = [this.$events[name]];\r\n  }\r\n\r\n  return this.$events[name];\r\n};\r\n\r\n/**\r\n * Emit an event.\r\n *\r\n * @api public\r\n * @param {string} name Event name.\r\n * @return {boolean} true if at least one handler was invoked, else false.\r\n */\r\nEventEmitter.prototype.emit = function(name) {\r\n  if (!this.$events) {\r\n    return false;\r\n  }\r\n\r\n  var handler = this.$events[name];\r\n\r\n  if (!handler) {\r\n    return false;\r\n  }\r\n\r\n  var args = Array.prototype.slice.call(arguments, 1);\r\n\r\n  if (typeof handler === 'function') {\r\n    handler.apply(this, args);\r\n  } else if (isArray(handler)) {\r\n    var listeners = handler.slice();\r\n\r\n    for (var i = 0, l = listeners.length; i < l; i++) {\r\n      listeners[i].apply(this, args);\r\n    }\r\n  } else {\r\n    return false;\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\n},{}],4:[function(require,module,exports){\r\n/**\r\n * Expose `Progress`.\r\n */\r\n\r\nmodule.exports = Progress;\r\n\r\n/**\r\n * Initialize a new `Progress` indicator.\r\n */\r\nfunction Progress() {\r\n  this.percent = 0;\r\n  this.size(0);\r\n  this.fontSize(11);\r\n  this.font('helvetica, arial, sans-serif');\r\n}\r\n\r\n/**\r\n * Set progress size to `size`.\r\n *\r\n * @api public\r\n * @param {number} size\r\n * @return {Progress} Progress instance.\r\n */\r\nProgress.prototype.size = function(size) {\r\n  this._size = size;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set text to `text`.\r\n *\r\n * @api public\r\n * @param {string} text\r\n * @return {Progress} Progress instance.\r\n */\r\nProgress.prototype.text = function(text) {\r\n  this._text = text;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set font size to `size`.\r\n *\r\n * @api public\r\n * @param {number} size\r\n * @return {Progress} Progress instance.\r\n */\r\nProgress.prototype.fontSize = function(size) {\r\n  this._fontSize = size;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set font to `family`.\r\n *\r\n * @param {string} family\r\n * @return {Progress} Progress instance.\r\n */\r\nProgress.prototype.font = function(family) {\r\n  this._font = family;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Update percentage to `n`.\r\n *\r\n * @param {number} n\r\n * @return {Progress} Progress instance.\r\n */\r\nProgress.prototype.update = function(n) {\r\n  this.percent = n;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Draw on `ctx`.\r\n *\r\n * @param {CanvasRenderingContext2d} ctx\r\n * @return {Progress} Progress instance.\r\n */\r\nProgress.prototype.draw = function(ctx) {\r\n  try {\r\n    var percent = Math.min(this.percent, 100);\r\n    var size = this._size;\r\n    var half = size / 2;\r\n    var x = half;\r\n    var y = half;\r\n    var rad = half - 1;\r\n    var fontSize = this._fontSize;\r\n\r\n    ctx.font = fontSize + 'px ' + this._font;\r\n\r\n    var angle = Math.PI * 2 * (percent / 100);\r\n    ctx.clearRect(0, 0, size, size);\r\n\r\n    // outer circle\r\n    ctx.strokeStyle = '#9f9f9f';\r\n    ctx.beginPath();\r\n    ctx.arc(x, y, rad, 0, angle, false);\r\n    ctx.stroke();\r\n\r\n    // inner circle\r\n    ctx.strokeStyle = '#eee';\r\n    ctx.beginPath();\r\n    ctx.arc(x, y, rad - 1, 0, angle, true);\r\n    ctx.stroke();\r\n\r\n    // text\r\n    var text = this._text || (percent | 0) + '%';\r\n    var w = ctx.measureText(text).width;\r\n\r\n    ctx.fillText(text, x - w / 2 + 1, y + fontSize / 2 - 1);\r\n  } catch (err) {\r\n    // don't fail if we can't render progress\r\n  }\r\n  return this;\r\n};\r\n\r\n},{}],5:[function(require,module,exports){\r\n(function (global){\r\nexports.isatty = function isatty() {\r\n  return true;\r\n};\r\n\r\nexports.getWindowSize = function getWindowSize() {\r\n  if ('innerHeight' in global) {\r\n    return [global.innerHeight, global.innerWidth];\r\n  }\r\n  // In a Web Worker, the DOM Window is not available.\r\n  return [640, 480];\r\n};\r\n\r\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{}],6:[function(require,module,exports){\r\n/**\r\n * Expose `Context`.\r\n */\r\n\r\nmodule.exports = Context;\r\n\r\n/**\r\n * Initialize a new `Context`.\r\n *\r\n * @api private\r\n */\r\nfunction Context() {}\r\n\r\n/**\r\n * Set or get the context `Runnable` to `runnable`.\r\n *\r\n * @api private\r\n * @param {Runnable} runnable\r\n * @return {Context}\r\n */\r\nContext.prototype.runnable = function(runnable) {\r\n  if (!arguments.length) {\r\n    return this._runnable;\r\n  }\r\n  this.test = this._runnable = runnable;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set test timeout `ms`.\r\n *\r\n * @api private\r\n * @param {number} ms\r\n * @return {Context} self\r\n */\r\nContext.prototype.timeout = function(ms) {\r\n  if (!arguments.length) {\r\n    return this.runnable().timeout();\r\n  }\r\n  this.runnable().timeout(ms);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set test timeout `enabled`.\r\n *\r\n * @api private\r\n * @param {boolean} enabled\r\n * @return {Context} self\r\n */\r\nContext.prototype.enableTimeouts = function(enabled) {\r\n  this.runnable().enableTimeouts(enabled);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set test slowness threshold `ms`.\r\n *\r\n * @api private\r\n * @param {number} ms\r\n * @return {Context} self\r\n */\r\nContext.prototype.slow = function(ms) {\r\n  this.runnable().slow(ms);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Mark a test as skipped.\r\n *\r\n * @api private\r\n * @return {Context} self\r\n */\r\nContext.prototype.skip = function() {\r\n  this.runnable().skip();\r\n  return this;\r\n};\r\n\r\n/**\r\n * Inspect the context void of `._runnable`.\r\n *\r\n * @api private\r\n * @return {string}\r\n */\r\nContext.prototype.inspect = function() {\r\n  return JSON.stringify(this, function(key, val) {\r\n    return key === 'runnable' || key === 'test' ? undefined : val;\r\n  }, 2);\r\n};\r\n\r\n},{}],7:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Runnable = require('./runnable');\r\nvar inherits = require('./utils').inherits;\r\n\r\n/**\r\n * Expose `Hook`.\r\n */\r\n\r\nmodule.exports = Hook;\r\n\r\n/**\r\n * Initialize a new `Hook` with the given `title` and callback `fn`.\r\n *\r\n * @param {String} title\r\n * @param {Function} fn\r\n * @api private\r\n */\r\nfunction Hook(title, fn) {\r\n  Runnable.call(this, title, fn);\r\n  this.type = 'hook';\r\n}\r\n\r\n/**\r\n * Inherit from `Runnable.prototype`.\r\n */\r\ninherits(Hook, Runnable);\r\n\r\n/**\r\n * Get or set the test `err`.\r\n *\r\n * @param {Error} err\r\n * @return {Error}\r\n * @api public\r\n */\r\nHook.prototype.error = function(err) {\r\n  if (!arguments.length) {\r\n    err = this._error;\r\n    this._error = null;\r\n    return err;\r\n  }\r\n\r\n  this._error = err;\r\n};\r\n\r\n},{\"./runnable\":35,\"./utils\":39}],8:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Suite = require('../suite');\r\nvar Test = require('../test');\r\nvar escapeRe = require('escape-string-regexp');\r\n\r\n/**\r\n * BDD-style interface:\r\n *\r\n *      describe('Array', function() {\r\n *        describe('#indexOf()', function() {\r\n *          it('should return -1 when not present', function() {\r\n *            // ...\r\n *          });\r\n *\r\n *          it('should return the index when present', function() {\r\n *            // ...\r\n *          });\r\n *        });\r\n *      });\r\n *\r\n * @param {Suite} suite Root suite.\r\n */\r\nmodule.exports = function(suite) {\r\n  var suites = [suite];\r\n\r\n  suite.on('pre-require', function(context, file, mocha) {\r\n    var common = require('./common')(suites, context);\r\n\r\n    context.before = common.before;\r\n    context.after = common.after;\r\n    context.beforeEach = common.beforeEach;\r\n    context.afterEach = common.afterEach;\r\n    context.run = mocha.options.delay && common.runWithSuite(suite);\r\n    /**\r\n     * Describe a \"suite\" with the given `title`\r\n     * and callback `fn` containing nested suites\r\n     * and/or tests.\r\n     */\r\n\r\n    context.describe = context.context = function(title, fn) {\r\n      var suite = Suite.create(suites[0], title);\r\n      suite.file = file;\r\n      suites.unshift(suite);\r\n      fn.call(suite);\r\n      suites.shift();\r\n      return suite;\r\n    };\r\n\r\n    /**\r\n     * Pending describe.\r\n     */\r\n\r\n    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {\r\n      var suite = Suite.create(suites[0], title);\r\n      suite.pending = true;\r\n      suites.unshift(suite);\r\n      fn.call(suite);\r\n      suites.shift();\r\n    };\r\n\r\n    /**\r\n     * Exclusive suite.\r\n     */\r\n\r\n    context.describe.only = function(title, fn) {\r\n      var suite = context.describe(title, fn);\r\n      mocha.grep(suite.fullTitle());\r\n      return suite;\r\n    };\r\n\r\n    /**\r\n     * Describe a specification or test-case\r\n     * with the given `title` and callback `fn`\r\n     * acting as a thunk.\r\n     */\r\n\r\n    context.it = context.specify = function(title, fn) {\r\n      var suite = suites[0];\r\n      if (suite.pending) {\r\n        fn = null;\r\n      }\r\n      var test = new Test(title, fn);\r\n      test.file = file;\r\n      suite.addTest(test);\r\n      return test;\r\n    };\r\n\r\n    /**\r\n     * Exclusive test-case.\r\n     */\r\n\r\n    context.it.only = function(title, fn) {\r\n      var test = context.it(title, fn);\r\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\r\n      mocha.grep(new RegExp(reString));\r\n      return test;\r\n    };\r\n\r\n    /**\r\n     * Pending test case.\r\n     */\r\n\r\n    context.xit = context.xspecify = context.it.skip = function(title) {\r\n      context.it(title);\r\n    };\r\n  });\r\n};\r\n\r\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],9:[function(require,module,exports){\r\n'use strict';\r\n\r\n/**\r\n * Functions common to more than one interface.\r\n *\r\n * @param {Suite[]} suites\r\n * @param {Context} context\r\n * @return {Object} An object containing common functions.\r\n */\r\nmodule.exports = function(suites, context) {\r\n  return {\r\n    /**\r\n     * This is only present if flag --delay is passed into Mocha. It triggers\r\n     * root suite execution.\r\n     *\r\n     * @param {Suite} suite The root wuite.\r\n     * @return {Function} A function which runs the root suite\r\n     */\r\n    runWithSuite: function runWithSuite(suite) {\r\n      return function run() {\r\n        suite.run();\r\n      };\r\n    },\r\n\r\n    /**\r\n     * Execute before running tests.\r\n     *\r\n     * @param {string} name\r\n     * @param {Function} fn\r\n     */\r\n    before: function(name, fn) {\r\n      suites[0].beforeAll(name, fn);\r\n    },\r\n\r\n    /**\r\n     * Execute after running tests.\r\n     *\r\n     * @param {string} name\r\n     * @param {Function} fn\r\n     */\r\n    after: function(name, fn) {\r\n      suites[0].afterAll(name, fn);\r\n    },\r\n\r\n    /**\r\n     * Execute before each test case.\r\n     *\r\n     * @param {string} name\r\n     * @param {Function} fn\r\n     */\r\n    beforeEach: function(name, fn) {\r\n      suites[0].beforeEach(name, fn);\r\n    },\r\n\r\n    /**\r\n     * Execute after each test case.\r\n     *\r\n     * @param {string} name\r\n     * @param {Function} fn\r\n     */\r\n    afterEach: function(name, fn) {\r\n      suites[0].afterEach(name, fn);\r\n    },\r\n\r\n    test: {\r\n      /**\r\n       * Pending test case.\r\n       *\r\n       * @param {string} title\r\n       */\r\n      skip: function(title) {\r\n        context.test(title);\r\n      }\r\n    }\r\n  };\r\n};\r\n\r\n},{}],10:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Suite = require('../suite');\r\nvar Test = require('../test');\r\n\r\n/**\r\n * TDD-style interface:\r\n *\r\n *     exports.Array = {\r\n *       '#indexOf()': {\r\n *         'should return -1 when the value is not present': function() {\r\n *\r\n *         },\r\n *\r\n *         'should return the correct index when the value is present': function() {\r\n *\r\n *         }\r\n *       }\r\n *     };\r\n *\r\n * @param {Suite} suite Root suite.\r\n */\r\nmodule.exports = function(suite) {\r\n  var suites = [suite];\r\n\r\n  suite.on('require', visit);\r\n\r\n  function visit(obj, file) {\r\n    var suite;\r\n    for (var key in obj) {\r\n      if (typeof obj[key] === 'function') {\r\n        var fn = obj[key];\r\n        switch (key) {\r\n          case 'before':\r\n            suites[0].beforeAll(fn);\r\n            break;\r\n          case 'after':\r\n            suites[0].afterAll(fn);\r\n            break;\r\n          case 'beforeEach':\r\n            suites[0].beforeEach(fn);\r\n            break;\r\n          case 'afterEach':\r\n            suites[0].afterEach(fn);\r\n            break;\r\n          default:\r\n            var test = new Test(key, fn);\r\n            test.file = file;\r\n            suites[0].addTest(test);\r\n        }\r\n      } else {\r\n        suite = Suite.create(suites[0], key);\r\n        suites.unshift(suite);\r\n        visit(obj[key]);\r\n        suites.shift();\r\n      }\r\n    }\r\n  }\r\n};\r\n\r\n},{\"../suite\":37,\"../test\":38}],11:[function(require,module,exports){\r\nexports.bdd = require('./bdd');\r\nexports.tdd = require('./tdd');\r\nexports.qunit = require('./qunit');\r\nexports.exports = require('./exports');\r\n\r\n},{\"./bdd\":8,\"./exports\":10,\"./qunit\":12,\"./tdd\":13}],12:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Suite = require('../suite');\r\nvar Test = require('../test');\r\nvar escapeRe = require('escape-string-regexp');\r\n\r\n/**\r\n * QUnit-style interface:\r\n *\r\n *     suite('Array');\r\n *\r\n *     test('#length', function() {\r\n *       var arr = [1,2,3];\r\n *       ok(arr.length == 3);\r\n *     });\r\n *\r\n *     test('#indexOf()', function() {\r\n *       var arr = [1,2,3];\r\n *       ok(arr.indexOf(1) == 0);\r\n *       ok(arr.indexOf(2) == 1);\r\n *       ok(arr.indexOf(3) == 2);\r\n *     });\r\n *\r\n *     suite('String');\r\n *\r\n *     test('#length', function() {\r\n *       ok('foo'.length == 3);\r\n *     });\r\n *\r\n * @param {Suite} suite Root suite.\r\n */\r\nmodule.exports = function(suite) {\r\n  var suites = [suite];\r\n\r\n  suite.on('pre-require', function(context, file, mocha) {\r\n    var common = require('./common')(suites, context);\r\n\r\n    context.before = common.before;\r\n    context.after = common.after;\r\n    context.beforeEach = common.beforeEach;\r\n    context.afterEach = common.afterEach;\r\n    context.run = mocha.options.delay && common.runWithSuite(suite);\r\n    /**\r\n     * Describe a \"suite\" with the given `title`.\r\n     */\r\n\r\n    context.suite = function(title) {\r\n      if (suites.length > 1) {\r\n        suites.shift();\r\n      }\r\n      var suite = Suite.create(suites[0], title);\r\n      suite.file = file;\r\n      suites.unshift(suite);\r\n      return suite;\r\n    };\r\n\r\n    /**\r\n     * Exclusive test-case.\r\n     */\r\n\r\n    context.suite.only = function(title, fn) {\r\n      var suite = context.suite(title, fn);\r\n      mocha.grep(suite.fullTitle());\r\n    };\r\n\r\n    /**\r\n     * Describe a specification or test-case\r\n     * with the given `title` and callback `fn`\r\n     * acting as a thunk.\r\n     */\r\n\r\n    context.test = function(title, fn) {\r\n      var test = new Test(title, fn);\r\n      test.file = file;\r\n      suites[0].addTest(test);\r\n      return test;\r\n    };\r\n\r\n    /**\r\n     * Exclusive test-case.\r\n     */\r\n\r\n    context.test.only = function(title, fn) {\r\n      var test = context.test(title, fn);\r\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\r\n      mocha.grep(new RegExp(reString));\r\n    };\r\n\r\n    context.test.skip = common.test.skip;\r\n  });\r\n};\r\n\r\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],13:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Suite = require('../suite');\r\nvar Test = require('../test');\r\nvar escapeRe = require('escape-string-regexp');\r\n\r\n/**\r\n * TDD-style interface:\r\n *\r\n *      suite('Array', function() {\r\n *        suite('#indexOf()', function() {\r\n *          suiteSetup(function() {\r\n *\r\n *          });\r\n *\r\n *          test('should return -1 when not present', function() {\r\n *\r\n *          });\r\n *\r\n *          test('should return the index when present', function() {\r\n *\r\n *          });\r\n *\r\n *          suiteTeardown(function() {\r\n *\r\n *          });\r\n *        });\r\n *      });\r\n *\r\n * @param {Suite} suite Root suite.\r\n */\r\nmodule.exports = function(suite) {\r\n  var suites = [suite];\r\n\r\n  suite.on('pre-require', function(context, file, mocha) {\r\n    var common = require('./common')(suites, context);\r\n\r\n    context.setup = common.beforeEach;\r\n    context.teardown = common.afterEach;\r\n    context.suiteSetup = common.before;\r\n    context.suiteTeardown = common.after;\r\n    context.run = mocha.options.delay && common.runWithSuite(suite);\r\n\r\n    /**\r\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\r\n     * nested suites and/or tests.\r\n     */\r\n    context.suite = function(title, fn) {\r\n      var suite = Suite.create(suites[0], title);\r\n      suite.file = file;\r\n      suites.unshift(suite);\r\n      fn.call(suite);\r\n      suites.shift();\r\n      return suite;\r\n    };\r\n\r\n    /**\r\n     * Pending suite.\r\n     */\r\n    context.suite.skip = function(title, fn) {\r\n      var suite = Suite.create(suites[0], title);\r\n      suite.pending = true;\r\n      suites.unshift(suite);\r\n      fn.call(suite);\r\n      suites.shift();\r\n    };\r\n\r\n    /**\r\n     * Exclusive test-case.\r\n     */\r\n    context.suite.only = function(title, fn) {\r\n      var suite = context.suite(title, fn);\r\n      mocha.grep(suite.fullTitle());\r\n    };\r\n\r\n    /**\r\n     * Describe a specification or test-case with the given `title` and\r\n     * callback `fn` acting as a thunk.\r\n     */\r\n    context.test = function(title, fn) {\r\n      var suite = suites[0];\r\n      if (suite.pending) {\r\n        fn = null;\r\n      }\r\n      var test = new Test(title, fn);\r\n      test.file = file;\r\n      suite.addTest(test);\r\n      return test;\r\n    };\r\n\r\n    /**\r\n     * Exclusive test-case.\r\n     */\r\n\r\n    context.test.only = function(title, fn) {\r\n      var test = context.test(title, fn);\r\n      var reString = '^' + escapeRe(test.fullTitle()) + '$';\r\n      mocha.grep(new RegExp(reString));\r\n    };\r\n\r\n    context.test.skip = common.test.skip;\r\n  });\r\n};\r\n\r\n},{\"../suite\":37,\"../test\":38,\"./common\":9,\"escape-string-regexp\":68}],14:[function(require,module,exports){\r\n(function (process,global,__dirname){\r\n/*!\r\n * mocha\r\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\r\n * MIT Licensed\r\n */\r\n\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar escapeRe = require('escape-string-regexp');\r\nvar path = require('path');\r\nvar reporters = require('./reporters');\r\nvar utils = require('./utils');\r\n\r\n/**\r\n * Expose `Mocha`.\r\n */\r\n\r\nexports = module.exports = Mocha;\r\n\r\n/**\r\n * To require local UIs and reporters when running in node.\r\n */\r\n\r\nif (!process.browser) {\r\n  var cwd = process.cwd();\r\n  module.paths.push(cwd, path.join(cwd, 'node_modules'));\r\n}\r\n\r\n/**\r\n * Expose internals.\r\n */\r\n\r\nexports.utils = utils;\r\nexports.interfaces = require('./interfaces');\r\nexports.reporters = reporters;\r\nexports.Runnable = require('./runnable');\r\nexports.Context = require('./context');\r\nexports.Runner = require('./runner');\r\nexports.Suite = require('./suite');\r\nexports.Hook = require('./hook');\r\nexports.Test = require('./test');\r\n\r\n/**\r\n * Return image `name` path.\r\n *\r\n * @api private\r\n * @param {string} name\r\n * @return {string}\r\n */\r\nfunction image(name) {\r\n  return path.join(__dirname, '../images', name + '.png');\r\n}\r\n\r\n/**\r\n * Set up mocha with `options`.\r\n *\r\n * Options:\r\n *\r\n *   - `ui` name \"bdd\", \"tdd\", \"exports\" etc\r\n *   - `reporter` reporter instance, defaults to `mocha.reporters.spec`\r\n *   - `globals` array of accepted globals\r\n *   - `timeout` timeout in milliseconds\r\n *   - `bail` bail on the first test failure\r\n *   - `slow` milliseconds to wait before considering a test slow\r\n *   - `ignoreLeaks` ignore global leaks\r\n *   - `fullTrace` display the full stack-trace on failing\r\n *   - `grep` string or regexp to filter tests with\r\n *\r\n * @param {Object} options\r\n * @api public\r\n */\r\nfunction Mocha(options) {\r\n  options = options || {};\r\n  this.files = [];\r\n  this.options = options;\r\n  if (options.grep) {\r\n    this.grep(new RegExp(options.grep));\r\n  }\r\n  if (options.fgrep) {\r\n    this.grep(options.fgrep);\r\n  }\r\n  this.suite = new exports.Suite('', new exports.Context());\r\n  this.ui(options.ui);\r\n  this.bail(options.bail);\r\n  this.reporter(options.reporter, options.reporterOptions);\r\n  if (typeof options.timeout !== 'undefined' && options.timeout !== null) {\r\n    this.timeout(options.timeout);\r\n  }\r\n  this.useColors(options.useColors);\r\n  if (options.enableTimeouts !== null) {\r\n    this.enableTimeouts(options.enableTimeouts);\r\n  }\r\n  if (options.slow) {\r\n    this.slow(options.slow);\r\n  }\r\n\r\n  this.suite.on('pre-require', function(context) {\r\n    exports.afterEach = context.afterEach || context.teardown;\r\n    exports.after = context.after || context.suiteTeardown;\r\n    exports.beforeEach = context.beforeEach || context.setup;\r\n    exports.before = context.before || context.suiteSetup;\r\n    exports.describe = context.describe || context.suite;\r\n    exports.it = context.it || context.test;\r\n    exports.setup = context.setup || context.beforeEach;\r\n    exports.suiteSetup = context.suiteSetup || context.before;\r\n    exports.suiteTeardown = context.suiteTeardown || context.after;\r\n    exports.suite = context.suite || context.describe;\r\n    exports.teardown = context.teardown || context.afterEach;\r\n    exports.test = context.test || context.it;\r\n    exports.run = context.run;\r\n  });\r\n}\r\n\r\n/**\r\n * Enable or disable bailing on the first failure.\r\n *\r\n * @api public\r\n * @param {boolean} [bail]\r\n */\r\nMocha.prototype.bail = function(bail) {\r\n  if (!arguments.length) {\r\n    bail = true;\r\n  }\r\n  this.suite.bail(bail);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Add test `file`.\r\n *\r\n * @api public\r\n * @param {string} file\r\n */\r\nMocha.prototype.addFile = function(file) {\r\n  this.files.push(file);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set reporter to `reporter`, defaults to \"spec\".\r\n *\r\n * @param {String|Function} reporter name or constructor\r\n * @param {Object} reporterOptions optional options\r\n * @api public\r\n * @param {string|Function} reporter name or constructor\r\n * @param {Object} reporterOptions optional options\r\n */\r\nMocha.prototype.reporter = function(reporter, reporterOptions) {\r\n  if (typeof reporter === 'function') {\r\n    this._reporter = reporter;\r\n  } else {\r\n    reporter = reporter || 'spec';\r\n    var _reporter;\r\n    // Try to load a built-in reporter.\r\n    if (reporters[reporter]) {\r\n      _reporter = reporters[reporter];\r\n    }\r\n    // Try to load reporters from process.cwd() and node_modules\r\n    if (!_reporter) {\r\n      try {\r\n        _reporter = require(reporter);\r\n      } catch (err) {\r\n        err.message.indexOf('Cannot find module') !== -1\r\n          ? console.warn('\"' + reporter + '\" reporter not found')\r\n          : console.warn('\"' + reporter + '\" reporter blew up with error:\\n' + err.stack);\r\n      }\r\n    }\r\n    if (!_reporter && reporter === 'teamcity') {\r\n      console.warn('The Teamcity reporter was moved to a package named '\r\n        + 'mocha-teamcity-reporter '\r\n        + '(https://npmjs.org/package/mocha-teamcity-reporter).');\r\n    }\r\n    if (!_reporter) {\r\n      throw new Error('invalid reporter \"' + reporter + '\"');\r\n    }\r\n    this._reporter = _reporter;\r\n  }\r\n  this.options.reporterOptions = reporterOptions;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set test UI `name`, defaults to \"bdd\".\r\n *\r\n * @api public\r\n * @param {string} bdd\r\n */\r\nMocha.prototype.ui = function(name) {\r\n  name = name || 'bdd';\r\n  this._ui = exports.interfaces[name];\r\n  if (!this._ui) {\r\n    try {\r\n      this._ui = require(name);\r\n    } catch (err) {\r\n      throw new Error('invalid interface \"' + name + '\"');\r\n    }\r\n  }\r\n  this._ui = this._ui(this.suite);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Load registered files.\r\n *\r\n * @api private\r\n */\r\nMocha.prototype.loadFiles = function(fn) {\r\n  var self = this;\r\n  var suite = this.suite;\r\n  var pending = this.files.length;\r\n  this.files.forEach(function(file) {\r\n    file = path.resolve(file);\r\n    suite.emit('pre-require', global, file, self);\r\n    suite.emit('require', require(file), file, self);\r\n    suite.emit('post-require', global, file, self);\r\n    --pending || (fn && fn());\r\n  });\r\n};\r\n\r\n/**\r\n * Enable growl support.\r\n *\r\n * @api private\r\n */\r\nMocha.prototype._growl = function(runner, reporter) {\r\n  var notify = require('growl');\r\n\r\n  runner.on('end', function() {\r\n    var stats = reporter.stats;\r\n    if (stats.failures) {\r\n      var msg = stats.failures + ' of ' + runner.total + ' tests failed';\r\n      notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });\r\n    } else {\r\n      notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {\r\n        name: 'mocha',\r\n        title: 'Passed',\r\n        image: image('ok')\r\n      });\r\n    }\r\n  });\r\n};\r\n\r\n/**\r\n * Add regexp to grep, if `re` is a string it is escaped.\r\n *\r\n * @param {RegExp|String} re\r\n * @return {Mocha}\r\n * @api public\r\n * @param {RegExp|string} re\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.grep = function(re) {\r\n  this.options.grep = typeof re === 'string' ? new RegExp(escapeRe(re)) : re;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Invert `.grep()` matches.\r\n *\r\n * @return {Mocha}\r\n * @api public\r\n */\r\nMocha.prototype.invert = function() {\r\n  this.options.invert = true;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Ignore global leaks.\r\n *\r\n * @param {Boolean} ignore\r\n * @return {Mocha}\r\n * @api public\r\n * @param {boolean} ignore\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.ignoreLeaks = function(ignore) {\r\n  this.options.ignoreLeaks = Boolean(ignore);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Enable global leak checking.\r\n *\r\n * @return {Mocha}\r\n * @api public\r\n */\r\nMocha.prototype.checkLeaks = function() {\r\n  this.options.ignoreLeaks = false;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Display long stack-trace on failing\r\n *\r\n * @return {Mocha}\r\n * @api public\r\n */\r\nMocha.prototype.fullTrace = function() {\r\n  this.options.fullStackTrace = true;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Enable growl support.\r\n *\r\n * @return {Mocha}\r\n * @api public\r\n */\r\nMocha.prototype.growl = function() {\r\n  this.options.growl = true;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Ignore `globals` array or string.\r\n *\r\n * @param {Array|String} globals\r\n * @return {Mocha}\r\n * @api public\r\n * @param {Array|string} globals\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.globals = function(globals) {\r\n  this.options.globals = (this.options.globals || []).concat(globals);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Emit color output.\r\n *\r\n * @param {Boolean} colors\r\n * @return {Mocha}\r\n * @api public\r\n * @param {boolean} colors\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.useColors = function(colors) {\r\n  if (colors !== undefined) {\r\n    this.options.useColors = colors;\r\n  }\r\n  return this;\r\n};\r\n\r\n/**\r\n * Use inline diffs rather than +/-.\r\n *\r\n * @param {Boolean} inlineDiffs\r\n * @return {Mocha}\r\n * @api public\r\n * @param {boolean} inlineDiffs\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.useInlineDiffs = function(inlineDiffs) {\r\n  this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set the timeout in milliseconds.\r\n *\r\n * @param {Number} timeout\r\n * @return {Mocha}\r\n * @api public\r\n * @param {number} timeout\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.timeout = function(timeout) {\r\n  this.suite.timeout(timeout);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set slowness threshold in milliseconds.\r\n *\r\n * @param {Number} slow\r\n * @return {Mocha}\r\n * @api public\r\n * @param {number} slow\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.slow = function(slow) {\r\n  this.suite.slow(slow);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Enable timeouts.\r\n *\r\n * @param {Boolean} enabled\r\n * @return {Mocha}\r\n * @api public\r\n * @param {boolean} enabled\r\n * @return {Mocha}\r\n */\r\nMocha.prototype.enableTimeouts = function(enabled) {\r\n  this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Makes all tests async (accepting a callback)\r\n *\r\n * @return {Mocha}\r\n * @api public\r\n */\r\nMocha.prototype.asyncOnly = function() {\r\n  this.options.asyncOnly = true;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Disable syntax highlighting (in browser).\r\n *\r\n * @api public\r\n */\r\nMocha.prototype.noHighlighting = function() {\r\n  this.options.noHighlighting = true;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Enable uncaught errors to propagate (in browser).\r\n *\r\n * @return {Mocha}\r\n * @api public\r\n */\r\nMocha.prototype.allowUncaught = function() {\r\n  this.options.allowUncaught = true;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Delay root suite execution.\r\n * @returns {Mocha}\r\n */\r\nMocha.prototype.delay = function delay() {\r\n  this.options.delay = true;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Run tests and invoke `fn()` when complete.\r\n *\r\n * @api public\r\n * @param {Function} fn\r\n * @return {Runner}\r\n */\r\nMocha.prototype.run = function(fn) {\r\n  if (this.files.length) {\r\n    this.loadFiles();\r\n  }\r\n  var suite = this.suite;\r\n  var options = this.options;\r\n  options.files = this.files;\r\n  var runner = new exports.Runner(suite, options.delay);\r\n  var reporter = new this._reporter(runner, options);\r\n  runner.ignoreLeaks = options.ignoreLeaks !== false;\r\n  runner.fullStackTrace = options.fullStackTrace;\r\n  runner.asyncOnly = options.asyncOnly;\r\n  runner.allowUncaught = options.allowUncaught;\r\n  if (options.grep) {\r\n    runner.grep(options.grep, options.invert);\r\n  }\r\n  if (options.globals) {\r\n    runner.globals(options.globals);\r\n  }\r\n  if (options.growl) {\r\n    this._growl(runner, reporter);\r\n  }\r\n  if (options.useColors !== undefined) {\r\n    exports.reporters.Base.useColors = options.useColors;\r\n  }\r\n  exports.reporters.Base.inlineDiffs = options.useInlineDiffs;\r\n\r\n  function done(failures) {\r\n    if (reporter.done) {\r\n      reporter.done(failures, fn);\r\n    } else {\r\n      fn && fn(failures);\r\n    }\r\n  }\r\n\r\n  return runner.run(done);\r\n};\r\n\r\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {},\"/lib\")\r\n},{\"./context\":6,\"./hook\":7,\"./interfaces\":11,\"./reporters\":22,\"./runnable\":35,\"./runner\":36,\"./suite\":37,\"./test\":38,\"./utils\":39,\"_process\":51,\"escape-string-regexp\":68,\"growl\":69,\"path\":41}],15:[function(require,module,exports){\r\n/**\r\n * Helpers.\r\n */\r\n\r\nvar s = 1000;\r\nvar m = s * 60;\r\nvar h = m * 60;\r\nvar d = h * 24;\r\nvar y = d * 365.25;\r\n\r\n/**\r\n * Parse or format the given `val`.\r\n *\r\n * Options:\r\n *\r\n *  - `long` verbose formatting [false]\r\n *\r\n * @api public\r\n * @param {string|number} val\r\n * @param {Object} options\r\n * @return {string|number}\r\n */\r\nmodule.exports = function(val, options) {\r\n  options = options || {};\r\n  if (typeof val === 'string') {\r\n    return parse(val);\r\n  }\r\n  // https://github.com/mochajs/mocha/pull/1035\r\n  return options['long'] ? longFormat(val) : shortFormat(val);\r\n};\r\n\r\n/**\r\n * Parse the given `str` and return milliseconds.\r\n *\r\n * @api private\r\n * @param {string} str\r\n * @return {number}\r\n */\r\nfunction parse(str) {\r\n  var match = (/^((?:\\d+)?\\.?\\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str);\r\n  if (!match) {\r\n    return;\r\n  }\r\n  var n = parseFloat(match[1]);\r\n  var type = (match[2] || 'ms').toLowerCase();\r\n  switch (type) {\r\n    case 'years':\r\n    case 'year':\r\n    case 'y':\r\n      return n * y;\r\n    case 'days':\r\n    case 'day':\r\n    case 'd':\r\n      return n * d;\r\n    case 'hours':\r\n    case 'hour':\r\n    case 'h':\r\n      return n * h;\r\n    case 'minutes':\r\n    case 'minute':\r\n    case 'm':\r\n      return n * m;\r\n    case 'seconds':\r\n    case 'second':\r\n    case 's':\r\n      return n * s;\r\n    case 'ms':\r\n      return n;\r\n    default:\r\n      // No default case\r\n  }\r\n}\r\n\r\n/**\r\n * Short format for `ms`.\r\n *\r\n * @api private\r\n * @param {number} ms\r\n * @return {string}\r\n */\r\nfunction shortFormat(ms) {\r\n  if (ms >= d) {\r\n    return Math.round(ms / d) + 'd';\r\n  }\r\n  if (ms >= h) {\r\n    return Math.round(ms / h) + 'h';\r\n  }\r\n  if (ms >= m) {\r\n    return Math.round(ms / m) + 'm';\r\n  }\r\n  if (ms >= s) {\r\n    return Math.round(ms / s) + 's';\r\n  }\r\n  return ms + 'ms';\r\n}\r\n\r\n/**\r\n * Long format for `ms`.\r\n *\r\n * @api private\r\n * @param {number} ms\r\n * @return {string}\r\n */\r\nfunction longFormat(ms) {\r\n  return plural(ms, d, 'day')\r\n    || plural(ms, h, 'hour')\r\n    || plural(ms, m, 'minute')\r\n    || plural(ms, s, 'second')\r\n    || ms + ' ms';\r\n}\r\n\r\n/**\r\n * Pluralization helper.\r\n *\r\n * @api private\r\n * @param {number} ms\r\n * @param {number} n\r\n * @param {string} name\r\n */\r\nfunction plural(ms, n, name) {\r\n  if (ms < n) {\r\n    return;\r\n  }\r\n  if (ms < n * 1.5) {\r\n    return Math.floor(ms / n) + ' ' + name;\r\n  }\r\n  return Math.ceil(ms / n) + ' ' + name + 's';\r\n}\r\n\r\n},{}],16:[function(require,module,exports){\r\n\r\n/**\r\n * Expose `Pending`.\r\n */\r\n\r\nmodule.exports = Pending;\r\n\r\n/**\r\n * Initialize a new `Pending` error with the given message.\r\n *\r\n * @param {string} message\r\n */\r\nfunction Pending(message) {\r\n  this.message = message;\r\n}\r\n\r\n},{}],17:[function(require,module,exports){\r\n(function (process,global){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar tty = require('tty');\r\nvar diff = require('diff');\r\nvar ms = require('../ms');\r\nvar utils = require('../utils');\r\nvar supportsColor = process.browser ? null : require('supports-color');\r\n\r\n/**\r\n * Expose `Base`.\r\n */\r\n\r\nexports = module.exports = Base;\r\n\r\n/**\r\n * Save timer references to avoid Sinon interfering.\r\n * See: https://github.com/mochajs/mocha/issues/237\r\n */\r\n\r\n/* eslint-disable no-unused-vars, no-native-reassign */\r\nvar Date = global.Date;\r\nvar setTimeout = global.setTimeout;\r\nvar setInterval = global.setInterval;\r\nvar clearTimeout = global.clearTimeout;\r\nvar clearInterval = global.clearInterval;\r\n/* eslint-enable no-unused-vars, no-native-reassign */\r\n\r\n/**\r\n * Check if both stdio streams are associated with a tty.\r\n */\r\n\r\nvar isatty = tty.isatty(1) && tty.isatty(2);\r\n\r\n/**\r\n * Enable coloring by default, except in the browser interface.\r\n */\r\n\r\nexports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined));\r\n\r\n/**\r\n * Inline diffs instead of +/-\r\n */\r\n\r\nexports.inlineDiffs = false;\r\n\r\n/**\r\n * Default color map.\r\n */\r\n\r\nexports.colors = {\r\n  pass: 90,\r\n  fail: 31,\r\n  'bright pass': 92,\r\n  'bright fail': 91,\r\n  'bright yellow': 93,\r\n  pending: 36,\r\n  suite: 0,\r\n  'error title': 0,\r\n  'error message': 31,\r\n  'error stack': 90,\r\n  checkmark: 32,\r\n  fast: 90,\r\n  medium: 33,\r\n  slow: 31,\r\n  green: 32,\r\n  light: 90,\r\n  'diff gutter': 90,\r\n  'diff added': 32,\r\n  'diff removed': 31\r\n};\r\n\r\n/**\r\n * Default symbol map.\r\n */\r\n\r\nexports.symbols = {\r\n  ok: '?',\r\n  err: '?',\r\n  dot: '�'\r\n};\r\n\r\n// With node.js on Windows: use symbols available in terminal default fonts\r\nif (process.platform === 'win32') {\r\n  exports.symbols.ok = '\\u221A';\r\n  exports.symbols.err = '\\u00D7';\r\n  exports.symbols.dot = '.';\r\n}\r\n\r\n/**\r\n * Color `str` with the given `type`,\r\n * allowing colors to be disabled,\r\n * as well as user-defined color\r\n * schemes.\r\n *\r\n * @param {string} type\r\n * @param {string} str\r\n * @return {string}\r\n * @api private\r\n */\r\nvar color = exports.color = function(type, str) {\r\n  if (!exports.useColors) {\r\n    return String(str);\r\n  }\r\n  return '\\u001b[' + exports.colors[type] + 'm' + str + '\\u001b[0m';\r\n};\r\n\r\n/**\r\n * Expose term window size, with some defaults for when stderr is not a tty.\r\n */\r\n\r\nexports.window = {\r\n  width: 75\r\n};\r\n\r\nif (isatty) {\r\n  exports.window.width = process.stdout.getWindowSize\r\n      ? process.stdout.getWindowSize(1)[0]\r\n      : tty.getWindowSize()[1];\r\n}\r\n\r\n/**\r\n * Expose some basic cursor interactions that are common among reporters.\r\n */\r\n\r\nexports.cursor = {\r\n  hide: function() {\r\n    isatty && process.stdout.write('\\u001b[?25l');\r\n  },\r\n\r\n  show: function() {\r\n    isatty && process.stdout.write('\\u001b[?25h');\r\n  },\r\n\r\n  deleteLine: function() {\r\n    isatty && process.stdout.write('\\u001b[2K');\r\n  },\r\n\r\n  beginningOfLine: function() {\r\n    isatty && process.stdout.write('\\u001b[0G');\r\n  },\r\n\r\n  CR: function() {\r\n    if (isatty) {\r\n      exports.cursor.deleteLine();\r\n      exports.cursor.beginningOfLine();\r\n    } else {\r\n      process.stdout.write('\\r');\r\n    }\r\n  }\r\n};\r\n\r\n/**\r\n * Output the given `failures` as a list.\r\n *\r\n * @param {Array} failures\r\n * @api public\r\n */\r\n\r\nexports.list = function(failures) {\r\n  console.log();\r\n  failures.forEach(function(test, i) {\r\n    // format\r\n    var fmt = color('error title', '  %s) %s:\\n')\r\n      + color('error message', '     %s')\r\n      + color('error stack', '\\n%s\\n');\r\n\r\n    // msg\r\n    var msg;\r\n    var err = test.err;\r\n    var message;\r\n    if (err.message) {\r\n      message = err.message;\r\n    } else if (typeof err.inspect === 'function') {\r\n      message = err.inspect() + '';\r\n    } else {\r\n      message = '';\r\n    }\r\n    var stack = err.stack || message;\r\n    var index = stack.indexOf(message);\r\n    var actual = err.actual;\r\n    var expected = err.expected;\r\n    var escape = true;\r\n\r\n    if (index === -1) {\r\n      msg = message;\r\n    } else {\r\n      index += message.length;\r\n      msg = stack.slice(0, index);\r\n      // remove msg from stack\r\n      stack = stack.slice(index + 1);\r\n    }\r\n\r\n    // uncaught\r\n    if (err.uncaught) {\r\n      msg = 'Uncaught ' + msg;\r\n    }\r\n    // explicitly show diff\r\n    if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) {\r\n      escape = false;\r\n      if (!(utils.isString(actual) && utils.isString(expected))) {\r\n        err.actual = actual = utils.stringify(actual);\r\n        err.expected = expected = utils.stringify(expected);\r\n      }\r\n\r\n      fmt = color('error title', '  %s) %s:\\n%s') + color('error stack', '\\n%s\\n');\r\n      var match = message.match(/^([^:]+): expected/);\r\n      msg = '\\n      ' + color('error message', match ? match[1] : msg);\r\n\r\n      if (exports.inlineDiffs) {\r\n        msg += inlineDiff(err, escape);\r\n      } else {\r\n        msg += unifiedDiff(err, escape);\r\n      }\r\n    }\r\n\r\n    // indent stack trace\r\n    stack = stack.replace(/^/gm, '  ');\r\n\r\n    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);\r\n  });\r\n};\r\n\r\n/**\r\n * Initialize a new `Base` reporter.\r\n *\r\n * All other reporters generally\r\n * inherit from this reporter, providing\r\n * stats such as test duration, number\r\n * of tests passed / failed etc.\r\n *\r\n * @param {Runner} runner\r\n * @api public\r\n */\r\n\r\nfunction Base(runner) {\r\n  var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 };\r\n  var failures = this.failures = [];\r\n\r\n  if (!runner) {\r\n    return;\r\n  }\r\n  this.runner = runner;\r\n\r\n  runner.stats = stats;\r\n\r\n  runner.on('start', function() {\r\n    stats.start = new Date();\r\n  });\r\n\r\n  runner.on('suite', function(suite) {\r\n    stats.suites = stats.suites || 0;\r\n    suite.root || stats.suites++;\r\n  });\r\n\r\n  runner.on('test end', function() {\r\n    stats.tests = stats.tests || 0;\r\n    stats.tests++;\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    stats.passes = stats.passes || 0;\r\n\r\n    if (test.duration > test.slow()) {\r\n      test.speed = 'slow';\r\n    } else if (test.duration > test.slow() / 2) {\r\n      test.speed = 'medium';\r\n    } else {\r\n      test.speed = 'fast';\r\n    }\r\n\r\n    stats.passes++;\r\n  });\r\n\r\n  runner.on('fail', function(test, err) {\r\n    stats.failures = stats.failures || 0;\r\n    stats.failures++;\r\n    test.err = err;\r\n    failures.push(test);\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    stats.end = new Date();\r\n    stats.duration = new Date() - stats.start;\r\n  });\r\n\r\n  runner.on('pending', function() {\r\n    stats.pending++;\r\n  });\r\n}\r\n\r\n/**\r\n * Output common epilogue used by many of\r\n * the bundled reporters.\r\n *\r\n * @api public\r\n */\r\nBase.prototype.epilogue = function() {\r\n  var stats = this.stats;\r\n  var fmt;\r\n\r\n  console.log();\r\n\r\n  // passes\r\n  fmt = color('bright pass', ' ')\r\n    + color('green', ' %d passing')\r\n    + color('light', ' (%s)');\r\n\r\n  console.log(fmt,\r\n    stats.passes || 0,\r\n    ms(stats.duration));\r\n\r\n  // pending\r\n  if (stats.pending) {\r\n    fmt = color('pending', ' ')\r\n      + color('pending', ' %d pending');\r\n\r\n    console.log(fmt, stats.pending);\r\n  }\r\n\r\n  // failures\r\n  if (stats.failures) {\r\n    fmt = color('fail', '  %d failing');\r\n\r\n    console.log(fmt, stats.failures);\r\n\r\n    Base.list(this.failures);\r\n    console.log();\r\n  }\r\n\r\n  console.log();\r\n};\r\n\r\n/**\r\n * Pad the given `str` to `len`.\r\n *\r\n * @api private\r\n * @param {string} str\r\n * @param {string} len\r\n * @return {string}\r\n */\r\nfunction pad(str, len) {\r\n  str = String(str);\r\n  return Array(len - str.length + 1).join(' ') + str;\r\n}\r\n\r\n/**\r\n * Returns an inline diff between 2 strings with coloured ANSI output\r\n *\r\n * @api private\r\n * @param {Error} err with actual/expected\r\n * @param {boolean} escape\r\n * @return {string} Diff\r\n */\r\nfunction inlineDiff(err, escape) {\r\n  var msg = errorDiff(err, 'WordsWithSpace', escape);\r\n\r\n  // linenos\r\n  var lines = msg.split('\\n');\r\n  if (lines.length > 4) {\r\n    var width = String(lines.length).length;\r\n    msg = lines.map(function(str, i) {\r\n      return pad(++i, width) + ' |' + ' ' + str;\r\n    }).join('\\n');\r\n  }\r\n\r\n  // legend\r\n  msg = '\\n'\r\n    + color('diff removed', 'actual')\r\n    + ' '\r\n    + color('diff added', 'expected')\r\n    + '\\n\\n'\r\n    + msg\r\n    + '\\n';\r\n\r\n  // indent\r\n  msg = msg.replace(/^/gm, '      ');\r\n  return msg;\r\n}\r\n\r\n/**\r\n * Returns a unified diff between two strings.\r\n *\r\n * @api private\r\n * @param {Error} err with actual/expected\r\n * @param {boolean} escape\r\n * @return {string} The diff.\r\n */\r\nfunction unifiedDiff(err, escape) {\r\n  var indent = '      ';\r\n  function cleanUp(line) {\r\n    if (escape) {\r\n      line = escapeInvisibles(line);\r\n    }\r\n    if (line[0] === '+') {\r\n      return indent + colorLines('diff added', line);\r\n    }\r\n    if (line[0] === '-') {\r\n      return indent + colorLines('diff removed', line);\r\n    }\r\n    if (line.match(/\\@\\@/)) {\r\n      return null;\r\n    }\r\n    if (line.match(/\\\\ No newline/)) {\r\n      return null;\r\n    }\r\n    return indent + line;\r\n  }\r\n  function notBlank(line) {\r\n    return typeof line !== 'undefined' && line !== null;\r\n  }\r\n  var msg = diff.createPatch('string', err.actual, err.expected);\r\n  var lines = msg.split('\\n').splice(4);\r\n  return '\\n      '\r\n    + colorLines('diff added', '+ expected') + ' '\r\n    + colorLines('diff removed', '- actual')\r\n    + '\\n\\n'\r\n    + lines.map(cleanUp).filter(notBlank).join('\\n');\r\n}\r\n\r\n/**\r\n * Return a character diff for `err`.\r\n *\r\n * @api private\r\n * @param {Error} err\r\n * @param {string} type\r\n * @param {boolean} escape\r\n * @return {string}\r\n */\r\nfunction errorDiff(err, type, escape) {\r\n  var actual = escape ? escapeInvisibles(err.actual) : err.actual;\r\n  var expected = escape ? escapeInvisibles(err.expected) : err.expected;\r\n  return diff['diff' + type](actual, expected).map(function(str) {\r\n    if (str.added) {\r\n      return colorLines('diff added', str.value);\r\n    }\r\n    if (str.removed) {\r\n      return colorLines('diff removed', str.value);\r\n    }\r\n    return str.value;\r\n  }).join('');\r\n}\r\n\r\n/**\r\n * Returns a string with all invisible characters in plain text\r\n *\r\n * @api private\r\n * @param {string} line\r\n * @return {string}\r\n */\r\nfunction escapeInvisibles(line) {\r\n  return line.replace(/\\t/g, '<tab>')\r\n    .replace(/\\r/g, '<CR>')\r\n    .replace(/\\n/g, '<LF>\\n');\r\n}\r\n\r\n/**\r\n * Color lines for `str`, using the color `name`.\r\n *\r\n * @api private\r\n * @param {string} name\r\n * @param {string} str\r\n * @return {string}\r\n */\r\nfunction colorLines(name, str) {\r\n  return str.split('\\n').map(function(str) {\r\n    return color(name, str);\r\n  }).join('\\n');\r\n}\r\n\r\n/**\r\n * Object#toString reference.\r\n */\r\nvar objToString = Object.prototype.toString;\r\n\r\n/**\r\n * Check that a / b have the same type.\r\n *\r\n * @api private\r\n * @param {Object} a\r\n * @param {Object} b\r\n * @return {boolean}\r\n */\r\nfunction sameType(a, b) {\r\n  return objToString.call(a) === objToString.call(b);\r\n}\r\n\r\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"../ms\":15,\"../utils\":39,\"_process\":51,\"diff\":67,\"supports-color\":41,\"tty\":5}],18:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar utils = require('../utils');\r\n\r\n/**\r\n * Expose `Doc`.\r\n */\r\n\r\nexports = module.exports = Doc;\r\n\r\n/**\r\n * Initialize a new `Doc` reporter.\r\n *\r\n * @param {Runner} runner\r\n * @api public\r\n */\r\nfunction Doc(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var indents = 2;\r\n\r\n  function indent() {\r\n    return Array(indents).join('  ');\r\n  }\r\n\r\n  runner.on('suite', function(suite) {\r\n    if (suite.root) {\r\n      return;\r\n    }\r\n    ++indents;\r\n    console.log('%s<section class=\"suite\">', indent());\r\n    ++indents;\r\n    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));\r\n    console.log('%s<dl>', indent());\r\n  });\r\n\r\n  runner.on('suite end', function(suite) {\r\n    if (suite.root) {\r\n      return;\r\n    }\r\n    console.log('%s</dl>', indent());\r\n    --indents;\r\n    console.log('%s</section>', indent());\r\n    --indents;\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));\r\n    var code = utils.escape(utils.clean(test.fn.toString()));\r\n    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);\r\n  });\r\n\r\n  runner.on('fail', function(test, err) {\r\n    console.log('%s  <dt class=\"error\">%s</dt>', indent(), utils.escape(test.title));\r\n    var code = utils.escape(utils.clean(test.fn.toString()));\r\n    console.log('%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>', indent(), code);\r\n    console.log('%s  <dd class=\"error\">%s</dd>', indent(), utils.escape(err));\r\n  });\r\n}\r\n\r\n},{\"../utils\":39,\"./base\":17}],19:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar inherits = require('../utils').inherits;\r\nvar color = Base.color;\r\n\r\n/**\r\n * Expose `Dot`.\r\n */\r\n\r\nexports = module.exports = Dot;\r\n\r\n/**\r\n * Initialize a new `Dot` matrix test reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction Dot(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var width = Base.window.width * .75 | 0;\r\n  var n = -1;\r\n\r\n  runner.on('start', function() {\r\n    process.stdout.write('\\n');\r\n  });\r\n\r\n  runner.on('pending', function() {\r\n    if (++n % width === 0) {\r\n      process.stdout.write('\\n  ');\r\n    }\r\n    process.stdout.write(color('pending', Base.symbols.dot));\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    if (++n % width === 0) {\r\n      process.stdout.write('\\n  ');\r\n    }\r\n    if (test.speed === 'slow') {\r\n      process.stdout.write(color('bright yellow', Base.symbols.dot));\r\n    } else {\r\n      process.stdout.write(color(test.speed, Base.symbols.dot));\r\n    }\r\n  });\r\n\r\n  runner.on('fail', function() {\r\n    if (++n % width === 0) {\r\n      process.stdout.write('\\n  ');\r\n    }\r\n    process.stdout.write(color('fail', Base.symbols.dot));\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    console.log();\r\n    self.epilogue();\r\n  });\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(Dot, Base);\r\n\r\n}).call(this,require('_process'))\r\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],20:[function(require,module,exports){\r\n(function (process,__dirname){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar JSONCov = require('./json-cov');\r\nvar readFileSync = require('fs').readFileSync;\r\nvar join = require('path').join;\r\n\r\n/**\r\n * Expose `HTMLCov`.\r\n */\r\n\r\nexports = module.exports = HTMLCov;\r\n\r\n/**\r\n * Initialize a new `JsCoverage` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction HTMLCov(runner) {\r\n  var jade = require('jade');\r\n  var file = join(__dirname, '/templates/coverage.jade');\r\n  var str = readFileSync(file, 'utf8');\r\n  var fn = jade.compile(str, { filename: file });\r\n  var self = this;\r\n\r\n  JSONCov.call(this, runner, false);\r\n\r\n  runner.on('end', function() {\r\n    process.stdout.write(fn({\r\n      cov: self.cov,\r\n      coverageClass: coverageClass\r\n    }));\r\n  });\r\n}\r\n\r\n/**\r\n * Return coverage class for a given coverage percentage.\r\n *\r\n * @api private\r\n * @param {number} coveragePctg\r\n * @return {string}\r\n */\r\nfunction coverageClass(coveragePctg) {\r\n  if (coveragePctg >= 75) {\r\n    return 'high';\r\n  }\r\n  if (coveragePctg >= 50) {\r\n    return 'medium';\r\n  }\r\n  if (coveragePctg >= 25) {\r\n    return 'low';\r\n  }\r\n  return 'terrible';\r\n}\r\n\r\n}).call(this,require('_process'),\"/lib/reporters\")\r\n},{\"./json-cov\":23,\"_process\":51,\"fs\":41,\"jade\":41,\"path\":41}],21:[function(require,module,exports){\r\n(function (global){\r\n/* eslint-env browser */\r\n\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar utils = require('../utils');\r\nvar Progress = require('../browser/progress');\r\nvar escapeRe = require('escape-string-regexp');\r\nvar escape = utils.escape;\r\n\r\n/**\r\n * Save timer references to avoid Sinon interfering (see GH-237).\r\n */\r\n\r\n/* eslint-disable no-unused-vars, no-native-reassign */\r\nvar Date = global.Date;\r\nvar setTimeout = global.setTimeout;\r\nvar setInterval = global.setInterval;\r\nvar clearTimeout = global.clearTimeout;\r\nvar clearInterval = global.clearInterval;\r\n/* eslint-enable no-unused-vars, no-native-reassign */\r\n\r\n/**\r\n * Expose `HTML`.\r\n */\r\n\r\nexports = module.exports = HTML;\r\n\r\n/**\r\n * Stats template.\r\n */\r\n\r\nvar statsTemplate = '<ul id=\"mocha-stats\">'\r\n  + '<li class=\"progress\"><canvas width=\"40\" height=\"40\"></canvas></li>'\r\n  + '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>'\r\n  + '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>'\r\n  + '<li class=\"duration\">duration: <em>0</em>s</li>'\r\n  + '</ul>';\r\n\r\n/**\r\n * Initialize a new `HTML` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction HTML(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var stats = this.stats;\r\n  var stat = fragment(statsTemplate);\r\n  var items = stat.getElementsByTagName('li');\r\n  var passes = items[1].getElementsByTagName('em')[0];\r\n  var passesLink = items[1].getElementsByTagName('a')[0];\r\n  var failures = items[2].getElementsByTagName('em')[0];\r\n  var failuresLink = items[2].getElementsByTagName('a')[0];\r\n  var duration = items[3].getElementsByTagName('em')[0];\r\n  var canvas = stat.getElementsByTagName('canvas')[0];\r\n  var report = fragment('<ul id=\"mocha-report\"></ul>');\r\n  var stack = [report];\r\n  var progress;\r\n  var ctx;\r\n  var root = document.getElementById('mocha');\r\n\r\n  if (canvas.getContext) {\r\n    var ratio = window.devicePixelRatio || 1;\r\n    canvas.style.width = canvas.width;\r\n    canvas.style.height = canvas.height;\r\n    canvas.width *= ratio;\r\n    canvas.height *= ratio;\r\n    ctx = canvas.getContext('2d');\r\n    ctx.scale(ratio, ratio);\r\n    progress = new Progress();\r\n  }\r\n\r\n  if (!root) {\r\n    return error('#mocha div missing, add it to your document');\r\n  }\r\n\r\n  // pass toggle\r\n  on(passesLink, 'click', function() {\r\n    unhide();\r\n    var name = (/pass/).test(report.className) ? '' : ' pass';\r\n    report.className = report.className.replace(/fail|pass/g, '') + name;\r\n    if (report.className.trim()) {\r\n      hideSuitesWithout('test pass');\r\n    }\r\n  });\r\n\r\n  // failure toggle\r\n  on(failuresLink, 'click', function() {\r\n    unhide();\r\n    var name = (/fail/).test(report.className) ? '' : ' fail';\r\n    report.className = report.className.replace(/fail|pass/g, '') + name;\r\n    if (report.className.trim()) {\r\n      hideSuitesWithout('test fail');\r\n    }\r\n  });\r\n\r\n  root.appendChild(stat);\r\n  root.appendChild(report);\r\n\r\n  if (progress) {\r\n    progress.size(40);\r\n  }\r\n\r\n  runner.on('suite', function(suite) {\r\n    if (suite.root) {\r\n      return;\r\n    }\r\n\r\n    // suite\r\n    var url = self.suiteURL(suite);\r\n    var el = fragment('<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>', url, escape(suite.title));\r\n\r\n    // container\r\n    stack[0].appendChild(el);\r\n    stack.unshift(document.createElement('ul'));\r\n    el.appendChild(stack[0]);\r\n  });\r\n\r\n  runner.on('suite end', function(suite) {\r\n    if (suite.root) {\r\n      return;\r\n    }\r\n    stack.shift();\r\n  });\r\n\r\n  runner.on('fail', function(test) {\r\n    if (test.type === 'hook') {\r\n      runner.emit('test end', test);\r\n    }\r\n  });\r\n\r\n  runner.on('test end', function(test) {\r\n    // TODO: add to stats\r\n    var percent = stats.tests / this.total * 100 | 0;\r\n    if (progress) {\r\n      progress.update(percent).draw(ctx);\r\n    }\r\n\r\n    // update stats\r\n    var ms = new Date() - stats.start;\r\n    text(passes, stats.passes);\r\n    text(failures, stats.failures);\r\n    text(duration, (ms / 1000).toFixed(2));\r\n\r\n    // test\r\n    var el;\r\n    if (test.state === 'passed') {\r\n      var url = self.testURL(test);\r\n      el = fragment('<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> <a href=\"%s\" class=\"replay\">?</a></h2></li>', test.speed, test.title, test.duration, url);\r\n    } else if (test.pending) {\r\n      el = fragment('<li class=\"test pass pending\"><h2>%e</h2></li>', test.title);\r\n    } else {\r\n      el = fragment('<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">?</a></h2></li>', test.title, self.testURL(test));\r\n      var stackString; // Note: Includes leading newline\r\n      var message = test.err.toString();\r\n\r\n      // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\r\n      // check for the result of the stringifying.\r\n      if (message === '[object Error]') {\r\n        message = test.err.message;\r\n      }\r\n\r\n      if (test.err.stack) {\r\n        var indexOfMessage = test.err.stack.indexOf(test.err.message);\r\n        if (indexOfMessage === -1) {\r\n          stackString = test.err.stack;\r\n        } else {\r\n          stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);\r\n        }\r\n      } else if (test.err.sourceURL && test.err.line !== undefined) {\r\n        // Safari doesn't give you a stack. Let's at least provide a source line.\r\n        stackString = '\\n(' + test.err.sourceURL + ':' + test.err.line + ')';\r\n      }\r\n\r\n      stackString = stackString || '';\r\n\r\n      if (test.err.htmlMessage && stackString) {\r\n        el.appendChild(fragment('<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>', test.err.htmlMessage, stackString));\r\n      } else if (test.err.htmlMessage) {\r\n        el.appendChild(fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage));\r\n      } else {\r\n        el.appendChild(fragment('<pre class=\"error\">%e%e</pre>', message, stackString));\r\n      }\r\n    }\r\n\r\n    // toggle code\r\n    // TODO: defer\r\n    if (!test.pending) {\r\n      var h2 = el.getElementsByTagName('h2')[0];\r\n\r\n      on(h2, 'click', function() {\r\n        pre.style.display = pre.style.display === 'none' ? 'block' : 'none';\r\n      });\r\n\r\n      var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));\r\n      el.appendChild(pre);\r\n      pre.style.display = 'none';\r\n    }\r\n\r\n    // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\r\n    if (stack[0]) {\r\n      stack[0].appendChild(el);\r\n    }\r\n  });\r\n}\r\n\r\n/**\r\n * Makes a URL, preserving querystring (\"search\") parameters.\r\n *\r\n * @param {string} s\r\n * @return {string} A new URL.\r\n */\r\nfunction makeUrl(s) {\r\n  var search = window.location.search;\r\n\r\n  // Remove previous grep query parameter if present\r\n  if (search) {\r\n    search = search.replace(/[?&]grep=[^&\\s]*/g, '').replace(/^&/, '?');\r\n  }\r\n\r\n  return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));\r\n}\r\n\r\n/**\r\n * Provide suite URL.\r\n *\r\n * @param {Object} [suite]\r\n */\r\nHTML.prototype.suiteURL = function(suite) {\r\n  return makeUrl(suite.fullTitle());\r\n};\r\n\r\n/**\r\n * Provide test URL.\r\n *\r\n * @param {Object} [test]\r\n */\r\nHTML.prototype.testURL = function(test) {\r\n  return makeUrl(test.fullTitle());\r\n};\r\n\r\n/**\r\n * Display error `msg`.\r\n *\r\n * @param {string} msg\r\n */\r\nfunction error(msg) {\r\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\r\n}\r\n\r\n/**\r\n * Return a DOM fragment from `html`.\r\n *\r\n * @param {string} html\r\n */\r\nfunction fragment(html) {\r\n  var args = arguments;\r\n  var div = document.createElement('div');\r\n  var i = 1;\r\n\r\n  div.innerHTML = html.replace(/%([se])/g, function(_, type) {\r\n    switch (type) {\r\n      case 's': return String(args[i++]);\r\n      case 'e': return escape(args[i++]);\r\n      // no default\r\n    }\r\n  });\r\n\r\n  return div.firstChild;\r\n}\r\n\r\n/**\r\n * Check for suites that do not have elements\r\n * with `classname`, and hide them.\r\n *\r\n * @param {text} classname\r\n */\r\nfunction hideSuitesWithout(classname) {\r\n  var suites = document.getElementsByClassName('suite');\r\n  for (var i = 0; i < suites.length; i++) {\r\n    var els = suites[i].getElementsByClassName(classname);\r\n    if (!els.length) {\r\n      suites[i].className += ' hidden';\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * Unhide .hidden suites.\r\n */\r\nfunction unhide() {\r\n  var els = document.getElementsByClassName('suite hidden');\r\n  for (var i = 0; i < els.length; ++i) {\r\n    els[i].className = els[i].className.replace('suite hidden', 'suite');\r\n  }\r\n}\r\n\r\n/**\r\n * Set an element's text contents.\r\n *\r\n * @param {HTMLElement} el\r\n * @param {string} contents\r\n */\r\nfunction text(el, contents) {\r\n  if (el.textContent) {\r\n    el.textContent = contents;\r\n  } else {\r\n    el.innerText = contents;\r\n  }\r\n}\r\n\r\n/**\r\n * Listen on `event` with callback `fn`.\r\n */\r\nfunction on(el, event, fn) {\r\n  if (el.addEventListener) {\r\n    el.addEventListener(event, fn, false);\r\n  } else {\r\n    el.attachEvent('on' + event, fn);\r\n  }\r\n}\r\n\r\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"../browser/progress\":4,\"../utils\":39,\"./base\":17,\"escape-string-regexp\":68}],22:[function(require,module,exports){\r\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\r\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\r\nexports.Base = exports.base = require('./base');\r\nexports.Dot = exports.dot = require('./dot');\r\nexports.Doc = exports.doc = require('./doc');\r\nexports.TAP = exports.tap = require('./tap');\r\nexports.JSON = exports.json = require('./json');\r\nexports.HTML = exports.html = require('./html');\r\nexports.List = exports.list = require('./list');\r\nexports.Min = exports.min = require('./min');\r\nexports.Spec = exports.spec = require('./spec');\r\nexports.Nyan = exports.nyan = require('./nyan');\r\nexports.XUnit = exports.xunit = require('./xunit');\r\nexports.Markdown = exports.markdown = require('./markdown');\r\nexports.Progress = exports.progress = require('./progress');\r\nexports.Landing = exports.landing = require('./landing');\r\nexports.JSONCov = exports['json-cov'] = require('./json-cov');\r\nexports.HTMLCov = exports['html-cov'] = require('./html-cov');\r\nexports.JSONStream = exports['json-stream'] = require('./json-stream');\r\n\r\n},{\"./base\":17,\"./doc\":18,\"./dot\":19,\"./html\":21,\"./html-cov\":20,\"./json\":25,\"./json-cov\":23,\"./json-stream\":24,\"./landing\":26,\"./list\":27,\"./markdown\":28,\"./min\":29,\"./nyan\":30,\"./progress\":31,\"./spec\":32,\"./tap\":33,\"./xunit\":34}],23:[function(require,module,exports){\r\n(function (process,global){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\n\r\n/**\r\n * Expose `JSONCov`.\r\n */\r\n\r\nexports = module.exports = JSONCov;\r\n\r\n/**\r\n * Initialize a new `JsCoverage` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n * @param {boolean} output\r\n */\r\nfunction JSONCov(runner, output) {\r\n  Base.call(this, runner);\r\n\r\n  output = arguments.length === 1 || output;\r\n  var self = this;\r\n  var tests = [];\r\n  var failures = [];\r\n  var passes = [];\r\n\r\n  runner.on('test end', function(test) {\r\n    tests.push(test);\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    passes.push(test);\r\n  });\r\n\r\n  runner.on('fail', function(test) {\r\n    failures.push(test);\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    var cov = global._$jscoverage || {};\r\n    var result = self.cov = map(cov);\r\n    result.stats = self.stats;\r\n    result.tests = tests.map(clean);\r\n    result.failures = failures.map(clean);\r\n    result.passes = passes.map(clean);\r\n    if (!output) {\r\n      return;\r\n    }\r\n    process.stdout.write(JSON.stringify(result, null, 2));\r\n  });\r\n}\r\n\r\n/**\r\n * Map jscoverage data to a JSON structure\r\n * suitable for reporting.\r\n *\r\n * @api private\r\n * @param {Object} cov\r\n * @return {Object}\r\n */\r\n\r\nfunction map(cov) {\r\n  var ret = {\r\n    instrumentation: 'node-jscoverage',\r\n    sloc: 0,\r\n    hits: 0,\r\n    misses: 0,\r\n    coverage: 0,\r\n    files: []\r\n  };\r\n\r\n  for (var filename in cov) {\r\n    if (Object.prototype.hasOwnProperty.call(cov, filename)) {\r\n      var data = coverage(filename, cov[filename]);\r\n      ret.files.push(data);\r\n      ret.hits += data.hits;\r\n      ret.misses += data.misses;\r\n      ret.sloc += data.sloc;\r\n    }\r\n  }\r\n\r\n  ret.files.sort(function(a, b) {\r\n    return a.filename.localeCompare(b.filename);\r\n  });\r\n\r\n  if (ret.sloc > 0) {\r\n    ret.coverage = (ret.hits / ret.sloc) * 100;\r\n  }\r\n\r\n  return ret;\r\n}\r\n\r\n/**\r\n * Map jscoverage data for a single source file\r\n * to a JSON structure suitable for reporting.\r\n *\r\n * @api private\r\n * @param {string} filename name of the source file\r\n * @param {Object} data jscoverage coverage data\r\n * @return {Object}\r\n */\r\nfunction coverage(filename, data) {\r\n  var ret = {\r\n    filename: filename,\r\n    coverage: 0,\r\n    hits: 0,\r\n    misses: 0,\r\n    sloc: 0,\r\n    source: {}\r\n  };\r\n\r\n  data.source.forEach(function(line, num) {\r\n    num++;\r\n\r\n    if (data[num] === 0) {\r\n      ret.misses++;\r\n      ret.sloc++;\r\n    } else if (data[num] !== undefined) {\r\n      ret.hits++;\r\n      ret.sloc++;\r\n    }\r\n\r\n    ret.source[num] = {\r\n      source: line,\r\n      coverage: data[num] === undefined ? '' : data[num]\r\n    };\r\n  });\r\n\r\n  ret.coverage = ret.hits / ret.sloc * 100;\r\n\r\n  return ret;\r\n}\r\n\r\n/**\r\n * Return a plain-object representation of `test`\r\n * free of cyclic properties etc.\r\n *\r\n * @api private\r\n * @param {Object} test\r\n * @return {Object}\r\n */\r\nfunction clean(test) {\r\n  return {\r\n    duration: test.duration,\r\n    fullTitle: test.fullTitle(),\r\n    title: test.title\r\n  };\r\n}\r\n\r\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"./base\":17,\"_process\":51}],24:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\n\r\n/**\r\n * Expose `List`.\r\n */\r\n\r\nexports = module.exports = List;\r\n\r\n/**\r\n * Initialize a new `List` test reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction List(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var total = runner.total;\r\n\r\n  runner.on('start', function() {\r\n    console.log(JSON.stringify(['start', { total: total }]));\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    console.log(JSON.stringify(['pass', clean(test)]));\r\n  });\r\n\r\n  runner.on('fail', function(test, err) {\r\n    test = clean(test);\r\n    test.err = err.message;\r\n    test.stack = err.stack || null;\r\n    console.log(JSON.stringify(['fail', test]));\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    process.stdout.write(JSON.stringify(['end', self.stats]));\r\n  });\r\n}\r\n\r\n/**\r\n * Return a plain-object representation of `test`\r\n * free of cyclic properties etc.\r\n *\r\n * @api private\r\n * @param {Object} test\r\n * @return {Object}\r\n */\r\nfunction clean(test) {\r\n  return {\r\n    title: test.title,\r\n    fullTitle: test.fullTitle(),\r\n    duration: test.duration\r\n  };\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"./base\":17,\"_process\":51}],25:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\n\r\n/**\r\n * Expose `JSON`.\r\n */\r\n\r\nexports = module.exports = JSONReporter;\r\n\r\n/**\r\n * Initialize a new `JSON` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction JSONReporter(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var tests = [];\r\n  var pending = [];\r\n  var failures = [];\r\n  var passes = [];\r\n\r\n  runner.on('test end', function(test) {\r\n    tests.push(test);\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    passes.push(test);\r\n  });\r\n\r\n  runner.on('fail', function(test) {\r\n    failures.push(test);\r\n  });\r\n\r\n  runner.on('pending', function(test) {\r\n    pending.push(test);\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    var obj = {\r\n      stats: self.stats,\r\n      tests: tests.map(clean),\r\n      pending: pending.map(clean),\r\n      failures: failures.map(clean),\r\n      passes: passes.map(clean)\r\n    };\r\n\r\n    runner.testResults = obj;\r\n\r\n    process.stdout.write(JSON.stringify(obj, null, 2));\r\n  });\r\n}\r\n\r\n/**\r\n * Return a plain-object representation of `test`\r\n * free of cyclic properties etc.\r\n *\r\n * @api private\r\n * @param {Object} test\r\n * @return {Object}\r\n */\r\nfunction clean(test) {\r\n  return {\r\n    title: test.title,\r\n    fullTitle: test.fullTitle(),\r\n    duration: test.duration,\r\n    err: errorJSON(test.err || {})\r\n  };\r\n}\r\n\r\n/**\r\n * Transform `error` into a JSON object.\r\n *\r\n * @api private\r\n * @param {Error} err\r\n * @return {Object}\r\n */\r\nfunction errorJSON(err) {\r\n  var res = {};\r\n  Object.getOwnPropertyNames(err).forEach(function(key) {\r\n    res[key] = err[key];\r\n  }, err);\r\n  return res;\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"./base\":17,\"_process\":51}],26:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar inherits = require('../utils').inherits;\r\nvar cursor = Base.cursor;\r\nvar color = Base.color;\r\n\r\n/**\r\n * Expose `Landing`.\r\n */\r\n\r\nexports = module.exports = Landing;\r\n\r\n/**\r\n * Airplane color.\r\n */\r\n\r\nBase.colors.plane = 0;\r\n\r\n/**\r\n * Airplane crash color.\r\n */\r\n\r\nBase.colors['plane crash'] = 31;\r\n\r\n/**\r\n * Runway color.\r\n */\r\n\r\nBase.colors.runway = 90;\r\n\r\n/**\r\n * Initialize a new `Landing` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction Landing(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var width = Base.window.width * .75 | 0;\r\n  var total = runner.total;\r\n  var stream = process.stdout;\r\n  var plane = color('plane', '?');\r\n  var crashed = -1;\r\n  var n = 0;\r\n\r\n  function runway() {\r\n    var buf = Array(width).join('-');\r\n    return '  ' + color('runway', buf);\r\n  }\r\n\r\n  runner.on('start', function() {\r\n    stream.write('\\n\\n\\n  ');\r\n    cursor.hide();\r\n  });\r\n\r\n  runner.on('test end', function(test) {\r\n    // check if the plane crashed\r\n    var col = crashed === -1 ? width * ++n / total | 0 : crashed;\r\n\r\n    // show the crash\r\n    if (test.state === 'failed') {\r\n      plane = color('plane crash', '?');\r\n      crashed = col;\r\n    }\r\n\r\n    // render landing strip\r\n    stream.write('\\u001b[' + (width + 1) + 'D\\u001b[2A');\r\n    stream.write(runway());\r\n    stream.write('\\n  ');\r\n    stream.write(color('runway', Array(col).join('�')));\r\n    stream.write(plane);\r\n    stream.write(color('runway', Array(width - col).join('�') + '\\n'));\r\n    stream.write(runway());\r\n    stream.write('\\u001b[0m');\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    cursor.show();\r\n    console.log();\r\n    self.epilogue();\r\n  });\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(Landing, Base);\r\n\r\n}).call(this,require('_process'))\r\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],27:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar inherits = require('../utils').inherits;\r\nvar color = Base.color;\r\nvar cursor = Base.cursor;\r\n\r\n/**\r\n * Expose `List`.\r\n */\r\n\r\nexports = module.exports = List;\r\n\r\n/**\r\n * Initialize a new `List` test reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction List(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var n = 0;\r\n\r\n  runner.on('start', function() {\r\n    console.log();\r\n  });\r\n\r\n  runner.on('test', function(test) {\r\n    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));\r\n  });\r\n\r\n  runner.on('pending', function(test) {\r\n    var fmt = color('checkmark', '  -')\r\n      + color('pending', ' %s');\r\n    console.log(fmt, test.fullTitle());\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    var fmt = color('checkmark', '  ' + Base.symbols.dot)\r\n      + color('pass', ' %s: ')\r\n      + color(test.speed, '%dms');\r\n    cursor.CR();\r\n    console.log(fmt, test.fullTitle(), test.duration);\r\n  });\r\n\r\n  runner.on('fail', function(test) {\r\n    cursor.CR();\r\n    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());\r\n  });\r\n\r\n  runner.on('end', self.epilogue.bind(self));\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(List, Base);\r\n\r\n}).call(this,require('_process'))\r\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],28:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar utils = require('../utils');\r\n\r\n/**\r\n * Constants\r\n */\r\n\r\nvar SUITE_PREFIX = '$';\r\n\r\n/**\r\n * Expose `Markdown`.\r\n */\r\n\r\nexports = module.exports = Markdown;\r\n\r\n/**\r\n * Initialize a new `Markdown` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction Markdown(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var level = 0;\r\n  var buf = '';\r\n\r\n  function title(str) {\r\n    return Array(level).join('#') + ' ' + str;\r\n  }\r\n\r\n  function mapTOC(suite, obj) {\r\n    var ret = obj;\r\n    var key = SUITE_PREFIX + suite.title;\r\n\r\n    obj = obj[key] = obj[key] || { suite: suite };\r\n    suite.suites.forEach(function(suite) {\r\n      mapTOC(suite, obj);\r\n    });\r\n\r\n    return ret;\r\n  }\r\n\r\n  function stringifyTOC(obj, level) {\r\n    ++level;\r\n    var buf = '';\r\n    var link;\r\n    for (var key in obj) {\r\n      if (key === 'suite') {\r\n        continue;\r\n      }\r\n      if (key !== SUITE_PREFIX) {\r\n        link = ' - [' + key.substring(1) + ']';\r\n        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\\n';\r\n        buf += Array(level).join('  ') + link;\r\n      }\r\n      buf += stringifyTOC(obj[key], level);\r\n    }\r\n    return buf;\r\n  }\r\n\r\n  function generateTOC(suite) {\r\n    var obj = mapTOC(suite, {});\r\n    return stringifyTOC(obj, 0);\r\n  }\r\n\r\n  generateTOC(runner.suite);\r\n\r\n  runner.on('suite', function(suite) {\r\n    ++level;\r\n    var slug = utils.slug(suite.fullTitle());\r\n    buf += '<a name=\"' + slug + '\"></a>' + '\\n';\r\n    buf += title(suite.title) + '\\n';\r\n  });\r\n\r\n  runner.on('suite end', function() {\r\n    --level;\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    var code = utils.clean(test.fn.toString());\r\n    buf += test.title + '.\\n';\r\n    buf += '\\n```js\\n';\r\n    buf += code + '\\n';\r\n    buf += '```\\n\\n';\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    process.stdout.write('# TOC\\n');\r\n    process.stdout.write(generateTOC(runner.suite));\r\n    process.stdout.write(buf);\r\n  });\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],29:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar inherits = require('../utils').inherits;\r\n\r\n/**\r\n * Expose `Min`.\r\n */\r\n\r\nexports = module.exports = Min;\r\n\r\n/**\r\n * Initialize a new `Min` minimal test reporter (best used with --watch).\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction Min(runner) {\r\n  Base.call(this, runner);\r\n\r\n  runner.on('start', function() {\r\n    // clear screen\r\n    process.stdout.write('\\u001b[2J');\r\n    // set cursor position\r\n    process.stdout.write('\\u001b[1;3H');\r\n  });\r\n\r\n  runner.on('end', this.epilogue.bind(this));\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(Min, Base);\r\n\r\n}).call(this,require('_process'))\r\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],30:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar inherits = require('../utils').inherits;\r\n\r\n/**\r\n * Expose `Dot`.\r\n */\r\n\r\nexports = module.exports = NyanCat;\r\n\r\n/**\r\n * Initialize a new `Dot` matrix test reporter.\r\n *\r\n * @param {Runner} runner\r\n * @api public\r\n */\r\n\r\nfunction NyanCat(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var width = Base.window.width * .75 | 0;\r\n  var nyanCatWidth = this.nyanCatWidth = 11;\r\n\r\n  this.colorIndex = 0;\r\n  this.numberOfLines = 4;\r\n  this.rainbowColors = self.generateColors();\r\n  this.scoreboardWidth = 5;\r\n  this.tick = 0;\r\n  this.trajectories = [[], [], [], []];\r\n  this.trajectoryWidthMax = (width - nyanCatWidth);\r\n\r\n  runner.on('start', function() {\r\n    Base.cursor.hide();\r\n    self.draw();\r\n  });\r\n\r\n  runner.on('pending', function() {\r\n    self.draw();\r\n  });\r\n\r\n  runner.on('pass', function() {\r\n    self.draw();\r\n  });\r\n\r\n  runner.on('fail', function() {\r\n    self.draw();\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    Base.cursor.show();\r\n    for (var i = 0; i < self.numberOfLines; i++) {\r\n      write('\\n');\r\n    }\r\n    self.epilogue();\r\n  });\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(NyanCat, Base);\r\n\r\n/**\r\n * Draw the nyan cat\r\n *\r\n * @api private\r\n */\r\n\r\nNyanCat.prototype.draw = function() {\r\n  this.appendRainbow();\r\n  this.drawScoreboard();\r\n  this.drawRainbow();\r\n  this.drawNyanCat();\r\n  this.tick = !this.tick;\r\n};\r\n\r\n/**\r\n * Draw the \"scoreboard\" showing the number\r\n * of passes, failures and pending tests.\r\n *\r\n * @api private\r\n */\r\n\r\nNyanCat.prototype.drawScoreboard = function() {\r\n  var stats = this.stats;\r\n\r\n  function draw(type, n) {\r\n    write(' ');\r\n    write(Base.color(type, n));\r\n    write('\\n');\r\n  }\r\n\r\n  draw('green', stats.passes);\r\n  draw('fail', stats.failures);\r\n  draw('pending', stats.pending);\r\n  write('\\n');\r\n\r\n  this.cursorUp(this.numberOfLines);\r\n};\r\n\r\n/**\r\n * Append the rainbow.\r\n *\r\n * @api private\r\n */\r\n\r\nNyanCat.prototype.appendRainbow = function() {\r\n  var segment = this.tick ? '_' : '-';\r\n  var rainbowified = this.rainbowify(segment);\r\n\r\n  for (var index = 0; index < this.numberOfLines; index++) {\r\n    var trajectory = this.trajectories[index];\r\n    if (trajectory.length >= this.trajectoryWidthMax) {\r\n      trajectory.shift();\r\n    }\r\n    trajectory.push(rainbowified);\r\n  }\r\n};\r\n\r\n/**\r\n * Draw the rainbow.\r\n *\r\n * @api private\r\n */\r\n\r\nNyanCat.prototype.drawRainbow = function() {\r\n  var self = this;\r\n\r\n  this.trajectories.forEach(function(line) {\r\n    write('\\u001b[' + self.scoreboardWidth + 'C');\r\n    write(line.join(''));\r\n    write('\\n');\r\n  });\r\n\r\n  this.cursorUp(this.numberOfLines);\r\n};\r\n\r\n/**\r\n * Draw the nyan cat\r\n *\r\n * @api private\r\n */\r\nNyanCat.prototype.drawNyanCat = function() {\r\n  var self = this;\r\n  var startWidth = this.scoreboardWidth + this.trajectories[0].length;\r\n  var dist = '\\u001b[' + startWidth + 'C';\r\n  var padding = '';\r\n\r\n  write(dist);\r\n  write('_,------,');\r\n  write('\\n');\r\n\r\n  write(dist);\r\n  padding = self.tick ? '  ' : '   ';\r\n  write('_|' + padding + '/\\\\_/\\\\ ');\r\n  write('\\n');\r\n\r\n  write(dist);\r\n  padding = self.tick ? '_' : '__';\r\n  var tail = self.tick ? '~' : '^';\r\n  write(tail + '|' + padding + this.face() + ' ');\r\n  write('\\n');\r\n\r\n  write(dist);\r\n  padding = self.tick ? ' ' : '  ';\r\n  write(padding + '\"\"  \"\" ');\r\n  write('\\n');\r\n\r\n  this.cursorUp(this.numberOfLines);\r\n};\r\n\r\n/**\r\n * Draw nyan cat face.\r\n *\r\n * @api private\r\n * @return {string}\r\n */\r\n\r\nNyanCat.prototype.face = function() {\r\n  var stats = this.stats;\r\n  if (stats.failures) {\r\n    return '( x .x)';\r\n  } else if (stats.pending) {\r\n    return '( o .o)';\r\n  } else if (stats.passes) {\r\n    return '( ^ .^)';\r\n  }\r\n  return '( - .-)';\r\n};\r\n\r\n/**\r\n * Move cursor up `n`.\r\n *\r\n * @api private\r\n * @param {number} n\r\n */\r\n\r\nNyanCat.prototype.cursorUp = function(n) {\r\n  write('\\u001b[' + n + 'A');\r\n};\r\n\r\n/**\r\n * Move cursor down `n`.\r\n *\r\n * @api private\r\n * @param {number} n\r\n */\r\n\r\nNyanCat.prototype.cursorDown = function(n) {\r\n  write('\\u001b[' + n + 'B');\r\n};\r\n\r\n/**\r\n * Generate rainbow colors.\r\n *\r\n * @api private\r\n * @return {Array}\r\n */\r\nNyanCat.prototype.generateColors = function() {\r\n  var colors = [];\r\n\r\n  for (var i = 0; i < (6 * 7); i++) {\r\n    var pi3 = Math.floor(Math.PI / 3);\r\n    var n = (i * (1.0 / 6));\r\n    var r = Math.floor(3 * Math.sin(n) + 3);\r\n    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\r\n    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\r\n    colors.push(36 * r + 6 * g + b + 16);\r\n  }\r\n\r\n  return colors;\r\n};\r\n\r\n/**\r\n * Apply rainbow to the given `str`.\r\n *\r\n * @api private\r\n * @param {string} str\r\n * @return {string}\r\n */\r\nNyanCat.prototype.rainbowify = function(str) {\r\n  if (!Base.useColors) {\r\n    return str;\r\n  }\r\n  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\r\n  this.colorIndex += 1;\r\n  return '\\u001b[38;5;' + color + 'm' + str + '\\u001b[0m';\r\n};\r\n\r\n/**\r\n * Stdout helper.\r\n *\r\n * @param {string} string A message to write to stdout.\r\n */\r\nfunction write(string) {\r\n  process.stdout.write(string);\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],31:[function(require,module,exports){\r\n(function (process){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar inherits = require('../utils').inherits;\r\nvar color = Base.color;\r\nvar cursor = Base.cursor;\r\n\r\n/**\r\n * Expose `Progress`.\r\n */\r\n\r\nexports = module.exports = Progress;\r\n\r\n/**\r\n * General progress bar color.\r\n */\r\n\r\nBase.colors.progress = 90;\r\n\r\n/**\r\n * Initialize a new `Progress` bar test reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n * @param {Object} options\r\n */\r\nfunction Progress(runner, options) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var width = Base.window.width * .50 | 0;\r\n  var total = runner.total;\r\n  var complete = 0;\r\n  var lastN = -1;\r\n\r\n  // default chars\r\n  options = options || {};\r\n  options.open = options.open || '[';\r\n  options.complete = options.complete || '?';\r\n  options.incomplete = options.incomplete || Base.symbols.dot;\r\n  options.close = options.close || ']';\r\n  options.verbose = false;\r\n\r\n  // tests started\r\n  runner.on('start', function() {\r\n    console.log();\r\n    cursor.hide();\r\n  });\r\n\r\n  // tests complete\r\n  runner.on('test end', function() {\r\n    complete++;\r\n\r\n    var percent = complete / total;\r\n    var n = width * percent | 0;\r\n    var i = width - n;\r\n\r\n    if (n === lastN && !options.verbose) {\r\n      // Don't re-render the line if it hasn't changed\r\n      return;\r\n    }\r\n    lastN = n;\r\n\r\n    cursor.CR();\r\n    process.stdout.write('\\u001b[J');\r\n    process.stdout.write(color('progress', '  ' + options.open));\r\n    process.stdout.write(Array(n).join(options.complete));\r\n    process.stdout.write(Array(i).join(options.incomplete));\r\n    process.stdout.write(color('progress', options.close));\r\n    if (options.verbose) {\r\n      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));\r\n    }\r\n  });\r\n\r\n  // tests are complete, output some stats\r\n  // and the failures if any\r\n  runner.on('end', function() {\r\n    cursor.show();\r\n    console.log();\r\n    self.epilogue();\r\n  });\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(Progress, Base);\r\n\r\n}).call(this,require('_process'))\r\n},{\"../utils\":39,\"./base\":17,\"_process\":51}],32:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar inherits = require('../utils').inherits;\r\nvar color = Base.color;\r\nvar cursor = Base.cursor;\r\n\r\n/**\r\n * Expose `Spec`.\r\n */\r\n\r\nexports = module.exports = Spec;\r\n\r\n/**\r\n * Initialize a new `Spec` test reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction Spec(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var self = this;\r\n  var indents = 0;\r\n  var n = 0;\r\n\r\n  function indent() {\r\n    return Array(indents).join('  ');\r\n  }\r\n\r\n  runner.on('start', function() {\r\n    console.log();\r\n  });\r\n\r\n  runner.on('suite', function(suite) {\r\n    ++indents;\r\n    console.log(color('suite', '%s%s'), indent(), suite.title);\r\n  });\r\n\r\n  runner.on('suite end', function() {\r\n    --indents;\r\n    if (indents === 1) {\r\n      console.log();\r\n    }\r\n  });\r\n\r\n  runner.on('pending', function(test) {\r\n    var fmt = indent() + color('pending', '  - %s');\r\n    console.log(fmt, test.title);\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    var fmt;\r\n    if (test.speed === 'fast') {\r\n      fmt = indent()\r\n        + color('checkmark', '  ' + Base.symbols.ok)\r\n        + color('pass', ' %s');\r\n      cursor.CR();\r\n      console.log(fmt, test.title);\r\n    } else {\r\n      fmt = indent()\r\n        + color('checkmark', '  ' + Base.symbols.ok)\r\n        + color('pass', ' %s')\r\n        + color(test.speed, ' (%dms)');\r\n      cursor.CR();\r\n      console.log(fmt, test.title, test.duration);\r\n    }\r\n  });\r\n\r\n  runner.on('fail', function(test) {\r\n    cursor.CR();\r\n    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);\r\n  });\r\n\r\n  runner.on('end', self.epilogue.bind(self));\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(Spec, Base);\r\n\r\n},{\"../utils\":39,\"./base\":17}],33:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\n\r\n/**\r\n * Expose `TAP`.\r\n */\r\n\r\nexports = module.exports = TAP;\r\n\r\n/**\r\n * Initialize a new `TAP` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction TAP(runner) {\r\n  Base.call(this, runner);\r\n\r\n  var n = 1;\r\n  var passes = 0;\r\n  var failures = 0;\r\n\r\n  runner.on('start', function() {\r\n    var total = runner.grepTotal(runner.suite);\r\n    console.log('%d..%d', 1, total);\r\n  });\r\n\r\n  runner.on('test end', function() {\r\n    ++n;\r\n  });\r\n\r\n  runner.on('pending', function(test) {\r\n    console.log('ok %d %s # SKIP -', n, title(test));\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    passes++;\r\n    console.log('ok %d %s', n, title(test));\r\n  });\r\n\r\n  runner.on('fail', function(test, err) {\r\n    failures++;\r\n    console.log('not ok %d %s', n, title(test));\r\n    if (err.stack) {\r\n      console.log(err.stack.replace(/^/gm, '  '));\r\n    }\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    console.log('# tests ' + (passes + failures));\r\n    console.log('# pass ' + passes);\r\n    console.log('# fail ' + failures);\r\n  });\r\n}\r\n\r\n/**\r\n * Return a TAP-safe title of `test`\r\n *\r\n * @api private\r\n * @param {Object} test\r\n * @return {String}\r\n */\r\nfunction title(test) {\r\n  return test.fullTitle().replace(/#/g, '');\r\n}\r\n\r\n},{\"./base\":17}],34:[function(require,module,exports){\r\n(function (global){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Base = require('./base');\r\nvar utils = require('../utils');\r\nvar inherits = utils.inherits;\r\nvar fs = require('fs');\r\nvar escape = utils.escape;\r\n\r\n/**\r\n * Save timer references to avoid Sinon interfering (see GH-237).\r\n */\r\n\r\n/* eslint-disable no-unused-vars, no-native-reassign */\r\nvar Date = global.Date;\r\nvar setTimeout = global.setTimeout;\r\nvar setInterval = global.setInterval;\r\nvar clearTimeout = global.clearTimeout;\r\nvar clearInterval = global.clearInterval;\r\n/* eslint-enable no-unused-vars, no-native-reassign */\r\n\r\n/**\r\n * Expose `XUnit`.\r\n */\r\n\r\nexports = module.exports = XUnit;\r\n\r\n/**\r\n * Initialize a new `XUnit` reporter.\r\n *\r\n * @api public\r\n * @param {Runner} runner\r\n */\r\nfunction XUnit(runner, options) {\r\n  Base.call(this, runner);\r\n\r\n  var stats = this.stats;\r\n  var tests = [];\r\n  var self = this;\r\n\r\n  if (options.reporterOptions && options.reporterOptions.output) {\r\n    if (!fs.createWriteStream) {\r\n      throw new Error('file output not supported in browser');\r\n    }\r\n    self.fileStream = fs.createWriteStream(options.reporterOptions.output);\r\n  }\r\n\r\n  runner.on('pending', function(test) {\r\n    tests.push(test);\r\n  });\r\n\r\n  runner.on('pass', function(test) {\r\n    tests.push(test);\r\n  });\r\n\r\n  runner.on('fail', function(test) {\r\n    tests.push(test);\r\n  });\r\n\r\n  runner.on('end', function() {\r\n    self.write(tag('testsuite', {\r\n      name: 'Mocha Tests',\r\n      tests: stats.tests,\r\n      failures: stats.failures,\r\n      errors: stats.failures,\r\n      skipped: stats.tests - stats.failures - stats.passes,\r\n      timestamp: (new Date()).toUTCString(),\r\n      time: (stats.duration / 1000) || 0\r\n    }, false));\r\n\r\n    tests.forEach(function(t) {\r\n      self.test(t);\r\n    });\r\n\r\n    self.write('</testsuite>');\r\n  });\r\n}\r\n\r\n/**\r\n * Inherit from `Base.prototype`.\r\n */\r\ninherits(XUnit, Base);\r\n\r\n/**\r\n * Override done to close the stream (if it's a file).\r\n *\r\n * @param failures\r\n * @param {Function} fn\r\n */\r\nXUnit.prototype.done = function(failures, fn) {\r\n  if (this.fileStream) {\r\n    this.fileStream.end(function() {\r\n      fn(failures);\r\n    });\r\n  } else {\r\n    fn(failures);\r\n  }\r\n};\r\n\r\n/**\r\n * Write out the given line.\r\n *\r\n * @param {string} line\r\n */\r\nXUnit.prototype.write = function(line) {\r\n  if (this.fileStream) {\r\n    this.fileStream.write(line + '\\n');\r\n  } else {\r\n    console.log(line);\r\n  }\r\n};\r\n\r\n/**\r\n * Output tag for the given `test.`\r\n *\r\n * @param {Test} test\r\n */\r\nXUnit.prototype.test = function(test) {\r\n  var attrs = {\r\n    classname: test.parent.fullTitle(),\r\n    name: test.title,\r\n    time: (test.duration / 1000) || 0\r\n  };\r\n\r\n  if (test.state === 'failed') {\r\n    var err = test.err;\r\n    this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + '\\n' + err.stack))));\r\n  } else if (test.pending) {\r\n    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));\r\n  } else {\r\n    this.write(tag('testcase', attrs, true));\r\n  }\r\n};\r\n\r\n/**\r\n * HTML tag helper.\r\n *\r\n * @param name\r\n * @param attrs\r\n * @param close\r\n * @param content\r\n * @return {string}\r\n */\r\nfunction tag(name, attrs, close, content) {\r\n  var end = close ? '/>' : '>';\r\n  var pairs = [];\r\n  var tag;\r\n\r\n  for (var key in attrs) {\r\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\r\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\r\n    }\r\n  }\r\n\r\n  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;\r\n  if (content) {\r\n    tag += content + '</' + name + end;\r\n  }\r\n  return tag;\r\n}\r\n\r\n/**\r\n * Return cdata escaped CDATA `str`.\r\n */\r\n\r\nfunction cdata(str) {\r\n  return '<![CDATA[' + escape(str) + ']]>';\r\n}\r\n\r\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"../utils\":39,\"./base\":17,\"fs\":41}],35:[function(require,module,exports){\r\n(function (global){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar EventEmitter = require('events').EventEmitter;\r\nvar Pending = require('./pending');\r\nvar debug = require('debug')('mocha:runnable');\r\nvar milliseconds = require('./ms');\r\nvar utils = require('./utils');\r\nvar inherits = utils.inherits;\r\n\r\n/**\r\n * Save timer references to avoid Sinon interfering (see GH-237).\r\n */\r\n\r\n/* eslint-disable no-unused-vars, no-native-reassign */\r\nvar Date = global.Date;\r\nvar setTimeout = global.setTimeout;\r\nvar setInterval = global.setInterval;\r\nvar clearTimeout = global.clearTimeout;\r\nvar clearInterval = global.clearInterval;\r\n/* eslint-enable no-unused-vars, no-native-reassign */\r\n\r\n/**\r\n * Object#toString().\r\n */\r\n\r\nvar toString = Object.prototype.toString;\r\n\r\n/**\r\n * Expose `Runnable`.\r\n */\r\n\r\nmodule.exports = Runnable;\r\n\r\n/**\r\n * Initialize a new `Runnable` with the given `title` and callback `fn`.\r\n *\r\n * @param {String} title\r\n * @param {Function} fn\r\n * @api private\r\n * @param {string} title\r\n * @param {Function} fn\r\n */\r\nfunction Runnable(title, fn) {\r\n  this.title = title;\r\n  this.fn = fn;\r\n  this.async = fn && fn.length;\r\n  this.sync = !this.async;\r\n  this._timeout = 2000;\r\n  this._slow = 75;\r\n  this._enableTimeouts = true;\r\n  this.timedOut = false;\r\n  this._trace = new Error('done() called multiple times');\r\n}\r\n\r\n/**\r\n * Inherit from `EventEmitter.prototype`.\r\n */\r\ninherits(Runnable, EventEmitter);\r\n\r\n/**\r\n * Set & get timeout `ms`.\r\n *\r\n * @api private\r\n * @param {number|string} ms\r\n * @return {Runnable|number} ms or Runnable instance.\r\n */\r\nRunnable.prototype.timeout = function(ms) {\r\n  if (!arguments.length) {\r\n    return this._timeout;\r\n  }\r\n  if (ms === 0) {\r\n    this._enableTimeouts = false;\r\n  }\r\n  if (typeof ms === 'string') {\r\n    ms = milliseconds(ms);\r\n  }\r\n  debug('timeout %d', ms);\r\n  this._timeout = ms;\r\n  if (this.timer) {\r\n    this.resetTimeout();\r\n  }\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set & get slow `ms`.\r\n *\r\n * @api private\r\n * @param {number|string} ms\r\n * @return {Runnable|number} ms or Runnable instance.\r\n */\r\nRunnable.prototype.slow = function(ms) {\r\n  if (!arguments.length) {\r\n    return this._slow;\r\n  }\r\n  if (typeof ms === 'string') {\r\n    ms = milliseconds(ms);\r\n  }\r\n  debug('timeout %d', ms);\r\n  this._slow = ms;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set and get whether timeout is `enabled`.\r\n *\r\n * @api private\r\n * @param {boolean} enabled\r\n * @return {Runnable|boolean} enabled or Runnable instance.\r\n */\r\nRunnable.prototype.enableTimeouts = function(enabled) {\r\n  if (!arguments.length) {\r\n    return this._enableTimeouts;\r\n  }\r\n  debug('enableTimeouts %s', enabled);\r\n  this._enableTimeouts = enabled;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Halt and mark as pending.\r\n *\r\n * @api private\r\n */\r\nRunnable.prototype.skip = function() {\r\n  throw new Pending();\r\n};\r\n\r\n/**\r\n * Return the full title generated by recursively concatenating the parent's\r\n * full title.\r\n *\r\n * @api public\r\n * @return {string}\r\n */\r\nRunnable.prototype.fullTitle = function() {\r\n  return this.parent.fullTitle() + ' ' + this.title;\r\n};\r\n\r\n/**\r\n * Clear the timeout.\r\n *\r\n * @api private\r\n */\r\nRunnable.prototype.clearTimeout = function() {\r\n  clearTimeout(this.timer);\r\n};\r\n\r\n/**\r\n * Inspect the runnable void of private properties.\r\n *\r\n * @api private\r\n * @return {string}\r\n */\r\nRunnable.prototype.inspect = function() {\r\n  return JSON.stringify(this, function(key, val) {\r\n    if (key[0] === '_') {\r\n      return;\r\n    }\r\n    if (key === 'parent') {\r\n      return '#<Suite>';\r\n    }\r\n    if (key === 'ctx') {\r\n      return '#<Context>';\r\n    }\r\n    return val;\r\n  }, 2);\r\n};\r\n\r\n/**\r\n * Reset the timeout.\r\n *\r\n * @api private\r\n */\r\nRunnable.prototype.resetTimeout = function() {\r\n  var self = this;\r\n  var ms = this.timeout() || 1e9;\r\n\r\n  if (!this._enableTimeouts) {\r\n    return;\r\n  }\r\n  this.clearTimeout();\r\n  this.timer = setTimeout(function() {\r\n    if (!self._enableTimeouts) {\r\n      return;\r\n    }\r\n    self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'));\r\n    self.timedOut = true;\r\n  }, ms);\r\n};\r\n\r\n/**\r\n * Whitelist a list of globals for this test run.\r\n *\r\n * @api private\r\n * @param {string[]} globals\r\n */\r\nRunnable.prototype.globals = function(globals) {\r\n  this._allowedGlobals = globals;\r\n};\r\n\r\n/**\r\n * Run the test and invoke `fn(err)`.\r\n *\r\n * @param {Function} fn\r\n * @api private\r\n */\r\nRunnable.prototype.run = function(fn) {\r\n  var self = this;\r\n  var start = new Date();\r\n  var ctx = this.ctx;\r\n  var finished;\r\n  var emitted;\r\n\r\n  // Sometimes the ctx exists, but it is not runnable\r\n  if (ctx && ctx.runnable) {\r\n    ctx.runnable(this);\r\n  }\r\n\r\n  // called multiple times\r\n  function multiple(err) {\r\n    if (emitted) {\r\n      return;\r\n    }\r\n    emitted = true;\r\n    self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));\r\n  }\r\n\r\n  // finished\r\n  function done(err) {\r\n    var ms = self.timeout();\r\n    if (self.timedOut) {\r\n      return;\r\n    }\r\n    if (finished) {\r\n      return multiple(err || self._trace);\r\n    }\r\n\r\n    self.clearTimeout();\r\n    self.duration = new Date() - start;\r\n    finished = true;\r\n    if (!err && self.duration > ms && self._enableTimeouts) {\r\n      err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.');\r\n    }\r\n    fn(err);\r\n  }\r\n\r\n  // for .resetTimeout()\r\n  this.callback = done;\r\n\r\n  // explicit async with `done` argument\r\n  if (this.async) {\r\n    this.resetTimeout();\r\n\r\n    if (this.allowUncaught) {\r\n      return callFnAsync(this.fn);\r\n    }\r\n    try {\r\n      callFnAsync(this.fn);\r\n    } catch (err) {\r\n      done(utils.getError(err));\r\n    }\r\n    return;\r\n  }\r\n\r\n  if (this.allowUncaught) {\r\n    callFn(this.fn);\r\n    done();\r\n    return;\r\n  }\r\n\r\n  // sync or promise-returning\r\n  try {\r\n    if (this.pending) {\r\n      done();\r\n    } else {\r\n      callFn(this.fn);\r\n    }\r\n  } catch (err) {\r\n    done(utils.getError(err));\r\n  }\r\n\r\n  function callFn(fn) {\r\n    var result = fn.call(ctx);\r\n    if (result && typeof result.then === 'function') {\r\n      self.resetTimeout();\r\n      result\r\n        .then(function() {\r\n          done();\r\n        },\r\n        function(reason) {\r\n          done(reason || new Error('Promise rejected with no or falsy reason'));\r\n        });\r\n    } else {\r\n      if (self.asyncOnly) {\r\n        return done(new Error('--async-only option in use without declaring `done()` or returning a promise'));\r\n      }\r\n\r\n      done();\r\n    }\r\n  }\r\n\r\n  function callFnAsync(fn) {\r\n    fn.call(ctx, function(err) {\r\n      if (err instanceof Error || toString.call(err) === '[object Error]') {\r\n        return done(err);\r\n      }\r\n      if (err) {\r\n        if (Object.prototype.toString.call(err) === '[object Object]') {\r\n          return done(new Error('done() invoked with non-Error: '\r\n            + JSON.stringify(err)));\r\n        }\r\n        return done(new Error('done() invoked with non-Error: ' + err));\r\n      }\r\n      done();\r\n    });\r\n  }\r\n};\r\n\r\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"./ms\":15,\"./pending\":16,\"./utils\":39,\"debug\":2,\"events\":3}],36:[function(require,module,exports){\r\n(function (process,global){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar EventEmitter = require('events').EventEmitter;\r\nvar Pending = require('./pending');\r\nvar utils = require('./utils');\r\nvar inherits = utils.inherits;\r\nvar debug = require('debug')('mocha:runner');\r\nvar Runnable = require('./runnable');\r\nvar filter = utils.filter;\r\nvar indexOf = utils.indexOf;\r\nvar keys = utils.keys;\r\nvar stackFilter = utils.stackTraceFilter();\r\nvar stringify = utils.stringify;\r\nvar type = utils.type;\r\nvar undefinedError = utils.undefinedError;\r\n\r\n/**\r\n * Non-enumerable globals.\r\n */\r\n\r\nvar globals = [\r\n  'setTimeout',\r\n  'clearTimeout',\r\n  'setInterval',\r\n  'clearInterval',\r\n  'XMLHttpRequest',\r\n  'Date',\r\n  'setImmediate',\r\n  'clearImmediate'\r\n];\r\n\r\n/**\r\n * Expose `Runner`.\r\n */\r\n\r\nmodule.exports = Runner;\r\n\r\n/**\r\n * Initialize a `Runner` for the given `suite`.\r\n *\r\n * Events:\r\n *\r\n *   - `start`  execution started\r\n *   - `end`  execution complete\r\n *   - `suite`  (suite) test suite execution started\r\n *   - `suite end`  (suite) all tests (and sub-suites) have finished\r\n *   - `test`  (test) test execution started\r\n *   - `test end`  (test) test completed\r\n *   - `hook`  (hook) hook execution started\r\n *   - `hook end`  (hook) hook complete\r\n *   - `pass`  (test) test passed\r\n *   - `fail`  (test, err) test failed\r\n *   - `pending`  (test) test pending\r\n *\r\n * @api public\r\n * @param {Suite} suite Root suite\r\n * @param {boolean} [delay] Whether or not to delay execution of root suite\r\n * until ready.\r\n */\r\nfunction Runner(suite, delay) {\r\n  var self = this;\r\n  this._globals = [];\r\n  this._abort = false;\r\n  this._delay = delay;\r\n  this.suite = suite;\r\n  this.started = false;\r\n  this.total = suite.total();\r\n  this.failures = 0;\r\n  this.on('test end', function(test) {\r\n    self.checkGlobals(test);\r\n  });\r\n  this.on('hook end', function(hook) {\r\n    self.checkGlobals(hook);\r\n  });\r\n  this._defaultGrep = /.*/;\r\n  this.grep(this._defaultGrep);\r\n  this.globals(this.globalProps().concat(extraGlobals()));\r\n}\r\n\r\n/**\r\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\r\n *\r\n * @param {Function} fn\r\n * @api private\r\n */\r\nRunner.immediately = global.setImmediate || process.nextTick;\r\n\r\n/**\r\n * Inherit from `EventEmitter.prototype`.\r\n */\r\ninherits(Runner, EventEmitter);\r\n\r\n/**\r\n * Run tests with full titles matching `re`. Updates runner.total\r\n * with number of tests matched.\r\n *\r\n * @param {RegExp} re\r\n * @param {Boolean} invert\r\n * @return {Runner} for chaining\r\n * @api public\r\n * @param {RegExp} re\r\n * @param {boolean} invert\r\n * @return {Runner} Runner instance.\r\n */\r\nRunner.prototype.grep = function(re, invert) {\r\n  debug('grep %s', re);\r\n  this._grep = re;\r\n  this._invert = invert;\r\n  this.total = this.grepTotal(this.suite);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Returns the number of tests matching the grep search for the\r\n * given suite.\r\n *\r\n * @param {Suite} suite\r\n * @return {Number}\r\n * @api public\r\n * @param {Suite} suite\r\n * @return {number}\r\n */\r\nRunner.prototype.grepTotal = function(suite) {\r\n  var self = this;\r\n  var total = 0;\r\n\r\n  suite.eachTest(function(test) {\r\n    var match = self._grep.test(test.fullTitle());\r\n    if (self._invert) {\r\n      match = !match;\r\n    }\r\n    if (match) {\r\n      total++;\r\n    }\r\n  });\r\n\r\n  return total;\r\n};\r\n\r\n/**\r\n * Return a list of global properties.\r\n *\r\n * @return {Array}\r\n * @api private\r\n */\r\nRunner.prototype.globalProps = function() {\r\n  var props = keys(global);\r\n\r\n  // non-enumerables\r\n  for (var i = 0; i < globals.length; ++i) {\r\n    if (~indexOf(props, globals[i])) {\r\n      continue;\r\n    }\r\n    props.push(globals[i]);\r\n  }\r\n\r\n  return props;\r\n};\r\n\r\n/**\r\n * Allow the given `arr` of globals.\r\n *\r\n * @param {Array} arr\r\n * @return {Runner} for chaining\r\n * @api public\r\n * @param {Array} arr\r\n * @return {Runner} Runner instance.\r\n */\r\nRunner.prototype.globals = function(arr) {\r\n  if (!arguments.length) {\r\n    return this._globals;\r\n  }\r\n  debug('globals %j', arr);\r\n  this._globals = this._globals.concat(arr);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Check for global variable leaks.\r\n *\r\n * @api private\r\n */\r\nRunner.prototype.checkGlobals = function(test) {\r\n  if (this.ignoreLeaks) {\r\n    return;\r\n  }\r\n  var ok = this._globals;\r\n\r\n  var globals = this.globalProps();\r\n  var leaks;\r\n\r\n  if (test) {\r\n    ok = ok.concat(test._allowedGlobals || []);\r\n  }\r\n\r\n  if (this.prevGlobalsLength === globals.length) {\r\n    return;\r\n  }\r\n  this.prevGlobalsLength = globals.length;\r\n\r\n  leaks = filterLeaks(ok, globals);\r\n  this._globals = this._globals.concat(leaks);\r\n\r\n  if (leaks.length > 1) {\r\n    this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));\r\n  } else if (leaks.length) {\r\n    this.fail(test, new Error('global leak detected: ' + leaks[0]));\r\n  }\r\n};\r\n\r\n/**\r\n * Fail the given `test`.\r\n *\r\n * @api private\r\n * @param {Test} test\r\n * @param {Error} err\r\n */\r\nRunner.prototype.fail = function(test, err) {\r\n  ++this.failures;\r\n  test.state = 'failed';\r\n\r\n  if (!(err instanceof Error || err && typeof err.message === 'string')) {\r\n    err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)');\r\n  }\r\n\r\n  err.stack = (this.fullStackTrace || !err.stack)\r\n    ? err.stack\r\n    : stackFilter(err.stack);\r\n\r\n  this.emit('fail', test, err);\r\n};\r\n\r\n/**\r\n * Fail the given `hook` with `err`.\r\n *\r\n * Hook failures work in the following pattern:\r\n * - If bail, then exit\r\n * - Failed `before` hook skips all tests in a suite and subsuites,\r\n *   but jumps to corresponding `after` hook\r\n * - Failed `before each` hook skips remaining tests in a\r\n *   suite and jumps to corresponding `after each` hook,\r\n *   which is run only once\r\n * - Failed `after` hook does not alter\r\n *   execution order\r\n * - Failed `after each` hook skips remaining tests in a\r\n *   suite and subsuites, but executes other `after each`\r\n *   hooks\r\n *\r\n * @api private\r\n * @param {Hook} hook\r\n * @param {Error} err\r\n */\r\nRunner.prototype.failHook = function(hook, err) {\r\n  if (hook.ctx && hook.ctx.currentTest) {\r\n    hook.originalTitle = hook.originalTitle || hook.title;\r\n    hook.title = hook.originalTitle + ' for \"' + hook.ctx.currentTest.title + '\"';\r\n  }\r\n\r\n  this.fail(hook, err);\r\n  if (this.suite.bail()) {\r\n    this.emit('end');\r\n  }\r\n};\r\n\r\n/**\r\n * Run hook `name` callbacks and then invoke `fn()`.\r\n *\r\n * @api private\r\n * @param {string} name\r\n * @param {Function} fn\r\n */\r\n\r\nRunner.prototype.hook = function(name, fn) {\r\n  var suite = this.suite;\r\n  var hooks = suite['_' + name];\r\n  var self = this;\r\n\r\n  function next(i) {\r\n    var hook = hooks[i];\r\n    if (!hook) {\r\n      return fn();\r\n    }\r\n    self.currentRunnable = hook;\r\n\r\n    hook.ctx.currentTest = self.test;\r\n\r\n    self.emit('hook', hook);\r\n\r\n    if (!hook.listeners('error').length) {\r\n      hook.on('error', function(err) {\r\n        self.failHook(hook, err);\r\n      });\r\n    }\r\n\r\n    hook.run(function(err) {\r\n      var testError = hook.error();\r\n      if (testError) {\r\n        self.fail(self.test, testError);\r\n      }\r\n      if (err) {\r\n        if (err instanceof Pending) {\r\n          suite.pending = true;\r\n        } else {\r\n          self.failHook(hook, err);\r\n\r\n          // stop executing hooks, notify callee of hook err\r\n          return fn(err);\r\n        }\r\n      }\r\n      self.emit('hook end', hook);\r\n      delete hook.ctx.currentTest;\r\n      next(++i);\r\n    });\r\n  }\r\n\r\n  Runner.immediately(function() {\r\n    next(0);\r\n  });\r\n};\r\n\r\n/**\r\n * Run hook `name` for the given array of `suites`\r\n * in order, and callback `fn(err, errSuite)`.\r\n *\r\n * @api private\r\n * @param {string} name\r\n * @param {Array} suites\r\n * @param {Function} fn\r\n */\r\nRunner.prototype.hooks = function(name, suites, fn) {\r\n  var self = this;\r\n  var orig = this.suite;\r\n\r\n  function next(suite) {\r\n    self.suite = suite;\r\n\r\n    if (!suite) {\r\n      self.suite = orig;\r\n      return fn();\r\n    }\r\n\r\n    self.hook(name, function(err) {\r\n      if (err) {\r\n        var errSuite = self.suite;\r\n        self.suite = orig;\r\n        return fn(err, errSuite);\r\n      }\r\n\r\n      next(suites.pop());\r\n    });\r\n  }\r\n\r\n  next(suites.pop());\r\n};\r\n\r\n/**\r\n * Run hooks from the top level down.\r\n *\r\n * @param {String} name\r\n * @param {Function} fn\r\n * @api private\r\n */\r\nRunner.prototype.hookUp = function(name, fn) {\r\n  var suites = [this.suite].concat(this.parents()).reverse();\r\n  this.hooks(name, suites, fn);\r\n};\r\n\r\n/**\r\n * Run hooks from the bottom up.\r\n *\r\n * @param {String} name\r\n * @param {Function} fn\r\n * @api private\r\n */\r\nRunner.prototype.hookDown = function(name, fn) {\r\n  var suites = [this.suite].concat(this.parents());\r\n  this.hooks(name, suites, fn);\r\n};\r\n\r\n/**\r\n * Return an array of parent Suites from\r\n * closest to furthest.\r\n *\r\n * @return {Array}\r\n * @api private\r\n */\r\nRunner.prototype.parents = function() {\r\n  var suite = this.suite;\r\n  var suites = [];\r\n  while (suite.parent) {\r\n    suite = suite.parent;\r\n    suites.push(suite);\r\n  }\r\n  return suites;\r\n};\r\n\r\n/**\r\n * Run the current test and callback `fn(err)`.\r\n *\r\n * @param {Function} fn\r\n * @api private\r\n */\r\nRunner.prototype.runTest = function(fn) {\r\n  var self = this;\r\n  var test = this.test;\r\n\r\n  if (this.asyncOnly) {\r\n    test.asyncOnly = true;\r\n  }\r\n\r\n  if (this.allowUncaught) {\r\n    test.allowUncaught = true;\r\n    return test.run(fn);\r\n  }\r\n  try {\r\n    test.on('error', function(err) {\r\n      self.fail(test, err);\r\n    });\r\n    test.run(fn);\r\n  } catch (err) {\r\n    fn(err);\r\n  }\r\n};\r\n\r\n/**\r\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\r\n *\r\n * @api private\r\n * @param {Suite} suite\r\n * @param {Function} fn\r\n */\r\nRunner.prototype.runTests = function(suite, fn) {\r\n  var self = this;\r\n  var tests = suite.tests.slice();\r\n  var test;\r\n\r\n  function hookErr(_, errSuite, after) {\r\n    // before/after Each hook for errSuite failed:\r\n    var orig = self.suite;\r\n\r\n    // for failed 'after each' hook start from errSuite parent,\r\n    // otherwise start from errSuite itself\r\n    self.suite = after ? errSuite.parent : errSuite;\r\n\r\n    if (self.suite) {\r\n      // call hookUp afterEach\r\n      self.hookUp('afterEach', function(err2, errSuite2) {\r\n        self.suite = orig;\r\n        // some hooks may fail even now\r\n        if (err2) {\r\n          return hookErr(err2, errSuite2, true);\r\n        }\r\n        // report error suite\r\n        fn(errSuite);\r\n      });\r\n    } else {\r\n      // there is no need calling other 'after each' hooks\r\n      self.suite = orig;\r\n      fn(errSuite);\r\n    }\r\n  }\r\n\r\n  function next(err, errSuite) {\r\n    // if we bail after first err\r\n    if (self.failures && suite._bail) {\r\n      return fn();\r\n    }\r\n\r\n    if (self._abort) {\r\n      return fn();\r\n    }\r\n\r\n    if (err) {\r\n      return hookErr(err, errSuite, true);\r\n    }\r\n\r\n    // next test\r\n    test = tests.shift();\r\n\r\n    // all done\r\n    if (!test) {\r\n      return fn();\r\n    }\r\n\r\n    // grep\r\n    var match = self._grep.test(test.fullTitle());\r\n    if (self._invert) {\r\n      match = !match;\r\n    }\r\n    if (!match) {\r\n      // Run immediately only if we have defined a grep. When we\r\n      // define a grep � It can cause maximum callstack error if\r\n      // the grep is doing a large recursive loop by neglecting\r\n      // all tests. The run immediately function also comes with\r\n      // a performance cost. So we don't want to run immediately\r\n      // if we run the whole test suite, because running the whole\r\n      // test suite don't do any immediate recursive loops. Thus,\r\n      // allowing a JS runtime to breathe.\r\n      if (self._grep !== self._defaultGrep) {\r\n        Runner.immediately(next);\r\n      } else {\r\n        next();\r\n      }\r\n      return;\r\n    }\r\n\r\n    // pending\r\n    if (test.pending) {\r\n      self.emit('pending', test);\r\n      self.emit('test end', test);\r\n      return next();\r\n    }\r\n\r\n    // execute test and hook(s)\r\n    self.emit('test', self.test = test);\r\n    self.hookDown('beforeEach', function(err, errSuite) {\r\n      if (suite.pending) {\r\n        self.emit('pending', test);\r\n        self.emit('test end', test);\r\n        return next();\r\n      }\r\n      if (err) {\r\n        return hookErr(err, errSuite, false);\r\n      }\r\n      self.currentRunnable = self.test;\r\n      self.runTest(function(err) {\r\n        test = self.test;\r\n\r\n        if (err) {\r\n          if (err instanceof Pending) {\r\n            self.emit('pending', test);\r\n          } else {\r\n            self.fail(test, err);\r\n          }\r\n          self.emit('test end', test);\r\n\r\n          if (err instanceof Pending) {\r\n            return next();\r\n          }\r\n\r\n          return self.hookUp('afterEach', next);\r\n        }\r\n\r\n        test.state = 'passed';\r\n        self.emit('pass', test);\r\n        self.emit('test end', test);\r\n        self.hookUp('afterEach', next);\r\n      });\r\n    });\r\n  }\r\n\r\n  this.next = next;\r\n  this.hookErr = hookErr;\r\n  next();\r\n};\r\n\r\n/**\r\n * Run the given `suite` and invoke the callback `fn()` when complete.\r\n *\r\n * @api private\r\n * @param {Suite} suite\r\n * @param {Function} fn\r\n */\r\nRunner.prototype.runSuite = function(suite, fn) {\r\n  var i = 0;\r\n  var self = this;\r\n  var total = this.grepTotal(suite);\r\n  var afterAllHookCalled = false;\r\n\r\n  debug('run suite %s', suite.fullTitle());\r\n\r\n  if (!total || (self.failures && suite._bail)) {\r\n    return fn();\r\n  }\r\n\r\n  this.emit('suite', this.suite = suite);\r\n\r\n  function next(errSuite) {\r\n    if (errSuite) {\r\n      // current suite failed on a hook from errSuite\r\n      if (errSuite === suite) {\r\n        // if errSuite is current suite\r\n        // continue to the next sibling suite\r\n        return done();\r\n      }\r\n      // errSuite is among the parents of current suite\r\n      // stop execution of errSuite and all sub-suites\r\n      return done(errSuite);\r\n    }\r\n\r\n    if (self._abort) {\r\n      return done();\r\n    }\r\n\r\n    var curr = suite.suites[i++];\r\n    if (!curr) {\r\n      return done();\r\n    }\r\n\r\n    // Avoid grep neglecting large number of tests causing a\r\n    // huge recursive loop and thus a maximum call stack error.\r\n    // See comment in `this.runTests()` for more information.\r\n    if (self._grep !== self._defaultGrep) {\r\n      Runner.immediately(function() {\r\n        self.runSuite(curr, next);\r\n      });\r\n    } else {\r\n      self.runSuite(curr, next);\r\n    }\r\n  }\r\n\r\n  function done(errSuite) {\r\n    self.suite = suite;\r\n    self.nextSuite = next;\r\n\r\n    if (afterAllHookCalled) {\r\n      fn(errSuite);\r\n    } else {\r\n      // mark that the afterAll block has been called once\r\n      // and so can be skipped if there is an error in it.\r\n      afterAllHookCalled = true;\r\n      self.hook('afterAll', function() {\r\n        self.emit('suite end', suite);\r\n        fn(errSuite);\r\n      });\r\n    }\r\n  }\r\n\r\n  this.nextSuite = next;\r\n\r\n  this.hook('beforeAll', function(err) {\r\n    if (err) {\r\n      return done();\r\n    }\r\n    self.runTests(suite, next);\r\n  });\r\n};\r\n\r\n/**\r\n * Handle uncaught exceptions.\r\n *\r\n * @param {Error} err\r\n * @api private\r\n */\r\nRunner.prototype.uncaught = function(err) {\r\n  if (err) {\r\n    debug('uncaught exception %s', err !== function() {\r\n      return this;\r\n    }.call(err) ? err : (err.message || err));\r\n  } else {\r\n    debug('uncaught undefined exception');\r\n    err = undefinedError();\r\n  }\r\n  err.uncaught = true;\r\n\r\n  var runnable = this.currentRunnable;\r\n\r\n  if (!runnable) {\r\n    runnable = new Runnable('Uncaught error outside test suite');\r\n    runnable.parent = this.suite;\r\n\r\n    if (this.started) {\r\n      this.fail(runnable, err);\r\n    } else {\r\n      // Can't recover from this failure\r\n      this.emit('start');\r\n      this.fail(runnable, err);\r\n      this.emit('end');\r\n    }\r\n\r\n    return;\r\n  }\r\n\r\n  runnable.clearTimeout();\r\n\r\n  // Ignore errors if complete\r\n  if (runnable.state) {\r\n    return;\r\n  }\r\n  this.fail(runnable, err);\r\n\r\n  // recover from test\r\n  if (runnable.type === 'test') {\r\n    this.emit('test end', runnable);\r\n    this.hookUp('afterEach', this.next);\r\n    return;\r\n  }\r\n\r\n // recover from hooks\r\n  if (runnable.type === 'hook') {\r\n    var errSuite = this.suite;\r\n    // if hook failure is in afterEach block\r\n    if (runnable.fullTitle().indexOf('after each') > -1) {\r\n      return this.hookErr(err, errSuite, true);\r\n    }\r\n    // if hook failure is in beforeEach block\r\n    if (runnable.fullTitle().indexOf('before each') > -1) {\r\n      return this.hookErr(err, errSuite, false);\r\n    }\r\n    // if hook failure is in after or before blocks\r\n    return this.nextSuite(errSuite);\r\n  }\r\n\r\n  // bail\r\n  this.emit('end');\r\n};\r\n\r\n/**\r\n * Run the root suite and invoke `fn(failures)`\r\n * on completion.\r\n *\r\n * @param {Function} fn\r\n * @return {Runner} for chaining\r\n * @api public\r\n * @param {Function} fn\r\n * @return {Runner} Runner instance.\r\n */\r\nRunner.prototype.run = function(fn) {\r\n  var self = this;\r\n  var rootSuite = this.suite;\r\n\r\n  fn = fn || function() {};\r\n\r\n  function uncaught(err) {\r\n    self.uncaught(err);\r\n  }\r\n\r\n  function start() {\r\n    self.started = true;\r\n    self.emit('start');\r\n    self.runSuite(rootSuite, function() {\r\n      debug('finished running');\r\n      self.emit('end');\r\n    });\r\n  }\r\n\r\n  debug('start');\r\n\r\n  // callback\r\n  this.on('end', function() {\r\n    debug('end');\r\n    process.removeListener('uncaughtException', uncaught);\r\n    fn(self.failures);\r\n  });\r\n\r\n  // uncaught exception\r\n  process.on('uncaughtException', uncaught);\r\n\r\n  if (this._delay) {\r\n    // for reporters, I guess.\r\n    // might be nice to debounce some dots while we wait.\r\n    this.emit('waiting', rootSuite);\r\n    rootSuite.once('run', start);\r\n  } else {\r\n    start();\r\n  }\r\n\r\n  return this;\r\n};\r\n\r\n/**\r\n * Cleanly abort execution.\r\n *\r\n * @api public\r\n * @return {Runner} Runner instance.\r\n */\r\nRunner.prototype.abort = function() {\r\n  debug('aborting');\r\n  this._abort = true;\r\n\r\n  return this;\r\n};\r\n\r\n/**\r\n * Filter leaks with the given globals flagged as `ok`.\r\n *\r\n * @api private\r\n * @param {Array} ok\r\n * @param {Array} globals\r\n * @return {Array}\r\n */\r\nfunction filterLeaks(ok, globals) {\r\n  return filter(globals, function(key) {\r\n    // Firefox and Chrome exposes iframes as index inside the window object\r\n    if (/^d+/.test(key)) {\r\n      return false;\r\n    }\r\n\r\n    // in firefox\r\n    // if runner runs in an iframe, this iframe's window.getInterface method not init at first\r\n    // it is assigned in some seconds\r\n    if (global.navigator && (/^getInterface/).test(key)) {\r\n      return false;\r\n    }\r\n\r\n    // an iframe could be approached by window[iframeIndex]\r\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\r\n    if (global.navigator && (/^\\d+/).test(key)) {\r\n      return false;\r\n    }\r\n\r\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\r\n    if (/^mocha-/.test(key)) {\r\n      return false;\r\n    }\r\n\r\n    var matched = filter(ok, function(ok) {\r\n      if (~ok.indexOf('*')) {\r\n        return key.indexOf(ok.split('*')[0]) === 0;\r\n      }\r\n      return key === ok;\r\n    });\r\n    return !matched.length && (!global.navigator || key !== 'onerror');\r\n  });\r\n}\r\n\r\n/**\r\n * Array of globals dependent on the environment.\r\n *\r\n * @return {Array}\r\n * @api private\r\n */\r\nfunction extraGlobals() {\r\n  if (typeof process === 'object' && typeof process.version === 'string') {\r\n    var parts = process.version.split('.');\r\n    var nodeVersion = utils.reduce(parts, function(a, v) {\r\n      return a << 8 | v;\r\n    });\r\n\r\n    // 'errno' was renamed to process._errno in v0.9.11.\r\n\r\n    if (nodeVersion < 0x00090B) {\r\n      return ['errno'];\r\n    }\r\n  }\r\n\r\n  return [];\r\n}\r\n\r\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"./pending\":16,\"./runnable\":35,\"./utils\":39,\"_process\":51,\"debug\":2,\"events\":3}],37:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar EventEmitter = require('events').EventEmitter;\r\nvar Hook = require('./hook');\r\nvar utils = require('./utils');\r\nvar inherits = utils.inherits;\r\nvar debug = require('debug')('mocha:suite');\r\nvar milliseconds = require('./ms');\r\n\r\n/**\r\n * Expose `Suite`.\r\n */\r\n\r\nexports = module.exports = Suite;\r\n\r\n/**\r\n * Create a new `Suite` with the given `title` and parent `Suite`. When a suite\r\n * with the same title is already present, that suite is returned to provide\r\n * nicer reporter and more flexible meta-testing.\r\n *\r\n * @api public\r\n * @param {Suite} parent\r\n * @param {string} title\r\n * @return {Suite}\r\n */\r\nexports.create = function(parent, title) {\r\n  var suite = new Suite(title, parent.ctx);\r\n  suite.parent = parent;\r\n  if (parent.pending) {\r\n    suite.pending = true;\r\n  }\r\n  title = suite.fullTitle();\r\n  parent.addSuite(suite);\r\n  return suite;\r\n};\r\n\r\n/**\r\n * Initialize a new `Suite` with the given `title` and `ctx`.\r\n *\r\n * @api private\r\n * @param {string} title\r\n * @param {Context} parentContext\r\n */\r\nfunction Suite(title, parentContext) {\r\n  this.title = title;\r\n  function Context() {}\r\n  Context.prototype = parentContext;\r\n  this.ctx = new Context();\r\n  this.suites = [];\r\n  this.tests = [];\r\n  this.pending = false;\r\n  this._beforeEach = [];\r\n  this._beforeAll = [];\r\n  this._afterEach = [];\r\n  this._afterAll = [];\r\n  this.root = !title;\r\n  this._timeout = 2000;\r\n  this._enableTimeouts = true;\r\n  this._slow = 75;\r\n  this._bail = false;\r\n  this.delayed = false;\r\n}\r\n\r\n/**\r\n * Inherit from `EventEmitter.prototype`.\r\n */\r\ninherits(Suite, EventEmitter);\r\n\r\n/**\r\n * Return a clone of this `Suite`.\r\n *\r\n * @api private\r\n * @return {Suite}\r\n */\r\nSuite.prototype.clone = function() {\r\n  var suite = new Suite(this.title);\r\n  debug('clone');\r\n  suite.ctx = this.ctx;\r\n  suite.timeout(this.timeout());\r\n  suite.enableTimeouts(this.enableTimeouts());\r\n  suite.slow(this.slow());\r\n  suite.bail(this.bail());\r\n  return suite;\r\n};\r\n\r\n/**\r\n * Set timeout `ms` or short-hand such as \"2s\".\r\n *\r\n * @api private\r\n * @param {number|string} ms\r\n * @return {Suite|number} for chaining\r\n */\r\nSuite.prototype.timeout = function(ms) {\r\n  if (!arguments.length) {\r\n    return this._timeout;\r\n  }\r\n  if (ms.toString() === '0') {\r\n    this._enableTimeouts = false;\r\n  }\r\n  if (typeof ms === 'string') {\r\n    ms = milliseconds(ms);\r\n  }\r\n  debug('timeout %d', ms);\r\n  this._timeout = parseInt(ms, 10);\r\n  return this;\r\n};\r\n\r\n/**\r\n  * Set timeout to `enabled`.\r\n  *\r\n  * @api private\r\n  * @param {boolean} enabled\r\n  * @return {Suite|boolean} self or enabled\r\n  */\r\nSuite.prototype.enableTimeouts = function(enabled) {\r\n  if (!arguments.length) {\r\n    return this._enableTimeouts;\r\n  }\r\n  debug('enableTimeouts %s', enabled);\r\n  this._enableTimeouts = enabled;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Set slow `ms` or short-hand such as \"2s\".\r\n *\r\n * @api private\r\n * @param {number|string} ms\r\n * @return {Suite|number} for chaining\r\n */\r\nSuite.prototype.slow = function(ms) {\r\n  if (!arguments.length) {\r\n    return this._slow;\r\n  }\r\n  if (typeof ms === 'string') {\r\n    ms = milliseconds(ms);\r\n  }\r\n  debug('slow %d', ms);\r\n  this._slow = ms;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Sets whether to bail after first error.\r\n *\r\n * @api private\r\n * @param {boolean} bail\r\n * @return {Suite|number} for chaining\r\n */\r\nSuite.prototype.bail = function(bail) {\r\n  if (!arguments.length) {\r\n    return this._bail;\r\n  }\r\n  debug('bail %s', bail);\r\n  this._bail = bail;\r\n  return this;\r\n};\r\n\r\n/**\r\n * Run `fn(test[, done])` before running tests.\r\n *\r\n * @api private\r\n * @param {string} title\r\n * @param {Function} fn\r\n * @return {Suite} for chaining\r\n */\r\nSuite.prototype.beforeAll = function(title, fn) {\r\n  if (this.pending) {\r\n    return this;\r\n  }\r\n  if (typeof title === 'function') {\r\n    fn = title;\r\n    title = fn.name;\r\n  }\r\n  title = '\"before all\" hook' + (title ? ': ' + title : '');\r\n\r\n  var hook = new Hook(title, fn);\r\n  hook.parent = this;\r\n  hook.timeout(this.timeout());\r\n  hook.enableTimeouts(this.enableTimeouts());\r\n  hook.slow(this.slow());\r\n  hook.ctx = this.ctx;\r\n  this._beforeAll.push(hook);\r\n  this.emit('beforeAll', hook);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Run `fn(test[, done])` after running tests.\r\n *\r\n * @api private\r\n * @param {string} title\r\n * @param {Function} fn\r\n * @return {Suite} for chaining\r\n */\r\nSuite.prototype.afterAll = function(title, fn) {\r\n  if (this.pending) {\r\n    return this;\r\n  }\r\n  if (typeof title === 'function') {\r\n    fn = title;\r\n    title = fn.name;\r\n  }\r\n  title = '\"after all\" hook' + (title ? ': ' + title : '');\r\n\r\n  var hook = new Hook(title, fn);\r\n  hook.parent = this;\r\n  hook.timeout(this.timeout());\r\n  hook.enableTimeouts(this.enableTimeouts());\r\n  hook.slow(this.slow());\r\n  hook.ctx = this.ctx;\r\n  this._afterAll.push(hook);\r\n  this.emit('afterAll', hook);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Run `fn(test[, done])` before each test case.\r\n *\r\n * @api private\r\n * @param {string} title\r\n * @param {Function} fn\r\n * @return {Suite} for chaining\r\n */\r\nSuite.prototype.beforeEach = function(title, fn) {\r\n  if (this.pending) {\r\n    return this;\r\n  }\r\n  if (typeof title === 'function') {\r\n    fn = title;\r\n    title = fn.name;\r\n  }\r\n  title = '\"before each\" hook' + (title ? ': ' + title : '');\r\n\r\n  var hook = new Hook(title, fn);\r\n  hook.parent = this;\r\n  hook.timeout(this.timeout());\r\n  hook.enableTimeouts(this.enableTimeouts());\r\n  hook.slow(this.slow());\r\n  hook.ctx = this.ctx;\r\n  this._beforeEach.push(hook);\r\n  this.emit('beforeEach', hook);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Run `fn(test[, done])` after each test case.\r\n *\r\n * @api private\r\n * @param {string} title\r\n * @param {Function} fn\r\n * @return {Suite} for chaining\r\n */\r\nSuite.prototype.afterEach = function(title, fn) {\r\n  if (this.pending) {\r\n    return this;\r\n  }\r\n  if (typeof title === 'function') {\r\n    fn = title;\r\n    title = fn.name;\r\n  }\r\n  title = '\"after each\" hook' + (title ? ': ' + title : '');\r\n\r\n  var hook = new Hook(title, fn);\r\n  hook.parent = this;\r\n  hook.timeout(this.timeout());\r\n  hook.enableTimeouts(this.enableTimeouts());\r\n  hook.slow(this.slow());\r\n  hook.ctx = this.ctx;\r\n  this._afterEach.push(hook);\r\n  this.emit('afterEach', hook);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Add a test `suite`.\r\n *\r\n * @api private\r\n * @param {Suite} suite\r\n * @return {Suite} for chaining\r\n */\r\nSuite.prototype.addSuite = function(suite) {\r\n  suite.parent = this;\r\n  suite.timeout(this.timeout());\r\n  suite.enableTimeouts(this.enableTimeouts());\r\n  suite.slow(this.slow());\r\n  suite.bail(this.bail());\r\n  this.suites.push(suite);\r\n  this.emit('suite', suite);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Add a `test` to this suite.\r\n *\r\n * @api private\r\n * @param {Test} test\r\n * @return {Suite} for chaining\r\n */\r\nSuite.prototype.addTest = function(test) {\r\n  test.parent = this;\r\n  test.timeout(this.timeout());\r\n  test.enableTimeouts(this.enableTimeouts());\r\n  test.slow(this.slow());\r\n  test.ctx = this.ctx;\r\n  this.tests.push(test);\r\n  this.emit('test', test);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Return the full title generated by recursively concatenating the parent's\r\n * full title.\r\n *\r\n * @api public\r\n * @return {string}\r\n */\r\nSuite.prototype.fullTitle = function() {\r\n  if (this.parent) {\r\n    var full = this.parent.fullTitle();\r\n    if (full) {\r\n      return full + ' ' + this.title;\r\n    }\r\n  }\r\n  return this.title;\r\n};\r\n\r\n/**\r\n * Return the total number of tests.\r\n *\r\n * @api public\r\n * @return {number}\r\n */\r\nSuite.prototype.total = function() {\r\n  return utils.reduce(this.suites, function(sum, suite) {\r\n    return sum + suite.total();\r\n  }, 0) + this.tests.length;\r\n};\r\n\r\n/**\r\n * Iterates through each suite recursively to find all tests. Applies a\r\n * function in the format `fn(test)`.\r\n *\r\n * @api private\r\n * @param {Function} fn\r\n * @return {Suite}\r\n */\r\nSuite.prototype.eachTest = function(fn) {\r\n  utils.forEach(this.tests, fn);\r\n  utils.forEach(this.suites, function(suite) {\r\n    suite.eachTest(fn);\r\n  });\r\n  return this;\r\n};\r\n\r\n/**\r\n * This will run the root suite if we happen to be running in delayed mode.\r\n */\r\nSuite.prototype.run = function run() {\r\n  if (this.root) {\r\n    this.emit('run');\r\n  }\r\n};\r\n\r\n},{\"./hook\":7,\"./ms\":15,\"./utils\":39,\"debug\":2,\"events\":3}],38:[function(require,module,exports){\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar Runnable = require('./runnable');\r\nvar inherits = require('./utils').inherits;\r\n\r\n/**\r\n * Expose `Test`.\r\n */\r\n\r\nmodule.exports = Test;\r\n\r\n/**\r\n * Initialize a new `Test` with the given `title` and callback `fn`.\r\n *\r\n * @api private\r\n * @param {String} title\r\n * @param {Function} fn\r\n */\r\nfunction Test(title, fn) {\r\n  Runnable.call(this, title, fn);\r\n  this.pending = !fn;\r\n  this.type = 'test';\r\n}\r\n\r\n/**\r\n * Inherit from `Runnable.prototype`.\r\n */\r\ninherits(Test, Runnable);\r\n\r\n},{\"./runnable\":35,\"./utils\":39}],39:[function(require,module,exports){\r\n(function (process,Buffer){\r\n/* eslint-env browser */\r\n\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar basename = require('path').basename;\r\nvar debug = require('debug')('mocha:watch');\r\nvar exists = require('fs').existsSync || require('path').existsSync;\r\nvar glob = require('glob');\r\nvar join = require('path').join;\r\nvar readdirSync = require('fs').readdirSync;\r\nvar statSync = require('fs').statSync;\r\nvar watchFile = require('fs').watchFile;\r\n\r\n/**\r\n * Ignored directories.\r\n */\r\n\r\nvar ignore = ['node_modules', '.git'];\r\n\r\nexports.inherits = require('util').inherits;\r\n\r\n/**\r\n * Escape special characters in the given string of html.\r\n *\r\n * @api private\r\n * @param  {string} html\r\n * @return {string}\r\n */\r\nexports.escape = function(html) {\r\n  return String(html)\r\n    .replace(/&/g, '&amp;')\r\n    .replace(/\"/g, '&quot;')\r\n    .replace(/</g, '&lt;')\r\n    .replace(/>/g, '&gt;');\r\n};\r\n\r\n/**\r\n * Array#forEach (<=IE8)\r\n *\r\n * @api private\r\n * @param {Array} arr\r\n * @param {Function} fn\r\n * @param {Object} scope\r\n */\r\nexports.forEach = function(arr, fn, scope) {\r\n  for (var i = 0, l = arr.length; i < l; i++) {\r\n    fn.call(scope, arr[i], i);\r\n  }\r\n};\r\n\r\n/**\r\n * Test if the given obj is type of string.\r\n *\r\n * @api private\r\n * @param {Object} obj\r\n * @return {boolean}\r\n */\r\nexports.isString = function(obj) {\r\n  return typeof obj === 'string';\r\n};\r\n\r\n/**\r\n * Array#map (<=IE8)\r\n *\r\n * @api private\r\n * @param {Array} arr\r\n * @param {Function} fn\r\n * @param {Object} scope\r\n * @return {Array}\r\n */\r\nexports.map = function(arr, fn, scope) {\r\n  var result = [];\r\n  for (var i = 0, l = arr.length; i < l; i++) {\r\n    result.push(fn.call(scope, arr[i], i, arr));\r\n  }\r\n  return result;\r\n};\r\n\r\n/**\r\n * Array#indexOf (<=IE8)\r\n *\r\n * @api private\r\n * @param {Array} arr\r\n * @param {Object} obj to find index of\r\n * @param {number} start\r\n * @return {number}\r\n */\r\nexports.indexOf = function(arr, obj, start) {\r\n  for (var i = start || 0, l = arr.length; i < l; i++) {\r\n    if (arr[i] === obj) {\r\n      return i;\r\n    }\r\n  }\r\n  return -1;\r\n};\r\n\r\n/**\r\n * Array#reduce (<=IE8)\r\n *\r\n * @api private\r\n * @param {Array} arr\r\n * @param {Function} fn\r\n * @param {Object} val Initial value.\r\n * @return {*}\r\n */\r\nexports.reduce = function(arr, fn, val) {\r\n  var rval = val;\r\n\r\n  for (var i = 0, l = arr.length; i < l; i++) {\r\n    rval = fn(rval, arr[i], i, arr);\r\n  }\r\n\r\n  return rval;\r\n};\r\n\r\n/**\r\n * Array#filter (<=IE8)\r\n *\r\n * @api private\r\n * @param {Array} arr\r\n * @param {Function} fn\r\n * @return {Array}\r\n */\r\nexports.filter = function(arr, fn) {\r\n  var ret = [];\r\n\r\n  for (var i = 0, l = arr.length; i < l; i++) {\r\n    var val = arr[i];\r\n    if (fn(val, i, arr)) {\r\n      ret.push(val);\r\n    }\r\n  }\r\n\r\n  return ret;\r\n};\r\n\r\n/**\r\n * Object.keys (<=IE8)\r\n *\r\n * @api private\r\n * @param {Object} obj\r\n * @return {Array} keys\r\n */\r\nexports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) {\r\n  var keys = [];\r\n  var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8\r\n\r\n  for (var key in obj) {\r\n    if (has.call(obj, key)) {\r\n      keys.push(key);\r\n    }\r\n  }\r\n\r\n  return keys;\r\n};\r\n\r\n/**\r\n * Watch the given `files` for changes\r\n * and invoke `fn(file)` on modification.\r\n *\r\n * @api private\r\n * @param {Array} files\r\n * @param {Function} fn\r\n */\r\nexports.watch = function(files, fn) {\r\n  var options = { interval: 100 };\r\n  files.forEach(function(file) {\r\n    debug('file %s', file);\r\n    watchFile(file, options, function(curr, prev) {\r\n      if (prev.mtime < curr.mtime) {\r\n        fn(file);\r\n      }\r\n    });\r\n  });\r\n};\r\n\r\n/**\r\n * Array.isArray (<=IE8)\r\n *\r\n * @api private\r\n * @param {Object} obj\r\n * @return {Boolean}\r\n */\r\nvar isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) {\r\n  return Object.prototype.toString.call(obj) === '[object Array]';\r\n};\r\n\r\n/**\r\n * Buffer.prototype.toJSON polyfill.\r\n *\r\n * @type {Function}\r\n */\r\nif (typeof Buffer !== 'undefined' && Buffer.prototype) {\r\n  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() {\r\n    return Array.prototype.slice.call(this, 0);\r\n  };\r\n}\r\n\r\n/**\r\n * Ignored files.\r\n *\r\n * @api private\r\n * @param {string} path\r\n * @return {boolean}\r\n */\r\nfunction ignored(path) {\r\n  return !~ignore.indexOf(path);\r\n}\r\n\r\n/**\r\n * Lookup files in the given `dir`.\r\n *\r\n * @api private\r\n * @param {string} dir\r\n * @param {string[]} [ext=['.js']]\r\n * @param {Array} [ret=[]]\r\n * @return {Array}\r\n */\r\nexports.files = function(dir, ext, ret) {\r\n  ret = ret || [];\r\n  ext = ext || ['js'];\r\n\r\n  var re = new RegExp('\\\\.(' + ext.join('|') + ')$');\r\n\r\n  readdirSync(dir)\r\n    .filter(ignored)\r\n    .forEach(function(path) {\r\n      path = join(dir, path);\r\n      if (statSync(path).isDirectory()) {\r\n        exports.files(path, ext, ret);\r\n      } else if (path.match(re)) {\r\n        ret.push(path);\r\n      }\r\n    });\r\n\r\n  return ret;\r\n};\r\n\r\n/**\r\n * Compute a slug from the given `str`.\r\n *\r\n * @api private\r\n * @param {string} str\r\n * @return {string}\r\n */\r\nexports.slug = function(str) {\r\n  return str\r\n    .toLowerCase()\r\n    .replace(/ +/g, '-')\r\n    .replace(/[^-\\w]/g, '');\r\n};\r\n\r\n/**\r\n * Strip the function definition from `str`, and re-indent for pre whitespace.\r\n *\r\n * @param {string} str\r\n * @return {string}\r\n */\r\nexports.clean = function(str) {\r\n  str = str\r\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, '\\n').replace(/^\\uFEFF/, '')\r\n    .replace(/^function *\\(.*\\)\\s*{|\\(.*\\) *=> *{?/, '')\r\n    .replace(/\\s+\\}$/, '');\r\n\r\n  var spaces = str.match(/^\\n?( *)/)[1].length;\r\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\r\n  var re = new RegExp('^\\n?' + (tabs ? '\\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');\r\n\r\n  str = str.replace(re, '');\r\n\r\n  return exports.trim(str);\r\n};\r\n\r\n/**\r\n * Trim the given `str`.\r\n *\r\n * @api private\r\n * @param {string} str\r\n * @return {string}\r\n */\r\nexports.trim = function(str) {\r\n  return str.replace(/^\\s+|\\s+$/g, '');\r\n};\r\n\r\n/**\r\n * Parse the given `qs`.\r\n *\r\n * @api private\r\n * @param {string} qs\r\n * @return {Object}\r\n */\r\nexports.parseQuery = function(qs) {\r\n  return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair) {\r\n    var i = pair.indexOf('=');\r\n    var key = pair.slice(0, i);\r\n    var val = pair.slice(++i);\r\n\r\n    obj[key] = decodeURIComponent(val);\r\n    return obj;\r\n  }, {});\r\n};\r\n\r\n/**\r\n * Highlight the given string of `js`.\r\n *\r\n * @api private\r\n * @param {string} js\r\n * @return {string}\r\n */\r\nfunction highlight(js) {\r\n  return js\r\n    .replace(/</g, '&lt;')\r\n    .replace(/>/g, '&gt;')\r\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\r\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\r\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\r\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\r\n    .replace(/\\bnew[ \\t]+(\\w+)/gm, '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>')\r\n    .replace(/\\b(function|new|throw|return|var|if|else)\\b/gm, '<span class=\"keyword\">$1</span>');\r\n}\r\n\r\n/**\r\n * Highlight the contents of tag `name`.\r\n *\r\n * @api private\r\n * @param {string} name\r\n */\r\nexports.highlightTags = function(name) {\r\n  var code = document.getElementById('mocha').getElementsByTagName(name);\r\n  for (var i = 0, len = code.length; i < len; ++i) {\r\n    code[i].innerHTML = highlight(code[i].innerHTML);\r\n  }\r\n};\r\n\r\n/**\r\n * If a value could have properties, and has none, this function is called,\r\n * which returns a string representation of the empty value.\r\n *\r\n * Functions w/ no properties return `'[Function]'`\r\n * Arrays w/ length === 0 return `'[]'`\r\n * Objects w/ no properties return `'{}'`\r\n * All else: return result of `value.toString()`\r\n *\r\n * @api private\r\n * @param {*} value The value to inspect.\r\n * @param {string} [type] The type of the value, if known.\r\n * @returns {string}\r\n */\r\nfunction emptyRepresentation(value, type) {\r\n  type = type || exports.type(value);\r\n\r\n  switch (type) {\r\n    case 'function':\r\n      return '[Function]';\r\n    case 'object':\r\n      return '{}';\r\n    case 'array':\r\n      return '[]';\r\n    default:\r\n      return value.toString();\r\n  }\r\n}\r\n\r\n/**\r\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\r\n * is.\r\n *\r\n * @api private\r\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\r\n * @param {*} value The value to test.\r\n * @returns {string}\r\n * @example\r\n * type({}) // 'object'\r\n * type([]) // 'array'\r\n * type(1) // 'number'\r\n * type(false) // 'boolean'\r\n * type(Infinity) // 'number'\r\n * type(null) // 'null'\r\n * type(new Date()) // 'date'\r\n * type(/foo/) // 'regexp'\r\n * type('type') // 'string'\r\n * type(global) // 'global'\r\n */\r\nexports.type = function type(value) {\r\n  if (value === undefined) {\r\n    return 'undefined';\r\n  } else if (value === null) {\r\n    return 'null';\r\n  } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\r\n    return 'buffer';\r\n  }\r\n  return Object.prototype.toString.call(value)\r\n    .replace(/^\\[.+\\s(.+?)\\]$/, '$1')\r\n    .toLowerCase();\r\n};\r\n\r\n/**\r\n * Stringify `value`. Different behavior depending on type of value:\r\n *\r\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\r\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\r\n * - If `value` is an *empty* object, function, or array, return result of function\r\n *   {@link emptyRepresentation}.\r\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\r\n *   JSON.stringify().\r\n *\r\n * @api private\r\n * @see exports.type\r\n * @param {*} value\r\n * @return {string}\r\n */\r\nexports.stringify = function(value) {\r\n  var type = exports.type(value);\r\n\r\n  if (!~exports.indexOf(['object', 'array', 'function'], type)) {\r\n    if (type !== 'buffer') {\r\n      return jsonStringify(value);\r\n    }\r\n    var json = value.toJSON();\r\n    // Based on the toJSON result\r\n    return jsonStringify(json.data && json.type ? json.data : json, 2)\r\n      .replace(/,(\\n|$)/g, '$1');\r\n  }\r\n\r\n  for (var prop in value) {\r\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\r\n      return jsonStringify(exports.canonicalize(value), 2).replace(/,(\\n|$)/g, '$1');\r\n    }\r\n  }\r\n\r\n  return emptyRepresentation(value, type);\r\n};\r\n\r\n/**\r\n * like JSON.stringify but more sense.\r\n *\r\n * @api private\r\n * @param {Object}  object\r\n * @param {number=} spaces\r\n * @param {number=} depth\r\n * @returns {*}\r\n */\r\nfunction jsonStringify(object, spaces, depth) {\r\n  if (typeof spaces === 'undefined') {\r\n    // primitive types\r\n    return _stringify(object);\r\n  }\r\n\r\n  depth = depth || 1;\r\n  var space = spaces * depth;\r\n  var str = isArray(object) ? '[' : '{';\r\n  var end = isArray(object) ? ']' : '}';\r\n  var length = object.length || exports.keys(object).length;\r\n  // `.repeat()` polyfill\r\n  function repeat(s, n) {\r\n    return new Array(n).join(s);\r\n  }\r\n\r\n  function _stringify(val) {\r\n    switch (exports.type(val)) {\r\n      case 'null':\r\n      case 'undefined':\r\n        val = '[' + val + ']';\r\n        break;\r\n      case 'array':\r\n      case 'object':\r\n        val = jsonStringify(val, spaces, depth + 1);\r\n        break;\r\n      case 'boolean':\r\n      case 'regexp':\r\n      case 'number':\r\n        val = val === 0 && (1 / val) === -Infinity // `-0`\r\n          ? '-0'\r\n          : val.toString();\r\n        break;\r\n      case 'date':\r\n        var sDate = isNaN(val.getTime())        // Invalid date\r\n          ? val.toString()\r\n          : val.toISOString();\r\n        val = '[Date: ' + sDate + ']';\r\n        break;\r\n      case 'buffer':\r\n        var json = val.toJSON();\r\n        // Based on the toJSON result\r\n        json = json.data && json.type ? json.data : json;\r\n        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';\r\n        break;\r\n      default:\r\n        val = (val === '[Function]' || val === '[Circular]')\r\n          ? val\r\n          : JSON.stringify(val); // string\r\n    }\r\n    return val;\r\n  }\r\n\r\n  for (var i in object) {\r\n    if (!object.hasOwnProperty(i)) {\r\n      continue; // not my business\r\n    }\r\n    --length;\r\n    str += '\\n ' + repeat(' ', space)\r\n      + (isArray(object) ? '' : '\"' + i + '\": ') // key\r\n      + _stringify(object[i])                     // value\r\n      + (length ? ',' : '');                     // comma\r\n  }\r\n\r\n  return str\r\n    // [], {}\r\n    + (str.length !== 1 ? '\\n' + repeat(' ', --space) + end : end);\r\n}\r\n\r\n/**\r\n * Test if a value is a buffer.\r\n *\r\n * @api private\r\n * @param {*} value The value to test.\r\n * @return {boolean} True if `value` is a buffer, otherwise false\r\n */\r\nexports.isBuffer = function(value) {\r\n  return typeof Buffer !== 'undefined' && Buffer.isBuffer(value);\r\n};\r\n\r\n/**\r\n * Return a new Thing that has the keys in sorted order. Recursive.\r\n *\r\n * If the Thing...\r\n * - has already been seen, return string `'[Circular]'`\r\n * - is `undefined`, return string `'[undefined]'`\r\n * - is `null`, return value `null`\r\n * - is some other primitive, return the value\r\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\r\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\r\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\r\n *\r\n * @api private\r\n * @see {@link exports.stringify}\r\n * @param {*} value Thing to inspect.  May or may not have properties.\r\n * @param {Array} [stack=[]] Stack of seen values\r\n * @return {(Object|Array|Function|string|undefined)}\r\n */\r\nexports.canonicalize = function(value, stack) {\r\n  var canonicalizedObj;\r\n  /* eslint-disable no-unused-vars */\r\n  var prop;\r\n  /* eslint-enable no-unused-vars */\r\n  var type = exports.type(value);\r\n  function withStack(value, fn) {\r\n    stack.push(value);\r\n    fn();\r\n    stack.pop();\r\n  }\r\n\r\n  stack = stack || [];\r\n\r\n  if (exports.indexOf(stack, value) !== -1) {\r\n    return '[Circular]';\r\n  }\r\n\r\n  switch (type) {\r\n    case 'undefined':\r\n    case 'buffer':\r\n    case 'null':\r\n      canonicalizedObj = value;\r\n      break;\r\n    case 'array':\r\n      withStack(value, function() {\r\n        canonicalizedObj = exports.map(value, function(item) {\r\n          return exports.canonicalize(item, stack);\r\n        });\r\n      });\r\n      break;\r\n    case 'function':\r\n      /* eslint-disable guard-for-in */\r\n      for (prop in value) {\r\n        canonicalizedObj = {};\r\n        break;\r\n      }\r\n      /* eslint-enable guard-for-in */\r\n      if (!canonicalizedObj) {\r\n        canonicalizedObj = emptyRepresentation(value, type);\r\n        break;\r\n      }\r\n    /* falls through */\r\n    case 'object':\r\n      canonicalizedObj = canonicalizedObj || {};\r\n      withStack(value, function() {\r\n        exports.forEach(exports.keys(value).sort(), function(key) {\r\n          canonicalizedObj[key] = exports.canonicalize(value[key], stack);\r\n        });\r\n      });\r\n      break;\r\n    case 'date':\r\n    case 'number':\r\n    case 'regexp':\r\n    case 'boolean':\r\n      canonicalizedObj = value;\r\n      break;\r\n    default:\r\n      canonicalizedObj = value.toString();\r\n  }\r\n\r\n  return canonicalizedObj;\r\n};\r\n\r\n/**\r\n * Lookup file names at the given `path`.\r\n *\r\n * @api public\r\n * @param {string} path Base path to start searching from.\r\n * @param {string[]} extensions File extensions to look for.\r\n * @param {boolean} recursive Whether or not to recurse into subdirectories.\r\n * @return {string[]} An array of paths.\r\n */\r\nexports.lookupFiles = function lookupFiles(path, extensions, recursive) {\r\n  var files = [];\r\n  var re = new RegExp('\\\\.(' + extensions.join('|') + ')$');\r\n\r\n  if (!exists(path)) {\r\n    if (exists(path + '.js')) {\r\n      path += '.js';\r\n    } else {\r\n      files = glob.sync(path);\r\n      if (!files.length) {\r\n        throw new Error(\"cannot resolve path (or pattern) '\" + path + \"'\");\r\n      }\r\n      return files;\r\n    }\r\n  }\r\n\r\n  try {\r\n    var stat = statSync(path);\r\n    if (stat.isFile()) {\r\n      return path;\r\n    }\r\n  } catch (err) {\r\n    // ignore error\r\n    return;\r\n  }\r\n\r\n  readdirSync(path).forEach(function(file) {\r\n    file = join(path, file);\r\n    try {\r\n      var stat = statSync(file);\r\n      if (stat.isDirectory()) {\r\n        if (recursive) {\r\n          files = files.concat(lookupFiles(file, extensions, recursive));\r\n        }\r\n        return;\r\n      }\r\n    } catch (err) {\r\n      // ignore error\r\n      return;\r\n    }\r\n    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') {\r\n      return;\r\n    }\r\n    files.push(file);\r\n  });\r\n\r\n  return files;\r\n};\r\n\r\n/**\r\n * Generate an undefined error with a message warning the user.\r\n *\r\n * @return {Error}\r\n */\r\n\r\nexports.undefinedError = function() {\r\n  return new Error('Caught undefined error, did you throw without specifying what?');\r\n};\r\n\r\n/**\r\n * Generate an undefined error if `err` is not defined.\r\n *\r\n * @param {Error} err\r\n * @return {Error}\r\n */\r\n\r\nexports.getError = function(err) {\r\n  return err || exports.undefinedError();\r\n};\r\n\r\n/**\r\n * @summary\r\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\r\n * @description\r\n * When invoking this function you get a filter function that get the Error.stack as an input,\r\n * and return a prettify output.\r\n * (i.e: strip Mocha and internal node functions from stack trace).\r\n * @returns {Function}\r\n */\r\nexports.stackTraceFilter = function() {\r\n  // TODO: Replace with `process.browser`\r\n  var slash = '/';\r\n  var is = typeof document === 'undefined' ? { node: true } : { browser: true };\r\n  var cwd = is.node\r\n      ? process.cwd() + slash\r\n      : (typeof location === 'undefined' ? window.location : location).href.replace(/\\/[^\\/]*$/, '/');\r\n\r\n  function isMochaInternal(line) {\r\n    return (~line.indexOf('node_modules' + slash + 'mocha' + slash))\r\n      || (~line.indexOf('components' + slash + 'mochajs' + slash))\r\n      || (~line.indexOf('components' + slash + 'mocha' + slash))\r\n      || (~line.indexOf(slash + 'mocha.js'));\r\n  }\r\n\r\n  function isNodeInternal(line) {\r\n    return (~line.indexOf('(timers.js:'))\r\n      || (~line.indexOf('(events.js:'))\r\n      || (~line.indexOf('(node.js:'))\r\n      || (~line.indexOf('(module.js:'))\r\n      || (~line.indexOf('GeneratorFunctionPrototype.next (native)'))\r\n      || false;\r\n  }\r\n\r\n  return function(stack) {\r\n    stack = stack.split('\\n');\r\n\r\n    stack = exports.reduce(stack, function(list, line) {\r\n      if (isMochaInternal(line)) {\r\n        return list;\r\n      }\r\n\r\n      if (is.node && isNodeInternal(line)) {\r\n        return list;\r\n      }\r\n\r\n      // Clean up cwd(absolute)\r\n      list.push(line.replace(cwd, ''));\r\n      return list;\r\n    }, []);\r\n\r\n    return stack.join('\\n');\r\n  };\r\n};\r\n\r\n}).call(this,require('_process'),require(\"buffer\").Buffer)\r\n},{\"_process\":51,\"buffer\":43,\"debug\":2,\"fs\":41,\"glob\":41,\"path\":41,\"util\":66}],40:[function(require,module,exports){\r\n(function (process){\r\nvar WritableStream = require('stream').Writable\r\nvar inherits = require('util').inherits\r\n\r\nmodule.exports = BrowserStdout\r\n\r\n\r\ninherits(BrowserStdout, WritableStream)\r\n\r\nfunction BrowserStdout(opts) {\r\n  if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts)\r\n\r\n  opts = opts || {}\r\n  WritableStream.call(this, opts)\r\n  this.label = (opts.label !== undefined) ? opts.label : 'stdout'\r\n}\r\n\r\nBrowserStdout.prototype._write = function(chunks, encoding, cb) {\r\n  var output = chunks.toString ? chunks.toString() : chunks\r\n  if (this.label === false) {\r\n    console.log(output)\r\n  } else {\r\n    console.log(this.label+':', output)\r\n  }\r\n  process.nextTick(cb)\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"_process\":51,\"stream\":63,\"util\":66}],41:[function(require,module,exports){\r\n\r\n},{}],42:[function(require,module,exports){\r\narguments[4][41][0].apply(exports,arguments)\r\n},{\"dup\":41}],43:[function(require,module,exports){\r\n/*!\r\n * The buffer module from node.js, for the browser.\r\n *\r\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\r\n * @license  MIT\r\n */\r\n\r\nvar base64 = require('base64-js')\r\nvar ieee754 = require('ieee754')\r\nvar isArray = require('is-array')\r\n\r\nexports.Buffer = Buffer\r\nexports.SlowBuffer = SlowBuffer\r\nexports.INSPECT_MAX_BYTES = 50\r\nBuffer.poolSize = 8192 // not used by this implementation\r\n\r\nvar rootParent = {}\r\n\r\n/**\r\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\r\n *   === true    Use Uint8Array implementation (fastest)\r\n *   === false   Use Object implementation (most compatible, even IE6)\r\n *\r\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\r\n * Opera 11.6+, iOS 4.2+.\r\n *\r\n * Due to various browser bugs, sometimes the Object implementation will be used even\r\n * when the browser supports typed arrays.\r\n *\r\n * Note:\r\n *\r\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\r\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\r\n *\r\n *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property\r\n *     on objects.\r\n *\r\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\r\n *\r\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\r\n *     incorrect length in some situations.\r\n\r\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\r\n * get the Object implementation, which is slower but behaves correctly.\r\n */\r\nBuffer.TYPED_ARRAY_SUPPORT = (function () {\r\n  function Bar () {}\r\n  try {\r\n    var arr = new Uint8Array(1)\r\n    arr.foo = function () { return 42 }\r\n    arr.constructor = Bar\r\n    return arr.foo() === 42 && // typed array instances can be augmented\r\n        arr.constructor === Bar && // constructor can be set\r\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\r\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\r\n  } catch (e) {\r\n    return false\r\n  }\r\n})()\r\n\r\nfunction kMaxLength () {\r\n  return Buffer.TYPED_ARRAY_SUPPORT\r\n    ? 0x7fffffff\r\n    : 0x3fffffff\r\n}\r\n\r\n/**\r\n * Class: Buffer\r\n * =============\r\n *\r\n * The Buffer constructor returns instances of `Uint8Array` that are augmented\r\n * with function properties for all the node `Buffer` API functions. We use\r\n * `Uint8Array` so that square bracket notation works as expected -- it returns\r\n * a single octet.\r\n *\r\n * By augmenting the instances, we can avoid modifying the `Uint8Array`\r\n * prototype.\r\n */\r\nfunction Buffer (arg) {\r\n  if (!(this instanceof Buffer)) {\r\n    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.\r\n    if (arguments.length > 1) return new Buffer(arg, arguments[1])\r\n    return new Buffer(arg)\r\n  }\r\n\r\n  this.length = 0\r\n  this.parent = undefined\r\n\r\n  // Common case.\r\n  if (typeof arg === 'number') {\r\n    return fromNumber(this, arg)\r\n  }\r\n\r\n  // Slightly less common case.\r\n  if (typeof arg === 'string') {\r\n    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')\r\n  }\r\n\r\n  // Unusual.\r\n  return fromObject(this, arg)\r\n}\r\n\r\nfunction fromNumber (that, length) {\r\n  that = allocate(that, length < 0 ? 0 : checked(length) | 0)\r\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\r\n    for (var i = 0; i < length; i++) {\r\n      that[i] = 0\r\n    }\r\n  }\r\n  return that\r\n}\r\n\r\nfunction fromString (that, string, encoding) {\r\n  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'\r\n\r\n  // Assumption: byteLength() return value is always < kMaxLength.\r\n  var length = byteLength(string, encoding) | 0\r\n  that = allocate(that, length)\r\n\r\n  that.write(string, encoding)\r\n  return that\r\n}\r\n\r\nfunction fromObject (that, object) {\r\n  if (Buffer.isBuffer(object)) return fromBuffer(that, object)\r\n\r\n  if (isArray(object)) return fromArray(that, object)\r\n\r\n  if (object == null) {\r\n    throw new TypeError('must start with number, buffer, array or string')\r\n  }\r\n\r\n  if (typeof ArrayBuffer !== 'undefined') {\r\n    if (object.buffer instanceof ArrayBuffer) {\r\n      return fromTypedArray(that, object)\r\n    }\r\n    if (object instanceof ArrayBuffer) {\r\n      return fromArrayBuffer(that, object)\r\n    }\r\n  }\r\n\r\n  if (object.length) return fromArrayLike(that, object)\r\n\r\n  return fromJsonObject(that, object)\r\n}\r\n\r\nfunction fromBuffer (that, buffer) {\r\n  var length = checked(buffer.length) | 0\r\n  that = allocate(that, length)\r\n  buffer.copy(that, 0, 0, length)\r\n  return that\r\n}\r\n\r\nfunction fromArray (that, array) {\r\n  var length = checked(array.length) | 0\r\n  that = allocate(that, length)\r\n  for (var i = 0; i < length; i += 1) {\r\n    that[i] = array[i] & 255\r\n  }\r\n  return that\r\n}\r\n\r\n// Duplicate of fromArray() to keep fromArray() monomorphic.\r\nfunction fromTypedArray (that, array) {\r\n  var length = checked(array.length) | 0\r\n  that = allocate(that, length)\r\n  // Truncating the elements is probably not what people expect from typed\r\n  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior\r\n  // of the old Buffer constructor.\r\n  for (var i = 0; i < length; i += 1) {\r\n    that[i] = array[i] & 255\r\n  }\r\n  return that\r\n}\r\n\r\nfunction fromArrayBuffer (that, array) {\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    // Return an augmented `Uint8Array` instance, for best performance\r\n    array.byteLength\r\n    that = Buffer._augment(new Uint8Array(array))\r\n  } else {\r\n    // Fallback: Return an object instance of the Buffer class\r\n    that = fromTypedArray(that, new Uint8Array(array))\r\n  }\r\n  return that\r\n}\r\n\r\nfunction fromArrayLike (that, array) {\r\n  var length = checked(array.length) | 0\r\n  that = allocate(that, length)\r\n  for (var i = 0; i < length; i += 1) {\r\n    that[i] = array[i] & 255\r\n  }\r\n  return that\r\n}\r\n\r\n// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.\r\n// Returns a zero-length buffer for inputs that don't conform to the spec.\r\nfunction fromJsonObject (that, object) {\r\n  var array\r\n  var length = 0\r\n\r\n  if (object.type === 'Buffer' && isArray(object.data)) {\r\n    array = object.data\r\n    length = checked(array.length) | 0\r\n  }\r\n  that = allocate(that, length)\r\n\r\n  for (var i = 0; i < length; i += 1) {\r\n    that[i] = array[i] & 255\r\n  }\r\n  return that\r\n}\r\n\r\nfunction allocate (that, length) {\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    // Return an augmented `Uint8Array` instance, for best performance\r\n    that = Buffer._augment(new Uint8Array(length))\r\n  } else {\r\n    // Fallback: Return an object instance of the Buffer class\r\n    that.length = length\r\n    that._isBuffer = true\r\n  }\r\n\r\n  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1\r\n  if (fromPool) that.parent = rootParent\r\n\r\n  return that\r\n}\r\n\r\nfunction checked (length) {\r\n  // Note: cannot use `length < kMaxLength` here because that fails when\r\n  // length is NaN (which is otherwise coerced to zero.)\r\n  if (length >= kMaxLength()) {\r\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\r\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\r\n  }\r\n  return length | 0\r\n}\r\n\r\nfunction SlowBuffer (subject, encoding) {\r\n  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)\r\n\r\n  var buf = new Buffer(subject, encoding)\r\n  delete buf.parent\r\n  return buf\r\n}\r\n\r\nBuffer.isBuffer = function isBuffer (b) {\r\n  return !!(b != null && b._isBuffer)\r\n}\r\n\r\nBuffer.compare = function compare (a, b) {\r\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\r\n    throw new TypeError('Arguments must be Buffers')\r\n  }\r\n\r\n  if (a === b) return 0\r\n\r\n  var x = a.length\r\n  var y = b.length\r\n\r\n  var i = 0\r\n  var len = Math.min(x, y)\r\n  while (i < len) {\r\n    if (a[i] !== b[i]) break\r\n\r\n    ++i\r\n  }\r\n\r\n  if (i !== len) {\r\n    x = a[i]\r\n    y = b[i]\r\n  }\r\n\r\n  if (x < y) return -1\r\n  if (y < x) return 1\r\n  return 0\r\n}\r\n\r\nBuffer.isEncoding = function isEncoding (encoding) {\r\n  switch (String(encoding).toLowerCase()) {\r\n    case 'hex':\r\n    case 'utf8':\r\n    case 'utf-8':\r\n    case 'ascii':\r\n    case 'binary':\r\n    case 'base64':\r\n    case 'raw':\r\n    case 'ucs2':\r\n    case 'ucs-2':\r\n    case 'utf16le':\r\n    case 'utf-16le':\r\n      return true\r\n    default:\r\n      return false\r\n  }\r\n}\r\n\r\nBuffer.concat = function concat (list, length) {\r\n  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')\r\n\r\n  if (list.length === 0) {\r\n    return new Buffer(0)\r\n  }\r\n\r\n  var i\r\n  if (length === undefined) {\r\n    length = 0\r\n    for (i = 0; i < list.length; i++) {\r\n      length += list[i].length\r\n    }\r\n  }\r\n\r\n  var buf = new Buffer(length)\r\n  var pos = 0\r\n  for (i = 0; i < list.length; i++) {\r\n    var item = list[i]\r\n    item.copy(buf, pos)\r\n    pos += item.length\r\n  }\r\n  return buf\r\n}\r\n\r\nfunction byteLength (string, encoding) {\r\n  if (typeof string !== 'string') string = '' + string\r\n\r\n  var len = string.length\r\n  if (len === 0) return 0\r\n\r\n  // Use a for loop to avoid recursion\r\n  var loweredCase = false\r\n  for (;;) {\r\n    switch (encoding) {\r\n      case 'ascii':\r\n      case 'binary':\r\n      // Deprecated\r\n      case 'raw':\r\n      case 'raws':\r\n        return len\r\n      case 'utf8':\r\n      case 'utf-8':\r\n        return utf8ToBytes(string).length\r\n      case 'ucs2':\r\n      case 'ucs-2':\r\n      case 'utf16le':\r\n      case 'utf-16le':\r\n        return len * 2\r\n      case 'hex':\r\n        return len >>> 1\r\n      case 'base64':\r\n        return base64ToBytes(string).length\r\n      default:\r\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\r\n        encoding = ('' + encoding).toLowerCase()\r\n        loweredCase = true\r\n    }\r\n  }\r\n}\r\nBuffer.byteLength = byteLength\r\n\r\n// pre-set for values that may exist in the future\r\nBuffer.prototype.length = undefined\r\nBuffer.prototype.parent = undefined\r\n\r\nfunction slowToString (encoding, start, end) {\r\n  var loweredCase = false\r\n\r\n  start = start | 0\r\n  end = end === undefined || end === Infinity ? this.length : end | 0\r\n\r\n  if (!encoding) encoding = 'utf8'\r\n  if (start < 0) start = 0\r\n  if (end > this.length) end = this.length\r\n  if (end <= start) return ''\r\n\r\n  while (true) {\r\n    switch (encoding) {\r\n      case 'hex':\r\n        return hexSlice(this, start, end)\r\n\r\n      case 'utf8':\r\n      case 'utf-8':\r\n        return utf8Slice(this, start, end)\r\n\r\n      case 'ascii':\r\n        return asciiSlice(this, start, end)\r\n\r\n      case 'binary':\r\n        return binarySlice(this, start, end)\r\n\r\n      case 'base64':\r\n        return base64Slice(this, start, end)\r\n\r\n      case 'ucs2':\r\n      case 'ucs-2':\r\n      case 'utf16le':\r\n      case 'utf-16le':\r\n        return utf16leSlice(this, start, end)\r\n\r\n      default:\r\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\r\n        encoding = (encoding + '').toLowerCase()\r\n        loweredCase = true\r\n    }\r\n  }\r\n}\r\n\r\nBuffer.prototype.toString = function toString () {\r\n  var length = this.length | 0\r\n  if (length === 0) return ''\r\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\r\n  return slowToString.apply(this, arguments)\r\n}\r\n\r\nBuffer.prototype.equals = function equals (b) {\r\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\r\n  if (this === b) return true\r\n  return Buffer.compare(this, b) === 0\r\n}\r\n\r\nBuffer.prototype.inspect = function inspect () {\r\n  var str = ''\r\n  var max = exports.INSPECT_MAX_BYTES\r\n  if (this.length > 0) {\r\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\r\n    if (this.length > max) str += ' ... '\r\n  }\r\n  return '<Buffer ' + str + '>'\r\n}\r\n\r\nBuffer.prototype.compare = function compare (b) {\r\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\r\n  if (this === b) return 0\r\n  return Buffer.compare(this, b)\r\n}\r\n\r\nBuffer.prototype.indexOf = function indexOf (val, byteOffset) {\r\n  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff\r\n  else if (byteOffset < -0x80000000) byteOffset = -0x80000000\r\n  byteOffset >>= 0\r\n\r\n  if (this.length === 0) return -1\r\n  if (byteOffset >= this.length) return -1\r\n\r\n  // Negative offsets start from the end of the buffer\r\n  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)\r\n\r\n  if (typeof val === 'string') {\r\n    if (val.length === 0) return -1 // special case: looking for empty string always fails\r\n    return String.prototype.indexOf.call(this, val, byteOffset)\r\n  }\r\n  if (Buffer.isBuffer(val)) {\r\n    return arrayIndexOf(this, val, byteOffset)\r\n  }\r\n  if (typeof val === 'number') {\r\n    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {\r\n      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)\r\n    }\r\n    return arrayIndexOf(this, [ val ], byteOffset)\r\n  }\r\n\r\n  function arrayIndexOf (arr, val, byteOffset) {\r\n    var foundIndex = -1\r\n    for (var i = 0; byteOffset + i < arr.length; i++) {\r\n      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {\r\n        if (foundIndex === -1) foundIndex = i\r\n        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex\r\n      } else {\r\n        foundIndex = -1\r\n      }\r\n    }\r\n    return -1\r\n  }\r\n\r\n  throw new TypeError('val must be string, number or Buffer')\r\n}\r\n\r\n// `get` is deprecated\r\nBuffer.prototype.get = function get (offset) {\r\n  console.log('.get() is deprecated. Access using array indexes instead.')\r\n  return this.readUInt8(offset)\r\n}\r\n\r\n// `set` is deprecated\r\nBuffer.prototype.set = function set (v, offset) {\r\n  console.log('.set() is deprecated. Access using array indexes instead.')\r\n  return this.writeUInt8(v, offset)\r\n}\r\n\r\nfunction hexWrite (buf, string, offset, length) {\r\n  offset = Number(offset) || 0\r\n  var remaining = buf.length - offset\r\n  if (!length) {\r\n    length = remaining\r\n  } else {\r\n    length = Number(length)\r\n    if (length > remaining) {\r\n      length = remaining\r\n    }\r\n  }\r\n\r\n  // must be an even number of digits\r\n  var strLen = string.length\r\n  if (strLen % 2 !== 0) throw new Error('Invalid hex string')\r\n\r\n  if (length > strLen / 2) {\r\n    length = strLen / 2\r\n  }\r\n  for (var i = 0; i < length; i++) {\r\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\r\n    if (isNaN(parsed)) throw new Error('Invalid hex string')\r\n    buf[offset + i] = parsed\r\n  }\r\n  return i\r\n}\r\n\r\nfunction utf8Write (buf, string, offset, length) {\r\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\r\n}\r\n\r\nfunction asciiWrite (buf, string, offset, length) {\r\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\r\n}\r\n\r\nfunction binaryWrite (buf, string, offset, length) {\r\n  return asciiWrite(buf, string, offset, length)\r\n}\r\n\r\nfunction base64Write (buf, string, offset, length) {\r\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\r\n}\r\n\r\nfunction ucs2Write (buf, string, offset, length) {\r\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\r\n}\r\n\r\nBuffer.prototype.write = function write (string, offset, length, encoding) {\r\n  // Buffer#write(string)\r\n  if (offset === undefined) {\r\n    encoding = 'utf8'\r\n    length = this.length\r\n    offset = 0\r\n  // Buffer#write(string, encoding)\r\n  } else if (length === undefined && typeof offset === 'string') {\r\n    encoding = offset\r\n    length = this.length\r\n    offset = 0\r\n  // Buffer#write(string, offset[, length][, encoding])\r\n  } else if (isFinite(offset)) {\r\n    offset = offset | 0\r\n    if (isFinite(length)) {\r\n      length = length | 0\r\n      if (encoding === undefined) encoding = 'utf8'\r\n    } else {\r\n      encoding = length\r\n      length = undefined\r\n    }\r\n  // legacy write(string, encoding, offset, length) - remove in v0.13\r\n  } else {\r\n    var swap = encoding\r\n    encoding = offset\r\n    offset = length | 0\r\n    length = swap\r\n  }\r\n\r\n  var remaining = this.length - offset\r\n  if (length === undefined || length > remaining) length = remaining\r\n\r\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\r\n    throw new RangeError('attempt to write outside buffer bounds')\r\n  }\r\n\r\n  if (!encoding) encoding = 'utf8'\r\n\r\n  var loweredCase = false\r\n  for (;;) {\r\n    switch (encoding) {\r\n      case 'hex':\r\n        return hexWrite(this, string, offset, length)\r\n\r\n      case 'utf8':\r\n      case 'utf-8':\r\n        return utf8Write(this, string, offset, length)\r\n\r\n      case 'ascii':\r\n        return asciiWrite(this, string, offset, length)\r\n\r\n      case 'binary':\r\n        return binaryWrite(this, string, offset, length)\r\n\r\n      case 'base64':\r\n        // Warning: maxLength not taken into account in base64Write\r\n        return base64Write(this, string, offset, length)\r\n\r\n      case 'ucs2':\r\n      case 'ucs-2':\r\n      case 'utf16le':\r\n      case 'utf-16le':\r\n        return ucs2Write(this, string, offset, length)\r\n\r\n      default:\r\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\r\n        encoding = ('' + encoding).toLowerCase()\r\n        loweredCase = true\r\n    }\r\n  }\r\n}\r\n\r\nBuffer.prototype.toJSON = function toJSON () {\r\n  return {\r\n    type: 'Buffer',\r\n    data: Array.prototype.slice.call(this._arr || this, 0)\r\n  }\r\n}\r\n\r\nfunction base64Slice (buf, start, end) {\r\n  if (start === 0 && end === buf.length) {\r\n    return base64.fromByteArray(buf)\r\n  } else {\r\n    return base64.fromByteArray(buf.slice(start, end))\r\n  }\r\n}\r\n\r\nfunction utf8Slice (buf, start, end) {\r\n  end = Math.min(buf.length, end)\r\n  var res = []\r\n\r\n  var i = start\r\n  while (i < end) {\r\n    var firstByte = buf[i]\r\n    var codePoint = null\r\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\r\n      : (firstByte > 0xDF) ? 3\r\n      : (firstByte > 0xBF) ? 2\r\n      : 1\r\n\r\n    if (i + bytesPerSequence <= end) {\r\n      var secondByte, thirdByte, fourthByte, tempCodePoint\r\n\r\n      switch (bytesPerSequence) {\r\n        case 1:\r\n          if (firstByte < 0x80) {\r\n            codePoint = firstByte\r\n          }\r\n          break\r\n        case 2:\r\n          secondByte = buf[i + 1]\r\n          if ((secondByte & 0xC0) === 0x80) {\r\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\r\n            if (tempCodePoint > 0x7F) {\r\n              codePoint = tempCodePoint\r\n            }\r\n          }\r\n          break\r\n        case 3:\r\n          secondByte = buf[i + 1]\r\n          thirdByte = buf[i + 2]\r\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\r\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\r\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\r\n              codePoint = tempCodePoint\r\n            }\r\n          }\r\n          break\r\n        case 4:\r\n          secondByte = buf[i + 1]\r\n          thirdByte = buf[i + 2]\r\n          fourthByte = buf[i + 3]\r\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\r\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\r\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\r\n              codePoint = tempCodePoint\r\n            }\r\n          }\r\n      }\r\n    }\r\n\r\n    if (codePoint === null) {\r\n      // we did not generate a valid codePoint so insert a\r\n      // replacement char (U+FFFD) and advance only 1 byte\r\n      codePoint = 0xFFFD\r\n      bytesPerSequence = 1\r\n    } else if (codePoint > 0xFFFF) {\r\n      // encode to utf16 (surrogate pair dance)\r\n      codePoint -= 0x10000\r\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\r\n      codePoint = 0xDC00 | codePoint & 0x3FF\r\n    }\r\n\r\n    res.push(codePoint)\r\n    i += bytesPerSequence\r\n  }\r\n\r\n  return decodeCodePointsArray(res)\r\n}\r\n\r\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\r\n// the lowest limit is Chrome, with 0x10000 args.\r\n// We go 1 magnitude less, for safety\r\nvar MAX_ARGUMENTS_LENGTH = 0x1000\r\n\r\nfunction decodeCodePointsArray (codePoints) {\r\n  var len = codePoints.length\r\n  if (len <= MAX_ARGUMENTS_LENGTH) {\r\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\r\n  }\r\n\r\n  // Decode in chunks to avoid \"call stack size exceeded\".\r\n  var res = ''\r\n  var i = 0\r\n  while (i < len) {\r\n    res += String.fromCharCode.apply(\r\n      String,\r\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\r\n    )\r\n  }\r\n  return res\r\n}\r\n\r\nfunction asciiSlice (buf, start, end) {\r\n  var ret = ''\r\n  end = Math.min(buf.length, end)\r\n\r\n  for (var i = start; i < end; i++) {\r\n    ret += String.fromCharCode(buf[i] & 0x7F)\r\n  }\r\n  return ret\r\n}\r\n\r\nfunction binarySlice (buf, start, end) {\r\n  var ret = ''\r\n  end = Math.min(buf.length, end)\r\n\r\n  for (var i = start; i < end; i++) {\r\n    ret += String.fromCharCode(buf[i])\r\n  }\r\n  return ret\r\n}\r\n\r\nfunction hexSlice (buf, start, end) {\r\n  var len = buf.length\r\n\r\n  if (!start || start < 0) start = 0\r\n  if (!end || end < 0 || end > len) end = len\r\n\r\n  var out = ''\r\n  for (var i = start; i < end; i++) {\r\n    out += toHex(buf[i])\r\n  }\r\n  return out\r\n}\r\n\r\nfunction utf16leSlice (buf, start, end) {\r\n  var bytes = buf.slice(start, end)\r\n  var res = ''\r\n  for (var i = 0; i < bytes.length; i += 2) {\r\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\r\n  }\r\n  return res\r\n}\r\n\r\nBuffer.prototype.slice = function slice (start, end) {\r\n  var len = this.length\r\n  start = ~~start\r\n  end = end === undefined ? len : ~~end\r\n\r\n  if (start < 0) {\r\n    start += len\r\n    if (start < 0) start = 0\r\n  } else if (start > len) {\r\n    start = len\r\n  }\r\n\r\n  if (end < 0) {\r\n    end += len\r\n    if (end < 0) end = 0\r\n  } else if (end > len) {\r\n    end = len\r\n  }\r\n\r\n  if (end < start) end = start\r\n\r\n  var newBuf\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    newBuf = Buffer._augment(this.subarray(start, end))\r\n  } else {\r\n    var sliceLen = end - start\r\n    newBuf = new Buffer(sliceLen, undefined)\r\n    for (var i = 0; i < sliceLen; i++) {\r\n      newBuf[i] = this[i + start]\r\n    }\r\n  }\r\n\r\n  if (newBuf.length) newBuf.parent = this.parent || this\r\n\r\n  return newBuf\r\n}\r\n\r\n/*\r\n * Need to make sure that buffer isn't trying to write out of bounds.\r\n */\r\nfunction checkOffset (offset, ext, length) {\r\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\r\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\r\n}\r\n\r\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\r\n  offset = offset | 0\r\n  byteLength = byteLength | 0\r\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\r\n\r\n  var val = this[offset]\r\n  var mul = 1\r\n  var i = 0\r\n  while (++i < byteLength && (mul *= 0x100)) {\r\n    val += this[offset + i] * mul\r\n  }\r\n\r\n  return val\r\n}\r\n\r\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\r\n  offset = offset | 0\r\n  byteLength = byteLength | 0\r\n  if (!noAssert) {\r\n    checkOffset(offset, byteLength, this.length)\r\n  }\r\n\r\n  var val = this[offset + --byteLength]\r\n  var mul = 1\r\n  while (byteLength > 0 && (mul *= 0x100)) {\r\n    val += this[offset + --byteLength] * mul\r\n  }\r\n\r\n  return val\r\n}\r\n\r\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 1, this.length)\r\n  return this[offset]\r\n}\r\n\r\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 2, this.length)\r\n  return this[offset] | (this[offset + 1] << 8)\r\n}\r\n\r\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 2, this.length)\r\n  return (this[offset] << 8) | this[offset + 1]\r\n}\r\n\r\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 4, this.length)\r\n\r\n  return ((this[offset]) |\r\n      (this[offset + 1] << 8) |\r\n      (this[offset + 2] << 16)) +\r\n      (this[offset + 3] * 0x1000000)\r\n}\r\n\r\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 4, this.length)\r\n\r\n  return (this[offset] * 0x1000000) +\r\n    ((this[offset + 1] << 16) |\r\n    (this[offset + 2] << 8) |\r\n    this[offset + 3])\r\n}\r\n\r\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\r\n  offset = offset | 0\r\n  byteLength = byteLength | 0\r\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\r\n\r\n  var val = this[offset]\r\n  var mul = 1\r\n  var i = 0\r\n  while (++i < byteLength && (mul *= 0x100)) {\r\n    val += this[offset + i] * mul\r\n  }\r\n  mul *= 0x80\r\n\r\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\r\n\r\n  return val\r\n}\r\n\r\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\r\n  offset = offset | 0\r\n  byteLength = byteLength | 0\r\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\r\n\r\n  var i = byteLength\r\n  var mul = 1\r\n  var val = this[offset + --i]\r\n  while (i > 0 && (mul *= 0x100)) {\r\n    val += this[offset + --i] * mul\r\n  }\r\n  mul *= 0x80\r\n\r\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\r\n\r\n  return val\r\n}\r\n\r\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 1, this.length)\r\n  if (!(this[offset] & 0x80)) return (this[offset])\r\n  return ((0xff - this[offset] + 1) * -1)\r\n}\r\n\r\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 2, this.length)\r\n  var val = this[offset] | (this[offset + 1] << 8)\r\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\r\n}\r\n\r\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 2, this.length)\r\n  var val = this[offset + 1] | (this[offset] << 8)\r\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\r\n}\r\n\r\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 4, this.length)\r\n\r\n  return (this[offset]) |\r\n    (this[offset + 1] << 8) |\r\n    (this[offset + 2] << 16) |\r\n    (this[offset + 3] << 24)\r\n}\r\n\r\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 4, this.length)\r\n\r\n  return (this[offset] << 24) |\r\n    (this[offset + 1] << 16) |\r\n    (this[offset + 2] << 8) |\r\n    (this[offset + 3])\r\n}\r\n\r\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 4, this.length)\r\n  return ieee754.read(this, offset, true, 23, 4)\r\n}\r\n\r\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 4, this.length)\r\n  return ieee754.read(this, offset, false, 23, 4)\r\n}\r\n\r\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 8, this.length)\r\n  return ieee754.read(this, offset, true, 52, 8)\r\n}\r\n\r\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\r\n  if (!noAssert) checkOffset(offset, 8, this.length)\r\n  return ieee754.read(this, offset, false, 52, 8)\r\n}\r\n\r\nfunction checkInt (buf, value, offset, ext, max, min) {\r\n  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')\r\n  if (value > max || value < min) throw new RangeError('value is out of bounds')\r\n  if (offset + ext > buf.length) throw new RangeError('index out of range')\r\n}\r\n\r\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  byteLength = byteLength | 0\r\n  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\r\n\r\n  var mul = 1\r\n  var i = 0\r\n  this[offset] = value & 0xFF\r\n  while (++i < byteLength && (mul *= 0x100)) {\r\n    this[offset + i] = (value / mul) & 0xFF\r\n  }\r\n\r\n  return offset + byteLength\r\n}\r\n\r\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  byteLength = byteLength | 0\r\n  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)\r\n\r\n  var i = byteLength - 1\r\n  var mul = 1\r\n  this[offset + i] = value & 0xFF\r\n  while (--i >= 0 && (mul *= 0x100)) {\r\n    this[offset + i] = (value / mul) & 0xFF\r\n  }\r\n\r\n  return offset + byteLength\r\n}\r\n\r\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\r\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\r\n  this[offset] = value\r\n  return offset + 1\r\n}\r\n\r\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\r\n  if (value < 0) value = 0xffff + value + 1\r\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {\r\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\r\n      (littleEndian ? i : 1 - i) * 8\r\n  }\r\n}\r\n\r\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset] = value\r\n    this[offset + 1] = (value >>> 8)\r\n  } else {\r\n    objectWriteUInt16(this, value, offset, true)\r\n  }\r\n  return offset + 2\r\n}\r\n\r\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset] = (value >>> 8)\r\n    this[offset + 1] = value\r\n  } else {\r\n    objectWriteUInt16(this, value, offset, false)\r\n  }\r\n  return offset + 2\r\n}\r\n\r\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\r\n  if (value < 0) value = 0xffffffff + value + 1\r\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {\r\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\r\n  }\r\n}\r\n\r\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset + 3] = (value >>> 24)\r\n    this[offset + 2] = (value >>> 16)\r\n    this[offset + 1] = (value >>> 8)\r\n    this[offset] = value\r\n  } else {\r\n    objectWriteUInt32(this, value, offset, true)\r\n  }\r\n  return offset + 4\r\n}\r\n\r\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset] = (value >>> 24)\r\n    this[offset + 1] = (value >>> 16)\r\n    this[offset + 2] = (value >>> 8)\r\n    this[offset + 3] = value\r\n  } else {\r\n    objectWriteUInt32(this, value, offset, false)\r\n  }\r\n  return offset + 4\r\n}\r\n\r\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) {\r\n    var limit = Math.pow(2, 8 * byteLength - 1)\r\n\r\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\r\n  }\r\n\r\n  var i = 0\r\n  var mul = 1\r\n  var sub = value < 0 ? 1 : 0\r\n  this[offset] = value & 0xFF\r\n  while (++i < byteLength && (mul *= 0x100)) {\r\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\r\n  }\r\n\r\n  return offset + byteLength\r\n}\r\n\r\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) {\r\n    var limit = Math.pow(2, 8 * byteLength - 1)\r\n\r\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\r\n  }\r\n\r\n  var i = byteLength - 1\r\n  var mul = 1\r\n  var sub = value < 0 ? 1 : 0\r\n  this[offset + i] = value & 0xFF\r\n  while (--i >= 0 && (mul *= 0x100)) {\r\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\r\n  }\r\n\r\n  return offset + byteLength\r\n}\r\n\r\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\r\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\r\n  if (value < 0) value = 0xff + value + 1\r\n  this[offset] = value\r\n  return offset + 1\r\n}\r\n\r\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset] = value\r\n    this[offset + 1] = (value >>> 8)\r\n  } else {\r\n    objectWriteUInt16(this, value, offset, true)\r\n  }\r\n  return offset + 2\r\n}\r\n\r\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset] = (value >>> 8)\r\n    this[offset + 1] = value\r\n  } else {\r\n    objectWriteUInt16(this, value, offset, false)\r\n  }\r\n  return offset + 2\r\n}\r\n\r\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset] = value\r\n    this[offset + 1] = (value >>> 8)\r\n    this[offset + 2] = (value >>> 16)\r\n    this[offset + 3] = (value >>> 24)\r\n  } else {\r\n    objectWriteUInt32(this, value, offset, true)\r\n  }\r\n  return offset + 4\r\n}\r\n\r\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\r\n  value = +value\r\n  offset = offset | 0\r\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\r\n  if (value < 0) value = 0xffffffff + value + 1\r\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n    this[offset] = (value >>> 24)\r\n    this[offset + 1] = (value >>> 16)\r\n    this[offset + 2] = (value >>> 8)\r\n    this[offset + 3] = value\r\n  } else {\r\n    objectWriteUInt32(this, value, offset, false)\r\n  }\r\n  return offset + 4\r\n}\r\n\r\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\r\n  if (value > max || value < min) throw new RangeError('value is out of bounds')\r\n  if (offset + ext > buf.length) throw new RangeError('index out of range')\r\n  if (offset < 0) throw new RangeError('index out of range')\r\n}\r\n\r\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\r\n  if (!noAssert) {\r\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\r\n  }\r\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\r\n  return offset + 4\r\n}\r\n\r\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\r\n  return writeFloat(this, value, offset, true, noAssert)\r\n}\r\n\r\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\r\n  return writeFloat(this, value, offset, false, noAssert)\r\n}\r\n\r\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\r\n  if (!noAssert) {\r\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\r\n  }\r\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\r\n  return offset + 8\r\n}\r\n\r\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\r\n  return writeDouble(this, value, offset, true, noAssert)\r\n}\r\n\r\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\r\n  return writeDouble(this, value, offset, false, noAssert)\r\n}\r\n\r\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\r\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\r\n  if (!start) start = 0\r\n  if (!end && end !== 0) end = this.length\r\n  if (targetStart >= target.length) targetStart = target.length\r\n  if (!targetStart) targetStart = 0\r\n  if (end > 0 && end < start) end = start\r\n\r\n  // Copy 0 bytes; we're done\r\n  if (end === start) return 0\r\n  if (target.length === 0 || this.length === 0) return 0\r\n\r\n  // Fatal error conditions\r\n  if (targetStart < 0) {\r\n    throw new RangeError('targetStart out of bounds')\r\n  }\r\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\r\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\r\n\r\n  // Are we oob?\r\n  if (end > this.length) end = this.length\r\n  if (target.length - targetStart < end - start) {\r\n    end = target.length - targetStart + start\r\n  }\r\n\r\n  var len = end - start\r\n  var i\r\n\r\n  if (this === target && start < targetStart && targetStart < end) {\r\n    // descending copy from end\r\n    for (i = len - 1; i >= 0; i--) {\r\n      target[i + targetStart] = this[i + start]\r\n    }\r\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\r\n    // ascending copy from start\r\n    for (i = 0; i < len; i++) {\r\n      target[i + targetStart] = this[i + start]\r\n    }\r\n  } else {\r\n    target._set(this.subarray(start, start + len), targetStart)\r\n  }\r\n\r\n  return len\r\n}\r\n\r\n// fill(value, start=0, end=buffer.length)\r\nBuffer.prototype.fill = function fill (value, start, end) {\r\n  if (!value) value = 0\r\n  if (!start) start = 0\r\n  if (!end) end = this.length\r\n\r\n  if (end < start) throw new RangeError('end < start')\r\n\r\n  // Fill 0 bytes; we're done\r\n  if (end === start) return\r\n  if (this.length === 0) return\r\n\r\n  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')\r\n  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')\r\n\r\n  var i\r\n  if (typeof value === 'number') {\r\n    for (i = start; i < end; i++) {\r\n      this[i] = value\r\n    }\r\n  } else {\r\n    var bytes = utf8ToBytes(value.toString())\r\n    var len = bytes.length\r\n    for (i = start; i < end; i++) {\r\n      this[i] = bytes[i % len]\r\n    }\r\n  }\r\n\r\n  return this\r\n}\r\n\r\n/**\r\n * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.\r\n * Added in Node 0.12. Only available in browsers that support ArrayBuffer.\r\n */\r\nBuffer.prototype.toArrayBuffer = function toArrayBuffer () {\r\n  if (typeof Uint8Array !== 'undefined') {\r\n    if (Buffer.TYPED_ARRAY_SUPPORT) {\r\n      return (new Buffer(this)).buffer\r\n    } else {\r\n      var buf = new Uint8Array(this.length)\r\n      for (var i = 0, len = buf.length; i < len; i += 1) {\r\n        buf[i] = this[i]\r\n      }\r\n      return buf.buffer\r\n    }\r\n  } else {\r\n    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')\r\n  }\r\n}\r\n\r\n// HELPER FUNCTIONS\r\n// ================\r\n\r\nvar BP = Buffer.prototype\r\n\r\n/**\r\n * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods\r\n */\r\nBuffer._augment = function _augment (arr) {\r\n  arr.constructor = Buffer\r\n  arr._isBuffer = true\r\n\r\n  // save reference to original Uint8Array set method before overwriting\r\n  arr._set = arr.set\r\n\r\n  // deprecated\r\n  arr.get = BP.get\r\n  arr.set = BP.set\r\n\r\n  arr.write = BP.write\r\n  arr.toString = BP.toString\r\n  arr.toLocaleString = BP.toString\r\n  arr.toJSON = BP.toJSON\r\n  arr.equals = BP.equals\r\n  arr.compare = BP.compare\r\n  arr.indexOf = BP.indexOf\r\n  arr.copy = BP.copy\r\n  arr.slice = BP.slice\r\n  arr.readUIntLE = BP.readUIntLE\r\n  arr.readUIntBE = BP.readUIntBE\r\n  arr.readUInt8 = BP.readUInt8\r\n  arr.readUInt16LE = BP.readUInt16LE\r\n  arr.readUInt16BE = BP.readUInt16BE\r\n  arr.readUInt32LE = BP.readUInt32LE\r\n  arr.readUInt32BE = BP.readUInt32BE\r\n  arr.readIntLE = BP.readIntLE\r\n  arr.readIntBE = BP.readIntBE\r\n  arr.readInt8 = BP.readInt8\r\n  arr.readInt16LE = BP.readInt16LE\r\n  arr.readInt16BE = BP.readInt16BE\r\n  arr.readInt32LE = BP.readInt32LE\r\n  arr.readInt32BE = BP.readInt32BE\r\n  arr.readFloatLE = BP.readFloatLE\r\n  arr.readFloatBE = BP.readFloatBE\r\n  arr.readDoubleLE = BP.readDoubleLE\r\n  arr.readDoubleBE = BP.readDoubleBE\r\n  arr.writeUInt8 = BP.writeUInt8\r\n  arr.writeUIntLE = BP.writeUIntLE\r\n  arr.writeUIntBE = BP.writeUIntBE\r\n  arr.writeUInt16LE = BP.writeUInt16LE\r\n  arr.writeUInt16BE = BP.writeUInt16BE\r\n  arr.writeUInt32LE = BP.writeUInt32LE\r\n  arr.writeUInt32BE = BP.writeUInt32BE\r\n  arr.writeIntLE = BP.writeIntLE\r\n  arr.writeIntBE = BP.writeIntBE\r\n  arr.writeInt8 = BP.writeInt8\r\n  arr.writeInt16LE = BP.writeInt16LE\r\n  arr.writeInt16BE = BP.writeInt16BE\r\n  arr.writeInt32LE = BP.writeInt32LE\r\n  arr.writeInt32BE = BP.writeInt32BE\r\n  arr.writeFloatLE = BP.writeFloatLE\r\n  arr.writeFloatBE = BP.writeFloatBE\r\n  arr.writeDoubleLE = BP.writeDoubleLE\r\n  arr.writeDoubleBE = BP.writeDoubleBE\r\n  arr.fill = BP.fill\r\n  arr.inspect = BP.inspect\r\n  arr.toArrayBuffer = BP.toArrayBuffer\r\n\r\n  return arr\r\n}\r\n\r\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\r\n\r\nfunction base64clean (str) {\r\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\r\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\r\n  // Node converts strings with length < 2 to ''\r\n  if (str.length < 2) return ''\r\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\r\n  while (str.length % 4 !== 0) {\r\n    str = str + '='\r\n  }\r\n  return str\r\n}\r\n\r\nfunction stringtrim (str) {\r\n  if (str.trim) return str.trim()\r\n  return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nfunction toHex (n) {\r\n  if (n < 16) return '0' + n.toString(16)\r\n  return n.toString(16)\r\n}\r\n\r\nfunction utf8ToBytes (string, units) {\r\n  units = units || Infinity\r\n  var codePoint\r\n  var length = string.length\r\n  var leadSurrogate = null\r\n  var bytes = []\r\n\r\n  for (var i = 0; i < length; i++) {\r\n    codePoint = string.charCodeAt(i)\r\n\r\n    // is surrogate component\r\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\r\n      // last char was a lead\r\n      if (!leadSurrogate) {\r\n        // no lead yet\r\n        if (codePoint > 0xDBFF) {\r\n          // unexpected trail\r\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r\n          continue\r\n        } else if (i + 1 === length) {\r\n          // unpaired lead\r\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r\n          continue\r\n        }\r\n\r\n        // valid lead\r\n        leadSurrogate = codePoint\r\n\r\n        continue\r\n      }\r\n\r\n      // 2 leads in a row\r\n      if (codePoint < 0xDC00) {\r\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r\n        leadSurrogate = codePoint\r\n        continue\r\n      }\r\n\r\n      // valid surrogate pair\r\n      codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000\r\n    } else if (leadSurrogate) {\r\n      // valid bmp char, but last char was a lead\r\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\r\n    }\r\n\r\n    leadSurrogate = null\r\n\r\n    // encode utf8\r\n    if (codePoint < 0x80) {\r\n      if ((units -= 1) < 0) break\r\n      bytes.push(codePoint)\r\n    } else if (codePoint < 0x800) {\r\n      if ((units -= 2) < 0) break\r\n      bytes.push(\r\n        codePoint >> 0x6 | 0xC0,\r\n        codePoint & 0x3F | 0x80\r\n      )\r\n    } else if (codePoint < 0x10000) {\r\n      if ((units -= 3) < 0) break\r\n      bytes.push(\r\n        codePoint >> 0xC | 0xE0,\r\n        codePoint >> 0x6 & 0x3F | 0x80,\r\n        codePoint & 0x3F | 0x80\r\n      )\r\n    } else if (codePoint < 0x110000) {\r\n      if ((units -= 4) < 0) break\r\n      bytes.push(\r\n        codePoint >> 0x12 | 0xF0,\r\n        codePoint >> 0xC & 0x3F | 0x80,\r\n        codePoint >> 0x6 & 0x3F | 0x80,\r\n        codePoint & 0x3F | 0x80\r\n      )\r\n    } else {\r\n      throw new Error('Invalid code point')\r\n    }\r\n  }\r\n\r\n  return bytes\r\n}\r\n\r\nfunction asciiToBytes (str) {\r\n  var byteArray = []\r\n  for (var i = 0; i < str.length; i++) {\r\n    // Node's code seems to be doing this and not & 0x7F..\r\n    byteArray.push(str.charCodeAt(i) & 0xFF)\r\n  }\r\n  return byteArray\r\n}\r\n\r\nfunction utf16leToBytes (str, units) {\r\n  var c, hi, lo\r\n  var byteArray = []\r\n  for (var i = 0; i < str.length; i++) {\r\n    if ((units -= 2) < 0) break\r\n\r\n    c = str.charCodeAt(i)\r\n    hi = c >> 8\r\n    lo = c % 256\r\n    byteArray.push(lo)\r\n    byteArray.push(hi)\r\n  }\r\n\r\n  return byteArray\r\n}\r\n\r\nfunction base64ToBytes (str) {\r\n  return base64.toByteArray(base64clean(str))\r\n}\r\n\r\nfunction blitBuffer (src, dst, offset, length) {\r\n  for (var i = 0; i < length; i++) {\r\n    if ((i + offset >= dst.length) || (i >= src.length)) break\r\n    dst[i + offset] = src[i]\r\n  }\r\n  return i\r\n}\r\n\r\n},{\"base64-js\":44,\"ieee754\":45,\"is-array\":46}],44:[function(require,module,exports){\r\nvar lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\r\n\r\n;(function (exports) {\r\n\t'use strict';\r\n\r\n  var Arr = (typeof Uint8Array !== 'undefined')\r\n    ? Uint8Array\r\n    : Array\r\n\r\n\tvar PLUS   = '+'.charCodeAt(0)\r\n\tvar SLASH  = '/'.charCodeAt(0)\r\n\tvar NUMBER = '0'.charCodeAt(0)\r\n\tvar LOWER  = 'a'.charCodeAt(0)\r\n\tvar UPPER  = 'A'.charCodeAt(0)\r\n\tvar PLUS_URL_SAFE = '-'.charCodeAt(0)\r\n\tvar SLASH_URL_SAFE = '_'.charCodeAt(0)\r\n\r\n\tfunction decode (elt) {\r\n\t\tvar code = elt.charCodeAt(0)\r\n\t\tif (code === PLUS ||\r\n\t\t    code === PLUS_URL_SAFE)\r\n\t\t\treturn 62 // '+'\r\n\t\tif (code === SLASH ||\r\n\t\t    code === SLASH_URL_SAFE)\r\n\t\t\treturn 63 // '/'\r\n\t\tif (code < NUMBER)\r\n\t\t\treturn -1 //no match\r\n\t\tif (code < NUMBER + 10)\r\n\t\t\treturn code - NUMBER + 26 + 26\r\n\t\tif (code < UPPER + 26)\r\n\t\t\treturn code - UPPER\r\n\t\tif (code < LOWER + 26)\r\n\t\t\treturn code - LOWER + 26\r\n\t}\r\n\r\n\tfunction b64ToByteArray (b64) {\r\n\t\tvar i, j, l, tmp, placeHolders, arr\r\n\r\n\t\tif (b64.length % 4 > 0) {\r\n\t\t\tthrow new Error('Invalid string. Length must be a multiple of 4')\r\n\t\t}\r\n\r\n\t\t// the number of equal signs (place holders)\r\n\t\t// if there are two placeholders, than the two characters before it\r\n\t\t// represent one byte\r\n\t\t// if there is only one, then the three characters before it represent 2 bytes\r\n\t\t// this is just a cheap hack to not do indexOf twice\r\n\t\tvar len = b64.length\r\n\t\tplaceHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0\r\n\r\n\t\t// base64 is 4/3 + up to two characters of the original data\r\n\t\tarr = new Arr(b64.length * 3 / 4 - placeHolders)\r\n\r\n\t\t// if there are placeholders, only get up to the last complete 4 chars\r\n\t\tl = placeHolders > 0 ? b64.length - 4 : b64.length\r\n\r\n\t\tvar L = 0\r\n\r\n\t\tfunction push (v) {\r\n\t\t\tarr[L++] = v\r\n\t\t}\r\n\r\n\t\tfor (i = 0, j = 0; i < l; i += 4, j += 3) {\r\n\t\t\ttmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))\r\n\t\t\tpush((tmp & 0xFF0000) >> 16)\r\n\t\t\tpush((tmp & 0xFF00) >> 8)\r\n\t\t\tpush(tmp & 0xFF)\r\n\t\t}\r\n\r\n\t\tif (placeHolders === 2) {\r\n\t\t\ttmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)\r\n\t\t\tpush(tmp & 0xFF)\r\n\t\t} else if (placeHolders === 1) {\r\n\t\t\ttmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)\r\n\t\t\tpush((tmp >> 8) & 0xFF)\r\n\t\t\tpush(tmp & 0xFF)\r\n\t\t}\r\n\r\n\t\treturn arr\r\n\t}\r\n\r\n\tfunction uint8ToBase64 (uint8) {\r\n\t\tvar i,\r\n\t\t\textraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes\r\n\t\t\toutput = \"\",\r\n\t\t\ttemp, length\r\n\r\n\t\tfunction encode (num) {\r\n\t\t\treturn lookup.charAt(num)\r\n\t\t}\r\n\r\n\t\tfunction tripletToBase64 (num) {\r\n\t\t\treturn encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)\r\n\t\t}\r\n\r\n\t\t// go through the array every three bytes, we'll deal with trailing stuff later\r\n\t\tfor (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {\r\n\t\t\ttemp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])\r\n\t\t\toutput += tripletToBase64(temp)\r\n\t\t}\r\n\r\n\t\t// pad the end with zeros, but make sure to not forget the extra bytes\r\n\t\tswitch (extraBytes) {\r\n\t\t\tcase 1:\r\n\t\t\t\ttemp = uint8[uint8.length - 1]\r\n\t\t\t\toutput += encode(temp >> 2)\r\n\t\t\t\toutput += encode((temp << 4) & 0x3F)\r\n\t\t\t\toutput += '=='\r\n\t\t\t\tbreak\r\n\t\t\tcase 2:\r\n\t\t\t\ttemp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])\r\n\t\t\t\toutput += encode(temp >> 10)\r\n\t\t\t\toutput += encode((temp >> 4) & 0x3F)\r\n\t\t\t\toutput += encode((temp << 2) & 0x3F)\r\n\t\t\t\toutput += '='\r\n\t\t\t\tbreak\r\n\t\t}\r\n\r\n\t\treturn output\r\n\t}\r\n\r\n\texports.toByteArray = b64ToByteArray\r\n\texports.fromByteArray = uint8ToBase64\r\n}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))\r\n\r\n},{}],45:[function(require,module,exports){\r\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\r\n  var e, m\r\n  var eLen = nBytes * 8 - mLen - 1\r\n  var eMax = (1 << eLen) - 1\r\n  var eBias = eMax >> 1\r\n  var nBits = -7\r\n  var i = isLE ? (nBytes - 1) : 0\r\n  var d = isLE ? -1 : 1\r\n  var s = buffer[offset + i]\r\n\r\n  i += d\r\n\r\n  e = s & ((1 << (-nBits)) - 1)\r\n  s >>= (-nBits)\r\n  nBits += eLen\r\n  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\r\n\r\n  m = e & ((1 << (-nBits)) - 1)\r\n  e >>= (-nBits)\r\n  nBits += mLen\r\n  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\r\n\r\n  if (e === 0) {\r\n    e = 1 - eBias\r\n  } else if (e === eMax) {\r\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\r\n  } else {\r\n    m = m + Math.pow(2, mLen)\r\n    e = e - eBias\r\n  }\r\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\r\n}\r\n\r\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\r\n  var e, m, c\r\n  var eLen = nBytes * 8 - mLen - 1\r\n  var eMax = (1 << eLen) - 1\r\n  var eBias = eMax >> 1\r\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\r\n  var i = isLE ? 0 : (nBytes - 1)\r\n  var d = isLE ? 1 : -1\r\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\r\n\r\n  value = Math.abs(value)\r\n\r\n  if (isNaN(value) || value === Infinity) {\r\n    m = isNaN(value) ? 1 : 0\r\n    e = eMax\r\n  } else {\r\n    e = Math.floor(Math.log(value) / Math.LN2)\r\n    if (value * (c = Math.pow(2, -e)) < 1) {\r\n      e--\r\n      c *= 2\r\n    }\r\n    if (e + eBias >= 1) {\r\n      value += rt / c\r\n    } else {\r\n      value += rt * Math.pow(2, 1 - eBias)\r\n    }\r\n    if (value * c >= 2) {\r\n      e++\r\n      c /= 2\r\n    }\r\n\r\n    if (e + eBias >= eMax) {\r\n      m = 0\r\n      e = eMax\r\n    } else if (e + eBias >= 1) {\r\n      m = (value * c - 1) * Math.pow(2, mLen)\r\n      e = e + eBias\r\n    } else {\r\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\r\n      e = 0\r\n    }\r\n  }\r\n\r\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\r\n\r\n  e = (e << mLen) | m\r\n  eLen += mLen\r\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\r\n\r\n  buffer[offset + i - d] |= s * 128\r\n}\r\n\r\n},{}],46:[function(require,module,exports){\r\n\r\n/**\r\n * isArray\r\n */\r\n\r\nvar isArray = Array.isArray;\r\n\r\n/**\r\n * toString\r\n */\r\n\r\nvar str = Object.prototype.toString;\r\n\r\n/**\r\n * Whether or not the given `val`\r\n * is an array.\r\n *\r\n * example:\r\n *\r\n *        isArray([]);\r\n *        // > true\r\n *        isArray(arguments);\r\n *        // > false\r\n *        isArray('');\r\n *        // > false\r\n *\r\n * @param {mixed} val\r\n * @return {bool}\r\n */\r\n\r\nmodule.exports = isArray || function (val) {\r\n  return !! val && '[object Array]' == str.call(val);\r\n};\r\n\r\n},{}],47:[function(require,module,exports){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\nfunction EventEmitter() {\r\n  this._events = this._events || {};\r\n  this._maxListeners = this._maxListeners || undefined;\r\n}\r\nmodule.exports = EventEmitter;\r\n\r\n// Backwards-compat with node 0.10.x\r\nEventEmitter.EventEmitter = EventEmitter;\r\n\r\nEventEmitter.prototype._events = undefined;\r\nEventEmitter.prototype._maxListeners = undefined;\r\n\r\n// By default EventEmitters will print a warning if more than 10 listeners are\r\n// added to it. This is a useful default which helps finding memory leaks.\r\nEventEmitter.defaultMaxListeners = 10;\r\n\r\n// Obviously not all Emitters should be limited to 10. This function allows\r\n// that to be increased. Set to zero for unlimited.\r\nEventEmitter.prototype.setMaxListeners = function(n) {\r\n  if (!isNumber(n) || n < 0 || isNaN(n))\r\n    throw TypeError('n must be a positive number');\r\n  this._maxListeners = n;\r\n  return this;\r\n};\r\n\r\nEventEmitter.prototype.emit = function(type) {\r\n  var er, handler, len, args, i, listeners;\r\n\r\n  if (!this._events)\r\n    this._events = {};\r\n\r\n  // If there is no 'error' event listener then throw.\r\n  if (type === 'error') {\r\n    if (!this._events.error ||\r\n        (isObject(this._events.error) && !this._events.error.length)) {\r\n      er = arguments[1];\r\n      if (er instanceof Error) {\r\n        throw er; // Unhandled 'error' event\r\n      }\r\n      throw TypeError('Uncaught, unspecified \"error\" event.');\r\n    }\r\n  }\r\n\r\n  handler = this._events[type];\r\n\r\n  if (isUndefined(handler))\r\n    return false;\r\n\r\n  if (isFunction(handler)) {\r\n    switch (arguments.length) {\r\n      // fast cases\r\n      case 1:\r\n        handler.call(this);\r\n        break;\r\n      case 2:\r\n        handler.call(this, arguments[1]);\r\n        break;\r\n      case 3:\r\n        handler.call(this, arguments[1], arguments[2]);\r\n        break;\r\n      // slower\r\n      default:\r\n        len = arguments.length;\r\n        args = new Array(len - 1);\r\n        for (i = 1; i < len; i++)\r\n          args[i - 1] = arguments[i];\r\n        handler.apply(this, args);\r\n    }\r\n  } else if (isObject(handler)) {\r\n    len = arguments.length;\r\n    args = new Array(len - 1);\r\n    for (i = 1; i < len; i++)\r\n      args[i - 1] = arguments[i];\r\n\r\n    listeners = handler.slice();\r\n    len = listeners.length;\r\n    for (i = 0; i < len; i++)\r\n      listeners[i].apply(this, args);\r\n  }\r\n\r\n  return true;\r\n};\r\n\r\nEventEmitter.prototype.addListener = function(type, listener) {\r\n  var m;\r\n\r\n  if (!isFunction(listener))\r\n    throw TypeError('listener must be a function');\r\n\r\n  if (!this._events)\r\n    this._events = {};\r\n\r\n  // To avoid recursion in the case that type === \"newListener\"! Before\r\n  // adding it to the listeners, first emit \"newListener\".\r\n  if (this._events.newListener)\r\n    this.emit('newListener', type,\r\n              isFunction(listener.listener) ?\r\n              listener.listener : listener);\r\n\r\n  if (!this._events[type])\r\n    // Optimize the case of one listener. Don't need the extra array object.\r\n    this._events[type] = listener;\r\n  else if (isObject(this._events[type]))\r\n    // If we've already got an array, just append.\r\n    this._events[type].push(listener);\r\n  else\r\n    // Adding the second element, need to change to array.\r\n    this._events[type] = [this._events[type], listener];\r\n\r\n  // Check for listener leak\r\n  if (isObject(this._events[type]) && !this._events[type].warned) {\r\n    var m;\r\n    if (!isUndefined(this._maxListeners)) {\r\n      m = this._maxListeners;\r\n    } else {\r\n      m = EventEmitter.defaultMaxListeners;\r\n    }\r\n\r\n    if (m && m > 0 && this._events[type].length > m) {\r\n      this._events[type].warned = true;\r\n      console.error('(node) warning: possible EventEmitter memory ' +\r\n                    'leak detected. %d listeners added. ' +\r\n                    'Use emitter.setMaxListeners() to increase limit.',\r\n                    this._events[type].length);\r\n      if (typeof console.trace === 'function') {\r\n        // not supported in IE 10\r\n        console.trace();\r\n      }\r\n    }\r\n  }\r\n\r\n  return this;\r\n};\r\n\r\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\r\n\r\nEventEmitter.prototype.once = function(type, listener) {\r\n  if (!isFunction(listener))\r\n    throw TypeError('listener must be a function');\r\n\r\n  var fired = false;\r\n\r\n  function g() {\r\n    this.removeListener(type, g);\r\n\r\n    if (!fired) {\r\n      fired = true;\r\n      listener.apply(this, arguments);\r\n    }\r\n  }\r\n\r\n  g.listener = listener;\r\n  this.on(type, g);\r\n\r\n  return this;\r\n};\r\n\r\n// emits a 'removeListener' event iff the listener was removed\r\nEventEmitter.prototype.removeListener = function(type, listener) {\r\n  var list, position, length, i;\r\n\r\n  if (!isFunction(listener))\r\n    throw TypeError('listener must be a function');\r\n\r\n  if (!this._events || !this._events[type])\r\n    return this;\r\n\r\n  list = this._events[type];\r\n  length = list.length;\r\n  position = -1;\r\n\r\n  if (list === listener ||\r\n      (isFunction(list.listener) && list.listener === listener)) {\r\n    delete this._events[type];\r\n    if (this._events.removeListener)\r\n      this.emit('removeListener', type, listener);\r\n\r\n  } else if (isObject(list)) {\r\n    for (i = length; i-- > 0;) {\r\n      if (list[i] === listener ||\r\n          (list[i].listener && list[i].listener === listener)) {\r\n        position = i;\r\n        break;\r\n      }\r\n    }\r\n\r\n    if (position < 0)\r\n      return this;\r\n\r\n    if (list.length === 1) {\r\n      list.length = 0;\r\n      delete this._events[type];\r\n    } else {\r\n      list.splice(position, 1);\r\n    }\r\n\r\n    if (this._events.removeListener)\r\n      this.emit('removeListener', type, listener);\r\n  }\r\n\r\n  return this;\r\n};\r\n\r\nEventEmitter.prototype.removeAllListeners = function(type) {\r\n  var key, listeners;\r\n\r\n  if (!this._events)\r\n    return this;\r\n\r\n  // not listening for removeListener, no need to emit\r\n  if (!this._events.removeListener) {\r\n    if (arguments.length === 0)\r\n      this._events = {};\r\n    else if (this._events[type])\r\n      delete this._events[type];\r\n    return this;\r\n  }\r\n\r\n  // emit removeListener for all listeners on all events\r\n  if (arguments.length === 0) {\r\n    for (key in this._events) {\r\n      if (key === 'removeListener') continue;\r\n      this.removeAllListeners(key);\r\n    }\r\n    this.removeAllListeners('removeListener');\r\n    this._events = {};\r\n    return this;\r\n  }\r\n\r\n  listeners = this._events[type];\r\n\r\n  if (isFunction(listeners)) {\r\n    this.removeListener(type, listeners);\r\n  } else {\r\n    // LIFO order\r\n    while (listeners.length)\r\n      this.removeListener(type, listeners[listeners.length - 1]);\r\n  }\r\n  delete this._events[type];\r\n\r\n  return this;\r\n};\r\n\r\nEventEmitter.prototype.listeners = function(type) {\r\n  var ret;\r\n  if (!this._events || !this._events[type])\r\n    ret = [];\r\n  else if (isFunction(this._events[type]))\r\n    ret = [this._events[type]];\r\n  else\r\n    ret = this._events[type].slice();\r\n  return ret;\r\n};\r\n\r\nEventEmitter.listenerCount = function(emitter, type) {\r\n  var ret;\r\n  if (!emitter._events || !emitter._events[type])\r\n    ret = 0;\r\n  else if (isFunction(emitter._events[type]))\r\n    ret = 1;\r\n  else\r\n    ret = emitter._events[type].length;\r\n  return ret;\r\n};\r\n\r\nfunction isFunction(arg) {\r\n  return typeof arg === 'function';\r\n}\r\n\r\nfunction isNumber(arg) {\r\n  return typeof arg === 'number';\r\n}\r\n\r\nfunction isObject(arg) {\r\n  return typeof arg === 'object' && arg !== null;\r\n}\r\n\r\nfunction isUndefined(arg) {\r\n  return arg === void 0;\r\n}\r\n\r\n},{}],48:[function(require,module,exports){\r\nif (typeof Object.create === 'function') {\r\n  // implementation from standard node.js 'util' module\r\n  module.exports = function inherits(ctor, superCtor) {\r\n    ctor.super_ = superCtor\r\n    ctor.prototype = Object.create(superCtor.prototype, {\r\n      constructor: {\r\n        value: ctor,\r\n        enumerable: false,\r\n        writable: true,\r\n        configurable: true\r\n      }\r\n    });\r\n  };\r\n} else {\r\n  // old school shim for old browsers\r\n  module.exports = function inherits(ctor, superCtor) {\r\n    ctor.super_ = superCtor\r\n    var TempCtor = function () {}\r\n    TempCtor.prototype = superCtor.prototype\r\n    ctor.prototype = new TempCtor()\r\n    ctor.prototype.constructor = ctor\r\n  }\r\n}\r\n\r\n},{}],49:[function(require,module,exports){\r\nmodule.exports = Array.isArray || function (arr) {\r\n  return Object.prototype.toString.call(arr) == '[object Array]';\r\n};\r\n\r\n},{}],50:[function(require,module,exports){\r\nexports.endianness = function () { return 'LE' };\r\n\r\nexports.hostname = function () {\r\n    if (typeof location !== 'undefined') {\r\n        return location.hostname\r\n    }\r\n    else return '';\r\n};\r\n\r\nexports.loadavg = function () { return [] };\r\n\r\nexports.uptime = function () { return 0 };\r\n\r\nexports.freemem = function () {\r\n    return Number.MAX_VALUE;\r\n};\r\n\r\nexports.totalmem = function () {\r\n    return Number.MAX_VALUE;\r\n};\r\n\r\nexports.cpus = function () { return [] };\r\n\r\nexports.type = function () { return 'Browser' };\r\n\r\nexports.release = function () {\r\n    if (typeof navigator !== 'undefined') {\r\n        return navigator.appVersion;\r\n    }\r\n    return '';\r\n};\r\n\r\nexports.networkInterfaces\r\n= exports.getNetworkInterfaces\r\n= function () { return {} };\r\n\r\nexports.arch = function () { return 'javascript' };\r\n\r\nexports.platform = function () { return 'browser' };\r\n\r\nexports.tmpdir = exports.tmpDir = function () {\r\n    return '/tmp';\r\n};\r\n\r\nexports.EOL = '\\n';\r\n\r\n},{}],51:[function(require,module,exports){\r\n// shim for using process in browser\r\n\r\nvar process = module.exports = {};\r\nvar queue = [];\r\nvar draining = false;\r\nvar currentQueue;\r\nvar queueIndex = -1;\r\n\r\nfunction cleanUpNextTick() {\r\n    draining = false;\r\n    if (currentQueue.length) {\r\n        queue = currentQueue.concat(queue);\r\n    } else {\r\n        queueIndex = -1;\r\n    }\r\n    if (queue.length) {\r\n        drainQueue();\r\n    }\r\n}\r\n\r\nfunction drainQueue() {\r\n    if (draining) {\r\n        return;\r\n    }\r\n    var timeout = setTimeout(cleanUpNextTick);\r\n    draining = true;\r\n\r\n    var len = queue.length;\r\n    while(len) {\r\n        currentQueue = queue;\r\n        queue = [];\r\n        while (++queueIndex < len) {\r\n            if (currentQueue) {\r\n                currentQueue[queueIndex].run();\r\n            }\r\n        }\r\n        queueIndex = -1;\r\n        len = queue.length;\r\n    }\r\n    currentQueue = null;\r\n    draining = false;\r\n    clearTimeout(timeout);\r\n}\r\n\r\nprocess.nextTick = function (fun) {\r\n    var args = new Array(arguments.length - 1);\r\n    if (arguments.length > 1) {\r\n        for (var i = 1; i < arguments.length; i++) {\r\n            args[i - 1] = arguments[i];\r\n        }\r\n    }\r\n    queue.push(new Item(fun, args));\r\n    if (queue.length === 1 && !draining) {\r\n        setTimeout(drainQueue, 0);\r\n    }\r\n};\r\n\r\n// v8 likes predictable objects\r\nfunction Item(fun, array) {\r\n    this.fun = fun;\r\n    this.array = array;\r\n}\r\nItem.prototype.run = function () {\r\n    this.fun.apply(null, this.array);\r\n};\r\nprocess.title = 'browser';\r\nprocess.browser = true;\r\nprocess.env = {};\r\nprocess.argv = [];\r\nprocess.version = ''; // empty string to avoid regexp issues\r\nprocess.versions = {};\r\n\r\nfunction noop() {}\r\n\r\nprocess.on = noop;\r\nprocess.addListener = noop;\r\nprocess.once = noop;\r\nprocess.off = noop;\r\nprocess.removeListener = noop;\r\nprocess.removeAllListeners = noop;\r\nprocess.emit = noop;\r\n\r\nprocess.binding = function (name) {\r\n    throw new Error('process.binding is not supported');\r\n};\r\n\r\nprocess.cwd = function () { return '/' };\r\nprocess.chdir = function (dir) {\r\n    throw new Error('process.chdir is not supported');\r\n};\r\nprocess.umask = function() { return 0; };\r\n\r\n},{}],52:[function(require,module,exports){\r\nmodule.exports = require(\"./lib/_stream_duplex.js\")\r\n\r\n},{\"./lib/_stream_duplex.js\":53}],53:[function(require,module,exports){\r\n(function (process){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n// a duplex stream is just a stream that is both readable and writable.\r\n// Since JS doesn't have multiple prototypal inheritance, this class\r\n// prototypally inherits from Readable, and then parasitically from\r\n// Writable.\r\n\r\nmodule.exports = Duplex;\r\n\r\n/*<replacement>*/\r\nvar objectKeys = Object.keys || function (obj) {\r\n  var keys = [];\r\n  for (var key in obj) keys.push(key);\r\n  return keys;\r\n}\r\n/*</replacement>*/\r\n\r\n\r\n/*<replacement>*/\r\nvar util = require('core-util-is');\r\nutil.inherits = require('inherits');\r\n/*</replacement>*/\r\n\r\nvar Readable = require('./_stream_readable');\r\nvar Writable = require('./_stream_writable');\r\n\r\nutil.inherits(Duplex, Readable);\r\n\r\nforEach(objectKeys(Writable.prototype), function(method) {\r\n  if (!Duplex.prototype[method])\r\n    Duplex.prototype[method] = Writable.prototype[method];\r\n});\r\n\r\nfunction Duplex(options) {\r\n  if (!(this instanceof Duplex))\r\n    return new Duplex(options);\r\n\r\n  Readable.call(this, options);\r\n  Writable.call(this, options);\r\n\r\n  if (options && options.readable === false)\r\n    this.readable = false;\r\n\r\n  if (options && options.writable === false)\r\n    this.writable = false;\r\n\r\n  this.allowHalfOpen = true;\r\n  if (options && options.allowHalfOpen === false)\r\n    this.allowHalfOpen = false;\r\n\r\n  this.once('end', onend);\r\n}\r\n\r\n// the no-half-open enforcer\r\nfunction onend() {\r\n  // if we allow half-open state, or if the writable side ended,\r\n  // then we're ok.\r\n  if (this.allowHalfOpen || this._writableState.ended)\r\n    return;\r\n\r\n  // no more data can be written.\r\n  // But allow more writes to happen in this tick.\r\n  process.nextTick(this.end.bind(this));\r\n}\r\n\r\nfunction forEach (xs, f) {\r\n  for (var i = 0, l = xs.length; i < l; i++) {\r\n    f(xs[i], i);\r\n  }\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"./_stream_readable\":55,\"./_stream_writable\":57,\"_process\":51,\"core-util-is\":58,\"inherits\":48}],54:[function(require,module,exports){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n// a passthrough stream.\r\n// basically just the most minimal sort of Transform stream.\r\n// Every written chunk gets output as-is.\r\n\r\nmodule.exports = PassThrough;\r\n\r\nvar Transform = require('./_stream_transform');\r\n\r\n/*<replacement>*/\r\nvar util = require('core-util-is');\r\nutil.inherits = require('inherits');\r\n/*</replacement>*/\r\n\r\nutil.inherits(PassThrough, Transform);\r\n\r\nfunction PassThrough(options) {\r\n  if (!(this instanceof PassThrough))\r\n    return new PassThrough(options);\r\n\r\n  Transform.call(this, options);\r\n}\r\n\r\nPassThrough.prototype._transform = function(chunk, encoding, cb) {\r\n  cb(null, chunk);\r\n};\r\n\r\n},{\"./_stream_transform\":56,\"core-util-is\":58,\"inherits\":48}],55:[function(require,module,exports){\r\n(function (process){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\nmodule.exports = Readable;\r\n\r\n/*<replacement>*/\r\nvar isArray = require('isarray');\r\n/*</replacement>*/\r\n\r\n\r\n/*<replacement>*/\r\nvar Buffer = require('buffer').Buffer;\r\n/*</replacement>*/\r\n\r\nReadable.ReadableState = ReadableState;\r\n\r\nvar EE = require('events').EventEmitter;\r\n\r\n/*<replacement>*/\r\nif (!EE.listenerCount) EE.listenerCount = function(emitter, type) {\r\n  return emitter.listeners(type).length;\r\n};\r\n/*</replacement>*/\r\n\r\nvar Stream = require('stream');\r\n\r\n/*<replacement>*/\r\nvar util = require('core-util-is');\r\nutil.inherits = require('inherits');\r\n/*</replacement>*/\r\n\r\nvar StringDecoder;\r\n\r\n\r\n/*<replacement>*/\r\nvar debug = require('util');\r\nif (debug && debug.debuglog) {\r\n  debug = debug.debuglog('stream');\r\n} else {\r\n  debug = function () {};\r\n}\r\n/*</replacement>*/\r\n\r\n\r\nutil.inherits(Readable, Stream);\r\n\r\nfunction ReadableState(options, stream) {\r\n  var Duplex = require('./_stream_duplex');\r\n\r\n  options = options || {};\r\n\r\n  // the point at which it stops calling _read() to fill the buffer\r\n  // Note: 0 is a valid value, means \"don't call _read preemptively ever\"\r\n  var hwm = options.highWaterMark;\r\n  var defaultHwm = options.objectMode ? 16 : 16 * 1024;\r\n  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;\r\n\r\n  // cast to ints.\r\n  this.highWaterMark = ~~this.highWaterMark;\r\n\r\n  this.buffer = [];\r\n  this.length = 0;\r\n  this.pipes = null;\r\n  this.pipesCount = 0;\r\n  this.flowing = null;\r\n  this.ended = false;\r\n  this.endEmitted = false;\r\n  this.reading = false;\r\n\r\n  // a flag to be able to tell if the onwrite cb is called immediately,\r\n  // or on a later tick.  We set this to true at first, because any\r\n  // actions that shouldn't happen until \"later\" should generally also\r\n  // not happen before the first write call.\r\n  this.sync = true;\r\n\r\n  // whenever we return null, then we set a flag to say\r\n  // that we're awaiting a 'readable' event emission.\r\n  this.needReadable = false;\r\n  this.emittedReadable = false;\r\n  this.readableListening = false;\r\n\r\n\r\n  // object stream flag. Used to make read(n) ignore n and to\r\n  // make all the buffer merging and length checks go away\r\n  this.objectMode = !!options.objectMode;\r\n\r\n  if (stream instanceof Duplex)\r\n    this.objectMode = this.objectMode || !!options.readableObjectMode;\r\n\r\n  // Crypto is kind of old and crusty.  Historically, its default string\r\n  // encoding is 'binary' so we have to make this configurable.\r\n  // Everything else in the universe uses 'utf8', though.\r\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\r\n\r\n  // when piping, we only care about 'readable' events that happen\r\n  // after read()ing all the bytes and not getting any pushback.\r\n  this.ranOut = false;\r\n\r\n  // the number of writers that are awaiting a drain event in .pipe()s\r\n  this.awaitDrain = 0;\r\n\r\n  // if true, a maybeReadMore has been scheduled\r\n  this.readingMore = false;\r\n\r\n  this.decoder = null;\r\n  this.encoding = null;\r\n  if (options.encoding) {\r\n    if (!StringDecoder)\r\n      StringDecoder = require('string_decoder/').StringDecoder;\r\n    this.decoder = new StringDecoder(options.encoding);\r\n    this.encoding = options.encoding;\r\n  }\r\n}\r\n\r\nfunction Readable(options) {\r\n  var Duplex = require('./_stream_duplex');\r\n\r\n  if (!(this instanceof Readable))\r\n    return new Readable(options);\r\n\r\n  this._readableState = new ReadableState(options, this);\r\n\r\n  // legacy\r\n  this.readable = true;\r\n\r\n  Stream.call(this);\r\n}\r\n\r\n// Manually shove something into the read() buffer.\r\n// This returns true if the highWaterMark has not been hit yet,\r\n// similar to how Writable.write() returns true if you should\r\n// write() some more.\r\nReadable.prototype.push = function(chunk, encoding) {\r\n  var state = this._readableState;\r\n\r\n  if (util.isString(chunk) && !state.objectMode) {\r\n    encoding = encoding || state.defaultEncoding;\r\n    if (encoding !== state.encoding) {\r\n      chunk = new Buffer(chunk, encoding);\r\n      encoding = '';\r\n    }\r\n  }\r\n\r\n  return readableAddChunk(this, state, chunk, encoding, false);\r\n};\r\n\r\n// Unshift should *always* be something directly out of read()\r\nReadable.prototype.unshift = function(chunk) {\r\n  var state = this._readableState;\r\n  return readableAddChunk(this, state, chunk, '', true);\r\n};\r\n\r\nfunction readableAddChunk(stream, state, chunk, encoding, addToFront) {\r\n  var er = chunkInvalid(state, chunk);\r\n  if (er) {\r\n    stream.emit('error', er);\r\n  } else if (util.isNullOrUndefined(chunk)) {\r\n    state.reading = false;\r\n    if (!state.ended)\r\n      onEofChunk(stream, state);\r\n  } else if (state.objectMode || chunk && chunk.length > 0) {\r\n    if (state.ended && !addToFront) {\r\n      var e = new Error('stream.push() after EOF');\r\n      stream.emit('error', e);\r\n    } else if (state.endEmitted && addToFront) {\r\n      var e = new Error('stream.unshift() after end event');\r\n      stream.emit('error', e);\r\n    } else {\r\n      if (state.decoder && !addToFront && !encoding)\r\n        chunk = state.decoder.write(chunk);\r\n\r\n      if (!addToFront)\r\n        state.reading = false;\r\n\r\n      // if we want the data now, just emit it.\r\n      if (state.flowing && state.length === 0 && !state.sync) {\r\n        stream.emit('data', chunk);\r\n        stream.read(0);\r\n      } else {\r\n        // update the buffer info.\r\n        state.length += state.objectMode ? 1 : chunk.length;\r\n        if (addToFront)\r\n          state.buffer.unshift(chunk);\r\n        else\r\n          state.buffer.push(chunk);\r\n\r\n        if (state.needReadable)\r\n          emitReadable(stream);\r\n      }\r\n\r\n      maybeReadMore(stream, state);\r\n    }\r\n  } else if (!addToFront) {\r\n    state.reading = false;\r\n  }\r\n\r\n  return needMoreData(state);\r\n}\r\n\r\n\r\n\r\n// if it's past the high water mark, we can push in some more.\r\n// Also, if we have no data yet, we can stand some\r\n// more bytes.  This is to work around cases where hwm=0,\r\n// such as the repl.  Also, if the push() triggered a\r\n// readable event, and the user called read(largeNumber) such that\r\n// needReadable was set, then we ought to push more, so that another\r\n// 'readable' event will be triggered.\r\nfunction needMoreData(state) {\r\n  return !state.ended &&\r\n         (state.needReadable ||\r\n          state.length < state.highWaterMark ||\r\n          state.length === 0);\r\n}\r\n\r\n// backwards compatibility.\r\nReadable.prototype.setEncoding = function(enc) {\r\n  if (!StringDecoder)\r\n    StringDecoder = require('string_decoder/').StringDecoder;\r\n  this._readableState.decoder = new StringDecoder(enc);\r\n  this._readableState.encoding = enc;\r\n  return this;\r\n};\r\n\r\n// Don't raise the hwm > 128MB\r\nvar MAX_HWM = 0x800000;\r\nfunction roundUpToNextPowerOf2(n) {\r\n  if (n >= MAX_HWM) {\r\n    n = MAX_HWM;\r\n  } else {\r\n    // Get the next highest power of 2\r\n    n--;\r\n    for (var p = 1; p < 32; p <<= 1) n |= n >> p;\r\n    n++;\r\n  }\r\n  return n;\r\n}\r\n\r\nfunction howMuchToRead(n, state) {\r\n  if (state.length === 0 && state.ended)\r\n    return 0;\r\n\r\n  if (state.objectMode)\r\n    return n === 0 ? 0 : 1;\r\n\r\n  if (isNaN(n) || util.isNull(n)) {\r\n    // only flow one buffer at a time\r\n    if (state.flowing && state.buffer.length)\r\n      return state.buffer[0].length;\r\n    else\r\n      return state.length;\r\n  }\r\n\r\n  if (n <= 0)\r\n    return 0;\r\n\r\n  // If we're asking for more than the target buffer level,\r\n  // then raise the water mark.  Bump up to the next highest\r\n  // power of 2, to prevent increasing it excessively in tiny\r\n  // amounts.\r\n  if (n > state.highWaterMark)\r\n    state.highWaterMark = roundUpToNextPowerOf2(n);\r\n\r\n  // don't have that much.  return null, unless we've ended.\r\n  if (n > state.length) {\r\n    if (!state.ended) {\r\n      state.needReadable = true;\r\n      return 0;\r\n    } else\r\n      return state.length;\r\n  }\r\n\r\n  return n;\r\n}\r\n\r\n// you can override either this method, or the async _read(n) below.\r\nReadable.prototype.read = function(n) {\r\n  debug('read', n);\r\n  var state = this._readableState;\r\n  var nOrig = n;\r\n\r\n  if (!util.isNumber(n) || n > 0)\r\n    state.emittedReadable = false;\r\n\r\n  // if we're doing read(0) to trigger a readable event, but we\r\n  // already have a bunch of data in the buffer, then just trigger\r\n  // the 'readable' event and move on.\r\n  if (n === 0 &&\r\n      state.needReadable &&\r\n      (state.length >= state.highWaterMark || state.ended)) {\r\n    debug('read: emitReadable', state.length, state.ended);\r\n    if (state.length === 0 && state.ended)\r\n      endReadable(this);\r\n    else\r\n      emitReadable(this);\r\n    return null;\r\n  }\r\n\r\n  n = howMuchToRead(n, state);\r\n\r\n  // if we've ended, and we're now clear, then finish it up.\r\n  if (n === 0 && state.ended) {\r\n    if (state.length === 0)\r\n      endReadable(this);\r\n    return null;\r\n  }\r\n\r\n  // All the actual chunk generation logic needs to be\r\n  // *below* the call to _read.  The reason is that in certain\r\n  // synthetic stream cases, such as passthrough streams, _read\r\n  // may be a completely synchronous operation which may change\r\n  // the state of the read buffer, providing enough data when\r\n  // before there was *not* enough.\r\n  //\r\n  // So, the steps are:\r\n  // 1. Figure out what the state of things will be after we do\r\n  // a read from the buffer.\r\n  //\r\n  // 2. If that resulting state will trigger a _read, then call _read.\r\n  // Note that this may be asynchronous, or synchronous.  Yes, it is\r\n  // deeply ugly to write APIs this way, but that still doesn't mean\r\n  // that the Readable class should behave improperly, as streams are\r\n  // designed to be sync/async agnostic.\r\n  // Take note if the _read call is sync or async (ie, if the read call\r\n  // has returned yet), so that we know whether or not it's safe to emit\r\n  // 'readable' etc.\r\n  //\r\n  // 3. Actually pull the requested chunks out of the buffer and return.\r\n\r\n  // if we need a readable event, then we need to do some reading.\r\n  var doRead = state.needReadable;\r\n  debug('need readable', doRead);\r\n\r\n  // if we currently have less than the highWaterMark, then also read some\r\n  if (state.length === 0 || state.length - n < state.highWaterMark) {\r\n    doRead = true;\r\n    debug('length less than watermark', doRead);\r\n  }\r\n\r\n  // however, if we've ended, then there's no point, and if we're already\r\n  // reading, then it's unnecessary.\r\n  if (state.ended || state.reading) {\r\n    doRead = false;\r\n    debug('reading or ended', doRead);\r\n  }\r\n\r\n  if (doRead) {\r\n    debug('do read');\r\n    state.reading = true;\r\n    state.sync = true;\r\n    // if the length is currently zero, then we *need* a readable event.\r\n    if (state.length === 0)\r\n      state.needReadable = true;\r\n    // call internal read method\r\n    this._read(state.highWaterMark);\r\n    state.sync = false;\r\n  }\r\n\r\n  // If _read pushed data synchronously, then `reading` will be false,\r\n  // and we need to re-evaluate how much data we can return to the user.\r\n  if (doRead && !state.reading)\r\n    n = howMuchToRead(nOrig, state);\r\n\r\n  var ret;\r\n  if (n > 0)\r\n    ret = fromList(n, state);\r\n  else\r\n    ret = null;\r\n\r\n  if (util.isNull(ret)) {\r\n    state.needReadable = true;\r\n    n = 0;\r\n  }\r\n\r\n  state.length -= n;\r\n\r\n  // If we have nothing in the buffer, then we want to know\r\n  // as soon as we *do* get something into the buffer.\r\n  if (state.length === 0 && !state.ended)\r\n    state.needReadable = true;\r\n\r\n  // If we tried to read() past the EOF, then emit end on the next tick.\r\n  if (nOrig !== n && state.ended && state.length === 0)\r\n    endReadable(this);\r\n\r\n  if (!util.isNull(ret))\r\n    this.emit('data', ret);\r\n\r\n  return ret;\r\n};\r\n\r\nfunction chunkInvalid(state, chunk) {\r\n  var er = null;\r\n  if (!util.isBuffer(chunk) &&\r\n      !util.isString(chunk) &&\r\n      !util.isNullOrUndefined(chunk) &&\r\n      !state.objectMode) {\r\n    er = new TypeError('Invalid non-string/buffer chunk');\r\n  }\r\n  return er;\r\n}\r\n\r\n\r\nfunction onEofChunk(stream, state) {\r\n  if (state.decoder && !state.ended) {\r\n    var chunk = state.decoder.end();\r\n    if (chunk && chunk.length) {\r\n      state.buffer.push(chunk);\r\n      state.length += state.objectMode ? 1 : chunk.length;\r\n    }\r\n  }\r\n  state.ended = true;\r\n\r\n  // emit 'readable' now to make sure it gets picked up.\r\n  emitReadable(stream);\r\n}\r\n\r\n// Don't emit readable right away in sync mode, because this can trigger\r\n// another read() call => stack overflow.  This way, it might trigger\r\n// a nextTick recursion warning, but that's not so bad.\r\nfunction emitReadable(stream) {\r\n  var state = stream._readableState;\r\n  state.needReadable = false;\r\n  if (!state.emittedReadable) {\r\n    debug('emitReadable', state.flowing);\r\n    state.emittedReadable = true;\r\n    if (state.sync)\r\n      process.nextTick(function() {\r\n        emitReadable_(stream);\r\n      });\r\n    else\r\n      emitReadable_(stream);\r\n  }\r\n}\r\n\r\nfunction emitReadable_(stream) {\r\n  debug('emit readable');\r\n  stream.emit('readable');\r\n  flow(stream);\r\n}\r\n\r\n\r\n// at this point, the user has presumably seen the 'readable' event,\r\n// and called read() to consume some data.  that may have triggered\r\n// in turn another _read(n) call, in which case reading = true if\r\n// it's in progress.\r\n// However, if we're not ended, or reading, and the length < hwm,\r\n// then go ahead and try to read some more preemptively.\r\nfunction maybeReadMore(stream, state) {\r\n  if (!state.readingMore) {\r\n    state.readingMore = true;\r\n    process.nextTick(function() {\r\n      maybeReadMore_(stream, state);\r\n    });\r\n  }\r\n}\r\n\r\nfunction maybeReadMore_(stream, state) {\r\n  var len = state.length;\r\n  while (!state.reading && !state.flowing && !state.ended &&\r\n         state.length < state.highWaterMark) {\r\n    debug('maybeReadMore read 0');\r\n    stream.read(0);\r\n    if (len === state.length)\r\n      // didn't get any data, stop spinning.\r\n      break;\r\n    else\r\n      len = state.length;\r\n  }\r\n  state.readingMore = false;\r\n}\r\n\r\n// abstract method.  to be overridden in specific implementation classes.\r\n// call cb(er, data) where data is <= n in length.\r\n// for virtual (non-string, non-buffer) streams, \"length\" is somewhat\r\n// arbitrary, and perhaps not very meaningful.\r\nReadable.prototype._read = function(n) {\r\n  this.emit('error', new Error('not implemented'));\r\n};\r\n\r\nReadable.prototype.pipe = function(dest, pipeOpts) {\r\n  var src = this;\r\n  var state = this._readableState;\r\n\r\n  switch (state.pipesCount) {\r\n    case 0:\r\n      state.pipes = dest;\r\n      break;\r\n    case 1:\r\n      state.pipes = [state.pipes, dest];\r\n      break;\r\n    default:\r\n      state.pipes.push(dest);\r\n      break;\r\n  }\r\n  state.pipesCount += 1;\r\n  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);\r\n\r\n  var doEnd = (!pipeOpts || pipeOpts.end !== false) &&\r\n              dest !== process.stdout &&\r\n              dest !== process.stderr;\r\n\r\n  var endFn = doEnd ? onend : cleanup;\r\n  if (state.endEmitted)\r\n    process.nextTick(endFn);\r\n  else\r\n    src.once('end', endFn);\r\n\r\n  dest.on('unpipe', onunpipe);\r\n  function onunpipe(readable) {\r\n    debug('onunpipe');\r\n    if (readable === src) {\r\n      cleanup();\r\n    }\r\n  }\r\n\r\n  function onend() {\r\n    debug('onend');\r\n    dest.end();\r\n  }\r\n\r\n  // when the dest drains, it reduces the awaitDrain counter\r\n  // on the source.  This would be more elegant with a .once()\r\n  // handler in flow(), but adding and removing repeatedly is\r\n  // too slow.\r\n  var ondrain = pipeOnDrain(src);\r\n  dest.on('drain', ondrain);\r\n\r\n  function cleanup() {\r\n    debug('cleanup');\r\n    // cleanup event handlers once the pipe is broken\r\n    dest.removeListener('close', onclose);\r\n    dest.removeListener('finish', onfinish);\r\n    dest.removeListener('drain', ondrain);\r\n    dest.removeListener('error', onerror);\r\n    dest.removeListener('unpipe', onunpipe);\r\n    src.removeListener('end', onend);\r\n    src.removeListener('end', cleanup);\r\n    src.removeListener('data', ondata);\r\n\r\n    // if the reader is waiting for a drain event from this\r\n    // specific writer, then it would cause it to never start\r\n    // flowing again.\r\n    // So, if this is awaiting a drain, then we just call it now.\r\n    // If we don't know, then assume that we are waiting for one.\r\n    if (state.awaitDrain &&\r\n        (!dest._writableState || dest._writableState.needDrain))\r\n      ondrain();\r\n  }\r\n\r\n  src.on('data', ondata);\r\n  function ondata(chunk) {\r\n    debug('ondata');\r\n    var ret = dest.write(chunk);\r\n    if (false === ret) {\r\n      debug('false write response, pause',\r\n            src._readableState.awaitDrain);\r\n      src._readableState.awaitDrain++;\r\n      src.pause();\r\n    }\r\n  }\r\n\r\n  // if the dest has an error, then stop piping into it.\r\n  // however, don't suppress the throwing behavior for this.\r\n  function onerror(er) {\r\n    debug('onerror', er);\r\n    unpipe();\r\n    dest.removeListener('error', onerror);\r\n    if (EE.listenerCount(dest, 'error') === 0)\r\n      dest.emit('error', er);\r\n  }\r\n  // This is a brutally ugly hack to make sure that our error handler\r\n  // is attached before any userland ones.  NEVER DO THIS.\r\n  if (!dest._events || !dest._events.error)\r\n    dest.on('error', onerror);\r\n  else if (isArray(dest._events.error))\r\n    dest._events.error.unshift(onerror);\r\n  else\r\n    dest._events.error = [onerror, dest._events.error];\r\n\r\n\r\n\r\n  // Both close and finish should trigger unpipe, but only once.\r\n  function onclose() {\r\n    dest.removeListener('finish', onfinish);\r\n    unpipe();\r\n  }\r\n  dest.once('close', onclose);\r\n  function onfinish() {\r\n    debug('onfinish');\r\n    dest.removeListener('close', onclose);\r\n    unpipe();\r\n  }\r\n  dest.once('finish', onfinish);\r\n\r\n  function unpipe() {\r\n    debug('unpipe');\r\n    src.unpipe(dest);\r\n  }\r\n\r\n  // tell the dest that it's being piped to\r\n  dest.emit('pipe', src);\r\n\r\n  // start the flow if it hasn't been started already.\r\n  if (!state.flowing) {\r\n    debug('pipe resume');\r\n    src.resume();\r\n  }\r\n\r\n  return dest;\r\n};\r\n\r\nfunction pipeOnDrain(src) {\r\n  return function() {\r\n    var state = src._readableState;\r\n    debug('pipeOnDrain', state.awaitDrain);\r\n    if (state.awaitDrain)\r\n      state.awaitDrain--;\r\n    if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {\r\n      state.flowing = true;\r\n      flow(src);\r\n    }\r\n  };\r\n}\r\n\r\n\r\nReadable.prototype.unpipe = function(dest) {\r\n  var state = this._readableState;\r\n\r\n  // if we're not piping anywhere, then do nothing.\r\n  if (state.pipesCount === 0)\r\n    return this;\r\n\r\n  // just one destination.  most common case.\r\n  if (state.pipesCount === 1) {\r\n    // passed in one, but it's not the right one.\r\n    if (dest && dest !== state.pipes)\r\n      return this;\r\n\r\n    if (!dest)\r\n      dest = state.pipes;\r\n\r\n    // got a match.\r\n    state.pipes = null;\r\n    state.pipesCount = 0;\r\n    state.flowing = false;\r\n    if (dest)\r\n      dest.emit('unpipe', this);\r\n    return this;\r\n  }\r\n\r\n  // slow case. multiple pipe destinations.\r\n\r\n  if (!dest) {\r\n    // remove all.\r\n    var dests = state.pipes;\r\n    var len = state.pipesCount;\r\n    state.pipes = null;\r\n    state.pipesCount = 0;\r\n    state.flowing = false;\r\n\r\n    for (var i = 0; i < len; i++)\r\n      dests[i].emit('unpipe', this);\r\n    return this;\r\n  }\r\n\r\n  // try to find the right one.\r\n  var i = indexOf(state.pipes, dest);\r\n  if (i === -1)\r\n    return this;\r\n\r\n  state.pipes.splice(i, 1);\r\n  state.pipesCount -= 1;\r\n  if (state.pipesCount === 1)\r\n    state.pipes = state.pipes[0];\r\n\r\n  dest.emit('unpipe', this);\r\n\r\n  return this;\r\n};\r\n\r\n// set up data events if they are asked for\r\n// Ensure readable listeners eventually get something\r\nReadable.prototype.on = function(ev, fn) {\r\n  var res = Stream.prototype.on.call(this, ev, fn);\r\n\r\n  // If listening to data, and it has not explicitly been paused,\r\n  // then call resume to start the flow of data on the next tick.\r\n  if (ev === 'data' && false !== this._readableState.flowing) {\r\n    this.resume();\r\n  }\r\n\r\n  if (ev === 'readable' && this.readable) {\r\n    var state = this._readableState;\r\n    if (!state.readableListening) {\r\n      state.readableListening = true;\r\n      state.emittedReadable = false;\r\n      state.needReadable = true;\r\n      if (!state.reading) {\r\n        var self = this;\r\n        process.nextTick(function() {\r\n          debug('readable nexttick read 0');\r\n          self.read(0);\r\n        });\r\n      } else if (state.length) {\r\n        emitReadable(this, state);\r\n      }\r\n    }\r\n  }\r\n\r\n  return res;\r\n};\r\nReadable.prototype.addListener = Readable.prototype.on;\r\n\r\n// pause() and resume() are remnants of the legacy readable stream API\r\n// If the user uses them, then switch into old mode.\r\nReadable.prototype.resume = function() {\r\n  var state = this._readableState;\r\n  if (!state.flowing) {\r\n    debug('resume');\r\n    state.flowing = true;\r\n    if (!state.reading) {\r\n      debug('resume read 0');\r\n      this.read(0);\r\n    }\r\n    resume(this, state);\r\n  }\r\n  return this;\r\n};\r\n\r\nfunction resume(stream, state) {\r\n  if (!state.resumeScheduled) {\r\n    state.resumeScheduled = true;\r\n    process.nextTick(function() {\r\n      resume_(stream, state);\r\n    });\r\n  }\r\n}\r\n\r\nfunction resume_(stream, state) {\r\n  state.resumeScheduled = false;\r\n  stream.emit('resume');\r\n  flow(stream);\r\n  if (state.flowing && !state.reading)\r\n    stream.read(0);\r\n}\r\n\r\nReadable.prototype.pause = function() {\r\n  debug('call pause flowing=%j', this._readableState.flowing);\r\n  if (false !== this._readableState.flowing) {\r\n    debug('pause');\r\n    this._readableState.flowing = false;\r\n    this.emit('pause');\r\n  }\r\n  return this;\r\n};\r\n\r\nfunction flow(stream) {\r\n  var state = stream._readableState;\r\n  debug('flow', state.flowing);\r\n  if (state.flowing) {\r\n    do {\r\n      var chunk = stream.read();\r\n    } while (null !== chunk && state.flowing);\r\n  }\r\n}\r\n\r\n// wrap an old-style stream as the async data source.\r\n// This is *not* part of the readable stream interface.\r\n// It is an ugly unfortunate mess of history.\r\nReadable.prototype.wrap = function(stream) {\r\n  var state = this._readableState;\r\n  var paused = false;\r\n\r\n  var self = this;\r\n  stream.on('end', function() {\r\n    debug('wrapped end');\r\n    if (state.decoder && !state.ended) {\r\n      var chunk = state.decoder.end();\r\n      if (chunk && chunk.length)\r\n        self.push(chunk);\r\n    }\r\n\r\n    self.push(null);\r\n  });\r\n\r\n  stream.on('data', function(chunk) {\r\n    debug('wrapped data');\r\n    if (state.decoder)\r\n      chunk = state.decoder.write(chunk);\r\n    if (!chunk || !state.objectMode && !chunk.length)\r\n      return;\r\n\r\n    var ret = self.push(chunk);\r\n    if (!ret) {\r\n      paused = true;\r\n      stream.pause();\r\n    }\r\n  });\r\n\r\n  // proxy all the other methods.\r\n  // important when wrapping filters and duplexes.\r\n  for (var i in stream) {\r\n    if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {\r\n      this[i] = function(method) { return function() {\r\n        return stream[method].apply(stream, arguments);\r\n      }}(i);\r\n    }\r\n  }\r\n\r\n  // proxy certain important events.\r\n  var events = ['error', 'close', 'destroy', 'pause', 'resume'];\r\n  forEach(events, function(ev) {\r\n    stream.on(ev, self.emit.bind(self, ev));\r\n  });\r\n\r\n  // when we try to consume some more bytes, simply unpause the\r\n  // underlying stream.\r\n  self._read = function(n) {\r\n    debug('wrapped _read', n);\r\n    if (paused) {\r\n      paused = false;\r\n      stream.resume();\r\n    }\r\n  };\r\n\r\n  return self;\r\n};\r\n\r\n\r\n\r\n// exposed for testing purposes only.\r\nReadable._fromList = fromList;\r\n\r\n// Pluck off n bytes from an array of buffers.\r\n// Length is the combined lengths of all the buffers in the list.\r\nfunction fromList(n, state) {\r\n  var list = state.buffer;\r\n  var length = state.length;\r\n  var stringMode = !!state.decoder;\r\n  var objectMode = !!state.objectMode;\r\n  var ret;\r\n\r\n  // nothing in the list, definitely empty.\r\n  if (list.length === 0)\r\n    return null;\r\n\r\n  if (length === 0)\r\n    ret = null;\r\n  else if (objectMode)\r\n    ret = list.shift();\r\n  else if (!n || n >= length) {\r\n    // read it all, truncate the array.\r\n    if (stringMode)\r\n      ret = list.join('');\r\n    else\r\n      ret = Buffer.concat(list, length);\r\n    list.length = 0;\r\n  } else {\r\n    // read just some of it.\r\n    if (n < list[0].length) {\r\n      // just take a part of the first list item.\r\n      // slice is the same for buffers and strings.\r\n      var buf = list[0];\r\n      ret = buf.slice(0, n);\r\n      list[0] = buf.slice(n);\r\n    } else if (n === list[0].length) {\r\n      // first list is a perfect match\r\n      ret = list.shift();\r\n    } else {\r\n      // complex case.\r\n      // we have enough to cover it, but it spans past the first buffer.\r\n      if (stringMode)\r\n        ret = '';\r\n      else\r\n        ret = new Buffer(n);\r\n\r\n      var c = 0;\r\n      for (var i = 0, l = list.length; i < l && c < n; i++) {\r\n        var buf = list[0];\r\n        var cpy = Math.min(n - c, buf.length);\r\n\r\n        if (stringMode)\r\n          ret += buf.slice(0, cpy);\r\n        else\r\n          buf.copy(ret, c, 0, cpy);\r\n\r\n        if (cpy < buf.length)\r\n          list[0] = buf.slice(cpy);\r\n        else\r\n          list.shift();\r\n\r\n        c += cpy;\r\n      }\r\n    }\r\n  }\r\n\r\n  return ret;\r\n}\r\n\r\nfunction endReadable(stream) {\r\n  var state = stream._readableState;\r\n\r\n  // If we get here before consuming all the bytes, then that is a\r\n  // bug in node.  Should never happen.\r\n  if (state.length > 0)\r\n    throw new Error('endReadable called on non-empty stream');\r\n\r\n  if (!state.endEmitted) {\r\n    state.ended = true;\r\n    process.nextTick(function() {\r\n      // Check that we didn't get one last unshift.\r\n      if (!state.endEmitted && state.length === 0) {\r\n        state.endEmitted = true;\r\n        stream.readable = false;\r\n        stream.emit('end');\r\n      }\r\n    });\r\n  }\r\n}\r\n\r\nfunction forEach (xs, f) {\r\n  for (var i = 0, l = xs.length; i < l; i++) {\r\n    f(xs[i], i);\r\n  }\r\n}\r\n\r\nfunction indexOf (xs, x) {\r\n  for (var i = 0, l = xs.length; i < l; i++) {\r\n    if (xs[i] === x) return i;\r\n  }\r\n  return -1;\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"./_stream_duplex\":53,\"_process\":51,\"buffer\":43,\"core-util-is\":58,\"events\":47,\"inherits\":48,\"isarray\":49,\"stream\":63,\"string_decoder/\":64,\"util\":42}],56:[function(require,module,exports){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n\r\n// a transform stream is a readable/writable stream where you do\r\n// something with the data.  Sometimes it's called a \"filter\",\r\n// but that's not a great name for it, since that implies a thing where\r\n// some bits pass through, and others are simply ignored.  (That would\r\n// be a valid example of a transform, of course.)\r\n//\r\n// While the output is causally related to the input, it's not a\r\n// necessarily symmetric or synchronous transformation.  For example,\r\n// a zlib stream might take multiple plain-text writes(), and then\r\n// emit a single compressed chunk some time in the future.\r\n//\r\n// Here's how this works:\r\n//\r\n// The Transform stream has all the aspects of the readable and writable\r\n// stream classes.  When you write(chunk), that calls _write(chunk,cb)\r\n// internally, and returns false if there's a lot of pending writes\r\n// buffered up.  When you call read(), that calls _read(n) until\r\n// there's enough pending readable data buffered up.\r\n//\r\n// In a transform stream, the written data is placed in a buffer.  When\r\n// _read(n) is called, it transforms the queued up data, calling the\r\n// buffered _write cb's as it consumes chunks.  If consuming a single\r\n// written chunk would result in multiple output chunks, then the first\r\n// outputted bit calls the readcb, and subsequent chunks just go into\r\n// the read buffer, and will cause it to emit 'readable' if necessary.\r\n//\r\n// This way, back-pressure is actually determined by the reading side,\r\n// since _read has to be called to start processing a new chunk.  However,\r\n// a pathological inflate type of transform can cause excessive buffering\r\n// here.  For example, imagine a stream where every byte of input is\r\n// interpreted as an integer from 0-255, and then results in that many\r\n// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in\r\n// 1kb of data being output.  In this case, you could write a very small\r\n// amount of input, and end up with a very large amount of output.  In\r\n// such a pathological inflating mechanism, there'd be no way to tell\r\n// the system to stop doing the transform.  A single 4MB write could\r\n// cause the system to run out of memory.\r\n//\r\n// However, even in such a pathological case, only a single written chunk\r\n// would be consumed, and then the rest would wait (un-transformed) until\r\n// the results of the previous transformed chunk were consumed.\r\n\r\nmodule.exports = Transform;\r\n\r\nvar Duplex = require('./_stream_duplex');\r\n\r\n/*<replacement>*/\r\nvar util = require('core-util-is');\r\nutil.inherits = require('inherits');\r\n/*</replacement>*/\r\n\r\nutil.inherits(Transform, Duplex);\r\n\r\n\r\nfunction TransformState(options, stream) {\r\n  this.afterTransform = function(er, data) {\r\n    return afterTransform(stream, er, data);\r\n  };\r\n\r\n  this.needTransform = false;\r\n  this.transforming = false;\r\n  this.writecb = null;\r\n  this.writechunk = null;\r\n}\r\n\r\nfunction afterTransform(stream, er, data) {\r\n  var ts = stream._transformState;\r\n  ts.transforming = false;\r\n\r\n  var cb = ts.writecb;\r\n\r\n  if (!cb)\r\n    return stream.emit('error', new Error('no writecb in Transform class'));\r\n\r\n  ts.writechunk = null;\r\n  ts.writecb = null;\r\n\r\n  if (!util.isNullOrUndefined(data))\r\n    stream.push(data);\r\n\r\n  if (cb)\r\n    cb(er);\r\n\r\n  var rs = stream._readableState;\r\n  rs.reading = false;\r\n  if (rs.needReadable || rs.length < rs.highWaterMark) {\r\n    stream._read(rs.highWaterMark);\r\n  }\r\n}\r\n\r\n\r\nfunction Transform(options) {\r\n  if (!(this instanceof Transform))\r\n    return new Transform(options);\r\n\r\n  Duplex.call(this, options);\r\n\r\n  this._transformState = new TransformState(options, this);\r\n\r\n  // when the writable side finishes, then flush out anything remaining.\r\n  var stream = this;\r\n\r\n  // start out asking for a readable event once data is transformed.\r\n  this._readableState.needReadable = true;\r\n\r\n  // we have implemented the _read method, and done the other things\r\n  // that Readable wants before the first _read call, so unset the\r\n  // sync guard flag.\r\n  this._readableState.sync = false;\r\n\r\n  this.once('prefinish', function() {\r\n    if (util.isFunction(this._flush))\r\n      this._flush(function(er) {\r\n        done(stream, er);\r\n      });\r\n    else\r\n      done(stream);\r\n  });\r\n}\r\n\r\nTransform.prototype.push = function(chunk, encoding) {\r\n  this._transformState.needTransform = false;\r\n  return Duplex.prototype.push.call(this, chunk, encoding);\r\n};\r\n\r\n// This is the part where you do stuff!\r\n// override this function in implementation classes.\r\n// 'chunk' is an input chunk.\r\n//\r\n// Call `push(newChunk)` to pass along transformed output\r\n// to the readable side.  You may call 'push' zero or more times.\r\n//\r\n// Call `cb(err)` when you are done with this chunk.  If you pass\r\n// an error, then that'll put the hurt on the whole operation.  If you\r\n// never call cb(), then you'll never get another chunk.\r\nTransform.prototype._transform = function(chunk, encoding, cb) {\r\n  throw new Error('not implemented');\r\n};\r\n\r\nTransform.prototype._write = function(chunk, encoding, cb) {\r\n  var ts = this._transformState;\r\n  ts.writecb = cb;\r\n  ts.writechunk = chunk;\r\n  ts.writeencoding = encoding;\r\n  if (!ts.transforming) {\r\n    var rs = this._readableState;\r\n    if (ts.needTransform ||\r\n        rs.needReadable ||\r\n        rs.length < rs.highWaterMark)\r\n      this._read(rs.highWaterMark);\r\n  }\r\n};\r\n\r\n// Doesn't matter what the args are here.\r\n// _transform does all the work.\r\n// That we got here means that the readable side wants more data.\r\nTransform.prototype._read = function(n) {\r\n  var ts = this._transformState;\r\n\r\n  if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {\r\n    ts.transforming = true;\r\n    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);\r\n  } else {\r\n    // mark that we need a transform, so that any data that comes in\r\n    // will get processed, now that we've asked for it.\r\n    ts.needTransform = true;\r\n  }\r\n};\r\n\r\n\r\nfunction done(stream, er) {\r\n  if (er)\r\n    return stream.emit('error', er);\r\n\r\n  // if there's nothing in the write buffer, then that means\r\n  // that nothing more will ever be provided\r\n  var ws = stream._writableState;\r\n  var ts = stream._transformState;\r\n\r\n  if (ws.length)\r\n    throw new Error('calling transform done when ws.length != 0');\r\n\r\n  if (ts.transforming)\r\n    throw new Error('calling transform done when still transforming');\r\n\r\n  return stream.push(null);\r\n}\r\n\r\n},{\"./_stream_duplex\":53,\"core-util-is\":58,\"inherits\":48}],57:[function(require,module,exports){\r\n(function (process){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n// A bit simpler than readable streams.\r\n// Implement an async ._write(chunk, cb), and it'll handle all\r\n// the drain event emission and buffering.\r\n\r\nmodule.exports = Writable;\r\n\r\n/*<replacement>*/\r\nvar Buffer = require('buffer').Buffer;\r\n/*</replacement>*/\r\n\r\nWritable.WritableState = WritableState;\r\n\r\n\r\n/*<replacement>*/\r\nvar util = require('core-util-is');\r\nutil.inherits = require('inherits');\r\n/*</replacement>*/\r\n\r\nvar Stream = require('stream');\r\n\r\nutil.inherits(Writable, Stream);\r\n\r\nfunction WriteReq(chunk, encoding, cb) {\r\n  this.chunk = chunk;\r\n  this.encoding = encoding;\r\n  this.callback = cb;\r\n}\r\n\r\nfunction WritableState(options, stream) {\r\n  var Duplex = require('./_stream_duplex');\r\n\r\n  options = options || {};\r\n\r\n  // the point at which write() starts returning false\r\n  // Note: 0 is a valid value, means that we always return false if\r\n  // the entire buffer is not flushed immediately on write()\r\n  var hwm = options.highWaterMark;\r\n  var defaultHwm = options.objectMode ? 16 : 16 * 1024;\r\n  this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;\r\n\r\n  // object stream flag to indicate whether or not this stream\r\n  // contains buffers or objects.\r\n  this.objectMode = !!options.objectMode;\r\n\r\n  if (stream instanceof Duplex)\r\n    this.objectMode = this.objectMode || !!options.writableObjectMode;\r\n\r\n  // cast to ints.\r\n  this.highWaterMark = ~~this.highWaterMark;\r\n\r\n  this.needDrain = false;\r\n  // at the start of calling end()\r\n  this.ending = false;\r\n  // when end() has been called, and returned\r\n  this.ended = false;\r\n  // when 'finish' is emitted\r\n  this.finished = false;\r\n\r\n  // should we decode strings into buffers before passing to _write?\r\n  // this is here so that some node-core streams can optimize string\r\n  // handling at a lower level.\r\n  var noDecode = options.decodeStrings === false;\r\n  this.decodeStrings = !noDecode;\r\n\r\n  // Crypto is kind of old and crusty.  Historically, its default string\r\n  // encoding is 'binary' so we have to make this configurable.\r\n  // Everything else in the universe uses 'utf8', though.\r\n  this.defaultEncoding = options.defaultEncoding || 'utf8';\r\n\r\n  // not an actual buffer we keep track of, but a measurement\r\n  // of how much we're waiting to get pushed to some underlying\r\n  // socket or file.\r\n  this.length = 0;\r\n\r\n  // a flag to see when we're in the middle of a write.\r\n  this.writing = false;\r\n\r\n  // when true all writes will be buffered until .uncork() call\r\n  this.corked = 0;\r\n\r\n  // a flag to be able to tell if the onwrite cb is called immediately,\r\n  // or on a later tick.  We set this to true at first, because any\r\n  // actions that shouldn't happen until \"later\" should generally also\r\n  // not happen before the first write call.\r\n  this.sync = true;\r\n\r\n  // a flag to know if we're processing previously buffered items, which\r\n  // may call the _write() callback in the same tick, so that we don't\r\n  // end up in an overlapped onwrite situation.\r\n  this.bufferProcessing = false;\r\n\r\n  // the callback that's passed to _write(chunk,cb)\r\n  this.onwrite = function(er) {\r\n    onwrite(stream, er);\r\n  };\r\n\r\n  // the callback that the user supplies to write(chunk,encoding,cb)\r\n  this.writecb = null;\r\n\r\n  // the amount that is being written when _write is called.\r\n  this.writelen = 0;\r\n\r\n  this.buffer = [];\r\n\r\n  // number of pending user-supplied write callbacks\r\n  // this must be 0 before 'finish' can be emitted\r\n  this.pendingcb = 0;\r\n\r\n  // emit prefinish if the only thing we're waiting for is _write cbs\r\n  // This is relevant for synchronous Transform streams\r\n  this.prefinished = false;\r\n\r\n  // True if the error was already emitted and should not be thrown again\r\n  this.errorEmitted = false;\r\n}\r\n\r\nfunction Writable(options) {\r\n  var Duplex = require('./_stream_duplex');\r\n\r\n  // Writable ctor is applied to Duplexes, though they're not\r\n  // instanceof Writable, they're instanceof Readable.\r\n  if (!(this instanceof Writable) && !(this instanceof Duplex))\r\n    return new Writable(options);\r\n\r\n  this._writableState = new WritableState(options, this);\r\n\r\n  // legacy.\r\n  this.writable = true;\r\n\r\n  Stream.call(this);\r\n}\r\n\r\n// Otherwise people can pipe Writable streams, which is just wrong.\r\nWritable.prototype.pipe = function() {\r\n  this.emit('error', new Error('Cannot pipe. Not readable.'));\r\n};\r\n\r\n\r\nfunction writeAfterEnd(stream, state, cb) {\r\n  var er = new Error('write after end');\r\n  // TODO: defer error events consistently everywhere, not just the cb\r\n  stream.emit('error', er);\r\n  process.nextTick(function() {\r\n    cb(er);\r\n  });\r\n}\r\n\r\n// If we get something that is not a buffer, string, null, or undefined,\r\n// and we're not in objectMode, then that's an error.\r\n// Otherwise stream chunks are all considered to be of length=1, and the\r\n// watermarks determine how many objects to keep in the buffer, rather than\r\n// how many bytes or characters.\r\nfunction validChunk(stream, state, chunk, cb) {\r\n  var valid = true;\r\n  if (!util.isBuffer(chunk) &&\r\n      !util.isString(chunk) &&\r\n      !util.isNullOrUndefined(chunk) &&\r\n      !state.objectMode) {\r\n    var er = new TypeError('Invalid non-string/buffer chunk');\r\n    stream.emit('error', er);\r\n    process.nextTick(function() {\r\n      cb(er);\r\n    });\r\n    valid = false;\r\n  }\r\n  return valid;\r\n}\r\n\r\nWritable.prototype.write = function(chunk, encoding, cb) {\r\n  var state = this._writableState;\r\n  var ret = false;\r\n\r\n  if (util.isFunction(encoding)) {\r\n    cb = encoding;\r\n    encoding = null;\r\n  }\r\n\r\n  if (util.isBuffer(chunk))\r\n    encoding = 'buffer';\r\n  else if (!encoding)\r\n    encoding = state.defaultEncoding;\r\n\r\n  if (!util.isFunction(cb))\r\n    cb = function() {};\r\n\r\n  if (state.ended)\r\n    writeAfterEnd(this, state, cb);\r\n  else if (validChunk(this, state, chunk, cb)) {\r\n    state.pendingcb++;\r\n    ret = writeOrBuffer(this, state, chunk, encoding, cb);\r\n  }\r\n\r\n  return ret;\r\n};\r\n\r\nWritable.prototype.cork = function() {\r\n  var state = this._writableState;\r\n\r\n  state.corked++;\r\n};\r\n\r\nWritable.prototype.uncork = function() {\r\n  var state = this._writableState;\r\n\r\n  if (state.corked) {\r\n    state.corked--;\r\n\r\n    if (!state.writing &&\r\n        !state.corked &&\r\n        !state.finished &&\r\n        !state.bufferProcessing &&\r\n        state.buffer.length)\r\n      clearBuffer(this, state);\r\n  }\r\n};\r\n\r\nfunction decodeChunk(state, chunk, encoding) {\r\n  if (!state.objectMode &&\r\n      state.decodeStrings !== false &&\r\n      util.isString(chunk)) {\r\n    chunk = new Buffer(chunk, encoding);\r\n  }\r\n  return chunk;\r\n}\r\n\r\n// if we're already writing something, then just put this\r\n// in the queue, and wait our turn.  Otherwise, call _write\r\n// If we return false, then we need a drain event, so set that flag.\r\nfunction writeOrBuffer(stream, state, chunk, encoding, cb) {\r\n  chunk = decodeChunk(state, chunk, encoding);\r\n  if (util.isBuffer(chunk))\r\n    encoding = 'buffer';\r\n  var len = state.objectMode ? 1 : chunk.length;\r\n\r\n  state.length += len;\r\n\r\n  var ret = state.length < state.highWaterMark;\r\n  // we must ensure that previous needDrain will not be reset to false.\r\n  if (!ret)\r\n    state.needDrain = true;\r\n\r\n  if (state.writing || state.corked)\r\n    state.buffer.push(new WriteReq(chunk, encoding, cb));\r\n  else\r\n    doWrite(stream, state, false, len, chunk, encoding, cb);\r\n\r\n  return ret;\r\n}\r\n\r\nfunction doWrite(stream, state, writev, len, chunk, encoding, cb) {\r\n  state.writelen = len;\r\n  state.writecb = cb;\r\n  state.writing = true;\r\n  state.sync = true;\r\n  if (writev)\r\n    stream._writev(chunk, state.onwrite);\r\n  else\r\n    stream._write(chunk, encoding, state.onwrite);\r\n  state.sync = false;\r\n}\r\n\r\nfunction onwriteError(stream, state, sync, er, cb) {\r\n  if (sync)\r\n    process.nextTick(function() {\r\n      state.pendingcb--;\r\n      cb(er);\r\n    });\r\n  else {\r\n    state.pendingcb--;\r\n    cb(er);\r\n  }\r\n\r\n  stream._writableState.errorEmitted = true;\r\n  stream.emit('error', er);\r\n}\r\n\r\nfunction onwriteStateUpdate(state) {\r\n  state.writing = false;\r\n  state.writecb = null;\r\n  state.length -= state.writelen;\r\n  state.writelen = 0;\r\n}\r\n\r\nfunction onwrite(stream, er) {\r\n  var state = stream._writableState;\r\n  var sync = state.sync;\r\n  var cb = state.writecb;\r\n\r\n  onwriteStateUpdate(state);\r\n\r\n  if (er)\r\n    onwriteError(stream, state, sync, er, cb);\r\n  else {\r\n    // Check if we're actually ready to finish, but don't emit yet\r\n    var finished = needFinish(stream, state);\r\n\r\n    if (!finished &&\r\n        !state.corked &&\r\n        !state.bufferProcessing &&\r\n        state.buffer.length) {\r\n      clearBuffer(stream, state);\r\n    }\r\n\r\n    if (sync) {\r\n      process.nextTick(function() {\r\n        afterWrite(stream, state, finished, cb);\r\n      });\r\n    } else {\r\n      afterWrite(stream, state, finished, cb);\r\n    }\r\n  }\r\n}\r\n\r\nfunction afterWrite(stream, state, finished, cb) {\r\n  if (!finished)\r\n    onwriteDrain(stream, state);\r\n  state.pendingcb--;\r\n  cb();\r\n  finishMaybe(stream, state);\r\n}\r\n\r\n// Must force callback to be called on nextTick, so that we don't\r\n// emit 'drain' before the write() consumer gets the 'false' return\r\n// value, and has a chance to attach a 'drain' listener.\r\nfunction onwriteDrain(stream, state) {\r\n  if (state.length === 0 && state.needDrain) {\r\n    state.needDrain = false;\r\n    stream.emit('drain');\r\n  }\r\n}\r\n\r\n\r\n// if there's something in the buffer waiting, then process it\r\nfunction clearBuffer(stream, state) {\r\n  state.bufferProcessing = true;\r\n\r\n  if (stream._writev && state.buffer.length > 1) {\r\n    // Fast case, write everything using _writev()\r\n    var cbs = [];\r\n    for (var c = 0; c < state.buffer.length; c++)\r\n      cbs.push(state.buffer[c].callback);\r\n\r\n    // count the one we are adding, as well.\r\n    // TODO(isaacs) clean this up\r\n    state.pendingcb++;\r\n    doWrite(stream, state, true, state.length, state.buffer, '', function(err) {\r\n      for (var i = 0; i < cbs.length; i++) {\r\n        state.pendingcb--;\r\n        cbs[i](err);\r\n      }\r\n    });\r\n\r\n    // Clear buffer\r\n    state.buffer = [];\r\n  } else {\r\n    // Slow case, write chunks one-by-one\r\n    for (var c = 0; c < state.buffer.length; c++) {\r\n      var entry = state.buffer[c];\r\n      var chunk = entry.chunk;\r\n      var encoding = entry.encoding;\r\n      var cb = entry.callback;\r\n      var len = state.objectMode ? 1 : chunk.length;\r\n\r\n      doWrite(stream, state, false, len, chunk, encoding, cb);\r\n\r\n      // if we didn't call the onwrite immediately, then\r\n      // it means that we need to wait until it does.\r\n      // also, that means that the chunk and cb are currently\r\n      // being processed, so move the buffer counter past them.\r\n      if (state.writing) {\r\n        c++;\r\n        break;\r\n      }\r\n    }\r\n\r\n    if (c < state.buffer.length)\r\n      state.buffer = state.buffer.slice(c);\r\n    else\r\n      state.buffer.length = 0;\r\n  }\r\n\r\n  state.bufferProcessing = false;\r\n}\r\n\r\nWritable.prototype._write = function(chunk, encoding, cb) {\r\n  cb(new Error('not implemented'));\r\n\r\n};\r\n\r\nWritable.prototype._writev = null;\r\n\r\nWritable.prototype.end = function(chunk, encoding, cb) {\r\n  var state = this._writableState;\r\n\r\n  if (util.isFunction(chunk)) {\r\n    cb = chunk;\r\n    chunk = null;\r\n    encoding = null;\r\n  } else if (util.isFunction(encoding)) {\r\n    cb = encoding;\r\n    encoding = null;\r\n  }\r\n\r\n  if (!util.isNullOrUndefined(chunk))\r\n    this.write(chunk, encoding);\r\n\r\n  // .end() fully uncorks\r\n  if (state.corked) {\r\n    state.corked = 1;\r\n    this.uncork();\r\n  }\r\n\r\n  // ignore unnecessary end() calls.\r\n  if (!state.ending && !state.finished)\r\n    endWritable(this, state, cb);\r\n};\r\n\r\n\r\nfunction needFinish(stream, state) {\r\n  return (state.ending &&\r\n          state.length === 0 &&\r\n          !state.finished &&\r\n          !state.writing);\r\n}\r\n\r\nfunction prefinish(stream, state) {\r\n  if (!state.prefinished) {\r\n    state.prefinished = true;\r\n    stream.emit('prefinish');\r\n  }\r\n}\r\n\r\nfunction finishMaybe(stream, state) {\r\n  var need = needFinish(stream, state);\r\n  if (need) {\r\n    if (state.pendingcb === 0) {\r\n      prefinish(stream, state);\r\n      state.finished = true;\r\n      stream.emit('finish');\r\n    } else\r\n      prefinish(stream, state);\r\n  }\r\n  return need;\r\n}\r\n\r\nfunction endWritable(stream, state, cb) {\r\n  state.ending = true;\r\n  finishMaybe(stream, state);\r\n  if (cb) {\r\n    if (state.finished)\r\n      process.nextTick(cb);\r\n    else\r\n      stream.once('finish', cb);\r\n  }\r\n  state.ended = true;\r\n}\r\n\r\n}).call(this,require('_process'))\r\n},{\"./_stream_duplex\":53,\"_process\":51,\"buffer\":43,\"core-util-is\":58,\"inherits\":48,\"stream\":63}],58:[function(require,module,exports){\r\n(function (Buffer){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\n// NOTE: These type checking functions intentionally don't use `instanceof`\r\n// because it is fragile and can be easily faked with `Object.create()`.\r\nfunction isArray(ar) {\r\n  return Array.isArray(ar);\r\n}\r\nexports.isArray = isArray;\r\n\r\nfunction isBoolean(arg) {\r\n  return typeof arg === 'boolean';\r\n}\r\nexports.isBoolean = isBoolean;\r\n\r\nfunction isNull(arg) {\r\n  return arg === null;\r\n}\r\nexports.isNull = isNull;\r\n\r\nfunction isNullOrUndefined(arg) {\r\n  return arg == null;\r\n}\r\nexports.isNullOrUndefined = isNullOrUndefined;\r\n\r\nfunction isNumber(arg) {\r\n  return typeof arg === 'number';\r\n}\r\nexports.isNumber = isNumber;\r\n\r\nfunction isString(arg) {\r\n  return typeof arg === 'string';\r\n}\r\nexports.isString = isString;\r\n\r\nfunction isSymbol(arg) {\r\n  return typeof arg === 'symbol';\r\n}\r\nexports.isSymbol = isSymbol;\r\n\r\nfunction isUndefined(arg) {\r\n  return arg === void 0;\r\n}\r\nexports.isUndefined = isUndefined;\r\n\r\nfunction isRegExp(re) {\r\n  return isObject(re) && objectToString(re) === '[object RegExp]';\r\n}\r\nexports.isRegExp = isRegExp;\r\n\r\nfunction isObject(arg) {\r\n  return typeof arg === 'object' && arg !== null;\r\n}\r\nexports.isObject = isObject;\r\n\r\nfunction isDate(d) {\r\n  return isObject(d) && objectToString(d) === '[object Date]';\r\n}\r\nexports.isDate = isDate;\r\n\r\nfunction isError(e) {\r\n  return isObject(e) &&\r\n      (objectToString(e) === '[object Error]' || e instanceof Error);\r\n}\r\nexports.isError = isError;\r\n\r\nfunction isFunction(arg) {\r\n  return typeof arg === 'function';\r\n}\r\nexports.isFunction = isFunction;\r\n\r\nfunction isPrimitive(arg) {\r\n  return arg === null ||\r\n         typeof arg === 'boolean' ||\r\n         typeof arg === 'number' ||\r\n         typeof arg === 'string' ||\r\n         typeof arg === 'symbol' ||  // ES6 symbol\r\n         typeof arg === 'undefined';\r\n}\r\nexports.isPrimitive = isPrimitive;\r\n\r\nfunction isBuffer(arg) {\r\n  return Buffer.isBuffer(arg);\r\n}\r\nexports.isBuffer = isBuffer;\r\n\r\nfunction objectToString(o) {\r\n  return Object.prototype.toString.call(o);\r\n}\r\n}).call(this,require(\"buffer\").Buffer)\r\n},{\"buffer\":43}],59:[function(require,module,exports){\r\nmodule.exports = require(\"./lib/_stream_passthrough.js\")\r\n\r\n},{\"./lib/_stream_passthrough.js\":54}],60:[function(require,module,exports){\r\nexports = module.exports = require('./lib/_stream_readable.js');\r\nexports.Stream = require('stream');\r\nexports.Readable = exports;\r\nexports.Writable = require('./lib/_stream_writable.js');\r\nexports.Duplex = require('./lib/_stream_duplex.js');\r\nexports.Transform = require('./lib/_stream_transform.js');\r\nexports.PassThrough = require('./lib/_stream_passthrough.js');\r\n\r\n},{\"./lib/_stream_duplex.js\":53,\"./lib/_stream_passthrough.js\":54,\"./lib/_stream_readable.js\":55,\"./lib/_stream_transform.js\":56,\"./lib/_stream_writable.js\":57,\"stream\":63}],61:[function(require,module,exports){\r\nmodule.exports = require(\"./lib/_stream_transform.js\")\r\n\r\n},{\"./lib/_stream_transform.js\":56}],62:[function(require,module,exports){\r\nmodule.exports = require(\"./lib/_stream_writable.js\")\r\n\r\n},{\"./lib/_stream_writable.js\":57}],63:[function(require,module,exports){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\nmodule.exports = Stream;\r\n\r\nvar EE = require('events').EventEmitter;\r\nvar inherits = require('inherits');\r\n\r\ninherits(Stream, EE);\r\nStream.Readable = require('readable-stream/readable.js');\r\nStream.Writable = require('readable-stream/writable.js');\r\nStream.Duplex = require('readable-stream/duplex.js');\r\nStream.Transform = require('readable-stream/transform.js');\r\nStream.PassThrough = require('readable-stream/passthrough.js');\r\n\r\n// Backwards-compat with node 0.4.x\r\nStream.Stream = Stream;\r\n\r\n\r\n\r\n// old-style streams.  Note that the pipe method (the only relevant\r\n// part of this class) is overridden in the Readable class.\r\n\r\nfunction Stream() {\r\n  EE.call(this);\r\n}\r\n\r\nStream.prototype.pipe = function(dest, options) {\r\n  var source = this;\r\n\r\n  function ondata(chunk) {\r\n    if (dest.writable) {\r\n      if (false === dest.write(chunk) && source.pause) {\r\n        source.pause();\r\n      }\r\n    }\r\n  }\r\n\r\n  source.on('data', ondata);\r\n\r\n  function ondrain() {\r\n    if (source.readable && source.resume) {\r\n      source.resume();\r\n    }\r\n  }\r\n\r\n  dest.on('drain', ondrain);\r\n\r\n  // If the 'end' option is not supplied, dest.end() will be called when\r\n  // source gets the 'end' or 'close' events.  Only dest.end() once.\r\n  if (!dest._isStdio && (!options || options.end !== false)) {\r\n    source.on('end', onend);\r\n    source.on('close', onclose);\r\n  }\r\n\r\n  var didOnEnd = false;\r\n  function onend() {\r\n    if (didOnEnd) return;\r\n    didOnEnd = true;\r\n\r\n    dest.end();\r\n  }\r\n\r\n\r\n  function onclose() {\r\n    if (didOnEnd) return;\r\n    didOnEnd = true;\r\n\r\n    if (typeof dest.destroy === 'function') dest.destroy();\r\n  }\r\n\r\n  // don't leave dangling pipes when there are errors.\r\n  function onerror(er) {\r\n    cleanup();\r\n    if (EE.listenerCount(this, 'error') === 0) {\r\n      throw er; // Unhandled stream error in pipe.\r\n    }\r\n  }\r\n\r\n  source.on('error', onerror);\r\n  dest.on('error', onerror);\r\n\r\n  // remove all the event listeners that were added.\r\n  function cleanup() {\r\n    source.removeListener('data', ondata);\r\n    dest.removeListener('drain', ondrain);\r\n\r\n    source.removeListener('end', onend);\r\n    source.removeListener('close', onclose);\r\n\r\n    source.removeListener('error', onerror);\r\n    dest.removeListener('error', onerror);\r\n\r\n    source.removeListener('end', cleanup);\r\n    source.removeListener('close', cleanup);\r\n\r\n    dest.removeListener('close', cleanup);\r\n  }\r\n\r\n  source.on('end', cleanup);\r\n  source.on('close', cleanup);\r\n\r\n  dest.on('close', cleanup);\r\n\r\n  dest.emit('pipe', source);\r\n\r\n  // Allow for unix-like usage: A.pipe(B).pipe(C)\r\n  return dest;\r\n};\r\n\r\n},{\"events\":47,\"inherits\":48,\"readable-stream/duplex.js\":52,\"readable-stream/passthrough.js\":59,\"readable-stream/readable.js\":60,\"readable-stream/transform.js\":61,\"readable-stream/writable.js\":62}],64:[function(require,module,exports){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\nvar Buffer = require('buffer').Buffer;\r\n\r\nvar isBufferEncoding = Buffer.isEncoding\r\n  || function(encoding) {\r\n       switch (encoding && encoding.toLowerCase()) {\r\n         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;\r\n         default: return false;\r\n       }\r\n     }\r\n\r\n\r\nfunction assertEncoding(encoding) {\r\n  if (encoding && !isBufferEncoding(encoding)) {\r\n    throw new Error('Unknown encoding: ' + encoding);\r\n  }\r\n}\r\n\r\n// StringDecoder provides an interface for efficiently splitting a series of\r\n// buffers into a series of JS strings without breaking apart multi-byte\r\n// characters. CESU-8 is handled as part of the UTF-8 encoding.\r\n//\r\n// @TODO Handling all encodings inside a single object makes it very difficult\r\n// to reason about this code, so it should be split up in the future.\r\n// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code\r\n// points as used by CESU-8.\r\nvar StringDecoder = exports.StringDecoder = function(encoding) {\r\n  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');\r\n  assertEncoding(encoding);\r\n  switch (this.encoding) {\r\n    case 'utf8':\r\n      // CESU-8 represents each of Surrogate Pair by 3-bytes\r\n      this.surrogateSize = 3;\r\n      break;\r\n    case 'ucs2':\r\n    case 'utf16le':\r\n      // UTF-16 represents each of Surrogate Pair by 2-bytes\r\n      this.surrogateSize = 2;\r\n      this.detectIncompleteChar = utf16DetectIncompleteChar;\r\n      break;\r\n    case 'base64':\r\n      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.\r\n      this.surrogateSize = 3;\r\n      this.detectIncompleteChar = base64DetectIncompleteChar;\r\n      break;\r\n    default:\r\n      this.write = passThroughWrite;\r\n      return;\r\n  }\r\n\r\n  // Enough space to store all bytes of a single character. UTF-8 needs 4\r\n  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).\r\n  this.charBuffer = new Buffer(6);\r\n  // Number of bytes received for the current incomplete multi-byte character.\r\n  this.charReceived = 0;\r\n  // Number of bytes expected for the current incomplete multi-byte character.\r\n  this.charLength = 0;\r\n};\r\n\r\n\r\n// write decodes the given buffer and returns it as JS string that is\r\n// guaranteed to not contain any partial multi-byte characters. Any partial\r\n// character found at the end of the buffer is buffered up, and will be\r\n// returned when calling write again with the remaining bytes.\r\n//\r\n// Note: Converting a Buffer containing an orphan surrogate to a String\r\n// currently works, but converting a String to a Buffer (via `new Buffer`, or\r\n// Buffer#write) will replace incomplete surrogates with the unicode\r\n// replacement character. See https://codereview.chromium.org/121173009/ .\r\nStringDecoder.prototype.write = function(buffer) {\r\n  var charStr = '';\r\n  // if our last write ended with an incomplete multibyte character\r\n  while (this.charLength) {\r\n    // determine how many remaining bytes this buffer has to offer for this char\r\n    var available = (buffer.length >= this.charLength - this.charReceived) ?\r\n        this.charLength - this.charReceived :\r\n        buffer.length;\r\n\r\n    // add the new bytes to the char buffer\r\n    buffer.copy(this.charBuffer, this.charReceived, 0, available);\r\n    this.charReceived += available;\r\n\r\n    if (this.charReceived < this.charLength) {\r\n      // still not enough chars in this buffer? wait for more ...\r\n      return '';\r\n    }\r\n\r\n    // remove bytes belonging to the current character from the buffer\r\n    buffer = buffer.slice(available, buffer.length);\r\n\r\n    // get the character that was split\r\n    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);\r\n\r\n    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\r\n    var charCode = charStr.charCodeAt(charStr.length - 1);\r\n    if (charCode >= 0xD800 && charCode <= 0xDBFF) {\r\n      this.charLength += this.surrogateSize;\r\n      charStr = '';\r\n      continue;\r\n    }\r\n    this.charReceived = this.charLength = 0;\r\n\r\n    // if there are no more bytes in this buffer, just emit our char\r\n    if (buffer.length === 0) {\r\n      return charStr;\r\n    }\r\n    break;\r\n  }\r\n\r\n  // determine and set charLength / charReceived\r\n  this.detectIncompleteChar(buffer);\r\n\r\n  var end = buffer.length;\r\n  if (this.charLength) {\r\n    // buffer the incomplete character bytes we got\r\n    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);\r\n    end -= this.charReceived;\r\n  }\r\n\r\n  charStr += buffer.toString(this.encoding, 0, end);\r\n\r\n  var end = charStr.length - 1;\r\n  var charCode = charStr.charCodeAt(end);\r\n  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character\r\n  if (charCode >= 0xD800 && charCode <= 0xDBFF) {\r\n    var size = this.surrogateSize;\r\n    this.charLength += size;\r\n    this.charReceived += size;\r\n    this.charBuffer.copy(this.charBuffer, size, 0, size);\r\n    buffer.copy(this.charBuffer, 0, 0, size);\r\n    return charStr.substring(0, end);\r\n  }\r\n\r\n  // or just emit the charStr\r\n  return charStr;\r\n};\r\n\r\n// detectIncompleteChar determines if there is an incomplete UTF-8 character at\r\n// the end of the given buffer. If so, it sets this.charLength to the byte\r\n// length that character, and sets this.charReceived to the number of bytes\r\n// that are available for this character.\r\nStringDecoder.prototype.detectIncompleteChar = function(buffer) {\r\n  // determine how many bytes we have to check at the end of this buffer\r\n  var i = (buffer.length >= 3) ? 3 : buffer.length;\r\n\r\n  // Figure out if one of the last i bytes of our buffer announces an\r\n  // incomplete char.\r\n  for (; i > 0; i--) {\r\n    var c = buffer[buffer.length - i];\r\n\r\n    // See http://en.wikipedia.org/wiki/UTF-8#Description\r\n\r\n    // 110XXXXX\r\n    if (i == 1 && c >> 5 == 0x06) {\r\n      this.charLength = 2;\r\n      break;\r\n    }\r\n\r\n    // 1110XXXX\r\n    if (i <= 2 && c >> 4 == 0x0E) {\r\n      this.charLength = 3;\r\n      break;\r\n    }\r\n\r\n    // 11110XXX\r\n    if (i <= 3 && c >> 3 == 0x1E) {\r\n      this.charLength = 4;\r\n      break;\r\n    }\r\n  }\r\n  this.charReceived = i;\r\n};\r\n\r\nStringDecoder.prototype.end = function(buffer) {\r\n  var res = '';\r\n  if (buffer && buffer.length)\r\n    res = this.write(buffer);\r\n\r\n  if (this.charReceived) {\r\n    var cr = this.charReceived;\r\n    var buf = this.charBuffer;\r\n    var enc = this.encoding;\r\n    res += buf.slice(0, cr).toString(enc);\r\n  }\r\n\r\n  return res;\r\n};\r\n\r\nfunction passThroughWrite(buffer) {\r\n  return buffer.toString(this.encoding);\r\n}\r\n\r\nfunction utf16DetectIncompleteChar(buffer) {\r\n  this.charReceived = buffer.length % 2;\r\n  this.charLength = this.charReceived ? 2 : 0;\r\n}\r\n\r\nfunction base64DetectIncompleteChar(buffer) {\r\n  this.charReceived = buffer.length % 3;\r\n  this.charLength = this.charReceived ? 3 : 0;\r\n}\r\n\r\n},{\"buffer\":43}],65:[function(require,module,exports){\r\nmodule.exports = function isBuffer(arg) {\r\n  return arg && typeof arg === 'object'\r\n    && typeof arg.copy === 'function'\r\n    && typeof arg.fill === 'function'\r\n    && typeof arg.readUInt8 === 'function';\r\n}\r\n},{}],66:[function(require,module,exports){\r\n(function (process,global){\r\n// Copyright Joyent, Inc. and other Node contributors.\r\n//\r\n// Permission is hereby granted, free of charge, to any person obtaining a\r\n// copy of this software and associated documentation files (the\r\n// \"Software\"), to deal in the Software without restriction, including\r\n// without limitation the rights to use, copy, modify, merge, publish,\r\n// distribute, sublicense, and/or sell copies of the Software, and to permit\r\n// persons to whom the Software is furnished to do so, subject to the\r\n// following conditions:\r\n//\r\n// The above copyright notice and this permission notice shall be included\r\n// in all copies or substantial portions of the Software.\r\n//\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\r\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\r\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\r\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n\r\nvar formatRegExp = /%[sdj%]/g;\r\nexports.format = function(f) {\r\n  if (!isString(f)) {\r\n    var objects = [];\r\n    for (var i = 0; i < arguments.length; i++) {\r\n      objects.push(inspect(arguments[i]));\r\n    }\r\n    return objects.join(' ');\r\n  }\r\n\r\n  var i = 1;\r\n  var args = arguments;\r\n  var len = args.length;\r\n  var str = String(f).replace(formatRegExp, function(x) {\r\n    if (x === '%%') return '%';\r\n    if (i >= len) return x;\r\n    switch (x) {\r\n      case '%s': return String(args[i++]);\r\n      case '%d': return Number(args[i++]);\r\n      case '%j':\r\n        try {\r\n          return JSON.stringify(args[i++]);\r\n        } catch (_) {\r\n          return '[Circular]';\r\n        }\r\n      default:\r\n        return x;\r\n    }\r\n  });\r\n  for (var x = args[i]; i < len; x = args[++i]) {\r\n    if (isNull(x) || !isObject(x)) {\r\n      str += ' ' + x;\r\n    } else {\r\n      str += ' ' + inspect(x);\r\n    }\r\n  }\r\n  return str;\r\n};\r\n\r\n\r\n// Mark that a method should not be used.\r\n// Returns a modified function which warns once by default.\r\n// If --no-deprecation is set, then it is a no-op.\r\nexports.deprecate = function(fn, msg) {\r\n  // Allow for deprecating things in the process of starting up.\r\n  if (isUndefined(global.process)) {\r\n    return function() {\r\n      return exports.deprecate(fn, msg).apply(this, arguments);\r\n    };\r\n  }\r\n\r\n  if (process.noDeprecation === true) {\r\n    return fn;\r\n  }\r\n\r\n  var warned = false;\r\n  function deprecated() {\r\n    if (!warned) {\r\n      if (process.throwDeprecation) {\r\n        throw new Error(msg);\r\n      } else if (process.traceDeprecation) {\r\n        console.trace(msg);\r\n      } else {\r\n        console.error(msg);\r\n      }\r\n      warned = true;\r\n    }\r\n    return fn.apply(this, arguments);\r\n  }\r\n\r\n  return deprecated;\r\n};\r\n\r\n\r\nvar debugs = {};\r\nvar debugEnviron;\r\nexports.debuglog = function(set) {\r\n  if (isUndefined(debugEnviron))\r\n    debugEnviron = process.env.NODE_DEBUG || '';\r\n  set = set.toUpperCase();\r\n  if (!debugs[set]) {\r\n    if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\r\n      var pid = process.pid;\r\n      debugs[set] = function() {\r\n        var msg = exports.format.apply(exports, arguments);\r\n        console.error('%s %d: %s', set, pid, msg);\r\n      };\r\n    } else {\r\n      debugs[set] = function() {};\r\n    }\r\n  }\r\n  return debugs[set];\r\n};\r\n\r\n\r\n/**\r\n * Echos the value of a value. Trys to print the value out\r\n * in the best way possible given the different types.\r\n *\r\n * @param {Object} obj The object to print out.\r\n * @param {Object} opts Optional options object that alters the output.\r\n */\r\n/* legacy: obj, showHidden, depth, colors*/\r\nfunction inspect(obj, opts) {\r\n  // default options\r\n  var ctx = {\r\n    seen: [],\r\n    stylize: stylizeNoColor\r\n  };\r\n  // legacy...\r\n  if (arguments.length >= 3) ctx.depth = arguments[2];\r\n  if (arguments.length >= 4) ctx.colors = arguments[3];\r\n  if (isBoolean(opts)) {\r\n    // legacy...\r\n    ctx.showHidden = opts;\r\n  } else if (opts) {\r\n    // got an \"options\" object\r\n    exports._extend(ctx, opts);\r\n  }\r\n  // set default options\r\n  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\r\n  if (isUndefined(ctx.depth)) ctx.depth = 2;\r\n  if (isUndefined(ctx.colors)) ctx.colors = false;\r\n  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\r\n  if (ctx.colors) ctx.stylize = stylizeWithColor;\r\n  return formatValue(ctx, obj, ctx.depth);\r\n}\r\nexports.inspect = inspect;\r\n\r\n\r\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\r\ninspect.colors = {\r\n  'bold' : [1, 22],\r\n  'italic' : [3, 23],\r\n  'underline' : [4, 24],\r\n  'inverse' : [7, 27],\r\n  'white' : [37, 39],\r\n  'grey' : [90, 39],\r\n  'black' : [30, 39],\r\n  'blue' : [34, 39],\r\n  'cyan' : [36, 39],\r\n  'green' : [32, 39],\r\n  'magenta' : [35, 39],\r\n  'red' : [31, 39],\r\n  'yellow' : [33, 39]\r\n};\r\n\r\n// Don't use 'blue' not visible on cmd.exe\r\ninspect.styles = {\r\n  'special': 'cyan',\r\n  'number': 'yellow',\r\n  'boolean': 'yellow',\r\n  'undefined': 'grey',\r\n  'null': 'bold',\r\n  'string': 'green',\r\n  'date': 'magenta',\r\n  // \"name\": intentionally not styling\r\n  'regexp': 'red'\r\n};\r\n\r\n\r\nfunction stylizeWithColor(str, styleType) {\r\n  var style = inspect.styles[styleType];\r\n\r\n  if (style) {\r\n    return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\r\n           '\\u001b[' + inspect.colors[style][1] + 'm';\r\n  } else {\r\n    return str;\r\n  }\r\n}\r\n\r\n\r\nfunction stylizeNoColor(str, styleType) {\r\n  return str;\r\n}\r\n\r\n\r\nfunction arrayToHash(array) {\r\n  var hash = {};\r\n\r\n  array.forEach(function(val, idx) {\r\n    hash[val] = true;\r\n  });\r\n\r\n  return hash;\r\n}\r\n\r\n\r\nfunction formatValue(ctx, value, recurseTimes) {\r\n  // Provide a hook for user-specified inspect functions.\r\n  // Check that value is an object with an inspect function on it\r\n  if (ctx.customInspect &&\r\n      value &&\r\n      isFunction(value.inspect) &&\r\n      // Filter out the util module, it's inspect function is special\r\n      value.inspect !== exports.inspect &&\r\n      // Also filter out any prototype objects using the circular check.\r\n      !(value.constructor && value.constructor.prototype === value)) {\r\n    var ret = value.inspect(recurseTimes, ctx);\r\n    if (!isString(ret)) {\r\n      ret = formatValue(ctx, ret, recurseTimes);\r\n    }\r\n    return ret;\r\n  }\r\n\r\n  // Primitive types cannot have properties\r\n  var primitive = formatPrimitive(ctx, value);\r\n  if (primitive) {\r\n    return primitive;\r\n  }\r\n\r\n  // Look up the keys of the object.\r\n  var keys = Object.keys(value);\r\n  var visibleKeys = arrayToHash(keys);\r\n\r\n  if (ctx.showHidden) {\r\n    keys = Object.getOwnPropertyNames(value);\r\n  }\r\n\r\n  // IE doesn't make error fields non-enumerable\r\n  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\r\n  if (isError(value)\r\n      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\r\n    return formatError(value);\r\n  }\r\n\r\n  // Some type of object without properties can be shortcutted.\r\n  if (keys.length === 0) {\r\n    if (isFunction(value)) {\r\n      var name = value.name ? ': ' + value.name : '';\r\n      return ctx.stylize('[Function' + name + ']', 'special');\r\n    }\r\n    if (isRegExp(value)) {\r\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\r\n    }\r\n    if (isDate(value)) {\r\n      return ctx.stylize(Date.prototype.toString.call(value), 'date');\r\n    }\r\n    if (isError(value)) {\r\n      return formatError(value);\r\n    }\r\n  }\r\n\r\n  var base = '', array = false, braces = ['{', '}'];\r\n\r\n  // Make Array say that they are Array\r\n  if (isArray(value)) {\r\n    array = true;\r\n    braces = ['[', ']'];\r\n  }\r\n\r\n  // Make functions say that they are functions\r\n  if (isFunction(value)) {\r\n    var n = value.name ? ': ' + value.name : '';\r\n    base = ' [Function' + n + ']';\r\n  }\r\n\r\n  // Make RegExps say that they are RegExps\r\n  if (isRegExp(value)) {\r\n    base = ' ' + RegExp.prototype.toString.call(value);\r\n  }\r\n\r\n  // Make dates with properties first say the date\r\n  if (isDate(value)) {\r\n    base = ' ' + Date.prototype.toUTCString.call(value);\r\n  }\r\n\r\n  // Make error with message first say the error\r\n  if (isError(value)) {\r\n    base = ' ' + formatError(value);\r\n  }\r\n\r\n  if (keys.length === 0 && (!array || value.length == 0)) {\r\n    return braces[0] + base + braces[1];\r\n  }\r\n\r\n  if (recurseTimes < 0) {\r\n    if (isRegExp(value)) {\r\n      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\r\n    } else {\r\n      return ctx.stylize('[Object]', 'special');\r\n    }\r\n  }\r\n\r\n  ctx.seen.push(value);\r\n\r\n  var output;\r\n  if (array) {\r\n    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\r\n  } else {\r\n    output = keys.map(function(key) {\r\n      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\r\n    });\r\n  }\r\n\r\n  ctx.seen.pop();\r\n\r\n  return reduceToSingleString(output, base, braces);\r\n}\r\n\r\n\r\nfunction formatPrimitive(ctx, value) {\r\n  if (isUndefined(value))\r\n    return ctx.stylize('undefined', 'undefined');\r\n  if (isString(value)) {\r\n    var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\r\n                                             .replace(/'/g, \"\\\\'\")\r\n                                             .replace(/\\\\\"/g, '\"') + '\\'';\r\n    return ctx.stylize(simple, 'string');\r\n  }\r\n  if (isNumber(value))\r\n    return ctx.stylize('' + value, 'number');\r\n  if (isBoolean(value))\r\n    return ctx.stylize('' + value, 'boolean');\r\n  // For some reason typeof null is \"object\", so special case here.\r\n  if (isNull(value))\r\n    return ctx.stylize('null', 'null');\r\n}\r\n\r\n\r\nfunction formatError(value) {\r\n  return '[' + Error.prototype.toString.call(value) + ']';\r\n}\r\n\r\n\r\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\r\n  var output = [];\r\n  for (var i = 0, l = value.length; i < l; ++i) {\r\n    if (hasOwnProperty(value, String(i))) {\r\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\r\n          String(i), true));\r\n    } else {\r\n      output.push('');\r\n    }\r\n  }\r\n  keys.forEach(function(key) {\r\n    if (!key.match(/^\\d+$/)) {\r\n      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\r\n          key, true));\r\n    }\r\n  });\r\n  return output;\r\n}\r\n\r\n\r\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\r\n  var name, str, desc;\r\n  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\r\n  if (desc.get) {\r\n    if (desc.set) {\r\n      str = ctx.stylize('[Getter/Setter]', 'special');\r\n    } else {\r\n      str = ctx.stylize('[Getter]', 'special');\r\n    }\r\n  } else {\r\n    if (desc.set) {\r\n      str = ctx.stylize('[Setter]', 'special');\r\n    }\r\n  }\r\n  if (!hasOwnProperty(visibleKeys, key)) {\r\n    name = '[' + key + ']';\r\n  }\r\n  if (!str) {\r\n    if (ctx.seen.indexOf(desc.value) < 0) {\r\n      if (isNull(recurseTimes)) {\r\n        str = formatValue(ctx, desc.value, null);\r\n      } else {\r\n        str = formatValue(ctx, desc.value, recurseTimes - 1);\r\n      }\r\n      if (str.indexOf('\\n') > -1) {\r\n        if (array) {\r\n          str = str.split('\\n').map(function(line) {\r\n            return '  ' + line;\r\n          }).join('\\n').substr(2);\r\n        } else {\r\n          str = '\\n' + str.split('\\n').map(function(line) {\r\n            return '   ' + line;\r\n          }).join('\\n');\r\n        }\r\n      }\r\n    } else {\r\n      str = ctx.stylize('[Circular]', 'special');\r\n    }\r\n  }\r\n  if (isUndefined(name)) {\r\n    if (array && key.match(/^\\d+$/)) {\r\n      return str;\r\n    }\r\n    name = JSON.stringify('' + key);\r\n    if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\r\n      name = name.substr(1, name.length - 2);\r\n      name = ctx.stylize(name, 'name');\r\n    } else {\r\n      name = name.replace(/'/g, \"\\\\'\")\r\n                 .replace(/\\\\\"/g, '\"')\r\n                 .replace(/(^\"|\"$)/g, \"'\");\r\n      name = ctx.stylize(name, 'string');\r\n    }\r\n  }\r\n\r\n  return name + ': ' + str;\r\n}\r\n\r\n\r\nfunction reduceToSingleString(output, base, braces) {\r\n  var numLinesEst = 0;\r\n  var length = output.reduce(function(prev, cur) {\r\n    numLinesEst++;\r\n    if (cur.indexOf('\\n') >= 0) numLinesEst++;\r\n    return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\r\n  }, 0);\r\n\r\n  if (length > 60) {\r\n    return braces[0] +\r\n           (base === '' ? '' : base + '\\n ') +\r\n           ' ' +\r\n           output.join(',\\n  ') +\r\n           ' ' +\r\n           braces[1];\r\n  }\r\n\r\n  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\r\n}\r\n\r\n\r\n// NOTE: These type checking functions intentionally don't use `instanceof`\r\n// because it is fragile and can be easily faked with `Object.create()`.\r\nfunction isArray(ar) {\r\n  return Array.isArray(ar);\r\n}\r\nexports.isArray = isArray;\r\n\r\nfunction isBoolean(arg) {\r\n  return typeof arg === 'boolean';\r\n}\r\nexports.isBoolean = isBoolean;\r\n\r\nfunction isNull(arg) {\r\n  return arg === null;\r\n}\r\nexports.isNull = isNull;\r\n\r\nfunction isNullOrUndefined(arg) {\r\n  return arg == null;\r\n}\r\nexports.isNullOrUndefined = isNullOrUndefined;\r\n\r\nfunction isNumber(arg) {\r\n  return typeof arg === 'number';\r\n}\r\nexports.isNumber = isNumber;\r\n\r\nfunction isString(arg) {\r\n  return typeof arg === 'string';\r\n}\r\nexports.isString = isString;\r\n\r\nfunction isSymbol(arg) {\r\n  return typeof arg === 'symbol';\r\n}\r\nexports.isSymbol = isSymbol;\r\n\r\nfunction isUndefined(arg) {\r\n  return arg === void 0;\r\n}\r\nexports.isUndefined = isUndefined;\r\n\r\nfunction isRegExp(re) {\r\n  return isObject(re) && objectToString(re) === '[object RegExp]';\r\n}\r\nexports.isRegExp = isRegExp;\r\n\r\nfunction isObject(arg) {\r\n  return typeof arg === 'object' && arg !== null;\r\n}\r\nexports.isObject = isObject;\r\n\r\nfunction isDate(d) {\r\n  return isObject(d) && objectToString(d) === '[object Date]';\r\n}\r\nexports.isDate = isDate;\r\n\r\nfunction isError(e) {\r\n  return isObject(e) &&\r\n      (objectToString(e) === '[object Error]' || e instanceof Error);\r\n}\r\nexports.isError = isError;\r\n\r\nfunction isFunction(arg) {\r\n  return typeof arg === 'function';\r\n}\r\nexports.isFunction = isFunction;\r\n\r\nfunction isPrimitive(arg) {\r\n  return arg === null ||\r\n         typeof arg === 'boolean' ||\r\n         typeof arg === 'number' ||\r\n         typeof arg === 'string' ||\r\n         typeof arg === 'symbol' ||  // ES6 symbol\r\n         typeof arg === 'undefined';\r\n}\r\nexports.isPrimitive = isPrimitive;\r\n\r\nexports.isBuffer = require('./support/isBuffer');\r\n\r\nfunction objectToString(o) {\r\n  return Object.prototype.toString.call(o);\r\n}\r\n\r\n\r\nfunction pad(n) {\r\n  return n < 10 ? '0' + n.toString(10) : n.toString(10);\r\n}\r\n\r\n\r\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\r\n              'Oct', 'Nov', 'Dec'];\r\n\r\n// 26 Feb 16:19:34\r\nfunction timestamp() {\r\n  var d = new Date();\r\n  var time = [pad(d.getHours()),\r\n              pad(d.getMinutes()),\r\n              pad(d.getSeconds())].join(':');\r\n  return [d.getDate(), months[d.getMonth()], time].join(' ');\r\n}\r\n\r\n\r\n// log is just a thin wrapper to console.log that prepends a timestamp\r\nexports.log = function() {\r\n  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\r\n};\r\n\r\n\r\n/**\r\n * Inherit the prototype methods from one constructor into another.\r\n *\r\n * The Function.prototype.inherits from lang.js rewritten as a standalone\r\n * function (not on Function.prototype). NOTE: If this file is to be loaded\r\n * during bootstrapping this function needs to be rewritten using some native\r\n * functions as prototype setup using normal JavaScript does not work as\r\n * expected during bootstrapping (see mirror.js in r114903).\r\n *\r\n * @param {function} ctor Constructor function which needs to inherit the\r\n *     prototype.\r\n * @param {function} superCtor Constructor function to inherit prototype from.\r\n */\r\nexports.inherits = require('inherits');\r\n\r\nexports._extend = function(origin, add) {\r\n  // Don't do anything if add isn't an object\r\n  if (!add || !isObject(add)) return origin;\r\n\r\n  var keys = Object.keys(add);\r\n  var i = keys.length;\r\n  while (i--) {\r\n    origin[keys[i]] = add[keys[i]];\r\n  }\r\n  return origin;\r\n};\r\n\r\nfunction hasOwnProperty(obj, prop) {\r\n  return Object.prototype.hasOwnProperty.call(obj, prop);\r\n}\r\n\r\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"./support/isBuffer\":65,\"_process\":51,\"inherits\":48}],67:[function(require,module,exports){\r\n/* See LICENSE file for terms of use */\r\n\r\n/*\r\n * Text diff implementation.\r\n *\r\n * This library supports the following APIS:\r\n * JsDiff.diffChars: Character by character diff\r\n * JsDiff.diffWords: Word (as defined by \\b regex) diff which ignores whitespace\r\n * JsDiff.diffLines: Line based diff\r\n *\r\n * JsDiff.diffCss: Diff targeted at CSS content\r\n *\r\n * These methods are based on the implementation proposed in\r\n * \"An O(ND) Difference Algorithm and its Variations\" (Myers, 1986).\r\n * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927\r\n */\r\n(function(global, undefined) {\r\n  var objectPrototypeToString = Object.prototype.toString;\r\n\r\n  /*istanbul ignore next*/\r\n  function map(arr, mapper, that) {\r\n    if (Array.prototype.map) {\r\n      return Array.prototype.map.call(arr, mapper, that);\r\n    }\r\n\r\n    var other = new Array(arr.length);\r\n\r\n    for (var i = 0, n = arr.length; i < n; i++) {\r\n      other[i] = mapper.call(that, arr[i], i, arr);\r\n    }\r\n    return other;\r\n  }\r\n  function clonePath(path) {\r\n    return { newPos: path.newPos, components: path.components.slice(0) };\r\n  }\r\n  function removeEmpty(array) {\r\n    var ret = [];\r\n    for (var i = 0; i < array.length; i++) {\r\n      if (array[i]) {\r\n        ret.push(array[i]);\r\n      }\r\n    }\r\n    return ret;\r\n  }\r\n  function escapeHTML(s) {\r\n    var n = s;\r\n    n = n.replace(/&/g, '&amp;');\r\n    n = n.replace(/</g, '&lt;');\r\n    n = n.replace(/>/g, '&gt;');\r\n    n = n.replace(/\"/g, '&quot;');\r\n\r\n    return n;\r\n  }\r\n\r\n  // This function handles the presence of circular references by bailing out when encountering an\r\n  // object that is already on the \"stack\" of items being processed.\r\n  function canonicalize(obj, stack, replacementStack) {\r\n    stack = stack || [];\r\n    replacementStack = replacementStack || [];\r\n\r\n    var i;\r\n\r\n    for (i = 0; i < stack.length; i += 1) {\r\n      if (stack[i] === obj) {\r\n        return replacementStack[i];\r\n      }\r\n    }\r\n\r\n    var canonicalizedObj;\r\n\r\n    if ('[object Array]' === objectPrototypeToString.call(obj)) {\r\n      stack.push(obj);\r\n      canonicalizedObj = new Array(obj.length);\r\n      replacementStack.push(canonicalizedObj);\r\n      for (i = 0; i < obj.length; i += 1) {\r\n        canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack);\r\n      }\r\n      stack.pop();\r\n      replacementStack.pop();\r\n    } else if (typeof obj === 'object' && obj !== null) {\r\n      stack.push(obj);\r\n      canonicalizedObj = {};\r\n      replacementStack.push(canonicalizedObj);\r\n      var sortedKeys = [],\r\n          key;\r\n      for (key in obj) {\r\n        sortedKeys.push(key);\r\n      }\r\n      sortedKeys.sort();\r\n      for (i = 0; i < sortedKeys.length; i += 1) {\r\n        key = sortedKeys[i];\r\n        canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack);\r\n      }\r\n      stack.pop();\r\n      replacementStack.pop();\r\n    } else {\r\n      canonicalizedObj = obj;\r\n    }\r\n    return canonicalizedObj;\r\n  }\r\n\r\n  function buildValues(components, newString, oldString, useLongestToken) {\r\n    var componentPos = 0,\r\n        componentLen = components.length,\r\n        newPos = 0,\r\n        oldPos = 0;\r\n\r\n    for (; componentPos < componentLen; componentPos++) {\r\n      var component = components[componentPos];\r\n      if (!component.removed) {\r\n        if (!component.added && useLongestToken) {\r\n          var value = newString.slice(newPos, newPos + component.count);\r\n          value = map(value, function(value, i) {\r\n            var oldValue = oldString[oldPos + i];\r\n            return oldValue.length > value.length ? oldValue : value;\r\n          });\r\n\r\n          component.value = value.join('');\r\n        } else {\r\n          component.value = newString.slice(newPos, newPos + component.count).join('');\r\n        }\r\n        newPos += component.count;\r\n\r\n        // Common case\r\n        if (!component.added) {\r\n          oldPos += component.count;\r\n        }\r\n      } else {\r\n        component.value = oldString.slice(oldPos, oldPos + component.count).join('');\r\n        oldPos += component.count;\r\n\r\n        // Reverse add and remove so removes are output first to match common convention\r\n        // The diffing algorithm is tied to add then remove output and this is the simplest\r\n        // route to get the desired output with minimal overhead.\r\n        if (componentPos && components[componentPos - 1].added) {\r\n          var tmp = components[componentPos - 1];\r\n          components[componentPos - 1] = components[componentPos];\r\n          components[componentPos] = tmp;\r\n        }\r\n      }\r\n    }\r\n\r\n    return components;\r\n  }\r\n\r\n  function Diff(ignoreWhitespace) {\r\n    this.ignoreWhitespace = ignoreWhitespace;\r\n  }\r\n  Diff.prototype = {\r\n    diff: function(oldString, newString, callback) {\r\n      var self = this;\r\n\r\n      function done(value) {\r\n        if (callback) {\r\n          setTimeout(function() { callback(undefined, value); }, 0);\r\n          return true;\r\n        } else {\r\n          return value;\r\n        }\r\n      }\r\n\r\n      // Handle the identity case (this is due to unrolling editLength == 0\r\n      if (newString === oldString) {\r\n        return done([{ value: newString }]);\r\n      }\r\n      if (!newString) {\r\n        return done([{ value: oldString, removed: true }]);\r\n      }\r\n      if (!oldString) {\r\n        return done([{ value: newString, added: true }]);\r\n      }\r\n\r\n      newString = this.tokenize(newString);\r\n      oldString = this.tokenize(oldString);\r\n\r\n      var newLen = newString.length, oldLen = oldString.length;\r\n      var editLength = 1;\r\n      var maxEditLength = newLen + oldLen;\r\n      var bestPath = [{ newPos: -1, components: [] }];\r\n\r\n      // Seed editLength = 0, i.e. the content starts with the same values\r\n      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);\r\n      if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\r\n        // Identity per the equality and tokenizer\r\n        return done([{value: newString.join('')}]);\r\n      }\r\n\r\n      // Main worker method. checks all permutations of a given edit length for acceptance.\r\n      function execEditLength() {\r\n        for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {\r\n          var basePath;\r\n          var addPath = bestPath[diagonalPath - 1],\r\n              removePath = bestPath[diagonalPath + 1],\r\n              oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;\r\n          if (addPath) {\r\n            // No one else is going to attempt to use this value, clear it\r\n            bestPath[diagonalPath - 1] = undefined;\r\n          }\r\n\r\n          var canAdd = addPath && addPath.newPos + 1 < newLen,\r\n              canRemove = removePath && 0 <= oldPos && oldPos < oldLen;\r\n          if (!canAdd && !canRemove) {\r\n            // If this path is a terminal then prune\r\n            bestPath[diagonalPath] = undefined;\r\n            continue;\r\n          }\r\n\r\n          // Select the diagonal that we want to branch from. We select the prior\r\n          // path whose position in the new string is the farthest from the origin\r\n          // and does not pass the bounds of the diff graph\r\n          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {\r\n            basePath = clonePath(removePath);\r\n            self.pushComponent(basePath.components, undefined, true);\r\n          } else {\r\n            basePath = addPath;   // No need to clone, we've pulled it from the list\r\n            basePath.newPos++;\r\n            self.pushComponent(basePath.components, true, undefined);\r\n          }\r\n\r\n          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);\r\n\r\n          // If we have hit the end of both strings, then we are done\r\n          if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {\r\n            return done(buildValues(basePath.components, newString, oldString, self.useLongestToken));\r\n          } else {\r\n            // Otherwise track this path as a potential candidate and continue.\r\n            bestPath[diagonalPath] = basePath;\r\n          }\r\n        }\r\n\r\n        editLength++;\r\n      }\r\n\r\n      // Performs the length of edit iteration. Is a bit fugly as this has to support the\r\n      // sync and async mode which is never fun. Loops over execEditLength until a value\r\n      // is produced.\r\n      if (callback) {\r\n        (function exec() {\r\n          setTimeout(function() {\r\n            // This should not happen, but we want to be safe.\r\n            /*istanbul ignore next */\r\n            if (editLength > maxEditLength) {\r\n              return callback();\r\n            }\r\n\r\n            if (!execEditLength()) {\r\n              exec();\r\n            }\r\n          }, 0);\r\n        }());\r\n      } else {\r\n        while (editLength <= maxEditLength) {\r\n          var ret = execEditLength();\r\n          if (ret) {\r\n            return ret;\r\n          }\r\n        }\r\n      }\r\n    },\r\n\r\n    pushComponent: function(components, added, removed) {\r\n      var last = components[components.length - 1];\r\n      if (last && last.added === added && last.removed === removed) {\r\n        // We need to clone here as the component clone operation is just\r\n        // as shallow array clone\r\n        components[components.length - 1] = {count: last.count + 1, added: added, removed: removed };\r\n      } else {\r\n        components.push({count: 1, added: added, removed: removed });\r\n      }\r\n    },\r\n    extractCommon: function(basePath, newString, oldString, diagonalPath) {\r\n      var newLen = newString.length,\r\n          oldLen = oldString.length,\r\n          newPos = basePath.newPos,\r\n          oldPos = newPos - diagonalPath,\r\n\r\n          commonCount = 0;\r\n      while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {\r\n        newPos++;\r\n        oldPos++;\r\n        commonCount++;\r\n      }\r\n\r\n      if (commonCount) {\r\n        basePath.components.push({count: commonCount});\r\n      }\r\n\r\n      basePath.newPos = newPos;\r\n      return oldPos;\r\n    },\r\n\r\n    equals: function(left, right) {\r\n      var reWhitespace = /\\S/;\r\n      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));\r\n    },\r\n    tokenize: function(value) {\r\n      return value.split('');\r\n    }\r\n  };\r\n\r\n  var CharDiff = new Diff();\r\n\r\n  var WordDiff = new Diff(true);\r\n  var WordWithSpaceDiff = new Diff();\r\n  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {\r\n    return removeEmpty(value.split(/(\\s+|\\b)/));\r\n  };\r\n\r\n  var CssDiff = new Diff(true);\r\n  CssDiff.tokenize = function(value) {\r\n    return removeEmpty(value.split(/([{}:;,]|\\s+)/));\r\n  };\r\n\r\n  var LineDiff = new Diff();\r\n\r\n  var TrimmedLineDiff = new Diff();\r\n  TrimmedLineDiff.ignoreTrim = true;\r\n\r\n  LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) {\r\n    var retLines = [],\r\n        lines = value.split(/^/m);\r\n    for (var i = 0; i < lines.length; i++) {\r\n      var line = lines[i],\r\n          lastLine = lines[i - 1],\r\n          lastLineLastChar = lastLine && lastLine[lastLine.length - 1];\r\n\r\n      // Merge lines that may contain windows new lines\r\n      if (line === '\\n' && lastLineLastChar === '\\r') {\r\n          retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\\r\\n';\r\n      } else {\r\n        if (this.ignoreTrim) {\r\n          line = line.trim();\r\n          // add a newline unless this is the last line.\r\n          if (i < lines.length - 1) {\r\n            line += '\\n';\r\n          }\r\n        }\r\n        retLines.push(line);\r\n      }\r\n    }\r\n\r\n    return retLines;\r\n  };\r\n\r\n  var PatchDiff = new Diff();\r\n  PatchDiff.tokenize = function(value) {\r\n    var ret = [],\r\n        linesAndNewlines = value.split(/(\\n|\\r\\n)/);\r\n\r\n    // Ignore the final empty token that occurs if the string ends with a new line\r\n    if (!linesAndNewlines[linesAndNewlines.length - 1]) {\r\n      linesAndNewlines.pop();\r\n    }\r\n\r\n    // Merge the content and line separators into single tokens\r\n    for (var i = 0; i < linesAndNewlines.length; i++) {\r\n      var line = linesAndNewlines[i];\r\n\r\n      if (i % 2) {\r\n        ret[ret.length - 1] += line;\r\n      } else {\r\n        ret.push(line);\r\n      }\r\n    }\r\n    return ret;\r\n  };\r\n\r\n  var SentenceDiff = new Diff();\r\n  SentenceDiff.tokenize = function(value) {\r\n    return removeEmpty(value.split(/(\\S.+?[.!?])(?=\\s+|$)/));\r\n  };\r\n\r\n  var JsonDiff = new Diff();\r\n  // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a\r\n  // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output:\r\n  JsonDiff.useLongestToken = true;\r\n  JsonDiff.tokenize = LineDiff.tokenize;\r\n  JsonDiff.equals = function(left, right) {\r\n    return LineDiff.equals(left.replace(/,([\\r\\n])/g, '$1'), right.replace(/,([\\r\\n])/g, '$1'));\r\n  };\r\n\r\n  var JsDiff = {\r\n    Diff: Diff,\r\n\r\n    diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); },\r\n    diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); },\r\n    diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); },\r\n    diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); },\r\n    diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); },\r\n\r\n    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },\r\n\r\n    diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); },\r\n    diffJson: function(oldObj, newObj, callback) {\r\n      return JsonDiff.diff(\r\n        typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, '  '),\r\n        typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, '  '),\r\n        callback\r\n      );\r\n    },\r\n\r\n    createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) {\r\n      var ret = [];\r\n\r\n      if (oldFileName == newFileName) {\r\n        ret.push('Index: ' + oldFileName);\r\n      }\r\n      ret.push('===================================================================');\r\n      ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\\t' + oldHeader));\r\n      ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\\t' + newHeader));\r\n\r\n      var diff = PatchDiff.diff(oldStr, newStr);\r\n      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier\r\n\r\n      // Formats a given set of lines for printing as context lines in a patch\r\n      function contextLines(lines) {\r\n        return map(lines, function(entry) { return ' ' + entry; });\r\n      }\r\n\r\n      // Outputs the no newline at end of file warning if needed\r\n      function eofNL(curRange, i, current) {\r\n        var last = diff[diff.length - 2],\r\n            isLast = i === diff.length - 2,\r\n            isLastOfType = i === diff.length - 3 && current.added !== last.added;\r\n\r\n        // Figure out if this is the last line for the given file and missing NL\r\n        if (!(/\\n$/.test(current.value)) && (isLast || isLastOfType)) {\r\n          curRange.push('\\\\ No newline at end of file');\r\n        }\r\n      }\r\n\r\n      var oldRangeStart = 0, newRangeStart = 0, curRange = [],\r\n          oldLine = 1, newLine = 1;\r\n      for (var i = 0; i < diff.length; i++) {\r\n        var current = diff[i],\r\n            lines = current.lines || current.value.replace(/\\n$/, '').split('\\n');\r\n        current.lines = lines;\r\n\r\n        if (current.added || current.removed) {\r\n          // If we have previous context, start with that\r\n          if (!oldRangeStart) {\r\n            var prev = diff[i - 1];\r\n            oldRangeStart = oldLine;\r\n            newRangeStart = newLine;\r\n\r\n            if (prev) {\r\n              curRange = contextLines(prev.lines.slice(-4));\r\n              oldRangeStart -= curRange.length;\r\n              newRangeStart -= curRange.length;\r\n            }\r\n          }\r\n\r\n          // Output our changes\r\n          curRange.push.apply(curRange, map(lines, function(entry) {\r\n            return (current.added ? '+' : '-') + entry;\r\n          }));\r\n          eofNL(curRange, i, current);\r\n\r\n          // Track the updated file position\r\n          if (current.added) {\r\n            newLine += lines.length;\r\n          } else {\r\n            oldLine += lines.length;\r\n          }\r\n        } else {\r\n          // Identical context lines. Track line changes\r\n          if (oldRangeStart) {\r\n            // Close out any changes that have been output (or join overlapping)\r\n            if (lines.length <= 8 && i < diff.length - 2) {\r\n              // Overlapping\r\n              curRange.push.apply(curRange, contextLines(lines));\r\n            } else {\r\n              // end the range and output\r\n              var contextSize = Math.min(lines.length, 4);\r\n              ret.push(\r\n                  '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize)\r\n                  + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize)\r\n                  + ' @@');\r\n              ret.push.apply(ret, curRange);\r\n              ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));\r\n              if (lines.length <= 4) {\r\n                eofNL(ret, i, current);\r\n              }\r\n\r\n              oldRangeStart = 0;\r\n              newRangeStart = 0;\r\n              curRange = [];\r\n            }\r\n          }\r\n          oldLine += lines.length;\r\n          newLine += lines.length;\r\n        }\r\n      }\r\n\r\n      return ret.join('\\n') + '\\n';\r\n    },\r\n\r\n    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {\r\n      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);\r\n    },\r\n\r\n    applyPatch: function(oldStr, uniDiff) {\r\n      var diffstr = uniDiff.split('\\n'),\r\n          hunks = [],\r\n          i = 0,\r\n          remEOFNL = false,\r\n          addEOFNL = false;\r\n\r\n      // Skip to the first change hunk\r\n      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {\r\n        i++;\r\n      }\r\n\r\n      // Parse the unified diff\r\n      for (; i < diffstr.length; i++) {\r\n        if (diffstr[i][0] === '@') {\r\n          var chnukHeader = diffstr[i].split(/@@ -(\\d+),(\\d+) \\+(\\d+),(\\d+) @@/);\r\n          hunks.unshift({\r\n            start: chnukHeader[3],\r\n            oldlength: +chnukHeader[2],\r\n            removed: [],\r\n            newlength: chnukHeader[4],\r\n            added: []\r\n          });\r\n        } else if (diffstr[i][0] === '+') {\r\n          hunks[0].added.push(diffstr[i].substr(1));\r\n        } else if (diffstr[i][0] === '-') {\r\n          hunks[0].removed.push(diffstr[i].substr(1));\r\n        } else if (diffstr[i][0] === ' ') {\r\n          hunks[0].added.push(diffstr[i].substr(1));\r\n          hunks[0].removed.push(diffstr[i].substr(1));\r\n        } else if (diffstr[i][0] === '\\\\') {\r\n          if (diffstr[i - 1][0] === '+') {\r\n            remEOFNL = true;\r\n          } else if (diffstr[i - 1][0] === '-') {\r\n            addEOFNL = true;\r\n          }\r\n        }\r\n      }\r\n\r\n      // Apply the diff to the input\r\n      var lines = oldStr.split('\\n');\r\n      for (i = hunks.length - 1; i >= 0; i--) {\r\n        var hunk = hunks[i];\r\n        // Sanity check the input string. Bail if we don't match.\r\n        for (var j = 0; j < hunk.oldlength; j++) {\r\n          if (lines[hunk.start - 1 + j] !== hunk.removed[j]) {\r\n            return false;\r\n          }\r\n        }\r\n        Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added));\r\n      }\r\n\r\n      // Handle EOFNL insertion/removal\r\n      if (remEOFNL) {\r\n        while (!lines[lines.length - 1]) {\r\n          lines.pop();\r\n        }\r\n      } else if (addEOFNL) {\r\n        lines.push('');\r\n      }\r\n      return lines.join('\\n');\r\n    },\r\n\r\n    convertChangesToXML: function(changes) {\r\n      var ret = [];\r\n      for (var i = 0; i < changes.length; i++) {\r\n        var change = changes[i];\r\n        if (change.added) {\r\n          ret.push('<ins>');\r\n        } else if (change.removed) {\r\n          ret.push('<del>');\r\n        }\r\n\r\n        ret.push(escapeHTML(change.value));\r\n\r\n        if (change.added) {\r\n          ret.push('</ins>');\r\n        } else if (change.removed) {\r\n          ret.push('</del>');\r\n        }\r\n      }\r\n      return ret.join('');\r\n    },\r\n\r\n    // See: http://code.google.com/p/google-diff-match-patch/wiki/API\r\n    convertChangesToDMP: function(changes) {\r\n      var ret = [],\r\n          change,\r\n          operation;\r\n      for (var i = 0; i < changes.length; i++) {\r\n        change = changes[i];\r\n        if (change.added) {\r\n          operation = 1;\r\n        } else if (change.removed) {\r\n          operation = -1;\r\n        } else {\r\n          operation = 0;\r\n        }\r\n\r\n        ret.push([operation, change.value]);\r\n      }\r\n      return ret;\r\n    },\r\n\r\n    canonicalize: canonicalize\r\n  };\r\n\r\n  /*istanbul ignore next */\r\n  /*global module */\r\n  if (typeof module !== 'undefined' && module.exports) {\r\n    module.exports = JsDiff;\r\n  } else if (typeof define === 'function' && define.amd) {\r\n    /*global define */\r\n    define([], function() { return JsDiff; });\r\n  } else if (typeof global.JsDiff === 'undefined') {\r\n    global.JsDiff = JsDiff;\r\n  }\r\n}(this));\r\n\r\n},{}],68:[function(require,module,exports){\r\n'use strict';\r\n\r\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\r\n\r\nmodule.exports = function (str) {\r\n\tif (typeof str !== 'string') {\r\n\t\tthrow new TypeError('Expected a string');\r\n\t}\r\n\r\n\treturn str.replace(matchOperatorsRe,  '\\\\$&');\r\n};\r\n\r\n},{}],69:[function(require,module,exports){\r\n(function (process){\r\n// Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)\r\n\r\n/**\r\n * Module dependencies.\r\n */\r\n\r\nvar exec = require('child_process').exec\r\n  , fs = require('fs')\r\n  , path = require('path')\r\n  , exists = fs.existsSync || path.existsSync\r\n  , os = require('os')\r\n  , quote = JSON.stringify\r\n  , cmd;\r\n\r\nfunction which(name) {\r\n  var paths = process.env.PATH.split(':');\r\n  var loc;\r\n  \r\n  for (var i = 0, len = paths.length; i < len; ++i) {\r\n    loc = path.join(paths[i], name);\r\n    if (exists(loc)) return loc;\r\n  }\r\n}\r\n\r\nswitch(os.type()) {\r\n  case 'Darwin':\r\n    if (which('terminal-notifier')) {\r\n      cmd = {\r\n          type: \"Darwin-NotificationCenter\"\r\n        , pkg: \"terminal-notifier\"\r\n        , msg: '-message'\r\n        , title: '-title'\r\n        , subtitle: '-subtitle'\r\n        , priority: {\r\n              cmd: '-execute'\r\n            , range: []\r\n          }\r\n      };\r\n    } else {\r\n      cmd = {\r\n          type: \"Darwin-Growl\"\r\n        , pkg: \"growlnotify\"\r\n        , msg: '-m'\r\n        , sticky: '--sticky'\r\n        , priority: {\r\n              cmd: '--priority'\r\n            , range: [\r\n                -2\r\n              , -1\r\n              , 0\r\n              , 1\r\n              , 2\r\n              , \"Very Low\"\r\n              , \"Moderate\"\r\n              , \"Normal\"\r\n              , \"High\"\r\n              , \"Emergency\"\r\n            ]\r\n          }\r\n      };\r\n    }\r\n    break;\r\n  case 'Linux':\r\n    cmd = {\r\n        type: \"Linux\"\r\n      , pkg: \"notify-send\"\r\n      , msg: ''\r\n      , sticky: '-t 0'\r\n      , icon: '-i'\r\n      , priority: {\r\n          cmd: '-u'\r\n        , range: [\r\n            \"low\"\r\n          , \"normal\"\r\n          , \"critical\"\r\n        ]\r\n      }\r\n    };\r\n    break;\r\n  case 'Windows_NT':\r\n    cmd = {\r\n        type: \"Windows\"\r\n      , pkg: \"growlnotify\"\r\n      , msg: ''\r\n      , sticky: '/s:true'\r\n      , title: '/t:'\r\n      , icon: '/i:'\r\n      , priority: {\r\n            cmd: '/p:'\r\n          , range: [\r\n              -2\r\n            , -1\r\n            , 0\r\n            , 1\r\n            , 2\r\n          ]\r\n        }\r\n    };\r\n    break;\r\n}\r\n\r\n/**\r\n * Expose `growl`.\r\n */\r\n\r\nexports = module.exports = growl;\r\n\r\n/**\r\n * Node-growl version.\r\n */\r\n\r\nexports.version = '1.4.1'\r\n\r\n/**\r\n * Send growl notification _msg_ with _options_.\r\n *\r\n * Options:\r\n *\r\n *  - title   Notification title\r\n *  - sticky  Make the notification stick (defaults to false)\r\n *  - priority  Specify an int or named key (default is 0)\r\n *  - name    Application name (defaults to growlnotify)\r\n *  - image\r\n *    - path to an icon sets --iconpath\r\n *    - path to an image sets --image\r\n *    - capitalized word sets --appIcon\r\n *    - filename uses extname as --icon\r\n *    - otherwise treated as --icon\r\n *\r\n * Examples:\r\n *\r\n *   growl('New email')\r\n *   growl('5 new emails', { title: 'Thunderbird' })\r\n *   growl('Email sent', function(){\r\n *     // ... notification sent\r\n *   })\r\n *\r\n * @param {string} msg\r\n * @param {object} options\r\n * @param {function} fn\r\n * @api public\r\n */\r\n\r\nfunction growl(msg, options, fn) {\r\n  var image\r\n    , args\r\n    , options = options || {}\r\n    , fn = fn || function(){};\r\n\r\n  // noop\r\n  if (!cmd) return fn(new Error('growl not supported on this platform'));\r\n  args = [cmd.pkg];\r\n\r\n  // image\r\n  if (image = options.image) {\r\n    switch(cmd.type) {\r\n      case 'Darwin-Growl':\r\n        var flag, ext = path.extname(image).substr(1)\r\n        flag = flag || ext == 'icns' && 'iconpath'\r\n        flag = flag || /^[A-Z]/.test(image) && 'appIcon'\r\n        flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image'\r\n        flag = flag || ext && (image = ext) && 'icon'\r\n        flag = flag || 'icon'\r\n        args.push('--' + flag, quote(image))\r\n        break;\r\n      case 'Linux':\r\n        args.push(cmd.icon, quote(image));\r\n        // libnotify defaults to sticky, set a hint for transient notifications\r\n        if (!options.sticky) args.push('--hint=int:transient:1');\r\n        break;\r\n      case 'Windows':\r\n        args.push(cmd.icon + quote(image));\r\n        break;\r\n    }\r\n  }\r\n\r\n  // sticky\r\n  if (options.sticky) args.push(cmd.sticky);\r\n\r\n  // priority\r\n  if (options.priority) {\r\n    var priority = options.priority + '';\r\n    var checkindexOf = cmd.priority.range.indexOf(priority);\r\n    if (~cmd.priority.range.indexOf(priority)) {\r\n      args.push(cmd.priority, options.priority);\r\n    }\r\n  }\r\n\r\n  // name\r\n  if (options.name && cmd.type === \"Darwin-Growl\") {\r\n    args.push('--name', options.name);\r\n  }\r\n\r\n  switch(cmd.type) {\r\n    case 'Darwin-Growl':\r\n      args.push(cmd.msg);\r\n      args.push(quote(msg));\r\n      if (options.title) args.push(quote(options.title));\r\n      break;\r\n    case 'Darwin-NotificationCenter':\r\n      args.push(cmd.msg);\r\n      args.push(quote(msg));\r\n      if (options.title) {\r\n        args.push(cmd.title);\r\n        args.push(quote(options.title));\r\n      }\r\n      if (options.subtitle) {\r\n        args.push(cmd.subtitle);\r\n        args.push(quote(options.subtitle));\r\n      }\r\n      break;\r\n    case 'Darwin-Growl':\r\n      args.push(cmd.msg);\r\n      args.push(quote(msg));\r\n      if (options.title) args.push(quote(options.title));\r\n      break;\r\n    case 'Linux':\r\n      if (options.title) {\r\n        args.push(quote(options.title));\r\n        args.push(cmd.msg);\r\n        args.push(quote(msg));\r\n      } else {\r\n        args.push(quote(msg));\r\n      }\r\n      break;\r\n    case 'Windows':\r\n      args.push(quote(msg));\r\n      if (options.title) args.push(cmd.title + quote(options.title));\r\n      break;\r\n  }\r\n\r\n  // execute\r\n  exec(args.join(' '), fn);\r\n};\r\n\r\n}).call(this,require('_process'))\r\n},{\"_process\":51,\"child_process\":41,\"fs\":41,\"os\":50,\"path\":41}],70:[function(require,module,exports){\r\n(function (process,global){\r\n/**\r\n * Shim process.stdout.\r\n */\r\n\r\nprocess.stdout = require('browser-stdout')();\r\n\r\nvar Mocha = require('../');\r\n\r\n/**\r\n * Create a Mocha instance.\r\n *\r\n * @return {undefined}\r\n */\r\n\r\nvar mocha = new Mocha({ reporter: 'html' });\r\n\r\n/**\r\n * Save timer references to avoid Sinon interfering (see GH-237).\r\n */\r\n\r\nvar Date = global.Date;\r\nvar setTimeout = global.setTimeout;\r\nvar setInterval = global.setInterval;\r\nvar clearTimeout = global.clearTimeout;\r\nvar clearInterval = global.clearInterval;\r\n\r\nvar uncaughtExceptionHandlers = [];\r\n\r\nvar originalOnerrorHandler = global.onerror;\r\n\r\n/**\r\n * Remove uncaughtException listener.\r\n * Revert to original onerror handler if previously defined.\r\n */\r\n\r\nprocess.removeListener = function(e, fn){\r\n  if ('uncaughtException' == e) {\r\n    if (originalOnerrorHandler) {\r\n      global.onerror = originalOnerrorHandler;\r\n    } else {\r\n      global.onerror = function() {};\r\n    }\r\n    var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);\r\n    if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }\r\n  }\r\n};\r\n\r\n/**\r\n * Implements uncaughtException listener.\r\n */\r\n\r\nprocess.on = function(e, fn){\r\n  if ('uncaughtException' == e) {\r\n    global.onerror = function(err, url, line){\r\n      fn(new Error(err + ' (' + url + ':' + line + ')'));\r\n      return !mocha.allowUncaught;\r\n    };\r\n    uncaughtExceptionHandlers.push(fn);\r\n  }\r\n};\r\n\r\n// The BDD UI is registered by default, but no UI will be functional in the\r\n// browser without an explicit call to the overridden `mocha.ui` (see below).\r\n// Ensure that this default UI does not expose its methods to the global scope.\r\nmocha.suite.removeAllListeners('pre-require');\r\n\r\nvar immediateQueue = []\r\n  , immediateTimeout;\r\n\r\nfunction timeslice() {\r\n  var immediateStart = new Date().getTime();\r\n  while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {\r\n    immediateQueue.shift()();\r\n  }\r\n  if (immediateQueue.length) {\r\n    immediateTimeout = setTimeout(timeslice, 0);\r\n  } else {\r\n    immediateTimeout = null;\r\n  }\r\n}\r\n\r\n/**\r\n * High-performance override of Runner.immediately.\r\n */\r\n\r\nMocha.Runner.immediately = function(callback) {\r\n  immediateQueue.push(callback);\r\n  if (!immediateTimeout) {\r\n    immediateTimeout = setTimeout(timeslice, 0);\r\n  }\r\n};\r\n\r\n/**\r\n * Function to allow assertion libraries to throw errors directly into mocha.\r\n * This is useful when running tests in a browser because window.onerror will\r\n * only receive the 'message' attribute of the Error.\r\n */\r\nmocha.throwError = function(err) {\r\n  Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {\r\n    fn(err);\r\n  });\r\n  throw err;\r\n};\r\n\r\n/**\r\n * Override ui to ensure that the ui functions are initialized.\r\n * Normally this would happen in Mocha.prototype.loadFiles.\r\n */\r\n\r\nmocha.ui = function(ui){\r\n  Mocha.prototype.ui.call(this, ui);\r\n  this.suite.emit('pre-require', global, null, this);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Setup mocha with the given setting options.\r\n */\r\n\r\nmocha.setup = function(opts){\r\n  if ('string' == typeof opts) opts = { ui: opts };\r\n  for (var opt in opts) this[opt](opts[opt]);\r\n  return this;\r\n};\r\n\r\n/**\r\n * Run mocha, returning the Runner.\r\n */\r\n\r\nmocha.run = function(fn){\r\n  var options = mocha.options;\r\n  mocha.globals('location');\r\n\r\n  var query = Mocha.utils.parseQuery(global.location.search || '');\r\n  if (query.grep) mocha.grep(new RegExp(query.grep));\r\n  if (query.fgrep) mocha.grep(query.fgrep);\r\n  if (query.invert) mocha.invert();\r\n\r\n  return Mocha.prototype.run.call(mocha, function(err){\r\n    // The DOM Document is not available in Web Workers.\r\n    var document = global.document;\r\n    if (document && document.getElementById('mocha') && options.noHighlighting !== true) {\r\n      Mocha.utils.highlightTags('code');\r\n    }\r\n    if (fn) fn(err);\r\n  });\r\n};\r\n\r\n/**\r\n * Expose the process shim.\r\n * https://github.com/mochajs/mocha/pull/916\r\n */\r\n\r\nMocha.process = process;\r\n\r\n/**\r\n * Expose mocha.\r\n */\r\nif(typeof window !== 'undefined'){\r\n\twindow.Mocha = Mocha;\r\n\twindow.mocha = mocha;\r\n}\r\n\r\n}).call(this,require('_process'),typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\r\n},{\"../\":1,\"_process\":51,\"browser-stdout\":40}]},{},[70]);"
  },
  {
    "path": "test/normalize/normalize.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<script src=\"../../../gun/examples/jquery.js\"></script>\n\t\t<script async src=\"../../../gun/lib/monotype.js\"></script>\n\t\t<script async src=\"../../../gun/lib/meta.js\"></script>\n\t</head>\n\t<body>\n\t\t<div id=\"edit\" contenteditable='true'>the world is a beautiful place.</div>\n\t\t<div id=\"out\">The world is a beautiful place.</div>\n\t\t<div id=\"test\">\n\t\t<button id=\"render\">render</button>\n\t\t\t<textarea id=\"before\"></textarea>\n\t\t\t<textarea id=\"after\"></textarea>\n\t\t\t<script src=\"../../../gun/lib/normalize.js\"></script>\n\t\t</div>\n\t\t<script>\n\t\t\t$('#render').on('click', check);\n\t\t\t$('#edit').on('keyup', check).focus();\n\t\t\tfunction check(){\n\t\t\t\tvar a = $('#edit').html();\n\t\t\t\t$('#before').val(a);\n\t\t\t\tvar opt = {};\n\t\t\t\topt.hierarchy = ['div', 'ol', 'ul', 'li', 'p', 'a', 'b', 'i', 'span', 's', 'sub', 'sup', 'u', 'br'];\n\t\t\t\topt.convert = {'em': 'i', 'strong': 'b', 'strike': 's', 'font': 'span'};\n\t\t\t\tvar b = $.normalize(a);\n\t\t\t\t$('#after').val(b);\n\t\t\t\t$('#out').html(b);\n\t\t\t}\n\t\t</script>\n\t\t<script>\n\t\t\tvar $xss = $('<div id=\"xss\">').appendTo('body');\n\t\t\t$.each([\n  \t\t\t'javascript:',\n  \t\t\t'JaVaScRiPt:',\n  \t\t\t'java script:',\n  \t\t\t'java\\nscript:',\n  \t\t\t'java\\tscript:',\n  \t\t\t'java\\0script:',\n  \t\t\t'jav&#x09;ascript:',\n  \t\t\t'jav&#x0A;ascript:',\n  \t\t\t'jav&#x0D;ascript:',\n  \t\t\t' &#14;  javascript:',\n  \t\t\t'&#106;avascript:',\n  \t\t\t'&#0000106avascript:',\n  \t\t\t'&#x6A;avascript:',\n  \t\t\t'\\u006Aavascript:',\n  \t\t\t'&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74:',\n  \t\t\t'&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x0003A;',\n  \t\t\t'&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;:',\n  \t\t\t'&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;',\n  \t\t\t'&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116:',\n  \t\t\t'&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058'\n  \t\t], function(i,v){\n  \t\t\t//console.log(v);\n  \t\t\tvar s = \"<div><a href='\"+v+\"alert(1)'>xss</a></div>\";\n  \t\t\tvar html = $.normalize(s);\n  \t\t\tif(html.match(/href/ig)){ alert('xss') }\n  \t\t\t$xss.append(html);\n  \t\t\tconsole.log(html);\n  \t\t});\n\t\t  // url(\"javascript: // and all permutations\n\t\t  // stylesheets can apparently have XSS?\n\t\t</script>\n\t\t<style>\n\t\t\tbutton { width: 100%; }\n\t\t\ttextarea { width: 45%; height: 20em; font-size: 18pt; }\n\t\t</style>\n\t</body>\n</html>"
  },
  {
    "path": "test/old/all.js",
    "content": "describe('All', function(){ \n\treturn;\n\tvar expect = global.expect = require(\"./expect\");\n\n\tvar Gun = Gun || require('../gun');\n\t(typeof window === 'undefined') && require('../lib/file');\n\t\n\tvar gun = Gun({file: 'data.json'});\n\n\tvar keys = {\n\t\t'emails/aquiva@gmail.com': 'asdf',\n\t\t'emails/mark@gunDB.io': 'asdf',\n\t\t'user/marknadal': 'asdf',\n\t\t'emails/timber@cazzell.com': 'fdsa',\n\t\t'user/timbernadal': 'fdsa',\n\t\t'user/forrest': 'abcd',\n\t\t'emails/banana@gmail.com': 'qwert',\n\t\t'user/marknadal/messages/asdf': 'rti',\n\t\t'user/marknadal/messages/fobar': 'yuoi',\n\t\t'user/marknadal/messages/lol': 'hjkl',\n\t\t'user/marknadal/messages/nano': 'vbnm',\n\t\t'user/marknadal/messages/sweet': 'xcvb',\n\t\t'user/marknadal/posts': 'qvtxz',\n\t\t'emails/for@rest.com': 'abcd'\n\t};\n\n\tit('from', function() {\n\t\tvar r = gun.__.opt.hooks.all(keys, {from: 'user/'});\n\t\t//console.log(r);\n\t\texpect(r).to.be.eql({\n\t\t\t'user/marknadal': { '#': 'asdf' },\n\t\t\t'user/timbernadal': { '#': 'fdsa' },\n\t\t\t'user/forrest': { '#': 'abcd' },\n\t\t\t'user/marknadal/messages/asdf': { '#': 'rti' },\n\t\t\t'user/marknadal/messages/fobar': { '#': 'yuoi' },\n\t\t\t'user/marknadal/messages/lol': { '#': 'hjkl' },\n\t\t\t'user/marknadal/messages/nano': { '#': 'vbnm' },\n\t\t\t'user/marknadal/messages/sweet': { '#': 'xcvb' },\n\t\t\t'user/marknadal/posts': { '#': 'qvtxz' } \n\t\t});\n\t});\n\n\tit('from and upto', function() {\n\t\tvar r = gun.__.opt.hooks.all(keys, {from: 'user/', upto: '/'});\n\t\t//console.log('upto', r);\n\t\texpect(r).to.be.eql({\n\t\t\t'user/marknadal': { '#': 'asdf' },\n\t\t\t'user/timbernadal': { '#': 'fdsa' },\n\t\t\t'user/forrest': { '#': 'abcd' }\n\t\t});\n\t});\n\n\tit('from and upto and start and end', function() {\n\t\tvar r = gun.__.opt.hooks.all(keys, {from: 'user/', upto: '/', start: \"c\", end: \"f\"});\n\t\t//console.log('upto and start and end', r);\n\t\texpect(r).to.be.eql({\n\t\t\t'user/forrest': { '#': 'abcd' }\n\t\t});\n\t});\n\n\tit('map', function(done) { return done();\n\t\tvar users = gun.put({\n\t\t\ta: {name: \"Mark Nadal\"},\n\t\t\tb: {name: \"timber Nadal\"},\n\t\t\tc: {name: \"Charlie Chapman\"},\n\t\t\td: {name: \"Johnny Depp\"},\n\t\t\te: {name: \"Santa Clause\"}\n\t\t});\n\t\t//console.log(\"map:\");\n\t\tusers.map().val(function(user){\n\t\t\t//console.log(\"each user:\", user);\n\t\t}).path(\"ohboy\");\n\t\treturn;\n\t\tusers.map(function(){\n\n\t\t});\n\t});\n\n});"
  },
  {
    "path": "test/old/interface.js",
    "content": "module.exports=require('theory')\r\n('interface',function(a){\r\n\treturn \":)\";\r\n},['../deps/discrete','../deps/key/key']);\r\nroot.opts.key = {host:'/deps'};"
  },
  {
    "path": "test/old/performance.js",
    "content": "describe('Performance', function(){ return; // performance tests\n\tvar console = root.console || {log: function(){}};\n\tfunction perf(fn, i){\n\t\ti = i || 1000;\n\t\twhile(--i){\n\t\t\tfn(i);\n\t\t}\n\t}\n\tperf.now = this.performance? function(){ return performance.now() } : function(){ return Gun.time.now()/1000 };\n\t(function(){\n\t\tvar t1 = perf.now();\n\t\tvar obj = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i'};\n\t\tObject.keys && perf(function(){\n\t\t\tvar l = Object.keys(obj), ll = l.length, i = 0, s = '';\n\t\t\tfor(; i < ll; i++){\n\t\t\t\tvar v = l[i];\n\t\t\t\ts += v;\n\t\t\t}\n\t\t});\n\t\tconsole.log('map: native', (t1 = (perf.now() - t1)/1000) + 's');\n\n\t\tvar t2 = perf.now();\n\t\tvar obj = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i'};\n\t\tperf(function(){\n\t\t\tvar s = '';\n\t\t\tGun.obj.map(obj, function(v){\n\t\t\t\ts += v;\n\t\t\t})\n\t\t});\n\t\tconsole.log('map: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.');\n\t}());\n\t(function(){\n\t\tif(!Gun.store){\n\t\t\tvar tab = Gun().tab;\n\t\t\tif(!tab){ return }\n\t\t\tGun.store = tab.store;\n\t\t}\n\t\troot.localStorage && root.localStorage.clear();\n\t\tvar it = 1000;\n\t\tvar t1 = perf.now();\n\t\tperf(function(i){\n\t\t\tvar obj = {'i': i, 'v': Gun.text.random(100)};\n\t\t\tGun.store.put('test/native/' + i, obj);\n\t\t}, it);\n\t\tconsole.log('store: native', (t1 = (perf.now() - t1)/1000) + 's');\n\n\t\troot.localStorage && root.localStorage.clear();\n\t\tvar gun = Gun({wire: {get:function(l,cb){cb()},put:function(g,cb){\n\t\t\tGun.is.graph(g, function(node, soul){\n\t\t\t\tGun.store.put(soul, node);\n\t\t\t});\n\t\t\tcb(null);\n\t\t}}});\n\t\tvar t2 = perf.now();\n\t\tperf(function(i){\n\t\t\tvar obj = {'i': i, 'v': Gun.text.random(100)};\n\t\t\tgun.put(obj);\n\t\t}, it);\n\t\tconsole.log('store: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.');\n\t\troot.localStorage && root.localStorage.clear();\n\t}());\n\t(function(){ // setTimeout\n\t\tif(!Gun.store){\n\t\t\tvar tab = Gun().tab;\n\t\t\tif(!tab){ return }\n\t\t\tGun.store = tab.store;\n\t\t}\n\t\troot.localStorage && root.localStorage.clear();\n\t\tvar t1 = perf.now();\n\t\ti = i || 1000;\n\t\twhile(--i){\n\t\t\tvar obj = {'i': i, 'v': Gun.text.random(100)};\n\t\t\tGun.store.put('test/native/' + i, obj);\n\t\t}\n\t\tconsole.log('store: native', (t1 = (perf.now() - t1)/1000) + 's');\n\n\t\troot.localStorage && root.localStorage.clear();\n\t\tvar gun = Gun({wire: {get:function(l,cb){cb()},put:function(g,cb){\n\t\t\tGun.is.graph(g, function(node, soul){\n\t\t\t\tGun.store.put(soul, node);\n\t\t\t});\n\t\t\tcb(null);\n\t\t}}});\n\t\tvar t2 = perf.now();\n\t\tperf(function(i){\n\t\t\tvar obj = {'i': i, 'v': Gun.text.random(100)};\n\t\t\tgun.put(obj);\n\t\t}, it);\n\t\tconsole.log('store: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.');\n\t\troot.localStorage && root.localStorage.clear();\n\t}());\n\t(function(){\n\t\tvar t1 = perf.now();\n\t\tvar on = Gun.on.create(), c = 0, o = [];\n\t\tperf(function(i){\n\t\t\to.push(function(n){\n\t\t\t\tc += 1;\n\t\t\t});\n\t\t\tvar ii = 0, l = o.length;\n\t\t\tfor(; ii < l; ii++){\n\t\t\t\to[ii](i);\n\t\t\t}\n\t\t});\n\t\tconsole.log('on: native', (t1 = (perf.now() - t1)/1000) + 's');\n\n\t\tvar on = Gun.on.create(), c = 0;\n\t\tvar t2 = perf.now();\n\t\tperf(function(i){\n\t\t\ton('change').event(function(n){\n\t\t\t\tc += 1;\n\t\t\t});\n\t\t\ton('change').emit(i);\n\t\t});\n\t\tconsole.log('on: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.');\n\t}());return;\n\t(function(){ // always do this last!\n\t\tvar t1 = perf.now();\n\t\tperf(function(i){\n\t\t\tsetTimeout(function(){\n\t\t\t\tif(i === 1){\n\t\t\t\t\tcb1();\n\t\t\t\t}\n\t\t\t},0);\n\t\t}); var cb1 = function(){\n\t\t\tconsole.log('setTimeout: native', (t1 = (perf.now() - t1)/1000) + 's', (t1 / t2).toFixed(1)+'x', 'slower.');\n\t\t}\n\t\tvar t2 = perf.now();\n\t\tperf(function(i){\n\t\t\tsetImmediate(function(){\n\t\t\t\tif(i === 1){\n\t\t\t\t\tcb2();\n\t\t\t\t}\n\t\t\t});\n\t\t}); var cb2 = function(){\n\t\t\tconsole.log('setImmediate: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.');\n\t\t}\n\t}());\n});"
  },
  {
    "path": "test/old/s3pricing.html",
    "content": "<!DOCTYPE html>\r\n<html>\r\n\t<head>\r\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\r\n\t\t<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js\"></script>\r\n\t</head>\r\n\t<body>\r\n\t\t<style>\r\n\t\t\t.table li {\r\n\t\t\t\tfloat: left;\r\n\t\t\t\tmin-width: 200px;\r\n\t\t\t\tmax-width: 400px;\r\n\t\t\t}\r\n\t\t\tul, li {\r\n\t\t\t\tlist-style: none;\r\n\t\t\t}\r\n\t\t\t.clear {\r\n\t\t\t\tclear: both;\r\n\t\t\t}\r\n\t\t\t.none {\r\n\t\t\t\tdisplay: none;\r\n\t\t\t}\r\n\t\t</style>\r\n\t\t<ul>\r\n\t\t\t<li><ul class=\"table none\">\r\n\t\t\t\t<li>Seconds in month:</li>\r\n\t\t\t\t<li><input type=\"number\" value=\"2629743.83\" id=\"sim\"></li>\r\n\t\t\t</ul></li>\r\n\t\t\t<li class=\"clear\"></li>\r\n\t\t\t<li><ul class=\"table\">\r\n\t\t\t\t<li>Persist every seconds:</li>\r\n\t\t\t\t<li><input type=\"number\" value=\"15\" id=\"se\"></li>\r\n\t\t\t</ul></li>\r\n\t\t\t<li class=\"clear\"></li>\r\n\t\t\t<li><ul class=\"table\">\r\n\t\t\t\t<li>Over how many objects:</li>\r\n\t\t\t\t<li><input type=\"number\" value=\"100\" id=\"o\"></li>\r\n\t\t\t</ul></li>\r\n\t\t\t<li class=\"clear\"></li>\r\n\t\t\t<li><ul class=\"table\">\r\n\t\t\t\t<li>Cost $:</li>\r\n\t\t\t\t<li><input type=\"number\" value=\"\" readonly id=\"r\"></li>\r\n\t\t\t</ul></li>\r\n\t\t</ul>\r\n\t\t<br>\r\n\t\t<p>\r\n\t\t\tThis page is for throughput calculation, it assumes continuous load non-stop.\r\n\t\t</p>\r\n\t\t<script>\r\n\t\t\t$(function(){\r\n\t\t\t\tvar sim = $('#sim')\r\n\t\t\t\t,\tse = $('#se')\r\n\t\t\t\t,\to = $('#o')\r\n\t\t\t\t,\tr = $('#r')\r\n\t\t\t\t,\tn = function(n){ return parseFloat(n) }\r\n\t\t\t\t$(document).on('keyup', function(){\r\n\t\t\t\t\tr.val(\r\n\t\t\t\t\t\t((( n(sim.val()) / n(se.val()) ) * n(o.val()) / 1000) * 0.005 ).toFixed(2)\r\n\t\t\t\t\t);\r\n\t\t\t\t})\r\n\t\t\t})\r\n\t\t</script>\r\n\t</body>\r\n</html>\r\n"
  },
  {
    "path": "test/old/server.js",
    "content": "module.exports=require('theory')\r\n({name: 'echo'\r\n, state: {way:'state', flow:-1}\r\n, invincible: true\r\n, dep: ['../shots']\r\n, init: function(a){\r\n\tvar echo = {}, redis, client;\r\n\techo.shot = a.shots();\r\n\techo.put = function(m){\r\n\t\tconsole.log('stream', m);\r\n\t}\r\n\techo.state = function(m){\r\n\t\tif(echo.shot.server(m,a.com.reply)){ return }\r\n\t\tm.what.body = 'module.exports = {boo: \"yay\"};';\r\n\t\tm.what.type = 'js';\r\n\t\ta.com.reply(m);\r\n\t};\r\n\t/*echo.shot.stream.on(function(m){\r\n\t\tconsole.log('stream on!', m);\r\n\t});*/\r\n\treturn echo;\r\n}});"
  },
  {
    "path": "test/old/set.js",
    "content": "(function(){ return;\n\tvar Gun = require('../gun');\n\tvar done = function(){};\n\t\n\tvar gun = Gun().get('set').set(), i = 0;\n\tgun.val(function(val){\n\t\tconsole.log('t1', val);\n\t}).set(1).set(2).set(3).set(4) // if you set an object you'd have to do a `.back`\n\t\t.map().val(function(val){ // TODO! BUG? If we do gun.set it immediately calls and we get stale data. Is this wrong?\n\t\tconsole.log('t2', val, ++i);\n\t\tif(4 === i){\n\t\t\tconsole.log(\"TODO? BUG! Double soul?\", gun.__.graph);\n\t\t\tdone() \n\t\t}\n\t});\n\n\treturn; // TODO! BUG! Causes tests to crash and burn badly.\n\t\n\trequire('../lib/set');\n\tvar gun = Gun();\n\t\n\tvar list = gun.get('thoughts');\n\tlist.set('a');\n\tlist.set('b');\n\tlist.set('c');\n\tlist.set('d').val(function(val){\n\t\tconsole.log('what', val, '\\n\\n');\n\t\tconsole.log(gun.__.graph);\n\t})\n\treturn;\n\tgun.set({\n\t\tname: \"Mark Nadal\",\n\t\tage: 23,\n\t\ttype: \"human\"\n\t}).back.set({\n\t\tname: \"Timber Nadal\",\n\t\tage: 3,\n\t\ttype: \"cat\"\n\t}).back.set({\n\t\tname: \"Hobbes\",\n\t\tage: 4,\n\t\ttype: \"kitten\"\n\t}).back.val(function(g){\n\t\tconsole.log(\"GOT\", g, this.__.graph);\n\t}).map(function(val, id){\n\t\tconsole.log(\"map\", id, val);\n\t});\n\t\n}());"
  },
  {
    "path": "test/old/shoot.html",
    "content": "<html>\r\n\t<head>\r\n\t\t<title>Shoot</title>\r\n\t\t<script src=\"../gate/amplify.store.js\"></script>\r\n\t\t<script src=\"../deps/jquery.js\"></script>\r\n\t\t<!--\r\n\t\t<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js\"></script>\r\n\t\t<script src=\"../gate/sock.js\"></script>\r\n\t\t-->\r\n\t\t<script src=\"../deps/theory.js\"></script>\r\n\t\t<script src=\"./shoot.js\"></script>\r\n\t\t<style>\r\n\t\t\thtml, body {\r\n\t\t\t\tfont-family: Verdana, Geneva, sans-serif;\r\n\t\t\t\tfont-size: 18pt;\r\n\t\t\t}\r\n\t\t\t#model {\r\n\t\t\t\tdisplay: none;\r\n\t\t\t}\r\n\t\t\t.binary {\r\n\t\t\t\tfont-family: Impact, Charcoal, sans-serif;\r\n\t\t\t\tcolor: #c0a343;\r\n\t\t\t}\r\n\t\t\t.number {\r\n\t\t\t\tfont-family: \"Courier New\", Courier, monospace;\r\n\t\t\t\tcolor: #3975aa;\r\n\t\t\t}\r\n\t\t\t.text {\r\n\t\t\t\tfont-family: \"Times New Roman\", Times, serif;\r\n\t\t\t\tquotes: \"\" \"\" \"\" \"\";\r\n\t\t\t\tcolor: #37a558;\r\n\t\t\t}\r\n\t\t\t.text:before {\r\n\t\t\t\tcontent: open-quote;\r\n\t\t\t}\r\n\t\t\t.text:after {\r\n\t\t\t\tcontent: close-quote;\r\n\t\t\t}\r\n\t\t\tli {\r\n\t\t\t\tlist-style: none;\r\n\t\t\t}\r\n\t\t\t.on {\r\n\t\t\t\tlist-style: inherit;\r\n\t\t\t\tborder-bottom: 0.1em dashed #DDD;\r\n\t\t\t}\r\n\t\t\t.id {\r\n\t\t\t\tfont-size: 1.2em;\r\n\t\t\t}\r\n\t\t\t.keyboard {\r\n\t\t\t\tfont-size: 12pt;\r\n\t\t\t}\r\n\t\t\t.node {\r\n\t\t\t\tmargin: 1.1em;\r\n\t\t\t\tf-loat: left;\r\n\t\t\t\tmin-width: 250px;\r\n\t\t\t}\r\n\t\t\t.space {\r\n\t\t\t\tmargin: 1.5em 0 0 1.5em;\r\n\t\t\t}\r\n\t\t\t.has > .key:after {\r\n\t\t\t\tcontent: \": \";\r\n\t\t\t}\r\n\t\t\t.ref > .key:after {\r\n\t\t\t\tcontent: \"\\2192\";\r\n\t\t\t}\r\n\t\t\t.obj > .key:after {\r\n\t\t\t\tcontent: \"...\";\r\n\t\t\t}\r\n\t\t</style>\r\n\t  </head>\r\n\t</head>\r\n\t<body>\r\n\t\t<div class=\"id space\">Loading...</div>\r\n\t\t<small><small>\r\n\t\t\tWarning: This is an incredibly buggy and unfinished demo, manually refreshing the page will be required.\r\n\t\t\tPlease rely on the demo video if this breaks.\r\n\t\t\tLoad <a href=\"http://gunjs.herokuapp.com/test/shoot.html\">heroku</a> and <a href=\"http://gunjs-amark.rhcloud.com/test/shoot.html\">openshift</a>,\r\n\t\t\tand make an edit on one (click on some text value, and modify it),\r\n\t\t\tthen refresh the page on the other and it should be updated (despite these being run on two completely different servers).\r\n\t\t</small></small>\r\n\t\t<ul id=\"graph\"></ul>\r\n\t\t<ul id=\"model\">\r\n\t\t\t<li class=\"node field\" id=\"model-node\">\r\n\t\t\t\t<span class=\"id key\">ID</span><ul class=\"sub\"></ul>\r\n\t\t\t</li>\r\n\t\t\t<li class=\"has field\" id=\"model-has\">\r\n\t\t\t\t<span class=\"key\">key</span><span class=\"val\" contenteditable=\"true\">val</span>\r\n\t\t\t</li>\r\n\t\t\t<li class=\"ref field\" id=\"model-ref\">\r\n\t\t\t\t<span class=\"key\">key</span><a class=\"val\" contenteditable=\"true\" href=\"#\">&rarr;</span>\r\n\t\t\t</li>\r\n\t\t\t<li class=\"obj field\" id=\"model-obj\">\r\n\t\t\t\t<span class=\"key\">key</span><ul class=\"sub\"></ul>\r\n\t\t\t</li>\r\n\t\t</ul>\r\n\t</body>\r\n</html>"
  },
  {
    "path": "test/old/shoot.js",
    "content": "module.exports=require('theory')\r\n('shoot',function(a){\r\n\tif(root.node){\r\n\t\tvar shot = require('../../shots0')({src: a.com, batch: 999}).pump(function(g, m, done){\r\n\t\t\tconsole.log('>>> pump!');\r\n\t\t\tdone();\r\n\t\t});\r\n\t\treturn shot.spray(function(g, m, done){\r\n\t\t\tconsole.log('>>> shoot!');\r\n\t\t\tvar gPrime = {};\r\n\t\t\tdone(gPrime); // allow me to send custom modified filtered version\r\n\t\t\t//console.log(g());\r\n\t\t});\r\n\t}\r\n\tvar shoot = {}\r\n\t, shot = a.shot()\r\n\t, the = a.discrete\r\n\t, $graph = $(\"#graph\")\r\n\t, $node = $(\"#model-node\")\r\n\t, $has = $(\"#model-has\")\r\n\t, $ref = $(\"#model-ref\")\r\n\t, $sub = $(\"#model-obj\")\r\n\t, $url = $('body>.id')\r\n\t, g;\r\n\tshoot.clone = function($e, $to, id, name){\r\n\t\tvar $r = $e.clone().attr('id',id).appendTo($to);\r\n\t\tname = name || id;\r\n\t\tif(name){ $r.attr('name', name) }\r\n\t\treturn $r;\r\n\t}\r\n\tshoot.graph = function(g, url){\r\n\t\tif(url){ $url.text(url) }\r\n\t\ta.obj(g).each(function(n,id){\r\n\t\t\tvar $n = $node.clone().attr('id',id).attr('name',id).appendTo($graph);\r\n\t\t\t$('.id', $n).text(id);\r\n\t\t\tshoot.field($('.sub', $n), n);\r\n\t\t});\r\n\t\t$('.node .sub .sub').slideUp();\r\n\t}\r\n\tshoot.field = function($n, n, p){\r\n\t\ta.obj(n).each(function(val,key){\r\n\t\t\tif(key === '_'){ return }\r\n\t\t\tif(a.obj.is(val)){\r\n\t\t\t\tvar $val = shoot.clone($sub, $n, key);\r\n\t\t\t\t$('.key', $val).text(key);\r\n\t\t\t\tshoot.field($('.sub', $val), val);\r\n\t\t\t} else {\r\n\t\t\t\tvar $val = shoot.clone($has, $n, key)\r\n\t\t\t\t, $v = $('.val', $val).text(val);\r\n\t\t\t\t$('.key', $val).text(key);\r\n\t\t\t\tif(a.bi.is(val)){\r\n\t\t\t\t\t$v.addClass('binary');\r\n\t\t\t\t} else\r\n\t\t\t\tif(a.num.is(val)){\r\n\t\t\t\t\t$v.addClass('number');\r\n\t\t\t\t} else\r\n\t\t\t\tif(a.text.is(val)){\r\n\t\t\t\t\t$v.addClass('text');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\tshot.load('gunjs.herokuapp.com/tests/package.json',function(graph){\r\n\t\tif(!graph){ return $url.text(\"Something went wrong :( please reload.\") }\r\n\t\tg = graph;\r\n\t\twindow.graphbug = g;\r\n\t\tconsole.log('graph', g());\r\n\t\tshoot.graph(g(), 'Graph');\r\n\t});\r\n\trequire('./interface')(function(){});\r\n\t$(document).on('keyboard',function(){\r\n\t\tvar the = theory.discrete\r\n\t\t, key = theory.key, u;\r\n\t\tkey.map({\r\n\t\t\t'up': 'prev'\r\n\t\t\t,'down': 'next'\r\n\t\t\t,'right': 'open'\r\n\t\t\t,'left': 'close'\r\n\t\t\t,'enter': 'add'\r\n\t\t\t,'erase': 'remove'\r\n\t\t});\r\n\t\t$(document).on('keyup','[contenteditable=\"true\"]',function(e){\r\n\t\t\tif(!g){ return }\r\n\t\t\te.where = this;\r\n\t\t\tvar $v = $(e.where).find('.val').addBack('.val')\r\n\t\t\t, p = shoot.path($v), val, v;\r\n\t\t\tif(!p){ return }\r\n\t\t\tval = g(p);\r\n\t\t\tif(val === u){ return }\r\n\t\t\tv = $v.text();\r\n\t\t\tv = (v === 'true')? true : v;\r\n\t\t\tv = (v === 'false')? false : v;\r\n\t\t\tv = (a.num.is(parseFloat(v)))? parseFloat(v) : v;\r\n\t\t\tif(val === v){ return }\r\n\t\t\tconsole.log(\"EDIT FINALLY\", p, val, v, (val === v));\r\n\t\t\tg(p,v);\r\n\t\t});\r\n\t\tthe.key('enter').up(function(e){\r\n\t\t\tif(!g || the.key.tame()){ return }\r\n\t\t},document);\r\n\t\tthe.key('erase').down(function(e){\r\n\t\t\tif(the.key.tame()){ return }\r\n\t\t\te.stun(); e.stop();\r\n\t\t},document);\r\n\t\tthe.key('erase').up(function(e){\r\n\t\t\te.stun(); e.stop();\r\n\t\t\tif(!g || the.key.tame()){ return }\r\n\t\t\tvar $v = $('.on')\r\n\t\t\t, p = shoot.path($v)\r\n\t\t\t, val;\r\n\t\t\tif(!p){ return }\r\n\t\t\tval = g(p);\r\n\t\t\tif(val === u){ return }\r\n\t\t\tg(p,null);\r\n\t\t\tshoot.nav();\r\n\t\t\t$v.closest('.field').remove();\r\n\t\t},document);\r\n\t\tshoot.path = function($e){\r\n\t\t\treturn $e.parents().addBack().map(function(){\r\n\t\t\t\treturn $(this).attr('name')\r\n\t\t\t}).get().join('.');\r\n\t\t}\r\n\t\tshoot.nav = function(dir){\r\n\t\t\tif(the.key.tame()){ return }\r\n\t\t\tvar f = '.field', c = 'on', g = $graph;\r\n\t\t\tvar x = dir? 'prev' : 'next', y = dir? 'last' : 'first';\r\n\t\t\tvar on = $('.'+c, g), n;\r\n\t\t\tif(!on.length){\r\n\t\t\t\treturn on = $(f, g)[y]().addClass(c);\r\n\t\t\t}\r\n\t\t\tif(dir){\r\n\t\t\t\tn = on.prev(f);\r\n\t\t\t\tif(!n.length){\r\n\t\t\t\t\tn = null;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tn = (n||on).find(f+':visible')[y]();\r\n\t\t\tif(!n.length){\r\n\t\t\t\tn = on[x](f);\r\n\t\t\t}\r\n\t\t\tif(!n.length){\r\n\t\t\t\tn = on.parents(f).first();\r\n\t\t\t\tif(!dir){\r\n\t\t\t\t\tn = n[x](f)[y]();\r\n\t\t\t\t}\r\n\t\t\t\tif(!n.length){\r\n\t\t\t\t\tn = $(f, g)[y]();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\ton.removeClass(c);\r\n\t\t\tn.addClass(c);\r\n\t\t}\r\n\t\tthe.key('down').hold(function(e){\r\n\t\t\tshoot.nav();\r\n\t\t});\r\n\t\tthe.key('up').hold(function(e){\r\n\t\t\tshoot.nav(-1);\r\n\t\t});\r\n\t\tthe.key('right').up(function(e){\r\n\t\t\tshoot.nav.out = false;\r\n\t\t\tif(the.key.tame()){ return }\r\n\t\t\tvar on = $('.on', $graph);\r\n\t\t\tif(!on.children('.sub').length){ \r\n\t\t\t\treturn on.children('.val').focus();\r\n\t\t\t}\r\n\t\t\ton.children('.sub').slideDown();\r\n\t\t});\r\n\t\tthe.key('left').up(function(e){\r\n\t\t\tvar on = $('.on', $graph), n;\r\n\t\t\tif(the.key.tame()){\r\n\t\t\t\tif(shoot.nav.out){\r\n\t\t\t\t\treturn $('.val',on).trigger('blur');\r\n\t\t\t\t}\r\n\t\t\t\ta.test(function(){\r\n\t\t\t\t\tvar s = window.getSelection()\r\n\t\t\t\t\t, r = s.getRangeAt(0);\r\n\t\t\t\t\tif(!r.startOffset){\r\n\t\t\t\t\t\tshoot.nav.out = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t})();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif(on.find('.field:visible').length){\r\n\t\t\t\treturn $('.sub',on).slideUp();\r\n\t\t\t}\r\n\t\t\tn = on.parents('.field').first();\r\n\t\t\tif(!n.length){ return }\r\n\t\t\ton.removeClass('on');\r\n\t\t\ton = n.addClass('on');\r\n\t\t\t$('.sub',on).slideUp();\r\n\t\t});\r\n\t\tthe.mouse.up(function(e){\r\n\t\t\t$('.on').removeClass('on');\r\n\t\t\t$(e.where).closest('.field').addClass('on');\r\n\t\t},'.field');\r\n\t});\r\n\treturn shot.spray;\r\n},['../../shot0']);"
  },
  {
    "path": "test/old/shotgun.js",
    "content": "var keys;\r\nif(process.env.LIVE || (process.env.NODE_ENV === 'production')){\r\n\t// Keys are provided by environment configs on the server\r\n} else {\r\n\t// Keys are hosted outside this public repo folder, you must provide your own with environment variables.\r\n\tif((require('fs').existsSync||require('path').existsSync)(keys = __dirname + '/../../../linux/.ssh/keys-gun.js')){\r\n\t\tkeys = require(keys);\r\n\t}\r\n}\r\n\r\nkeys = keys || {};\r\nkeys.bucket = keys.bucket || 'gunjs.herokuapp.com';\r\n\r\nmodule.exports = keys || {};"
  },
  {
    "path": "test/old/timelines.txt",
    "content": "Earth\t\t\t\t\t\t\t\t\t\t\t\t\tMars\r\nthing = {}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing = {}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing.a = 'hello'\r\n\r\nthing.z = 'cool'\r\n\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t----> thing\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t----> thing.z = 'cool'\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing = {a: 'hello', z: 'cool'}\r\nthing = {z: 'cool'} <----\r\nthing.a = 'hello' <----\r\nthing = {a: 'hello', z: 'cool'}\r\n\r\n------------------------------------------------------------------------------------\r\nEarth\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tMars\r\nthing = 5\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing = 5\r\n\r\nthing = {a: 'yay'}\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing = {b: 'cool'}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t22 -> thing = {a: 'yay', b: 'cool'}\r\n\r\nthing = {a: 'yay', b:'cool'} <- 24\r\n------------------------------------------------------------------------------------\r\nEarth\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tMars\r\nthing = 5\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing = 5\r\n\r\nthing = {a: 'yay'}\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing = {b: 'cool'}\r\nthing = 9\r\nthing = {z: 1}\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\r\nthing.j = 'how?'\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing.k = 'lol'\r\nthing = {z: 1, j: 'how?'} <- 36\r\nthing = {z: 1, j: 'how?', k: 'lol'} <- 41\t\t\t\t\t\t\t\t// wrong! need to send thing when also\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tthing.c = 20\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t34 -> thing = {a: 'yay', b: 'cool'}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t38 -> thing = 9\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t39 -> thing = {z:1}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t40 -> thing = {j: 'how?', z: 1}\r\nthing = {z: 1, j: 'how?'} <- 45"
  },
  {
    "path": "test/old/tmp.js",
    "content": "(function(){\n\treturn; // this file is for temporary testings and shouldn't get run.\n\tvar Gun = require('../gun');\n\tvar gun = Gun();\n\tGun.log.verbose = true;\n\n\t/*\n\tgun.put({foo: \"bar\"}).val(function(val){\n\t\tconsole.log(\"POWR HOUSE\", val);\n\t\tthis.put({lol: 'pancakes'}).val(function(v){\n\t\t\tconsole.log(\"YEAH CAKES\", v);\n\t\t})\n\t});\n\t*/\n\n\tgun.get('hello/world').put({hello: 'Mark'}).path('hello').val(function(val){\n\t\tconsole.log(\"YO\", val);\n\t\texpect(val).to.be('Mark');\n\t\tdone();\n\t});\n\n\n\treturn;\n\tfunction Next(){\n\t\tvar fn = function(cb){\n\t\t\tif(!fn.stack || !fn.stack.length){\n\t\t\t\tsetImmediate(function next(n){\n\t\t\t\t\treturn (n = (fn.stack||[]).shift() || function(){}), n.back = fn.stack, fn.stack = [], n(function(){\n\t\t\t\t\t\treturn (fn.stack = (fn.stack||[]).concat(n.back)), next();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t} if(cb){ \n\t\t\t\t(fn.stack = fn.stack || []).push(cb);\n\t\t\t} return fn;\n\t\t}, setImmediate = setImmediate || function(cb){return setTimeout(cb,0)}\n\t\treturn fn;\n\t}\n\n\tmodule.exports = Next;\n\n\tvar next = Next();\n\tvar state = {};\n\n\tnext(function(n){\n\t\tconsole.log(1);\n\t\tsetTimeout(n, 500);\n\t});\n\tnext(function(n){\n\t\tconsole.log(2);\n\t\tsetTimeout(function(){\n\n\t\t\t//n(function(){\n\t\t\t\tconsole.log(3);\n\n\t\t\t\tnext(function(n){\n\t\t\t\t\tconsole.log(4);\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tconsole.log(\"before five\");\n\t\t\t\t\t\tn();\n\t\t\t\t\t}, 5000);\n\t\t\t\t})\n\t\t\t\tnext(function(n){\n\t\t\t\t\tconsole.log(5);\n\t\t\t\t\tsetTimeout(n, 3000);\n\t\t\t\t});\n\t\t\t\tn();\n\t\t\t//});\n\n\t\t}, 1000);\n\t});\n\tnext(function(n){\n\t\tconsole.log(6);\n\t\tn();\n\t});\n\n}());"
  },
  {
    "path": "test/panic/1putackget.js",
    "content": "/*\nThis is the first in a series of basic networking correctness tests.\nEach test itself might be dumb and simple, but built up together,\nthey prove desired end goals for behavior at scale.\n\n1. (this file) When Alice saves data, acks should daisy chain back to her.\n2. (this file) When Dave asks for data, Bob & Alice do not need to reply because it would be the same as Carl's reply.\n\nAssume we have a 4 peer federated-like topology,\n\n..B--C..\n./....\\.\nA......D\n\nAlice's data can be saved by more than just Bob.\nDave asking for the data should not flood him with more than necessary responses.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 2,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar bob = relays.pluck(1);\nvar carl = relays.excluding(bob).pluck(1);\nvar browsers = clients.excluding(relays);\nvar alice = browsers.pluck(1);\nvar dave = browsers.excluding(alice).pluck(1);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"Put ACK\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\t// currently fails because rod doesn't ack\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, ['start', '--port', port, '--sled-storage=false', '--peers', peers.join(',').replaceAll('http', 'ws')]);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server, axe: false}); // Note: test with AXE on & off.\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.ref = gun.get('a');\n\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n// end PANIC template --> \n\n\tit(\"Put\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tvar c = test.props.acks, acks = {}, tmp;\n\t\t\tc = c < 2? 2 : c; // at least 2 acks.\n\t\t\tref.put({hello: 'world'}, function(ack){\n\t\t\t\tacks[ack['#']] = 1; // uniquely list all the ack IDs.\n\t\t\t\ttmp = Object.keys(acks).length;\n\t\t\t\tif(tmp >= c){ // when there are enough\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\ttest.done(); // confirm test passes\n\t\t\t\t\t\twire(); // start sniffing for future tests\n\t\t\t\t\t}, 1000 * 2);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}, {acks: c,  ok: c*10}); // TODO: Upon breaking change (> 2020) update this test with the deprecated `acks` behavior.\n\t\t\t\n\t\t\tfunction wire(){ // for the future tests, track how many wire messages are heard/sent.\n\t\t\t\tref.hear = ref.hear || [];\n\t\t\t\tvar dam = ref.back('opt.mesh');\n\t\t\t\tvar hear = dam.hear;\n\t\t\t\tdam.hear = function(raw, peer){\n\t\t\t\t\thear(raw, peer);\n\t\t\t\t\tref.hear.push(raw);\n\t\t\t\t}\n\n\t\t\t\tvar peers = ref.back('opt.peers');\n\t\t\t\tObject.keys(peers).forEach(function(peer){\n\t\t\t\t\tpeer = peers[peer];\n\t\t\t\t\tpeer.say = function(raw){\n\t\t\t\t\t\t(ref.say || (ref.say = [])).push(raw); // add to count.\n\t\t\t\t\t\tpeer.wire.send(raw);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}, {acks: config.relays});\n\t});\n\n\tit(\"Get\", function(){\n\t\t/*\n\t\t\tHere is the recursive rule for GET, keep replying while hashes mismatch.\n\t\t\t1. Receive a GET message.\n\t\t\t2. If it has a hash, and if you have a thing matching the GET, then see if the hashes are the same, if they are then don't ACK, don't relay, end. (Tho subscribe them)\n\t\t\t3. If you would have the thing but do not, then ACK that YOU have nothing.\n\t\t\t4. If you have a thing matching the GET or an ACK for the GET's message, add the hash to the GET message, and ACK with the thing or ideally the remaining difference.\n\t\t\t5. Pick ?3? OTHER peers preferably by priority that they have got the thing, send them the GET, plus to all \"up\" peers.\n\t\t\t6. If no ACKs you are done, end. (Or sample other peers until confident)\n\t\t\t7. If you get ACKs back to the GET with things and different hashes, optionally merge into the thing you have GOT and update the hash.\n\t\t\t8. Go to 4.\n\t\t\t// Deduplicated reply hashes cannot be global, they need to be request specific to avoid other bugs.\n\t\t*/\n\t\treturn dave.run(function(test){\n\t\t\tconsole.log(\"I AM DAVE\");\n\t\t\ttest.async();\n\t\t\tvar c = 0, to;\n\t\t\tref.hear = ref.hear || [];\n\t\t\tvar dam = ref.back('opt.mesh');\n\t\t\tvar hear = dam.hear;\n\t\t\tdam.hear = function(raw, peer){ // hijack listener\n\t\t\t\tvar msg = JSON.parse(raw);\n\t\t\t\t//console.log('hear:', msg);\n\t\t\t\thear(raw, peer);\n\t\t\t\tref.hear.push(msg);\n\n\t\t\t\tif(msg.put){ ++c } // count how many acks our GET gets.\n\t\t\t}\n\t\t\tref.get(function(ack){ // GET data\n\t\t\t\tif(!ack.put || ack.put.hello !== 'world'){ return } // reject any wrong data.\n\t\t\t\t// because the data is the same on all peers,\n\t\t\t\t// we should only get 1 ack because the others dedup off the 1st ACK's hash.\n\t\t\t\tif(c > 1){ return too_many_acks }\n\n\t\t\t\tclearTimeout(to);\n\t\t\t\tto = setTimeout(test.done, 1000);\n\t\t\t});\n\t\t}, {acks: config.relays});\n\t});\n\n\tit(\"DAM\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tif(ref.hear.length > 1){ return heard_to_much } // Alice should hear the GET\n\t\t\tif(ref.say){ return said_too_much } // But should not reply because their reply hash dedups with an earlier reply that was added to the GET.\n\t\t\ttest.done()\n\t\t}, {acks: config.relays});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/2getget.js",
    "content": "/*\nThis test is almost the opposite of the first test.\n1. Alice saves data \"\"offline\"\" so nobody knows it exists.\n2. Then Carl & Dave simultaneously ask for it, even tho they are not connected to Alice and Bob does not know where it is.\n3. They must receive the data, and their requests must not conflict or cause the other's to drop.\n4. Optionally: Then Ed comes along and asks for the data again, he must receive it from the closest cached peer.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 1,\n\tbrowsers: 4,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar bob = relays.pluck(1);\nvar browsers = clients.excluding(relays);\nvar alice = browsers.pluck(1);\nvar carl = browsers.excluding(alice).pluck(1);\nvar dave = browsers.excluding([alice, carl]).pluck(1);\nvar cd = new panic.ClientList([carl, dave]);\nvar ed = browsers.excluding([alice, carl, dave]).pluck(1);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"GET GET\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tvar args = ['start', '--port', port, '--sled-storage=false'];\n\t\t\t\t\tif (peers.length) {\n\t\t\t\t\t\targs.push('--peers=' + peers.join(',').replaceAll('http', 'ws'));\n\t\t\t\t\t}\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, args);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\n\t\t\t\t/* BELOW IS HACKY NON-STANDARD TEST STUFF, DO NOT REUSE */\n\t\t\t\tsetInterval(function(){\n\t\t\t\t\tvar tmp = gun._.graph.a;\n\t\t\t\t\tif(!tmp || !tmp.hello){ return }\n\t\t\t\t\ttmp.hello = \"bob_cache\";\n\t\t\t\t}, 1);\n\t\t\t\t// END HACKY STUFF.\n\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun', localStorage: false});\n\t\t\t\twindow.gun = gun;\n\t\t\t\twindow.ref = gun.get('a');\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n// end PANIC template -->\n\n\tit(\"connect\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tgun.get('random').get(function(ack){\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t}, 1000);\n\t\t\t})\n\t\t});\n\t});\n\n\tit(\"Put\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\t\n\t\t\tvar dam = ref.back('opt.mesh');\n\t\t\tvar say = dam.say;\n\t\t\tdam.say = function(){}; // prevent from syncing\n\n\t\t\tvar c = 0;\n\t\t\tref.put({hello: 'world'}, function(ack){ ++c }); // count acks, which should be none because disconnected\n\t\t\tsetTimeout(function(){\n\t\t\t\tif(c){ return should_not_have_ack } // make sure there were none.\n\t\t\t\tdam.say = say; // restore normal code\n\t\t\t\ttest.done();\n\t\t\t}, 1000);\n\t\t});\n\t});\n\n\tit(\"Get\", function(){\n\t\treturn cd.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I am Carl or Dave\");\n\t\t\tref.get(function(ack){ // this makes sure data was found p2p, even without subscription knowledge.\n\t\t\t\tif(ack.put){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Get Cached\", function(){\n\t\treturn ed.run(function(test){\n\t\t\ttest.async();\n\n\t\t\tref.get(function(ack){ // the data should reply from a cache in the daisy chain now.\n\t\t\t\tif(test.c){ return }\n\t\t\t\tif(ack.put.hello !== 'bob_cache'){\n\t\t\t\t\tconsole.log(\"FAIL: we_want_bob_only\");\n\t\t\t\t\treturn we_want_bob_only;\n\t\t\t\t}\n\t\t\t\ttest.done();test.c=1;\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/3puts.js",
    "content": "/*\nMake sure that our writes are all saved by the other browser.\n// Note: This test has many manual adjustments: Many features disabled, etc. consider some variations.\n// Bug: Failing due to lS ack disabled if peered, need to fix with advanced probabilistic mode.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 1,\n\tbrowsers: 2,\n\tputs: 1000,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar bob = relays.pluck(1);\nvar browsers = clients.excluding(relays);\nvar alice = browsers.pluck(1);\nvar carl = browsers.excluding(alice).pluck(1);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"Put ACK\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tvar args = ['start', '--port', port, '--sled-storage=false'];\n\t\t\t\t\tif (peers.length) {\n\t\t\t\t\t\targs.push('--peers=' + peers.join(',').replaceAll('http', 'ws'));\n\t\t\t\t\t}\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, args);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar gun = Gun({file: false, rad: false, localStorage: false, file: env.i+'data', peers: peers, web: server, axe: false});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n// end PANIC template -->\n\n\tit(\"Alice\", function(){\n\t\treturn alice.run(function(test){\n\t\t\twindow.ALICE = 1;\n\t\t}, {puts: config.puts});\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun', localStorage: window.ALICE? false : true});\n\t\t\t\twindow.ref = gun.get('test').on(function(){ });\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Puts\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tvar i = test.props.puts, d = 0;\n\t\t\twhile(i--){ go(i) }\n\t\t\tfunction go(i){\n\t\t\t\tref.get(i).put({hello: 'world'}, function(ack){\n\t\t\t\t\t//console.log(\"acked:\", JSON.stringify(ack.ok) || ('err:'+ack.err));\n\t\t\t\t\tif(ack.err){ put_failed }\n\t\t\t\t\tif(++d !== test.props.puts){ return }\n\t\t\t\t\tconsole.log(\"all success\", d);\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}\n\t\t}, {puts: config.puts});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/4putackdedup.js",
    "content": "/*\nAssume we have 5000 peers in a star topology:\n\n ..______r1______..\n ./.../..|...\\...\\.\n b1..b2..b3..b4..b5\n\nThey are all subscribed to the same data and Alice makes a 1 byte change to it. Even if a save acknowledgement is 1 byte, that would be 5K times the change. This does not scale. So instead, Alice states a sample size of 3/X and then the peers saving data use that ratio to decide whether they ack.\n\nEach time the message gets relayed we modify X to be how many peers this hop sent it to. We also should decrease the sample size by 1.\n\nThis test checks that we get fewer acks than (half) the peers connected.\nThis also tests that custom ACKs get sent back thru AXE to one of the sending peers.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 1,\n\tbrowsers: 9,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar r1 = relays.pluck(1);\n\nvar browsers = clients.excluding(relays);\nvar b1 = browsers.pluck(1);\nvar others = browsers.excluding(b1);\nvar b2 = relays.excluding(b1).pluck(1);\nvar b3 = relays.excluding([b1,b2]).pluck(1);\nvar b4 = relays.excluding([b1,b2]).pluck(1);\nvar b5 = relays.excluding([b1,b2]).pluck(1);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"Dedup load balancing GETs\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tvar args = ['start', '--port', port, '--sled-storage=false'];\n\t\t\t\t\tif (peers.length) {\n\t\t\t\t\t\targs.push('--peers=' + peers.join(',').replaceAll('http', 'ws'));\n\t\t\t\t\t}\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, args);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar gun = Gun({peers: peers, web: server, rad: false, radisk: false, file: false, localStorage: false});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\n\t\t\t\t//gun.get('test').put({tmp: 1}); // temporary workaround for bug.\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n// end PANIC template -->\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(browser, id){\n\t\t\ttests.push(browser.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\t\n\t\t\t\t// start with the first peer:\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun', localStorage: false});\n\n\t\t\t\twindow.gun = gun;\n\t\t\t\twindow.ref = gun.get('test');\n\n\t\t\t\tref.on(function(data){ });\n\n\t\t\t}, {i: i += 1, config: config}));\n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"ACK\", function(){\n\t\tvar tests = [], i = 0;\n\t\tothers.each(function(browser, id){\n\t\t\ttests.push(browser.run(function(test){\n\t\t\t\tvar id = test.props.i;\n\n\t\t\t\t// these lines are for debugging...\n\t\t\t\t/*var dam = ref.back('opt.mesh');\n\t\t\t\tvar say = dam.say;\n\t\t\t\tdam.say = function(raw, peer){\n\t\t\t\t\tsay(raw, peer);\n\t\t\t\t\t//console.log(\"said:\", JSON.stringify(raw));\n\t\t\t\t}\n\t\t\t\tvar hear = dam.hear;\n\t\t\t\tdam.hear = function(raw, peer){\n\t\t\t\t\t//console.log(\"heard:\", raw);\n\t\t\t\t\thear(raw, peer);\n\t\t\t\t}*/\n\n\t\t\t\tgun.on('put', function(msg){\n\t\t\t\t\tvar ok = msg.ok;\n\t\t\t\t\tif(ok['@'] > 2){\n\t\t\t\t\t\tconsole.log(\"Relay did not decrement!\")\n\t\t\t\t\t\ttest.fail(\"Relay did not decrement!\");\n\t\t\t\t\t\t_relay_did_not_decrement;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(Math.random() > (ok['@'] / ok['/'])){ return }\n\t\t\t\t\t//console.log(\"WAS THE SPECIAL ONE TO ACK!\", JSON.stringify(msg));\n\t\t\t\t\tgun.on('out', {'@': msg['#'], ok: {yay: 1}});\n\t\t\t\t});\n\n\t\t\t}, {i: i += 1, config: config}));\n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\t\n\tit(\"wait...\", function(done){\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},2000);\n\t});\n\n\tit(\"Alice saves data\", function(){\n\t\treturn b1.run(function(test){\n\t\t\ttest.async();\n\n\t\t\t// these lines are for debugging...\n\t\t\t/*var dam = ref.back('opt.mesh');\n\t\t\tvar say = dam.say;\n\t\t\tdam.say = function(raw, peer){\n\t\t\t\tsay(raw, peer);\n\t\t\t\t//console.log(\"said:\", JSON.stringify(raw), dam.near, Object.keys(gun._.opt.peers).join(','));\n\t\t\t}\n\t\t\tvar hear = dam.hear;\n\t\t\tdam.hear = function(raw, peer){\n\t\t\t\thear(raw, peer);\n\t\t\t\t//console.log(\"heard:\", raw);\n\t\t\t}*/\n\n\t\t\tvar many = test.props.config.browsers;\n\t\t\tconsole.log(\"Alice is saving...\");\n\t\t\ttest.c = 0;\n\t\t\tref.put({hello: 'world'}, function(ack){\n\t\t\t\tif(!ack.ok.yay){\n\t\t\t\t\ttest.fail(\"ERROR: No custom ack!\");\n\t\t\t\t\tconsole.log(\"ERROR: No custom ack!\");\n\t\t\t\t\treturn no_custom_ack;\n\t\t\t\t}\n\t\t\t\t//console.log(\"I saved data, this is the ACK\", JSON.stringify(ack));\n\t\t\t\ttest.c++;\n\t\t\t\tclearTimeout(test.to);\n\t\t\t\ttest.to = setTimeout(function(){\n\t\t\t\t\tif(test.c >= (many/2)){\n\t\t\t\t\t\ttest.fail(\"ERROR: Too many acks!\");\n\t\t\t\t\t\tconsole.log(\"ERROR: Too many acks!\");\n\t\t\t\t\t\treturn too_many_acks;\n\t\t\t\t\t}\n\t\t\t\t\ttest.done();\n\t\t\t\t}, 999);\n\t\t\t\t\n\t\t\t}, {ok: 3, acks: 9999});\n\t\t}, {config: config});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\tconsole.log(\"REMINDER: RUN THIS TEST WITH AXE ON & OFF!\");\n\t\trequire('./util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/axe/1no_self.js",
    "content": "/*\nIt is possible to connect to yourself, which just wastes bandwidth, so this test checks that we disconnect from ourselves.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 1\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\t//config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar alice = relays.pluck(1);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"Do not connect to self\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\tglobal.self_url = 'http://'+ env.config.IP + ':' + port + '/gun';\n\t\t\t\t// make sure to connect to self/same.\n\t\t\t\tpeers.push(self_url);\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tvar args = ['start', '--port', port, '--sled-storage=false'];\n\t\t\t\t\tif (peers.length) {\n\t\t\t\t\t\targs.push('--peers=' + peers.join(',').replaceAll('http', 'ws'));\n\t\t\t\t\t}\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, args);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server, multicast: false});\n\t\t\t\tglobal.gun = gun;\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n// end PANIC template -->\n\n\tit(\"Drop self\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\tvar peers = gun.back('opt.peers');\n\t\t\t\tvar peer = peers[self_url];\n\n\t\t\t\tgun.get('test').on(function(a){ });\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tif(peers[self_url] || peer.wire){\n\t\t\t\t\t\tconsole.log(\"FAIL: should_not_have_self_anymore\");\n\t\t\t\t\t\tshould_not_have_self_anymore;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\ttest.done();\n\t\t\t\t},99);\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('../util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/axe/2no_dup.js",
    "content": "/*\nIf Alice calls Bob and Bob calls Alice, 2 connections will be formed, which wastes bandwidth. This test checks for that and deduplicates the connections.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 3,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"Put ACK\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){ // make sure to connect to self/same.\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t}\n\t\t\t\tglobal.peerID = String.fromCharCode(64 + env.i);\n\t\t\t\tconsole.log(env.i, port, \" connect to \", peers);\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tvar args = ['start', '--port', port, '--sled-storage=false'];\n\t\t\t\t\tif (peers.length) {\n\t\t\t\t\t\targs.push('--peers=' + peers.join(',').replaceAll('http', 'ws'));\n\t\t\t\t\t}\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, args);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// TODO what should gun be when testing on rod?\n\t\t\t\tvar gun = Gun({file: env.i+'data', pid: peerID, peers: peers, web: server});\n\t\t\t\tglobal.gun = gun;\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n// end PANIC template -->\n\n\tit(\"Drop duplicates\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\tvar peers = gun.back('opt.peers');\n\n\t\t\t\tgun.get('test').on(function(a){ }); // connections are lazy, so trigger a read. A feature, tho also a bug in this case, should probably have its own tests to determine if this ought be intended or not.\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tvar p = [], o = {}, err; Object.keys(peers).forEach(function(id){\n\t\t\t\t\t\tid = peers[id];\n\t\t\t\t\t\tp.push(id.pid);\n\t\t\t\t\t\terr = err || (o[id.pid] = (o[id.pid] || 0) + 1) - 1;\n\t\t\t\t\t});\n\t\t\t\t\tconsole.log(peerID, 'connected to:', p);\n\t\t\t\t\tif(p.length > 2 || err){\n\t\t\t\t\t\tconsole.log(\"FAIL: too_many_connections\");\n\t\t\t\t\t\ttoo_many_connections;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\ttest.done();\n\t\t\t\t},2000);\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('../util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/axe/3get_turns.js",
    "content": "/*\nAssume we have 6 peers in a star topology,\n\n ..______r1______..\n ./.../..|...\\...\\.\n b1..b2..b3..b4..b5\n\n Alice, Bob, Carl, Dave, Ed using 1 relay. Alice joins later, asks for data all the others are subscribed to. The GET should be load balanced to ?3? other peers at a time. If ack hashes are not the same, keep asking. If they do match, stop asking other peers - this test checks that.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 1,\n\tbrowsers: 5,\n\troute: {\n\t\t'/': __dirname + '/../index.html',\n\t\t'/gun.js': __dirname + '/../../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar r1 = relays.pluck(1);\n\nvar browsers = clients.excluding(relays);\nvar b1 = browsers.pluck(1);\nvar b2 = relays.excluding(b1).pluck(1);\nvar b3 = relays.excluding([b1,b2]).pluck(1);\nvar b4 = relays.excluding([b1,b2]).pluck(1);\nvar b5 = relays.excluding([b1,b2]).pluck(1);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"Dedup load balancing GETs\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){ // make sure to connect to self/same.\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t}\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tvar args = ['start', '--port', port, '--sled-storage=false'];\n\t\t\t\t\tif (peers.length) {\n\t\t\t\t\t\targs.push('--peers=' + peers.join(',').replaceAll('http', 'ws'));\n\t\t\t\t\t}\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, args);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('../util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n// end PANIC template -->\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(browser, id){\n\t\t\ttests.push(browser.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\t\n\t\t\t\t// start with the first peer:\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\n\t\t\t\twindow.gun = gun;\n\t\t\t\twindow.ref = gun.get('test');\n\t\t\t\twindow.ID = test.props.i;\n\n\t\t\t\tif(window.ID === 1){ return } // everyone BUT NOT alice yet.\n\t\t\t\ttest.async();\n\n\t\t\t\tgun.get('test').on(function(data){\n\t\t\t\t\tif(window.C){ return } window.C = 1;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tvar dam = ref.back('opt.mesh');\n\t\t\t\t\t\tvar hear = dam.hear;\n\t\t\t\t\t\tdam.hear = function(raw, peer){\n\t\t\t\t\t\t\t//console.log(window.ID, \"HEARD:\", raw);\n\t\t\t\t\t\t\twindow.HEARD = 1;\n\t\t\t\t\t\t\thear(raw, peer);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 1000);\n\t\t\t\t\ttest.done();\n\t\t\t\t})\n\t\t\t\tif(window.ID == 2){\n\t\t\t\t\tsetTimeout(function(){ gun.get('test').put({hello: 'world'}) },1000);\n\t\t\t\t}\n\t\t\t}, {i: i += 1, config: config}));\n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\t\n\tit(\"wait...\", function(done){\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},2000);\n\t});\n\n\tit(\"Carl already has the data.\", function(){\n\t\treturn b3.run(function(test){\n\t\t\ttest.async();\n\t\t\tif('world' === gun._.graph.test.hello){ // TODO: BAD! Tests should probably not use non-API ways to check things. But whatever, hacky for now.\n\t\t\t\ttest.done();\n\t\t\t}\n\t\t}, {acks: config.relays});\n\t});\n\n\tit(\"Alice does not have the data, needs to ask for it.\", function(){\n\t\treturn b1.run(function(test){\n\t\t\tif(window.ID !== 1){\n\t\t\t\tconsole.log(\"FAIL: Alice not match ID\");\n\t\t\t\talice_mismatch;\n\t\t\t}\n\t\t\tif(gun._.graph.test){ // TODO: BAD! Tests should probably not use non-API ways to check things. But whatever, hacky for now.\n\t\t\t\tconsole.log(\"FAIL: Alice got synced data she was not subscribed to. This may mean a more basic feature (pub/sub) of AXE is broken.\");\n\t\t\t\talice_already_had_the_data;\n\t\t\t}\n\t\t\ttest.async();\n\n\t\t\tref.once(function(data){\n\t\t\t\tif('world' === data.hello){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t})\n\t\t}, {acks: config.relays});\n\t});\n\n\tit(\"How many heard?\", function(){ // This test is a little weird...\n\t\tthis.timeout(2000);\n\t\tvar heard = 0, missed = 0;\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(browser, id){\n\t\t\ttests.push(browser.run(function(test){\n\t\t\t\t//console.log(window.ID, 'heard?', window.HEARD);\n\t\t\t\ttest.async();\n\t\t\t\tif(window.HEARD){\n\t\t\t\t\ttest.done();\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"DID NOT HEAR\");\n\t\t\t\t}\n\t\t\t}, {i: i += 1, config: config}).then(function(){\n\t\t\t\tconsole.log(id.slice(0,2), \"was asked\");\n\t\t\t\t heard += 1;\n\t\t\t}).catch(function(err){\n\t\t\t\tif(0 <= err.message.indexOf('NOT HEAR')){\n\t\t\t\t\tconsole.log(id.slice(0,2), \"was NOT asked.\");\n\t\t\t\t\tmissed += 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthrow new Error(\"other error\");\n\t\t\t}));\n\t\t});\n\t\treturn Promise.all(tests).then(function(){\n\t\t\tconsole.log(\"COMPARE?\", heard, missed);\n\t\t\tif(missed >= 2 && heard <= 3){ return }\n\t\t\tconsole.log(\"ERROR! Note: This test was hardcoded to 3 AXE turns. If turns are dynamic or different or variable now, you need to update this test.\")\n\t\t\tthrow new Error(\"GET was heard by too many peers!\");\n\t\t})\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('../util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/axe/4get_subs.js",
    "content": "/*\nThis test is similar to GUN/2getget test, but we add in routing & subscriptions:\n1. Alice saves data \"\"offline\"\" so nobody knows it exists.\n2. Then Carl & Dave simultaneously ask for it, even tho they are not connected to Alice and Bob does not know where it is.\n3. They must receive the data, and their requests must not conflict or cause the other's to drop, and they must be subscribed to the data.\n4. Ed must not get pushed the data or be subscribed.\n\n..F--Bob--E\n./...|\\....\nA....C.D...\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 3,\n\tbrowsers: 3,\n\troute: {\n\t\t'/': __dirname + '/../index.html',\n\t\t'/gun.js': __dirname + '/../../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar bob = relays.pluck(1);\nvar fred = relays.excluding(bob).pluck(1);\nvar ed = relays.excluding([bob, fred]).pluck(1);\nvar browsers = clients.excluding(relays);\nvar alice = browsers.pluck(1);\nvar carl = browsers.excluding(alice).pluck(1);\nvar dave = browsers.excluding([alice, carl]).pluck(1);\nvar cd = new panic.ClientList([carl, dave]);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"GET GET\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\t\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tObject.PORT = port;\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server, multicast: false});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t\tglobal.gun = gun;\n\t\t\t\tglobal.WHO = port;\n\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('../util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\twindow.ID = test.props.i;\n\n\t\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + ((ID === 1)? 2 : 1)) + '/gun', localStorage: false});\n\t\t\t\twindow.gun = gun;\n\t\t\t\twindow.ref = gun.get('a');//.on(function(){ });\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n// end PANIC template -->\n\n\tit(\"connect\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\twindow.WHO = \"Alice\";\n\t\t\ttest.async();\n\t\t\tgun.get('random').get(function(ack){\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t}, 1000);\n\t\t\t})\n\t\t});\n\t});\n\n\tit(\"Put\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\t\n\t\t\tvar dam = ref.back('opt.mesh');\n\t\t\tvar say = dam.say;\n\t\t\tdam.say = function(){}; // prevent from syncing\n\n\t\t\tvar c = 0;\n\t\t\tref.put({hello: 'world'}, function(ack){ ++c }); // count acks, which should be none because disconnected\n\t\t\tsetTimeout(function(){\n\t\t\t\tif(c){ return should_not_have_ack } // make sure there were none.\n\t\t\t\tdam.say = say; // restore normal code\n\t\t\t\ttest.done();\n\n\t\t\t\tgun.get('a').on(function(data){ });\n\t\t\t}, 1000);\n\t\t});\n\t});\n\n\tit(\"Get\", function(){\n\t\treturn cd.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I am Carl or Dave\");\n\t\t\twindow.WHO = \"Carl\";\n\t\t\tref.get(function(ack){ // this makes sure data was found p2p, even without subscription knowledge.\n\t\t\t\tif(ack.put){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Dave pushes changes\", function(){\n\t\treturn dave.run(function(test){\n\t\t\twindow.WHO = \"Dave\";\n\t\t\ttest.async();\n\t\t\tref.put({hello: \"dave\"});\n\t\t\tsetTimeout(test.done, 2 * 1000);\n\t\t});\n\t});\n\n\tit(\"All updated, but not Ed.\", function(){\n\t\tvar tests = [], i = 0;\n\t\tclients.excluding(ed).each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\n\t\t\t\ttest.async();\n\t\t\t\tconsole.log(WHO, \"cache:\", JSON.stringify(gun._.graph.a));\n\t\t\t\tif(\"dave\" !== gun._.graph.a.hello){\n\t\t\t\t\tthrow new Error(\"not_updated\");\n\t\t\t\t\treturn not_updated;\n\t\t\t\t}\n\t\t\t\ttest.done();\n\n\t\t\t})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Ed NOT subscribed\", function(){\n\t\treturn ed.run(function(test){\n\t\t\ttest.async();\n\n\t\t\tconsole.log(\"Ed's cache:\", JSON.stringify(gun._.graph.a));\n\t\t\tif(gun._.graph.a){\n\t\t\t\tthrow new Error(\"was_updated\");\n\t\t\t\treturn was_updated;\n\t\t\t}\n\t\t\ttest.done();\n\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('../util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/axe/5mob.js",
    "content": "/*\nIf WebRTC fails browsers will fallback to using a relay.\nA relay may be running on a Raspberry Pi or some low-end cloud VM.\nThere is a limit to how many peers it can help before it crashes.\nIt can only handle a \"mob\" of a certain size.\nSo what happens then?\n\nIt would be useful if it could tell newly connecting peers to connect to someone else.\nThis will rebalance the load on the network.\n\nImagine there are 3 relays that can handle 100K peers,\nBut then 300K peers connect to the 1st one.\nWe want to then see the peers move to the other relays, such that the 3 have 100K peers each.\n\n(1) To simulate this, we will have 3 peers connect starting like this:\n  ..r1-----r2--r3\n  ./\\.\\..........\n  b1.b2.b3.......\n\n(2) By the end of the test, the \"mob\" logic should rebalance the load to look like this:\n  ..r1--r2--r3..\n  ./....|.....\\.\n  b1....b2....b3\n\nIf it does, the test passes.\n\n(Note: At the end of this test, it uses GUN to sync data about what peers are connected to whom. While this is useful in that it also verifies that sync between b1 <-> b3 works regardless of whether direct or indirect connections, as such it could result in errors: If GUN has a bug, the AXE test may fail even if it is not the fault of AXE, and likewise - the usage of GUN in this test is contrived, it passing has 0 correlation that GUN is correctly handling the sync logic. In fact, assume it is not, make sure you use another test to verify that.)\n\nThanks @Draeder for helping with these tests!!!!\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 3,\n\tbrowsers: 3,\n\troute: {\n\t\t'/': __dirname + '/../index.html',\n\t\t'/gun.js': __dirname + '/../../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar r1 = relays.pluck(1);\nvar r2 = relays.excluding(r1).pluck(1);\nvar r3 = relays.excluding([r1,r2]).pluck(1);\n\nvar browsers = clients.excluding(relays);\nvar b1 = browsers.pluck(1);\nvar b2 = relays.excluding(b1).pluck(1);\nvar b3 = relays.excluding([b1,b2]).pluck(1);\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"Mob test.\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\ttest.async();\n\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){ // make sure to connect to self/same.\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t}\n\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\tconsole.log('testing with rod');\n\t\t\t\t\tvar args = ['start', '--port', port, '--sled-storage=false'];\n\t\t\t\t\tif (peers.length) {\n\t\t\t\t\t\targs.push('--peers=' + peers.join(',').replaceAll('http', 'ws'));\n\t\t\t\t\t}\n\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, args);\n\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\trequire('fs').unlinkSync(env.i + 'data')\n\t\t\t\t} catch (e) {\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\trequire('gun/lib/fsrm')(env.i + 'data')\n\t\t\t\t} catch (e) {\n\t\t\t\t}\n\t\t\t\tvar server = require('http').createServer(function (req, res) {\n\t\t\t\t\tres.end(\"I am \" + env.i + \"!\");\n\t\t\t\t});\n\t\t\t\tvar Gun;\n\t\t\t\ttry {\n\t\t\t\t\tGun = require('gun')\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\")\n\t\t\t\t}\n\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server, mob: 3, multicast: false});\n\t\t\t\tglobal.gun = gun;\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\tgun.get('a').on(function(){ }); // TODO: Wrong! This is an example of the test using GUN in weird ways to work around bugs at the time of writing. This line should not be necessary, AXE should still pass even if this line is commented out, however if it fails then that is a bug in GUN's logic, not AXE.\n\t\t\t}, {i: i += 1, config: config}));\n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('../util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n// end PANIC template -->\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(browser, id){\n\t\t\ttests.push(browser.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\t\n\t\t\t\t// start with the first peer:\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\n\t\t\t\t// NOTE: This \"mob\" logic will be moved into axe.js (or maybe gun.js itself), but while we're building the logic it is easier to quickly hack/iterate by prototyping here in the test itself until it passes. But it needs to be refactored into the actual code or else you might have false positives of this test overloading \"mob\" logic.\n\t\t\t\t// ^^^^^^^^^ THIS HAS BEEN MOVED TO GUN CORE, HOWEVER,\n\t\t\t\t// ^^^^^^^^^ EXPERIMENT WITH MORE ADVANCED LOGIC THAT AXE OVERLOADS CORE.\n\t\t\t\tvar mesh = gun.back('opt.mesh'); // overload...\n\t\t\t\t/*mesh.hear['mob'] = function(msg, peer){\n\t\t\t\t\t// TODO: NOTE, code AXE DHT to aggressively drop new peers AFTER superpeer sends this rebalance/disconnect message that contains some other superpeers.\n\t\t\t\t\tclearTimeout(gun.TO); gun.TO = setTimeout(end, 2000);\n\t\t\t\t\tif(!msg.peers){ return }\n\t\t\t\t\tvar peers = Object.keys(msg.peers), one = peers[Math.floor(Math.random()*peers.length)];\n\t\t\t\t\tconsole.log('Browser', env.i, 'chooses', one, 'from', JSON.stringify(peers), 'that', peer.url, 'suggested, because it is mobbed.');//, 'from', msg.peers+'');\n\t\t\t\t\tmesh.bye(peer); // Idea: Should keep track of failed ones to reduce repeats. For another feature/module that deserves its own separate test.\n\t\t\t\t\tmesh.hi(one);\n\t\t\t\t}*/\n\n\t\t\t\t//console.log('Browser', env.i, \"started with:\", Object.keys(gun._.opt.peers)+'');\n\t\t\t\twindow.gun = gun;\n\t\t\t\twindow.ref = gun.get('test');\n\t\t\t\tfunction end(){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t\tgun.TO = setTimeout(end, 3000);\n\t\t\t}, {i: i += 1, config: config}));\n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\t\n\tit(\"wait...\", function(done){\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},3000);\n\t});\n\n\tit(\"Got Load Balanced to Different Peer\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(browser, id){\n\t\t\ttests.push(browser.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\tref.get('b'+test.props.i).put(''+Object.keys(gun.back('opt.peers')));\n\t\t\t\t// NOTE: Above line was put here as a workaround. Even if this line was in the prior step, this test should still pass. Make sure there is another test that correctly checks for reconnect logic properly restoring sync.\n\n\t\t\t\tref.on(function(data){\n\t\t\t\t\tif(!data.b1 || !data.b2 || !data.b3){ return }\n\t\t\t\t\tclearTimeout(test.to);\n\t\t\t\t\ttest.to = setTimeout(function(){\n\t\t\t\t\t\tvar d = {}; Object.keys(data).sort().forEach(function(i){ d[i] = data[i] }); delete d._; console.log(test.props.i, \"sees\", JSON.stringify(d));\n\t\t\t\t\t\tvar now = Object.keys(gun.back('opt.peers'));\n\t\t\t\t\t\tif(now.length > 1){\n\t\t\t\t\t\t\tconsole.log(\"FAIL: too_many_connections\");\n\t\t\t\t\t\t\ttoo_many_connections;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar not = {};\n\t\t\t\t\t\tObject.keys(data).forEach(function(k,v){ v = data[k];\n\t\t\t\t\t\t\tif('_' === k){ return }\n\t\t\t\t\t\t\tif(v.split(',').length > 1){\n\t\t\t\t\t\t\t\tconsole.log(\"FAIL: too_many\");\n\t\t\t\t\t\t\t\ttoo_many;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(not[v]){\n\t\t\t\t\t\t\t\tconsole.log(\"FAIL: already\");\n\t\t\t\t\t\t\t\talready_;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnot[v] = 1;\n\t\t\t\t\t\t});\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t}, 2000);\n\t\t\t\t});\n\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('../util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/axe/index.html",
    "content": "<script src='panic.js'></script>\n<script>panic.server(location.origin)</script>\n<script src='gun.js'></script>\n<script src='gun/axe.js'></script>\n<script src=\"gun/lib/radix.js\"></script>\n<script src='gun/lib/webrtc.js'></script>\n<script src='jquery.js'></script>\n<meta charset=\"utf-8\"/>\n<h1>Running AXE Tests</h1>\n<div><span>Name: </span><span id=\"name\"></span></div>\n<div><span>PID: </span><span id=\"pid\"></span></div>\n<div id=\"log\"></div>\n<!-- <textarea id=\"print\" style=\"width: 100%; height: 90%; border: 0;\"></textarea> -->\n"
  },
  {
    "path": "test/panic/axe/load_balance.js",
    "content": "/**\n * AXE test loadbalance\n *\n * Bob, Carl, Dave, Ed, subscribed to Zebra(relay).\n * \n * Test case 3) Bob Carl Dave Ed browser peers, all subscribed to Zebra(Relay). Alice joins, gets Zebra. Relay should only load balance GET to 3 other peers, as acks will have matching hashes and therefore stop propagating. (if acks are inconsistent, it will keep propagating, but we're not testing that here). The tricky thing is you'll have to hijack requests to make sure the 4th peer doesn't get the GET.\n */\n\nvar config = { IP: require('ip').address(), port: 8765, servers: 1, browsers:4, i:0,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../../gun.js',\n\t\t'/gun/axe.js': __dirname + '/../../../axe.js',\n\t\t'/jquery.js': __dirname + '/../../../examples/jquery.js'\n\t}\n};\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){ config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\nmanager.start({\n\tclients: Array(config.servers).fill().map(function(u, i){ return { type: 'node', port: config.port + (i + 1) } }),\n\tpanic\t: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = servers.pluck(1);\nvar browsers = clients.excluding(servers);\n\ndescribe(\"AXE Test: LOADBALANCE\", function(){\n\tthis.timeout(5 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){ return servers.atLeast(config.servers); });\n\n\tit(\"GUN started!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'dataaxe') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'dataaxe') }catch(e){}\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){ res.end(\"I am \"+ env.i +\"!\"); });\n\t\t\tvar Gun = require('gun');\n//\t\t\t require('gun/axe');\n\t\t\tvar gun = global.gun = Gun({ file: env.i+'dataaxe', web: server, pid:'Relay_pid' });\n\t\t\tconsole.log('\t\t [ RELAY PID ] '+gun._.opt.pid);\n\t\t\tGun.on('create', function(root){\n\t\t\t\tthis.to.next(root);\n\t\t\t\troot.on('in', function(msg){\n\t\t\t\t\tconsole.log('[ GET RELAY ]* PID:'+gun._.opt.pid+' RELAY MESSAGE: ', (msg));\n\t\t\t\t\tthis.to.next(msg);\n\t\t\t\t});\n\t\t\t\troot.on('out', function(msg){\n\t\t\t\t\tconsole.log('[ OUT RELAY ]* ', msg);\n\t\t\t\t\tthis.to.next(msg);\n\t\t\t\t});\n\n\t\t\t});\n\t\t\tserver.listen(port, function(){ test.done(); });\n\t\t\tgun.get('ref_soul').put({ 'hi':'value_'+String.random(3) });\n\t\t}, {i: 1, config: config});\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('../util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n//\t\t console.log(\"\t PLEASE OPEN http://\"+ config.IP +\":\"+ config.port +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i=0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tlocalStorage.clear(); //console.log('Clear localStorage!!!');\n\t\t\t\twindow.uuid = function(l){ return new Date(Gun.state()).toISOString() + '/' + String.random(l||3) };\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar opt = {\n\t\t\t\t\tpeers:['http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'],\n// \t\t\t\tpid:'Peer_'+('0'+(env.config.i+1)).slice(-2)+'_',\n\t\t\t\t\tuuid\n\t\t\t\t};\n\n\t\t\t\tGun.on('create', function(root){\n\t\t\t\t\tthis.to.next(root);\n\t\t\t\t\troot.on('in', function(msg){\n\t\t\t\t\t\tthis.to.next(msg);\n\t\t\t\t\t\tif (msg.get && msg.get['#'] && msg.get['#'] !== 'balance') {\n\t\t\t\t\t\t\t++gun.total_gets; /// increment each peer total `in` events\n\t\t\t\t\t\t\tvar hash = (msg['#'] ? '_'+msg['#'] : '') + (msg['><'] ? '_O ' : '');\n\t\t\t\t\t\t\tgun.get('balance').set(gun._.opt.pid+' '+(msg['#'] ? '_msg_id_'+msg['#'] : ''));\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\tvar gun = window.gun = Gun(opt);\n\t\t\t\tgun.total_gets=0;\n\t\t\t}, {i: i += 1, config: config}));\n\t\t\t++config.i;\n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\t\n\tit(\"Peers subscribe\", function(){\n\t\tvar tests = [], i=0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\tfunction done(v,k) {\n// \t\t\t\t\tconsole.log('!!!!!!! Peer subscribed pid:' + gun._.opt.pid + ' msg:' + JSON.stringify({ k, v }));\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n        gun.get('ref_soul').once(done);\n\t\t\t}, {i: i += 1, config: config}));\n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Check balance!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tfunction onlyUnique(value, index, self) { return self.indexOf(value) === index; }\n\t\t\tconsole.log('RELAY PID:' + gun._.opt.pid);\n\t\t\ttest.async();\n\t\t\tgun.get('balance').once(function(v,k) {\n        var tmp = [], i=0, participants=[], keys = Object.keys(v['_']).sort();\n\t\t\t\tfor (i=0;i<keys.length;++i) { participants.push(v[ keys[ i ] ]); }\n\t\t\t\tparticipants.sort();\n\t\t\t\tvar pid, pids = Object.keys(v).sort();\n\t\t\t\tvar pids_sorted = Object.keys(v['_']['>']).map(soul => v[soul].split(' ')[0]).filter(onlyUnique).sort();\n\t\t\t\tvar msgs_id = Object.keys(v['_']['>']).map(soul => v[soul].split(' ')[1]).filter(onlyUnique);\n\t\t\t\tvar msgs_sorted_bytime = Object.keys(v['_']['>']).sort();\n\t\t\t\tvar table={}, msg_id, peer_id;\n\n\t\t\t\tfor (i=0;i<msgs_sorted_bytime.length;++i) {\n\t\t\t\t\ttmp =v[msgs_sorted_bytime[i]].split(' ');\n\t\t\t\t\tpeer_id = tmp[0];\n\t\t\t\t\tmsg_id = tmp[1];\n\t\t\t\t\tif (!table[msg_id]) { table[msg_id]=[]; }\n\t\t\t\t\ttable[msg_id].push(peer_id);\n\t\t\t\t\tif (table[msg_id].length > 4) { console.log('Ouch!!!!', table); test.fail('Msg ('+msg_id+') with more then 4 requests.'); return; }\n\t\t\t\t}\n\t\t\t\tfor (i=0;i<pids_sorted.length;++i) {\n          if (typeof pids_sorted[i] !== 'string') { continue; }\n\t\t\t\t\tpid = pids_sorted[i];\n\t\t\t\t}\n\t\t\t\tfor (i=0;i<pids.length;++i) {\n\t\t\t\t\tvar p1=pids[i-1], p2=pids[i];\n\t\t\t\t\tif (!v[p1] || !v[p2]) { continue; }\n\t\t\t\t\tif ('string' !== typeof v[p1]) { v[p1]='relay'; }\n\t\t\t\t\tif ('string' !== typeof v[p2]) { v[p2]='relay'; }\n\t\t\t\t}\n// \t\t\t\t console.log('TABLE: ', table);/// NOTE: this data have each peer_id who participant of a message delivery.\n\t\t\t\tsetTimeout(test.done, 1000);\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n//\t\t browsers.each(function(client, id){ client.run(function() { console.log('TOTAL gets PID:'+gun._.opt.pid+': ', gun.total_gets); }); });\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(done, 2000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t require('../util/open').cleanup() ||\tbrowsers.run(function(){\n\t\t\tsetTimeout(function(){ \n\t\t\t\tlocation.reload();\n\t\t\t}, 15 * 1000);\n\t\t});\n\t\treturn servers.run(function(){ process.exit(); });\n\t});\n});\n"
  },
  {
    "path": "test/panic/b2s2s2b.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 2,\n\tbrowsers: 2,\n\teach: 500,\n\tburst: 50,\n\twait: 1,\n\tnotrad: true,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar browsers = clients.excluding(servers);\n\ndescribe(\"Load test \"+ config.browsers +\" browser(s) across \"+ config.servers +\" server(s)!\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun = require('gun');\n\t\t\t\tvar peers = [], i = env.config.servers;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server, localStorage: env.config.notrad});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\tbrowsers.atLeast(1).then(function(){\n\t\t\tbrowsers.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\t$('body').prepend(\"<button onclick='allopen()'>Open All Browsers</button>\");\n\t\t\t\twindow.allopen = function(i){\n\t\t\t\t\tif(env.config.browsers <= i){ return }\n\t\t\t\t\ti = i || 1;\n\t\t\t\t\tvar win = window.open(location, '_blank');\n\t\t\t\t\twin.focus();\n\t\t\t\t\tsetTimeout(function(){allopen(i+1)},0);\n\t\t\t\t}\n\t\t\t}, {config: config});\n\t\t});\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Data was saved and synced across all browsers!\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t//Gun.state.drift = Math.random() * 10000;\t\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\tvar peers = [], i = env.i;\n\t\t\t\t//while(i--){\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + (env.config.port + (i)) + '/gun');\n\t\t\t\t//}\n\t\t\t\tconsole.log(\"Connect to\", peers);\n\t\t\t\tvar gun = Gun(peers);\n\t\t\t\tvar num = 0, total = 0, check = Gun.obj.map(env.ids, function(v,id,t){\n\t\t\t\t\tvar i = env.config.each;\n\t\t\t\t\twhile(i--){\n\t\t\t\t\t\tt(id + (i + 1), 1);\n\t\t\t\t\t\ttotal += 1;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tvar report = $(\"<div>\").css({position: 'fixed', top: 0, right: 0, background: 'white', padding: 10}).text(num +\" / \"+ total +\" Verified\").prependTo('body');\n\t\t\t\tvar wait;\n\t\t\t\tgun.get('test').map().on(function(data, key){\n\t\t\t\t\t//$(log).text(key +\": \"+ data);\n\t\t\t\t\tif((\"Hello world, \"+key+\"!\") === data){\n\t\t\t\t\t\tif(check[key]){ num += 1 }\n\t\t\t\t\t\tcheck[key] = 0;\n\t\t\t\t\t\treport.text(num +\" / \"+ total +\" Verified\");\n\t\t\t\t\t}\n\t\t\t\t\tif(wait){ return }\n\t\t\t\t\twait = setTimeout(function(){\n\t\t\t\t\t\twait = false;\n\t\t\t\t\t\tif(Gun.obj.map(check, function(still){\n\t\t\t\t\t\t\tif(still){ return true }\n\t\t\t\t\t\t})){ return }\n\t\t\t\t\t\tconsole.log(\"SUCCESS\");\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t},10);\n\t\t\t\t});\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tconsole.log(\"<<<<< START >>>>>\");\n\t\t\t\t\tvar i = 0, burst = false, to = setInterval(function go(){\n\t\t\t\t\t\tif(!burst){\n\t\t\t\t\t\t\tburst = env.config.burst;\n\t\t\t\t\t\t\twhile(--burst){\n\t\t\t\t\t\t\t\tgo();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tburst = false;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(env.config.each <= i){\n\t\t\t\t\t\t\tclearTimeout(to);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti += 1;\n\t\t\t\t\t\tvar p = env.id + i;\n\t\t\t\t\t\tgun.get('test').get(p).put('Hello world, '+ p +'!');\n\t\t\t\t\t}, env.config.wait);\n\t\t\t\t},500);\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/bulkimport.js",
    "content": "/*\nThis is the first in a series of basic networking correctness tests.\nEach test itself might be dumb and simple, but built up together,\nthey prove desired end goals for behavior at scale.\n1. (this file) Is a browser write is confirmed as save by multiple peers even if by daisy chain.\n2. \n*/\n\nvar config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\tputs: 1000,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar bob = servers.pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar carl = browsers.excluding(alice).pluck(1);\n\ndescribe(\"Put ACK\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun = require('gun');\n\t\t\t\tvar peers = [], i = env.config.servers;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.ref = gun.get('test');\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Puts\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tvar i = test.props.puts, d = 0;\n\t\t\twhile(i--){ go(i) }\n\t\t\tfunction go(i){\n\t\t\t\tref.get(i).put({hello: 'world'}, function(ack){\n\t\t\t\t\tif(ack.err){ put_failed }\n\t\t\t\t\tif(++d !== test.props.puts){ return }\n\t\t\t\t\tconsole.log(\"all success\", d);\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}\n\t\t}, {puts: config.puts});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/chat-user.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2, //3,\n\teach: 50000,//100000,\n\tsize: 1,\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/sea.js': __dirname + '/../../sea.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\n/*\nAssume we have 3 peers in a star topology,\n\n..B..\n./.\\.\nA...C\n\nAnd they share a chat room with 10K messages.\n\nA -> GET chat -> B (cache miss) -> C\nC hosts the data and streams it back\nC -> PUT chat -> B (relay) -> A got.\n\nUsing the WebRTC module, C <-> A directly, no need for a relay!\nBut we're wanting to test the performance of the whole network.\n*/\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){ // Static server\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port); // Start panic server.\n\n// In order to tell the clients what to do,\n// We need a way to reference all of them.\nvar clients = panic.clients;\n\n// Some of the clients may be NodeJS servers on different machines.\n// PANIC manager is a nifty tool that lets us remotely spawn them.\nvar manager = require('panic-manager')();\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){ // Create a bunch of servers.\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1) // They'll need unique ports to start their servers on, if we run the test on 1 machine.\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port // Auto-connect to our panic server.\n});\n\n// Now lets divide our clients into \"servers\" and \"browsers\".\nvar servers = clients.filter('Node.js');\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar carl = browsers.excluding(alice).pluck(1);\n\ndescribe(\"Load test \"+ config.browsers +\" browser(s) across \"+ config.servers +\" server(s)!\", function(){\n\tthis.timeout(50 * 60 * 1000);\n\n\tconsole.log('start', config.pair);\n\t// We'll have to manually launch the browsers,\n\t// So lets up the timeout so we have time to do that.\n\n\tit(\"Generate keypair\", async function(){\n\t\treturn config.pair = await require('gun/sea').pair();\n\t});\n\n\tit(\"Servers have joined!\", function(){\n\t\t// Alright, lets wait until enough gun server peers are connected.\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data.json') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\t// Launch the server and start gun!\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\t// Attach the server to gun.\n\t\t\t\tvar gun = Gun({file: env.i+'data', web: server, axe: false, localStorage: false, radisk: false});\n\t\t\t\tserver.listen(env.config.port + env.i, function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ (\"localhost\"||config.IP) +\":\"+ config.port); //console.log(\"PLEASE OPEN http://\"+ config.IP +\":\"+ config.port +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load SEA!\", function(){\n\t\t//return carl.run(function(test){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\tconsole.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\tload('sea.js', function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t\t//}, config);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\t//var gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\tvar gun = Gun({localStorage: false, radisk: false, peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'});\n\t\t\t\twindow.gun = gun;\n\t\t\t\t//window.ref = gun.user(env.config.pair.pub);\n\t\t\t\twindow.ref = gun.get('~'+env.config.pair.pub);\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Carl Create Chats\", function(){\n\t\treturn carl.run(function(test){\n\t\t\tconsole.log(\"I AM CARL\");\n\t\t\t$('body').append(\"<div>CPU turns stacked: <u></u> <button onclick='this.innerText = Math.random();'>Can you click me?</button><input id='msg' style='width:100%;'><b></b></div>\");\n\t\t\ttest.async();\n\t\t\tvar env = test.props;\n\t\t\tvar dam = gun.back('opt.mesh');\n\t\t\tdam.old = dam.say;\n\t\t\tdam.say = function(){};\n\t\t\tvar rand = String.random || Gun.text.random;\n\t\t\tvar i = test.props.each, chat = {}, S = Gun.state();\n\t\t\tvar tmp = \"generating \" + i + \" records...\"; console.log(tmp); $('b').text(tmp);\n\t\t\tvar big = rand(test.props.size || 1); //1000 * 10);\n\t\t\tfunction gen(){\n\t\t\t\tvar j = 99;\n\t\t\t\t$('b').text(i + ' left to generate...');\n\t\t\t\tvar data = rand(100);\n\t\t\t\twhile(--j && i){ --i;\n\t\t\t\t\tref.get(i).put(rand(100) + data + big, function(ack){ console.log('err?', ack) });\n\t\t\t\t\t//Gun.state.ify(chat, i/*+'-'+rand(9)*/, S, rand(100) + data + big, '~'+test.config.pair.pub);\n\t\t\t\t}\n\t\t\t\tif(i === 0){\n\t\t\t\t\tref.get('1').once(function(x){\n\t\t\t\t\t\t//gun._.graph.chat = chat;\n\t\t\t\t\t\tdam.say = dam.old;\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t//console.log(\"Done!\", x);\n\t\t\t\t\t\t$('b').text('');\n\t\t\t\t\t})\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetTimeout.turn(gen);\n\t\t\t}\n\t\t\tgun.on('auth', function(ack){ setTimeout(gen,9) });\n\t\t\twindow.ref = gun.user().auth(env.pair);\n\t\t\t//window.chat = chat;\n\t\t\t//console.log(JSON.stringify(chat,null,2));\n\t\t\tsetInterval(function(){ $('u').text(setTimeout.turn.s.length) },1000);\n\t\t}, config);\n\t});\n\n\tit(\"Alice Asks for Chat\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tvar i = 0, t = test.props.each, tmp;\n\t\t\t$('body').append(\"<div><i></i> / \"+t+\", seconds to first reply: <span></span>, CPU turns stacked: <u></u> <button onclick='this.innerText = Math.random();'>Can you click me?</button><input id='msg' style='width:100%;'><b></b></div>\");\n\t\t\tvar $msg = $('#msg'), $i = $('i');\n\t\t\tvar V, I, S = +new Date, SS = S, tmp;\n\t\t\tref.map().once(function(v,k){\n\t\t\t\tS && console.log('first:', $('span').text(tmp = (+new Date - S)/1000) && tmp) || (S = null);\n\t\t\t\tif(!v){ no_data }\n\t\t\t\tV = v; \n\t\t\t\tI = ++i;\n\t\t\t\t//console.log(i, \"chat:\",k,v);\n\t\t\t\tif(i === t){\n\t\t\t\t\tconsole.log(tmp = \"seconds from start to end: \" + (tmp = ((+new Date - SS)/1000)) + \", roughly \" + (t/tmp).toFixed(2) + \"ops/sec.\");\n\t\t\t\t\t$('b').text(tmp);\n\t\t\t\t\tsetTimeout(function(){ test.done() },100);\n\t\t\t\t}\n\t\t\t});\n\t\t\twindow.requestAnimationFrame = window.requestAnimationFrame || setTimeout;\n\t\t\twindow.requestAnimationFrame(function frame(){\n\t\t\t\twindow.requestAnimationFrame(frame, 16);\n\t\t\t\t$msg.val(V);\n\t\t\t\t$i.text(I);\n\t\t\t}, 16);\n\t\t\tsetInterval(function(){ $('u').text(setTimeout.turn.s.length) },1000);\n\t\t}, config);\n\t});\n\t\n\tafter(\"Everything shut down.\", function(){\n\t\t// which is to shut down all the browsers.\n\t\trequire('./util/open').cleanup() || browsers.run(function(){\n\t\t\tsetTimeout(function(){\n\t\t\t\tlocation.reload();\n\t\t\t}, 15 * 1000);\n\t\t});\n\t\t// And shut down all the servers.\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n})"
  },
  {
    "path": "test/panic/chat.js",
    "content": "/*\nAssume we have 3 peers in a star topology,\n\n..B..\n./.\\.\nA...C\n\nAnd they share a chat room with 10K messages.\n\nA -> GET chat -> B (cache miss) -> C\nC hosts the data and streams it back\nC -> PUT chat -> B (relay) -> A got.\n\nUsing the WebRTC module, C <-> A directly, no need for a relay!\nBut we're wanting to test the performance of the whole network.\n*/\n\n// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 1,\n\tbrowsers: 2, //3,\n\teach: 100000,\n\tsize: 1,\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){ // Static server\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port); // Start panic server.\n\n// In order to tell the clients what to do,\n// We need a way to reference all of them.\nvar clients = panic.clients;\n\n// Some of the clients may be NodeJS relays on different machines.\n// PANIC manager is a nifty tool that lets us remotely spawn them.\nvar manager = require('panic-manager')();\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){ // Create a bunch of relays.\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1) // They'll need unique ports to start on, if we run the test on 1 machine.\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port // Auto-connect to our panic server.\n});\n\n// Now lets divide our clients into \"relays\" and \"browsers\".\nvar relays = clients.filter('Node.js');\nvar browsers = clients.excluding(relays);\nvar alice = browsers.pluck(1);\nvar carl = browsers.excluding(alice).pluck(1);\n\ndescribe(\"Load test \"+ config.browsers +\" browser(s) across \"+ config.relays +\" server(s)!\", function(){\n\n\t// We'll have to manually launch the browsers,\n\t// So lets up the timeout so we have time to do that.\n\tthis.timeout(50 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\t// Alright, lets wait until enough gun server peers are connected.\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, ['start', '--port', env.config.port + env.i, '--sled-storage=false']);\n\t\t\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t\t});\n\t\t\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t\t\t});\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.log(e);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data.json') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\t// Launch the server and start gun!\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\t// Attach the server to gun.\n\t\t\t\tvar gun = Gun({file: env.i+'data', web: server, localStorage: false, radisk: false});\n\t\t\t\tserver.listen(env.config.port + env.i, function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port); //console.log(\"PLEASE OPEN http://\"+ config.IP +\":\"+ config.port +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\t//var gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\tvar gun = Gun({localStorage: false, radisk: false, peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'});\n\t\t\t\twindow.gun = gun;\n\t\t\t\twindow.ref = gun.get('chat');\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Carl Create Chats\", function(){\n\t\treturn carl.run(function(test){\n\t\t\tconsole.log(\"I AM CARL\");\n\t\t\t$('body').append(\"<div>CPU turns stacked: <u></u> <button onclick='this.innerText = Math.random();'>Can you click me?</button><input id='msg' style='width:100%;'><b></b></div>\");\n\t\t\ttest.async();\n\t\t\tvar rand = String.random || Gun.text.random;\n\t\t\tvar i = test.props.each, chat = {}, S = Gun.state();\n\t\t\tvar tmp = \"generating \" + i + \" records...\"; console.log(tmp); $('b').text(tmp);\n\t\t\tvar big = rand(test.props.size || 1); //1000 * 10);\n\t\t\tfunction gen(){\n\t\t\t\tvar j = 99;\n\t\t\t\t$('b').text(i + ' left to generate...');\n\t\t\t\tvar data = rand(100);\n\t\t\t\twhile(--j && i){ --i;\n\t\t\t\t\tGun.state.ify(chat, i/*+'-'+rand(9)*/, S, rand(100) + data + big, 'chat');\n\t\t\t\t}\n\t\t\t\tif(i === 0){\n\t\t\t\t\tgun._.graph.chat = chat;\n\t\t\t\t\ttest.done();\n\t\t\t\t\t$('b').text('');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetTimeout.turn(gen);\n\t\t\t}\n\t\t\tgen();\n\t\t\t//window.chat = chat;\n\t\t\t//console.log(JSON.stringify(chat,null,2));\n\t\t\tsetInterval(function(){ $('u').text(setTimeout.turn.s.length) },1000);\n\t\t}, config);\n\t});\n\n\tit(\"Alice Asks for Chat\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tvar i = 0, t = test.props.each, tmp;\n\t\t\t$('body').append(\"<div><i></i> / \"+t+\", seconds to first reply: <span></span>, CPU turns stacked: <u></u> <button onclick='this.innerText = Math.random();'>Can you click me?</button><input id='msg' style='width:100%;'><b></b></div>\");\n\t\t\tvar $msg = $('#msg'), $i = $('i');\n\t\t\tvar V, I, S = +new Date, SS = S, tmp;\n\t\t\tref.map().once(function(v,k){\n\t\t\t\tS && console.log('first:', $('span').text(tmp = (+new Date - S)/1000) && tmp) || (S = null);\n\t\t\t\tif(!v){ no_data }\n\t\t\t\tV = v; \n\t\t\t\tI = ++i;\n\t\t\t\t//console.log(i, \"chat:\",k,v);\n\t\t\t\tif(i === t){\n\t\t\t\t\tconsole.log(tmp = \"seconds from start to end: \" + (tmp = ((+new Date - SS)/1000)) + \", roughly \" + (t/tmp).toFixed(2) + \"ops/sec.\");\n\t\t\t\t\t$('b').text(tmp);\n\t\t\t\t\tsetTimeout(function(){ test.done() },100);\n\t\t\t\t}\n\t\t\t});\n\t\t\twindow.requestAnimationFrame = window.requestAnimationFrame || setTimeout;\n\t\t\twindow.requestAnimationFrame(function frame(){\n\t\t\t\twindow.requestAnimationFrame(frame, 16);\n\t\t\t\t$msg.val(V);\n\t\t\t\t$i.text(I);\n\t\t\t}, 16);\n\t\t\tsetInterval(function(){ $('u').text(setTimeout.turn.s.length) },1000);\n\t\t}, config);\n\t});\n\t\n\tafter(\"Everything shut down.\", function(){\n\t\t// which is to shut down all the browsers.\n\t\trequire('./util/open').cleanup() || browsers.run(function(){\n\t\t\tsetTimeout(function(){\n\t\t\t\tlocation.reload();\n\t\t\t}, 15 * 1000);\n\t\t});\n\t\t// And shut down all the relays.\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n})"
  },
  {
    "path": "test/panic/curl-server.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 2,\n\tdir: __dirname\n}\n\nvar panic = require('panic-server');\npanic.server().listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar alice = servers.pluck(1);\nvar bob = servers.excluding(alice).pluck(1);\n\ndescribe(\"Server to server sync\", function(){\n\tthis.timeout(5000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"Start GUN Bob server.\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\t\t\t\t\n\t\t\tvar express = require('express');\n\t\t\tvar bodyParser = require('body-parser');\n\t\t\tvar Gun = require('gun');\n\n\t\t\tvar app = express();\n\n\t\t\tapp.use(Gun.serve)\n\t\t\tapp.use(bodyParser.json())\n\n\t\t\tapp.post('/foo', function(req, res) {\n\t\t\t    gun.get('bar').put(req.body)\n\t\t\t    res.sendStatus(200)\n\t\t\t});\n\n\t\t\tvar server = app.listen(8082, function(){ test.done() })\n\n\t\t\tvar gun = Gun({peers: 'http://localhost:8081/gun', web: server})\n\n\t\t\tgun.get('bar').on(function(data, key){\n\t\t\t    console.log('bob', data, key)\n\t\t\t})\n\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(\"Start GUN Alice server.\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\t\n\t\t\tvar express = require('express');\n\t\t\tvar bodyParser = require('body-parser');\n\t\t\tvar Gun = require('gun');\n\n\n\t\t\tvar app = express()\n\n\t\t\tapp.use(Gun.serve)\n\n\t\t\tvar server = app.listen(8081, function(){ test.done() })\n\n\t\t\tvar gun = Gun({peers: 'http://localhost:8082/gun', web: server})\n\n\t\t\tgun.get('bar').on(function(data, key){\n\t\t\t    console.log('alice', data, key)\n\t\t\t    global.DATA = data;\n\t\t\t})\n\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(\"Curl Bob!\", function(){\n\t\tvar reply = require('child_process').execSync(\"curl --request POST \"\n\t\t+\t\"--url http://localhost:8082/foo \"\n\t\t+\t\"--header 'content-type: application/json' \"\n\t\t+ \"--data '\"+JSON.stringify({bar: \"FOOBAR\"})+\"'\");\n\t\tconsole.log(\"REPLY:\", reply.toString());\n\t  if(reply.toString().indexOf(\"err\") >= 0){\n\t  \tconsole.log(reply.toString());\n\t\t\tthrow new Error(\"Server did not like the request!\");\n\t\t}\n\t\treturn;\n\t});\n\n\tit(\"Did Alice get it?\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\t\t\t\t\n\t\t\tsetTimeout(function(){\n\t\t\t\tconsole.log(\"does Alice have it?\", global.DATA);\n\t\t\t\tif(!global.DATA){\n\t\t\t\t\tconsole.log(\"no data!\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttest.done();\n\t\t\t}, 1000);\n\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/e2e/distributed.js",
    "content": "require('./holy/grail');\n\ndescribe('PANIC!', function(){\n\tthis.timeout(1000 * 100);\n\n\tvar Gun = require('../');\n\tvar gun = Gun();\n\n\tvar panic = require('panic-server');\n\n\tvar server = require('http').createServer(function(req, res){\n\t\tvar path = require('path');\n\t\tif (req.url === '/') {\n\t\t\treq.url = '/panic.html';\n\t\t}\n\t\tif(gun.wsp.server(req, res)){ \n\t\t\treturn; // filters gun requests!\n\t\t}\n\t\trequire('fs').createReadStream(path.join(__dirname, req.url))\n\t\t.on('error',function(){}).pipe(res); // stream\n\t});\n\n\tpanic.server(server);\n\tgun.wsp(server);\n\tserver.listen(8765);\n\n\tvar clients = panic.clients;\n\n\tvar wd = require('selenium-webdriver');\n\tvar ff1 = new wd.Builder()\n\t\t.forBrowser('firefox').build()\n\t\t.get('http://localhost:8765/panic.html');\n\tvar ff2 = new wd.Builder()\n\t\t.forBrowser('firefox').build()\n\t\t.get('http://localhost:8765/panic.html');\n\n\tfunction min(n, done, list){\n\t\tlist = list || clients;\n\t\tfunction ready() {\n\t\t\tif (list.length >= n) {\n\t\t\t\tdone();\n\t\t\t\tlist.removeListener('add', ready);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tif (!ready()) {\n\t\t\tlist.on('add', ready);\n\t\t}\n\t}\n\n\tfunction gunify(done, ctx){\n\t\tvar s = document.createElement('script');\n\t\ts.src = 'gun.js';\n\t\ts.onload = done;\n\t\ts.onerror = ctx.fail;\n\t\tdocument.body.appendChild(s);\n\t}\n\n\tdescribe('Should sync', function(){\n\n\t\tvar alice = clients.pluck(1);\n\t\tvar bob = clients.excluding(alice).pluck(1);\n\n\t\tbefore(function(done){\n\t\t\tmin(2, done, clients);\n\t\t});\n\n\t\tit('browsers', function(done){\n\n\t\t\talice.run(function(){\n\t\t\t\tvar sync = gun.get('sync');\n\t\t\t\tsync.put({hello: 'world'})\n\t\t\t}).then(function(){\n\t\t\t\treturn bob.run(function(done, ctx){\n\t\t\t\t\tvar sync = gun.get('sync');\n\t\t\t\t\tsync.on(function(val){\n\t\t\t\t\t\tif(val.hello === 'world'){\n\t\t\t\t\t\t\tdone();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.fail(\"Wrong data\");\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}).then(function(){\n\t\t\t\tdone();\n\t\t\t}).catch(function(e){\n\t\t\t\tdone(new Error(e.message));\n\t\t\t});\n\n\t\t});\n\t\t\n\t});\n\n});\n"
  },
  {
    "path": "test/panic/e2e/holy/grail.js",
    "content": "/*\n  This file should be one\n  folder deeper than every\n  other file. It requires\n  mocha to run.\n*/\nvar panic = require('panic-server');\nvar spawn = require('child_process').spawn;\nvar path = require('path');\nvar http = require('http');\nvar fs = require('fs');\nvar ports = require('./ports');\n\nvar wd = require('selenium-webdriver');\n\nfunction open(url) {\n\tvar driver = new wd.Builder()\n\t\t.forBrowser('firefox')\n\t\t.build();\n\n\tdriver.get(url);\n\n\treturn driver;\n}\n\nopen('http://localhost:' + ports.panic + '/index.html');\nopen('http://localhost:' + ports.panic + '/index.html');\n\nvar staticServer = new http.Server(function (req, res) {\n\tif (req.url === '/') {\n\t\treq.url = '/index.html';\n\t}\n\tvar file = path.join(__dirname, req.url);\n\ttry {\n\t\tvar page = fs.readFileSync(file, 'utf8');\n\t\tres.end(page);\n\t} catch (e) {\n\t\t// don't care\n\t}\n});\n\nvar server = panic.clients.filter('Node.js').pluck(1);\nvar browsers = panic.clients.excluding(server);\n\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\n\nvar serverPath = path.join(__dirname, 'gun-server.js');\n\n// start the server on :8765\nspawn('node', [serverPath]);\n\nfunction waitFor (num, list) {\n\treturn new Promise(function (res) {\n\n\t\tfunction ready() {\n\t\t\tif (list.length < num) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tres();\n\t\t\tlist.removeListener('add', ready);\n\n\t\t\treturn true;\n\t\t}\n\n\t\tif (!ready()) {\n\t\t\tlist.on('add', ready);\n\t\t}\n\n\t});\n}\n\nbefore(function () {\n\n\tthis.timeout(1500000);\n\n\t// start the panic server\n\tpanic.server(staticServer).listen(ports.panic);\n\n\treturn waitFor(2, browsers)\n\t\t.then(function () {\n\t\t\treturn waitFor(1, server);\n\t\t});\n});\n\nvar scope = {\n\tuniqueKey: Math.random().toString(16).slice(2),\n\tfile: path.join(process.cwd(), 'delete-me.json'),\n\t'@scope': true\n}\n\ndescribe('The holy grail', function () {\n\n\tit('should allow full recovery', function () {\n\t\tthis.timeout(1500000);\n\n\t\treturn browsers.run(function () {\n\t\t\tlocalStorage.clear();\n\t\t})\n\t\t.then(function () {\n\t\t\treturn browsers.run(function () {\n\t\t\t\twindow.ref = gun.get(uniqueKey).put({\n\t\t\t\t\ttext: 'ignore'\n\t\t\t\t});\n\t\t\t}, scope)\n\t\t})\n\t\t.then(function () {\n\t\t\treturn alice.run(function (done) {\n\t\t\t\t// alice saves some data\n\t\t\t\t//ref.path('text').put('Initial text', done); // TODO: USE THIS LINE INSTEAD!\n\t\t\t\tref.path('text').put('Initial text');\n\t\t\t\tsetTimeout(done, 50);\n\t\t\t});\n\t\t})\n\t\t.then(function () {\n\t\t\treturn bob.run(function (done) {\n\t\t\t\tvar ctx = this;\n\t\t\t\tref.path('text').on(function (data) {\n\t\t\t\t\tif (data === 'ignore') {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// bob sees alice's data\n\t\t\t\t\tif (data !== 'Initial text') {\n\t\t\t\t\t\tctx.fail('Wrong data showed up: ' + JSON.stringify(data));\n\t\t\t\t\t}\n\t\t\t\t\tdone();\n\t\t\t\t});\n\t\t\t});\n\t\t})\n\t\t.then(function () {\n\t\t\treturn server.run(function () {\n\t\t\t\tvar fs = require('fs');\n\n\t\t\t\t// destroy the data\n\t\t\t\tfs.unlinkSync(file);\n\n\t\t\t\t// crash the server\n\t\t\t\tprocess.exit(0);\n\t\t\t}, scope);\n\t\t})\n\t\t.then(function () {\n\t\t\treturn alice.run(function (done) {\n\t\t\t\tref.path('text').put('A conflicting update');\n\t\t\t\tsetTimeout(done, 50);\n\t\t\t});\n\t\t})\n\t\t.then(function () {\n\t\t\treturn bob.run(function () {\n\t\t\t\tref.path('text').put('B conflicting update');\n\t\t\t});\n\t\t})\n\t\t.then(function () {\n\t\t\tspawn('node', [serverPath]);\n\t\t\treturn waitFor(1, server);\n\t\t})\n\t\t.then(function () {\n\t\t\treturn browsers.run(function (done) {\n\t\t\t\tvar ctx = this;\n\t\t\t\tref.path('text').on(function (value) {\n\t\t\t\t\tif (value === 'B conflicting update') {\n\t\t\t\t\t\tdone();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n});\n\n\nafter(function () {\n\tif (server.length) {\n\t\treturn server.run(function () {\n\t\t\tprocess.exit(0);\n\t\t});\n\t}\n});"
  },
  {
    "path": "test/panic/e2e/holy/gun-server.js",
    "content": "var panic = require('panic-client');\nvar ports = require('./ports');\nvar Gun = require('gun');\nvar gun = new Gun({\n\tfile: 'delete-me.json'\n});\n\nvar http = require('http');\n\nvar server = new http.Server(gun.wsp.server);\n\ngun.wsp(server);\n\nserver.listen(ports.gun);\n\npanic.server('http://localhost:' + ports.panic);"
  },
  {
    "path": "test/panic/e2e/holy/index.html",
    "content": "\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>Holy grail demo</title>\n</head>\n<body>\n\t<script src='panic.js'></script>\n\t<script src='http://localhost:8765/gun.js'></script>\n\n\t<script>\n\t\t(function () {\n\t\t\tvar req = new XMLHttpRequest();\n\t\t\treq.overrideMimeType('application/json');\n\t\t\treq.open('GET', 'ports.json');\n\t\t\treq.addEventListener('load', function () {\n\t\t\t\tvar ports = JSON.parse(req.responseText);\n\t\t\t\tvar server = 'http://localhost:' + ports.gun + '/gun';\n\t\t\t\twindow.gun = new Gun(server);\n\t\t\t\tpanic.server('http://localhost:' + ports.panic);\n\t\t\t});\n\t\t\treq.send();\n\t\t}());\n\t</script>\n</body>\n</html>"
  },
  {
    "path": "test/panic/e2e/holy/ports.json",
    "content": "{\n\t\"panic\": 3000,\n\t\"gun\": 8765\n}"
  },
  {
    "path": "test/panic/e2e/package.json",
    "content": "{\n  \"name\": \"gun-tests-e2e\",\n  \"version\": \"0.0.0\",\n  \"description\": \"End to end tests for gun\",\n  \"private\": true,\n  \"main\": \"distributed.js\",\n  \"devDependencies\": {\n    \"panic-server\": \">1.1.0\",\n    \"selenium-webdriver\": \">3.3.0\"\n  }\n}\n"
  },
  {
    "path": "test/panic/holy-grail.js",
    "content": "// <-- PANIC template, copy & paste, tweak a few settings if needed...\nvar ip; try{ ip = require('ip').address() }catch(e){}\nvar config = {\n\tIP: ip || 'localhost',\n\tport: 8765,\n\trelays: 2,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar relays = clients.filter('Node.js');\nvar relay = relays.pluck(1);\nvar spawn = relays.excluding(relay).pluck(1);\nvar browsers = clients.excluding(relays);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\nvar again = {};\n\n// continue boiler plate, tweak a few defaults if needed, but give descriptive test names...\ndescribe(\"The Holy Grail Test!\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"relays have joined!\", function(){\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\treturn relay.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\tvar port = env.config.port + env.i;\n\t\t\ttest.async();\n\n\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\tconsole.log('testing with rod');\n\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, ['start', '--port', port, '--sled-storage=false']);\n\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t});\n\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t});\n\t\t\t\ttest.done();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')((env.i+1)+'data') }catch(e){}\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\tvar gun = Gun({file: env.i+'data', web: server});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config});\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\twindow.ENV = test.props;\n\t\t\t\tlocalStorage.clear();\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n// end PANIC template --> \n\n\tit(\"Write initial value\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\tvar env = window.ENV;\n\t\t\tvar gun = Gun({peers: ['http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'], file: 'alicedata'});\n\t\t\twindow.ref = gun.get('holy').get('grail');\n\t\t\tref.put(\"value\");\n\t\t\tsetTimeout(test.async(), 2000);\n\t\t});\n\t});\n\n\tit(\"Read initial value\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tconsole.log(\"I AM BOB\");\n\t\t\tvar env = window.ENV;\n\t\t\tvar gun = Gun({peers: ['http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'], file: 'bobdata'});\n\t\t\twindow.ref = gun.get('holy').get('grail');\n\t\t\ttest.async();\n\t\t\tref.on(function(data){\n\t\t\t\tif(\"value\" === data){\n\t\t\t\t\treturn test.done();\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t});\n\n\tit(\"Relay has crashed and been wiped!\", function(){\n\t\treturn relay.run(function(test){\n\t\t\tconsole.log(3);\n\t\t\tvar env = test.props;\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\tprocess.exit(0);\n\t\t}, {i: 1, config: config})\n\t});\n\n\tit(\"Wait...\", function(done){\n\t\tconsole.log(4);\n\t\tsetTimeout(done, 2000);\n\t});\n\n\tit(\"Alice conflicted.\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\tif(window.WebSocket){\n\t\t\t\tvar err;\n\t\t\t\ttry{ new WebSocket('http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun') }catch(e){ err = e }\n\t\t\t\tif(!err){\n\t\t\t\t\ttest.fail(\"Relay did not crash.\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tref.put(\"Alice\");\n\t\t\tsetTimeout(test.async(), 100);\n\t\t}, {config: config});\n\t});\n\n\tit(\"Bob conflicted.\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\tif(window.WebSocket){\n\t\t\t\tvar err;\n\t\t\t\ttry{ new WebSocket('http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun') }catch(e){ err = e }\n\t\t\t\tif(!err){\n\t\t\t\t\ttest.fail(\"Relay did not crash.\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tref.put(\"Bob\");\n\t\t\tsetTimeout(test.async(), 2000);\n\t\t}, {config: config});\n\t});\n\n\tit(\"Alice reloading.\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(localStorage);\n\t\t\tlocation.reload();\n\t\t});\n\t});\n\n\tit(\"Got Alice.\", function(){\n\t\tagain.alice = browsers.excluding(new panic.ClientList([alice, bob])).pluck(1);\n\t\treturn again.alice.atLeast(1);\n\t});\n\n\tit(\"Wait for Bob...\", function(done){\n\t\tsetTimeout(done, 1000);\n\t});\n\n\tit(\"Bob reloading.\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tlocation.reload();\n\t\t});\n\t});\n\n\tit(\"Got Bob.\", function(){\n\t\tagain.bob = browsers.excluding(new panic.ClientList([alice, bob, again.alice])).pluck(1);\n\t\treturn again.bob.atLeast(1);\n\t});\n\n\tit(\"GUN spawned!\", function(){\n\t\treturn spawn.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\tvar port = env.config.port + env.i;\n\t\t\ttest.async();\n\n\t\t\tif (process.env.ROD_PATH) {\n\t\t\t\tconsole.log('testing with rod');\n\t\t\t\tconst sp = require('child_process').spawn(process.env.ROD_PATH, ['start', '--port', port, '--sled-storage=false']);\n\t\t\t\tsp.stdout.on('data', function(data){\n\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t});\n\t\t\t\tsp.stderr.on('data', function(data){\n\t\t\t\t\tconsole.log(data.toString());\n\t\t\t\t});\n\t\t\t\ttest.done();\n\t\t\t\treturn;\n\t\t\t}\n\n\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun = require('gun');\n\t\t\tvar gun = Gun({file: env.i+'data', web: server});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 2, config: config}); \n\t});\n\n\tit(\"Browsers ready!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tnew panic.ClientList([again.alice, again.bob]).each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\twindow.ENV = test.props;\n\t\t\t\t// NOTE: WE DO NOT CLEAR localStorage!\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Alice re-initialized gun!\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\tvar env = window.ENV;\n\t\t\tvar gun = Gun({peers: ['http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun'], file: 'alicedata'});\n\t\t\twindow.ref = gun.get('holy').get('grail');\n\t\t});\n\t});\n\n\tit(\"Bob re-initialized gun!\", function(){\n\t\treturn again.bob.run(function(test){\n\t\t\tvar env = window.ENV;\n\t\t\tvar gun = Gun({peers: ['http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun'], file: 'bobdata'});\n\t\t\twindow.ref = gun.get('holy').get('grail');\n\t\t});\n\t});\n\n\tit(\"Alice conflict.\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tref.on(function(data){\n\t\t\t\tconsole.log(\"======\", data);\n\t\t\t\twindow.stay = data;\n\t\t\t\tif(\"Bob\" == data){\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tif(window.ALICE){ return }\n\t\t\t\t\t\twindow.ALICE = true;\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t}, 1000);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Bob converged.\", function(){\n\t\treturn again.bob.run(function(test){\n\t\t\ttest.async();\n\t\t\tref.on(function(data){\n\t\t\t\tconsole.log(\"======\", data);\n\t\t\t\twindow.stay = data;\n\t\t\t\tif(\"Bob\" != data){\n\t\t\t\t\ttest.fail(\"wrong local value!\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tif(window.BOB){ return }\n\t\t\t\t\twindow.BOB = true;\n\t\t\t\t\ttest.done();\n\t\t\t\t}, 1000);\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Alice converged.\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\t//console.log(stay);return;\n\t\t\tif(\"Bob\" != stay){\n\t\t\t\ttest.fail(\"wrong local value!\");\n\t\t\t}\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});\n\n"
  },
  {
    "path": "test/panic/index.html",
    "content": "<script src='panic.js'></script>\n<script>panic.server(location.origin)</script>\n<script src='gun.js'></script>\n<script src='jquery.js'></script>\n<h1>Running Tests.</h1>\n<div id=\"log\"></div>\n<!-- <textarea id=\"print\" style=\"width: 100%; height: 90%; border: 0;\"></textarea> -->"
  },
  {
    "path": "test/panic/infinite-scroll/index.html",
    "content": "<html>\n  <head>\n    <title>Infinite scroll example</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"./style.css\">\n    <script src=\"/jquery.js\"></script>\n    <script src=\"/gun.js\"></script>\n    <script src=\"./ScrollWindow.js\"></script>\n    <script src='panic.js'></script>\n    <script>panic.server(location.origin)</script>\n  </head>\n\n  <body>\n    <header>\n      <form id=\"generate\">\n        <input type=\"text\" id=\"number\" placeholder=\"Number of posts\"/>\n        <button>Generate</button>\n      </form>\n      <div id=\"top-buttons\">\n        <button id=\"top\">Top</button>\n      </div>\n    </header>\n\n    <div id=\"container\" style=\"padding-top: 0px; padding-bottom: 0px\"></div>\n\n    <button id=\"bottom\">Bottom</button>\n\n    <script src=\"./index.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "test/panic/infinite-scroll/index.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 1,\n\teach: 1500,\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/ScrollWindow.js': __dirname + '/../../../examples/infinite-scroll/ScrollWindow.js',\n\t\t'/index.js': __dirname + '/../../../examples/infinite-scroll/index.js',\n\t\t'/style.css': __dirname + '/../../../examples/infinite-scroll/style.css',\n\t\t'/gun.js': __dirname + '/../../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../../examples/jquery.js'\n\t}\n}\n\n/*\n\tWelcome, person!\n\tYou have found the test that causes gun to PANIC with load!\n\tAbove are options to configure, the only ones useful are:\n\t - browsers // number of browsers you want to load test across.\n\t - each // the number of messages each browser should sync.\n\tThis test is less than 200 lines of code (without comments)!\n\tHowever, if you aren't familiar with PANIC - you are in for a surprise!\n\tI'm Plublious, and I shall be your guide!\n*/\n\n// First we need to create a PANIC server.\n// Each device/browser in the distributed system we are testing connects to it.\n// It then coordinates these clients to cause chaos in the distributed system.\n// Cool huh?\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){ // Static server\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port); // Start panic server.\n\n// In order to tell the clients what to do,\n// We need a way to reference all of them.\nvar clients = panic.clients;\n\n// Some of the clients may be NodeJS servers on different machines.\n// PANIC manager is a nifty tool that lets us remotely spawn them.\nvar manager = require('panic-manager')();\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){ // Create a bunch of servers.\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1) // They'll need unique ports to start their servers on, if we run the test on 1 machine.\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port // Auto-connect to our panic server.\n});\n\n// Now lets divide our clients into \"servers\" and \"browsers\".\nvar servers = clients.filter('Node.js');\nvar browsers = clients.excluding(servers);\n\n// Sweet! Now we can start the tests.\n// PANIC works with Mocha and other testing libraries!\n// So it is easy to use PANIC.\n\ndescribe(\"Load test \"+ config.browsers +\" browser(s) across \"+ config.servers +\" server(s)!\", function(){\n\n\t// We'll have to manually launch the browsers,\n\t// So lets up the timeout so we have time to do that.\n\tthis.timeout(5 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\t// Alright, lets wait until enough gun server peers are connected.\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data.json') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\t// Launch the server and start gun!\n\t\t\t\tvar Gun = require('gun');\n\t\t\t\t// Attach the server to gun.\n\t\t\t\tvar gun = Gun({file: env.i+'data', web: server, localStorage: false});\n\t\t\t\tserver.listen(env.config.port + env.i, function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config}));\n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\t// Okay! Cool. Now we can move on to the next step...\n\t\tconsole.log(\"PLEASE OPEN http://\"+ config.IP +\":\"+ config.port +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\t// Which is to manually open up a bunch of browser tabs\n\t\t// and connect to the PANIC server in the same way\n\t\t// the NodeJS servers did.\n\n\t\t// However! We're gonna cheat...\n\t\tbrowsers.atLeast(1).then(function(){\n\t\t\t// When there is at least one browser opened, tell it to run this code:\n\t\t\tbrowsers.run(function(test){\n\t\t\t\t// NOTE: This closure is now being run IN THE BROWSER.\n\t\t\t\t// This code is not server side code, despite the fact\n\t\t\t\t// that we've written it on the server. It is not.\n\t\t\t\t// Mind blowing, right?\n\t\t\t\tvar env = test.props;\n\t\t\t}, {config: config});\n\t\t});\n\t\t// Cool! Once that is done...\n\t\t// WAIT until all those browser tabs\n\t\t// have connected to the PANIC server\n\t\t// THEN move onto the next step\n\t\t// where we will cause chaos!\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Data was saved and synced across all browsers!\", function(){\n\t\t// This is where it gets good!\n\t\tvar tests = [], ids = {}, i = 0;\n\t\t// Let us create a list of all the browsers IDs connected.\n\t\t// This will later let each browser check against every other browser.\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\t// for every browser, run the following code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t//var audio = new Audio('https://www.nasa.gov/mp3/640170main_Roger%20Roll.mp3');audio.addEventListener('ended', function() {this.currentTime = 0;this.play();}, false);audio.play(); // testing if audio prevents Chrome throttle?\n\t\t\t\tlocalStorage.clear(); // Clean up anything from before.\n\t\t\t\tvar env = test.props;\n\t\t\t\t// Get access to the \"outer scope\" which has the browser IDs\n\t\t\t\t// as well as other configuration information.\n\t\t\t\ttest.async();\n\t\t\t\t// Now we want to connect to every gun server peer...\n\t\t\t\tvar peers = [], i = env.config.servers;\n\t\t\t\twhile(i--){\n\t\t\t\t\t// For the total number of servers listed in the configuration\n\t\t\t\t\t// Add their URL into an array.\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + (env.config.port + (i + 1)) + '/gun');\n\t\t\t\t}\n\t\t\t\t// Pass all the servers we want to connect to into gun.\n\t\t\t\t//var gun = Gun();\n\t\t\t\tvar gun = Gun(peers);\n\t\t\t\t// Now we want to create a list\n\t\t\t\t// of all the messages that WILL be sent\n\t\t\t\t// according to the expected configuration.\n\t\t\t\t// This is equal to...\n\t\t\t\tvar num = 0, total = env.config.each, check = {};\n\t\t\t\tvar report = $(\"<div>\").css({position: 'fixed', top: 0, right: 0, background: 'white', padding: 10}).text(num +\" / \"+ total +\" Verified\").prependTo('body');\n\t\t\t\t// Add a nifty UI that tells us how many messages have been verified.\n\t\t\t\t// FINALLY, tell gun to subscribe to every record\n\t\t\t\t// that is is/will be saved to this table.\n\n\t\t\t\tvar countAndScroll = () => {\n\t\t\t\t\t$('.post b').each(function() {\n\t\t\t\t\t\tvar t = $(this).text();\n\t\t\t\t\t\tif (check[t]) return;\n\t\t\t\t\t\tnum += 1;\n\t\t\t\t\t\treport.text(num +\" / \"+ total +\" Verified\");\n\t\t\t\t\t\tif (num === total) {\n\t\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcheck[t] = true;\n\t\t\t\t\t});\n\t\t\t\t\t$(window).scrollTop($(window).height());\n\t\t\t\t}\n\t\t\t\twindow.onRender = elements => {\n\t\t\t\t\tcountAndScroll();\n\t\t\t\t};\n\n\t\t\t\t$('#number').val(env.config.each);\n\t\t\t\t$('#generate button').click();\n\t\t\t\tcountAndScroll();\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));\n\t\t});\n\t\t// YAY! We're finally done.\n\t\t// IF AND ONLY IF\n\t\t// EVERY SINGLE BROWSER\n\t\t// HAS VERIFIED\n\t\t// EVERY OTHER BROWSERS' data.\n\t\t// If they are ALL done, go to the next step.\n\t\treturn Promise.all(tests);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\t// which is to shut down all the browsers.\n\t\tbrowsers.run(function(){\n\t\t\tsetTimeout(function(){\n\t\t\t\tlocation.reload();\n\t\t\t}, 15 * 1000);\n\t\t});\n\t\t// And shut down all the servers.\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n})\n// THE END!\n// Congrats, wasn't that epic?\n// Or still confused how a single 200 LOC test file\n// Is running correctness verification tests\n// across an entire distributed system of devices/browsers?\n// Well, jump on https://gitter.im/amark/gun !\n\n// Think adding tests like this to your work place would be bomb awesome?\n// We totally sell PANIC training, licenses, and support!\n// Please reach out to hi@gunDB.io if you are interested\n// in purchasing consulting or services for PANIC.\n"
  },
  {
    "path": "test/panic/large-nodes.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar bob = servers.pluck(1);\n//var carl = servers.excluding(bob).pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar dave = browsers.excluding(alice).pluck(1);\n\ndescribe(\"Put ACK\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun = require('gun');\n\t\t\t\tvar peers = [], i = env.config.servers;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server, chunk: 1024 * 10});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\tconsole.log(\"PLEASE OPEN http://\"+ config.IP +\":\"+ config.port +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.ref = gun.get('a');\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Put\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tvar i = test.props.each || 25000;\n\t\t\tvar put = {};\n\t\t\twhile(--i){\n\t\t\t\tput[Gun.text.random(9)] = i;\n\t\t\t}\n\t\t\tvar S = +new Date;\n\t\t\tref.put(put, function(ack){\n\t\t\t\tconsole.log(\"acks:\", +new Date - S, ack);\n\t\t\t\ttest.done();\n\t\t\t});\n\n\t\t}, {acks: config.servers});\n\t});\n\treturn;\n\n\tit(\"Get\", function(){\n\t\t/*\n\t\t\tHere is the recursive rule for GET, keep replying while hashes mismatch.\n\t\t\t1. Receive a GET message.\n\t\t\t2. If it has a hash, and if you have a thing matching the GET, then see if the hashes are the same, if they are then don't ACK, don't relay, end.\n\t\t\t3. If you would have the thing but do not, then ACK that YOU have nothing.\n\t\t\t4. If you have a thing matching the GET or an ACK for the GET's message, add the hash to the GET message, and ACK with the thing or ideally the remaining difference.\n\t\t\t5. Pick ?3? OTHER peers preferably by priority that they have got the thing, send them the GET, plus all \"up\" peers.\n\t\t\t6. If no ACKs you are done, end.\n\t\t\t7. If you get ACKs back to the GET with things and different hashes, optionally merge into the thing you have GOT and update the hash.\n\t\t\t8. Go to 4.\n\t\t*/\n\t\treturn dave.run(function(test){\n\t\t\tconsole.log(\"I AM DAVE\");\n\t\t\ttest.async();\n\t\t\tvar c = 0, to;\n\t\t\tref.hear = ref.hear || [];\n\t\t\tvar hear = ref._.root.opt.mesh.hear;\n\t\t\tref._.root.opt.mesh.hear = function(raw, peer){\n\t\t\t\tvar msg = Gun.obj.ify(raw);\n\t\t\t\tconsole.log('hear:', msg);\n\t\t\t\thear(raw, peer);\n\t\t\t\tref.hear.push(msg);\n\n\t\t\t\tif(msg.put){ ++c }\n\t\t\t}\n\t\t\tref.get(function(ack){\n\t\t\t\tif(!ack.put || ack.put.hello !== 'world'){ return }\n\t\t\t\tif(c > 1){ too_many_acks }\n\n\t\t\t\tclearTimeout(to);\n\t\t\t\tto = setTimeout(test.done, 1000);\n\t\t\t});\n\t\t}, {acks: config.servers});\n\t});\n\n\tit(\"DAM\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tif(ref.say){ said_too_much }\n\t\t\tif(ref.hear.length > 1){ heard_to_much }\n\t\t\ttest.done()\n\t\t}, {acks: config.servers});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\tbrowsers.run(function(){\n\t\t\t//location.reload();\n\t\t\t//setTimeout(function(){\n\t\t\t//}, 15 * 1000);\n\t\t});\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/latency.js",
    "content": "// this has Alice read data, measuring its latency, while other browsers are flooding relay with updates.\nvar config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\teach: 10000,\n\tburst: 10,\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/sea.js': __dirname + '/../../sea.js',\n\t\t'/yson.js': __dirname + '/../../lib/yson.js'\n\t},\n\tdir: __dirname\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){ // Static server\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port); // Start panic server.\n\n// In order to tell the clients what to do,\n// We need a way to reference all of them.\nvar clients = panic.clients;\n\n// Some of the clients may be NodeJS servers on different machines.\n// PANIC manager is a nifty tool that lets us remotely spawn them.\nvar manager = require('panic-manager')();\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){ // Create a bunch of servers.\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1) // They'll need unique ports to start their servers on, if we run the test on 1 machine.\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port // Auto-connect to our panic server.\n});\n\n// Now lets divide our clients into \"servers\" and \"browsers\".\nvar servers = clients.filter('Node.js');\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar others = browsers.excluding(alice);\n\ndescribe(\"Test vanishing property \"+ config.browsers +\" browser(s) across \"+ config.servers +\" server(s)!\", function(){\n\n\t// We'll have to manually launch the browsers,\n\t// So lets up the timeout so we have time to do that.\n\tthis.timeout(5 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\t// Alright, lets wait until enough gun server peers are connected.\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data.json') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\t// Launch the server and start gun!\n\t\t\t\tvar Gun = require(env.config.dir+'/../../');\n\t\t\t\t// Attach the server to gun.\n\t\t\t\t//var gun = Gun({file: env.i+'data', web: server});\n\t\t\t\tvar gun = Gun({file: env.i+'data', web: server, rad: false, localStorage: false});\n\t\t\t\tserver.listen(env.config.port + env.i, function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t\t//setInterval(function(){ console.log(\"CPU turns stacked:\", setTimeout.turn.s.length) },1000);\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\tconsole.log(\"PLEASE OPEN http://\"+ config.IP +\":\"+ config.port +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun({retry: 2, peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'});\n\t\t\t\twindow.gun = gun;\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Start flooding\", function(){\n\t\tvar tests = [], i = 0;\n\t\tothers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tconsole.log(\"I SHALL FLOOD\");\n\t\t\t\ttest.async();\n\t\t\t\tvar config = test.props.config;\n\n\t\t\t\tgun.get('test').get('latency').put(\"hello world\");\n\t\t\t\t\n\t\t\t\tvar go = setInterval(function(){\n\t\t\t\t\tvar burst = config.burst;\n\t\t\t\t\twhile(--burst){\n\t\t\t\t\t\tconsole.log(burst);\n\t\t\t\t\t\tgun.get(String.random(Math.random()*100)).get(String.random(Math.random()*10)).put(String.random(Math.random()*1000))\n\t\t\t\t\t}\n\t\t\t\t},config.wait);\n\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t\tsetTimeout(function(){ clearInterval(go) }, 2000);\n\t\t\t\t}, 1000 * 10);\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Alice reads during flood\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\", gun.back('opt.pid'));\n\t\t\t$('body').css('background', 'red');\n\t\t\ttest.async();\n\t\t\tvar S = +new Date;\n\t\t\tgun.get('test').get('latency').on(function(data){\n\t\t\t\tvar latency = +new Date - S;\n\t\t\t\tconsole.log(latency, data);\n\t\t\t\tif(!data){ return }\n\t\t\t\t//test.done();\n\t\t\t});\n\t\t}, config);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\t// which is to shut down all the browsers.\n\t\tbrowsers.run(function(){\n\t\t\tsetTimeout(function(){\n\t\t\t\treturn;\n\t\t\t\tlocation.reload();\n\t\t\t}, 15 * 1000);\n\t\t});\n\t\t// And shut down all the servers.\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n})"
  },
  {
    "path": "test/panic/level.js",
    "content": "const panic   = require('panic-server');\nconst clients = panic.clients;\nconst manager = require('panic-manager')();\nconst opts    = { radisk: false, localStorage: false, file: false };\n\nrequire('events').EventEmitter.defaultMaxListeners = Infinity;\n\nconst config = {\n  ip      : require('ip').address(),\n  port    : 8765,\n  servers : 3,\n  route   : {\n    '/'          : __dirname + '/index.html',\n    '/gun.js'    : __dirname + '/../../gun.js',\n    '/jquery.js' : __dirname + '/../../examples/jquery.js'\n  }\n};\n\nconst srv = panic.server();\nsrv.on('request', (req, res) => {\n  config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nmanager.start({\n  clients: Array(config.servers).fill().map((u,i) => ({\n    type: 'node',\n    port: config.port + i + 1,\n  })),\n  panic: `http://${config.ip}:${config.port}`\n});\n\nconst servers = clients.filter('Node.js');\nconst server  = servers.pluck(1);\nconst alice   = servers.excluding(server).pluck(1);\nconst bob     = servers.excluding(server).excluding(alice).pluck(1);\n\ndescribe('Make sure the leveldb storage engine works', function() {\n  this.timeout(5 * 60 * 60 * 1000);\n\n  it(\"servers have joined!\", function() {\n    return servers.atLeast(config.servers);\n  });\n\n  it(\"GUN started!\", function() {\n    return server.run(function(test) {\n      test.async();\n      const {config,opts} = test.props;\n\n      const leveldown = require('leveldown');\n      const encode    = require('encoding-down');\n      const levelup   = require('levelup');\n\n      if (require('fs').existsSync('./lvldata')) {\n        console.error('Please delete previous data first!');\n        return;\n      }\n\n      // Initialize leveldb\n      // const level = global.level = levelup(leveldown('./lvldata'));\n      const level = global.level = levelup(encode(leveldown('./lvldata'), { valueEncoding: 'json' }));\n\n      // Load the libraries under test\n      const Gun   = require('../../../index');\n      const debug = require('../../../lib/level');\n\n      // // Add debug message\n      // debug.on('create', () => console.log('LEVEL CREATE'));\n      // debug.on('get'   , key => console.log('LEVEL GET', key));\n      // debug.on('put'   , (key, value) => console.log('LEVEL PUT', key, value));\n      // // debug.on('list', () => console.log('LEVEL LIST'));\n      // debug.on('error' , err => console.log('LEVEL ERROR', err));\n\n      // Track state (so we can wait on put, it's called late by radisk)\n      global.state = 0;\n      debug.on('put', () => global.state++);\n\n      // Create server\n      opts.web = require('http').createServer(function(req, res) {\n        res.end(\"Number five is alive!\");\n      });\n\n      // Initialize gun & start server\n      const gun = global.gun = Gun({ ...opts, level });\n      opts.web.listen(config.port + 1, function() {\n        test.done();\n      });\n\n    }, {config,opts});\n  });\n\n  it(\"Alice saves data\", function() {\n    return alice.run(function(test) {\n      test.async();\n      const {config,opts} = test.props;\n      const Gun           = require('../../../index');\n\n      // Start gun\n      const gun = global.gun = Gun({\n        ...opts,\n        peers: 'http://'+ config.ip + ':' + (config.port + 1) + '/gun',\n        lack : 1000 * 60 * 60,\n      });\n\n      // Save data\n      // Timeout allows callbacks to fire before server read\n      const ref = gun.get('asdf');\n      ref.put({ hello: 'world' });\n      setTimeout(() => {\n        test.done();\n      }, 1);\n    }, {config,opts});\n  });\n\n  it('Server read data', function() {\n    return server.run(function(test) {\n      test.async();\n\n      // Read data (triggers fetch from alice + write to disk)\n      const ref = gun.get('asdf');\n      ref.on(data => {\n        if (data.hello !== 'world') {\n          return test.fail('Invalid data returned');\n        }\n        ref.off();\n        test.done();\n      });\n\n    });\n  });\n\n  it('Wait for server to store', function() {\n    return server.run(function(test) {\n      test.async();\n      setTimeout(function awaitState() {\n        if (global.state < 2) return setTimeout(awaitState, 50);\n        test.done();\n      }, 50);\n    });\n  });\n\n  it('Close all original running nodes', function() {\n    clients.pluck(2).run(function() {\n      if (global.level) {\n        global.level.close(function() {\n          process.exit();\n        });\n      } else {\n        process.exit();\n      }\n    });\n  });\n\n  it('Start bob', function() {\n    return bob.run(function(test) {\n      test.async();\n      const {config,opts} = test.props;\n\n      const leveldown = require('leveldown');\n      const encode    = require('encoding-down');\n      const levelup   = require('levelup');\n\n      // Initialize gun opts\n      const level = global.level = levelup(encode(leveldown('./lvldata'), { valueEncoding: 'json' }));\n\n      // Load the libraries under test\n      const Gun   = require('../../../index');\n      const debug = require('../../../lib/level');\n\n      // // Add debug messages\n      // debug.on('get', key => console.log('LEVEL GET', key));\n      // debug.on('put', (key, value) => console.log('LEVEL PUT', key, value));\n      // // debug.on('list', () => console.log('LEVEL LIST'));\n      // debug.on('error', err => console.log('LEVEL ERROR', err));\n\n      // Create server\n      opts.web = require('http').createServer((req, res) => {\n        res.end(\"Number five is alive!\");\n      });\n\n      // Initialize gun & start server\n      const gun = global.gun = Gun({ ...opts, level });\n      opts.web.listen(config.port + 1, () => {\n        test.done();\n      });\n    }, {config,opts});\n  });\n\n  it('Bob read', function() {\n    return bob.run(function(test) {\n      test.async();\n\n      // Read data\n      const ref = gun.get('asdf');\n      ref.on(data => {\n        if (data.hello !== 'world') {\n          return test.fail('Invalid data returned');\n        }\n        ref.off();\n        test.done();\n      });\n\n    });\n  });\n\n  it('Shutdown bob', function() {\n    return clients.run(function() {\n      process.exit()\n    });\n  });\n\n  it(\"All finished!\", function(done) {\n    srv.close();\n    done();\n  });\n\n});\n"
  },
  {
    "path": "test/panic/lexical.js",
    "content": "/**\n * RAD Lexical search test\n * \n * What we want here: (1) Superpeer and (n) peers\n *  - The Superpeer have a graph with `key(timestamp)->value(value)`\n *  - The peer will run an amount of queries and the total of results are the 'expected results'.\n *\n * Tip: to run this `mocha test/panic/lexical`\n * \n */\nvar config = {\n  IP: require('ip').address(),\n  port: process.env.PORT ? parseInt(process.env.PORT) : 8765,\n  servers: 1,\n  browsers: 1,\n  route: {\n    '/': __dirname + '/index.html',\n    '/gun.js': __dirname + '/../../gun.js',\n    '/gun/lib/radix.js': __dirname + '/../../lib/radix.js',\n    '/gun/lib/radisk.js': __dirname + '/../../lib/radisk.js',\n    '/gun/lib/store.js': __dirname + '/../../lib/store.js',\n    '/gun/lib/rindexed.js': __dirname + '/../../lib/rindexed.js',\n    '/jquery.js': __dirname + '/../../examples/jquery.js'\n  },\n  wait_map: 700\n}\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res) {\n  config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\nmanager.start({\n  clients: Array(config.servers).fill().map(function(u, i) {\n    return {\n      type: 'node',\n      port: config.port + (i + 1)\n    }\n  }),\n  panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = global.server = servers.pluck(1);\nvar server2 = servers.excluding(server).pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\nvar john = browsers.excluding(alice).excluding(bob).pluck(1);\n\ndescribe('RAD Lexical search Test!           ', function() {\n  this.timeout(5 * 60 * 1000);\n  // \tthis.timeout(10 * 60 * 1000);\n  it('Servers have joined!                   ', function() {\n    return servers.atLeast(config.servers);\n  });\n  it('GUN server started!                    ', function() {\n    return server.run(function(test) {\n      var env = test.props;\n      test.async();\n      try { require('fs').unlinkSync('radata_test_lexical_' + env.i) } catch (e) {}\n      try { require('fs').unlinkSync('radata_test_lexical_' + (env.i + 1)) } catch (e) {}\n      var port = env.config.port + env.i;\n      var server = require('http').createServer(function(req, res) { res.end(\"I am \" + env.i + \"!\"); });\n      var Gun = global.Gun = require('gun');\n      var gun = global.gun = Gun({\n        axe: false,\n        multicast: false,\n        web: server,\n        file: 'radata_test_lexical_' + env.i,\n        //radisk:false, localStorage:false\n      });\n      server.listen(port, function() {\n        test.done();\n      });\n    }, {\n      i: 1,\n      config: config\n    });\n  });\n  it('Create graph with all days of year 2020', function() {\n    return server.run(function(test) {\n      test.async();\n      var j = 0;\n      graph = gun._.graph, timenode = {}, start = new Date('2020-01-01T00:00:00Z'), end = new Date('2020-12-31T23:59:59Z'), startt = start.getTime(), endt = end.getTime(), p = startt;\n      var ref = global.ref = gun.get('timenode');\n      while (p <= endt) { //console.log('.... >>> ', p, ++j, new Date(p).toISOString());\n        var t = new Date(p);\n        var ts = t.toISOString();\n        var soul = 'timeline_' + ts;\n        var d = { msg: ' datetime ' + ts };\n        var n = gun.get(soul).put(d);\n        ref.get(ts).put(n);\n\n        p = p + (24 * 60 * 60 * 1000); //24h\n      }\n      setTimeout(function() { /// wait a while for the .put\n        test.done();\n      }, 1000);\n    });\n  });\n  it('Query server - Between(< item <)      ', function() {\n    var i=0;\n    return server.run(function(test) {\n      var env = test.props;\n      var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n      var results = [];\n      var query = { '%': 100000, '.': { '>': '2020-02-01', '<': '2020-02-26' } };\n      test.async();\n      ref.get(query).map().once(function(v, k) {\n         if (k && v) { results.push(k); }\n      });\n      var t2 = setTimeout(function() {\n        var len = 25; /// expected number of results\n        var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n        clearTimeout(t);\n        if (results_unique.length === len) {\n          test.done();\n        } else {\n          console.log('RESULTS Query server - Between(< item <): ', results_unique.length, results_unique.join(', '));\n          test.fail('Error: get ' + results_unique.length + ' attributes.');\n        }\n      }, env.config.wait_map);\n    }, {\n      i: i += 1,\n      config: config\n    });\n  });\n  it('Query server - Higher(>)               ', function() {\n    var i=0;\n    return server.run(function(test) {\n      var env = test.props;\n      var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n      var results = [];\n      var query = { '%': 100000, '.': { '>': '2020-12-01' } };\n      test.async();\n      ref.get(query).map().once(function(v, k) {\n         if (k && v) { results.push(k); }\n      });\n      var t2 = setTimeout(function() {\n        var len = 31; /// expected number of results\n        var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n        clearTimeout(t);\n        if (results_unique.length === len) {\n          test.done();\n        } else {\n          console.log('RESULTS Query server - Higher(>): ', results_unique.length, results_unique.join(', '));\n          test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n        }\n      }, env.config.wait_map);\n    }, {\n      i: i += 1,\n      config: config\n    });\n  });\n  it('Query server - Lower(<)                ', function() {\n    var i=0;\n    return server.run(function(test) {\n      test.async();\n      var env = test.props;\n      var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n      var results = [];\n      var query = { '%': 100000, '.': { '<': '2020-02-06' } };\n      ref.get(query).map().once(function(v, k) {\n         if (k && v) { results.push(k); }\n      });\n      var t2 = setTimeout(function() {\n        var len = 37; /// expected number of results\n        var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n        clearTimeout(t);\n        if (results_unique.length === len) {\n          test.done();\n        } else {\n          console.log('RESULTS Query server - Lower(<): ', results_unique.length, results_unique.join(', '));\n          test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n        }\n      }, env.config.wait_map);\n    }, {\n      i: i += 1,\n      config: config\n    });\n  });\n  it('Query server - Exact match(=)          ', function() {\n    var i=0;\n    return server.run(function(test) {\n      var env = test.props;\n      var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n      var results = [];\n      var query = { '%': 100000, '.': { '=': '2020-03-01T00:00:00.000Z' } };\n      test.async();\n      ref.get(query).map().once(function(v, k) {\n         if (k && v) { results.push(k); }\n      });\n      var t2 = setTimeout(function() {\n        var len = 1; /// expected number of results\n        var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n        clearTimeout(t);\n        if (results_unique.length === len) {\n          test.done();\n        } else {\n          console.log('RESULTS Query server - Exact match(=): ', results_unique.length, results_unique.join(', '));\n          test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n        }\n      }, env.config.wait_map);\n    }, {\n      i: i += 1,\n      config: config\n    });\n  });\n  it('Query server - Prefix match(*)         ', function() {\n    var i=0;\n    return server.run(function(test) {\n      var env = test.props;\n      var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n      var results = [];\n      var query = { '%': 100000, '.': { '*': '2020-10-' } };\n      test.async();\n      ref.get(query).map().once(function(v, k) {\n         if (k && v) { results.push(k); }\n      });\n      var t2 = setTimeout(function() {\n        var len = 31; /// expected number of results\n        var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n        clearTimeout(t);\n        if (results_unique.length === len) {\n          test.done();\n        } else {\n          console.log('RESULTS Query server - Prefix match(*): ', results_unique.length, results_unique);\n          test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n        }\n      }, env.config.wait_map);\n    }, {\n      i: i += 1,\n      config: config\n    });\n  });\n\n  it(config.browsers + ' browser(s) have joined!              ', function() {\n    console.log('PLEASE OPEN http://' + config.IP + ':' + config.port + ' IN ' + config.browsers + ' BROWSER(S)!');\n    return browsers.atLeast(config.browsers);\n  });\n  it('Browsers initialized gun!              ', function() {\n    var tests = [], i = 0;\n    browsers.each(function(client, id) {\n      tests.push(client.run(function(test) {\n        test.async();\n        localStorage.clear();\n        console.log('Clear localStorage!!!');\n//         ['/gun/lib/radix.js', '/gun/lib/radisk.js', '/gun/lib/store.js', '/gun/lib/rindexed.js'].map(function(src) {\n//           var script = document.createElement('script');\n//           script.setAttribute('src', src);\n//           document.head.appendChild(script);\n//         });\n\n        var env = test.props;\n        var opt = {\n          peers: ['http://' + env.config.IP + ':' + (env.config.port + 1) + '/gun'],\n          localStorage: false\n        };\n        var pid = location.hash.slice(1);\n        if (pid) {\n          opt.pid = pid;\n        }\n        Gun.on('opt', function(ctx) {\n          this.to.next(ctx);\n          ctx.on('hi', function(opt) {\n            document.title = 'RAD test PID: ' + this.on.opt.pid;\n          });\n        });\n        setTimeout(function() {\n        var gun = window.gun = Gun(opt);\n        var ref = window.ref = gun.get('timenode');\n        test.done();\n        }, 1000);\n      }, {\n        i: i += 1,\n        config: config\n      }));\n    });\n    return Promise.all(tests);\n  });\n\n  it('Query browser - Between(< item <)     ', function() {\n    var tests = [], i = 0;\n    browsers.each(function(client, id) {\n      tests.push(client.run(function(test) {\n        var env = test.props;\n        var t = setTimeout(function() { test.fail('Error: No response.'); }, 6000);\n        var results = [];\n        var query = { '%': 100000, '.': { '>': '2020-06-01', '<': '2020-09-01' } };\n        test.async();\n        ref.get(query).map().once(function(v, k) {\n          if (k && v) { results.push(k); }\n        });\n        var t2 = setTimeout(function() {\n          var len = 30+31+31; /// expected number of results\n          var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n          clearTimeout(t);\n          if (results_unique.length === len) {\n            test.done();\n          } else {\n            console.log('RESULTS Query browser - Between(< item <): ', results_unique.length, results_unique.join(', '));\n            test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n          }\n        }, env.config.wait_map);\n      }, { i: i += 1, config: config }));\n    });\n    return Promise.all(tests);\n  });\n  it('Query browser - Higher(>)              ', function() {\n    var tests = [], i = 0;\n    browsers.each(function(client, id) {\n      tests.push(client.run(function(test) {\n      var env = test.props;\n      var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n      var results = [];\n      var query = { '%': 100000, '.': { '>': '2020-11-01' } };\n      test.async();\n      ref.get(query).map().once(function(v, k) {\n         if (k && v) { results.push(k); }\n      });\n      var t2 = setTimeout(function() {\n        var len = 61; /// expected number of results\n        var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n        clearTimeout(t);\n        if (results_unique.length === len) {\n          test.done();\n        } else {\n          console.log('RESULTS Query browser - Higher(>): ', results_unique.length, results_unique.join(', '));\n          test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n        }\n      }, env.config.wait_map);\n    }, {\n        i: i += 1,\n        config: config\n      }));\n    });\n    return Promise.all(tests);\n  });\n  it('Query browser - Lower(<)               ', function() {\n    var tests = [], i = 0;\n    browsers.each(function(client, id) {\n      tests.push(client.run(function(test) {\n        var env = test.props;\n        var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n        var results = [];\n        var query = { '%': 100000, '.': { '<': '2020-02-05' } };\n        test.async();\n        ref.get(query).map().once(function(v, k) {\n          if (k && v) { results.push(k); }\n        });\n        var t2 = setTimeout(function() {\n          var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n          var len = 35; /// expected number of results\n          clearTimeout(t);\n          if (results_unique.length === len) {\n            test.done();\n          } else {\n            console.log('RESULTS Query browser - Lower(<): ', results_unique.length, results_unique.join(', '));\n            test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n          }\n        }, env.config.wait_map);\n      }, {\n        i: i += 1,\n        config: config\n      }));\n    });\n    return Promise.all(tests);\n  });\n  it('Query browser - Exact match(=)         ', function() {\n    var tests = [], i = 0;\n    browsers.each(function(client, id) {\n      tests.push(client.run(function(test) {\n        var env = test.props;\n        var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n        var results = [];\n        var query = { '%': 100000, '.': { '=': '2020-06-01T00:00:00.000Z' } };\n        test.async();\n        ref.get(query).map().once(function(v, k) {\n          if (k && v) { results.push(k); }\n        });\n        var t2 = setTimeout(function() {\n          var len = 1; /// expected number of results\n          var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n          clearTimeout(t);\n          if (results_unique.length === len) {\n            test.done();\n          } else {\n            console.log('RESULTS Query browser - Exact match(=): ', results_unique.length, results_unique.join(', '));\n            test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n          }\n        }, env.config.wait_map);\n      }, {\n        i: i += 1,\n        config: config\n      }));\n    });\n    return Promise.all(tests);\n  });\n  it('Query browser - Prefix match(*)        ', function() {\n    var tests = [], i = 0;\n    browsers.each(function(client, id) {\n      tests.push(client.run(function(test) {\n        var env = test.props;\n        var t = setTimeout(function() { test.fail('Error: No response.');}, 5000);\n        var results = [];\n        var query = { '%': 100000, '.': { '*': '2020-10-' } };\n        test.async();\n        ref.get(query).map().once(function(v, k) {\n          if (k && v) { results.push(k); }\n        });\n        var t2 = setTimeout(function() {\n          var len = 31; /// expected number of results\n          var results_unique = results.filter(function(v, i, a) { return a.indexOf(v) === i; }).sort();\n          clearTimeout(t);\n          if (results_unique.length === len) {\n            test.done();\n          } else {\n            console.log('RESULTS Query browser - Prefix match(*): ', results_unique.length, results_unique);\n            test.fail('Error: get ' + results_unique.length + ' attributes instead of '+len);\n          }\n        }, env.config.wait_map);\n      }, {\n        i: i += 1,\n        config: config\n      }));\n    });\n    return Promise.all(tests);\n  });\n\n  ////////////////////////////////\n  it(\"Wait...\", function(done){\n  \tsetTimeout(done, 3000);\n  });\n  it(\"All finished!\", function(done){\n  \tconsole.log(\"Done! Cleaning things up...\");\n  \tsetTimeout(function(){\n  \t\tdone();\n  \t},1000);\n  });\n  after(\"Everything shut down.\", function(){\n  \tbrowsers.run(function(){\n  \t\t//location.reload();\n  \t\t//setTimeout(function(){\n  \t\t//}, 15 * 1000);\n  \t});\n  \treturn servers.run(function(){\n  \t\tprocess.exit();\n  \t});\n  });\n});\n"
  },
  {
    "path": "test/panic/livestream.js",
    "content": "/*\nThis is the first in a series of basic networking correctness tests.\nEach test itself might be dumb and simple, but built up together,\nthey prove desired end goals for behavior at scale.\n1. (this file) Is a browser write is confirmed as save by multiple peers even if by daisy chain.\n2. \n*/\n\nvar config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/livestream.html': __dirname + '/livestream.html',\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar bob = servers.pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar others = browsers.excluding(alice);\n\ndescribe(\"Broadcast Video\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n  \t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\tvar port = env.config.port + env.i;\n\t\t\t\tvar Gun = require('gun');\n\t\t\t\tvar peers = [], i = env.config.servers;\n\t\t\t\twhile(i--){\n\t\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\t\tvar gun = Gun({file: env.i+'data', peers: peers, web: server});\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load QVDev's streaming!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\tconsole.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\tload('https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/GunRecorder.js', function(){\n\t\t\t\t\tload('https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/GunStreamer.js', function(){\n\t\t\t\t\t\tload('https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/GunViewer.js', function(){\n\t\t\t\t\t\t\tload('https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/mediabuffer.js', function(){\n\t\t\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\t$('body').append('<video id=\"video\" width=\"100%\" autoplay></video>');\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.gun = gun;\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Stream\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tvar stream = window.stream = new GunStreamer({\n\t\t\t\turl: \"https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/parser_worker.js\",\n\t\t\t\tgun: gun,\n\t\t\t\tstreamId: 'livestream',\n\t\t\t\tdbRecord: 'streams'\n\t\t\t});\n\t\t\tvar record = window.record = new GunRecorder({\n\t\t\t\tmimeType: 'video/webm; codecs=\"opus,vp8\"',\n\t\t\t\t//audioBitsPerSecond: 6000,//Audio bits per second this is the lowest quality\n\t\t\t\t//videoBitsPerSecond: 100000,//Video bits per second this is the lowest quality\n\t\t\t\tcameraOptions: {video:{width: 1280, height: 720, facingMode: \"environment\", frameRate: 60}, audio: false},\n\t\t\t\tvideo_id: \"video\",\n\t\t\t\trecordInterval: 1000, // how long each chunk?\n\t\t\t\tonRecordStateChange: function(state){ /* change play/pause buttons */ },\n\t\t\t\tonDataAvailable: function(data){ stream.onDataAvailable(data) } // pass recorded data to streamer\n\t\t\t});\n\t\t\trecord.startCamera();\n\t\t\t$('#video').on('playing', function(eve){\n\t\t\t  record.record();\n\t\t\t  test.done();\n\t\t\t});\n  \t\tconsole.log(\"start recording!\");\n\t\t}, {acks: config.servers});\n\t});\n\n\tit(\"View\", function(){\n\t\treturn others.run(function(test){\n\t\t\tconsole.log(\"I AM A VIEWER!\");\n\t\t\ttest.async();\n\t\t\tvar view = new GunViewer({\n\t\t\t\t//mimeType: 'video/webm; codecs=\"opus,vp8\"', // NEED THIS ONE FOR AUDIO+VIDEO\n\t\t\t\tmimeType: 'video/webm; codecs=\"vp8\"',\n\t\t\t\tstreamerId: \"video\",\n\t\t\t\tdebug: true,//For debug logs  \n\t\t\t});\n\t\t\tgun.get('livestream').on(function(data){\n\t\t\t\twindow.data = data;\n\t\t\t\tview.onStreamerData(data);\n\t\t\t});\n\t\t}, {acks: config.servers});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/load.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\trelays: 1,\n\tbrowsers: 4,\n\teach: 1500,\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\n/*\n\tWelcome, person!\n\tYou have found the test that causes gun to PANIC with load!\n\tAbove are options to configure, the only ones useful are:\n\t - browsers // number of browsers you want to load test across.\n\t - each // the number of messages each browser should sync.\n\tThis test is less than 200 lines of code (without comments)!\n\tHowever, if you aren't familiar with PANIC - you are in for a surprise!\n\tI'm Plublious, and I shall be your guide!\n*/\n\n// First we need to create a PANIC server.\n// Each device/browser in the distributed system we are testing connects to it.\n// It then coordinates these clients to cause chaos in the distributed system.\n// Cool huh?\nvar panic; try{ panic = require('panic-server') } catch(e){ console.log(\"PANIC not installed! `npm install panic-server panic-manager panic-client`\") }\n\npanic.server().on('request', function(req, res){ // Static server\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port); // Start panic server.\n\n// In order to tell the clients what to do,\n// We need a way to reference all of them.\nvar clients = panic.clients;\n\n// Some of the clients may be NodeJS relays on different machines.\n// PANIC manager is a nifty tool that lets us remotely spawn them.\nvar manager = require('panic-manager')();\nmanager.start({\n    clients: Array(config.relays).fill().map(function(u, i){ // Create a bunch of relays.\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1) // They'll need unique ports to start on, if we run the test on 1 machine.\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port // Auto-connect to our panic server.\n});\n\n// Now lets divide our PANIC clients into \"relays\" and \"browsers\".\nvar relays = clients.filter('Node.js');\nvar browsers = clients.excluding(relays);\n\n// Sweet! Now we can start the tests.\n// PANIC works with Mocha and other testing libraries!\n// So it is easy to use PANIC.\n\ndescribe(\"Load test \"+ config.browsers +\" browser(s) across \"+ config.relays +\" server(s)!\", function(){\n\n\t// We'll have to manually launch the browsers,\n\t// So lets up the timeout so we have time to do that.\n\tthis.timeout(5 * 60 * 1000);\n\n\tit(\"Relays have joined!\", function(){\n\t\t// Alright, lets wait until enough gun server peers are connected.\n\t\treturn relays.atLeast(config.relays);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\trelays.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data.json') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\t// Launch the server and start gun!\n\t\t\t\tvar Gun; try{ Gun = require('gun') }catch(e){ console.log(\"GUN not found! You need to link GUN to PANIC. Nesting the `gun` repo inside a `node_modules` parent folder often fixes this.\") }\n\t\t\t\t// Attach the server to gun.\n\t\t\t\tvar gun = Gun({file: env.i+'data', web: server, localStorage: false});\n\t\t\t\tserver.listen(env.config.port + env.i, function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\t// Okay! Cool. Now we can move on to the next step...\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\t// Which is to automatically or manually open up a bunch of browser tabs\n\t\t// and connect to the PANIC server in the same way\n\t\t// the NodeJS relays did.\n\n\t\t// However! We're gonna cheat...\n\t\tbrowsers.atLeast(1).then(function(){\n\t\t\t// When there is at least one browser opened, tell it to run this code:\n\t\t\tbrowsers.run(function(test){\n\t\t\t\t// NOTE: This closure is now being run IN THE BROWSER.\n\t\t\t\t// This code is not server side code, despite the fact\n\t\t\t\t// that we've written it on the server. It is not.\n\t\t\t\t// Mind blowing, right?\n\t\t\t\tvar env = test.props;\n\t\t\t\t// Like before, we had to manually pass it some scope.\n\t\t\t\t$('body').prepend(\"<button onclick='allopen()'>Open All Browsers</button>\");\n\t\t\t\t// All right, lets cheat by making a button\n\t\t\t\t// that will automatically open all the\n\t\t\t\t// remaining browser tabs for us\n\t\t\t\t// so we don't have to do it manually.\n\t\t\t\twindow.allopen = function(i){\n\t\t\t\t\tif(env.config.browsers <= i){ return }\n\t\t\t\t\ti = i || 1;\n\t\t\t\t\tvar win = window.open(location, '_blank');\n\t\t\t\t\twin.focus();\n\t\t\t\t\tsetTimeout(function(){allopen(i+1)},0);\n\t\t\t\t}\n\t\t\t}, {config: config});\n\t\t});\n\t\t// Cool! Once that is done...\n\t\t// WAIT until all those browser tabs\n\t\t// have connected to the PANIC server\n\t\t// THEN move onto the next step\n\t\t// where we will cause chaos!\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Data was saved and synced across all browsers!\", function(){\n\t\t// This is where it gets good!\n\t\tvar tests = [], ids = {}, i = 0;\n\t\t// Let us create a list of all the browsers IDs connected.\n\t\t// This will later let each browser check against every other browser.\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\t// for every browser, run the following code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t//var audio = new Audio('https://www.nasa.gov/mp3/640170main_Roger%20Roll.mp3');audio.addEventListener('ended', function() {this.currentTime = 0;this.play();}, false);audio.play(); // testing if audio prevents Chrome throttle?\n\t\t\t\tlocalStorage.clear(); // Clean up anything from before.\n\t\t\t\tvar env = test.props;\n\t\t\t\t// Get access to the \"outer scope\" which has the browser IDs\n\t\t\t\t// as well as other configuration information.\n\t\t\t\ttest.async();\n\t\t\t\t// Now we want to connect to every gun server peer...\n\t\t\t\tvar peers = [], i = env.config.relays;\n\t\t\t\twhile(i--){\n\t\t\t\t\t// For the total number of relays listed in the configuration\n\t\t\t\t\t// Add their URL into an array.\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + (env.config.port + (i + 1)) + '/gun');\n\t\t\t\t}\n\t\t\t\t// Pass all the relays we want to connect to into gun.\n\t\t\t\t//var gun = Gun();\n\t\t\t\tvar gun = Gun(peers);\n\t\t\t\t// Now we want to create a list\n\t\t\t\t// of all the messages that WILL be sent\n\t\t\t\t// according to the expected configuration.\n\t\t\t\t// This is equal to...\n\t\t\t\tvar num = 0, total = 0, check = Gun.obj.map(env.ids, function(v,id,t){\n\t\t\t\t\t// for each browser ID\n\t\t\t\t\t// they will be saving X number of messages each.\n\t\t\t\t\tvar i = env.config.each;\n\t\t\t\t\twhile(i--){\n\t\t\t\t\t\t// So add a deterministic key we can check against.\n\t\t\t\t\t\tt(id + (i + 1), 1);\n\t\t\t\t\t\t// And count up the total number of messages we expect for all.\n\t\t\t\t\t\ttotal += 1;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Note, this `check` hash table now looks something like this:\n\t\t\t\t// {alice1: 1, alice2: 1, alice3: 1, bob1: 1, bob2: 1, bob3: 1}\n\t\t\t\tvar report = $(\"<div>\").css({position: 'fixed', top: 0, right: 0, background: 'white', padding: 10}).text(num +\" / \"+ total +\" Verified\").prependTo('body');\n\t\t\t\t// Add a nifty UI that tells us how many messages have been verified.\n\t\t\t\t// FINALLY, tell gun to subscribe to every record\n\t\t\t\t// that is is/will be saved to this table.\n\t\t\t\tgun.get('test').map().on(function(data, key){\n\t\t\t\t\t// When we get realtime updates to the data,\n\t\t\t\t\t// create or reuse a DIV that we\n\t\t\t\t\t//var el = $('#'+key).length ? $('#'+key) : $('<div>');\n\t\t\t\t\t// log the data out to, so we can visually see our test.\n\t\t\t\t\t//$(log).append(el.attr('id', key).text(key +\": \"+ data));\n\t\t\t\t\t$(log).text(key +\": \"+ data); // DOM updates thrash performance, try this.\n\t\t\t\t\t// Scroll down with the logging.\n\t\t\t\t\t//$('body').stop(true).animate({scrollTop: $(log).height()});\n\t\t\t\t\t// Now, make sure the received data\n\t\t\t\t\t// matches exactly the data we EXPECT\n\t\t\t\t\tif((\"Hello world, \"+key+\"!\") === data){\n\t\t\t\t\t\t// if it does, we can \"check off\" record\n\t\t\t\t\t\t// Bump the total number of verified items and update the UI.\n\t\t\t\t\t\tif(check[key]){ num += 1 }\n\t\t\t\t\t\t// from our verify todo list.\n\t\t\t\t\t\tcheck[key] = 0;\n\t\t\t\t\t\treport.text(num +\" / \"+ total +\" Verified\");\n\t\t\t\t\t}\n\t\t\t\t\t// This next part is important:\n\t\t\t\t\tif(Gun.obj.map(check, function(still){\n\t\t\t\t\t\t// IF THERE ARE ANY RECORDS STILL LEFT TO BE VERIFIED\n\t\t\t\t\t\tif(still){ return true }\n\t\t\t\t\t})){ return } // return, PREVENTING the test from being finished.\n\t\t\t\t\t// IF HOWEVER, every single message\n\t\t\t\t\t// that we EXPECTED to see\n\t\t\t\t\t// has now been seen\n\t\t\t\t\t// then THIS ONE BROWSER PEER (of many peers)\n\t\t\t\t\t// is finally done.\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t\t// But we have to actually tell the browser to save data!\n\t\t\t\tvar i = 0, to = setInterval(function go(){\n\t\t\t\t\t// Cool, make a recursive function\n\t\t\t\t\t// that keeps going until we've saved each message.\n\t\t\t\t\tif(env.config.each <= i){\n\t\t\t\t\t\tclearTimeout(to);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t//to = setTimeout(go, env.config.wait * Math.random()); // add a little jitter.\n\t\t\t\t\ti += 1;\n\t\t\t\t\tvar p = env.id + i;\n\t\t\t\t\t// And actually save the data with gun,\n\t\t\t\t\t// as a record added to one big 'test' table.\n\t\t\t\t\tgun.get('test').get(p).put('Hello world, '+ p +'!');\n\t\t\t\t}, env.config.wait);\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config})); \n\t\t});\n\t\t// YAY! We're finally done.\n\t\t// IF AND ONLY IF\n\t\t// EVERY SINGLE BROWSER\n\t\t// HAS VERIFIED\n\t\t// EVERY OTHER BROWSERS' data.\n\t\t// If they are ALL done, go to the next step.\n\t\treturn Promise.all(tests);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\t// which is to shut down all the browsers.\n\t\trequire('./util/open').cleanup() || browsers.run(function(){\n\t\t\tsetTimeout(function(){\n\t\t\t\tlocation.reload();\n\t\t\t}, 15 * 1000);\n\t\t});\n\t\t// And shut down all the relays.\n\t\treturn relays.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n})\n// THE END!\n// Congrats, wasn't that epic?\n// Or still confused how a single 200 LOC test file\n// Is running correctness verification tests\n// across an entire distributed system of devices/browsers?\n// Well, jump on https://gitter.im/amark/gun !\n\n// Think adding tests like this to your work place would be bomb awesome?\n// We totally sell PANIC training, licenses, and support!\n// Please reach out to hi@gunDB.io if you are interested\n// in purchasing consulting or services for PANIC."
  },
  {
    "path": "test/panic/no-override.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = servers.pluck(1);\nvar spawn = servers.excluding(server).pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar again = {};\n\ndescribe(\"No Empty Object on .Once\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')((env.i+1)+'data') }catch(e){}\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun = require('gun');\n\t\t\tvar gun = Gun({file: env.i+'data', web: server});\n\t\t\tserver.listen(port, function(){});\n\t\t\tsetTimeout(function(){\n\n\t\t\t\tgun.get('survey').get('231119').get('x').put({z:1})\n\t\t\t\tgun.get('survey').get('231119').get('y').put({z:1})\n\t\t\t\tgun.get('survey').get('231119').once(function(data){\n\t\t\t\t\tconsole.log(data);\n\t\t\t\t\tif(!data.x || !data.y){\n\t\t\t\t\t\tno_data_explode;\n\t\t\t\t\t}\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\n\t\t\t},500);\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.ref = gun.get('survey').get('231119');\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Write initial value\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\tref.get('z').put({z:1});\n\t\t\tsetTimeout(function(){\n\t\t\t\tref.once(function(data){\n\t\t\t\t\tconsole.log(\"DOES X Y & Z EXIST?\", data);\n\t\t\t\t\tif(!data.x || !data.y || !data.z){\n\t\t\t\t\t\ttest.fail(\"overwrote old object!\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\ttest.done();\n\t\t\t\t})\n\t\t\t}, 500);\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/on-recovery.js",
    "content": "// Gun is supposed to be able to gracefully handle peers going offline and then\n// coming back online. If a client has subscribed to some piece of data via the\n// gun.on() API method, the subscription should continue to work if a peer goes\n// offline briefly and then comes back online. This test confirms that such is\n// the case, or fails otherwise.\n\n// Important: It turns out that it's very important that both browsers tabs be\n// visible/active throughout the tests, because an inactive tab will NOT\n// reconnect to the relay peer until the tab is active again. (Chrome 83)\n\n// Uses a pattern described in https://stackoverflow.com/a/39286581/13564512\n// to run multiple configurations of a mocha test.\n\nvar config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 2,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/radix.js': __dirname + '/../../lib/radix.js',\n\t\t'/radisk.js': __dirname + '/../../lib/radisk.js',\n\t\t'/store.js': __dirname + '/../../lib/store.js',\n\t\t'/rindexed.js': __dirname + '/../../lib/rindexed.js'\n\t},\n\t/** Test variants to run */\n\tvariants: ['default', 'radisk'],\n\t/** Configuration details for each variant. If unspecified, variant will run with no additional configuration. */\n\tvariantConfigs: {\n\t\tradisk: {\n\t\t\t/** Options to pass the Gun constructor */\n\t\t\topts: {\n\t\t\t\tlocalStorage: false\n\t\t\t},\n\t\t\t/** Libraries to import before constructing Gun */\n\t\t\timports: [\n\t\t\t\t'radix.js',\n\t\t\t\t'radisk.js',\n\t\t\t\t'store.js',\n\t\t\t\t'rindexed.js'\n\t\t\t]\n\t\t}\n\t}\n};\n\nvar {loadBrowserScripts} = require('./util/load-browser-scripts');\nvar panic = require('panic-server');\npanic.server().on('request', function (req, res) {\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\n\nvar manager = require('panic-manager')();\n\nvar clients = panic.clients;\nvar servers = clients.filter('Node.js');\n/** The first relay peer */\nvar bob = servers.pluck(1);\n/** The second relay peer */\nvar carl = servers.excluding(bob).pluck(1);\nvar browsers = clients.excluding(servers);\n/** The \"sending\" browser */\nvar alice = browsers.pluck(1);\n/** The \"receiving\" browser */\nvar dave = browsers.excluding(alice).pluck(1);\n\n// Describe the test itself\ndescribe(\"gun.on should receive updates after crashed relay peer comes back online\", function () {\n\tthis.timeout(10 * 1000);\n\tconfig.variants.forEach((variant) => {\n\t\tvar variantConfig = config.variantConfigs[variant] || {};\n\n\t\t// Describe the variant\n\t\tdescribe(`with ${variant} plugin configuration`, function () {\n\t\t\tbefore('PANIC manager setup servers', function () {\n\t\t\t\t// we are terminating the gun servers after each test variant, so we need to start them up again before each test variant\n\t\t\t\tmanager.start({\n\t\t\t\t\tclients: Array(config.servers).fill().map(function (u, i) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: 'node',\n\t\t\t\t\t\t\tport: config.port + (i + 1)\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t\tpanic: 'http://' + config.IP + ':' + config.port\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tbefore(\"Servers have joined!\", function () {\n\t\t\t\treturn servers.atLeast(config.servers);\n\t\t\t});\n\n\t\t\tit(\"GUN started!\", function () {\n\t\t\t\treturn bob.run(function (test) {\n\t\t\t\t\tvar env = test.props;\n\t\t\t\t\tvar filepath = env.dir + '/data';\n\t\t\t\t\ttest.async();\n\t\t\t\t\tvar fs = require('fs');\n\t\t\t\t\ttry {if (fs.existsSync(filepath)) {fs.rmdirSync(filepath, {recursive: true});} } catch (e) {console.error(e); test.fail('');}\n\t\t\t\t\tvar server = require('http').createServer(function (req, res) {\n\t\t\t\t\t\tres.end(\"I AM BOB\");\n\t\t\t\t\t});\n\t\t\t\t\tvar port = env.config.port + 1;\n\t\t\t\t\ttry {var Gun = require(env.dir + '/../../index.js');} catch (e) {console.error(e); test.fail('');}\n\t\t\t\t\tvar gun = Gun({file: filepath, web: server});\n\t\t\t\t\tserver.listen(port, function () {\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});\n\t\t\t\t}, {config: config, dir: __dirname});\n\t\t\t});\n\n\t\t\tit(config.browsers + \" browser(s) have joined!\", function () {\n\t\t\t\trequire('./util/open').web(config.browsers, \"http://\" + config.IP + \":\" + config.port, {\n\t\t\t\t\theadless: true,\n\t\t\t\t});\n\t\t\t\treturn browsers.atLeast(config.browsers);\n\t\t\t});\n\n\t\t\tit(`Browsers loaded ${variant} plugin libraries`, function () {\n\t\t\t\treturn loadBrowserScripts(browsers, variantConfig.imports);\n\t\t\t});\n\n\t\t\tit(\"Browsers initialized gun!\", function () {\n\t\t\t\tvar tests = [], i = 0;\n\t\t\t\tbrowsers.each(function (client, id) {\n\t\t\t\t\ttests.push(client.run(function (test) {\n\t\t\t\t\t\ttry {localStorage.clear()} catch (e) { }\n\t\t\t\t\t\ttry {indexedDB.deleteDatabase('radata')} catch (e) { }\n\t\t\t\t\t\tvar env = test.props;\n\t\t\t\t\t\tvar configOpts = env.variantConfig.opts || {};\n\t\t\t\t\t\tvar opts = {\n\t\t\t\t\t\t\tpeers: ['http://' + env.config.IP + ':' + (env.config.port + 1) + '/gun'],\n\t\t\t\t\t\t\t...configOpts\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconsole.log('using constructor options: ', JSON.stringify(opts));\n\t\t\t\t\t\tvar gun = Gun(opts);\n\t\t\t\t\t\twindow.ref = gun.get('a');\n\t\t\t\t\t}, {i: i += 1, config: config, variantConfig: variantConfig}));\n\t\t\t\t});\n\t\t\t\treturn Promise.all(tests);\n\t\t\t});\n\n\t\t\tit(\"Dave subscribed to updates using gun.on()\", function () {\n\t\t\t\treturn dave.run(function (test) {\n\t\t\t\t\tconsole.log(\"I AM DAVE\");\n\t\t\t\t\ttest.async();\n\t\t\t\t\tref.on(function (data) {\n\t\t\t\t\t\tconsole.log(\"Just received data: \", JSON.stringify(data));\n\t\t\t\t\t\tif (data.hello === 'world') {window.receivedFirst = true;}\n\t\t\t\t\t\tif (data.foo === 'bar') {window.receivedSecond = true;}\n\t\t\t\t\t});\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit(\"Alice put first data\", function () {\n\t\t\t\treturn alice.run(function (test) {\n\t\t\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\t\t\ttest.async();\n\t\t\t\t\tref.put({hello: 'world'}, function (ack) {\n\t\t\t\t\t\tif (!ack.err) {\n\t\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log('ALICE WAS UNABLE TO PUT DATA!');\n\t\t\t\t\t\t\ttest.fail();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit(\"Dave received first data\", function () {\n\t\t\t\treturn dave.run(function (test) {\n\t\t\t\t\ttest.async();\n\t\t\t\t\tvar myInterval;\n\t\t\t\t\tmyInterval = setInterval(function () {\n\t\t\t\t\t\tif (window.receivedFirst) {\n\t\t\t\t\t\t\tclearInterval(myInterval);\n\t\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 10);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit(\"Killed relay peer\", function () {\n\t\t\t\treturn bob.run(function (test) {\n\t\t\t\t\ttest.async();\n\t\t\t\t\tprocess.exit();\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit(\"Waited 1 second\", function (done) {\n\t\t\t\tsetTimeout(done, 1000);\n\t\t\t});\n\n\t\t\tit(\"Alice put second data\", function () {\n\t\t\t\treturn alice.run(function (test) {\n\t\t\t\t\ttest.async();\n\t\t\t\t\tref.put({foo: 'bar'}, function (ack) {\n\t\t\t\t\t\tif (!ack.err) {\n\t\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// FIXME: Don't copy paste the entire block!!\n\t\t\tit(\"Restored relay peer\", function () {\n\t\t\t\treturn carl.run(function (test) {\n\t\t\t\t\tvar env = test.props;\n\t\t\t\t\tvar filepath = env.dir + '/data';\n\t\t\t\t\ttest.async();\n\t\t\t\t\tvar fs = require('fs');\n\t\t\t\t\ttry {if (fs.existsSync(filepath)) {fs.rmdirSync(filepath, {recursive: true});} } catch (e) {console.error(e); test.fail('');}\n\t\t\t\t\tvar server = require('http').createServer(function (req, res) {\n\t\t\t\t\t\tres.end(\"I AM CARL\");\n\t\t\t\t\t});\n\t\t\t\t\tvar port = env.config.port + 1;\n\t\t\t\t\ttry {var Gun = require(env.dir + '/../../index.js');} catch (e) {console.error(e); test.fail('');}\n\t\t\t\t\tvar gun = Gun({file: filepath, web: server});\n\t\t\t\t\tserver.listen(port, function () {\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});\n\t\t\t\t}, {config: config, dir: __dirname});\n\t\t\t});\n\n\t\t\tit(\"Browsers reconnected\", function () {\n\t\t\t\tvar tests = [], i = 0;\n\t\t\t\tbrowsers.each(function (client, id) {\n\t\t\t\t\ttests.push(client.run(function (test) {\n\t\t\t\t\t\ttest.async();\n\t\t\t\t\t\tvar config = test.props.config;\n\t\t\t\t\t\tvar seconds = 15;\n\t\t\t\t\t\tvar timeout = Date.now() + seconds * 1000;\n\t\t\t\t\t\tvar url = \"http://\" + config.IP + \":\" + (config.port + 1) + \"/gun\";\n\t\t\t\t\t\tvar peers = ref.back(1)._.opt.peers;\n\t\t\t\t\t\tvar i;\n\t\t\t\t\t\ti = setInterval(function () {\n\t\t\t\t\t\t\tif (peers[url] && peers[url].wire.readyState === 1) {\n\t\t\t\t\t\t\t\tclearInterval(i);\n\t\t\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (Date.now() >= timeout) {\n\t\t\t\t\t\t\t\ttest.fail('Timed out after ' + seconds + ' seconds');\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 10);\n\t\t\t\t\t}, {config: config}));\n\t\t\t\t});\n\t\t\t\treturn Promise.all(tests);\n\t\t\t});\n\n\t\t\tit(\"Dave received second data\", function () {\n\t\t\t\treturn dave.run(function (test) {\n\t\t\t\t\ttest.async();\n\t\t\t\t\tvar seconds = 60;\n\t\t\t\t\tvar timeout = Date.now() + seconds * 1000;\n\t\t\t\t\tvar i;\n\t\t\t\t\ti = setInterval(function () {\n\t\t\t\t\t\tif (window.receivedSecond) {\n\t\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Date.now() >= timeout) {\n\t\t\t\t\t\t\ttest.fail('Timed out after ' + seconds + ' seconds');\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 10);\n\t\t\t\t});\n\t\t\t});\n\n\t\t\tit('Closed browsers & servers', function () {\n\t\t\t\tvar promises = [];\n\t\t\t\tpromises.push(bob.run(function () {\n\t\t\t\t\tprocess.exit();\n\t\t\t\t}));\n\t\t\t\tpromises.push(carl.run(function () {\n\t\t\t\t\tprocess.exit();\n\t\t\t\t}));\n\t\t\t\tpromises.push(require('./util/open').cleanup());\n\t\t\t\treturn Promise.all(promises);\n\t\t\t});\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/panic/radisk.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 2,\n\tbrowsers: 3,\n\teach: 100000, //1000000,\n\tburst: 1,\n\twait: 1,\n\tdir: __dirname,\n\tchunk: 1024 * 1024 * 10,\n\tnotrad: false,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\nconfig.gundir = require('path').resolve(config.dir, '../../')+'/';\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = servers.pluck(1);\nvar spawn = servers.excluding(server).pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\nvar carl = browsers.excluding(new panic.ClientList([alice, bob])).pluck(1);\n\ndescribe(\"Make sure the Radix Storage Engine (RAD) works.\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(5 * 60 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\tif(require('fs').existsSync('radata')){\n\t\t\t\tconsole.log(\"Please delete previous data first!\");\n\t\t\t\texplode;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tconsole.log('??? ===', require('gun/package.json').version);\n\t\t\tvar Gun = require('gun');\n\t\t\tvar gun = Gun({web: server, localStorage: env.config.notrad, chunk: env.config.chunk, file: 'radata'});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Alice save data\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\tlocalStorage.clear();\n\t\t\tvar env = test.props;\n\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun', localStorage: false, lack: 1000 * 60 * 60});\n\t\t\twindow.gun = gun;\n\n\t\t\tvar n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each;\n\t\t\tvar raw = Gun.text.random(200, 'a');// \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n\n\t\t\tfunction save(i){\n\t\t\t\tif(i > l){\n\t\t\t\t\treturn clearTimeout(t);\n\t\t\t\t}\n\t\t\t\tvar d;\n\t\t\t\tvar ref = window.gun.get('asdf'+i);\n\t\t\t\tref.put({hello: raw + i}, function(ack){\n\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\tif(ack.lack){\n\t\t\t\t\t\t\tconsole.log(\"!!!???\", i);\n\t\t\t\t\t\t\treturn test.fail(\"ACK timed out, turn your lack of ack up or thruput down.\"); \n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn test.fail(ack.err);\n\t\t\t\t\t}\n\t\t\t\t\t//console.log('ack?', ack.rad);\n\t\t\t\t\tif(d){ return } d = true;\n\t\t\t\t\tc++;\n\t\t\t\t\t!(i % (b * 4)) && console.log(i+'/'+l);//, '@'+Math.floor(b/((-n + (n = Gun.time.is()))/1000))+'/sec');\n\t\t\t\t\t//localStorage.clear();\n\t\t\t\t\tref.off();\n\t\t\t\t\t//console.log(\"gl:\", Object.keys(window.gun._.graph).length);\n\t\t\t\t\tif(c < l){ return }\n\t\t\t\t\tconsole.log(\"DONE!\", c+'/'+l);\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\tlocation = 'http://asdf';\n\t\t\t\t\t\t}, 1500)\n\t\t\t\t\t}, 1);\n\t\t\t\t});\n\t\t\t}\n\t\t\tfunction burst(){\n\t\t\t\tfor(var j = 0; j <= b; j++){\n\t\t\t\t\tsave(++i);\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar t = setInterval(burst, env.config.wait);\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(\"Shut server down!\", function(){\n\t\treturn server.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"giving server time to cool down...\");\n\t\t\tsetTimeout(function(){\n\t\t\t\tprocess.exit();\n\t\t\t\ttest.done();\n\t\t\t}, 100);\n\t\t});\n\t});\n\n\tit(\"GUN spawned!\", function(){\n\t\treturn spawn.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\tif(!require('fs').existsSync('radata')){\n\t\t\t\tconsole.log(\"Server data could not be found!\");\n\t\t\t\texplode;\n\t\t\t\treturn;\n\t\t\t}\t\n\t\t\t/*setInterval(function(){\n\t\t\t\tvar mem = process.memoryUsage();\n\t\t\t\tvar u = Math.round(mem.heapUsed / 1024 / 1024 * 100) / 100;\n\t\t\t\tconsole.log(u, 'MB');\n\t\t\t}, 1000);*/\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun = require('gun');\n\t\t\tvar gun = Gun({web: server, localStorage: env.config.notrad, chunk: env.config.notrad, file: 'radata', lack: 1000 * 60 * 60});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 2, config: config}); \n\t});\n\n\tit(\"Bob read data\", function(){\n\t\tthis.timeout(1000 * 60 * 60 * 5);\n\t\t//return alice.run(function(test){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I AM BOB\");\n\t\t\tlocalStorage.clear();\n\t\t\tvar env = test.props;\n\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun', localStorage: false});\n\t\t\twindow.gun = gun;\n\n\t\t\tvar n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each/2;\n\t\t\tvar raw = Gun.text.random(200, 'a');// \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\";\n\t\t\t$('body').append($(\"<div id='log'></div>\")); var $log = $('#log');\n\n\t\t\tfunction check(i){\n\t\t\t\tif(i > l){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar d;\n\t\t\t\tvar ref = window.gun.get('asdf' + i);\n\t\t\t\tref.on(function(data){\n\t\t\t\t\tif((raw+i) !== data.hello){ return test.fail('wrong ' + i) }\n\t\t\t\t\tif(d){ return } d = true;\n\t\t\t\t\tc++;\n\t\t\t\t\t!(i % 1000) && console.log(i+'/'+l);\n\t\t\t\t\t!(i % 1000) && $log.prepend('<p>'+i+'/'+l+'</p>');\n\t\t\t\t\t//console.log(i+'/'+l);\n\t\t\t\t\tref.off();\n\t\t\t\t\tif(c < l){ return }\n\t\t\t\t\tconsole.log(\"DONE!\", c+'/'+l);\n\t\t\t\t\t$log.prepend('<p>DONE! '+i+'/'+l+'</p>');\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t\tlocation = 'http://asdf';\n\t\t\t\t\t\t}, 1500)\n\t\t\t\t\t}, 1);\n\t\t\t\t});\n\t\t\t}\n\t\t\tfunction burst(){\n\t\t\t\tif(i > l){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor(var j = 0; j <= b; j++){\n\t\t\t\t\tcheck(++i);\t\n\t\t\t\t}\n\t\t\t\tsetTimeout(burst, env.config.wait);\n\t\t\t}\n\t\t\tburst();\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(\"Carl read data\", function(){\n\t\tthis.timeout(1000 * 60 * 60 * 5);\n\t\t//return alice.run(function(test){\n\t\treturn carl.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I AM CARL\");\n\t\t\tlocalStorage.clear();\n\t\t\tvar env = test.props;\n\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun', localStorage: false});\n\t\t\twindow.gun = gun;\n\t\t\tvar n = Gun.time.is(), i = env.config.each / 2, c = 0, b = env.config.burst, l = env.config.each;\n\t\t\tvar raw = Gun.text.random(200, 'a');// \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\";\n\t\t\t$('body').append($(\"<div id='log'></div>\")); var $log = $('#log');\n\n\t\t\tfunction check(i){\n\t\t\t\tif(i > l){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar d;\n\t\t\t\tvar ref = window.gun.get('asdf' + i);\n\t\t\t\tref.on(function(data){\n\t\t\t\t\tif((raw+i) !== data.hello){ return test.fail('wrong ' + i) }\n\t\t\t\t\tif(d){ return } d = true;\n\t\t\t\t\tc++;\n\t\t\t\t\t!(i % 1000) && console.log(i+'/'+l);\n\t\t\t\t\t!(i % 1000) && $log.prepend('<p>'+i+'/'+l+'</p>');\n\t\t\t\t\t//console.log(i+'/'+l);\n\t\t\t\t\tref.off();\n\t\t\t\t\tif(c < (l / 2)){ return }\n\t\t\t\t\tconsole.log(\"DONE!\", c+'/'+l);\n\t\t\t\t\t$log.prepend('<p>DONE! '+i+'/'+l+'</p>');\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}\n\t\t\tfunction burst(){\n\t\t\t\tif(i > l){\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor(var j = 0; j <= b; j++){\n\t\t\t\t\tcheck(++i);\t\n\t\t\t\t}\n\t\t\t\tsetTimeout(burst, env.config.wait);\n\t\t\t}\n\t\t\tburst();\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/radisk_split_failure.js",
    "content": "var Radisk = require('../../lib/radisk.js');\nvar Radix = require('../../lib/radix.js');\n\n// Mock options\nvar opt = {\n  file: 'radata_test_split_failure',\n  chunk: 10, // Very small chunk to force split\n  store: {\n    get: function (file, cb) {\n      cb(null, null);\n    },\n    put: function (file, data, cb) {\n      cb(null, 'ok');\n    },\n  },\n  log: function () {}, // Silence logs\n};\n\nvar r = Radisk(opt);\n\n// Construct a radix tree that needs splitting\n// Key size + value size + overhead > 10\n// Entry: len#key:val\\n\n// 3#key:val\\n -> ~10 chars\nvar tree = Radix();\n// Add enough keys to ensure split happens (need > 1 key)\nfor (var i = 10; i < 20; i++) {\n  tree('k' + i, 'val' + i);\n}\n// tree file\ntree.file = 'root_file';\n\nconsole.log('--- TEST: Split Failure Safety ---');\n\nvar putCalls = [];\nopt.store.put = function (file, data, cb) {\n  putCalls.push(file);\n  console.log('Store.put called for:', file);\n\n  if (file === 'root_file') {\n    // This is the old file being overwritten/truncated\n    cb(null, 'ok');\n  } else {\n    // This is the new split file\n    console.log('Simulating FAILURE for new file:', file);\n    cb('MockWriteError');\n  }\n};\n\nr.write('root_file', tree, function (err, ok) {\n  console.log('Callback received:', err);\n\n  // Check results\n  var newFileCalls = putCalls.filter(function (f) {\n    return f !== 'root_file';\n  });\n  var oldFileCalls = putCalls.filter(function (f) {\n    return f === 'root_file';\n  });\n\n  if (newFileCalls.length === 0) {\n    console.log('FAILURE: Did not attempt to write new file (Did not split?)');\n  } else if (oldFileCalls.length > 0) {\n    console.log(\n      'FAILURE: Old file was written despite new file failure! DATA LOSS RISK.',\n    );\n    console.log('Writes:', putCalls);\n  } else {\n    console.log(\n      'SUCCESS: Old file was NOT written after new file failure. Data is safe.',\n    );\n  }\n});\n"
  },
  {
    "path": "test/panic/s2s-all-delayed-peer-add.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 2,\n\tbrowsers: 0,\n\tdir: __dirname,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\n//var servers = clients.filter('Node.js');\nvar servers = clients;\nvar alice = servers.pluck(1);\nvar bob = clients.excluding(alice).pluck(1);\n\ndescribe(\"Sync all data from one server to another one added as peer after initialisation!\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"Alice GUN has spawned!\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\tglobal.ALICE = true;\n\t\t\ttry{ require('fs').unlinkSync(env.i+'alldata') }catch(e){}\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar Gun = require(env.config.dir + '/../../');\n\n\t\t\tvar peers = [], i = env.config.servers;\n\t\t\tvar gun = Gun({file: env.i+'alldata', peers: peers, web: server});\n\n\t\t\tgun.get('a1').put({a:1});\n\t\t\tgun.get('b2').put({b:2});\n\t\t\tgun.get('c3').put({c:3});\n\t\t\tgun.get('d4').put({d:4});\n\n\t\t\tserver.listen(port, function(){\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t},1000);\n\t\t\t});\n\t\t}, {i: 1, config: config});\n\t});\n\n\tit(\"Bob GUN has spawned!\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'alldata') }catch(e){}\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar Gun = require(env.config.dir + '/../../');\n\n\t\t\t// Initialise gun with no peers\n\t\t\tvar peers = [];\n\t\t\tvar gun = Gun({file: env.i+'alldata', peers: peers, web: server});\n\n\t\t\tserver.listen(port);\n\t\t\tconsole.log(\"IGNORE 'invalid' WARNINGS!\");\n\t\t\tgun.on('out', {'#': 'loadthemall', get: {'#': {'*': ''}}});\n\n\t\t\t// Add the other server as a peer\n\t\t\tvar i = env.config.servers;\n\t\t\twhile(i--){\n\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\tgun.opt({peers: peers});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\ttest.done();\n\t\t\t}, 2000);\n\t\t}, {i: 2, config: config});\n\t});\n\n\n\tit(\"Bob checked his file!\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\tvar raw = require('fs').readFileSync(env.i+'alldata');\n\t\t\tvar json = JSON.parse(raw);\n\t\t\tvar graph = json.graph;\n\t\t\tconsole.log(\"Bob's graph on disk:\", json);\n\n\t\t\tif(!graph.a1 || graph.a1.a !== 1){\n\t\t\t\tthrow \"a1 was not synced!\";\n\t\t\t}\n\t\t\tif(!graph.b2 || graph.b2.b !== 2){\n\t\t\t\tthrow \"b2 was not synced!\";\n\t\t\t}\n\t\t\tif(!graph.c3 || graph.c3.c !== 3){\n\t\t\t\tthrow \"c3 was not synced!\";\n\t\t\t}\n\t\t\tif(!graph.d4 || graph.d4.d !== 4){\n\t\t\t\tthrow \"b4 was not synced!\";\n\t\t\t}\n\n\t\t\ttest.done();\n\t\t}, {i: 2, config: config});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "test/panic/s2s-all.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 2,\n\tbrowsers: 0,\n\tdir: __dirname,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar alice = servers.pluck(1);\nvar bob = clients.excluding(alice).pluck(1);\n\ndescribe(\"Sync all data from one server to another!\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"Alice GUN has spawned!\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\tglobal.ALICE = true;\n\t\t\ttry{ require('fs').unlinkSync(env.i+'alldata') }catch(e){}\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar Gun = require(env.config.dir + '/../../');\n\n\t\t\tvar peers = [], i = env.config.servers;\n\t\t\tvar gun = Gun({file: env.i+'alldata', peers: peers, web: server});\n\n\t\t\tgun.get('a1').put({a:1});\n\t\t\tgun.get('b2').put({b:2});\n\t\t\tgun.get('c3').put({c:3});\n\t\t\tgun.get('d4').put({d:4});\n\n\t\t\tserver.listen(port, function(){\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t},1000);\n\t\t\t});\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(\"Bob GUN has spawned!\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'alldata') }catch(e){}\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar Gun = require(env.config.dir + '/../../');\n\t\t\tvar peers = [], i = env.config.servers;\n\t\t\twhile(i--){\n\t\t\t\tvar tmp = (env.config.port + (i + 1));\n\t\t\t\tif(port != tmp){ // ignore ourselves\n\t\t\t\t\tpeers.push('http://'+ env.config.IP + ':' + tmp + '/gun');\n\t\t\t\t}\n\t\t\t}\n\t\t\tconsole.log(port, \" connect to \", peers);\n\t\t\tvar gun = Gun({file: env.i+'alldata', peers: peers, web: server});\n\n\t\t\tserver.listen(port);\n\t\t\tconsole.log(\"IGNORE 'invalid' WARNINGS!\");\n\t\t\tgun.on('out', {'#': 'loadthemall', get: {'#': {'*': ''}}});\n\t\t\t\n\t\t\tsetTimeout(function(){\n\t\t\t\ttest.done();\n\t\t\t}, 2000);\n\t\t}, {i: 2, config: config}); \n\t});\n\n\tit(\"Bob checked his file!\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\tvar raw = require('fs').readFileSync(env.i+'alldata');\n\t\t\tvar json = JSON.parse(raw);\n\t\t\tvar graph = json;\n\t\t\tconsole.log(\"Bob's graph on disk:\", json);\n\n\t\t\tif(!graph.a1 || graph.a1.a !== 1){\n\t\t\t\tthrow \"a1 was not synced!\";\n\t\t\t}\n\t\t\tif(!graph.b2 || graph.b2.b !== 2){\n\t\t\t\tthrow \"b2 was not synced!\";\n\t\t\t}\n\t\t\tif(!graph.c3 || graph.c3.c !== 3){\n\t\t\t\tthrow \"c3 was not synced!\";\n\t\t\t}\n\t\t\tif(!graph.d4 || graph.d4.d !== 4){\n\t\t\t\tthrow \"b4 was not synced!\";\n\t\t\t}\n\n\t\t\ttest.done();\n\t\t}, {i: 2, config: config}); \n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/scale.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\teach: 2500,\n\tburst: 1, // do not go below 1!\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/sea.js': __dirname + '/../../sea.js'\n\t}\n}\n\nvar fs = require('fs');\nvar server = require('https').createServer({\n\tkey: fs.readFileSync(__dirname+'/../https/server.key'),\n\tcert: fs.readFileSync(__dirname+'/../https/server.crt'),\n\tca: fs.readFileSync(__dirname+'/../https/ca.crt'),\n\trequestCert: true,\n\trejectUnauthorized: false\n});\n\nvar panic = require('panic-server');\npanic.server(server).on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'https://' + config.IP + ':' + config.port\n});\n\n// Now lets divide our clients into \"servers\" and \"browsers\".\nvar servers = clients.filter('Node.js');\nvar browsers = clients.excluding(servers);\n\n// Sweet! Now we can start the tests.\n// PANIC works with Mocha and other testing libraries!\n// So it is easy to use PANIC.\n\ndescribe(\"Stress test GUN with SEA users causing PANIC!\", function(){\n\tthis.timeout(10 * 60 * 1000);\n\t\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){ console.log(\"!!! WARNING !!!! MUST MANUALLY REMOVE OLD DATA!!!!, e\") }\n\t\t\t\tvar purl = 'https://'+env.config.IP+':'+env.config.port;\n\t\t\t\trequire('gun/test/https/test')(env.config.port + env.i, env.i+'data', function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t}, function(file){\n\t\t\t\t\tfile = file.toString();\n\t\t\t\t\tif(0 >= file.indexOf('<script src=\"/gun.js\"></script>')){ return }\n\t\t\t\t\tfile = file.replace('<script src=\"/gun.js\"></script>',\n\t\t\t\t\t\t\t\"<script src='\"+purl+\"/panic.js'></script><script>panic.server('\"+purl+\"')</script><script src='/gun.js'></script><script>localStorage.clear();sessionStorage.clear();</script>\");\n\t\t\t\t\treturn file;\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\tconsole.log(\"PLEASE OPEN https://\"+ config.IP +\":\"+ (config.port+1) +\"/contact/index.html IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Use UI to create user.\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\tlocalStorage.clear();sessionStorage.clear();\n\t\t\t\t$('#sign').find('input').first().val(env.id);\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t$('#sign').find('input').last().val('pass'+env.id+'phrase');\n\t\t\t\t},750 * 1);\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t$('#sign').find('button').last().trigger('click');\n\t\t\t\t},750 * 2);\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tc.tell(\"Wait until we are logged in...\");\n\t\t\t\t\ttest.done();\n\t\t\t\t},750 * 3);\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Load user UI once logged in.\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\tsetTimeout(function waitlogin(){\n\t\t\t\t\tconsole.log(user._.pub);\n\t\t\t\t\tif(!user._.pub){ return setTimeout(waitlogin, 500) }\n\t\t\t\t\ttest.done();\n\t\t\t\t}, 750);\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Update user's name!\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tlocation.hash = 'person/' + user._.pub;\n\t\t\t\t\tvar $name = $('#person').find('h2').first(), t = 250;\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$name.text(env.id.slice(0,1));\n\t\t\t\t\t\t$name.trigger('keyup');\n\t\t\t\t\t},t * 1);\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$name.text(env.id.slice(0,2));\n\t\t\t\t\t\t$name.trigger('keyup');\n\t\t\t\t\t},t * 2);\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$name.text(env.id.slice(0,3));\n\t\t\t\t\t\t$name.trigger('keyup');\n\t\t\t\t\t},t * 3);\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$name.text(env.id.slice(0,4));\n\t\t\t\t\t\t$name.trigger('keyup');\n\t\t\t\t\t},t * 4);\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t$name.text(env.id.slice(0,5));\n\t\t\t\t\t\t$name.trigger('keyup');\n\t\t\t\t\t},t * 5);\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\tlocation.hash = 'people';\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t}, 2000);\n\t\t\t\t}, 3000 * env.i);\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Reset\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tlocalStorage.clear();sessionStorage.clear();\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\tlocation.hash = '#sign';\n\t\t\t\t\tlocation.reload();\n\t\t\t\t}, 9000);\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\t/* MODEL TEST\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// code here\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\t*/\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t}, 2000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/set.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/cryptomodules.js': __dirname + '/../../lib/cryptomodules.js',\n\t\t'/sea.js': __dirname + '/../../sea.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = servers.pluck(1);\nvar spawn = servers.excluding(server).pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\nvar again = {};\n\ndescribe(\"Make sure SEA syncs correctly\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun = require('gun');\n\t\t\tvar gun = Gun({file: env.i+'data', web: server});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load SEA!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\t//console.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\t/*load('cryptomodules.js', function(){\n\t\t\t\t\tload('sea.js', function(){\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});\n\t\t\t\t});*/\n\t\t\t\ttest.done();\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.gun = gun;\n\t\t\t\tvar user = window.user = gun.get('pub/alice');\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Create Alice\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tuser.put({pub: 'alice'}, function(ack){\n\t\t\t\tif(ack.err){ return }\n\t\t\t\tconsole.log(\"write...\");\n\t\t\t\tuser.get('who').get('said').set({\n\t\t\t\t\twhat: \"Hello world!\"\n\t\t\t\t}, function(ack){\n\t\t\t\t\tif(ack.err){ return }\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Have Bob listen\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.count = [];\n\t\t\tuser.get('who').get('said').map().val(function(data){\n\t\t\t\tconsole.log(\"read...\", data);\n\t\t\t\twindow.count.push(data);\n\t\t\t\tif(window.count.length - 1){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Alice reloading.\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tlocation.reload();\n\t\t});\n\t});\n\n\tit(\"Got Alice.\", function(){\n\t\tagain.alice = browsers.excluding(new panic.ClientList([alice, bob])).pluck(1);\n\t\treturn again.alice.atLeast(1);\n\t});\n\n\tit(\"Alice reloaded.\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\twindow.gun = gun;\n\t\t\tvar user = window.user = gun.get('pub/alice');\n\t\t}, {i: 1, config: config})\n\t});\n\n\tit(\"Alice write.\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"write...\");\n\t\t\tuser.get('who').get('said').set({\n\t\t\t\twhat: \"AAA\"\n\t\t\t}, function(ack){\n\t\t\t\tif(ack.err){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Bob got\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(window.count);\n\t\t\tsetTimeout(function(){\n\t\t\t\tif('AAA' === window.count[1].what){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t}, 100);\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/shocknet.js",
    "content": "//before run: npm install && cd node_modules && ln -s ../ gun\n//run: npm test test/panic/gun-shocknet\nvar config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 4,\n\tbrowsers: 0,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js'\n\t},\n\tnames:['alice','bob'],\n\tkeys:{\n\t\tPROFILE:'Profile',\n\t\tDISPLAY_NAME:'displayName',\n\t\tCURRENT_HANDSHAKE_ADDRESS:'currentHandshakeAddress',\n\t\tHANDSHAKE_NODES:'handshakeNodes',\n\t\tCURRENT_ORDER_ADDRESS:'currentOrderAddress',\n\t\tBIO:'bio',\n\t\tUSER_TO_INCOMING:'userToIncoming',\n\t\tRECIPIENT_TO_OUTGOING:'recipientToOutgoing',\n\t\tUSER_TO_LAST_REQUEST_SENT:'USER_TO_LAST_REQUEST_SENT',\n\t\tOUTGOINGS:'outgoings',\n\t\tMESSAGES:'messages',\n\t\tSTORED_REQS:'storedReqs',\n\n\t},\n\tstoppers:{\n\t}\n}\nvar testData = Array(config.servers-2).fill()\nconst rands = length => {\n\tvar result           = '';\n\tvar characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\tvar charactersLength = characters.length;\n\tfor ( var i = 0; i < length; i++ ) {\n\t   result += characters.charAt(Math.floor(Math.random() * charactersLength));\n\t}\n\treturn result;\n }\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar peer1 = servers.pluck(1);\nvar peer2 = servers.excluding(peer1).pluck(1);\nvar peerClients = new panic.ClientList([peer1, peer2])\nvar serverClients = servers.excluding(new panic.ClientList([peer1, peer2]))\n//var browsers = clients.excluding(servers);\nvar alice = serverClients.pluck(1);\nvar bob = serverClients.excluding(alice).pluck(1);\nvar again = {};\n\ndescribe(\"Shocknet Test!\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\t\n\tit(\"Server Peer initialized gun!\",function(){\n\t\tvar tests = [], i = 0;\n\t\tpeerClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tvar env = test.props;\n\t\t\t\ttest.async();\n\t\t\t\ttry{ require('fs').unlinkSync((3+env.i)+'data') }catch(e){}\n\t\t\t\ttry{ require('fs').unlinkSync((env.i+1+3)+'data') }catch(e){}\n\t\t\t\ttry{ require('gun/lib/fsrm')((3+env.i)+'data') }catch(e){}\n\t\t\t\ttry{ require('gun/lib/fsrm')((env.i+1+3)+'data') }catch(e){}\n\t\t\t\tvar port = env.config.port + 3+env.i;\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ (3+env.i) +\"!\");\n\t\t\t\t});\n\t\t\t\tconst peerPort = env.i === 1 ? 5 : 4\n\t\t\t\tconst peerAddr = 'http://'+ env.config.IP + ':' + (env.config.port+peerPort) + '/gun'\n\t\t\t\tvar Gun = require('gun');\n\t\t\t\tvar gun = Gun({file: (3+env.i)+'data', web: server,peers:[peerAddr],axe:false});\n\t\t\t\tconsole.log('\\x1b[32m',` I am peer #${env.i}, I am listening on port ${port} and connecting to ${peerAddr}`,'\\x1b[0m')\n\t\t\t\tserver.listen(port, function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t})\n\n\tit(\"Server Clients initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t//localStorage.clear();\n\t\t\t\tglobal.rands = length => {\n\t\t\t\t\tvar result           = '';\n\t\t\t\t\tvar characters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\t\t\t\t\tvar charactersLength = characters.length;\n\t\t\t\t\tfor ( var i = 0; i < length; i++ ) {\n\t\t\t\t\t   result += characters.charAt(Math.floor(Math.random() * charactersLength));\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t\tvar env = test.props;\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}\n\t\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\ttry{ require('gun/lib/fsrm')((env.i+1)+'data') }catch(e){}\n\t\t\t\tvar Gun = require('gun');\n\t\t\t\tconst peerAddr = 'http://'+ env.config.IP + ':' + (env.config.port + 3 + env.i) + '/gun'\n\t\t\t\tvar gun = Gun({\n\t\t\t\t\tpeers:[peerAddr],\n\t\t\t\t\tfile:env.i+'data',\n\t\t\t\t\taxe:false\n\t\t\t\t\t\n\t\t\t\t});\n\t\t\t\tconsole.log('\\x1b[32m',` I am client #${env.i}, I am connecting to ${peerAddr}`,'\\x1b[0m')\n\t\t\t\tglobal.gun = gun;\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Server Clients auth with gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\trequire('gun/lib/open.js')\n\t\t\t\trequire('gun/lib/load.js')\n\t\t\t\t//localStorage.clear();\n\t\t\t\tvar env = test.props;\n\t\t\t\t//try{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\t\t//try{ require('gun/lib/fsrm')((env.i+1)+'data') }catch(e){}\n\t\t\t\tconst user = global.gun.user()\n\t\t\t\tconst alias = env.config.names[env.i-1] + rands(4)\n\t\t\t\tconst pass = rands(8)\n\t\t\t\t\n\t\t\t\t//return new Promise((res,rej) => {\n\t\t\t\t\tuser.create(alias,pass,ack => {\n\t\t\t\t\t\n\t\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t\t//rej(ack.err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tuser.auth(alias,pass,ack1 =>{\n\t\t\t\t\t\t\t\tif(ack1.err){\n\t\t\t\t\t\t\t\t\ttest.fail(ack1.err)\n\t\t\t\t\t\t\t\t\t//rej(ack1.err)\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tglobal.alias = alias\n\t\t\t\t\t\t\t\t\tglobal.pass = pass\n\t\t\t\t\t\t\t\t\tglobal.user = user\n\t\t\t\t\t\t\t\t\tconsole.log(env.i,alias,pass)\n\t\t\t\t\t\t\t\t\t//done()\n\t\t\t\t\t\t\t\t\tdone({i:env.i,pub:user.is.pub,alias:alias})\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t//})\n\t\t\t}, {i: i += 1, config: config}).then(res => {\n\t\t\t\ttestData[res.i-1] = res\n\t\t\t})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Server Clients generating SEA secret!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(async function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tvar env = test.props;\n\t\t\t\tconst SEA = require('gun/sea')\n\t\t\t\tconst user = global.user\n\t\t\t\treturn SEA.secret(user._.sea.epub,user._.sea)\n\t\t\t\t\t.then(mySecret => {\n\t\t\t\t\t\tglobal.SEA = SEA \n\t\t\t\t\t\tglobal.mySecret = mySecret\n\t\t\t\t\t\tdone()\n\t\t\t\t\t})\n\t\t\t\t\n\t\t\t\t\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Server Clients set display name!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar keys = env.config.keys\n\t\t\t\tglobal.user\n\t\t\t\t\t.get(keys.PROFILE)\n\t\t\t\t\t.get(keys.DISPLAY_NAME)\n\t\t\t\t\t.put(global.alias,ack =>{\n\t\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\t\tconsole.log(env.i,ack)\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Reading alice display name using .on !\",function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {pub} = test.props\n\t\t\tconst {keys} = test.props.config\n\t\t\tglobal.gun\n\t\t\t\t.user(pub)\n\t\t\t\t.get(keys.PROFILE)\n\t\t\t\t.get(keys.DISPLAY_NAME)\n\t\t\t\t.on(dn => {\n\t\t\t\t\tif(!dn.startsWith('alice')){\n\t\t\t\t\t\ttest.fail(`display Name > ${dn}`)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(dn)\n\t\t\t\t\t\tdone()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},{pub: testData[0].pub, config: config})\n\t})\n\t\n\tit(\"Reading bob display name using .once !\",function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {pub} = test.props\n\t\t\tconst {keys} = test.props.config\n\t\t\tglobal.gun\n\t\t\t\t.user(pub)\n\t\t\t\t.get(keys.PROFILE)\n\t\t\t\t.get(keys.DISPLAY_NAME)\n\t\t\t\t.once(dn => {\n\t\t\t\t\tif(!dn.startsWith('bob')){\n\t\t\t\t\t\ttest.fail(`display Name > ${dn}`)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(dn)\n\t\t\t\t\t\tdone()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},{pub: testData[1].pub, config: config})\n\t})\n\tit(\"Reading bob display name using .then !\",function(){\n\t\treturn alice.run(async function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {pub} = test.props\n\t\t\tconst {keys} = test.props.config\n\t\t\tconst dn = await global.gun\n\t\t\t\t.user(pub)\n\t\t\t\t.get(keys.PROFILE)\n\t\t\t\t.get(keys.DISPLAY_NAME)\n\t\t\t\t.then()\n\t\t\tif(!dn.startsWith('bob')){\n\t\t\t\ttest.fail(`display Name > ${dn}`)\n\t\t\t} else {\n\t\t\t\tconsole.log(dn)\n\t\t\t\tdone()\n\t\t\t}\n\t\t},{pub: testData[1].pub, config: config})\n\t})\n\n\tit(\"Server Clients generate handshake node!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar keys = env.config.keys\n\t\t\t\tvar address = rands(24)\n\t\t\t\tglobal.user\n\t\t\t\t\t.get(keys.CURRENT_HANDSHAKE_ADDRESS)\n\t\t\t\t\t.put(address,ack =>{\n\t\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tglobal.user\n\t\t\t\t\t\t\t\t.get(keys.HANDSHAKE_NODES)\n\t\t\t\t\t\t\t\t.get(address)\n\t\t\t\t\t\t\t\t.put({ unused: 0 },ack1 =>{\n\t\t\t\t\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\tit(\"Server Clients generate order address!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar keys = env.config.keys\n\t\t\t\tvar address = rands(24)\n\t\t\t\tglobal.user\n\t\t\t\t\t.get(keys.CURRENT_ORDER_ADDRESS)\n\t\t\t\t\t.put(address,ack => {\n\t\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Server Clients set bio!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props;\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst name = env.config.names[env.i-1]\n\t\t\t\tconst bio = `Hi my name is ${name}`\n\t\t\t\tglobal.user\n\t\t\t\t\t.get(keys.BIO)\n\t\t\t\t\t.put(bio,ack => {\n\t\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tglobal.user\n\t\t\t\t\t\t\t\t.get(keys.PROFILE)\n\t\t\t\t\t\t\t\t.get(keys.BIO)\n\t\t\t\t\t\t\t\t.put(bio,ack => {\n\t\t\t\t\t\t\t\t\tif(ack.err){\n\t\t\t\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\n\tit(\"Server Clients registering helpers\",function(){\n\t\tvar tests = [], i = 0;\n\t\tserverClients.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tconst env = test.props;\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tglobal.pubToEpub = async (pub,fail) =>{\n\t\t\t\t\tconst epub = await global.gun\n\t\t\t\t\t\t.user(pub)\n\t\t\t\t\t\t.get('epub')\n\t\t\t\t\t\t.then()\n\t\t\t\t\tif(typeof epub === 'string'){\n\t\t\t\t\t\treturn epub\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfail(`Expected epub ti be string found ${typeof epub}`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tglobal.successfulHandshakeAlreadyExists = async pub =>{\n\t\t\t\t\tconst {user} = global\n\t\t\t\t\tconst maybeIncomingID = await user\n\t\t\t\t\t\t.get(keys.USER_TO_INCOMING)\n\t\t\t\t\t\t.get(pub)\n\t\t\t\t\t\t.then()\n\t\t\t\t\tconst maybeOutgoingID = await user\n\t\t\t\t\t\t.get(keys.RECIPIENT_TO_OUTGOING)\n\t\t\t\t\t\t.get(pub)\n\t\t\t\t\t\t.then()\n\t\t\t\t\treturn typeof maybeIncomingID === 'string' && typeof maybeOutgoingID === 'string'\n\t\t\t\t}\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t})\n\tvar handshakeRequestID\n\tconst clenUp = (name,testClient,data)=>{\n\t\tit(`Sending handshake request to ${name} 1: cleanup 1:USER_TO_INCOMING !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\n\t\t\t\tglobal.hsData = {}\n\n\t\t\t\tuser\n\t\t\t\t\t.get(keys.USER_TO_INCOMING)\n\t\t\t\t\t.get(pub)\n\t\t\t\t\t.put(null, ack => {\n\t\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`Sending handshake request to ${name} 1: cleanup 2:RECIPIENT_TO_OUTGOING !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tuser\n\t\t\t\t\t.get(keys.RECIPIENT_TO_OUTGOING)\n\t\t\t\t\t.get(pub)\n\t\t\t\t\t.put(null, ack => {\n\t\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`Sending handshake request to ${name} 1: cleanup 3:USER_TO_LAST_REQUEST_SENT !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tuser\n\t\t\t\t\t.get(keys.USER_TO_LAST_REQUEST_SENT)\n\t\t\t\t\t.get(pub)\n\t\t\t\t\t.put(null, ack => {\n\t\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`Sending handshake request to ${name} 1: cleanup 4:recipientToOutgoingID !`,function(){\n\t\t\treturn testClient.run(async function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst maybeEncryptedOutgoingID = await global.user\n\t\t\t\t\t.get(keys.RECIPIENT_TO_OUTGOING)\n\t\t\t\t\t.get(pub)\n\t\t\t\t\t.then()\n\t\t\t\tif(maybeEncryptedOutgoingID === 'string'){\n\t\t\t\t\t\t\n\t\t\t\t\tglobal.hsData.maybeEncryptedOutgoingID = maybeEncryptedOutgoingID\n\t\t\t\t\t/*global.SEA.decrypt(maybeEncryptedOutgoingID,global.mySecret)\n\t\t\t\t\t\t.then(outgoingID => outgoingID ? res(outgoingID) : rej(`expected outgoingID to be exist`))*/\n\t\t\t\t} else {\n\t\t\t\t\tglobal.hsData.outgoingID = maybeEncryptedOutgoingID\n\t\t\t\t}\n\t\t\t\tdone()\n\t\t\t\t\n\t\t\t},data)\n\t\t})\n\t\tit(`Sending handshake request to ${name} 1: cleanup 5:decrypt recipientToOutgoingID !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst {maybeEncryptedOutgoingID} = global.hsData\n\t\t\t\t\n\t\t\t\tif(maybeEncryptedOutgoingID === 'string'){\n\t\t\t\t\tglobal.hsData.maybeEncryptedOutgoingID = maybeEncryptedOutgoingID\n\t\t\t\t\tglobal.SEA.decrypt(maybeEncryptedOutgoingID,global.mySecret)\n\t\t\t\t\t\t.then(outgoingID => {\n\t\t\t\t\t\t\tif(outgoingID){\n\t\t\t\t\t\t\t\tglobal.hsData.outgoingID = outgoingID\n\t\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\ttest.fail(`expected outgoingID to exist`)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tdone()\n\t\t\t\t}\n\t\t\t},data)\n\t\t})\n\t\tit(`Sending handshake request to ${name} 1: cleanup 6:OUTGOINGS !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst {outgoingID} = global.hsData\n\t\t\t\t\n\t\t\t\tif(outgoingID){\n\t\t\t\t\tuser\n\t\t\t\t\t\t.get(keys.OUTGOINGS)\n\t\t\t\t\t\t.get(outGoingID)\n\t\t\t\t\t\t.put(null, ack => {\n\t\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(\"ok\")\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tdone()\n\t\t\t\t}\n\t\t\t\t\n\t\t\t},data)\n\t\t})\n\t}\n\tclenUp(\"bob\",alice,{testData, config: config,index:1})\n\n\tit(\"Sending handshake request to bob 2: ourSecret!\",function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {pub} = test.props\n\t\t\tconst {keys} = test.props.config\n\t\t\tconst {\n\t\t\t\tuser,\n\t\t\t\tpubToEpub,\n\t\t\t\tSEA,\n\t\t\t} = global\n\t\t\tpubToEpub(pub,test.fail)\n\t\t\t.then(bobEpub =>{\n\t\t\t\tSEA.secret(bobEpub,user._.sea)\n\t\t\t\t.then(ourSecret =>{\n\t\t\t\t\tglobal.hsData.ourSecret = ourSecret\n\t\t\t\t\tglobal.hsData.otherEpub = bobEpub\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t\t})\n\t\t\t\n\n\t\t},{pub: testData[1].pub, config: config})\n\t})\n\tit(\"Sending handshake request to bob 3: check if handshake already done!\",function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {pub} = test.props\n\t\t\tconst {keys} = test.props.config\n\t\t\tconst {successfulHandshakeAlreadyExists} = global\n\t\t\treturn successfulHandshakeAlreadyExists(pub)\n\t\t\t.then(alreadyHandshaked => {\n\t\t\t\tif(alreadyHandshaked){\n\t\t\t\t\ttest.fail(\"handshake already exists\")\n\t\t\t\t} else {\n\t\t\t\t\tdone()\n\t\t\t\t}\n\t\t\t})\n\t\t\t\n\t\t},{pub: testData[1].pub, config: config})\n\t})\n\n\tit(\"Sending handshake request to bob 4: getting handshake address!\",function(){\n\t\treturn alice.run(async function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {pub} = test.props\n\t\t\tconst {keys} = test.props.config\n\t\t\tconst currentHandshakeAddress = await gun\n\t\t\t\t.user(pub)\n\t\t\t\t.get(keys.CURRENT_HANDSHAKE_ADDRESS)\n\t\t\t\t.then()\n\t\t\tif(typeof currentHandshakeAddress !== 'string'){\n\t\t\t\ttest.fail(\"expected current handshake address to be string\")\n\t\t\t} else {\n\t\t\t\tglobal.hsData.currentHandshakeAddress = currentHandshakeAddress\n\t\t\t\tdone()\n\t\t\t}\n\t\t\t\n\t\t},{pub: testData[1].pub, config: config})\n\t})\n\n\tit(\"Sending handshake request to bob 5: check if already sent request!\",function(){\n\t\treturn alice.run(async function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {pub} = test.props\n\t\t\tconst {keys} = test.props.config\n\t\t\tconst {currentHandshakeAddress} = global.hsData\n\t\t\tconst maybeLastRequestIDSentToUser = await user\n\t\t\t\t.get(keys.USER_TO_LAST_REQUEST_SENT)\n\t\t\t\t.get(pub)\n\t\t\t\t.then()\n\t\t\tif(typeof maybeLastRequestIDSentToUser === 'string'){\n\t\t\t\tif (maybeLastRequestIDSentToUser.length < 5) {\n\t\t\t\t\ttest.fail(\"maybeLastRequestIDSentToUser.length < 5\")\n\t\t\t\t}\n\t\t\t\tconst lastRequestIDSentToUser = maybeLastRequestIDSentToUser\n\t\t\t\tconst hrInHandshakeNode = await gun\n\t\t\t\t\t.get(keys.HANDSHAKE_NODES)\n\t\t\t\t\t.get(currentHandshakeAddress)\n\t\t\t\t\t.get(lastRequestIDSentToUser)\n\t\t\t\t\t.then()\n\t\t\t\tif(typeof hrInHandshakeNode !== 'undefined'){\n\t\t\t\t\ttest.fail(\"request already sent\")\n\t\t\t\t} else {\n\t\t\t\t\tdone()\n\t\t\t\t}\n\t\t\t\t\n\t\t\t} else {\n\t\t\t\tdone()\n\t\t\t}\n\t\t},{pub: testData[1].pub, config: config})\n\t})\n\tconst createOutgoingFeed =(name,testClient,data)=>{\n\t\t\n\t\tit(`${name}: create outgoing feed 1:encryptedForMeRecipientPub !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst {mySecret,SEA} = global\n\t\t\t\tSEA.encrypt(pub, mySecret)\n\t\t\t\t.then(encryptedForMeRecipientPub => {\n\t\t\t\t\tglobal.hsData.encryptedForMeRecipientPub = encryptedForMeRecipientPub\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 2:ourSecret !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst {user,SEA} = global\n\t\t\t\tconst {otherEpub} = global.hsData\n\t\t\t\tSEA.secret(\n\t\t\t\t\totherEpub,\n\t\t\t\t\tuser._.sea\n\t\t\t\t).then(ourSecret => {\n\t\t\t\t\tglobal.hsData.ourSecret = ourSecret\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 2.8:maybeOutgoingID !`,function(){\n\t\t\treturn testClient.run(async function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst maybeEncryptedOutgoingID = await global.user\n\t\t\t\t\t.get(keys.RECIPIENT_TO_OUTGOING)\n\t\t\t\t\t.get(pub)\n\t\t\t\t\t.then()\n\t\t\t\tif(maybeEncryptedOutgoingID === 'string'){\n\t\t\t\t\t\t\n\t\t\t\t\tglobal.hsData.maybeEncryptedOutgoingID = maybeEncryptedOutgoingID\n\t\t\t\t\t/*global.SEA.decrypt(maybeEncryptedOutgoingID,global.mySecret)\n\t\t\t\t\t\t.then(outgoingID => outgoingID ? res(outgoingID) : rej(`expected outgoingID to be exist`))*/\n\t\t\t\t} else {\n\t\t\t\t\tglobal.hsData.maybeOutgoingID = maybeEncryptedOutgoingID\n\t\t\t\t}\n\t\t\t\tdone()\n\t\t\t\t\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 2.9:decrypt maybeOutgoingID !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst {maybeEncryptedOutgoingID} = global.hsData\n\t\t\t\t\n\t\t\t\tif(maybeEncryptedOutgoingID === 'string'){\n\t\t\t\t\tglobal.hsData.maybeEncryptedOutgoingID = maybeEncryptedOutgoingID\n\t\t\t\t\tglobal.SEA.decrypt(maybeEncryptedOutgoingID,global.mySecret)\n\t\t\t\t\t\t.then(outgoingID => {\n\t\t\t\t\t\t\tif(outgoingID){\n\t\t\t\t\t\t\t\tglobal.hsData.maybeOutgoingID = outgoingID\n\t\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\ttest.fail(`expected outgoingID to exist`)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tdone()\n\t\t\t\t}\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 3.1:newOutgoingFeedID !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst {maybeOutgoingID,encryptedForMeRecipientPub} = global.hsData\n\t\t\t\tif(typeof maybeOutgoingID === 'string'){\n\t\t\t\t\tdone()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst newPartialOutgoingFeed = {\n\t\t\t\t\twith: encryptedForMeRecipientPub\n\t\t\t\t}\n\t\t\t\tconst _outFeedNode = user\n\t\t\t\t\t.get(keys.OUTGOINGS)\n\t\t\t\t\t.set(newPartialOutgoingFeed, ack => {\n\t\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst newOutgoingFeedID = _outFeedNode._.get\n\t\t\t\t\t\t\tif (typeof newOutgoingFeedID !== 'string') {\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\ttest.fail('typeof newOutgoingFeedID !== \"string\"')\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tglobal.hsData.newOutgoingFeedID = newOutgoingFeedID\n\t\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 3.2:encryptedForUsInitialMessage !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst {mySecret,SEA} = global\n\t\t\t\tconst {ourSecret} = global.hsData\n\t\t\t\tSEA.encrypt(\"$$__SHOCKWALLET__INITIAL__MESSAGE\", ourSecret)\n\t\t\t\t.then(encryptedForUsInitialMessage => {\n\t\t\t\t\tglobal.hsData.encryptedForUsInitialMessage = encryptedForUsInitialMessage\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 3.3:initialMsg !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst {user,SEA} = global\n\t\t\t\tconst {maybeOutgoingID,newOutgoingFeedID,encryptedForUsInitialMessage} = global.hsData\n\t\t\t\tif(typeof maybeOutgoingID === 'string'){\n\t\t\t\t\tdone()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tconst initialMsg = {\n\t\t\t\t\tbody: encryptedForUsInitialMessage,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}//\"$$__SHOCKWALLET__INITIAL__MESSAGE\"\n\t\t\t\t\n\t\t\t\tuser\n\t\t\t\t\t.get(keys.OUTGOINGS)\n\t\t\t\t\t.get(newOutgoingFeedID)\n\t\t\t\t\t.get(keys.MESSAGES)\n\t\t\t\t\t.set(initialMsg, ack => {\n\t\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 3.4:encryptedForMeNewOutgoingFeedID !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst {mySecret,SEA} = global\n\t\t\t\tconst {maybeOutgoingID,newOutgoingFeedID} = global.hsData\n\t\t\t\tif(typeof maybeOutgoingID === 'string'){\n\t\t\t\t\tdone()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tSEA.encrypt(newOutgoingFeedID, mySecret)\n\t\t\t\t.then(encryptedForMeNewOutgoingFeedID => {\n\t\t\t\t\tglobal.hsData.encryptedForMeNewOutgoingFeedID = encryptedForMeNewOutgoingFeedID\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 3.5:save encryptedForMeNewOutgoingFeedID !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst {user} = global\n\t\t\t\tconst {maybeOutgoingID,encryptedForMeNewOutgoingFeedID} = global.hsData\n\t\t\t\tif(typeof maybeOutgoingID === 'string'){\n\t\t\t\t\tdone()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tuser\n\t\t\t\t\t.get(keys.RECIPIENT_TO_OUTGOING)\n\t\t\t\t\t.get(pub)\n\t\t\t\t\t.put(encryptedForMeNewOutgoingFeedID, ack => {\n\t\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdone()\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t},data)\n\t\t})\n\t\tit(`${name}: create outgoing feed 3.6:check OutgoingFeedID !`,function(){\n\t\t\treturn testClient.run(function(test){\n\t\t\t\tconst done = test.async()\n\t\t\t\tconst env = test.props\n\t\t\t\tconst keys = env.config.keys\n\t\t\t\tconst {index} = env\n\t\t\t\tconst {pub} = env.testData[index]\n\t\t\t\tconst {user} = global\n\t\t\t\tconst {maybeOutgoingID,newOutgoingFeedID} = global.hsData\n\t\t\t\t\n\t\t\t\tif(typeof maybeOutgoingID === 'string'){\n\t\t\t\t\tglobal.hsData.OutgoingFeedID = maybeOutgoingID\n\t\t\t\t\tdone()\n\t\t\t\t} else {\n\t\t\t\t\tconst outgoingFeedID = newOutgoingFeedID\n\t\t\t\t\tif (typeof outgoingFeedID === 'undefined') {\n\t\t\t\t\t\ttest.fail(\n\t\t\t\t\t\t\t'__createOutgoingFeed() -> typeof outgoingFeedID === \"undefined\"'\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (typeof outgoingFeedID !== 'string') {\n\t\t\t\t\t\ttest.fail(\n\t\t\t\t\t\t\t'__createOutgoingFeed() -> expected outgoingFeedID to be an string'\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (outgoingFeedID.length === 0) {\n\t\t\t\t\t\ttest.fail(\n\t\t\t\t\t\t\t'__createOutgoingFeed() -> expected outgoingFeedID to be a populated string.'\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\tglobal.hsData.outgoingFeedID = outgoingFeedID\n\t\t\t\t\tdone()\n\t\t\t\t}\n\t\t\t},data)\n\t\t})\n\t}\n\tcreateOutgoingFeed(\"Sending handshake request to bob 6\",alice,{testData, config: config,index:1})\n\tit(`Sending handshake request to bob 6: create outgoing feed 4:encryptedForUsOutgoingFeedID !`,function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {index} = env\n\t\t\tconst {pub} = env.testData[index]\n\t\t\tconst {SEA} = global\n\t\t\tconst {outgoingFeedID,ourSecret} = global.hsData\n\t\t\tSEA.encrypt(outgoingFeedID, ourSecret)\n\t\t\t\t.then(encryptedForUsOutgoingFeedID => {\n\t\t\t\t\t\n\t\t\t\t\tglobal.hsData.encryptedForUsOutgoingFeedID = encryptedForUsOutgoingFeedID\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t},{testData, config: config,index:1})\n\t})\n\tit(`Sending handshake request to bob 6: create outgoing feed 5:newHandshakeRequestID in gun !`,function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {index} = env\n\t\t\tconst {pub} = env.testData[index]\n\t\t\tconst {user,gun} = global\n\t\t\tconst {currentHandshakeAddress,encryptedForUsOutgoingFeedID} = global.hsData\n\t\t\tconst timestamp = Date.now()\n\t\t\tconst handshakeRequestData = {\n\t\t\t\tfrom: user.is.pub,\n\t\t\t\tresponse: encryptedForUsOutgoingFeedID,\n\t\t\t\ttimestamp\n\t\t\t}\n\t\t\tconst hr = gun\n\t\t\t\t.get(keys.HANDSHAKE_NODES)\n\t\t\t\t.get(currentHandshakeAddress)\n\t\t\t\t.set(handshakeRequestData, ack => {\n\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tglobal.hsData.newHandshakeRequestID = hr._.get\n\t\t\t\t\t\t\n\t\t\t\t\t\tglobal.hsData.timestamp = timestamp\n\t\t\t\t\t\tdone(hr._.get)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},{testData, config: config,index:1}).then(newHandshakeRequestID => handshakeRequestID=newHandshakeRequestID)\n\t})\n\tit(`Sending handshake request to bob 6: create outgoing feed 6:newHandshakeRequestID !`,function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {index} = env\n\t\t\tconst {pub} = env.testData[index]\n\t\t\tconst {user} = global\n\t\t\tconst {newHandshakeRequestID} = global.hsData\n\t\t\tuser\n\t\t\t\t.get(keys.USER_TO_LAST_REQUEST_SENT)\n\t\t\t\t.get(pub)\n\t\t\t\t.put(newHandshakeRequestID, ack => {\n\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t},{testData, config: config,index:1})\n\t})\n\tit(`Sending handshake request to bob 6: create outgoing feed 7:encrypt newHandshakeRequestID !`,function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {index} = env\n\t\t\tconst {pub} = env.testData[index]\n\t\t\tconst {SEA,mySecret} = global\n\t\t\tconst {newHandshakeRequestID} = global.hsData\n\t\t\tSEA.encrypt(newHandshakeRequestID,mySecret)\n\t\t\t.then(encryptedHandshakeRequestID =>{\n\t\t\t\tglobal.hsData.encryptedHandshakeRequestID = encryptedHandshakeRequestID\n\t\t\t\tdone()\n\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:1})\n\t})\n\tit(`Sending handshake request to bob 6: create outgoing feed 8:encrypt currentHandshakeAddress !`,function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {index} = env\n\t\t\tconst {pub} = env.testData[index]\n\t\t\tconst {SEA,mySecret} = global\n\t\t\tconst {currentHandshakeAddress} = global.hsData\n\t\t\tSEA.encrypt(currentHandshakeAddress,mySecret)\n\t\t\t.then(encryptedHandshakeAddress =>{\n\t\t\t\tglobal.hsData.encryptedHandshakeAddress = encryptedHandshakeAddress\n\t\t\t\tdone()\n\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:1})\n\t})\n\tit(`Sending handshake request to bob 6: create outgoing feed 9:storedReq !`,function(){\n\t\treturn alice.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {index} = env\n\t\t\tconst {pub} = env.testData[index]\n\t\t\tconst {SEA,mySecret} = global\n\t\t\tconst {\n\t\t\t\tencryptedHandshakeAddress,\n\t\t\t\tencryptedForMeRecipientPub,\n\t\t\t\tencryptedHandshakeRequestID,\n\t\t\t\ttimestamp\n\t\t\t} = global.hsData\n\t\t\tconst storedReq = {\n\t\t\t\tsentReqID: encryptedHandshakeRequestID,\n\t\t\t\trecipientPub: encryptedForMeRecipientPub,\n\t\t\t\thandshakeAddress: encryptedHandshakeAddress,\n\t\t\t\ttimestamp\n\t\t\t}\n\t\t\tuser\n\t\t\t\t.get(keys.STORED_REQS)\n\t\t\t\t.set(storedReq, ack => {\n\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:1})\n\t})\n\tit(`Accepting handshake request from alice 7: currentHandshakeAddress !`,function(){\n\t\treturn bob.run(async function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {user} = global\n\t\t\tglobal.hsData = {}\n\t\t\tconst currentHandshakeAddress = await user\n\t\t\t\t.get(keys.CURRENT_HANDSHAKE_ADDRESS)\n\t\t\t\t.then()\n\t\t\t\tif(typeof currentHandshakeAddress !== 'string'){\n\t\t\t\t\ttest.fail(\"expected currentHandshakeAddress to be string\")\n\t\t\t\t} else {\n\t\t\t\t\tglobal.hsData.currentHandshakeAddress = currentHandshakeAddress\n\t\t\t\t\tdone()\n\t\t\t\t}\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(`Accepting handshake request from alice 7: receivedReqs **using .load!`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {gun} = global\n\t\t\tconst {currentHandshakeAddress} = global.hsData\n\t\t\tgun\n\t\t\t\t.get(keys.HANDSHAKE_NODES)\n\t\t\t\t.get(currentHandshakeAddress)\n\t\t\t\t.open(receivedReqs =>{\n\t\t\t\t\tglobal.hsData.receivedReqs = receivedReqs\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(`Accepting handshake request from alice 7: extract request data`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst {handshakeRequestID} = env\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {gun} = global\n\t\t\tconst {receivedReqs} = global.hsData\n\t\t\tconst data = receivedReqs[handshakeRequestID]\n\t\t\tif(typeof data.from !== 'string'){\n\t\t\t\ttest.fail(`expected \"from\" to be string, found ${typeof data.from}`)\n\t\t\t}\n\t\t\tif(typeof data.response !== 'string'){\n\t\t\t\ttest.fail(`expected \"response\" to be string, found ${typeof data.response}`)\n\t\t\t}\n\t\t\tif(typeof data.timestamp !== 'number'){\n\t\t\t\ttest.fail(`expected \"timestamp\" to be string, found ${typeof data.timestamp}`)\n\t\t\t}\n\t\t\tglobal.hsData.handshakeRequestID = handshakeRequestID\n\t\t\tglobal.hsData.data = receivedReqs[handshakeRequestID]\n\t\t\tdone()\n\t\t\t\n\t\t},{testData, config: config,index:2,handshakeRequestID})\n\t})//handshakeRequestID\n\n\tit(`Accepting handshake request from alice 7: pub to Epub`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {pubToEpub} = global\n\t\t\tconst {data} = global.hsData\n\t\t\tpubToEpub(data.from,test.fail)\n\t\t\t.then(aliceEpub => {\n\t\t\t\tglobal.hsData.otherEpub = aliceEpub\n\t\t\t\tdone()\n\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(`Accepting handshake request from alice 7: our secret`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {SEA,user} = global\n\t\t\tconst {otherEpub} = global.hsData\n\t\t\tSEA.secret(otherEpub,user._.sea)\n\t\t\t\t.then(ourSecret =>{\n\t\t\t\t\tglobal.hsData.ourSecret = ourSecret\n\t\t\t\t\tdone()\n\t\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(`Accepting handshake request from alice 7: decrypt encryptedForUsIncomingID`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {SEA,user} = global\n\t\t\tconst {data,ourSecret} = global.hsData\n\t\t\tSEA.decrypt(data.response,ourSecret)\n\t\t\t\t.then(incomingID =>{\n\t\t\t\t\tif(typeof incomingID !== 'string'){\n\t\t\t\t\t\ttest.fail(`expected \"incomingID\" to be string, found ${typeof incomingID}`)\n\t\t\t\t\t}else {\n\t\t\t\t\t\tglobal.hsData.incomingID = incomingID\n\t\t\t\t\t\tdone()\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:0})\n\t})\n\tcreateOutgoingFeed(\"Accepting handshake request from alice 7\",bob,{testData, config: config,index:0})\n\tit(`Accepting handshake request from alice 7: encrypt encryptedForMeIncomingID`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {SEA,mySecret} = global\n\t\t\tconst {incomingID} = global.hsData\n\t\t\tSEA.encrypt(incomingID,mySecret)\n\t\t\t\t.then(encryptedForMeIncomingID =>{\n\t\t\t\t\tglobal.hsData.encryptedForMeIncomingID = encryptedForMeIncomingID\n\t\t\t\t\tdone()\n\t\t\t\t\t\n\t\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(`Accepting handshake request from alice 7: encryptedForMeIncomingID`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {user} = global\n\t\t\tconst {encryptedForMeIncomingID,data} = global.hsData\n\t\t\tuser\n\t\t\t\t.get(keys.USER_TO_INCOMING)\n\t\t\t\t.get(data.from)\n\t\t\t\t.put(encryptedForMeIncomingID, ack => {\n\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(`Accepting handshake request from alice 7: encrypt encryptedForUsOutgoingID`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {SEA} = global\n\t\t\tconst {ourSecret,outgoingFeedID} = global.hsData\n\t\t\tSEA.encrypt(outgoingFeedID,ourSecret)\n\t\t\t\t.then(encryptedForUsOutgoingID =>{\n\t\t\t\t\tglobal.hsData.encryptedForUsOutgoingID = encryptedForUsOutgoingID\n\t\t\t\t\tdone()\n\t\t\t\t\t\n\t\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(`Accepting handshake request from alice 7: encryptedForUsOutgoingID`,function(){\n\t\treturn bob.run(function(test){\n\t\t\tconst done = test.async()\n\t\t\tconst {gun} = global\n\t\t\tconst env = test.props\n\t\t\tconst keys = env.config.keys\n\t\t\tconst {\n\t\t\t\tencryptedForUsOutgoingID,\n\t\t\t\tcurrentHandshakeAddress,\n\t\t\t\thandshakeRequestID\n\t\t\t} = global.hsData\n\t\t\tconst data = {response:encryptedForUsOutgoingID}\n\t\t\tgun\n\t\t\t\t.get(keys.HANDSHAKE_NODES)\n\t\t\t\t.get(currentHandshakeAddress)\n\t\t\t\t.get(handshakeRequestID)\n\t\t\t\t.put(data,ack => {\n\t\t\t\t\tif (ack.err) {\n\t\t\t\t\t\ttest.fail(\"error fail ack:\"+JSON.stringify(ack.err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdone()\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\n\t\t},{testData, config: config,index:0})\n\t})\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/speak.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\teach: 250,\n\tburst: 1, // do not go below 1!\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/cryptomodules.js': __dirname + '/../../lib/cryptomodules.js',\n\t\t'/sea.js': __dirname + '/../../sea.js'\n\t}\n}\n\nvar fs = require('fs');\nvar server = require('https').createServer({\n\tkey: fs.readFileSync(__dirname+'/../https/server.key'),\n\tcert: fs.readFileSync(__dirname+'/../https/server.crt'),\n\tca: fs.readFileSync(__dirname+'/../https/ca.crt'),\n\trequestCert: true,\n\trejectUnauthorized: false\n});\n\nvar panic = require('panic-server');\npanic.server(server).on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'https://' + config.IP + ':' + config.port\n});\n\n// Now lets divide our clients into \"servers\" and \"browsers\".\nvar servers = clients.filter('Node.js');\nvar browsers = clients.excluding(servers);\n\n// Sweet! Now we can start the tests.\n// PANIC works with Mocha and other testing libraries!\n// So it is easy to use PANIC.\n\ndescribe(\"Stress test GUN with SEA users causing PANIC!\", function(){\n\tthis.timeout(10 * 60 * 1000);\n\t\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\t//setInterval(function(){ var u, t; u = process.memoryUsage().heapUsed; t = require('os').totalmem(); console.log((u/t).toFixed(2)) }, 1000)\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){ console.log(\"!!! WARNING !!!! MUST MANUALLY REMOVE OLD DATA!!!!, e\") }\n\t\t\t\tvar purl = 'https://'+env.config.IP+':'+env.config.port;\n\t\t\t\trequire('gun/test/https/test')(env.config.port + env.i, env.i+'data', function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t}, function(file){\n\t\t\t\t\tfile = file.toString();\n\t\t\t\t\tif(0 >= file.indexOf('<script src=\"/gun.js\"></script>')){ return }\n\t\t\t\t\tfile = file.replace('<script src=\"/gun.js\"></script>',\n\t\t\t\t\t\t\t\"<script src='\"+purl+\"/panic.js'></script><script>panic.server('\"+purl+\"')</script><script src='/gun.js'></script><script>localStorage.clear();sessionStorage.clear();</script>\");\n\t\t\t\t\treturn file;\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\tconsole.log(\"PLEASE OPEN https://\"+ config.IP +\":\"+ (config.port) +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load SEA!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\t//console.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\tload('sea.js', function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\t// Let us create a list of all the browsers IDs connected.\n\t\t// This will later let each browser check against every other browser.\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tvar env = window.env = test.props;\n\t\t\t\tvar peers = [], i = env.config.servers;\n\t\t\t\twhile(i--){\n\t\t\t\t\t// For the total number of servers listed in the configuration\n\t\t\t\t\t// Add their URL into an array.\n\t\t\t\t\tpeers.push('https://'+ env.config.IP + ':' + (env.config.port + (i + 1)) + '/gun');\n\t\t\t\t}\n\t\t\t\tvar gun = window.gun = Gun(peers);\n\t\t\t\tvar user = window.user = gun.user();\n\t\t\t\tvar go = window.go = {num: 0, total: 0, users: {}, pub: {}};\n\t\t\t\twindow.ID = env.id;\n\t\t\t\tgo.check = Gun.obj.map(env.ids, function(v,id,t){\n\t\t\t\t\t// for each browser ID\n\t\t\t\t\t// they will be saving X number of messages each.\n\t\t\t\t\tgo.users[id] = true; // set an outstanding flag to check against.\n\t\t\t\t\tvar i = env.config.each;\n\t\t\t\t\twhile(i--){\n\t\t\t\t\t\t// So add a deterministic key we can check against.\n\t\t\t\t\t\tt(id + (i + 1), 1);\n\t\t\t\t\t\t// And count up the total number of messages we expect for all.\n\t\t\t\t\t\tgo.total += 1;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tconsole.log(peers, go);\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"All users created!\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\n\t\t\t\tgun.on('secure', function(at){\n\t\t\t\t\t/* enforce some rules about shared app level data */\n\t\t\t\t\tif(!at.put || !at.put.users){ return }\n\t\t\t\t\tvar no;\n\t\t\t\t\tGun.node.is(at.put.users, function(val, key){\n\t\t\t\t\t\tGun.SEA.read(val, false, function(val){\n\t\t\t\t\t\t\tif('alias/'+key === Gun.val.link.is(val)){ return }\n\t\t\t\t\t\t\tno = true;\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif(no){ return no }\n\t\t\t\t\t});\n\t\t\t\t\tif(no){ return }\n\t\t\t\t\tthis.to.next(at);\n\t\t\t\t});\n\n\t\t\t\tvar unsafepassword = 'asdf'+ID;\n\t\t\t\tconsole.log(\"sign in and up:\", ID);\n\t\t\t\twindow.user.create(ID, unsafepassword, function(ack){\n\t\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\t\twindow.pub = ack.pub;\n\t\t\t\t\tgun.get('users').get(ID).put(gun.get('alias/'+ID));\n\t\t\t\t\tconsole.log(\"signed up\", ack.pub);\n\t\t\t\t\tconsole.debug.j = 1;\n\t\t\t\t\twindow.user.auth(ID, unsafepassword, function(ack){\n\t\t\t\t\t\tconsole.debug.j = 0;\n\t\t\t\t\t\tconsole.log(\"signed in\", ack);\n\t\t\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Start reading and sending messages!\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\n\t\t\t\tgun.get('users').map().map()\n\t\t\t\t\t.get('who').get('said').map().on(function(msg){\n\t\t\t\t\t\tcheck(msg);\n\t\t\t\t});\n\n\t\t\t\tvar said = user.get('who').get('said');\n\n\t\t\t\tfunction run(i){\n\n\t\t\t\t\tvar what = i +\"|||\"+ \"Hello world!\" +\"|||\"+ pub +\"|||\"+ ID;\n\t\t\t\t\tsaid.set({\n\t\t\t\t\t\twhat: what\n\t\t\t\t\t});/*, function(ack){\n\t\t\t\t\t\tif(ack.err){ return }\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});*/\n\n\t\t\t\t}\n\t\t\t\t/* TODO: sometimes sign in hangs */\n\t\t\t\tconsole.log(\"<<<<< START >>>>>\");\n\t\t\t\tvar i = 0, to = setInterval(function frame(a, b){\n\t\t\t\t\tif(!b && 2 <= (b = env.config.burst)){\n\t\t\t\t\t\twhile(--b){\n\t\t\t\t\t\t\tframe(i, true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif(env.config.each <= i){\n\t\t\t\t\t\tclearTimeout(to);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\trun(i += 1);\n\t\t\t\t}, env.config.wait || 1);\n\n\n\t\t\t\tvar col = $(\"<div>\").css({width: 250, position: 'relative', float: 'left', border: 'solid 1px black'}), cols = {};\n\t\t\t\tvar report = $(\"<div>\").css({position: 'fixed', top: 0, right: 0, background: 'white', padding: 10}).text(\" / \"+ go.total +\" Verified\").prependTo('body');\n\t\t\t\tvar reportc = $('<span>').text(0).prependTo(report);\n\t\t\t\tvar last = $(\"<div>\").text(\"Processing: \").css({border: \"solid 1px black\"}).appendTo(\"body\");\n\t\t\t\tlast = $(\"<span>\").text(\" \").appendTo(last);\n\n\t\t\t\tfunction check(data){\n\t\t\t\t\tdata = data.what.split(\"|||\");\n\t\t\t\t\tvar msg = {num: data[0], what: data[0] +' '+ data[1], who: data[2], id: data[3]};\n\t\t\t\t\tvar who;\n\t\t\t\t\tif(!go.pub[msg.who]){\n\t\t\t\t\t\tgo.pub[msg.who] = msg.id;\n\t\t\t\t\t\tgo.users[msg.id] = false;\n\t\t\t\t\t\t//who = cols[msg.id] = col.clone(true).appendTo('body');\n\t\t\t\t\t\t//who.prepend(\"<input value='\"+ msg.who +\"'>\");\n\t\t\t\t\t\t//who.prepend(\"<input value='\"+ msg.id +\"'>\");\n\t\t\t\t\t}\n\t\t\t\t\tif(!go.check[msg.id + msg.num]){\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tgo.check[msg.id + msg.num] = false;\n\t\t\t\t\tclearTimeout(end.to); end.to = setTimeout(end, 9);\n\t\t\t\t\treportc.text(++go.num);\n\t\t\t\t\tlast.text(msg.what);\n\t\t\t\t\t//who = cols[msg.id];\n\t\t\t\t\t//$(\"<div>\").css({border: 'solid 1px blue'}).text(msg.what).appendTo(who);\n\t\t\t\t}\n\n\t\t\t\tfunction end(){\n\t\t\t\t\tvar wait = Gun.obj.map(go.users, function(v){ if(v){ return true }});\n\t\t\t\t\tif(wait){ return }\n\t\t\t\t\tvar more = Gun.obj.map(go.check, function(v){ if(v){ return true }});\n\t\t\t\t\tif(more){ return }\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\t/* MODEL TEST\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], ids = {}, i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\tids[id] = 1;\n\t\t});\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// code here\n\t\t\t}, {i: i += 1, id: id, ids: ids, config: config}));  \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\t*/\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t}, 2000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/thread.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/sea.js': __dirname + '/../../sea.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = servers.pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\n\ndescribe(\"Private Message Threading\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}\n\t\t\ttry{ require('gun/lib/fsrm')((env.i+1)+'data') }catch(e){}\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun = require('gun');\n\t\t\tvar gun = Gun({file: env.i+'data', web: server});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load SEA!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\t//console.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\tload('sea.js', function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Browsers initiate user!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tvar env = test.props;\n\t\t\t\tconsole.log(\"I AM!!!!\", env.i);\n\t\t\t\tvar gun = window.gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\tvar alice = window.alice = {\n\t\t\t\t  \"pub\": \"iYIONCL4rq6-SqmXHjDBoWBJIuhReIHy7MtzBp0zEiw.OXqW4c-FnmcbG2K9IM4avl8WyULHvZxQIyvgTH25PSo\",\n\t\t\t\t  \"priv\": \"5xIKfcjHSrPPr9u80YVJjDITMsif-MHYQyKY7xH-474\",\n\t\t\t\t  \"epub\": \"4Goj7wufxhuyc7IdIMInEOqXgNHaZi8mCWgDGrQIikI.2oTovqZJb8Ez-GB4VEIVU4ixWlshPwt-99hcZk9i63E\",\n\t\t\t\t  \"epriv\": \"6ut8nfxpGSBbyBoZso7QU7jyhiYGRgZZ4LPAtJvWQsQ\"\n\t\t\t\t};\n\t\t\t\tvar bob = window.bob = {\n\t\t\t\t  \"pub\": \"xDAF7JiabamDhUiUFuh4dI8cjRM-yIZwYInzoKoOLlQ.qyBHHKvFhNs0BesfWmpkkg-AyBslWgQ5NtIjZjtzpRM\",\n\t\t\t\t  \"priv\": \"skNy4i4FGFZudqxgkPYMjnggylMu_fZnl-vLref1Hl0\",\n\t\t\t\t  \"epub\": \"ZiCAyWdAixUxYr0I4KRI2raWDXwj0dQltMvdR0_Eld8.Vjz_pGf2LE6i1Qi-8je9U42mnjoPyB50S2dmXZpnC_E\",\n\t\t\t\t  \"epriv\": \"JdGqj9E_VzfjgLdi0fpj1VjeP5tKPYfstpd1n9DQklg\"\n\t\t\t\t}\n\t\t\t\tvar me = window.me = (env.i-1)? bob : alice; // keep it DRY since both need to login.\n\t\t\t\tvar them = window.them = (env.i-1)? alice : bob;\n\t\t\t\twindow.count = 0;\n\t\t\t\twindow.check = {};\n\t\t\t\twindow.thread = function thread(node, my, their){\n\t\t\t\t\tnode.on(msgs => {\n\t\t\t\t\t\t//console.log(\"THREAD!!!\", msgs);\n\t\t\t\t\t\tfor(var time in msgs){\n\t\t\t\t\t\t\t// don't load ones already loaded\n\t\t\t\t\t\t\tif(thread[time]){ continue } thread[time] = 1;\n\t\t\t\t\t\t\t//console.log(\"get...\", time, msgs);\n\t\t\t\t\t\t\tnode.get(time).on(async function(chat){\n\t\t\t\t\t\t\t\tif(!chat.msg){ return }\n\t\t\t\t\t\t\t\tvar msg = await SEA.decrypt(chat.msg, sec);\n\t\t\t\t\t\t\t\tconsole.log('chat:::::::::::::::::', msg);\n\t\t\t\t\t\t\t\twindow.check[chat.pub + chat.count] = msg;\n\t\t\t\t\t\t\t\t$('<li>').text(msg).appendTo('#chats');\n\t\t\t\t\t\t\t\t//gun.get('pchat').get(my).get(their).get('new').get(time).put(null);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tvar to, fro, sec;\n\t\t\t\tgun.user().auth(me, null, function(){\n\t\t\t\t\tconsole.log(\"logged in\");\n\t\t\t\t\tstart();\n\t\t\t\t\tsetTimeout(function(){\n\t\t\t\t\t\t//return;\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t}, 2000);\n\t\t\t\t});\n\t\t\t\tasync function start(){\n\t\t\t\t\tsec = window.sec = await SEA.secret(me.epub, them);\n\t\t\t\t\tto = window.to = gun.user().get('pchat').get(them.pub);\n\t\t\t\t\tfro = window.fro = gun.user(them.pub).get('pchat').get(me.pub);\n\t\t\t\t\t// TODO: THIS SHOULD DO THE THREADING FOR US LOL!! We have to manually do it.\n\t\t\t\t\tthread(to, me.pub, them.pub);\n\t\t\t\t\tthread(fro, me.pub, them.pub);\n\t\t\t\t}\n\t\t\t\twindow.send = async function send(text, my, their, me, cb){\n\t\t\t\t\tvar time = +new Date;\n\t\t\t\t\tvar enc = await SEA.encrypt(text, sec);\n\t\t\t\t\tvar msg = {\n\t\t\t\t\t\tmsg: enc,\n\t\t\t\t\t\tpub: my.pub,\n\t\t\t\t\t\ttime: time,\n\t\t\t\t\t\tcount: ++window.count,\n\t\t\t\t\t\tonly_for_test: text\n\t\t\t\t\t}\n\t\t\t\t\tconsole.log('send', msg);\n\t\t\t\t\tme.get(time).put(msg, cb);\n\t\t\t\t}\n\t\t\t\tconsole.log(\"*****\", gun._.opt.pid);\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Alice send PM\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\tsend(\"I am Alice!\", window.alice, window.bob, window.to, function(ack){\n\t\t\t\tconsole.log(\"Alice saved!\", ack);\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t}, 2000);\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Bob send PM\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"I AM BOB\");\n\t\t\tsend(\"I am Bob!\", window.bob, window.alice, window.to, function(ack){\n\t\t\t\tconsole.log(\"Bob saved!\", ack);\n\t\t\t\tsetTimeout(function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t}, 2000);\n\t\t\t});\n\t\t})\n\t});\n\t\n\tit(\"Wait...\", function(done){\n\t\tsetTimeout(done, 2000);\n\t});\n\n\tit(\"Alice & Bob both got each other PM\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tif(Object.keys(window.check).length !== 2){ more_messages }\n\t\t\t\tif(!window.check[window.me.pub + 1]){ no_me_message }\n\t\t\t\tif(!window.check[window.them.pub + 1]){ no_me_message }\n\t\t\t\ttest.done();\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/user-paste.js",
    "content": "// test SEA end to end.\nvar config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\teach: 10000,\n\twait: 1,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/sea.js': __dirname + '/../../sea.js',\n\t\t'/yson.js': __dirname + '/../../lib/yson.js'\n\t},\n\tdir: __dirname\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){ // Static server\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port); // Start panic server.\n\n// In order to tell the clients what to do,\n// We need a way to reference all of them.\nvar clients = panic.clients;\n\n// Some of the clients may be NodeJS servers on different machines.\n// PANIC manager is a nifty tool that lets us remotely spawn them.\nvar manager = require('panic-manager')();\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){ // Create a bunch of servers.\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1) // They'll need unique ports to start their servers on, if we run the test on 1 machine.\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port // Auto-connect to our panic server.\n});\n\n// Now lets divide our clients into \"servers\" and \"browsers\".\nvar servers = clients.filter('Node.js');\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\n\ndescribe(\"Test vanishing property \"+ config.browsers +\" browser(s) across \"+ config.servers +\" server(s)!\", function(){\n\n\t// We'll have to manually launch the browsers,\n\t// So lets up the timeout so we have time to do that.\n\tthis.timeout(5 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\t// Alright, lets wait until enough gun server peers are connected.\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN has spawned!\", function(){\n\t\t// Once they are, we need to actually spin up the gun server.\n\t\tvar tests = [], i = 0;\n\t\tservers.each(function(client){\n\t\t\t// for each server peer, tell it to run this code:\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\t// NOTE: Despite the fact this LOOKS like we're in a closure...\n\t\t\t\t// it is not! This code is actually getting run\n\t\t\t\t// in a DIFFERENT machine or process!\n\t\t\t\tvar env = test.props;\n\t\t\t\t// As a result, we have to manually pass it scope.\n\t\t\t\ttest.async();\n\t\t\t\t// Clean up from previous test.\n\t\t\t\ttry{ require('fs').unlinkSync(env.i+'data.json') }catch(e){}\n\t\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t\t});\n\t\t\t\t// Launch the server and start gun!\n\t\t\t\tvar Gun = require(env.config.dir+'/../../');\n\t\t\t\t// Attach the server to gun.\n\t\t\t\t//var gun = Gun({file: env.i+'data', web: server});\n\t\t\t\tconsole.log(\"UNDO THIS!!!!!!!!\");var gun = Gun({file: env.i+'data', web: server, rad: false, localStorage: false});\n\t\t\t\tserver.listen(env.config.port + env.i, function(){\n\t\t\t\t\t// This server peer is now done with the test!\n\t\t\t\t\t// It has successfully launched.\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t\t//setInterval(function(){ console.log(\"CPU turns stacked:\", setTimeout.turn.s.length) },1000);\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\t// NOW, this is very important:\n\t\t// Do not proceed to the next test until\n\t\t// every single server (in different machines/processes)\n\t\t// have ALL successfully launched.\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\tconsole.log(\"PLEASE OPEN http://\"+ config.IP +\":\"+ config.port +\" IN \"+ config.browsers +\" BROWSER(S)!\");\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load SEA!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\t//console.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\tload('sea.js', function(){\n\t\t\t\t\tload('yson.js', function(){\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttry{ localStorage.clear() }catch(e){}\n\t\t\t\ttry{ indexedDB.deleteDatabase('radata') }catch(e){}\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun'});\n\t\t\t\twindow.gun = gun;\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Alice creates user\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\tgun.user().create('alice','password', function(){ gun.user().auth('alice','password', function(ack){\n\t\t\t\tif(ack.err){ _bad_login_ }\n\t\t\t\ttest.done();\n\t\t\t})});\n\t\t}, config);\n\t});\n\n\tit(\"Bob logs into user\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tconsole.log(\"I AM BOB\");\n\t\t\ttest.async();\n\t\t\tconsole.only.i=1;console.log(\"====================\");\n\t\t\tgun.user().auth('alice','password', function(ack){\n\t\t\t\tif(ack.err){ _bad_login_ }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, config);\n\t});\n\n\tit(\"Alice pastes\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"paste\");\n\t\t\ttest.async();\n\t\t\tgun.user().get('paste').put('hello world!').on(function(data){\n\t\t\t\tif(this.stop){ return } this.stop = 1; // hack for now!\n\t\t\t\tif('hello world!' != data){ _bad_data_ }\n\t\t\t\tsetTimeout(function(){ test.done() }, 1000);\n\t\t\t})\n\t\t}, config);\n\t});\n\n\tit(\"Bob reads\", function(){\n\t\treturn bob.run(function(test){\n\t\t\tconsole.log(\"I AM BOB\");\n\t\t\ttest.async();\n\t\t\tgun.user().once(function(data){\n\t\t\t\tconsole.log(\"data!\", data);\n\t\t\t\tif('hello world!' != data.paste){ _bad_data2_ }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, config);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\t// which is to shut down all the browsers.\n\t\tbrowsers.run(function(){\n\t\t\tsetTimeout(function(){\n\t\t\t\treturn;\n\t\t\t\tlocation.reload();\n\t\t\t}, 15 * 1000);\n\t\t});\n\t\t// And shut down all the servers.\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n})"
  },
  {
    "path": "test/panic/users.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 2,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/cryptomodules.js': __dirname + '/../../lib/cryptomodules.js',\n\t\t'/sea.js': __dirname + '/../../sea.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = servers.pluck(1);\nvar spawn = servers.excluding(server).pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\nvar again = {};\n\ndescribe(\"End-to-End Encryption on User Accounts\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun = require('gun');\n\t\t\tvar gun = Gun({file: env.i+'data', web: server});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load SEA!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\tconsole.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\tload('cryptomodules.js', function(){\n\t\t\t\t\tload('sea.js', function(){\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.gun = gun;\n\t\t\t\twindow.user = gun.user();\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Create Alice\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\twindow.user.create('alice', 'xyzabcmnopq', function(ack){\n\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Create Bob\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.user.create('bob', 'zyxcbaqponm', function(ack){\n\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Auth Alice\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.user.auth('alice', 'xyzabcmnopq', function(ack){\n\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n/*\n\tit(\"Auth Bob typo\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.user.auth('bob', 'zyxcbaqponmb', function(ack){\n\t\t\t\tif(ack.err && !ack.pub){ console.log(\"BAD SAUCE\"); return test.done() }\n\t\t\t});\n\t\t});\n\t});\n*/\n\n\tit(\"Auth Bob\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.user.auth('bob', 'zyxcbaqponm', function(ack){\n\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\t\tconsole.log(\"AWESOME\");\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Alice save & subscribe to Bob\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.user.on(function(alice){\n\t\t\t\tconsole.log('alice!', alice);\n\t\t\t\tif(alice.hello === 'world'){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\twindow.user.get('hello').put('world');\n\t\t\t}, 100);\n\n\t\t\twindow.gun.get('alias/bob').map().on(function(data){\n\t\t\t\tconsole.log(\"WOOOHOOOOOO!!!\", data);\n\t\t\t\twindow.MARS = data.hello;\n\t\t\t\twindow.PUB = data.pub;\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Bob save\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.user.on(function(bob){\n\t\t\t\tconsole.log('bob!', bob);\n\t\t\t\tif(bob.hello === 'mars'){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tsetTimeout(function(){\n\t\t\t\twindow.user.get('hello').put('mars');\n\t\t\t}, 100);\n\t\t});\n\t});\n\n\tit(\"Alice should have Bob\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tsetTimeout(function(){\n\t\t\t\tif(window.PUB && 'mars' === window.MARS){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t}, 100);\n\t\t});\n\t});\n\n\tit(\"Alice tries to crack Bob\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tgun.get('pub/' + window.PUB).get('crackers').put('gonna crack');\n\t\t\tsetTimeout(function(){\n\t\t\t\ttest.done();\n\t\t\t}, 100);\n\t\t});\n\t});\n\n\tit(\"Alice has no cracked Bob\", function(){\n\t\treturn alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tgun.get('pub/' + window.PUB).val(function(data){\n\t\t\t\tif(data.pub === window.PUB\n\t\t\t\t&& data.hello === 'mars'\n\t\t\t\t&& data.alias === 'bob'\n\t\t\t\t&& data.crackers !== 'gonna crack'\n\t\t\t\t&& undefined === data.crackers){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Bob has no cracked Bob\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\tuser.val(function(data){\n\t\t\t\tif(data.hello === 'mars'\n\t\t\t\t&& data.alias === 'bob'\n\t\t\t\t&& data.crackers !== 'gonna crack'\n\t\t\t\t&& undefined === data.crackers){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic/util/load-browser-scripts.js",
    "content": "module.exports = {\n  /**\n   * Loads scripts in PANIC clients\n   * @param browsers a Panic.ClientList of browsers\n   * @param paths an array of paths to desired .js files\n   * @returns Promise which will resolve when all browsers have loaded all dependencies\n   */\n  loadBrowserScripts: function (browsers, paths) {\n    var promises = [];\n    browsers.each(function (client, id) {\n      promises.push(client.run(function (test) {\n        test.async();\n        var env = test.props;\n        var imports = env.paths || [];\n        /** Loads a single script in the browser */\n        function load(src, cb) {\n          var script = document.createElement('script');\n          script.onload = cb; script.src = src;\n          document.head.appendChild(script);\n        }\n        /** Loads scripts in order, waiting on each to load before proceeding */\n        function loadAll(src, cb) {\n          if (src.length === 0) {\n            cb();\n            return;\n          }\n          var cur = src.shift();\n          // console.log('loading library:', cur);\n          load(cur, function () {\n            loadAll(src, cb);\n          });\n        }\n\n        loadAll(imports, function () {\n          test.done();\n        });\n      }, {paths: paths}));\n    });\n    return Promise.all(promises);\n  }\n};"
  },
  {
    "path": "test/panic/util/open.js",
    "content": "let _browsers = [];\n\nmodule.exports = {\n    web: (count, url, options) => {\n        if (typeof count === 'string') {\n            options = url;\n            url = count;\n            count = 1;\n        }\n        if (!url || typeof url !== 'string') {\n            throw new Error('Invalid URL');\n        }\n        try {\n\t\t\trequire('puppeteer').launch(options).then(browser => {\n\t\t\t\t_browsers.push(browser);\n\t\t\t\tArray(count).fill(0).forEach((x, i) => {\n\t\t\t\t\tconsole.log('Opening browser page ' + i + ' with puppeteer...');\n\t\t\t\t\tbrowser.newPage().then(page => {\n\t\t\t\t\t\tpage.on('console', msg => {\n\t\t\t\t\t\t\tif (msg.text() === 'JSHandle@object') {\n\t\t\t\t\t\t\t\t// FIXME: Avoid text comparison\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconsole.log(`${i} [${msg.type()}]: ${msg.text()}`);\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn page.goto(url);\n\t\t\t\t\t}).then(() => {\n\t\t\t\t\t\tconsole.log('Browser page ' + i + ' open');\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconsole.log(\"PLEASE OPEN \"+ url +\" IN \"+ count +\" BROWSER(S)!\");\n\t\t\tconsole.warn('Consider installing puppeteer to automate browser management (npm i -g puppeteer && npm link puppeteer)');\n\t\t}\n\t},\n\tcleanup: () => {\n\t\tif (_browsers.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconsole.log('Closing all puppeteer browsers...');\n\t\treturn Promise.all(_browsers.map(b => b.close()))\n\t\t\t.then(() => console.log('Closed all puppeteer browsers'));\n\t}\n}\n"
  },
  {
    "path": "test/panic/who.js",
    "content": "var config = {\n\tIP: require('ip').address(),\n\tport: 8765,\n\tservers: 1,\n\tbrowsers: 2,\n\troute: {\n\t\t'/': __dirname + '/index.html',\n\t\t'/gun.js': __dirname + '/../../gun.js',\n\t\t'/jquery.js': __dirname + '/../../examples/jquery.js',\n\t\t'/sea.js': __dirname + '/../../sea.js'\n\t}\n}\n\nvar panic = require('panic-server');\npanic.server().on('request', function(req, res){\n\tconfig.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);\n}).listen(config.port);\n\nvar clients = panic.clients;\nvar manager = require('panic-manager')();\n\nmanager.start({\n    clients: Array(config.servers).fill().map(function(u, i){\n\t\t\treturn {\n\t\t\t\ttype: 'node',\n\t\t\t\tport: config.port + (i + 1)\n\t\t\t}\n    }),\n    panic: 'http://' + config.IP + ':' + config.port\n});\n\nvar servers = clients.filter('Node.js');\nvar server = servers.pluck(1);\nvar spawn = servers.excluding(server).pluck(1);\nvar browsers = clients.excluding(servers);\nvar alice = browsers.pluck(1);\nvar bob = browsers.excluding(alice).pluck(1);\nvar again = {};\n\ndescribe(\"Make sure SEA syncs correctly\", function(){\n\t//this.timeout(5 * 60 * 1000);\n\tthis.timeout(10 * 60 * 1000);\n\n\tit(\"Servers have joined!\", function(){\n\t\treturn servers.atLeast(config.servers);\n\t});\n\n\tit(\"GUN started!\", function(){\n\t\treturn server.run(function(test){\n\t\t\tvar env = test.props;\n\t\t\ttest.async();\n\t\t\ttry{ require('fs').unlinkSync(env.i+'data') }catch(e){}\n\t\t\ttry{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}\n\t\t\tvar port = env.config.port + env.i;\n\t\t\tvar server = require('http').createServer(function(req, res){\n\t\t\t\tres.end(\"I am \"+ env.i +\"!\");\n\t\t\t});\n\t\t\tvar Gun = require('gun');\n\t\t\trequire('gun/sea');\n\t\t\tvar gun = Gun({file: env.i+'data', web: server});\n\t\t\tserver.listen(port, function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config}); \n\t});\n\n\tit(config.browsers +\" browser(s) have joined!\", function(){\n\t\trequire('./util/open').web(config.browsers, \"http://\"+ config.IP +\":\"+ config.port);\n\t\treturn browsers.atLeast(config.browsers);\n\t});\n\n\tit(\"Browsers load SEA!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\ttest.async();\n\t\t\t\t//console.log(\"load?\");\n\t\t\t\tfunction load(src, cb){\n\t\t\t\t\tvar script = document.createElement('script');\n\t\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\t\tdocument.head.appendChild(script);\n\t\t\t\t}\n\t\t\t\tload('sea.js', function(){\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Browsers initialized gun!\", function(){\n\t\tvar tests = [], i = 0;\n\t\tbrowsers.each(function(client, id){\n\t\t\ttests.push(client.run(function(test){\n\t\t\t\tlocalStorage.clear();\n\t\t\t\tvar env = test.props;\n\t\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\t\twindow.gun = gun;\n\t\t\t\tvar user = window.user = gun.user();\n\t\t\t}, {i: i += 1, config: config})); \n\t\t});\n\t\treturn Promise.all(tests);\n\t});\n\n\tit(\"Create Alice\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tconsole.log(\"I AM ALICE\");\n\t\t\ttest.async();\n\t\t\twindow.user.create('alice', 'xyzabcmnopq', function(ack){\n\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\twindow.user.auth('alice', 'xyzabcmnopq', function(ack){\n\t\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\t\tuser.get('who').get('said').set({\n\t\t\t\t\t\twhat: \"Hello world!\"\n\t\t\t\t\t}, function(ack){\n\t\t\t\t\t\tif(ack.err){ return }\n\t\t\t\t\t\ttest.done();\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Create Bob\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\twindow.user.create('bob', 'zyxcbaqponm', function(ack){\n\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\twindow.user.auth('bob', 'zyxcbaqponm', function(ack){\n\t\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\t\ttest.done();\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Have Bob find Alice\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\n\t\t\twindow.gun.get('~@alice').map().once(function(data){\n\t\t\t\twindow.ref = gun.get('~'+data.pub);\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Have Bob listen\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\n\t\t\twindow.count = [];\n\t\t\tref.get('who').get('said').map().once(function(data){\n\t\t\t\tconsole.log(\"read...\", data);\n\t\t\t\twindow.count.push(data);\n\t\t\t\tif(window.count.length - 1){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Alice reloading.\", function(){\n\t\treturn alice.run(function(test){\n\t\t\tlocation.reload();\n\t\t});\n\t});\n\n\tit(\"Got Alice.\", function(){\n\t\tagain.alice = browsers.excluding(new panic.ClientList([alice, bob])).pluck(1);\n\t\treturn again.alice.atLeast(1);\n\t});\n\n\tit(\"Alice reloaded.\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\ttest.async();\n\t\t\t//console.log(\"load?\");\n\t\t\tfunction load(src, cb){\n\t\t\t\tvar script = document.createElement('script');\n\t\t\t\tscript.onload = cb; script.src = src;\n\t\t\t\tdocument.head.appendChild(script);\n\t\t\t}\n\t\t\tload('sea.js', function(){\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config});\n\t});\n\n\tit(\"Alice loaded.\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\ttest.async();\n\n\t\t\tvar env = test.props;\n\t\t\tvar gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');\n\t\t\twindow.gun = gun;\n\t\t\tvar user = window.user = gun.user();\n\t\t\tuser.auth('alice', 'xyzabcmnopq', function(ack){\n\t\t\t\tif(ack.err || !ack.pub){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t}, {i: 1, config: config})\n\t});\n\n\tit(\"Alice write.\", function(){\n\t\treturn again.alice.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(\"write...\");\n\t\t\tuser.get('who').get('said').set({\n\t\t\t\twhat: \"AAA\"\n\t\t\t}, function(ack){\n\t\t\t\tif(ack.err){ return }\n\t\t\t\ttest.done();\n\t\t\t});\n\t\t});\n\t});\n\n\tit(\"Have Bob listen\", function(){\n\t\treturn bob.run(function(test){\n\t\t\ttest.async();\n\t\t\tconsole.log(window.count);\n\t\t\tsetTimeout(function(){\n\t\t\t\tif('AAA' === window.count[1].what){\n\t\t\t\t\ttest.done();\n\t\t\t\t}\n\t\t\t}, 1200);\n\t\t});\n\t});\n\n\tit(\"All finished!\", function(done){\n\t\tconsole.log(\"Done! Cleaning things up...\");\n\t\tsetTimeout(function(){\n\t\t\tdone();\n\t\t},1000);\n\t});\n\n\tafter(\"Everything shut down.\", function(){\n\t\trequire('./util/open').cleanup();\n\t\treturn servers.run(function(){\n\t\t\tprocess.exit();\n\t\t});\n\t});\n});"
  },
  {
    "path": "test/panic.html",
    "content": "<html>\n\t<body>\n\t\t<script src=\"panic.js\"></script>\n\t\t<script>\n\t\t\tpanic.server(location.origin);\n\t\t\tconsole.log('Connecting to', location.origin);\n\t\t</script>\n\t\t<script src=\"expect.js\"></script>\n\t\t<script src=\"gun.js\"></script>\n\t\t<script>\n\t\t\tvar gun = Gun(location.origin + '/gun');\n\t\t</script>\n\t</body>\n</html>"
  },
  {
    "path": "test/ptsd/benchmark.js",
    "content": "/*!\n * Benchmark.js v1.0.0 <http://benchmarkjs.com/>\n * Copyright 2010-2012 Mathias Bynens <http://mths.be/>\n * Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/>\n * Modified by John-David Dalton <http://allyoucanleet.com/>\n * Available under MIT license <http://mths.be/mit>\n */\n;(function(window, undefined) {\n  'use strict';\n\n  /** Used to assign each benchmark an incremented id */\n  var counter = 0;\n\n  /** Detect DOM document object */\n  var doc = isHostType(window, 'document') && document;\n\n  /** Detect free variable `define` */\n  var freeDefine = typeof define == 'function' &&\n    typeof define.amd == 'object' && define.amd && define;\n\n  /** Detect free variable `exports` */\n  var freeExports = typeof exports == 'object' && exports &&\n    (typeof global == 'object' && global && global == global.global && (window = global), exports);\n\n  /** Detect free variable `require` */\n  var freeRequire = typeof require == 'function' && require;\n\n  /** Used to crawl all properties regardless of enumerability */\n  var getAllKeys = Object.getOwnPropertyNames;\n\n  /** Used to get property descriptors */\n  var getDescriptor = Object.getOwnPropertyDescriptor;\n\n  /** Used in case an object doesn't have its own method */\n  var hasOwnProperty = {}.hasOwnProperty;\n\n  /** Used to check if an object is extensible */\n  var isExtensible = Object.isExtensible || function() { return true; };\n\n  /** Used to access Wade Simmons' Node microtime module */\n  var microtimeObject = req('microtime');\n\n  /** Used to access the browser's high resolution timer */\n  var perfObject = isHostType(window, 'performance') && performance;\n\n  /** Used to call the browser's high resolution timer */\n  var perfName = perfObject && (\n    perfObject.now && 'now' ||\n    perfObject.webkitNow && 'webkitNow'\n  );\n\n  /** Used to access Node's high resolution timer */\n  var processObject = isHostType(window, 'process') && process;\n\n  /** Used to check if an own property is enumerable */\n  var propertyIsEnumerable = {}.propertyIsEnumerable;\n\n  /** Used to set property descriptors */\n  var setDescriptor = Object.defineProperty;\n\n  /** Used to resolve a value's internal [[Class]] */\n  var toString = {}.toString;\n\n  /** Used to prevent a `removeChild` memory leak in IE < 9 */\n  var trash = doc && doc.createElement('div');\n\n  /** Used to integrity check compiled tests */\n  var uid = 'uid' + (+new Date);\n\n  /** Used to avoid infinite recursion when methods call each other */\n  var calledBy = {};\n\n  /** Used to avoid hz of Infinity */\n  var divisors = {\n    '1': 4096,\n    '2': 512,\n    '3': 64,\n    '4': 8,\n    '5': 0\n  };\n\n  /**\n   * T-Distribution two-tailed critical values for 95% confidence\n   * http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm\n   */\n  var tTable = {\n    '1':  12.706,'2':  4.303, '3':  3.182, '4':  2.776, '5':  2.571, '6':  2.447,\n    '7':  2.365, '8':  2.306, '9':  2.262, '10': 2.228, '11': 2.201, '12': 2.179,\n    '13': 2.16,  '14': 2.145, '15': 2.131, '16': 2.12,  '17': 2.11,  '18': 2.101,\n    '19': 2.093, '20': 2.086, '21': 2.08,  '22': 2.074, '23': 2.069, '24': 2.064,\n    '25': 2.06,  '26': 2.056, '27': 2.052, '28': 2.048, '29': 2.045, '30': 2.042,\n    'infinity': 1.96\n  };\n\n  /**\n   * Critical Mann-Whitney U-values for 95% confidence\n   * http://www.saburchill.com/IBbiology/stats/003.html\n   */\n  var uTable = {\n    '5':  [0, 1, 2],\n    '6':  [1, 2, 3, 5],\n    '7':  [1, 3, 5, 6, 8],\n    '8':  [2, 4, 6, 8, 10, 13],\n    '9':  [2, 4, 7, 10, 12, 15, 17],\n    '10': [3, 5, 8, 11, 14, 17, 20, 23],\n    '11': [3, 6, 9, 13, 16, 19, 23, 26, 30],\n    '12': [4, 7, 11, 14, 18, 22, 26, 29, 33, 37],\n    '13': [4, 8, 12, 16, 20, 24, 28, 33, 37, 41, 45],\n    '14': [5, 9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55],\n    '15': [5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64],\n    '16': [6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75],\n    '17': [6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81, 87],\n    '18': [7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86, 93, 99],\n    '19': [7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92, 99, 106, 113],\n    '20': [8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127],\n    '21': [8, 15, 22, 29, 36, 43, 50, 58, 65, 73, 80, 88, 96, 103, 111, 119, 126, 134, 142],\n    '22': [9, 16, 23, 30, 38, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 150, 158],\n    '23': [9, 17, 24, 32, 40, 48, 56, 64, 73, 81, 89, 98, 106, 115, 123, 132, 140, 149, 157, 166, 175],\n    '24': [10, 17, 25, 33, 42, 50, 59, 67, 76, 85, 94, 102, 111, 120, 129, 138, 147, 156, 165, 174, 183, 192],\n    '25': [10, 18, 27, 35, 44, 53, 62, 71, 80, 89, 98, 107, 117, 126, 135, 145, 154, 163, 173, 182, 192, 201, 211],\n    '26': [11, 19, 28, 37, 46, 55, 64, 74, 83, 93, 102, 112, 122, 132, 141, 151, 161, 171, 181, 191, 200, 210, 220, 230],\n    '27': [11, 20, 29, 38, 48, 57, 67, 77, 87, 97, 107, 118, 125, 138, 147, 158, 168, 178, 188, 199, 209, 219, 230, 240, 250],\n    '28': [12, 21, 30, 40, 50, 60, 70, 80, 90, 101, 111, 122, 132, 143, 154, 164, 175, 186, 196, 207, 218, 228, 239, 250, 261, 272],\n    '29': [13, 22, 32, 42, 52, 62, 73, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 238, 249, 260, 271, 282, 294],\n    '30': [13, 23, 33, 43, 54, 65, 76, 87, 98, 109, 120, 131, 143, 154, 166, 177, 189, 200, 212, 223, 235, 247, 258, 270, 282, 293, 305, 317]\n  };\n\n  /**\n   * An object used to flag environments/features.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @type Object\n   */\n  var support = {};\n\n  (function() {\n\n    /**\n     * Detect Adobe AIR.\n     *\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.air = isClassOf(window.runtime, 'ScriptBridgingProxyObject');\n\n    /**\n     * Detect if `arguments` objects have the correct internal [[Class]] value.\n     *\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.argumentsClass = isClassOf(arguments, 'Arguments');\n\n    /**\n     * Detect if in a browser environment.\n     *\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.browser = doc && isHostType(window, 'navigator');\n\n    /**\n     * Detect if strings support accessing characters by index.\n     *\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.charByIndex =\n      // IE 8 supports indexes on string literals but not string objects\n      ('x'[0] + Object('x')[0]) == 'xx';\n\n    /**\n     * Detect if strings have indexes as own properties.\n     *\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.charByOwnIndex =\n      // Narwhal, Rhino, RingoJS, IE 8, and Opera < 10.52 support indexes on\n      // strings but don't detect them as own properties\n      support.charByIndex && hasKey('x', '0');\n\n    /**\n     * Detect if Java is enabled/exposed.\n     *\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.java = isClassOf(window.java, 'JavaPackage');\n\n    /**\n     * Detect if the Timers API exists.\n     *\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.timeout = isHostType(window, 'setTimeout') && isHostType(window, 'clearTimeout');\n\n    /**\n     * Detect if functions support decompilation.\n     *\n     * @name decompilation\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    try {\n      // Safari 2.x removes commas in object literals\n      // from Function#toString results\n      // http://webk.it/11609\n      // Firefox 3.6 and Opera 9.25 strip grouping\n      // parentheses from Function#toString results\n      // http://bugzil.la/559438\n      support.decompilation = Function(\n        'return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')'\n      )()(0).x === '1';\n    } catch(e) {\n      support.decompilation = false;\n    }\n\n    /**\n     * Detect ES5+ property descriptor API.\n     *\n     * @name descriptors\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    try {\n      var o = {};\n      support.descriptors = (setDescriptor(o, o, o), 'value' in getDescriptor(o, o));\n    } catch(e) {\n      support.descriptors = false;\n    }\n\n    /**\n     * Detect ES5+ Object.getOwnPropertyNames().\n     *\n     * @name getAllKeys\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    try {\n      support.getAllKeys = /\\bvalueOf\\b/.test(getAllKeys(Object.prototype));\n    } catch(e) {\n      support.getAllKeys = false;\n    }\n\n    /**\n     * Detect if own properties are iterated before inherited properties (all but IE < 9).\n     *\n     * @name iteratesOwnLast\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    support.iteratesOwnFirst = (function() {\n      var props = [];\n      function ctor() { this.x = 1; }\n      ctor.prototype = { 'y': 1 };\n      for (var prop in new ctor) { props.push(prop); }\n      return props[0] == 'x';\n    }());\n\n    /**\n     * Detect if a node's [[Class]] is resolvable (all but IE < 9)\n     * and that the JS engine errors when attempting to coerce an object to a\n     * string without a `toString` property value of `typeof` \"function\".\n     *\n     * @name nodeClass\n     * @memberOf Benchmark.support\n     * @type Boolean\n     */\n    try {\n      support.nodeClass = ({ 'toString': 0 } + '', toString.call(doc || 0) != '[object Object]');\n    } catch(e) {\n      support.nodeClass = true;\n    }\n  }());\n\n  /**\n   * Timer object used by `clock()` and `Deferred#resolve`.\n   *\n   * @private\n   * @type Object\n   */\n  var timer = {\n\n   /**\n    * The timer namespace object or constructor.\n    *\n    * @private\n    * @memberOf timer\n    * @type Function|Object\n    */\n    'ns': Date,\n\n   /**\n    * Starts the deferred timer.\n    *\n    * @private\n    * @memberOf timer\n    * @param {Object} deferred The deferred instance.\n    */\n    'start': null, // lazy defined in `clock()`\n\n   /**\n    * Stops the deferred timer.\n    *\n    * @private\n    * @memberOf timer\n    * @param {Object} deferred The deferred instance.\n    */\n    'stop': null // lazy defined in `clock()`\n  };\n\n  /** Shortcut for inverse results */\n  var noArgumentsClass = !support.argumentsClass,\n      noCharByIndex = !support.charByIndex,\n      noCharByOwnIndex = !support.charByOwnIndex;\n\n  /** Math shortcuts */\n  var abs   = Math.abs,\n      floor = Math.floor,\n      max   = Math.max,\n      min   = Math.min,\n      pow   = Math.pow,\n      sqrt  = Math.sqrt;\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * The Benchmark constructor.\n   *\n   * @constructor\n   * @param {String} name A name to identify the benchmark.\n   * @param {Function|String} fn The test to benchmark.\n   * @param {Object} [options={}] Options object.\n   * @example\n   *\n   * // basic usage (the `new` operator is optional)\n   * var bench = new Benchmark(fn);\n   *\n   * // or using a name first\n   * var bench = new Benchmark('foo', fn);\n   *\n   * // or with options\n   * var bench = new Benchmark('foo', fn, {\n   *\n   *   // displayed by Benchmark#toString if `name` is not available\n   *   'id': 'xyz',\n   *\n   *   // called when the benchmark starts running\n   *   'onStart': onStart,\n   *\n   *   // called after each run cycle\n   *   'onCycle': onCycle,\n   *\n   *   // called when aborted\n   *   'onAbort': onAbort,\n   *\n   *   // called when a test errors\n   *   'onError': onError,\n   *\n   *   // called when reset\n   *   'onReset': onReset,\n   *\n   *   // called when the benchmark completes running\n   *   'onComplete': onComplete,\n   *\n   *   // compiled/called before the test loop\n   *   'setup': setup,\n   *\n   *   // compiled/called after the test loop\n   *   'teardown': teardown\n   * });\n   *\n   * // or name and options\n   * var bench = new Benchmark('foo', {\n   *\n   *   // a flag to indicate the benchmark is deferred\n   *   'defer': true,\n   *\n   *   // benchmark test function\n   *   'fn': function(deferred) {\n   *     // call resolve() when the deferred test is finished\n   *     deferred.resolve();\n   *   }\n   * });\n   *\n   * // or options only\n   * var bench = new Benchmark({\n   *\n   *   // benchmark name\n   *   'name': 'foo',\n   *\n   *   // benchmark test as a string\n   *   'fn': '[1,2,3,4].sort()'\n   * });\n   *\n   * // a test's `this` binding is set to the benchmark instance\n   * var bench = new Benchmark('foo', function() {\n   *   'My name is '.concat(this.name); // My name is foo\n   * });\n   */\n  function Benchmark(name, fn, options) {\n    var me = this;\n\n    // allow instance creation without the `new` operator\n    if (me == null || me.constructor != Benchmark) {\n      return new Benchmark(name, fn, options);\n    }\n    // juggle arguments\n    if (isClassOf(name, 'Object')) {\n      // 1 argument (options)\n      options = name;\n    }\n    else if (isClassOf(name, 'Function')) {\n      // 2 arguments (fn, options)\n      options = fn;\n      fn = name;\n    }\n    else if (isClassOf(fn, 'Object')) {\n      // 2 arguments (name, options)\n      options = fn;\n      fn = null;\n      me.name = name;\n    }\n    else {\n      // 3 arguments (name, fn [, options])\n      me.name = name;\n    }\n    setOptions(me, options);\n    me.id || (me.id = ++counter);\n    me.fn == null && (me.fn = fn);\n    me.stats = deepClone(me.stats);\n    me.times = deepClone(me.times);\n  }\n\n  /**\n   * The Deferred constructor.\n   *\n   * @constructor\n   * @memberOf Benchmark\n   * @param {Object} clone The cloned benchmark instance.\n   */\n  function Deferred(clone) {\n    var me = this;\n    if (me == null || me.constructor != Deferred) {\n      return new Deferred(clone);\n    }\n    me.benchmark = clone;\n    clock(me);\n  }\n\n  /**\n   * The Event constructor.\n   *\n   * @constructor\n   * @memberOf Benchmark\n   * @param {String|Object} type The event type.\n   */\n  function Event(type) {\n    var me = this;\n    return (me == null || me.constructor != Event)\n      ? new Event(type)\n      : (type instanceof Event)\n          ? type\n          : extend(me, { 'timeStamp': +new Date }, typeof type == 'string' ? { 'type': type } : type);\n  }\n\n  /**\n   * The Suite constructor.\n   *\n   * @constructor\n   * @memberOf Benchmark\n   * @param {String} name A name to identify the suite.\n   * @param {Object} [options={}] Options object.\n   * @example\n   *\n   * // basic usage (the `new` operator is optional)\n   * var suite = new Benchmark.Suite;\n   *\n   * // or using a name first\n   * var suite = new Benchmark.Suite('foo');\n   *\n   * // or with options\n   * var suite = new Benchmark.Suite('foo', {\n   *\n   *   // called when the suite starts running\n   *   'onStart': onStart,\n   *\n   *   // called between running benchmarks\n   *   'onCycle': onCycle,\n   *\n   *   // called when aborted\n   *   'onAbort': onAbort,\n   *\n   *   // called when a test errors\n   *   'onError': onError,\n   *\n   *   // called when reset\n   *   'onReset': onReset,\n   *\n   *   // called when the suite completes running\n   *   'onComplete': onComplete\n   * });\n   */\n  function Suite(name, options) {\n    var me = this;\n\n    // allow instance creation without the `new` operator\n    if (me == null || me.constructor != Suite) {\n      return new Suite(name, options);\n    }\n    // juggle arguments\n    if (isClassOf(name, 'Object')) {\n      // 1 argument (options)\n      options = name;\n    } else {\n      // 2 arguments (name [, options])\n      me.name = name;\n    }\n    setOptions(me, options);\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Note: Some array methods have been implemented in plain JavaScript to avoid\n   * bugs in IE, Opera, Rhino, and Mobile Safari.\n   *\n   * IE compatibility mode and IE < 9 have buggy Array `shift()` and `splice()`\n   * functions that fail to remove the last element, `object[0]`, of\n   * array-like-objects even though the `length` property is set to `0`.\n   * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`\n   * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.\n   *\n   * In Opera < 9.50 and some older/beta Mobile Safari versions using `unshift()`\n   * generically to augment the `arguments` object will pave the value at index 0\n   * without incrementing the other values's indexes.\n   * https://github.com/documentcloud/underscore/issues/9\n   *\n   * Rhino and environments it powers, like Narwhal and RingoJS, may have\n   * buggy Array `concat()`, `reverse()`, `shift()`, `slice()`, `splice()` and\n   * `unshift()` functions that make sparse arrays non-sparse by assigning the\n   * undefined indexes a value of undefined.\n   * https://github.com/mozilla/rhino/commit/702abfed3f8ca043b2636efd31c14ba7552603dd\n   */\n\n  /**\n   * Creates an array containing the elements of the host array followed by the\n   * elements of each argument in order.\n   *\n   * @memberOf Benchmark.Suite\n   * @returns {Array} The new array.\n   */\n  function concat() {\n    var value,\n        j = -1,\n        length = arguments.length,\n        result = slice.call(this),\n        index = result.length;\n\n    while (++j < length) {\n      value = arguments[j];\n      if (isClassOf(value, 'Array')) {\n        for (var k = 0, l = value.length; k < l; k++, index++) {\n          if (k in value) {\n            result[index] = value[k];\n          }\n        }\n      } else {\n        result[index++] = value;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Utility function used by `shift()`, `splice()`, and `unshift()`.\n   *\n   * @private\n   * @param {Number} start The index to start inserting elements.\n   * @param {Number} deleteCount The number of elements to delete from the insert point.\n   * @param {Array} elements The elements to insert.\n   * @returns {Array} An array of deleted elements.\n   */\n  function insert(start, deleteCount, elements) {\n    // `result` should have its length set to the `deleteCount`\n    // see https://bugs.ecmascript.org/show_bug.cgi?id=332\n    var deleteEnd = start + deleteCount,\n        elementCount = elements ? elements.length : 0,\n        index = start - 1,\n        length = start + elementCount,\n        object = this,\n        result = Array(deleteCount),\n        tail = slice.call(object, deleteEnd);\n\n    // delete elements from the array\n    while (++index < deleteEnd) {\n      if (index in object) {\n        result[index - start] = object[index];\n        delete object[index];\n      }\n    }\n    // insert elements\n    index = start - 1;\n    while (++index < length) {\n      object[index] = elements[index - start];\n    }\n    // append tail elements\n    start = index--;\n    length = max(0, (object.length >>> 0) - deleteCount + elementCount);\n    while (++index < length) {\n      if ((index - start) in tail) {\n        object[index] = tail[index - start];\n      } else if (index in object) {\n        delete object[index];\n      }\n    }\n    // delete excess elements\n    deleteCount = deleteCount > elementCount ? deleteCount - elementCount : 0;\n    while (deleteCount--) {\n      index = length + deleteCount;\n      if (index in object) {\n        delete object[index];\n      }\n    }\n    object.length = length;\n    return result;\n  }\n\n  /**\n   * Rearrange the host array's elements in reverse order.\n   *\n   * @memberOf Benchmark.Suite\n   * @returns {Array} The reversed array.\n   */\n  function reverse() {\n    var upperIndex,\n        value,\n        index = -1,\n        object = Object(this),\n        length = object.length >>> 0,\n        middle = floor(length / 2);\n\n    if (length > 1) {\n      while (++index < middle) {\n        upperIndex = length - index - 1;\n        value = upperIndex in object ? object[upperIndex] : uid;\n        if (index in object) {\n          object[upperIndex] = object[index];\n        } else {\n          delete object[upperIndex];\n        }\n        if (value != uid) {\n          object[index] = value;\n        } else {\n          delete object[index];\n        }\n      }\n    }\n    return object;\n  }\n\n  /**\n   * Removes the first element of the host array and returns it.\n   *\n   * @memberOf Benchmark.Suite\n   * @returns {Mixed} The first element of the array.\n   */\n  function shift() {\n    return insert.call(this, 0, 1)[0];\n  }\n\n  /**\n   * Creates an array of the host array's elements from the start index up to,\n   * but not including, the end index.\n   *\n   * @memberOf Benchmark.Suite\n   * @param {Number} start The starting index.\n   * @param {Number} end The end index.\n   * @returns {Array} The new array.\n   */\n  function slice(start, end) {\n    var index = -1,\n        object = Object(this),\n        length = object.length >>> 0,\n        result = [];\n\n    start = toInteger(start);\n    start = start < 0 ? max(length + start, 0) : min(start, length);\n    start--;\n    end = end == null ? length : toInteger(end);\n    end = end < 0 ? max(length + end, 0) : min(end, length);\n\n    while ((++index, ++start) < end) {\n      if (start in object) {\n        result[index] = object[start];\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Allows removing a range of elements and/or inserting elements into the\n   * host array.\n   *\n   * @memberOf Benchmark.Suite\n   * @param {Number} start The start index.\n   * @param {Number} deleteCount The number of elements to delete.\n   * @param {Mixed} [val1, val2, ...] values to insert at the `start` index.\n   * @returns {Array} An array of removed elements.\n   */\n  function splice(start, deleteCount) {\n    var object = Object(this),\n        length = object.length >>> 0;\n\n    start = toInteger(start);\n    start = start < 0 ? max(length + start, 0) : min(start, length);\n\n    // support the de-facto SpiderMonkey extension\n    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice#Parameters\n    // https://bugs.ecmascript.org/show_bug.cgi?id=429\n    deleteCount = arguments.length == 1\n      ? length - start\n      : min(max(toInteger(deleteCount), 0), length - start);\n\n    return insert.call(object, start, deleteCount, slice.call(arguments, 2));\n  }\n\n  /**\n   * Converts the specified `value` to an integer.\n   *\n   * @private\n   * @param {Mixed} value The value to convert.\n   * @returns {Number} The resulting integer.\n   */\n  function toInteger(value) {\n    value = +value;\n    return value === 0 || !isFinite(value) ? value || 0 : value - (value % 1);\n  }\n\n  /**\n   * Appends arguments to the host array.\n   *\n   * @memberOf Benchmark.Suite\n   * @returns {Number} The new length.\n   */\n  function unshift() {\n    var object = Object(this);\n    insert.call(object, 0, 0, arguments);\n    return object.length;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * A generic `Function#bind` like method.\n   *\n   * @private\n   * @param {Function} fn The function to be bound to `thisArg`.\n   * @param {Mixed} thisArg The `this` binding for the given function.\n   * @returns {Function} The bound function.\n   */\n  function bind(fn, thisArg) {\n    return function() { fn.apply(thisArg, arguments); };\n  }\n\n  /**\n   * Creates a function from the given arguments string and body.\n   *\n   * @private\n   * @param {String} args The comma separated function arguments.\n   * @param {String} body The function body.\n   * @returns {Function} The new function.\n   */\n  function createFunction() {\n    // lazy define\n    createFunction = function(args, body) {\n      var result,\n          anchor = freeDefine ? define.amd : Benchmark,\n          prop = uid + 'createFunction';\n\n      runScript((freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '=function(' + args + '){' + body + '}');\n      result = anchor[prop];\n      delete anchor[prop];\n      return result;\n    };\n    // fix JaegerMonkey bug\n    // http://bugzil.la/639720\n    createFunction = support.browser && (createFunction('', 'return\"' + uid + '\"') || noop)() == uid ? createFunction : Function;\n    return createFunction.apply(null, arguments);\n  }\n\n  /**\n   * Delay the execution of a function based on the benchmark's `delay` property.\n   *\n   * @private\n   * @param {Object} bench The benchmark instance.\n   * @param {Object} fn The function to execute.\n   */\n  function delay(bench, fn) {\n    bench._timerId = setTimeout(fn, bench.delay * 1e3);\n  }\n\n  /**\n   * Destroys the given element.\n   *\n   * @private\n   * @param {Element} element The element to destroy.\n   */\n  function destroyElement(element) {\n    trash.appendChild(element);\n    trash.innerHTML = '';\n  }\n\n  /**\n   * Iterates over an object's properties, executing the `callback` for each.\n   * Callbacks may terminate the loop by explicitly returning `false`.\n   *\n   * @private\n   * @param {Object} object The object to iterate over.\n   * @param {Function} callback The function executed per own property.\n   * @param {Object} options The options object.\n   * @returns {Object} Returns the object iterated over.\n   */\n  function forProps() {\n    var forShadowed,\n        skipSeen,\n        forArgs = true,\n        shadowed = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'];\n\n    (function(enumFlag, key) {\n      // must use a non-native constructor to catch the Safari 2 issue\n      function Klass() { this.valueOf = 0; };\n      Klass.prototype.valueOf = 0;\n      // check various for-in bugs\n      for (key in new Klass) {\n        enumFlag += key == 'valueOf' ? 1 : 0;\n      }\n      // check if `arguments` objects have non-enumerable indexes\n      for (key in arguments) {\n        key == '0' && (forArgs = false);\n      }\n      // Safari 2 iterates over shadowed properties twice\n      // http://replay.waybackmachine.org/20090428222941/http://tobielangel.com/2007/1/29/for-in-loop-broken-in-safari/\n      skipSeen = enumFlag == 2;\n      // IE < 9 incorrectly makes an object's properties non-enumerable if they have\n      // the same name as other non-enumerable properties in its prototype chain.\n      forShadowed = !enumFlag;\n    }(0));\n\n    // lazy define\n    forProps = function(object, callback, options) {\n      options || (options = {});\n\n      var result = object;\n      object = Object(object);\n\n      var ctor,\n          key,\n          keys,\n          skipCtor,\n          done = !result,\n          which = options.which,\n          allFlag = which == 'all',\n          index = -1,\n          iteratee = object,\n          length = object.length,\n          ownFlag = allFlag || which == 'own',\n          seen = {},\n          skipProto = isClassOf(object, 'Function'),\n          thisArg = options.bind;\n\n      if (thisArg !== undefined) {\n        callback = bind(callback, thisArg);\n      }\n      // iterate all properties\n      if (allFlag && support.getAllKeys) {\n        for (index = 0, keys = getAllKeys(object), length = keys.length; index < length; index++) {\n          key = keys[index];\n          if (callback(object[key], key, object) === false) {\n            break;\n          }\n        }\n      }\n      // else iterate only enumerable properties\n      else {\n        for (key in object) {\n          // Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1\n          // (if the prototype or a property on the prototype has been set)\n          // incorrectly set a function's `prototype` property [[Enumerable]] value\n          // to `true`. Because of this we standardize on skipping the `prototype`\n          // property of functions regardless of their [[Enumerable]] value.\n          if ((done =\n              !(skipProto && key == 'prototype') &&\n              !(skipSeen && (hasKey(seen, key) || !(seen[key] = true))) &&\n              (!ownFlag || ownFlag && hasKey(object, key)) &&\n              callback(object[key], key, object) === false)) {\n            break;\n          }\n        }\n        // in IE < 9 strings don't support accessing characters by index\n        if (!done && (forArgs && isArguments(object) ||\n            ((noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String') &&\n              (iteratee = noCharByIndex ? object.split('') : object)))) {\n          while (++index < length) {\n            if ((done =\n                callback(iteratee[index], String(index), object) === false)) {\n              break;\n            }\n          }\n        }\n        if (!done && forShadowed) {\n          // Because IE < 9 can't set the `[[Enumerable]]` attribute of an existing\n          // property and the `constructor` property of a prototype defaults to\n          // non-enumerable, we manually skip the `constructor` property when we\n          // think we are iterating over a `prototype` object.\n          ctor = object.constructor;\n          skipCtor = ctor && ctor.prototype && ctor.prototype.constructor === ctor;\n          for (index = 0; index < 7; index++) {\n            key = shadowed[index];\n            if (!(skipCtor && key == 'constructor') &&\n                hasKey(object, key) &&\n                callback(object[key], key, object) === false) {\n              break;\n            }\n          }\n        }\n      }\n      return result;\n    };\n    return forProps.apply(null, arguments);\n  }\n\n  /**\n   * Gets the name of the first argument from a function's source.\n   *\n   * @private\n   * @param {Function} fn The function.\n   * @returns {String} The argument name.\n   */\n  function getFirstArgument(fn) {\n    return (!hasKey(fn, 'toString') &&\n      (/^[\\s(]*function[^(]*\\(([^\\s,)]+)/.exec(fn) || 0)[1]) || '';\n  }\n\n  /**\n   * Computes the arithmetic mean of a sample.\n   *\n   * @private\n   * @param {Array} sample The sample.\n   * @returns {Number} The mean.\n   */\n  function getMean(sample) {\n    return reduce(sample, function(sum, x) {\n      return sum + x;\n    }) / sample.length || 0;\n  }\n\n  /**\n   * Gets the source code of a function.\n   *\n   * @private\n   * @param {Function} fn The function.\n   * @param {String} altSource A string used when a function's source code is irretrievable.\n   * @returns {String} The function's source code.\n   */\n  function getSource(fn, altSource) {\n    var result = altSource;\n    if (isStringable(fn)) {\n      result = String(fn);\n    } else if (support.decompilation) {\n      // escape the `{` for Firefox 1\n      result = (/^[^{]+\\{([\\s\\S]*)}\\s*$/.exec(fn) || 0)[1];\n    }\n    // trim string\n    result = (result || '').replace(/^\\s+|\\s+$/g, '');\n\n    // detect strings containing only the \"use strict\" directive\n    return /^(?:\\/\\*+[\\w|\\W]*?\\*\\/|\\/\\/.*?[\\n\\r\\u2028\\u2029]|\\s)*([\"'])use strict\\1;?$/.test(result)\n      ? ''\n      : result;\n  }\n\n  /**\n   * Checks if a value is an `arguments` object.\n   *\n   * @private\n   * @param {Mixed} value The value to check.\n   * @returns {Boolean} Returns `true` if the value is an `arguments` object, else `false`.\n   */\n  function isArguments() {\n    // lazy define\n    isArguments = function(value) {\n      return toString.call(value) == '[object Arguments]';\n    };\n    if (noArgumentsClass) {\n      isArguments = function(value) {\n        return hasKey(value, 'callee') &&\n          !(propertyIsEnumerable && propertyIsEnumerable.call(value, 'callee'));\n      };\n    }\n    return isArguments(arguments[0]);\n  }\n\n  /**\n   * Checks if an object is of the specified class.\n   *\n   * @private\n   * @param {Mixed} value The value to check.\n   * @param {String} name The name of the class.\n   * @returns {Boolean} Returns `true` if the value is of the specified class, else `false`.\n   */\n  function isClassOf(value, name) {\n    return value != null && toString.call(value) == '[object ' + name + ']';\n  }\n\n  /**\n   * Host objects can return type values that are different from their actual\n   * data type. The objects we are concerned with usually return non-primitive\n   * types of object, function, or unknown.\n   *\n   * @private\n   * @param {Mixed} object The owner of the property.\n   * @param {String} property The property to check.\n   * @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.\n   */\n  function isHostType(object, property) {\n    var type = object != null ? typeof object[property] : 'number';\n    return !/^(?:boolean|number|string|undefined)$/.test(type) &&\n      (type == 'object' ? !!object[property] : true);\n  }\n\n  /**\n   * Checks if a given `value` is an object created by the `Object` constructor\n   * assuming objects created by the `Object` constructor have no inherited\n   * enumerable properties and that there are no `Object.prototype` extensions.\n   *\n   * @private\n   * @param {Mixed} value The value to check.\n   * @returns {Boolean} Returns `true` if the `value` is a plain `Object` object, else `false`.\n   */\n  function isPlainObject(value) {\n    // avoid non-objects and false positives for `arguments` objects in IE < 9\n    var result = false;\n    if (!(value && typeof value == 'object') || isArguments(value)) {\n      return result;\n    }\n    // IE < 9 presents DOM nodes as `Object` objects except they have `toString`\n    // methods that are `typeof` \"string\" and still can coerce nodes to strings.\n    // Also check that the constructor is `Object` (i.e. `Object instanceof Object`)\n    var ctor = value.constructor;\n    if ((support.nodeClass || !(typeof value.toString != 'function' && typeof (value + '') == 'string')) &&\n        (!isClassOf(ctor, 'Function') || ctor instanceof ctor)) {\n      // In most environments an object's own properties are iterated before\n      // its inherited properties. If the last iterated property is an object's\n      // own property then there are no inherited enumerable properties.\n      if (support.iteratesOwnFirst) {\n        forProps(value, function(subValue, subKey) {\n          result = subKey;\n        });\n        return result === false || hasKey(value, result);\n      }\n      // IE < 9 iterates inherited properties before own properties. If the first\n      // iterated property is an object's own property then there are no inherited\n      // enumerable properties.\n      forProps(value, function(subValue, subKey) {\n        result = !hasKey(value, subKey);\n        return false;\n      });\n      return result === false;\n    }\n    return result;\n  }\n\n  /**\n   * Checks if a value can be safely coerced to a string.\n   *\n   * @private\n   * @param {Mixed} value The value to check.\n   * @returns {Boolean} Returns `true` if the value can be coerced, else `false`.\n   */\n  function isStringable(value) {\n    return hasKey(value, 'toString') || isClassOf(value, 'String');\n  }\n\n  /**\n   * Wraps a function and passes `this` to the original function as the\n   * first argument.\n   *\n   * @private\n   * @param {Function} fn The function to be wrapped.\n   * @returns {Function} The new function.\n   */\n  function methodize(fn) {\n    return function() {\n      var args = [this];\n      args.push.apply(args, arguments);\n      return fn.apply(null, args);\n    };\n  }\n\n  /**\n   * A no-operation function.\n   *\n   * @private\n   */\n  function noop() {\n    // no operation performed\n  }\n\n  /**\n   * A wrapper around require() to suppress `module missing` errors.\n   *\n   * @private\n   * @param {String} id The module id.\n   * @returns {Mixed} The exported module or `null`.\n   */\n  function req(id) {\n    try {\n      var result = freeExports && freeRequire(id);\n    } catch(e) { }\n    return result || null;\n  }\n\n  /**\n   * Runs a snippet of JavaScript via script injection.\n   *\n   * @private\n   * @param {String} code The code to run.\n   */\n  function runScript(code) {\n    var anchor = freeDefine ? define.amd : Benchmark,\n        script = doc.createElement('script'),\n        sibling = doc.getElementsByTagName('script')[0],\n        parent = sibling.parentNode,\n        prop = uid + 'runScript',\n        prefix = '(' + (freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '||function(){})();';\n\n    // Firefox 2.0.0.2 cannot use script injection as intended because it executes\n    // asynchronously, but that's OK because script injection is only used to avoid\n    // the previously commented JaegerMonkey bug.\n    try {\n      // remove the inserted script *before* running the code to avoid differences\n      // in the expected script element count/order of the document.\n      script.appendChild(doc.createTextNode(prefix + code));\n      anchor[prop] = function() { destroyElement(script); };\n    } catch(e) {\n      parent = parent.cloneNode(false);\n      sibling = null;\n      script.text = code;\n    }\n    parent.insertBefore(script, sibling);\n    delete anchor[prop];\n  }\n\n  /**\n   * A helper function for setting options/event handlers.\n   *\n   * @private\n   * @param {Object} bench The benchmark instance.\n   * @param {Object} [options={}] Options object.\n   */\n  function setOptions(bench, options) {\n    options = extend({}, bench.constructor.options, options);\n    bench.options = forOwn(options, function(value, key) {\n      if (value != null) {\n        // add event listeners\n        if (/^on[A-Z]/.test(key)) {\n          forEach(key.split(' '), function(key) {\n            bench.on(key.slice(2).toLowerCase(), value);\n          });\n        } else if (!hasKey(bench, key)) {\n          bench[key] = deepClone(value);\n        }\n      }\n    });\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Handles cycling/completing the deferred benchmark.\n   *\n   * @memberOf Benchmark.Deferred\n   */\n  function resolve() {\n    var me = this,\n        clone = me.benchmark,\n        bench = clone._original;\n\n    if (bench.aborted) {\n      // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete\n      me.teardown();\n      clone.running = false;\n      cycle(me);\n    }\n    else if (++me.cycles < clone.count) {\n      // continue the test loop\n      if (support.timeout) {\n        // use setTimeout to avoid a call stack overflow if called recursively\n        setTimeout(function() { clone.compiled.call(me, timer); }, 0);\n      } else {\n        clone.compiled.call(me, timer);\n      }\n    }\n    else {\n      timer.stop(me);\n      me.teardown();\n      delay(clone, function() { cycle(me); });\n    }\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * A deep clone utility.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Mixed} value The value to clone.\n   * @returns {Mixed} The cloned value.\n   */\n  function deepClone(value) {\n    var accessor,\n        circular,\n        clone,\n        ctor,\n        descriptor,\n        extensible,\n        key,\n        length,\n        markerKey,\n        parent,\n        result,\n        source,\n        subIndex,\n        data = { 'value': value },\n        index = 0,\n        marked = [],\n        queue = { 'length': 0 },\n        unmarked = [];\n\n    /**\n     * An easily detectable decorator for cloned values.\n     */\n    function Marker(object) {\n      this.raw = object;\n    }\n\n    /**\n     * The callback used by `forProps()`.\n     */\n    function forPropsCallback(subValue, subKey) {\n      // exit early to avoid cloning the marker\n      if (subValue && subValue.constructor == Marker) {\n        return;\n      }\n      // add objects to the queue\n      if (subValue === Object(subValue)) {\n        queue[queue.length++] = { 'key': subKey, 'parent': clone, 'source': value };\n      }\n      // assign non-objects\n      else {\n        try {\n          // will throw an error in strict mode if the property is read-only\n          clone[subKey] = subValue;\n        } catch(e) { }\n      }\n    }\n\n    /**\n     * Gets an available marker key for the given object.\n     */\n    function getMarkerKey(object) {\n      // avoid collisions with existing keys\n      var result = uid;\n      while (object[result] && object[result].constructor != Marker) {\n        result += 1;\n      }\n      return result;\n    }\n\n    do {\n      key = data.key;\n      parent = data.parent;\n      source = data.source;\n      clone = value = source ? source[key] : data.value;\n      accessor = circular = descriptor = false;\n\n      // create a basic clone to filter out functions, DOM elements, and\n      // other non `Object` objects\n      if (value === Object(value)) {\n        // use custom deep clone function if available\n        if (isClassOf(value.deepClone, 'Function')) {\n          clone = value.deepClone();\n        } else {\n          ctor = value.constructor;\n          switch (toString.call(value)) {\n            case '[object Array]':\n              clone = new ctor(value.length);\n              break;\n\n            case '[object Boolean]':\n              clone = new ctor(value == true);\n              break;\n\n            case '[object Date]':\n              clone = new ctor(+value);\n              break;\n\n            case '[object Object]':\n              isPlainObject(value) && (clone = {});\n              break;\n\n            case '[object Number]':\n            case '[object String]':\n              clone = new ctor(value);\n              break;\n\n            case '[object RegExp]':\n              clone = ctor(value.source,\n                (value.global     ? 'g' : '') +\n                (value.ignoreCase ? 'i' : '') +\n                (value.multiline  ? 'm' : ''));\n          }\n        }\n        // continue clone if `value` doesn't have an accessor descriptor\n        // http://es5.github.com/#x8.10.1\n        if (clone && clone != value &&\n            !(descriptor = source && support.descriptors && getDescriptor(source, key),\n              accessor = descriptor && (descriptor.get || descriptor.set))) {\n          // use an existing clone (circular reference)\n          if ((extensible = isExtensible(value))) {\n            markerKey = getMarkerKey(value);\n            if (value[markerKey]) {\n              circular = clone = value[markerKey].raw;\n            }\n          } else {\n            // for frozen/sealed objects\n            for (subIndex = 0, length = unmarked.length; subIndex < length; subIndex++) {\n              data = unmarked[subIndex];\n              if (data.object === value) {\n                circular = clone = data.clone;\n                break;\n              }\n            }\n          }\n          if (!circular) {\n            // mark object to allow quickly detecting circular references and tie it to its clone\n            if (extensible) {\n              value[markerKey] = new Marker(clone);\n              marked.push({ 'key': markerKey, 'object': value });\n            } else {\n              // for frozen/sealed objects\n              unmarked.push({ 'clone': clone, 'object': value });\n            }\n            // iterate over object properties\n            forProps(value, forPropsCallback, { 'which': 'all' });\n          }\n        }\n      }\n      if (parent) {\n        // for custom property descriptors\n        if (accessor || (descriptor && !(descriptor.configurable && descriptor.enumerable && descriptor.writable))) {\n          if ('value' in descriptor) {\n            descriptor.value = clone;\n          }\n          setDescriptor(parent, key, descriptor);\n        }\n        // for default property descriptors\n        else {\n          parent[key] = clone;\n        }\n      } else {\n        result = clone;\n      }\n    } while ((data = queue[index++]));\n\n    // remove markers\n    for (index = 0, length = marked.length; index < length; index++) {\n      data = marked[index];\n      delete data.object[data.key];\n    }\n    return result;\n  }\n\n  /**\n   * An iteration utility for arrays and objects.\n   * Callbacks may terminate the loop by explicitly returning `false`.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array|Object} object The object to iterate over.\n   * @param {Function} callback The function called per iteration.\n   * @param {Mixed} thisArg The `this` binding for the callback.\n   * @returns {Array|Object} Returns the object iterated over.\n   */\n  function each(object, callback, thisArg) {\n    var result = object;\n    object = Object(object);\n\n    var fn = callback,\n        index = -1,\n        length = object.length,\n        isSnapshot = !!(object.snapshotItem && (length = object.snapshotLength)),\n        isSplittable = (noCharByIndex || noCharByOwnIndex) && isClassOf(object, 'String'),\n        isConvertable = isSnapshot || isSplittable || 'item' in object,\n        origObject = object;\n\n    // in Opera < 10.5 `hasKey(object, 'length')` returns `false` for NodeLists\n    if (length === length >>> 0) {\n      if (isConvertable) {\n        // the third argument of the callback is the original non-array object\n        callback = function(value, index) {\n          return fn.call(this, value, index, origObject);\n        };\n        // in IE < 9 strings don't support accessing characters by index\n        if (isSplittable) {\n          object = object.split('');\n        } else {\n          object = [];\n          while (++index < length) {\n            // in Safari 2 `index in object` is always `false` for NodeLists\n            object[index] = isSnapshot ? result.snapshotItem(index) : result[index];\n          }\n        }\n      }\n      forEach(object, callback, thisArg);\n    } else {\n      forOwn(object, callback, thisArg);\n    }\n    return result;\n  }\n\n  /**\n   * Copies enumerable properties from the source(s) object to the destination object.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Object} destination The destination object.\n   * @param {Object} [source={}] The source object.\n   * @returns {Object} The destination object.\n   */\n  function extend(destination, source) {\n    // Chrome < 14 incorrectly sets `destination` to `undefined` when we `delete arguments[0]`\n    // http://code.google.com/p/v8/issues/detail?id=839\n    var result = destination;\n    delete arguments[0];\n\n    forEach(arguments, function(source) {\n      forProps(source, function(value, key) {\n        result[key] = value;\n      });\n    });\n    return result;\n  }\n\n  /**\n   * A generic `Array#filter` like method.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array} array The array to iterate over.\n   * @param {Function|String} callback The function/alias called per iteration.\n   * @param {Mixed} thisArg The `this` binding for the callback.\n   * @returns {Array} A new array of values that passed callback filter.\n   * @example\n   *\n   * // get odd numbers\n   * Benchmark.filter([1, 2, 3, 4, 5], function(n) {\n   *   return n % 2;\n   * }); // -> [1, 3, 5];\n   *\n   * // get fastest benchmarks\n   * Benchmark.filter(benches, 'fastest');\n   *\n   * // get slowest benchmarks\n   * Benchmark.filter(benches, 'slowest');\n   *\n   * // get benchmarks that completed without erroring\n   * Benchmark.filter(benches, 'successful');\n   */\n  function filter(array, callback, thisArg) {\n    var result;\n\n    if (callback == 'successful') {\n      // callback to exclude those that are errored, unrun, or have hz of Infinity\n      callback = function(bench) { return bench.cycles && isFinite(bench.hz); };\n    }\n    else if (callback == 'fastest' || callback == 'slowest') {\n      // get successful, sort by period + margin of error, and filter fastest/slowest\n      result = filter(array, 'successful').sort(function(a, b) {\n        a = a.stats; b = b.stats;\n        return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback == 'fastest' ? 1 : -1);\n      });\n      result = filter(result, function(bench) {\n        return result[0].compare(bench) == 0;\n      });\n    }\n    return result || reduce(array, function(result, value, index) {\n      return callback.call(thisArg, value, index, array) ? (result.push(value), result) : result;\n    }, []);\n  }\n\n  /**\n   * A generic `Array#forEach` like method.\n   * Callbacks may terminate the loop by explicitly returning `false`.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array} array The array to iterate over.\n   * @param {Function} callback The function called per iteration.\n   * @param {Mixed} thisArg The `this` binding for the callback.\n   * @returns {Array} Returns the array iterated over.\n   */\n  function forEach(array, callback, thisArg) {\n    var index = -1,\n        length = (array = Object(array)).length >>> 0;\n\n    if (thisArg !== undefined) {\n      callback = bind(callback, thisArg);\n    }\n    while (++index < length) {\n      if (index in array &&\n          callback(array[index], index, array) === false) {\n        break;\n      }\n    }\n    return array;\n  }\n\n  /**\n   * Iterates over an object's own properties, executing the `callback` for each.\n   * Callbacks may terminate the loop by explicitly returning `false`.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Object} object The object to iterate over.\n   * @param {Function} callback The function executed per own property.\n   * @param {Mixed} thisArg The `this` binding for the callback.\n   * @returns {Object} Returns the object iterated over.\n   */\n  function forOwn(object, callback, thisArg) {\n    return forProps(object, callback, { 'bind': thisArg, 'which': 'own' });\n  }\n\n  /**\n   * Converts a number to a more readable comma-separated string representation.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Number} number The number to convert.\n   * @returns {String} The more readable string representation.\n   */\n  function formatNumber(number) {\n    number = String(number).split('.');\n    return number[0].replace(/(?=(?:\\d{3})+$)(?!\\b)/g, ',') +\n      (number[1] ? '.' + number[1] : '');\n  }\n\n  /**\n   * Checks if an object has the specified key as a direct property.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Object} object The object to check.\n   * @param {String} key The key to check for.\n   * @returns {Boolean} Returns `true` if key is a direct property, else `false`.\n   */\n  function hasKey() {\n    // lazy define for worst case fallback (not as accurate)\n    hasKey = function(object, key) {\n      var parent = object != null && (object.constructor || Object).prototype;\n      return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]);\n    };\n    // for modern browsers\n    if (isClassOf(hasOwnProperty, 'Function')) {\n      hasKey = function(object, key) {\n        return object != null && hasOwnProperty.call(object, key);\n      };\n    }\n    // for Safari 2\n    else if ({}.__proto__ == Object.prototype) {\n      hasKey = function(object, key) {\n        var result = false;\n        if (object != null) {\n          object = Object(object);\n          object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];\n        }\n        return result;\n      };\n    }\n    return hasKey.apply(this, arguments);\n  }\n\n  /**\n   * A generic `Array#indexOf` like method.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array} array The array to iterate over.\n   * @param {Mixed} value The value to search for.\n   * @param {Number} [fromIndex=0] The index to start searching from.\n   * @returns {Number} The index of the matched value or `-1`.\n   */\n  function indexOf(array, value, fromIndex) {\n    var index = toInteger(fromIndex),\n        length = (array = Object(array)).length >>> 0;\n\n    index = (index < 0 ? max(0, length + index) : index) - 1;\n    while (++index < length) {\n      if (index in array && value === array[index]) {\n        return index;\n      }\n    }\n    return -1;\n  }\n\n  /**\n   * Modify a string by replacing named tokens with matching object property values.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {String} string The string to modify.\n   * @param {Object} object The template object.\n   * @returns {String} The modified string.\n   */\n  function interpolate(string, object) {\n    forOwn(object, function(value, key) {\n      // escape regexp special characters in `key`\n      string = string.replace(RegExp('#\\\\{' + key.replace(/([.*+?^=!:${}()|[\\]\\/\\\\])/g, '\\\\$1') + '\\\\}', 'g'), value);\n    });\n    return string;\n  }\n\n  /**\n   * Invokes a method on all items in an array.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array} benches Array of benchmarks to iterate over.\n   * @param {String|Object} name The name of the method to invoke OR options object.\n   * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.\n   * @returns {Array} A new array of values returned from each method invoked.\n   * @example\n   *\n   * // invoke `reset` on all benchmarks\n   * Benchmark.invoke(benches, 'reset');\n   *\n   * // invoke `emit` with arguments\n   * Benchmark.invoke(benches, 'emit', 'complete', listener);\n   *\n   * // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks\n   * Benchmark.invoke(benches, {\n   *\n   *   // invoke the `run` method\n   *   'name': 'run',\n   *\n   *   // pass a single argument\n   *   'args': true,\n   *\n   *   // treat as queue, removing benchmarks from front of `benches` until empty\n   *   'queued': true,\n   *\n   *   // called before any benchmarks have been invoked.\n   *   'onStart': onStart,\n   *\n   *   // called between invoking benchmarks\n   *   'onCycle': onCycle,\n   *\n   *   // called after all benchmarks have been invoked.\n   *   'onComplete': onComplete\n   * });\n   */\n  function invoke(benches, name) {\n    var args,\n        bench,\n        queued,\n        index = -1,\n        eventProps = { 'currentTarget': benches },\n        options = { 'onStart': noop, 'onCycle': noop, 'onComplete': noop },\n        result = map(benches, function(bench) { return bench; });\n\n    /**\n     * Invokes the method of the current object and if synchronous, fetches the next.\n     */\n    function execute() {\n      var listeners,\n          async = isAsync(bench);\n\n      if (async) {\n        // use `getNext` as the first listener\n        bench.on('complete', getNext);\n        listeners = bench.events.complete;\n        listeners.splice(0, 0, listeners.pop());\n      }\n      // execute method\n      result[index] = isClassOf(bench && bench[name], 'Function') ? bench[name].apply(bench, args) : undefined;\n      // if synchronous return true until finished\n      return !async && getNext();\n    }\n\n    /**\n     * Fetches the next bench or executes `onComplete` callback.\n     */\n    function getNext(event) {\n      var cycleEvent,\n          last = bench,\n          async = isAsync(last);\n\n      if (async) {\n        last.off('complete', getNext);\n        last.emit('complete');\n      }\n      // emit \"cycle\" event\n      eventProps.type = 'cycle';\n      eventProps.target = last;\n      cycleEvent = Event(eventProps);\n      options.onCycle.call(benches, cycleEvent);\n\n      // choose next benchmark if not exiting early\n      if (!cycleEvent.aborted && raiseIndex() !== false) {\n        bench = queued ? benches[0] : result[index];\n        if (isAsync(bench)) {\n          delay(bench, execute);\n        }\n        else if (async) {\n          // resume execution if previously asynchronous but now synchronous\n          while (execute()) { }\n        }\n        else {\n          // continue synchronous execution\n          return true;\n        }\n      } else {\n        // emit \"complete\" event\n        eventProps.type = 'complete';\n        options.onComplete.call(benches, Event(eventProps));\n      }\n      // When used as a listener `event.aborted = true` will cancel the rest of\n      // the \"complete\" listeners because they were already called above and when\n      // used as part of `getNext` the `return false` will exit the execution while-loop.\n      if (event) {\n        event.aborted = true;\n      } else {\n        return false;\n      }\n    }\n\n    /**\n     * Checks if invoking `Benchmark#run` with asynchronous cycles.\n     */\n    function isAsync(object) {\n      // avoid using `instanceof` here because of IE memory leak issues with host objects\n      var async = args[0] && args[0].async;\n      return Object(object).constructor == Benchmark && name == 'run' &&\n        ((async == null ? object.options.async : async) && support.timeout || object.defer);\n    }\n\n    /**\n     * Raises `index` to the next defined index or returns `false`.\n     */\n    function raiseIndex() {\n      var length = result.length;\n      if (queued) {\n        // if queued remove the previous bench and subsequent skipped non-entries\n        do {\n          ++index > 0 && shift.call(benches);\n        } while ((length = benches.length) && !('0' in benches));\n      }\n      else {\n        while (++index < length && !(index in result)) { }\n      }\n      // if we reached the last index then return `false`\n      return (queued ? length : index < length) ? index : (index = false);\n    }\n\n    // juggle arguments\n    if (isClassOf(name, 'String')) {\n      // 2 arguments (array, name)\n      args = slice.call(arguments, 2);\n    } else {\n      // 2 arguments (array, options)\n      options = extend(options, name);\n      name = options.name;\n      args = isClassOf(args = 'args' in options ? options.args : [], 'Array') ? args : [args];\n      queued = options.queued;\n    }\n\n    // start iterating over the array\n    if (raiseIndex() !== false) {\n      // emit \"start\" event\n      bench = result[index];\n      eventProps.type = 'start';\n      eventProps.target = bench;\n      options.onStart.call(benches, Event(eventProps));\n\n      // end early if the suite was aborted in an \"onStart\" listener\n      if (benches.aborted && benches.constructor == Suite && name == 'run') {\n        // emit \"cycle\" event\n        eventProps.type = 'cycle';\n        options.onCycle.call(benches, Event(eventProps));\n        // emit \"complete\" event\n        eventProps.type = 'complete';\n        options.onComplete.call(benches, Event(eventProps));\n      }\n      // else start\n      else {\n        if (isAsync(bench)) {\n          delay(bench, execute);\n        } else {\n          while (execute()) { }\n        }\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Creates a string of joined array values or object key-value pairs.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array|Object} object The object to operate on.\n   * @param {String} [separator1=','] The separator used between key-value pairs.\n   * @param {String} [separator2=': '] The separator used between keys and values.\n   * @returns {String} The joined result.\n   */\n  function join(object, separator1, separator2) {\n    var result = [],\n        length = (object = Object(object)).length,\n        arrayLike = length === length >>> 0;\n\n    separator2 || (separator2 = ': ');\n    each(object, function(value, key) {\n      result.push(arrayLike ? value : key + separator2 + value);\n    });\n    return result.join(separator1 || ',');\n  }\n\n  /**\n   * A generic `Array#map` like method.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array} array The array to iterate over.\n   * @param {Function} callback The function called per iteration.\n   * @param {Mixed} thisArg The `this` binding for the callback.\n   * @returns {Array} A new array of values returned by the callback.\n   */\n  function map(array, callback, thisArg) {\n    return reduce(array, function(result, value, index) {\n      result[index] = callback.call(thisArg, value, index, array);\n      return result;\n    }, Array(Object(array).length >>> 0));\n  }\n\n  /**\n   * Retrieves the value of a specified property from all items in an array.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array} array The array to iterate over.\n   * @param {String} property The property to pluck.\n   * @returns {Array} A new array of property values.\n   */\n  function pluck(array, property) {\n    return map(array, function(object) {\n      return object == null ? undefined : object[property];\n    });\n  }\n\n  /**\n   * A generic `Array#reduce` like method.\n   *\n   * @static\n   * @memberOf Benchmark\n   * @param {Array} array The array to iterate over.\n   * @param {Function} callback The function called per iteration.\n   * @param {Mixed} accumulator Initial value of the accumulator.\n   * @returns {Mixed} The accumulator.\n   */\n  function reduce(array, callback, accumulator) {\n    var noaccum = arguments.length < 3;\n    forEach(array, function(value, index) {\n      accumulator = noaccum ? (noaccum = false, value) : callback(accumulator, value, index, array);\n    });\n    return accumulator;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Aborts all benchmarks in the suite.\n   *\n   * @name abort\n   * @memberOf Benchmark.Suite\n   * @returns {Object} The suite instance.\n   */\n  function abortSuite() {\n    var event,\n        me = this,\n        resetting = calledBy.resetSuite;\n\n    if (me.running) {\n      event = Event('abort');\n      me.emit(event);\n      if (!event.cancelled || resetting) {\n        // avoid infinite recursion\n        calledBy.abortSuite = true;\n        me.reset();\n        delete calledBy.abortSuite;\n\n        if (!resetting) {\n          me.aborted = true;\n          invoke(me, 'abort');\n        }\n      }\n    }\n    return me;\n  }\n\n  /**\n   * Adds a test to the benchmark suite.\n   *\n   * @memberOf Benchmark.Suite\n   * @param {String} name A name to identify the benchmark.\n   * @param {Function|String} fn The test to benchmark.\n   * @param {Object} [options={}] Options object.\n   * @returns {Object} The benchmark instance.\n   * @example\n   *\n   * // basic usage\n   * suite.add(fn);\n   *\n   * // or using a name first\n   * suite.add('foo', fn);\n   *\n   * // or with options\n   * suite.add('foo', fn, {\n   *   'onCycle': onCycle,\n   *   'onComplete': onComplete\n   * });\n   *\n   * // or name and options\n   * suite.add('foo', {\n   *   'fn': fn,\n   *   'onCycle': onCycle,\n   *   'onComplete': onComplete\n   * });\n   *\n   * // or options only\n   * suite.add({\n   *   'name': 'foo',\n   *   'fn': fn,\n   *   'onCycle': onCycle,\n   *   'onComplete': onComplete\n   * });\n   */\n  function add(name, fn, options) {\n    var me = this,\n        bench = Benchmark(name, fn, options),\n        event = Event({ 'type': 'add', 'target': bench });\n\n    if (me.emit(event), !event.cancelled) {\n      me.push(bench);\n    }\n    return me;\n  }\n\n  /**\n   * Creates a new suite with cloned benchmarks.\n   *\n   * @name clone\n   * @memberOf Benchmark.Suite\n   * @param {Object} options Options object to overwrite cloned options.\n   * @returns {Object} The new suite instance.\n   */\n  function cloneSuite(options) {\n    var me = this,\n        result = new me.constructor(extend({}, me.options, options));\n\n    // copy own properties\n    forOwn(me, function(value, key) {\n      if (!hasKey(result, key)) {\n        result[key] = value && isClassOf(value.clone, 'Function')\n          ? value.clone()\n          : deepClone(value);\n      }\n    });\n    return result;\n  }\n\n  /**\n   * An `Array#filter` like method.\n   *\n   * @name filter\n   * @memberOf Benchmark.Suite\n   * @param {Function|String} callback The function/alias called per iteration.\n   * @returns {Object} A new suite of benchmarks that passed callback filter.\n   */\n  function filterSuite(callback) {\n    var me = this,\n        result = new me.constructor;\n\n    result.push.apply(result, filter(me, callback));\n    return result;\n  }\n\n  /**\n   * Resets all benchmarks in the suite.\n   *\n   * @name reset\n   * @memberOf Benchmark.Suite\n   * @returns {Object} The suite instance.\n   */\n  function resetSuite() {\n    var event,\n        me = this,\n        aborting = calledBy.abortSuite;\n\n    if (me.running && !aborting) {\n      // no worries, `resetSuite()` is called within `abortSuite()`\n      calledBy.resetSuite = true;\n      me.abort();\n      delete calledBy.resetSuite;\n    }\n    // reset if the state has changed\n    else if ((me.aborted || me.running) &&\n        (me.emit(event = Event('reset')), !event.cancelled)) {\n      me.running = false;\n      if (!aborting) {\n        invoke(me, 'reset');\n      }\n    }\n    return me;\n  }\n\n  /**\n   * Runs the suite.\n   *\n   * @name run\n   * @memberOf Benchmark.Suite\n   * @param {Object} [options={}] Options object.\n   * @returns {Object} The suite instance.\n   * @example\n   *\n   * // basic usage\n   * suite.run();\n   *\n   * // or with options\n   * suite.run({ 'async': true, 'queued': true });\n   */\n  function runSuite(options) {\n    var me = this;\n\n    me.reset();\n    me.running = true;\n    options || (options = {});\n\n    invoke(me, {\n      'name': 'run',\n      'args': options,\n      'queued': options.queued,\n      'onStart': function(event) {\n        me.emit(event);\n      },\n      'onCycle': function(event) {\n        var bench = event.target;\n        if (bench.error) {\n          me.emit({ 'type': 'error', 'target': bench });\n        }\n        me.emit(event);\n        event.aborted = me.aborted;\n      },\n      'onComplete': function(event) {\n        me.running = false;\n        me.emit(event);\n      }\n    });\n    return me;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Executes all registered listeners of the specified event type.\n   *\n   * @memberOf Benchmark, Benchmark.Suite\n   * @param {String|Object} type The event type or object.\n   * @returns {Mixed} Returns the return value of the last listener executed.\n   */\n  function emit(type) {\n    var listeners,\n        me = this,\n        event = Event(type),\n        events = me.events,\n        args = (arguments[0] = event, arguments);\n\n    event.currentTarget || (event.currentTarget = me);\n    event.target || (event.target = me);\n    delete event.result;\n\n    if (events && (listeners = hasKey(events, event.type) && events[event.type])) {\n      forEach(listeners.slice(), function(listener) {\n        if ((event.result = listener.apply(me, args)) === false) {\n          event.cancelled = true;\n        }\n        return !event.aborted;\n      });\n    }\n    return event.result;\n  }\n\n  /**\n   * Returns an array of event listeners for a given type that can be manipulated\n   * to add or remove listeners.\n   *\n   * @memberOf Benchmark, Benchmark.Suite\n   * @param {String} type The event type.\n   * @returns {Array} The listeners array.\n   */\n  function listeners(type) {\n    var me = this,\n        events = me.events || (me.events = {});\n\n    return hasKey(events, type) ? events[type] : (events[type] = []);\n  }\n\n  /**\n   * Unregisters a listener for the specified event type(s),\n   * or unregisters all listeners for the specified event type(s),\n   * or unregisters all listeners for all event types.\n   *\n   * @memberOf Benchmark, Benchmark.Suite\n   * @param {String} [type] The event type.\n   * @param {Function} [listener] The function to unregister.\n   * @returns {Object} The benchmark instance.\n   * @example\n   *\n   * // unregister a listener for an event type\n   * bench.off('cycle', listener);\n   *\n   * // unregister a listener for multiple event types\n   * bench.off('start cycle', listener);\n   *\n   * // unregister all listeners for an event type\n   * bench.off('cycle');\n   *\n   * // unregister all listeners for multiple event types\n   * bench.off('start cycle complete');\n   *\n   * // unregister all listeners for all event types\n   * bench.off();\n   */\n  function off(type, listener) {\n    var me = this,\n        events = me.events;\n\n    events && each(type ? type.split(' ') : events, function(listeners, type) {\n      var index;\n      if (typeof listeners == 'string') {\n        type = listeners;\n        listeners = hasKey(events, type) && events[type];\n      }\n      if (listeners) {\n        if (listener) {\n          index = indexOf(listeners, listener);\n          if (index > -1) {\n            listeners.splice(index, 1);\n          }\n        } else {\n          listeners.length = 0;\n        }\n      }\n    });\n    return me;\n  }\n\n  /**\n   * Registers a listener for the specified event type(s).\n   *\n   * @memberOf Benchmark, Benchmark.Suite\n   * @param {String} type The event type.\n   * @param {Function} listener The function to register.\n   * @returns {Object} The benchmark instance.\n   * @example\n   *\n   * // register a listener for an event type\n   * bench.on('cycle', listener);\n   *\n   * // register a listener for multiple event types\n   * bench.on('start cycle', listener);\n   */\n  function on(type, listener) {\n    var me = this,\n        events = me.events || (me.events = {});\n\n    forEach(type.split(' '), function(type) {\n      (hasKey(events, type)\n        ? events[type]\n        : (events[type] = [])\n      ).push(listener);\n    });\n    return me;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Aborts the benchmark without recording times.\n   *\n   * @memberOf Benchmark\n   * @returns {Object} The benchmark instance.\n   */\n  function abort() {\n    var event,\n        me = this,\n        resetting = calledBy.reset;\n\n    if (me.running) {\n      event = Event('abort');\n      me.emit(event);\n      if (!event.cancelled || resetting) {\n        // avoid infinite recursion\n        calledBy.abort = true;\n        me.reset();\n        delete calledBy.abort;\n\n        if (support.timeout) {\n          clearTimeout(me._timerId);\n          delete me._timerId;\n        }\n        if (!resetting) {\n          me.aborted = true;\n          me.running = false;\n        }\n      }\n    }\n    return me;\n  }\n\n  /**\n   * Creates a new benchmark using the same test and options.\n   *\n   * @memberOf Benchmark\n   * @param {Object} options Options object to overwrite cloned options.\n   * @returns {Object} The new benchmark instance.\n   * @example\n   *\n   * var bizarro = bench.clone({\n   *   'name': 'doppelganger'\n   * });\n   */\n  function clone(options) {\n    var me = this,\n        result = new me.constructor(extend({}, me, options));\n\n    // correct the `options` object\n    result.options = extend({}, me.options, options);\n\n    // copy own custom properties\n    forOwn(me, function(value, key) {\n      if (!hasKey(result, key)) {\n        result[key] = deepClone(value);\n      }\n    });\n    return result;\n  }\n\n  /**\n   * Determines if a benchmark is faster than another.\n   *\n   * @memberOf Benchmark\n   * @param {Object} other The benchmark to compare.\n   * @returns {Number} Returns `-1` if slower, `1` if faster, and `0` if indeterminate.\n   */\n  function compare(other) {\n    var critical,\n        zStat,\n        me = this,\n        sample1 = me.stats.sample,\n        sample2 = other.stats.sample,\n        size1 = sample1.length,\n        size2 = sample2.length,\n        maxSize = max(size1, size2),\n        minSize = min(size1, size2),\n        u1 = getU(sample1, sample2),\n        u2 = getU(sample2, sample1),\n        u = min(u1, u2);\n\n    function getScore(xA, sampleB) {\n      return reduce(sampleB, function(total, xB) {\n        return total + (xB > xA ? 0 : xB < xA ? 1 : 0.5);\n      }, 0);\n    }\n\n    function getU(sampleA, sampleB) {\n      return reduce(sampleA, function(total, xA) {\n        return total + getScore(xA, sampleB);\n      }, 0);\n    }\n\n    function getZ(u) {\n      return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12);\n    }\n\n    // exit early if comparing the same benchmark\n    if (me == other) {\n      return 0;\n    }\n    // reject the null hypothesis the two samples come from the\n    // same population (i.e. have the same median) if...\n    if (size1 + size2 > 30) {\n      // ...the z-stat is greater than 1.96 or less than -1.96\n      // http://www.statisticslectures.com/topics/mannwhitneyu/\n      zStat = getZ(u);\n      return abs(zStat) > 1.96 ? (zStat > 0 ? -1 : 1) : 0;\n    }\n    // ...the U value is less than or equal the critical U value\n    // http://www.geoib.com/mann-whitney-u-test.html\n    critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3];\n    return u <= critical ? (u == u1 ? 1 : -1) : 0;\n  }\n\n  /**\n   * Reset properties and abort if running.\n   *\n   * @memberOf Benchmark\n   * @returns {Object} The benchmark instance.\n   */\n  function reset() {\n    var data,\n        event,\n        me = this,\n        index = 0,\n        changes = { 'length': 0 },\n        queue = { 'length': 0 };\n\n    if (me.running && !calledBy.abort) {\n      // no worries, `reset()` is called within `abort()`\n      calledBy.reset = true;\n      me.abort();\n      delete calledBy.reset;\n    }\n    else {\n      // a non-recursive solution to check if properties have changed\n      // http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4\n      data = { 'destination': me, 'source': extend({}, me.constructor.prototype, me.options) };\n      do {\n        forOwn(data.source, function(value, key) {\n          var changed,\n              destination = data.destination,\n              currValue = destination[key];\n\n          if (value && typeof value == 'object') {\n            if (isClassOf(value, 'Array')) {\n              // check if an array value has changed to a non-array value\n              if (!isClassOf(currValue, 'Array')) {\n                changed = currValue = [];\n              }\n              // or has changed its length\n              if (currValue.length != value.length) {\n                changed = currValue = currValue.slice(0, value.length);\n                currValue.length = value.length;\n              }\n            }\n            // check if an object has changed to a non-object value\n            else if (!currValue || typeof currValue != 'object') {\n              changed = currValue = {};\n            }\n            // register a changed object\n            if (changed) {\n              changes[changes.length++] = { 'destination': destination, 'key': key, 'value': currValue };\n            }\n            queue[queue.length++] = { 'destination': currValue, 'source': value };\n          }\n          // register a changed primitive\n          else if (value !== currValue && !(value == null || isClassOf(value, 'Function'))) {\n            changes[changes.length++] = { 'destination': destination, 'key': key, 'value': value };\n          }\n        });\n      }\n      while ((data = queue[index++]));\n\n      // if changed emit the `reset` event and if it isn't cancelled reset the benchmark\n      if (changes.length && (me.emit(event = Event('reset')), !event.cancelled)) {\n        forEach(changes, function(data) {\n          data.destination[data.key] = data.value;\n        });\n      }\n    }\n    return me;\n  }\n\n  /**\n   * Displays relevant benchmark information when coerced to a string.\n   *\n   * @name toString\n   * @memberOf Benchmark\n   * @returns {String} A string representation of the benchmark instance.\n   */\n  function toStringBench() {\n    var me = this,\n        error = me.error,\n        hz = me.hz,\n        id = me.id,\n        stats = me.stats,\n        size = stats.sample.length,\n        pm = support.java ? '+/-' : '\\xb1',\n        result = me.name || (isNaN(id) ? id : '<Test #' + id + '>');\n\n    if (error) {\n      result += ': ' + join(error);\n    } else {\n      result += ' x ' + formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + ' ops/sec ' + pm +\n        stats.rme.toFixed(2) + '% (' + size + ' run' + (size == 1 ? '' : 's') + ' sampled)';\n    }\n    return result;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Clocks the time taken to execute a test per cycle (secs).\n   *\n   * @private\n   * @param {Object} bench The benchmark instance.\n   * @returns {Number} The time taken.\n   */\n  function clock() {\n    var applet,\n        options = Benchmark.options,\n        template = { 'begin': 's$=new n$', 'end': 'r$=(new n$-s$)/1e3', 'uid': uid },\n        timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }];\n\n    // lazy define for hi-res timers\n    clock = function(clone) {\n      var deferred;\n      if (clone instanceof Deferred) {\n        deferred = clone;\n        clone = deferred.benchmark;\n      }\n\n      var bench = clone._original,\n          fn = bench.fn,\n          fnArg = deferred ? getFirstArgument(fn) || 'deferred' : '',\n          stringable = isStringable(fn);\n\n      var source = {\n        'setup': getSource(bench.setup, preprocess('m$.setup()')),\n        'fn': getSource(fn, preprocess('m$.fn(' + fnArg + ')')),\n        'fnArg': fnArg,\n        'teardown': getSource(bench.teardown, preprocess('m$.teardown()'))\n      };\n\n      var count = bench.count = clone.count,\n          decompilable = support.decompilation || stringable,\n          id = bench.id,\n          isEmpty = !(source.fn || stringable),\n          name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id),\n          ns = timer.ns,\n          result = 0;\n\n      // init `minTime` if needed\n      clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime);\n\n      // repair nanosecond timer\n      // (some Chrome builds erase the `ns` variable after millions of executions)\n      if (applet) {\n        try {\n          ns.nanoTime();\n        } catch(e) {\n          // use non-element to avoid issues with libs that augment them\n          ns = timer.ns = new applet.Packages.nano;\n        }\n      }\n\n      // Compile in setup/teardown functions and the test loop.\n      // Create a new compiled test, instead of using the cached `bench.compiled`,\n      // to avoid potential engine optimizations enabled over the life of the test.\n      var compiled = bench.compiled = createFunction(preprocess('t$'), interpolate(\n        preprocess(deferred\n          ? 'var d$=this,#{fnArg}=d$,m$=d$.benchmark._original,f$=m$.fn,su$=m$.setup,td$=m$.teardown;' +\n            // when `deferred.cycles` is `0` then...\n            'if(!d$.cycles){' +\n            // set `deferred.fn`\n            'd$.fn=function(){var #{fnArg}=d$;if(typeof f$==\"function\"){try{#{fn}\\n}catch(e$){f$(d$)}}else{#{fn}\\n}};' +\n            // set `deferred.teardown`\n            'd$.teardown=function(){d$.cycles=0;if(typeof td$==\"function\"){try{#{teardown}\\n}catch(e$){td$()}}else{#{teardown}\\n}};' +\n            // execute the benchmark's `setup`\n            'if(typeof su$==\"function\"){try{#{setup}\\n}catch(e$){su$()}}else{#{setup}\\n};' +\n            // start timer\n            't$.start(d$);' +\n            // execute `deferred.fn` and return a dummy object\n            '}d$.fn();return{}'\n\n          : 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count,n$=t$.ns;#{setup}\\n#{begin};' +\n            'while(i$--){#{fn}\\n}#{end};#{teardown}\\nreturn{elapsed:r$,uid:\"#{uid}\"}'),\n        source\n      ));\n\n      try {\n        if (isEmpty) {\n          // Firefox may remove dead code from Function#toString results\n          // http://bugzil.la/536085\n          throw new Error('The test \"' + name + '\" is empty. This may be the result of dead code removal.');\n        }\n        else if (!deferred) {\n          // pretest to determine if compiled code is exits early, usually by a\n          // rogue `return` statement, by checking for a return object with the uid\n          bench.count = 1;\n          compiled = (compiled.call(bench, timer) || {}).uid == uid && compiled;\n          bench.count = count;\n        }\n      } catch(e) {\n        compiled = null;\n        clone.error = e || new Error(String(e));\n        bench.count = count;\n      }\n      // fallback when a test exits early or errors during pretest\n      if (decompilable && !compiled && !deferred && !isEmpty) {\n        compiled = createFunction(preprocess('t$'), interpolate(\n          preprocess(\n            (clone.error && !stringable\n              ? 'var r$,s$,m$=this,f$=m$.fn,i$=m$.count'\n              : 'function f$(){#{fn}\\n}var r$,s$,m$=this,i$=m$.count'\n            ) +\n            ',n$=t$.ns;#{setup}\\n#{begin};m$.f$=f$;while(i$--){m$.f$()}#{end};' +\n            'delete m$.f$;#{teardown}\\nreturn{elapsed:r$}'\n          ),\n          source\n        ));\n\n        try {\n          // pretest one more time to check for errors\n          bench.count = 1;\n          compiled.call(bench, timer);\n          bench.compiled = compiled;\n          bench.count = count;\n          delete clone.error;\n        }\n        catch(e) {\n          bench.count = count;\n          if (clone.error) {\n            compiled = null;\n          } else {\n            bench.compiled = compiled;\n            clone.error = e || new Error(String(e));\n          }\n        }\n      }\n      // assign `compiled` to `clone` before calling in case a deferred benchmark\n      // immediately calls `deferred.resolve()`\n      clone.compiled = compiled;\n      // if no errors run the full test loop\n      if (!clone.error) {\n        result = compiled.call(deferred || bench, timer).elapsed;\n      }\n      return result;\n    };\n\n    /*------------------------------------------------------------------------*/\n\n    /**\n     * Gets the current timer's minimum resolution (secs).\n     */\n    function getRes(unit) {\n      var measured,\n          begin,\n          count = 30,\n          divisor = 1e3,\n          ns = timer.ns,\n          sample = [];\n\n      // get average smallest measurable time\n      while (count--) {\n        if (unit == 'us') {\n          divisor = 1e6;\n          if (ns.stop) {\n            ns.start();\n            while (!(measured = ns.microseconds())) { }\n          } else if (ns[perfName]) {\n            divisor = 1e3;\n            measured = Function('n', 'var r,s=n.' + perfName + '();while(!(r=n.' + perfName + '()-s)){};return r')(ns);\n          } else {\n            begin = ns();\n            while (!(measured = ns() - begin)) { }\n          }\n        }\n        else if (unit == 'ns') {\n          divisor = 1e9;\n          if (ns.nanoTime) {\n            begin = ns.nanoTime();\n            while (!(measured = ns.nanoTime() - begin)) { }\n          } else {\n            begin = (begin = ns())[0] + (begin[1] / divisor);\n            while (!(measured = ((measured = ns())[0] + (measured[1] / divisor)) - begin)) { }\n            divisor = 1;\n          }\n        }\n        else {\n          begin = new ns;\n          while (!(measured = new ns - begin)) { }\n        }\n        // check for broken timers (nanoTime may have issues)\n        // http://alivebutsleepy.srnet.cz/unreliable-system-nanotime/\n        if (measured > 0) {\n          sample.push(measured);\n        } else {\n          sample.push(Infinity);\n          break;\n        }\n      }\n      // convert to seconds\n      return getMean(sample) / divisor;\n    }\n\n    /**\n     * Replaces all occurrences of `$` with a unique number and\n     * template tokens with content.\n     */\n    function preprocess(code) {\n      return interpolate(code, template).replace(/\\$/g, /\\d+/.exec(uid));\n    }\n\n    /*------------------------------------------------------------------------*/\n\n    // detect nanosecond support from a Java applet\n    each(doc && doc.applets || [], function(element) {\n      return !(timer.ns = applet = 'nanoTime' in element && element);\n    });\n\n    // check type in case Safari returns an object instead of a number\n    try {\n      if (typeof timer.ns.nanoTime() == 'number') {\n        timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' });\n      }\n    } catch(e) { }\n\n    // detect Chrome's microsecond timer:\n    // enable benchmarking via the --enable-benchmarking command\n    // line switch in at least Chrome 7 to use chrome.Interval\n    try {\n      if ((timer.ns = new (window.chrome || window.chromium).Interval)) {\n        timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });\n      }\n    } catch(e) { }\n\n    // detect `performance.now` microsecond resolution timer\n    if ((timer.ns = perfName && perfObject)) {\n      timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' });\n    }\n\n    // detect Node's nanosecond resolution timer available in Node >= 0.8\n    if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') {\n      timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' });\n    }\n\n    // detect Wade Simmons' Node microtime module\n    if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') {\n      timers.push({ 'ns': timer.ns,  'res': getRes('us'), 'unit': 'us' });\n    }\n\n    // pick timer with highest resolution\n    timer = reduce(timers, function(timer, other) {\n      return other.res < timer.res ? other : timer;\n    });\n\n    // remove unused applet\n    if (timer.unit != 'ns' && applet) {\n      applet = destroyElement(applet);\n    }\n    // error if there are no working timers\n    if (timer.res == Infinity) {\n      throw new Error('Benchmark.js was unable to find a working timer.');\n    }\n    // use API of chosen timer\n    if (timer.unit == 'ns') {\n      if (timer.ns.nanoTime) {\n        extend(template, {\n          'begin': 's$=n$.nanoTime()',\n          'end': 'r$=(n$.nanoTime()-s$)/1e9'\n        });\n      } else {\n        extend(template, {\n          'begin': 's$=n$()',\n          'end': 'r$=n$(s$);r$=r$[0]+(r$[1]/1e9)'\n        });\n      }\n    }\n    else if (timer.unit == 'us') {\n      if (timer.ns.stop) {\n        extend(template, {\n          'begin': 's$=n$.start()',\n          'end': 'r$=n$.microseconds()/1e6'\n        });\n      } else if (perfName) {\n        extend(template, {\n          'begin': 's$=n$.' + perfName + '()',\n          'end': 'r$=(n$.' + perfName + '()-s$)/1e3'\n        });\n      } else {\n        extend(template, {\n          'begin': 's$=n$()',\n          'end': 'r$=(n$()-s$)/1e6'\n        });\n      }\n    }\n\n    // define `timer` methods\n    timer.start = createFunction(preprocess('o$'),\n      preprocess('var n$=this.ns,#{begin};o$.elapsed=0;o$.timeStamp=s$'));\n\n    timer.stop = createFunction(preprocess('o$'),\n      preprocess('var n$=this.ns,s$=o$.timeStamp,#{end};o$.elapsed=r$'));\n\n    // resolve time span required to achieve a percent uncertainty of at most 1%\n    // http://spiff.rit.edu/classes/phys273/uncert/uncert.html\n    options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05));\n    return clock.apply(null, arguments);\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Computes stats on benchmark results.\n   *\n   * @private\n   * @param {Object} bench The benchmark instance.\n   * @param {Object} options The options object.\n   */\n  function compute(bench, options) {\n    options || (options = {});\n\n    var async = options.async,\n        elapsed = 0,\n        initCount = bench.initCount,\n        minSamples = bench.minSamples,\n        queue = [],\n        sample = bench.stats.sample;\n\n    /**\n     * Adds a clone to the queue.\n     */\n    function enqueue() {\n      queue.push(bench.clone({\n        '_original': bench,\n        'events': {\n          'abort': [update],\n          'cycle': [update],\n          'error': [update],\n          'start': [update]\n        }\n      }));\n    }\n\n    /**\n     * Updates the clone/original benchmarks to keep their data in sync.\n     */\n    function update(event) {\n      var clone = this,\n          type = event.type;\n\n      if (bench.running) {\n        if (type == 'start') {\n          // Note: `clone.minTime` prop is inited in `clock()`\n          clone.count = bench.initCount;\n        }\n        else {\n          if (type == 'error') {\n            bench.error = clone.error;\n          }\n          if (type == 'abort') {\n            bench.abort();\n            bench.emit('cycle');\n          } else {\n            event.currentTarget = event.target = bench;\n            bench.emit(event);\n          }\n        }\n      } else if (bench.aborted) {\n        // clear abort listeners to avoid triggering bench's abort/cycle again\n        clone.events.abort.length = 0;\n        clone.abort();\n      }\n    }\n\n    /**\n     * Determines if more clones should be queued or if cycling should stop.\n     */\n    function evaluate(event) {\n      var critical,\n          df,\n          mean,\n          moe,\n          rme,\n          sd,\n          sem,\n          variance,\n          clone = event.target,\n          done = bench.aborted,\n          now = +new Date,\n          size = sample.push(clone.times.period),\n          maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime,\n          times = bench.times,\n          varOf = function(sum, x) { return sum + pow(x - mean, 2); };\n\n      // exit early for aborted or unclockable tests\n      if (done || clone.hz == Infinity) {\n        maxedOut = !(size = sample.length = queue.length = 0);\n      }\n\n      if (!done) {\n        // sample mean (estimate of the population mean)\n        mean = getMean(sample);\n        // sample variance (estimate of the population variance)\n        variance = reduce(sample, varOf, 0) / (size - 1) || 0;\n        // sample standard deviation (estimate of the population standard deviation)\n        sd = sqrt(variance);\n        // standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean)\n        sem = sd / sqrt(size);\n        // degrees of freedom\n        df = size - 1;\n        // critical value\n        critical = tTable[Math.round(df) || 1] || tTable.infinity;\n        // margin of error\n        moe = sem * critical;\n        // relative margin of error\n        rme = (moe / mean) * 100 || 0;\n\n        extend(bench.stats, {\n          'deviation': sd,\n          'mean': mean,\n          'moe': moe,\n          'rme': rme,\n          'sem': sem,\n          'variance': variance\n        });\n\n        // Abort the cycle loop when the minimum sample size has been collected\n        // and the elapsed time exceeds the maximum time allowed per benchmark.\n        // We don't count cycle delays toward the max time because delays may be\n        // increased by browsers that clamp timeouts for inactive tabs.\n        // https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs\n        if (maxedOut) {\n          // reset the `initCount` in case the benchmark is rerun\n          bench.initCount = initCount;\n          bench.running = false;\n          done = true;\n          times.elapsed = (now - times.timeStamp) / 1e3;\n        }\n        if (bench.hz != Infinity) {\n          bench.hz = 1 / mean;\n          times.cycle = mean * bench.count;\n          times.period = mean;\n        }\n      }\n      // if time permits, increase sample size to reduce the margin of error\n      if (queue.length < 2 && !maxedOut) {\n        enqueue();\n      }\n      // abort the invoke cycle when done\n      event.aborted = done;\n    }\n\n    // init queue and begin\n    enqueue();\n    invoke(queue, {\n      'name': 'run',\n      'args': { 'async': async },\n      'queued': true,\n      'onCycle': evaluate,\n      'onComplete': function() { bench.emit('complete'); }\n    });\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Cycles a benchmark until a run `count` can be established.\n   *\n   * @private\n   * @param {Object} clone The cloned benchmark instance.\n   * @param {Object} options The options object.\n   */\n  function cycle(clone, options) {\n    options || (options = {});\n\n    var deferred;\n    if (clone instanceof Deferred) {\n      deferred = clone;\n      clone = clone.benchmark;\n    }\n\n    var clocked,\n        cycles,\n        divisor,\n        event,\n        minTime,\n        period,\n        async = options.async,\n        bench = clone._original,\n        count = clone.count,\n        times = clone.times;\n\n    // continue, if not aborted between cycles\n    if (clone.running) {\n      // `minTime` is set to `Benchmark.options.minTime` in `clock()`\n      cycles = ++clone.cycles;\n      clocked = deferred ? deferred.elapsed : clock(clone);\n      minTime = clone.minTime;\n\n      if (cycles > bench.cycles) {\n        bench.cycles = cycles;\n      }\n      if (clone.error) {\n        event = Event('error');\n        event.message = clone.error;\n        clone.emit(event);\n        if (!event.cancelled) {\n          clone.abort();\n        }\n      }\n    }\n\n    // continue, if not errored\n    if (clone.running) {\n      // time taken to complete last test cycle\n      bench.times.cycle = times.cycle = clocked;\n      // seconds per operation\n      period = bench.times.period = times.period = clocked / count;\n      // ops per second\n      bench.hz = clone.hz = 1 / period;\n      // avoid working our way up to this next time\n      bench.initCount = clone.initCount = count;\n      // do we need to do another cycle?\n      clone.running = clocked < minTime;\n\n      if (clone.running) {\n        // tests may clock at `0` when `initCount` is a small number,\n        // to avoid that we set its count to something a bit higher\n        if (!clocked && (divisor = divisors[clone.cycles]) != null) {\n          count = floor(4e6 / divisor);\n        }\n        // calculate how many more iterations it will take to archive the `minTime`\n        if (count <= clone.count) {\n          count += Math.ceil((minTime - clocked) / period);\n        }\n        clone.running = count != Infinity;\n      }\n    }\n    // should we exit early?\n    event = Event('cycle');\n    clone.emit(event);\n    if (event.aborted) {\n      clone.abort();\n    }\n    // figure out what to do next\n    if (clone.running) {\n      // start a new cycle\n      clone.count = count;\n      if (deferred) {\n        clone.compiled.call(deferred, timer);\n      } else if (async) {\n        delay(clone, function() { cycle(clone, options); });\n      } else {\n        cycle(clone);\n      }\n    }\n    else {\n      // fix TraceMonkey bug associated with clock fallbacks\n      // http://bugzil.la/509069\n      if (support.browser) {\n        runScript(uid + '=1;delete ' + uid);\n      }\n      // done\n      clone.emit('complete');\n    }\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * Runs the benchmark.\n   *\n   * @memberOf Benchmark\n   * @param {Object} [options={}] Options object.\n   * @returns {Object} The benchmark instance.\n   * @example\n   *\n   * // basic usage\n   * bench.run();\n   *\n   * // or with options\n   * bench.run({ 'async': true });\n   */\n  function run(options) {\n    var me = this,\n        event = Event('start');\n\n    // set `running` to `false` so `reset()` won't call `abort()`\n    me.running = false;\n    me.reset();\n    me.running = true;\n\n    me.count = me.initCount;\n    me.times.timeStamp = +new Date;\n    me.emit(event);\n\n    if (!event.cancelled) {\n      options = { 'async': ((options = options && options.async) == null ? me.async : options) && support.timeout };\n\n      // for clones created within `compute()`\n      if (me._original) {\n        if (me.defer) {\n          Deferred(me);\n        } else {\n          cycle(me, options);\n        }\n      }\n      // for original benchmarks\n      else {\n        compute(me, options);\n      }\n    }\n    return me;\n  }\n\n  /*--------------------------------------------------------------------------*/\n\n  // Firefox 1 erroneously defines variable and argument names of functions on\n  // the function itself as non-configurable properties with `undefined` values.\n  // The bugginess continues as the `Benchmark` constructor has an argument\n  // named `options` and Firefox 1 will not assign a value to `Benchmark.options`,\n  // making it non-writable in the process, unless it is the first property\n  // assigned by for-in loop of `extend()`.\n  extend(Benchmark, {\n\n    /**\n     * The default options copied by benchmark instances.\n     *\n     * @static\n     * @memberOf Benchmark\n     * @type Object\n     */\n    'options': {\n\n      /**\n       * A flag to indicate that benchmark cycles will execute asynchronously\n       * by default.\n       *\n       * @memberOf Benchmark.options\n       * @type Boolean\n       */\n      'async': false,\n\n      /**\n       * A flag to indicate that the benchmark clock is deferred.\n       *\n       * @memberOf Benchmark.options\n       * @type Boolean\n       */\n      'defer': false,\n\n      /**\n       * The delay between test cycles (secs).\n       * @memberOf Benchmark.options\n       * @type Number\n       */\n      'delay': 0.005,\n\n      /**\n       * Displayed by Benchmark#toString when a `name` is not available\n       * (auto-generated if absent).\n       *\n       * @memberOf Benchmark.options\n       * @type String\n       */\n      'id': undefined,\n\n      /**\n       * The default number of times to execute a test on a benchmark's first cycle.\n       *\n       * @memberOf Benchmark.options\n       * @type Number\n       */\n      'initCount': 1,\n\n      /**\n       * The maximum time a benchmark is allowed to run before finishing (secs).\n       *\n       * Note: Cycle delays aren't counted toward the maximum time.\n       *\n       * @memberOf Benchmark.options\n       * @type Number\n       */\n      'maxTime': 5,\n\n      /**\n       * The minimum sample size required to perform statistical analysis.\n       *\n       * @memberOf Benchmark.options\n       * @type Number\n       */\n      'minSamples': 5,\n\n      /**\n       * The time needed to reduce the percent uncertainty of measurement to 1% (secs).\n       *\n       * @memberOf Benchmark.options\n       * @type Number\n       */\n      'minTime': 0,\n\n      /**\n       * The name of the benchmark.\n       *\n       * @memberOf Benchmark.options\n       * @type String\n       */\n      'name': undefined,\n\n      /**\n       * An event listener called when the benchmark is aborted.\n       *\n       * @memberOf Benchmark.options\n       * @type Function\n       */\n      'onAbort': undefined,\n\n      /**\n       * An event listener called when the benchmark completes running.\n       *\n       * @memberOf Benchmark.options\n       * @type Function\n       */\n      'onComplete': undefined,\n\n      /**\n       * An event listener called after each run cycle.\n       *\n       * @memberOf Benchmark.options\n       * @type Function\n       */\n      'onCycle': undefined,\n\n      /**\n       * An event listener called when a test errors.\n       *\n       * @memberOf Benchmark.options\n       * @type Function\n       */\n      'onError': undefined,\n\n      /**\n       * An event listener called when the benchmark is reset.\n       *\n       * @memberOf Benchmark.options\n       * @type Function\n       */\n      'onReset': undefined,\n\n      /**\n       * An event listener called when the benchmark starts running.\n       *\n       * @memberOf Benchmark.options\n       * @type Function\n       */\n      'onStart': undefined\n    },\n\n    /**\n     * Platform object with properties describing things like browser name,\n     * version, and operating system.\n     *\n     * @static\n     * @memberOf Benchmark\n     * @type Object\n     */\n    'platform': req('platform') || window.platform || {\n\n      /**\n       * The platform description.\n       *\n       * @memberOf Benchmark.platform\n       * @type String\n       */\n      'description': window.navigator && navigator.userAgent || null,\n\n      /**\n       * The name of the browser layout engine.\n       *\n       * @memberOf Benchmark.platform\n       * @type String|Null\n       */\n      'layout': null,\n\n      /**\n       * The name of the product hosting the browser.\n       *\n       * @memberOf Benchmark.platform\n       * @type String|Null\n       */\n      'product': null,\n\n      /**\n       * The name of the browser/environment.\n       *\n       * @memberOf Benchmark.platform\n       * @type String|Null\n       */\n      'name': null,\n\n      /**\n       * The name of the product's manufacturer.\n       *\n       * @memberOf Benchmark.platform\n       * @type String|Null\n       */\n      'manufacturer': null,\n\n      /**\n       * The name of the operating system.\n       *\n       * @memberOf Benchmark.platform\n       * @type String|Null\n       */\n      'os': null,\n\n      /**\n       * The alpha/beta release indicator.\n       *\n       * @memberOf Benchmark.platform\n       * @type String|Null\n       */\n      'prerelease': null,\n\n      /**\n       * The browser/environment version.\n       *\n       * @memberOf Benchmark.platform\n       * @type String|Null\n       */\n      'version': null,\n\n      /**\n       * Return platform description when the platform object is coerced to a string.\n       *\n       * @memberOf Benchmark.platform\n       * @type Function\n       * @returns {String} The platform description.\n       */\n      'toString': function() {\n        return this.description || '';\n      }\n    },\n\n    /**\n     * The semantic version number.\n     *\n     * @static\n     * @memberOf Benchmark\n     * @type String\n     */\n    'version': '1.0.0',\n\n    // an object of environment/feature detection flags\n    'support': support,\n\n    // clone objects\n    'deepClone': deepClone,\n\n    // iteration utility\n    'each': each,\n\n    // augment objects\n    'extend': extend,\n\n    // generic Array#filter\n    'filter': filter,\n\n    // generic Array#forEach\n    'forEach': forEach,\n\n    // generic own property iteration utility\n    'forOwn': forOwn,\n\n    // converts a number to a comma-separated string\n    'formatNumber': formatNumber,\n\n    // generic Object#hasOwnProperty\n    // (trigger hasKey's lazy define before assigning it to Benchmark)\n    'hasKey': (hasKey(Benchmark, ''), hasKey),\n\n    // generic Array#indexOf\n    'indexOf': indexOf,\n\n    // template utility\n    'interpolate': interpolate,\n\n    // invokes a method on each item in an array\n    'invoke': invoke,\n\n    // generic Array#join for arrays and objects\n    'join': join,\n\n    // generic Array#map\n    'map': map,\n\n    // retrieves a property value from each item in an array\n    'pluck': pluck,\n\n    // generic Array#reduce\n    'reduce': reduce\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  extend(Benchmark.prototype, {\n\n    /**\n     * The number of times a test was executed.\n     *\n     * @memberOf Benchmark\n     * @type Number\n     */\n    'count': 0,\n\n    /**\n     * The number of cycles performed while benchmarking.\n     *\n     * @memberOf Benchmark\n     * @type Number\n     */\n    'cycles': 0,\n\n    /**\n     * The number of executions per second.\n     *\n     * @memberOf Benchmark\n     * @type Number\n     */\n    'hz': 0,\n\n    /**\n     * The compiled test function.\n     *\n     * @memberOf Benchmark\n     * @type Function|String\n     */\n    'compiled': undefined,\n\n    /**\n     * The error object if the test failed.\n     *\n     * @memberOf Benchmark\n     * @type Object\n     */\n    'error': undefined,\n\n    /**\n     * The test to benchmark.\n     *\n     * @memberOf Benchmark\n     * @type Function|String\n     */\n    'fn': undefined,\n\n    /**\n     * A flag to indicate if the benchmark is aborted.\n     *\n     * @memberOf Benchmark\n     * @type Boolean\n     */\n    'aborted': false,\n\n    /**\n     * A flag to indicate if the benchmark is running.\n     *\n     * @memberOf Benchmark\n     * @type Boolean\n     */\n    'running': false,\n\n    /**\n     * Compiled into the test and executed immediately **before** the test loop.\n     *\n     * @memberOf Benchmark\n     * @type Function|String\n     * @example\n     *\n     * // basic usage\n     * var bench = Benchmark({\n     *   'setup': function() {\n     *     var c = this.count,\n     *         element = document.getElementById('container');\n     *     while (c--) {\n     *       element.appendChild(document.createElement('div'));\n     *     }\n     *   },\n     *   'fn': function() {\n     *     element.removeChild(element.lastChild);\n     *   }\n     * });\n     *\n     * // compiles to something like:\n     * var c = this.count,\n     *     element = document.getElementById('container');\n     * while (c--) {\n     *   element.appendChild(document.createElement('div'));\n     * }\n     * var start = new Date;\n     * while (count--) {\n     *   element.removeChild(element.lastChild);\n     * }\n     * var end = new Date - start;\n     *\n     * // or using strings\n     * var bench = Benchmark({\n     *   'setup': '\\\n     *     var a = 0;\\n\\\n     *     (function() {\\n\\\n     *       (function() {\\n\\\n     *         (function() {',\n     *   'fn': 'a += 1;',\n     *   'teardown': '\\\n     *          }())\\n\\\n     *        }())\\n\\\n     *      }())'\n     * });\n     *\n     * // compiles to something like:\n     * var a = 0;\n     * (function() {\n     *   (function() {\n     *     (function() {\n     *       var start = new Date;\n     *       while (count--) {\n     *         a += 1;\n     *       }\n     *       var end = new Date - start;\n     *     }())\n     *   }())\n     * }())\n     */\n    'setup': noop,\n\n    /**\n     * Compiled into the test and executed immediately **after** the test loop.\n     *\n     * @memberOf Benchmark\n     * @type Function|String\n     */\n    'teardown': noop,\n\n    /**\n     * An object of stats including mean, margin or error, and standard deviation.\n     *\n     * @memberOf Benchmark\n     * @type Object\n     */\n    'stats': {\n\n      /**\n       * The margin of error.\n       *\n       * @memberOf Benchmark#stats\n       * @type Number\n       */\n      'moe': 0,\n\n      /**\n       * The relative margin of error (expressed as a percentage of the mean).\n       *\n       * @memberOf Benchmark#stats\n       * @type Number\n       */\n      'rme': 0,\n\n      /**\n       * The standard error of the mean.\n       *\n       * @memberOf Benchmark#stats\n       * @type Number\n       */\n      'sem': 0,\n\n      /**\n       * The sample standard deviation.\n       *\n       * @memberOf Benchmark#stats\n       * @type Number\n       */\n      'deviation': 0,\n\n      /**\n       * The sample arithmetic mean.\n       *\n       * @memberOf Benchmark#stats\n       * @type Number\n       */\n      'mean': 0,\n\n      /**\n       * The array of sampled periods.\n       *\n       * @memberOf Benchmark#stats\n       * @type Array\n       */\n      'sample': [],\n\n      /**\n       * The sample variance.\n       *\n       * @memberOf Benchmark#stats\n       * @type Number\n       */\n      'variance': 0\n    },\n\n    /**\n     * An object of timing data including cycle, elapsed, period, start, and stop.\n     *\n     * @memberOf Benchmark\n     * @type Object\n     */\n    'times': {\n\n      /**\n       * The time taken to complete the last cycle (secs).\n       *\n       * @memberOf Benchmark#times\n       * @type Number\n       */\n      'cycle': 0,\n\n      /**\n       * The time taken to complete the benchmark (secs).\n       *\n       * @memberOf Benchmark#times\n       * @type Number\n       */\n      'elapsed': 0,\n\n      /**\n       * The time taken to execute the test once (secs).\n       *\n       * @memberOf Benchmark#times\n       * @type Number\n       */\n      'period': 0,\n\n      /**\n       * A timestamp of when the benchmark started (ms).\n       *\n       * @memberOf Benchmark#times\n       * @type Number\n       */\n      'timeStamp': 0\n    },\n\n    // aborts benchmark (does not record times)\n    'abort': abort,\n\n    // creates a new benchmark using the same test and options\n    'clone': clone,\n\n    // compares benchmark's hertz with another\n    'compare': compare,\n\n    // executes listeners\n    'emit': emit,\n\n    // get listeners\n    'listeners': listeners,\n\n    // unregister listeners\n    'off': off,\n\n    // register listeners\n    'on': on,\n\n    // reset benchmark properties\n    'reset': reset,\n\n    // runs the benchmark\n    'run': run,\n\n    // pretty print benchmark info\n    'toString': toStringBench\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  extend(Deferred.prototype, {\n\n    /**\n     * The deferred benchmark instance.\n     *\n     * @memberOf Benchmark.Deferred\n     * @type Object\n     */\n    'benchmark': null,\n\n    /**\n     * The number of deferred cycles performed while benchmarking.\n     *\n     * @memberOf Benchmark.Deferred\n     * @type Number\n     */\n    'cycles': 0,\n\n    /**\n     * The time taken to complete the deferred benchmark (secs).\n     *\n     * @memberOf Benchmark.Deferred\n     * @type Number\n     */\n    'elapsed': 0,\n\n    /**\n     * A timestamp of when the deferred benchmark started (ms).\n     *\n     * @memberOf Benchmark.Deferred\n     * @type Number\n     */\n    'timeStamp': 0,\n\n    // cycles/completes the deferred benchmark\n    'resolve': resolve\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  extend(Event.prototype, {\n\n    /**\n     * A flag to indicate if the emitters listener iteration is aborted.\n     *\n     * @memberOf Benchmark.Event\n     * @type Boolean\n     */\n    'aborted': false,\n\n    /**\n     * A flag to indicate if the default action is cancelled.\n     *\n     * @memberOf Benchmark.Event\n     * @type Boolean\n     */\n    'cancelled': false,\n\n    /**\n     * The object whose listeners are currently being processed.\n     *\n     * @memberOf Benchmark.Event\n     * @type Object\n     */\n    'currentTarget': undefined,\n\n    /**\n     * The return value of the last executed listener.\n     *\n     * @memberOf Benchmark.Event\n     * @type Mixed\n     */\n    'result': undefined,\n\n    /**\n     * The object to which the event was originally emitted.\n     *\n     * @memberOf Benchmark.Event\n     * @type Object\n     */\n    'target': undefined,\n\n    /**\n     * A timestamp of when the event was created (ms).\n     *\n     * @memberOf Benchmark.Event\n     * @type Number\n     */\n    'timeStamp': 0,\n\n    /**\n     * The event type.\n     *\n     * @memberOf Benchmark.Event\n     * @type String\n     */\n    'type': ''\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  /**\n   * The default options copied by suite instances.\n   *\n   * @static\n   * @memberOf Benchmark.Suite\n   * @type Object\n   */\n  Suite.options = {\n\n    /**\n     * The name of the suite.\n     *\n     * @memberOf Benchmark.Suite.options\n     * @type String\n     */\n    'name': undefined\n  };\n\n  /*--------------------------------------------------------------------------*/\n\n  extend(Suite.prototype, {\n\n    /**\n     * The number of benchmarks in the suite.\n     *\n     * @memberOf Benchmark.Suite\n     * @type Number\n     */\n    'length': 0,\n\n    /**\n     * A flag to indicate if the suite is aborted.\n     *\n     * @memberOf Benchmark.Suite\n     * @type Boolean\n     */\n    'aborted': false,\n\n    /**\n     * A flag to indicate if the suite is running.\n     *\n     * @memberOf Benchmark.Suite\n     * @type Boolean\n     */\n    'running': false,\n\n    /**\n     * An `Array#forEach` like method.\n     * Callbacks may terminate the loop by explicitly returning `false`.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {Function} callback The function called per iteration.\n     * @returns {Object} The suite iterated over.\n     */\n    'forEach': methodize(forEach),\n\n    /**\n     * An `Array#indexOf` like method.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {Mixed} value The value to search for.\n     * @returns {Number} The index of the matched value or `-1`.\n     */\n    'indexOf': methodize(indexOf),\n\n    /**\n     * Invokes a method on all benchmarks in the suite.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {String|Object} name The name of the method to invoke OR options object.\n     * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.\n     * @returns {Array} A new array of values returned from each method invoked.\n     */\n    'invoke': methodize(invoke),\n\n    /**\n     * Converts the suite of benchmarks to a string.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {String} [separator=','] A string to separate each element of the array.\n     * @returns {String} The string.\n     */\n    'join': [].join,\n\n    /**\n     * An `Array#map` like method.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {Function} callback The function called per iteration.\n     * @returns {Array} A new array of values returned by the callback.\n     */\n    'map': methodize(map),\n\n    /**\n     * Retrieves the value of a specified property from all benchmarks in the suite.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {String} property The property to pluck.\n     * @returns {Array} A new array of property values.\n     */\n    'pluck': methodize(pluck),\n\n    /**\n     * Removes the last benchmark from the suite and returns it.\n     *\n     * @memberOf Benchmark.Suite\n     * @returns {Mixed} The removed benchmark.\n     */\n    'pop': [].pop,\n\n    /**\n     * Appends benchmarks to the suite.\n     *\n     * @memberOf Benchmark.Suite\n     * @returns {Number} The suite's new length.\n     */\n    'push': [].push,\n\n    /**\n     * Sorts the benchmarks of the suite.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {Function} [compareFn=null] A function that defines the sort order.\n     * @returns {Object} The sorted suite.\n     */\n    'sort': [].sort,\n\n    /**\n     * An `Array#reduce` like method.\n     *\n     * @memberOf Benchmark.Suite\n     * @param {Function} callback The function called per iteration.\n     * @param {Mixed} accumulator Initial value of the accumulator.\n     * @returns {Mixed} The accumulator.\n     */\n    'reduce': methodize(reduce),\n\n    // aborts all benchmarks in the suite\n    'abort': abortSuite,\n\n    // adds a benchmark to the suite\n    'add': add,\n\n    // creates a new suite with cloned benchmarks\n    'clone': cloneSuite,\n\n    // executes listeners of a specified type\n    'emit': emit,\n\n    // creates a new suite of filtered benchmarks\n    'filter': filterSuite,\n\n    // get listeners\n    'listeners': listeners,\n\n    // unregister listeners\n    'off': off,\n\n   // register listeners\n    'on': on,\n\n    // resets all benchmarks in the suite\n    'reset': resetSuite,\n\n    // runs all benchmarks in the suite\n    'run': runSuite,\n\n    // array methods\n    'concat': concat,\n\n    'reverse': reverse,\n\n    'shift': shift,\n\n    'slice': slice,\n\n    'splice': splice,\n\n    'unshift': unshift\n  });\n\n  /*--------------------------------------------------------------------------*/\n\n  // expose Deferred, Event and Suite\n  extend(Benchmark, {\n    'Deferred': Deferred,\n    'Event': Event,\n    'Suite': Suite\n  });\n\n  // expose Benchmark\n  // some AMD build optimizers, like r.js, check for specific condition patterns like the following:\n  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {\n    // define as an anonymous module so, through path mapping, it can be aliased\n    define(function() {\n      return Benchmark;\n    });\n  }\n  // check for `exports` after `define` in case a build optimizer adds an `exports` object\n  else if (freeExports) {\n    // in Node.js or RingoJS v0.8.0+\n    if (typeof module == 'object' && module && module.exports == freeExports) {\n      (module.exports = Benchmark).Benchmark = Benchmark;\n    }\n    // in Narwhal or RingoJS v0.7.0-\n    else {\n      freeExports.Benchmark = Benchmark;\n    }\n  }\n  // in a browser or Rhino\n  else {\n    // use square bracket notation so Closure Compiler won't munge `Benchmark`\n    // http://code.google.com/closure/compiler/docs/api-tutorial3.html#export\n    window['Benchmark'] = Benchmark;\n  }\n\n  // trigger clock's lazy define early to avoid a security error\n  if (support.air) {\n    clock({ '_original': { 'fn': noop, 'count': 1, 'options': {} } });\n  }\n}(this));\n"
  },
  {
    "path": "test/ptsd/memdisk.html",
    "content": "<script src=\"../../gun.js\"></script>\n<script>\nvar gun = Gun({localStorage: false, WebSocket: false});\nvar c = 100000, big = \"big\";\nwhile(--c){big += \"big\"}\nc = 0;\nwindow.STOP = false;\nvar to = setInterval(function(){\n\tif(window.STOP){ clearTimeout(to); return; }\n\tvar i = 10;\n\twhile(--i){\n\t\tit(i);\n\t}\n\tconsole.log(Object.keys(gun._.graph).length);//, 'item in memory graph:', Object.keys(gun._.graph));\n\t//return;\n\tvar mem = console.memory;\n\tconsole.log(((mem.usedJSHeapSize / mem.totalJSHeapSize) * 100).toFixed(0) + '% memory');\n},2);\n\nfunction it(i){\n\tc++;\n\tvar key = Gun.text.random(5);\n\tgun.get(key).put({data: big});\n\tsetTimeout(function(){\n\t\tgun.get(key).off();\n\t},1);\n}\n</script>"
  },
  {
    "path": "test/ptsd/memdisk.js",
    "content": "var Gun = require('../../gun');\nrequire('../../lib/memdisk');\n//require('../../lib/file');\n\nvar gun = Gun();\nvar TOTAL = 10000000;\nvar c = 1000, big = \"big\";\nwhile(--c){big += \"big\"}\nc = 0;\n\nvar to = setInterval(function(){\n\tif(TOTAL < c){ return clearTimeout(to) }\n\tvar i = 100;\n\twhile(--i){\n\t\tit(i);\n\t}\n},2);\n\nfunction it(i){\n\tc++;\n\tvar key = Gun.text.random(5);\n\tgun.get(key).put({data: Math.random() + big + Math.random()});\n\tsetTimeout(function(){\n\t\tgun.get(key).off();\n\t},5);\n\tif(c % 5000){ return }\n\tif(typeof process === 'undefined'){ return }\n\t//try{global.gc()}catch(e){console.log(e)}\n\tvar mem = process.memoryUsage();\n\tconsole.log(((mem.heapUsed / mem.heapTotal) * 100).toFixed(0) + '% memory with', Object.keys(gun._.graph).length, 'memory nodes, put', c);\n}"
  },
  {
    "path": "test/ptsd/memory.html",
    "content": "<button onclick=\"START()\">spam</button>\n<button onclick=\"STOP()\">stop</button>\n<script src=\"../../gun.js\"></script>\n<script>\n;(function(){\nwindow.SPAM = function(cb, opt){\n\topt = Gun.num.is(opt)? {each: opt} : opt || {};\n\tsetInterval(burst, opt.wait);\n\nvar n = Gun.time.is(), i = 0, c = 0, b = opt.burst || 1, l = opt.each || 100;\nvar raw = \"AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA AAAAA \"\n\nfunction save(i){\n\tif(!window.SPAM){ return }\n\tif(i > l){\n\t\treturn clearTimeout(t);\n\t}\n\tcb(i, raw + i);\n\treturn;\n\tvar d;\n\tvar ref = window.gun.get('asdf'+i);\n\tref.put({hello: raw + i}, function(ack){\n\t\tif(d){ return } d = true;\n\t\tc++;\n\t\t!(i % b) && console.log(i+'/'+l);//, '@'+Math.floor(b/((-n + (n = Gun.time.is()))/1000))+'/sec');\n\t\t//localStorage.clear();\n\t\tref.off();\n\t\t//console.log(\"gl:\", Object.keys(window.gun._.graph).length);\n\t\tif(c < l){ return }\n\t\tsetTimeout(function(){\n\t\t\ttest.done();\n\t\t}, 1000);\n\t});\n}\nfunction burst(){\n\tfor(var j = 0; j <= b; j++){\n\t\tsave(++i);\n\t}\n}\nvar t;\n}\n}());\n\nvar gun = Gun(); \nwindow.foo = [];\nfunction START(){\n\talert(1);\n\tSPAM(function(i, v){\n\t\t//foo.push(Gun.text.random(1000));\n\t\tgun.get('asdf/'+i).put({data: Gun.text.random(1000), i: i});\n\t}, 10000);\n}\nfunction STOP(){\n\twindow.SPAM = false;\n}\n</script>"
  },
  {
    "path": "test/ptsd/perf.js",
    "content": ";(function(){\n\t// Performance Testing Stress Development\n\t// Performance Testing Style Development\n\t// Performance Testing Speed Development\n\t// Performance Testing Superior Development\n\t// Performance Testing Snippet Development\n\t// Performance Testing Skilled Development\n\t// Performance Testing Steady Development\n\t// Performance Testing Stepwise Development\n\t// Performance Testing Strong Development\n\t// Performance Testing Specified Development\n\t// Performance Testing Stipulated Development\n\t// Performance Testing Systematic Development\n\n\t/*\n\t\t******* START AT THE BOTTOM AND READ UP *******\n\t*/\n\twindow.i = 1;\n\tif(!this.stool){ return }\n\tsetTimeout(function(){\n\t\tstool.run();\n\t},1);\n\tstool.setup(window.setup = function(){\n\t\t\tvar list = [1,2,3];\n\t\t\tvar add = function(a,b){ return a + b };\n\t\t\tvar addprop = function(a,b){ return a.num + b.num };\n\t\t\t//var i = 1;\n\t\t\tvar pos = {lat: Math.random(), lng: Math.random(), i: i};\n\t\t\tvar f1 = function(a){ return a };\n\t\t\tvar f2 = function(a,b){ return b };\n\t\t\tvar f3 = function(a,b){ return a + b };\n\t\t\tvar f4 = function(a,b){ return b + a };\n\t\t\tvar f5 = function(a,b,c){ return a + b + c };\n\t\t\t//window.localStorage.clear();\n\t\t\tvar g = window.g = window.g || Gun();\n\t\t\t//gun.get('users').path(1).path('where').put(pos);\n\t\t\t//var got = gun.get('hewo');\n\t\t\t//got.put({hello: 'world'});\n\t\t\tvar on = Gun.on;\n\t\t\ton('data', function(o){\n\t\t\t\to.a = false;\n\t\t\t});\n\t\t\ton('data', function(o){\n\t\t\t\to.b++;\n\t\t\t});\n\t\t\ton('data', function(o){\n\t\t\t\to.c = 'Hi!';\n\t\t\t});\n\t\t\ton('data', function(o){\n\t\t\t\t//console.log('last', o);\n\t\t\t});\n\t\t\tvar obj = {a: true, b: 1, c: 'Hello world!'};\n\t\t\tvar data = {users: {1: {where: {lat: Math.random(), lng: Math.random(), i: 1}}}};\n\n\t\t\tvar any = function(err, node){\n\t\t\t\t//console.log('any', err, node);\n\t\t\t}\n\t\t\tvar ok = function(node, field){\n\t\t\t\t//$('#log').append(field  + ' ' + Gun.text.ify(node));\n\t\t\t\t//console.log('ok', field, node);\n\t\t\t}\n\t\t\tvar err = function(err){\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t\tfunction fn(){};\n\n\t\t\tfunction Thing(){\n\t\t\t\tthis._ = {};\n\t\t\t}\n\t\t\tThing.prototype.get = function(lex){\n\t\t\t\tvar gun = this, at = gun._;\n\t\t\t\treturn gun;\n\t\t\t}\n\t\t\tThing.prototype.on = function(cb){\n\t\t\t\tvar gun = this, at = gun._;\n\t\t\t\tif(at.cache){\n\n\t\t\t\t}\n\t\t\t\treturn gun;\n\t\t\t}\n\t\t\tvar thing = new Thing();\n\n\t\t\tfunction CHAIN(){}\n\t\t\tCHAIN.chain = CHAIN.prototype;\n\t\t\tCHAIN.chain.get = function(){ return this };\n\t\t\tCHAIN.chain.path = function(){ return this };\n\t\t\tCHAIN.chain.put = function(){ return this };\n\t\t\tvar chain = new CHAIN();\n\n\t\t\tfunction CHAIN2(){}\n\t\t\tCHAIN2.chain = CHAIN2.prototype;\n\t\t\tCHAIN2.chain.get = function(soul, cb, opt){ return this };\n\t\t\tCHAIN2.chain.path = function(field, cb, opt){ return this };\n\t\t\tCHAIN2.chain.put = function(data, cb, opt){ return this };\n\t\t\tvar chain2 = new CHAIN2();\n\n\t\t\tfunction CHAIN3(){}\n\t\t\tCHAIN3.chain = CHAIN3.prototype;\n\t\t\tCHAIN3.chain.get = function(soul, cb, opt){\n\t\t\t\tthis._ = {soul: soul};\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tCHAIN3.chain.path = function(field, cb, opt){ \n\t\t\t\tthis._ = {field: field};\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tCHAIN3.chain.put = function(data, cb, opt){ \n\t\t\t\tthis._ = {put: data};\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tvar chain3 = new CHAIN3();\n\n\t\t\tvar u;\n\t\t\tfunction CHAIN4(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tsoul: u,\n\t\t\t\t\tfield: u\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAIN4.chain = CHAIN4.prototype;\n\t\t\tCHAIN4.chain.get = function(soul, cb, opt){\n\t\t\t\tthis._.soul = soul;\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tCHAIN4.chain.path = function(field, cb, opt){ \n\t\t\t\tthis._.field = field;\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tCHAIN4.chain.put = function(data, cb, opt){ \n\t\t\t\tthis._.put = data;\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tvar chain4 = new CHAIN4();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAIN5(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tsoul: u,\n\t\t\t\t\tfield: u\n\t\t\t\t};\n\t\t\t\t//this.back = this; // compare against CHAIN6!\n\t\t\t}\n\t\t\tCHAIN5.constructor = CHAIN5;\n\t\t\tCHAIN5.chain = CHAIN5.prototype;\n\t\t\tCHAIN5.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAIN5();\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAIN5.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain();\n\t\t\t\tchain._.soul = soul;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN5.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain();\n\t\t\t\tchain._.field = field;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN5.chain.put = function(data, cb, opt){ \n\t\t\t\tthis._.put = data;\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tvar chain5 = new CHAIN5();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAIN6(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tsoul: u,\n\t\t\t\t\tfield: u\n\t\t\t\t};\n\t\t\t\tthis.back = this; // compare against CHAIN5!\n\t\t\t}\n\t\t\tCHAIN6.constructor = CHAIN6;\n\t\t\tCHAIN6.chain = CHAIN6.prototype;\n\t\t\tCHAIN6.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAIN6();\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAIN6.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain();\n\t\t\t\tchain._.soul = soul;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN6.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain();\n\t\t\t\tchain._.field = field;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN6.chain.put = function(data, cb, opt){ \n\t\t\t\tthis._.put = data;\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tvar chain6 = new CHAIN6();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAIN7(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tsoul: u,\n\t\t\t\t\tfield: u\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAIN7.constructor = CHAIN7;\n\t\t\tCHAIN7.chain = CHAIN7.prototype;\n\t\t\tCHAIN7.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAIN7();\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAIN7.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain();\n\t\t\t\tchain._.soul = soul;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN7.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain();\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tchain._.field = field = ''+field;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN7.chain.put = function(data, cb, opt){ \n\t\t\t\tthis._.put = data;\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tvar chain7 = new CHAIN7();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAIN8(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tsoul: u,\n\t\t\t\t\tfield: u,\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAIN8.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAIN8.constructor = CHAIN8;\n\t\t\tCHAIN8.chain = CHAIN8.prototype;\n\t\t\tCHAIN8.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAIN8();\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAIN8.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain();\n\t\t\t\tchain._.soul = soul;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN8.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain();\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tchain._.field = field = ''+field;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN8.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAIN8.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chain8 = new CHAIN8();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAIN9(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tsoul: u,\n\t\t\t\t\tfield: u\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAIN9.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAIN9.constructor = CHAIN9;\n\t\t\tCHAIN9.chain = CHAIN9.prototype;\n\t\t\tCHAIN9.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAIN9();\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAIN9.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain();\n\t\t\t\tchain._.soul = soul;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAIN9.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain();\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tchain._.field = field = ''+field;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tfunction PUT(){ this.data = u; this.state = u; }\n\t\t\tCHAIN9.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put = new PUT();\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAIN9.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chain9 = new CHAIN9();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA1(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAINA1.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA1.constructor = CHAINA1;\n\t\t\tCHAINA1.chain = CHAINA1.prototype;\n\t\t\tCHAINA1.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAINA1();\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA1.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA1.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlex.field = field = ''+field;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA1.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA1.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina1 = new CHAINA1();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA2(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAINA2.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA2.constructor = CHAINA2;\n\t\t\tCHAINA2.chain = CHAINA2.prototype;\n\t\t\tCHAINA2.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAINA2();\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA2.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA2.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex, flex = this._.lex;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlex.field = field = ''+field;\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA2.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA2.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina2 = new CHAINA2();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA3(){\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAINA3.get = function(lex, cb){\n\n\t\t\t}\n\t\t\tCHAINA3.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA3.constructor = CHAINA3;\n\t\t\tCHAINA3.chain = CHAINA3.prototype;\n\t\t\tCHAINA3.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAINA3();\n\t\t\t\tchain.__ = this.__ = this.__ || this._;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t/*CHAINA3.get(lex, function(){\n\n\t\t\t\t\t});*/\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex, flex = this._.lex;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlex.field = field = ''+field;\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA3.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina3 = new CHAINA3();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA3A(){\n\t\t\t\tif(!(this instanceof CHAINA3A)){ return new CHAINA3A() }\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAINA3A.is = function(chain){ return chain instanceof CHAINA3A }\n\t\t\tCHAINA3A.get = function(lex, cb){\n\n\t\t\t}\n\t\t\tCHAINA3A.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA3A.constructor = CHAINA3A;\n\t\t\tCHAINA3A.chain = CHAINA3A.prototype;\n\t\t\tCHAINA3A.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAINA3A();\n\t\t\t\tchain.__ = this.__ = this.__ || this._;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3A.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t/*CHAINA3A.get(lex, function(){\n\n\t\t\t\t\t});*/\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3A.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex, flex = this._.lex;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlex.field = field = ''+field;\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3A.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA3A.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina3a = CHAINA3A();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA3B(){\n\t\t\t\tif(!CHAINA3B.is(this)){ return new CHAINA3B() }\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\tCHAINA3B.is = function(chain){ return chain instanceof CHAINA3B }\n\t\t\tCHAINA3B.get = function(lex, cb){\n\n\t\t\t}\n\t\t\tCHAINA3B.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA3B.constructor = CHAINA3B;\n\t\t\tCHAINA3B.chain = CHAINA3B.prototype;\n\t\t\tCHAINA3B.chain.chain = function(){ \n\t\t\t\tvar chain = new CHAINA3B();\n\t\t\t\tchain.__ = this.__ = this.__ || this._;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3B.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t/*CHAINA3B.get(lex, function(){\n\n\t\t\t\t\t});*/\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3B.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex, flex = this._.lex;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlex.field = field = ''+field;\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3B.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA3B.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina3b = CHAINA3B();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA3C(o){\n\t\t\t\tif(!(this instanceof CHAINA3C)){ return new CHAINA3C(o) }\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t//if(o instanceof CHAINA3C){ return this }\n\t\t\t}\n\t\t\tCHAINA3C.is = function(chain){ return chain instanceof CHAINA3C }\n\t\t\tCHAINA3C.get = function(lex, cb){\n\n\t\t\t}\n\t\t\tCHAINA3C.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA3C.constructor = CHAINA3C;\n\t\t\tCHAINA3C.chain = CHAINA3C.prototype;\n\t\t\tCHAINA3C.chain.opt = function(){\n\t\t\t\tvar chain = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3C.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA3C(this);\n\t\t\t\tchain.__ = this.__ = this.__ || this._;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3C.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t/*CHAINA3C.get(lex, function(){\n\n\t\t\t\t\t});*/\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3C.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex, flex = this._.lex;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlex.field = field = ''+field;\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3C.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA3C.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina3c = CHAINA3C();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA3D(o){\n\t\t\t\tif(!(this instanceof CHAINA3D)){ return new CHAINA3D(o) }\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tif(!(o instanceof CHAINA3D)){ this.opt(o) }\n\t\t\t}\n\t\t\tCHAINA3D.is = function(chain){ return chain instanceof CHAINA3D }\n\t\t\tCHAINA3D.get = function(lex, cb){\n\n\t\t\t}\n\t\t\tCHAINA3D.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA3D.constructor = CHAINA3D;\n\t\t\tCHAINA3D.chain = CHAINA3D.prototype;\n\t\t\tCHAINA3D.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3D.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA3D(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3D.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t/*CHAINA3D.get(lex, function(){\n\n\t\t\t\t\t});*/\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3D.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex, flex = this._.lex;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlex.field = field = ''+field;\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3D.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, put = this._.put;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA3D.state();\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina3d = CHAINA3D();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA3E(o){\n\t\t\t\tif(!(this instanceof CHAINA3E)){ return new CHAINA3E(o) }\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\terr: u,\n\t\t\t\t\tnode: u,\n\t\t\t\t\tcount: 0\n\t\t\t\t};\n\t\t\t\tif(!(o instanceof CHAINA3E)){ this.opt(o) }\n\t\t\t}\n\t\t\tCHAINA3E.is = function(chain){ return chain instanceof CHAINA3E }\n\t\t\tCHAINA3E.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb(null, node);\n\t\t\t\t}\n\t\t\t\treturn cb(null, node);\n\t\t\t}\n\t\t\tCHAINA3E.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA3E.constructor = CHAINA3E;\n\t\t\tCHAINA3E.chain = CHAINA3E.prototype;\n\t\t\tCHAINA3E.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3E.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA3E(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3E.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t\tCHAINA3E.get(chain, lex, function(err, node){\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3E.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tback.next = chain;\n\t\t\t\tchain.on = function(cat){\n\t\t\t\t}\n\t\t\t\tif(from.count){\n\t\t\t\t\tchain.on(from);\n\t\t\t\t} else\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\tCHAINA3E.get(chain, lex, function(err, node){\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3E.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, at = this._, put = at.put, back = this, from = this._;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA3E.state();\n\t\t\t\tchain.on = function(cat){\n\t\t\t\t};\n\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina3e = CHAINA3E();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA3F(o){\n\t\t\t\tif(!(this instanceof CHAINA3F)){ return new CHAINA3F(o) }\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\terr: u,\n\t\t\t\t\tnode: u,\n\t\t\t\t\tcount: 0\n\t\t\t\t};\n\t\t\t\tif(!(o instanceof CHAINA3F)){ this.opt(o) }\n\t\t\t}\n\t\t\tCHAINA3F.is = function(chain){ return chain instanceof CHAINA3F }\n\t\t\tCHAINA3F.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb(null, node);\n\t\t\t\t}\n\t\t\t\treturn cb(null, node);\n\t\t\t}\n\t\t\tCHAINA3F.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA3F.constructor = CHAINA3F;\n\t\t\tCHAINA3F.chain = CHAINA3F.prototype;\n\t\t\tCHAINA3F.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3F.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA3F(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t}\n\t\t\tCHAINA3F.chain.get = function(soul, cb, opt){\n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\tlex.soul = soul;\n\t\t\t\tif(cb){\n\t\t\t\t\tat.ok = cb;\n\t\t\t\t\tCHAINA3F.get(chain, lex, function(err, node){\n\t\t\t\t\t\tat.count++;\n\t\t\t\t\t\tat.err = err;\n\t\t\t\t\t\tat.node = node;\n\t\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3F.chain.path = function(field, cb, opt){ \n\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\tif(!field){\n\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\treturn chain;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tback.next = chain;\n\t\t\t\tchain.on = function(cat){\n\t\t\t\t\tvar node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tif(from.count){\n\t\t\t\t\tchain.on(from);\n\t\t\t\t} else\n\t\t\t\tif(!flex.field){\n\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\tCHAINA3F.get(chain, lex, function(err, node){\n\t\t\t\t\t\tat.err = err;\n\t\t\t\t\t\tat.node = node;\n\t\t\t\t\t\tchain.on(at);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA3F.chain.put = function(data, cb, opt){ \n\t\t\t\tvar chain = this, at = this._, put = at.put, back = this, from = this._;\n\t\t\t\tput.data = data;\n\t\t\t\tput.state = CHAINA3F.state();\n\t\t\t\tchain.on = function(cat){\n\t\t\t\t\tcat.node;\n\t\t\t\t};\n\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tvar chaina3f = CHAINA3F();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA4(o){\n\t\t\t\tif(!(this instanceof CHAINA4)){ return new CHAINA4(o) }\n\t\t\t\tthis._ = {\n\t\t\t\t\tlex: {\n\t\t\t\t\t\tsoul: u,\n\t\t\t\t\t\tfield: u,\n\t\t\t\t\t\tvalue: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\tput: {\n\t\t\t\t\t\tdata: u,\n\t\t\t\t\t\tstate: u\n\t\t\t\t\t},\n\t\t\t\t\topt: u,\n\t\t\t\t\terr: u,\n\t\t\t\t\tnode: u,\n\t\t\t\t\tcount: 0\n\t\t\t\t};\n\t\t\t\tif(!(o instanceof CHAINA4)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINA4.is = function(chain){ return chain instanceof CHAINA4 }\n\t\t\tCHAINA4.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t};\n\t\t\tCHAINA4.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA4.constructor = CHAINA4;\n\t\t\tCHAINA4.chain = CHAINA4.prototype;\n\t\t\tCHAINA4.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA4.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA4(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA4.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINA4.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tchain.on(at);\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tvar chain = this, at = chain._, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA4.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.on(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINA4.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tcat.node;\n\t\t\t\t}\n\t\t\t\tCHAINA4.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINA4.state();\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tvar chaina4 = CHAINA4();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA5(o){\n\t\t\t\tif(!(this instanceof CHAINA5)){ return new CHAINA5(o) }\n\t\t\t\tthis._ = {lex: {}, put: {}, count: 0};\n\t\t\t\tif(!(o instanceof CHAINA5)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINA5.is = function(chain){ return chain instanceof CHAINA5 }\n\t\t\tCHAINA5.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t};\n\t\t\tCHAINA5.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA5.constructor = CHAINA5;\n\t\t\tCHAINA5.chain = CHAINA5.prototype;\n\t\t\tCHAINA5.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA5.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA5(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA5.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINA5.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tchain.on(at);\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tvar chain = this, at = chain._, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA5.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.on(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINA5.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tcat.node;\n\t\t\t\t}\n\t\t\t\tCHAINA5.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINA5.state();\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tvar chaina5 = CHAINA5();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA6(o){\n\t\t\t\tif(!(this instanceof CHAINA6)){ return new CHAINA6(o) }\n\t\t\t\tthis._ = {lex: {}, put: {}, count: 0};\n\t\t\t\tif(!(o instanceof CHAINA6)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINA6.is = function(chain){ return chain instanceof CHAINA6 }\n\t\t\tCHAINA6.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t};\n\t\t\tCHAINA6.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA6.constructor = CHAINA6;\n\t\t\tCHAINA6.chain = CHAINA6.prototype;\n\t\t\tCHAINA6.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA6.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA6(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA6.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._ = chain._ || {}, lex = at.lex = at.lex || {};\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINA6.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tchain.on(at);\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tvar chain = this, at = chain._, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA6.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.on(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINA6.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tcat.node;\n\t\t\t\t}\n\t\t\t\tCHAINA6.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINA6.state();\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tvar chaina6 = CHAINA6();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA7(o){\n\t\t\t\tif(!(this instanceof CHAINA7)){ return new CHAINA7(o) }\n\t\t\t\tthis._ = {lex: {}, put: {}, count: 0};\n\t\t\t\tif(!(o instanceof CHAINA7)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINA7.is = function(chain){ return chain instanceof CHAINA7 }\n\t\t\tCHAINA7.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\tcb.call(chain, null, node);\n\t\t\t};\n\t\t\tCHAINA7.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA7.constructor = CHAINA7;\n\t\t\tCHAINA7.chain = CHAINA7.prototype;\n\t\t\tCHAINA7.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA7.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA7(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA7.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINA7.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tchain.on(at);\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tvar chain = this, at = chain._, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA7.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.on(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINA7.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction map(node, soul){\n\t\t\t\t\tGun.tab.store.put(soul, node);\n\t\t\t\t}\n\t\t\t\tfunction ify(err, env){\n\t\t\t\t\tif(err){ return }\n\t\t\t\t\tGun.obj.map(env.graph, map);\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tGun.ify(cat.put.data, ify);\n\t\t\t\t}\n\t\t\t\tCHAINA7.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINA7.state();\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tvar chaina7 = CHAINA7();\n\n\t\t\t;(function(exports){ // On event emitter generic javascript utility.\n\t\t\t\tfunction Scope(){\n\t\t\t\t\tvar s = function(a,b,c){ return s.tag = a, b? s.event(b,c) : s }\n\t\t\t\t\ts.emit = emit;\n\t\t\t\t\ts.event = event;\n\t\t\t\t\ts.create = Scope;\n\t\t\t\t\ts.on = {};\n\t\t\t\t\treturn s;\n\t\t\t\t}\n\t\t\t\tfunction emit(a){\n\t\t\t\t\tvar s = this, tag = s.tag, on = s.on[tag], i = -1, at;\n\t\t\t\t\tif(!on){ on = s.on[tag] = [] }\n\t\t\t\t\twhile(at = on[i = 1 + i]){ at.on(a) }\n\t\t\t\t\treturn s;\n\t\t\t\t}\n\t\t\t\tfunction event(fn){\n\t\t\t\t\tvar s = this, tag = s.tag, on = s.on[tag], at = new At(fn, tag, s);\n\t\t\t\t\tif(!on){ on = s.on[tag] = [] }\n\t\t\t\t\ton.push(at);\n\t\t\t\t\treturn s;\n\t\t\t\t}\n\t\t\t\tfunction At(fn, tag, s){\n\t\t\t\t\tthis.on = fn;\n\t\t\t\t\tthis.tag = tag;\n\t\t\t\t\tthis.scope = s;\n\t\t\t\t}\n\t\t\t\texports.on = Scope();\n\t\t\t}(window));\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA8(o){\n\t\t\t\tif(!(this instanceof CHAINA8)){ return new CHAINA8(o) }\n\t\t\t\tthis._ = {lex: {}, put: {}, count: 0};\n\t\t\t\tif(!(o instanceof CHAINA8)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINA8.is = function(chain){ return chain instanceof CHAINA8 }\n\t\t\tCHAINA8.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\tcb.call(chain, null, node);\n\t\t\t};\n\t\t\tCHAINA8.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA8.constructor = CHAINA8;\n\t\t\tCHAINA8.chain = CHAINA8.prototype;\n\t\t\tCHAINA8.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA8.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA8(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA8.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINA8.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tchain.on(at);\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tvar chain = this, at = chain._, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tat.back = cat;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA8.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.on(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINA8.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction map(node, soul){\n\t\t\t\t\tGun.tab.store.put(soul, node);\n\t\t\t\t}\n\t\t\t\tfunction ify(err, env){\n\t\t\t\t\tif(err){ return }\n\t\t\t\t\tGun.obj.map(env.graph, map);\n\t\t\t\t}\n\t\t\t\tfunction wrap(cat, data){\n\t\t\t\t\tif(!cat){ return data }\n\t\t\t\t\tif(cat.lex.field){\n\t\t\t\t\t\tdata = Gun.obj.put({}, cat.lex.field, data);\n\t\t\t\t\t}\n\t\t\t\t\tdata = Gun.is.node.soul.ify(data, cat.lex.soul);\n\t\t\t\t\tif(cat.lex.soul){ return data }\n\t\t\t\t\tif(cat !== cat.back){\n\t\t\t\t\t\treturn wrap(cat.back, data);\n\t\t\t\t\t}\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tvar data = wrap(cat, cat.put.data);\n\t\t\t\t\tGun.ify(data, ify);\n\t\t\t\t}\n\t\t\t\tCHAINA8.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINA8.state();\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tvar chaina8 = CHAINA8();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINA9(o){\n\t\t\t\tif(!(this instanceof CHAINA9)){ return new CHAINA9(o) }\n\t\t\t\tthis._ = {lex: {}, put: {}, count: 0};\n\t\t\t\tif(!(o instanceof CHAINA9)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINA9.is = function(chain){ return chain instanceof CHAINA9 }\n\t\t\tCHAINA9.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\tcb.call(chain, null, node);\n\t\t\t};\n\t\t\tCHAINA9.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINA9.constructor = CHAINA9;\n\t\t\tCHAINA9.chain = CHAINA9.prototype;\n\t\t\tCHAINA9.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINA9.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINA9(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA9.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINA9.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tchain.on(at);\n\t\t\t\t}\n\t\t\t\tfunction on(cat){\n\t\t\t\t\tvar chain = this, at = chain._, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tat.back = cat;\n\t\t\t\t\tif(chain.next){ chain.next.on(at) }\n\t\t\t\t}\n\t\t\t\tCHAINA9.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.on(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINA9.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction wrap(cat, data){\n\t\t\t\t\tif(!cat){ return data }\n\t\t\t\t\tif(cat.lex.field){\n\t\t\t\t\t\tdata = Gun.obj.put({}, cat.lex.field, data);\n\t\t\t\t\t}\n\t\t\t\t\tdata = Gun.is.node.soul.ify(data, cat.lex.soul);\n\t\t\t\t\tif(cat.lex.soul){ return data }\n\t\t\t\t\tif(cat !== cat.back){\n\t\t\t\t\t\treturn wrap(cat.back, data);\n\t\t\t\t\t}\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\t\t\t\tfunction on(cat){ var at = cat, state = Gun.time.is();\n\t\t\t\t\tvar data = wrap(cat, cat.put.data);\n\t\t\t\t\tGun.ify(data, end, {\n\t\t\t\t\t\tnode: function(env, cb){ var eat = env.at;\n\t\t\t\t\t\t\tif(1 === eat.path.length && at.node){\n\t\t\t\t\t\t\t\teat.soul = Gun.is.rel(at.node[eat.path[0]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcb(env, eat);\n\t\t\t\t\t\t}, value: function(env){ var eat = env.at;\n\t\t\t\t\t\t\tif(!eat.field){ return }\n\t\t\t\t\t\t\tGun.is.node.state.ify(eat.node, {field: eat.field, state: state});\n\t\t\t\t\t\t}, uuid: gun.__.opt.uuid, state: state\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tfunction ack(err, ok){\n\t\t\t\t\t//if(Gun.fns.is(opt.any)){ opt.any.call(gun, err, ok) } // TODO: gun context!\n\t\t\t\t}\n\t\t\t\tfunction end(err, env){\n\t\t\t\t\tif(err){ return }\n\t\t\t\t\tGun.put(gun, env.graph, ack, env.opt); // TODO: incorrect options!\n\t\t\t\t}\n\t\t\t\tCHAINA9.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINA9.state();\n\t\t\t\t\tchain.on = on;\n\t\t\t\t\tif(at.count){ chain.on(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tvar chaina9 = CHAINA9();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINB1(o){\n\t\t\t\tif(!(this instanceof CHAINB1)){ return new CHAINB1(o) }\n\t\t\t\tthis._ = {lex: {}, put: {}, count: 0};\n\t\t\t\tif(!(o instanceof CHAINB1)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINB1.is = function(chain){ return chain instanceof CHAINB1 }\n\t\t\tCHAINB1.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\tGun.tab.store.get(soul, function(err, data){\n\t\t\t\t\tgraph[soul] = data;\n\t\t\t\t\tcb.call(chain, err, data);\n\t\t\t\t});\n\t\t\t};\n\t\t\tCHAINB1.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINB1.constructor = CHAINB1;\n\t\t\tCHAINB1.chain = CHAINB1.prototype;\n\t\t\tCHAINB1.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINB1.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINB1(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.run(at) }\n\t\t\t\t}\n\t\t\t\tCHAINB1.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINB1.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tfunction got(err, node){\n\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\tat.err = err;\n\t\t\t\tat.node = node;\n\t\t\t\tchain.run(at);\n\t\t\t}\n\t\t\t;(function(){\n\t\t\t\tfunction run(cat){\n\t\t\t\t\tvar chain = this, at = chain._, lex = at.lex, field = lex.field, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = Gun.is.rel(node[cat.lex.field])){\n\t\t\t\t\t\t\treturn CHAINB1.get(chain, {soul: val}, got);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tat.back = cat;\n\t\t\t\t\tif(chain.next){ chain.next.run(at) }\n\t\t\t\t}\n\t\t\t\tCHAINB1.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.run = run;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.run(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINB1.get(chain, lex, got);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction wrap(cat, data){\n\t\t\t\t\tif(!cat){ return data }\n\t\t\t\t\tif(cat.lex.field){\n\t\t\t\t\t\tdata = Gun.obj.put({}, cat.lex.field, data);\n\t\t\t\t\t}\n\t\t\t\t\tdata = Gun.is.node.soul.ify(data, cat.lex.soul);\n\t\t\t\t\tif(cat.lex.soul){ return data }\n\t\t\t\t\tif(cat !== cat.back){\n\t\t\t\t\t\treturn wrap(cat.back, data);\n\t\t\t\t\t}\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\t\t\t\tfunction run(cat){ var at = cat, state = Gun.time.is();\n\t\t\t\t\tvar data = wrap(cat, cat.put.data);\n\t\t\t\t\tGun.ify(data, end, {\n\t\t\t\t\t\tnode: function(env, cb){ var eat = env.at;\n\t\t\t\t\t\t\tif(1 === eat.path.length && at.node){\n\t\t\t\t\t\t\t\teat.soul = Gun.is.rel(at.node[eat.path[0]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcb(env, eat);\n\t\t\t\t\t\t}, value: function(env){ var eat = env.at;\n\t\t\t\t\t\t\tif(!eat.field){ return }\n\t\t\t\t\t\t\tGun.is.node.state.ify(eat.node, {field: eat.field, state: state});\n\t\t\t\t\t\t}, uuid: gun.__.opt.uuid, state: state\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tfunction ack(err, ok){\n\t\t\t\t\t//if(Gun.fns.is(opt.any)){ opt.any.call(gun, err, ok) } // TODO: gun context!\n\t\t\t\t}\n\t\t\t\tfunction end(err, env){\n\t\t\t\t\tif(err){ return }\n\t\t\t\t\tGun.put(gun, env.graph, ack, env.opt); // TODO: incorrect options!\n\t\t\t\t}\n\t\t\t\tCHAINB1.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINB1.state();\n\t\t\t\t\tchain.run = run;\n\t\t\t\t\tif(at.count){ chain.run(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction run(cat){\n\t\t\t\t\tvar chain = this, lex = cat.lex, node = cat.node, field = lex.field, val;\n\t\t\t\t\tif(field && (val = Gun.is.rel(node[field]))){\n\t\t\t\t\t\treturn CHAINB1.get(chain, {soul: val}, got);\n\t\t\t\t\t}\n\t\t\t\t\tchain.cb(cat.node);\n\t\t\t\t}\n\t\t\t\tCHAINB1.chain.on = function(cb){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tchain.run = run;\n\t\t\t\t\tchain.cb = cb;\n\t\t\t\t\tif(at.count){ chain.run(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t}\n\t\t\t}());\n\t\t\tvar chainb1 = CHAINB1();\n\n\t\t\tvar u; function noop(){};\n\t\t\tfunction CHAINB2(o){\n\t\t\t\tif(!(this instanceof CHAINB2)){ return new CHAINB2(o) }\n\t\t\t\tthis._ = {lex: {}, put: {}, count: 0};\n\t\t\t\tif(!(o instanceof CHAINB2)){ this.opt(o) }\n\t\t\t};\n\t\t\tCHAINB2.is = function(chain){ return chain instanceof CHAINB2 }\n\t\t\tCHAINB2.get = function(chain, lex, cb){\n\t\t\t\tvar soul = lex.soul, graph = chain.__.graph, node;\n\t\t\t\tif(node = graph[soul]){\n\t\t\t\t\treturn cb.call(chain, null, node);\n\t\t\t\t}\n\t\t\t\tGun.tab.store.get(soul, function(err, data){\n\t\t\t\t\tgraph[soul] = data;\n\t\t\t\t\tcb.call(chain, err, data);\n\t\t\t\t});\n\t\t\t};\n\t\t\tCHAINB2.state = Date.now || function(){ return new Date().getTime() }\n\t\t\tCHAINB2.constructor = CHAINB2;\n\t\t\tCHAINB2.chain = CHAINB2.prototype;\n\t\t\tCHAINB2.chain.opt = function(o){\n\t\t\t\tvar chain = this;\n\t\t\t\tchain.__ = chain.__ || chain._;\n\t\t\t\tchain.__.graph = chain.__.graph || {};\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\tCHAINB2.chain.chain = function(){\n\t\t\t\tvar chain = new CHAINB2(this);\n\t\t\t\tchain.__ = this.__;\n\t\t\t\tchain.back = this;\n\t\t\t\treturn chain;\n\t\t\t};\n\t\t\t;(function(){\n\t\t\t\tfunction get(err, node){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = err;\n\t\t\t\t\tat.node = node;\n\t\t\t\t\tif(chain.next){ chain.next.run(at) }\n\t\t\t\t}\n\t\t\t\tCHAINB2.chain.get = function(soul, cb, opt){\n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex;\n\t\t\t\t\tlex.soul = soul;\n\t\t\t\t\tlex.opt = opt;\n\t\t\t\t\tif(cb){\n\t\t\t\t\t\tat.ok = cb;\n\t\t\t\t\t\tCHAINB2.get(chain, lex, get);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\tfunction got(err, node){\n\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\tat.err = err;\n\t\t\t\tat.node = node;\n\t\t\t\tchain.run(at);\n\t\t\t}\n\t\t\t;(function(){\n\t\t\t\tfunction run(cat){\n\t\t\t\t\tvar chain = this, at = chain._, lex = at.lex, field = lex.field, node, vert, val;\n\t\t\t\t\tat.count++;\n\t\t\t\t\tat.err = cat.err;\n\t\t\t\t\tif(node = cat.node){\n\t\t\t\t\t\tif(val = Gun.is.rel(node[cat.lex.field])){\n\t\t\t\t\t\t\treturn CHAINB2.get(chain, {soul: val}, got);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(val = node[field]){\n\t\t\t\t\t\t\tat.node = vert = {};\n\t\t\t\t\t\t\tvert[field] = val;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tat.back = cat;\n\t\t\t\t\tif(chain.next){ chain.next.run(at) }\n\t\t\t\t}\n\t\t\t\tCHAINB2.chain.path = function(field, cb, opt){ \n\t\t\t\t\tvar chain = this.chain(), at = chain._, lex = at.lex\n\t\t\t\t\t, back = this, from = back._, flex = from.lex, vert;\n\t\t\t\t\tif(!field){\n\t\t\t\t\t\tif(0 != field){\n\t\t\t\t\t\t\treturn chain;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlex.field = field = ''+field;\n\t\t\t\t\tback.next = chain;\n\t\t\t\t\tchain.run = run;\n\t\t\t\t\tif(from.count){\n\t\t\t\t\t\tchain.run(from);\n\t\t\t\t\t} else\n\t\t\t\t\tif(!flex.field){\n\t\t\t\t\t\tlex.soul = flex.soul;\n\t\t\t\t\t\tCHAINB2.get(chain, lex, got);\n\t\t\t\t\t}\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction wrap(cat, data){\n\t\t\t\t\tif(!cat){ return data }\n\t\t\t\t\tif(cat.lex.field){\n\t\t\t\t\t\tdata = Gun.obj.put({}, cat.lex.field, data);\n\t\t\t\t\t}\n\t\t\t\t\tdata = Gun.is.node.soul.ify(data, cat.lex.soul);\n\t\t\t\t\tif(cat.lex.soul){ return data }\n\t\t\t\t\tif(cat !== cat.back){\n\t\t\t\t\t\treturn wrap(cat.back, data);\n\t\t\t\t\t}\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\t\t\t\tfunction run(cat){ var at = cat, state = Gun.time.is();\n\t\t\t\t\tvar data = wrap(cat, cat.put.data);\n\t\t\t\t\t/*end(null, {graph: {\n\t\t\t\t\t\tusers: {_: {'#': 'users', '>': {1: 9}}, 1: {'#': 'fdsa'}},\n\t\t\t\t\t\tfdsa: {_: {'#': 'fdsa', '>': {where: 9}}, where: {'#': 'sadf'}},\n\t\t\t\t\t\tsadf: {_: {'#': 'sadf', '>': {lat: 9, lng: 9, i: 9}}, lat: 0.123456789, lng: 0.987654321, i:1}\n\t\t\t\t\t}});return;*/\n\t\t\t\t\tGun.ify(data, end, {\n\t\t\t\t\t\tnode: function(env, cb){ var eat = env.at;\n\t\t\t\t\t\t\tif(1 === eat.path.length && at.node){\n\t\t\t\t\t\t\t\teat.soul = Gun.is.rel(at.node[eat.path[0]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcb(env, eat);\n\t\t\t\t\t\t}, value: function(env){ var eat = env.at;\n\t\t\t\t\t\t\tif(!eat.field){ return }\n\t\t\t\t\t\t\tGun.is.node.state.ify(eat.node, {field: eat.field, state: state});\n\t\t\t\t\t\t}, uuid: gun.__.opt.uuid, state: state\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tfunction ack(err, ok){\n\t\t\t\t\t//if(Gun.fns.is(opt.any)){ opt.any.call(gun, err, ok) } // TODO: gun context!\n\t\t\t\t}\n\t\t\t\tfunction end(err, env){\n\t\t\t\t\tif(err){ return }\n\t\t\t\t\tGun.put(gun, env.graph, ack, env.opt); // TODO: incorrect options!\n\t\t\t\t}\n\t\t\t\tCHAINB2.chain.put = function(data, cb, opt){ \n\t\t\t\t\tvar chain = this, at = chain._, put = at.put;\n\t\t\t\t\tput.data = data;\n\t\t\t\t\tput.state = CHAINB2.state();\n\t\t\t\t\tchain.run = run;\n\t\t\t\t\tif(at.count){ chain.run(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t};\n\t\t\t}());\n\t\t\t;(function(){\n\t\t\t\tfunction run(cat){\n\t\t\t\t\tvar chain = this, lex = cat.lex, node = cat.node, field = lex.field, val;\n\t\t\t\t\tif(field && (val = Gun.is.rel(node[field]))){\n\t\t\t\t\t\treturn CHAINB2.get(chain, {soul: val}, got);\n\t\t\t\t\t}\n\t\t\t\t\tchain.cb(cat.node);\n\t\t\t\t}\n\t\t\t\tCHAINB2.chain.on = function(cb){\n\t\t\t\t\tvar chain = this, at = chain._;\n\t\t\t\t\tchain.run = run;\n\t\t\t\t\tchain.cb = cb;\n\t\t\t\t\tif(at.count){ chain.run(at) }\n\t\t\t\t\treturn chain;\n\t\t\t\t}\n\t\t\t}());\n\t\t\tvar chainb2 = CHAINB2();\n\n\t\t\tfunction gun_get(soul){\n\t\t\t\tgun_get.as = 'a';\n\t\t\t\tif(!gun_get.a) Gun.tab.store.get(soul, gun_get.load);\n\t\t\t\treturn gun_get;\n\t\t\t}\n\t\t\tgun_get.load = function(err,data){ gun_get[gun_get.as] = data }\n\t\t\tgun_get.path = function(f){\n\t\t\t\tvar soul = Gun.is.rel(gun_get.a[f]);\n\t\t\t\tgun_get.as = 'b';\n\t\t\t\tif(!gun_get.b) Gun.tab.store.get(soul, gun_get.load);\n\t\t\t\treturn gun_get;\n\t\t\t}\n\t\t\tgun_get.pathing = function(f){\n\t\t\t\tvar soul = Gun.is.rel(gun_get.b[f]);\n\t\t\t\tgun_get.as = 'c';\n\t\t\t\tif(!gun_get.c) Gun.tab.store.get(soul, gun_get.load);\n\t\t\t\treturn gun_get;\n\t\t\t}\n\t\t\tgun_get.on = function(cb){\n\t\t\t\tcb(gun_get.c);\n\t\t\t\treturn gun_get;\n\t\t\t}\n\t\t\tvar hewo = {hello: \"world\"};\n\t\t\twindow.puti = window.puti || 0;\n\t\t\twindow.geti = window.geti || 0;\n\t\t\tlocalStorage.clear();\n\t\t\tvar gun = g.get('heylo');\n\t\t\tgun.once(ok);\n\t\t\t//var ok = function(a,b){ console.log('wat', a,b) }\n\t\t\t/*\n\t\t\tgun.get('users').put({1: {where: {lat: Math.random(), lng: Math.random(), i: 1}}});\n\t\t\t//Gun.log.debug=1;console.log(\"------------------\");\n\t\t\tvar val = gun.get('users').path(1).path('where').once(ok);\n\t\t\t*/\n\t});\n\t//localStorage.clear();\n\tstool.add('nothing', function(){\n\t\t// do nothing\n\t});\n\tstool.add('write', function(){\n\t\tgun.put({hello: \"world\"});\n\t});\n\tstool.add('read', function(){\n\t\tgun.once(ok);\n\t});return;\n\t// without variable caching:\n\tstool.add('write', function(){\n\t\tgun.get('hi').put({hello: \"world\"});\n\t});\n\tstool.add('read', function(){\n\t\tgun.get('hi').once(ok);\n\t});return;\n\t/*\n\tstool.add('put', function(){\n\t\tgun.get('users').put({1: {where: {lat: Math.random(), lng: Math.random(), i: 1}}});\n\t});\n\tstool.add('on', function(){\n\t\tval.once(ok);\n\t});\n\tstool.add('on', function(){\n\t\tgun.get('users').path(1).path('where').once(ok);\n\t});\n\treturn;\n\tstool.add('put', function(){\n\t\tgun.get(puti++).put(hewo, any);asdf;\n\t});return;\n\tstool.add('put', function(){\n\t\tgun.get(geti++, any);\n\t});\n\treturn;\n\tstool.add('get', function(){\n\t\tgot.on(ok);\n\t});\n\tstool.add('get', function(){\n\t\tgun.get('users', any);\n\t});\n\treturn;\n\treturn;\n\tstool.add('get path * 2 put', function(){\n\t\tgun.get('users').path(i).path('where').put(pos);\n\t});\n\tstool.add('get path path on', function(){\n\t\tgun.get('users').path(i).path('where').on(ok);\n\t});\n\tstool.add('get path path', function(){\n\t\tgun.get('users').path(i).path('where', any);\n\t});\n\tstool.add('get path', function(){\n\t\tgun.get('users').path(i, any);\n\t});\n\tstool.add('get on', function(){\n\t\tgun.get('users').on(ok);\n\t});\n\tstool.add('get', function(){\n\t\tgun.get('users', any);\n\t});\n\tstool.add('get', function(){\n\t\tgot.on(ok);\n\t});\n\tstool.add('fnx2', function(){\n\t\tthing.get('users').on(ok);\n\t});\n\treturn;\n\tstool.add('get path * 2 on', function(){\n\t\tgun.get('users').path(i).path('where').on(function(node){\n\t\t\tconsole.log(node);\n\t\t});\n\t});\n\treturn;\n\tstool.add('chain', function(){\n\t\tchainb2.get('users').path(i).path('where').on(function(node){\n\t\t\t//console.log(node);\n\t\t});\n\t});\n\treturn;\n\tstool.add('chain', function(){\n\t\tchainb1.get('users').path(i).path('where').on(function(node){\n\t\t\tconsole.log(node);\n\t\t});\n\t});\n\tstool.add('chain', function(){\n\t\tchaina9.get('users').path(i).path('where').put(pos);\n\t});\n\treturn;\n\tstool.add('chain', function(){\n\t\tchaina8.get('users').path(i).path('where').put(pos);\n\t});\n\tstool.add('chain', function(){\n\t\tchaina7.get('users').path(i).path('where').put(pos);\n\t});\n\t// Not declaring any metadata in the constructor takes this too far, still faster to initialize default values so methods don't do the work instead.\n\tstool.add('chain', function(){\n\t\tchaina6.get('users').path(i).path('where').put(pos);\n\t});\n\t// Counter to performance advice other places, it seems faster to not declare the fields in advance!\n\tstool.add('chain', function(){\n\t\tchaina5.get('users').path(i).path('where').put(pos);\n\t});\n\t// Caching functions allows us to keep above 1M ops/sec on my machine.\n\tstool.add('chain proto cache', function(){\n\t\tchaina4.get('users').path(i).path('where').put(pos);\n\t});\n\t// What if we then want the functions to actually do something?\n\tstool.add('chain proto fn work', function(){\n\t\tchaina3f.get('users').path(i).path('where').put(pos);\n\t});\n\t// HOLY COW! Major performance impact. This is probably the most important lesson. Do everything possible to prevent dynamic allocation of functions. They destroy performance more than anything else it seems. A good article on this: http://code.tutsplus.com/tutorials/stop-nesting-functions-but-not-all-of-them--net-22315 . \n\tstool.add('chain proto fn', function(){\n\t\tchaina3e.get('users').path(i).path('where').put(pos);\n\t});\n\t// Be clever and check the param and then do one-time root level instantiation. Clean up referencing the root in every chain and gain +1M! Is this a card/board game?\n\tstool.add('chain proto check param', function(){\n\t\tchaina3d.get('users').path(i).path('where').put(pos);\n\t});\n\t// Add for the ability to have a parameter in your constructor. Lose 1M for being lame like that.\n\tstool.add('chain proto param', function(){\n\t\tchaina3c.get('users').path(i).path('where').put(pos);\n\t});\n\t// Try and make the class check be its own function and then have your heart get crushed. Don't do it or suffer ~1.5M ops/sec lost.\n\tstool.add('chain proto is check', function(){\n\t\tchaina3b.get('users').path(i).path('where').put(pos);\n\t});\n\t// Let's see if we can move some of this logic towards the constructor and lose the need for new.\n\tstool.add('chain proto no new', function(){\n\t\tchaina3a.get('users').path(i).path('where').put(pos);\n\t});\n\t// Now we need to check the in memory graph - so we have to reference it somehow. Lose ~half million ops/sec.\n\tstool.add('chain proto state put', function(){\n\t\tchaina3.get('users').path(i).path('where').put(pos);\n\t});\n\t// Have `path` look up its previous chain's context. Burn a couple million dollars.\n\tstool.add('chain proto state path', function(){\n\t\tchaina2.get('users').path(i).path('where').put(pos);\n\t});\n\t// Now start to flesh out the actual metadata states for the classes. Loose some performance.\n\tstool.add('chain proto state get', function(){\n\t\tchaina1.get('users').path(i).path('where').put(pos);\n\t});\n\t// What if we try to make put be a class on the existing class metadata? Well nope, makes things worse - high 1M ops/sec compared to a low 2M ops/sec. Moral of the story is have your class stub deeply and don't try to speed things up by using more classes (it doesn't work).\n\tstool.add('chain proto state every put class', function(){\n\t\tchain9.get('users').path(i).path('where').put(pos);\n\t});\n\t// Now we want to actually do stuff with the put arguments, which puts us now at the low 2M ops/sec. Let's stub them out as well.\n\tstool.add('chain proto state every back put', function(){\n\t\tchain8.get('users').path(i).path('where').put(pos);\n\t});\n\t// Alright, now we need `path` to actually do some validation on its parameters. You'll now might lose what you just gained back.\n\tstool.add('chain proto state every back path', function(){\n\t\tchain7.get('users').path(i).path('where').put(pos);\n\t});\n\t// Does stubbing out `chain.back` help at all? No. In fact, noticeably worse. Don't go down this pathway.\n\tstool.add('chain proto state every back', function(){\n\t\tchain6.get('users').path(i).path('where').put(pos);\n\t});\n\t// However our chain isn't actually creating new contextual chains. Something not every tool has to support but is important for us and things like jQuery. So prepare to then ditch ~1/4 or ~1/3 of your performance.\n\tstool.add('chain proto state every', function(){\n\t\tchain5.get('users').path(i).path('where').put(pos);\n\t});\n\t// But using a prototype to stub out the metadata gives us back an extra 1M ops/sec.\n\tstool.add('chain proto state', function(){\n\t\tchain4.get('users').path(i).path('where').put(pos);\n\t});\n\t// And then ~40% loss of performance just to assign the parameter to metadata on the chain.\n\tstool.add('chain proto state', function(){\n\t\tchain3.get('users').path(i).path('where').put(pos);\n\t});\n\t// Roughly ~1M ops/sec difference between the exact same code, except having arguments. No, not referencing the magical `arguments` object, just literally including parameters.\n\tstool.add('chain params', function(){\n\t\tchain2.get('users').path(i).path('where').put(pos);\n\t});\n\tstool.add('chain nothing', function(){\n\t\tchain.get('users').path(i).path('where').put(pos);\n\t});\n\t*/\n\tstool.add('Gun.ify', function(){\n\t\tGun.graph.ify(data);\n\t});\n\tstool.add('Gun.ify', function(){\n\t\tGun.ify(data);\n\t});\n\treturn;\n\tstool.add('JSON.ify', function(){\n\t\tJSON.stringify(data);\n\t});\n\tstool.add('on', function(){\n\t\ton('data').emit(obj);\n\t});\n\t// This wound up being ~25M ops/sec on my machine.\n\tstool.add('call fn', function(){\n\t\tvar a,b,c,d,e;\n\t\ta = f1(1);\n\t\tif(a){\n\t\t\tb = f2(a,2);\n\t\t}\n\t\tif(b){\n\t\t\tc = f3(b,3);\n\t\t}\n\t\tif(c){\n\t\t\td = f4(c,4);\n\t\t}\n\t\tif(d){\n\t\t\te = f5(c,d,5);\n\t\t}\n\t});\n\t// Each function call reduces performance by about half, although that amount decreases near the end.\n\tstool.add('call fn', function(){\n\t\tf1();\n\t}).add('call fn * 2', function(){\n\t\tf1();f2();\n\t}).add('call fn * 3', function(){\n\t\tf1();f2();f3();\n\t}).add('call fn * 4', function(){\n\t\tf1();f2();f3();f4();\n\t}).add('call fn * 5', function(){\n\t\tf1();f2();f3();f4();f5();\n\t});\n\tstool.add('list a Array?', function(){\n\t\tlist instanceof Array;\n\t}).add('list isArray?', function(){\n\t\tArray.isArray(list);\n\t});\n\t// Wildly inconsistent winning results, although loose equality seemed to occasionally spike and instanceof was most stable at being fastest.\n\tstool.add('add a fn?', function(){\n\t\tadd instanceof Function;\n\t}).add('add type fn?', function(){\n\t\ttypeof add === 'function';\n\t}).add('add loose type fn?', function(){\n\t\ttypeof add == 'function';\n\t});\n\t// Tad less than half the speed of a straightforward function call.\n\tstool.add('Call add', function(){\n\t\tvar a = {num: 1};\n\t\tvar b = {num: 2};\n\t\taddprop(a,b);\n\t});\n\t// The primitive assignments on an object were ~225% better in performance.\n\tstool.add('Assigning', function(){\n\t\tvar bi = true;\n\t\tvar num = 1;\n\t\tvar text = \"Hello world!\";\n\t\tvar list = [bi, num, text];\n\t\tvar obj = {\n\t\t\tbi: bi,\n\t\t\tnum: num,\n\t\t\ttext: text,\n\t\t\tlist: list,\n\t\t\tobj: {sub: true}\n\t\t};\n\t});\n\tstool.add('Assign circular', function(){\n\t\tvar obj = {};\n\t\tobj.me = obj;\n\t});\n\t// If you thought calling a function was slow... you should probably just leave, now. It was 2/3rds the speed of a function call on my machine.\n\tstool.add('Assign object', function(){\n\t\tvar obj = {\n\t\t\tbi: true,\n\t\t\tnum: 1,\n\t\t\ttext: 'Hello world!'\n\t\t};\n\t});\n\t// Oh javascript, you make me sad. An ORDER OF MAGNITUDE difference? Let every one be warned: Don't call functions in javascript. Like, no. Just don't. You be slow. So sad. Sad. I'm going to go cry now.\n\tstool.add('Call a function', function(){\n\t\tadd(1,2);\n\t});\n\tstool.add('Add', function(){\n\t\t1 + 2;\n\t});\n\t// Simple addition and primitive assignment wasn't too bad either, 1B+ ops/sec!\n\tstool.add('Assign text', function(){\n\t\tvar text = 'Hello world!';\n\t});\n\tstool.add('Assign', function(){\n\t\tvar bi = true;\n\t});\n\t// We found out that doing nothing is extremely fast. In fact, on our machine we clocked over 1B ops/sec. This is obviously the future of JavaScript.\n\tstool.add('Nothing', function(){\n\n\t});\n}());"
  },
  {
    "path": "test/ptsd/ptsd.html",
    "content": "<html>\n<head>\n\t<title>PTSD</title>\n\t<meta name=\"Description\" content=\"JavaScript benchmarking utility\">\n\t<link rel=\"stylesheet\" href=\"stool.css\">\n</head>\n<body>\n\t<div id=\"inject\"></div>\n\t<h1>PTSD</h1>\n\t<section>\n\t\t<h3>Setup code</h3>\n\t\t<textarea rows=\"6\" id=\"common\" class=\"common input\" placeholder=\"Common Code\"></textarea>\n\t\t<textarea id='log'>logs</textarea>\n\t</section>\n\t<section>\n\t\t<h3>Test cases</h3>\n\t\t<table id=\"suite\">\n\t\t\t<tr>\n\t\t\t\t<th class=\"th-remove\"></th>\n\t\t\t\t<th class=\"th-case\">Case</th>\n\t\t\t\t<th class=\"th-result\">Result</th>\n\t\t\t</tr>\n\t\t</table>\n\t\t<a href=\"#\" id=\"add\">+ Add test case</a>\n\t</section>\n\t<button id=\"run\">Run!</button>\n\t<button id=\"abort\">Abort</button>\n\t<button id=\"share\">Share</button>\n\t<a id=\"share-result\"></a>\n\t<script src=\"../json2.js\"></script>\n\t<script src=\"../../examples/jquery.js\"></script>\n\t<script src=\"benchmark.js\"></script>\n\t<script src=\"ptsd.js\"></script>\n\t<script src=\"../../gun.js\"></script>\n\t<script src=\"perf.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "test/ptsd/ptsd.js",
    "content": "(function(){\nvar console = window.console || {log: function(s){alert(s)}};\nvar stool = {}; // rewritten entirely to use jQuery.\nvar suite;\n\nfunction abort() {\n\tif (!suite || (suite && !suite.running)) return;\n\n\tsuite.abort();\n\t$('.result').each(function(){\n\t\tif($(this).is('.running')){\n\t\t\t$(this).text('aborted');\n\t\t}\n\t});\n\treturn stool;\n}\nstool.abort = abort;\n\nfunction clear() {\n\tif (suite && suite.running) abort();\n\n\t$('.results').each(function(){\n\t\t$(this).text('').removeClass('running');\n\t});\n\treturn stool;\n}\nstool.clear = clear;\n\nfunction run() {\n\tabort();\n\n\tvar titles = $('.title');\n\tvar cases = $('.case');\n\tvar results = $('.result');\n\tvar common = $('#common');\n\n\tsuite = new Benchmark.Suite;\n\tsuite.on('complete', function() {\n\t\t$('body').removeClass('running');\n\t});\n\n\t$('body').addClass('running');\n\n\tresults.each(function(i){\n\t\tvar result = $(this).addClass('running').text('queued');\n\t\tsuite.add(titles[i].value, cases[i].value, {\n\t\t\t'setup': common.val(),\n\t\t\t'onError': function(a,b,c){ console.log(a.message.message) },\n\t\t\t'onCycle': (function (result) {\n\t\t\t\treturn function(event) {\n\t\t\t\t\tif (event.target.aborted) return;\n\t\t\t\t\tresult.text(Math.round(event.target.hz).toLocaleString() + ' ops/sec');\n\t\t\t\t};\n\t\t\t})(result),\n\t\t\t'onComplete': (function (result) {\n\t\t\t\treturn function(event) {\n\t\t\t\t\tif (event.target.aborted) return;\n\t\t\t\t\tresult.text(Math.round(event.target.hz).toLocaleString() + ' ops/sec');\n\t\t\t\t\tresult.removeClass('running');\n\t\t\t\t};\n\t\t\t})(result)\n\t\t});\n\t});\n\n\tsuite.run({ 'async': true });\n\treturn stool;\n}\nstool.run = run;\n\n//wat;\nfunction add(title, code) {\n\tvar html = '<td><button class=\"remove\" tabindex=\"-1\">Remove</button></td><td class=\"inputs\"><input type=\"text\" class=\"title input\" placeholder=\"Label\"><textarea rows=\"6\" class=\"case input\" placeholder=\"Code\"></textarea></td><td class=\"result\"></td>'\n\tvar s = $('#suite');\n\tvar tr = $('<tr>');\n\ttr.html(html);\n\ttr.find('.remove')[0].onclick = (function (tr) {\n\t\treturn function () {\n\t\t\ttr.remove();\n\t\t\tclear();\n\t\t};\n\t})(tr);\n\n\tvar inputs = tr.find('.input').each(function(){\n\t\tthis.onkeydown = function () {\n\t\t\tabort();\n\t\t\tvar shareResult = $('#share-result').text('');\n\t\t\tshareResult.attr('href', '');\n\t\t}\n\t});\n\tif(code){\n\t\tcode = stool.text(code);\n\t\ttr.find('.title').val(title);\n\t\ttr.find('.case').val(code);\n\t}\n\ts.append(tr);\n\n\tclear();\n\n\treturn code? stool : tr;\n}\nstool.add = add;\n\nfunction setup(code){\n\tvar common = $('#common');\n\tcommon.val(stool.text(code));\n\treturn stool;\n}\nstool.setup = setup;\n\nfunction share() {\n\tvar body = {\n\t\t'public': true,\n\t\t'files': {}\n\t}\n\n\tvar titles = document.getElementsByClassName('title');\n\tvar cases = document.getElementsByClassName('case');\n\tvar common = document.getElementById('common');\n\n\tfor (var i = 0; i < cases.length; i++) {\n\t\tif (cases[i].value)\n\t\t\tbody.files[titles[i].value || '__empty' + i] = {'content': cases[i].value};\n\t}\n\n\tif (common.value)\n\t\tbody.files['__common'] = {'content': common.value};\n\n\tif (Object.keys(body.files).length == 0)\n\t\treturn;\n\n\tvar req = new XMLHttpRequest();\n\treq.open('post', 'https://api.github.com/gists', true);\n\treq.onload = function() {\n\t\tvar result = JSON.parse(req.responseText);\n\t\tvar shareResult = document.getElementById('share-result');\n\t\tvar location  = window.location.toString().replace(/#.*$/, '');\n\t\tshareResult.href = shareResult.innerText = location + '#' + result.id;\n\t}\n\treq.send(JSON.stringify(body));\n\treturn stool;\n}\nstool.share = share;\n\nfunction parse(id) {\n\tif (!id && !window.location.hash.length) return false;\n\n\tid = id || window.location.hash.substring(1);\n\tvar req = new XMLHttpRequest();\n\treq.open('get', 'https://api.github.com/gists/' + id, true);\n\treq.onload = function() {\n\t\tvar result = JSON.parse(req.responseText);\n\t\tvar files = result.files;\n\t\tfor (var file in files) {\n\t\t\tif (file == '__common') {\n\t\t\t\tdocument.getElementById('common').value = files[file].content;\n\t\t\t} else {\n\t\t\t\tvar tr = add();\n\t\t\t\ttr.getElementsByClassName('title')[0].value = file;\n\t\t\t\ttr.getElementsByClassName('case')[0].value = files[file].content;\n\t\t\t}\n\t\t}\n\t}\n\treq.send();\n\n\tvar shareResult = document.getElementById('share-result');\n\tshareResult.href = shareResult.innerText = window.location;\n\n\treturn true;\n}\nstool.parse = parse;\n\nstool.text = function(code){\n\tif(typeof code === 'function'){\n\t\treturn code.toString().slice(12).slice(0,-1);\n\t} else {\n\t\treturn code;\n\t}\n}\n\ndocument.getElementById('add').onclick = function() {\n\tadd();\n\treturn false;\n}\ndocument.getElementById('run').onclick = run;\ndocument.getElementById('abort').onclick = abort;\ndocument.getElementById('share').onclick = share;\n\nif (!parse()) {\n\t//add();\n\t//add();\n}\nwindow.stool = stool; // export!\n}());"
  },
  {
    "path": "test/ptsd/radix.html",
    "content": "<html>\n<head>\n\t<title>PTSD</title>\n\t<meta name=\"Description\" content=\"JavaScript benchmarking utility\">\n\t<link rel=\"stylesheet\" href=\"stool.css\">\n</head>\n<body>\n\t<div id=\"inject\"></div>\n\t<h1>PTSD</h1>\n\t<section>\n\t\t<h3>Setup code</h3>\n\t\t<textarea rows=\"6\" id=\"common\" class=\"common input\" placeholder=\"Common Code\"></textarea>\n\t\t<textarea id='log'>logs</textarea>\n\t</section>\n\t<section>\n\t\t<h3>Test cases</h3>\n\t\t<table id=\"suite\">\n\t\t\t<tr>\n\t\t\t\t<th class=\"th-remove\"></th>\n\t\t\t\t<th class=\"th-case\">Case</th>\n\t\t\t\t<th class=\"th-result\">Result</th>\n\t\t\t</tr>\n\t\t</table>\n\t\t<a href=\"#\" id=\"add\">+ Add test case</a>\n\t</section>\n\t<button id=\"run\">Run!</button>\n\t<button id=\"abort\">Abort</button>\n\t<button id=\"share\">Share</button>\n\t<a id=\"share-result\"></a>\n\t<script src=\"../../examples/jquery.js\"></script>\n\t<script src=\"benchmark.js\"></script>\n\t<script src=\"ptsd.js\"></script>\n\t<script src=\"../../gun.js\"></script>\n\t<script src=\"../../lib/radix.js\"></script>\n\t<script src=\"../../lib/radisk.js\"></script>\n\t<script src=\"radix.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "test/ptsd/radix.js",
    "content": ";(function(){\n\t// Performance Testing Stress Development\n\t// Performance Testing Style Development\n\t// Performance Testing Speed Development\n\t// Performance Testing Superior Development\n\t// Performance Testing Snippet Development\n\t// Performance Testing Skilled Development\n\t// Performance Testing Steady Development\n\t// Performance Testing Stepwise Development\n\t// Performance Testing Strong Development\n\t// Performance Testing Specified Development\n\t// Performance Testing Stipulated Development\n\t// Performance Testing Systematic Development\n\tif(!this.stool){ return }\n\tsetTimeout(function(){\n\t\tstool.run();\n\t},1);\n\tstool.setup(window.setup = function(){\n\t\t//window.BigText = Gun.text.random(1024, 'abcdef');\n\t\t//window.MedText = Gun.text.random(200, 'abcdef');\n\t\t//window.jsonText = JSON.stringify(window.BigText);\n\t\t//window.radText = Radisk.encode(window.BigText);\n\n\t\twindow.namez = [\"Adalard\",\"Adora\",\"Aia\",\"Albertina\",\"Alfie\",\"Allyn\",\"Amabil\",\"Ammamaria\",\"Andy\",\"Anselme\",\"Ardeen\",\"Armand\",\"Ashelman\",\"Aube\",\"Averyl\",\"Baker\",\"Barger\",\"Baten\",\"Bee\",\"Benia\",\"Bernat\",\"Bevers\",\"Bittner\",\"Bobbe\",\"Bonny\",\"Boyce\",\"Breech\",\"Brittaney\",\"Bryn\",\"Burkitt\",\"Cadmann\",\"Campagna\",\"Carlee\",\"Carver\",\"Cavallaro\",\"Chainey\",\"Chaunce\",\"Ching\",\"Cianca\",\"Claudina\",\"Clyve\",\"Colon\",\"Cooke\",\"Corrina\",\"Crawley\",\"Cullie\",\"Dacy\",\"Daniela\",\"Daryn\",\"Deedee\",\"Denie\",\"Devland\",\"Dimitri\",\"Dolphin\",\"Dorinda\",\"Dream\",\"Dunham\",\"Eachelle\",\"Edina\",\"Eisenstark\",\"Elish\",\"Elvis\",\"Eng\",\"Erland\",\"Ethan\",\"Evelyn\",\"Fairman\",\"Faus\",\"Fenner\",\"Fillander\",\"Flip\",\"Foskett\",\"Fredette\",\"Fullerton\",\"Gamali\",\"Gaspar\",\"Gemina\",\"Germana\",\"Gilberto\",\"Giuditta\",\"Goer\",\"Gotcher\",\"Greenstein\",\"Grosvenor\",\"Guthrey\",\"Haldane\",\"Hankins\",\"Harriette\",\"Hayman\",\"Heise\",\"Hepsiba\",\"Hewie\",\"Hiroshi\",\"Holtorf\",\"Howlond\",\"Hurless\",\"Ieso\",\"Ingold\",\"Isidora\",\"Jacoba\",\"Janelle\",\"Jaye\",\"Jennee\",\"Jillana\",\"Johnson\",\"Josy\",\"Justinian\",\"Kannan\",\"Kast\",\"Keeley\",\"Kennett\",\"Kho\",\"Kiran\",\"Knowles\",\"Koser\",\"Kroll\",\"LaMori\",\"Lanctot\",\"Lasky\",\"Laverna\",\"Leff\",\"Leonanie\",\"Lewert\",\"Lilybel\",\"Lissak\",\"Longerich\",\"Lou\",\"Ludeman\",\"Lyman\",\"Madai\",\"Maia\",\"Malvina\",\"Marcy\",\"Maris\",\"Martens\",\"Mathilda\",\"Maye\",\"McLain\",\"Melamie\",\"Meras\",\"Micco\",\"Millburn\",\"Mittel\",\"Montfort\",\"Moth\",\"Mutz\",\"Nananne\",\"Nazler\",\"Nesta\",\"Nicolina\",\"Noellyn\",\"Nuli\",\"Ody\",\"Olympie\",\"Orlena\",\"Other\",\"Pain\",\"Parry\",\"Paynter\",\"Pentheas\",\"Pettifer\",\"Phyllida\",\"Plath\",\"Posehn\",\"Proulx\",\"Quinlan\",\"Raimes\",\"Ras\",\"Redmer\",\"Renelle\",\"Ricard\",\"Rior\",\"Rocky\",\"Ron\",\"Rosetta\",\"Rubia\",\"Ruttger\",\"Salbu\",\"Sandy\",\"Saw\",\"Scholz\",\"Secor\",\"September\",\"Shanleigh\",\"Shenan\",\"Sholes\",\"Sig\",\"Sisely\",\"Soble\",\"Spanos\",\"Stanwinn\",\"Stevie\",\"Stu\",\"Suzanne\",\"Tacy\",\"Tanney\",\"Tekla\",\"Thackeray\",\"Thomasin\",\"Tilla\",\"Tomas\",\"Tracay\",\"Tristis\",\"Ty\",\"Urana\",\"Valdis\",\"Vasta\",\"Vezza\",\"Vitoria\",\"Wait\",\"Warring\",\"Weissmann\",\"Whetstone\",\"Williamson\",\"Wittenburg\",\"Wymore\",\"Yoho\",\"Zamir\",\"Zimmermann\"];\n\t\twindow.radix = window.radix || Radix();\n\t\twindow.arr = []; var i = 1000; while(--i){ arr.push(Math.random()) }\n\t\twindow.arrs = arr.slice(0).sort();\n\t\twindow.ALLZ = window.ALLZ || {};\n\t\twindow.namez.forEach(function(v,i){ ALLZ[v] = i });\n\t});\n\t/* TEMPORARY COPY OF RADIX UNIT TESTS TO BOOST SPEED */\n\t/* THESE ARE PROBABLY STALE AND NEED TO BE COPIED FROM UNIT TESTS AGAIN */\n\t/*stool.add('map', function(){\n\t\tGun.obj.map(ALLZ, function(v,i){\n\t\t\tv;\n\t\t});\n\t});\n\tstool.add('for', function(){\n\t\tfor(var k in ALLZ){\n\t\t\tALLZ[k];\n\t\t}\n\t});\n\tstool.add('for', function(){\n\t\tObject.keys(ALLZ).forEach(function(k){\n\t\t\tALLZ[k];\n\t\t})\n\t});\n\treturn;*/\n\tstool.add('1', function(){\n        var rad = Radix();\n        rad('asdf.pub', 'yum');\n        rad('ablah', 'cool');\n        rad('ab', {yes: 1});\n        rad('node/circle.bob', 'awesome');\n\n        (JSON.stringify(rad('asdf.')) !== JSON.stringify({pub: {'': 'yum'}})) && bada;\n        (rad('nv/foo.bar') != undefined) && badb;\n        (JSON.stringify(rad('ab')) != JSON.stringify({yes: 1})) && badc\n        (JSON.stringify(rad()) != JSON.stringify({\"a\":{\"sdf.pub\":{\"\":\"yum\"},\"b\":{\"lah\":{\"\":\"cool\"},\"\":{\"yes\":1}}},\"node/circle.bob\":{\"\":\"awesome\"}})) && badd;\n\t});\n\tstool.add('2', function(){\n        var all = {};\n        namez.forEach(function(v,i){\n            v = v.toLowerCase();\n            all[v] = v;\n            ALLZ[v] = i;\n            radix(v, i)\n        });\n        (Gun.obj.empty(all) === true) && bad3;\n        Radix.map(radix, function(v,k){\n            delete all[k];\n        });\n        (Gun.obj.empty(all) !== true) && bad4;\n\t});\n\tstool.add('fast?', function(){\n\t\tALLZ['rubia'];\n\t});\n\tstool.add('fastest?', function(){\n\t\tnamez.indexOf('Rubia');\n\t});\n\tstool.add('3', function(){\n        var all = {};\n        namez.forEach(function(v,i){\n            v = v.toLowerCase();\n            all[v] = v;\n            //rad(v, i)\n        });\n        (Gun.obj.empty(all) === true) && bad5;\n        Radix.map(radix, function(v,k){\n            delete all[k];\n        });\n        (Gun.obj.empty(all) !== true) && bad6;\n\t});\n\tstool.add('4', function(){\n        var all = {}, start = 'Warring'.toLowerCase(), end = 'Zamir'.toLowerCase();\n        namez.forEach(function(v,i){\n            v = v.toLowerCase();\n            if(v < start){ return }\n            if(end < v){ return }\n            all[v] = v;\n            //rad(v, i)\n        });\n        (Gun.obj.empty(all) === true) && bad7;\n        Radix.map(radix, function(v,k, a,b){\n            //if(!all[k]){ throw \"out of range!\" }\n            delete all[k];\n        }, {start: start, end: end});\n        (Gun.obj.empty(all) !== true) && bad8;\n\t});\n\tstool.add('5', function(){\n        var all = {}, start = 'Warrinf'.toLowerCase(), end = 'Zamis'.toLowerCase();\n        namez.forEach(function(v,i){\n            v = v.toLowerCase();\n            if(v < start){ return }\n            if(end < v){ return }\n            all[v] = v;\n            //rad(v, i)\n        });\n        (Gun.obj.empty(all) === true) && bad9;\n        Radix.map(radix, function(v,k, a,b){\n            //if(!all[k]){ throw \"out of range!\" }\n            delete all[k];\n        }, {start: start, end: end});\n        (Gun.obj.empty(all) !== true) && bad10;\n\t});\n\tstool.add('reverse item', function(){\n        Radix.map(radix, function(v,k, a,b){\n            (k !== 'ieso') && badri;\n            (v !== 96) && badri2;\n            return true;\n        }, {reverse: 1, end: 'iesogon'});\n\t});\n\tstool.add('6', function(){\n        var r = Radix(), tmp;\n        r('alice', 1);r('bob', 2);r('carl', 3);r('carlo',4);\n        r('dave', 5);r('zach',6);r('zachary',7);\n        var by = ['alice','bob','carl','carlo','dave','zach','zachary'];\n        Gun.obj.map(by, function(k,i){\n            r(k,i);\n        });\n        Radix.map(r, function(v,k, a,b){\n        \t(by.pop() !== k) && bad11;\n          tmp = v;\n        }, {reverse: 1});\n        (tmp !== 1) && bad12;\n        (by.length !== 0) && bad13;\n        Radix.map(r, function(v,k, a,b){\n            tmp = v;\n        });\n        (tmp !== 7) && bad14;\n\t});\n\treturn;\n\tstool.add('JSON encode string', function(){\n\t\tJSON.stringify(window.BigText);\n\t});\n\tstool.add('RAD encode string', function(){\n\t\tRadisk.encode(window.BigText);\n\t});\n\tstool.add('JSON decode string', function(){\n\t\tJSON.parse(window.jsonText);\n\t});\n\tstool.add('RAD decode string', function(){\n\t\tRadisk.decode(window.radText);\n\t});\n\treturn;\n\tstool.add('JSON null', function(){\n\t\tJSON.parse(JSON.stringify(null));\n\t});\n\tstool.add('RAD null', function(){\n\t\tRadisk.decode(Radisk.encode(null));\n\t});\n\tstool.add('JSON false', function(){\n\t\tJSON.parse(JSON.stringify(false));\n\t});\n\tstool.add('RAD false', function(){\n\t\tRadisk.decode(Radisk.encode(false));\n\t});\n\tstool.add('JSON true', function(){\n\t\tJSON.parse(JSON.stringify(true));\n\t});\n\tstool.add('RAD true', function(){\n\t\tRadisk.decode(Radisk.encode(true));\n\t});\n\tstool.add('JSON number', function(){\n\t\tJSON.parse(JSON.stringify(23));\n\t});\n\tstool.add('RAD number', function(){\n\t\tRadisk.decode(Radisk.encode(23));\n\t});\n\tstool.add('JSON text', function(){\n\t\tJSON.parse(JSON.stringify(\"hello world\"));\n\t});\n\tstool.add('RAD text', function(){\n\t\tRadisk.decode(Radisk.encode(\"hello world\"));\n\t});\n\tstool.add('JSON text big', function(){\n\t\tJSON.parse(JSON.stringify(window.BigText));\n\t});\n\tstool.add('RAD text big', function(){\n\t\tRadisk.decode(Radisk.encode(window.BigText));\n\t});\n}());"
  },
  {
    "path": "test/ptsd/spam.js",
    "content": ";(function(){\nwindow.SPAM = function(cb, opt){\n\topt = Gun.num.is(opt)? {each: opt} : opt || {};\n\topt.wait = opt.wait || 1;\n\tsetInterval(burst, opt.wait);\n\nvar n = Gun.time.is(), i = 0, c = 0, b = opt.burst || 10, l = opt.each || 100;\nvar r = Gun.text.random, raw;\n\nfunction save(i){\n\tif(!window.SPAM){ return }\n\tif(i > l){\n\t\treturn clearTimeout(t);\n\t}\n\tcb(i, i + raw + i);\n}\nfunction burst(){\n\traw = r(1000000);\n\tfor(var j = 0; j <= b; j++){\n\t\tsave(++i);\n\t}\n}\nvar t;\n}\n}());\n\nvar gun = Gun({localStorage: false, peers: 'http://localhost:8765/gun'});\nvar g = gun.get('test');\nvar room = Gun.text.random(100);\nvar pub = Gun.text.random(1000);\nSPAM(function(i, v){\n\t//console.log(Gun.state(), i);return;\n\tconsole.log(i);\n\tvar ref = g.set({\n\t\ta: v,\n\t\tb: i,\n\t\tc: room,\n\t\td: pub\n\t}, function(ack){\n\t\tref.off();\n\t});\n}, 99999999999999);\n\n/*\n;(function(){\n\t$(\"#say\").on('submit', function(){\n\t\tsetTimeout(function(){\n\t\t\t$(\"#say\").find('input').first().val(Gun.text.random(1000));\n\t\t},1);\n\t});\n});\n*/"
  },
  {
    "path": "test/ptsd/stool.css",
    "content": "body {\n\twidth: 90%;\n\tmax-width: 800px;\n\tmargin: 4em auto;\n\tfont: 12pt Helvetia, Arial, sans-serif;\n}\n\nsection {\n\tmargin: 0 0 4em;\n}\n\ntable {\n\tborder-spacing: 0;\n\twidth: 100%;\n}\n\nth, td {\n\tvertical-align: top;\n\tpadding: 0 0 1em 0;\n}\n\nth {\n\ttext-align: left;\n}\n\nth.th-result {\n\twidth: 200px;\n}\n\nth.th-remove {\n\twidth: 0;\n}\n\ntd.inputs {\n\tpadding-right: 1em;\n}\n\n.remove {\n\tposition: absolute;\n\tmargin-left: -6em;\n\twidth: 5em;\n}\n\ninput, textarea {\n\tmargin: 0 0 1em 0;\n\twidth: 100%;\n\tdisplay: block;\n\tresize: vertical;\n}\n\n.result.running {\n\tcolor: #ccc;\n}\n\n#abort {\n\tdisplay: none;\n}\n.running #abort {\n\tdisplay: initial;\n}\n\n.running #run {\n\tdisplay: none;\n}"
  },
  {
    "path": "test/ptsd/streampipe.js",
    "content": "const stream = require('stream')\nconst Gun = require('gun')\n\nconst randomString = length => {\n  const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n  let text = ''\n  for (var i = 0; i < length; i++) {\n    text += possible[Math.floor(Math.random() * possible.length)]\n  }\n  return text\n}\n\n// Generator\n// generates stream of json {id: \"\", name: \"\", description: \"\"}\nclass Generator extends stream.Readable {\n  constructor(n) {\n    super()\n\n    this._n = n\n    this._i = 0\n  }\n\n  _read(size) {\n    if (this._i < this._n) {\n      this.push(\n        JSON.stringify({\n          id: `${this._i}`,\n          name: randomString(20),\n          description: randomString(200)\n        })\n      )\n      this.push('\\n')\n      this._i++\n    } else {\n      this.push(null)\n    }\n  }\n}\n\n// Line\n// read line by line as stream comes through it\nclass Line extends stream.Transform {\n  constructor() {\n    super()\n    this.buff = ''\n  }\n\n  trySendLine() {\n    let index = this.buff.indexOf(`\\n`)\n\n    while (index !== -1) {\n      const line = this.buff.slice(0, index)\n      this.buff = this.buff.slice(index + 1)\n\n      this.push(line)\n\n      index = this.buff.indexOf(`\\n`)\n    }\n  }\n\n  _transform(chunk, enc, cb) {\n    this.buff += chunk.toString()\n\n    this.trySendLine()\n\n    cb()\n  }\n\n  end() {\n    this.trySendLine()\n\n    if (this.buff.length > 0) {\n      this.push(this.buff)\n    }\n  }\n}\n\n// Graph\n// parse the chunk and tries to add it to table\nclass Graph extends stream.Transform {\n  constructor() {\n    super()\n\n    this.db = new Gun({\n      //file: 'graph.json'\n      localStorage: false\n    })\n    this.items = this.db.get('items')\n  }\n\n  _transform(chunk, enc, cb) {\n    const json = JSON.parse(chunk.toString())\n    const item = this.db.get(json.id)\n\n    item.put(\n      {\n        id: json.id,\n        name: json.name,\n        description: json.description\n      },\n      () => {\n        this.items.set(item, () => {\n          this.push(chunk)\n          cb()\n        })\n      }\n    )\n  }\n}\n\n// Report\n// shows how many item has pass through the system\nclass Report extends stream.Transform {\n  constructor() {\n    super()\n    this._count = 0\n  }\n\n  _transform(chunk, enc, cb) {\n    this.push(`count: ${this._count++}\\r`)\n    cb()\n  }\n}\n\nconst generator = new Generator(5000)\nconst line = new Line()\nconst graph = new Graph()\nconst report = new Report()\n\ngenerator\n  .pipe(line)\n  .pipe(graph)\n  .pipe(report)\n  .pipe(process.stdout)"
  },
  {
    "path": "test/rad/2020and2021.js",
    "content": "var Gun = require('../../index');\n\nvar gun = Gun({file: __dirname+'/old2020json'});\n\ngun.get('test').once(function(data, key){\n\tconsole.log(key, data);\n\tif(!data){ throw \"not compatible!\" }\n});"
  },
  {
    "path": "test/rad/bench.js",
    "content": "var Gun = (typeof window !== \"undefined\")? window.Gun : require('../../../gun/gun');\n\nvar Radisk = (Gun.window && window.Radisk) || require('../../../gun/lib/radisk');\nGun.TESTING = true;\ntry{localStorage.clear()}catch(e){}\ntry{indexedDB.deleteDatabase('radatatest');}catch(e){}\ntry{indexedDB.deleteDatabase('radata');}catch(e){}\n\nvar opt = {localStorage: false};\n//opt.chunk = 1024;\nopt.store = (Gun.window && window.RindexedDB(opt)) || require('../../../gun/lib/rfs')(opt)\nvar rad = Radisk(opt);\n//var gun = Gun(opt);\nvar gun = Gun('http://localhost:8765/gun');\n\nGun.window && (wait.onchange = function(){ spam.wait = this.value })\nGun.window && (burst.onchange = function(){ spam.burst = this.value })\n//setTimeout(spam, 1);\nfunction spam(){\n\t//spam.max = 100000; spam.left = spam.max; spam.wait = 1; spam.burst = 250; spam.c = 0; spam.s = (+new Date);\n\t//spam.max = 1000000; spam.left = spam.max; spam.wait = 0; spam.burst = 100; spam.c = 0; spam.s = (+new Date);\n\t//spam.max = 300000; spam.left = spam.max; spam.wait = 1; spam.burst = 5; spam.c = 0; spam.s = (+new Date);\n\t//spam.max = 100000; spam.left = spam.max; spam.wait = 0; spam.burst = 2; spam.c = 0; spam.s = (+new Date);\n\t//spam.max = 100000; spam.left = spam.max; spam.wait = 20; spam.burst = 2; spam.c = 0; spam.s = (+new Date);\n\t//spam.max = 100; spam.left = spam.max; spam.wait = 1; spam.burst = 1; spam.c = 0; spam.s = (+new Date);\n\tspam.max = 100000; spam.left = spam.max; spam.wait = 100; spam.burst = 100; spam.c = 99; spam.s = (+new Date);\n\tvar S = +new Date, slow = 0; console.only.i = 1;\n\tvar to = setTimeout(function gap(){\n\t\tif(spam.c >= spam.max){ clearTimeout(to); return; }\n\t\tsetTimeout(gap, Math.random() * 100);\n\t\tvar b = spam.burst;\n\t\tb = Math.ceil(Math.random() * b);\n\t\t//console.log('spam', +new Date - S, spam.c); S = +new Date;\n\t\tif(!b){ b = burst = 1 }\n\t\twhile(b--){ go(++spam.c) }\n\t\tfunction go(i){ var d = 0, s = +new Date;\n\t\t\ti = Math.random().toString(32).slice(2);\n\t\t\t//console.log('go', spam.c, i);\n\t\t\t//setTimeout(function(){ var ack = {err: 0, ok: 1};\n\t\t\t//loc.put(i, {test: i}, function(err, ok){ var ack = {err: err, ok: ok};\n\t\t\t//ind.put(i, {test: i}, function(err, ok){ var ack = {err: err, ok: ok};\n\t\t\t//rad(i, {test: i}, function(err, ok){ var ack = {err: err, ok: ok};\n\t\t\tvar ref = gun.get(i).put({test: i}, function(ack){\n\t\t\t\tvar t = (+new Date - s)/1000; if(1 < t){ ++slow; }\n\t\t\t\tif(ack.err){ console.log(ack); }\n\t\t\t\tif(d++){ return }\n\t\t\t\tif(--spam.left){ return }\n\t\t\t\tspam.end = (+new Date) - spam.s;\n\t\t\t\tconsole.log('DONE!\\n', spam.max, 'in', spam.end/1000, 'seconds\\n', Math.round(spam.max / (spam.end/1000)), 'per second. Slow:' + slow);\n\t\t\t\tGun.window && (document.body.style.backgroundColor = 'lime');\n\t\t\t});\n\t\t}\n\t},spam.wait);\n\tsetInterval(function(){\n\t\tif(spam.end === true){ return }\n\t\tif(spam.end){ spam.end = true }\n\t\tvar t = (+new Date) - spam.s, tmp, sec;\n\t\tvar status = 'saved\\n'+ (tmp = (spam.max - spam.left)) +' in '+ (sec = (t/1000)) +' seconds\\n'+ Math.round(tmp / sec) +' per second';\n\t\t(Gun.window && (debugs.innerText = status)) || console.log(status.replace(/\\n/ig,' '));\n\t}, 500);\n}\n!Gun.window && setTimeout(spam,1);\n\n;(function(){\nif(!Gun.window){ return }\n;(function(){\nvar f = 'index';\nindexedDB.deleteDatabase(f);\nvar o = indexedDB.open(f, 1), ind = {}, db;\no.onupgradeneeded = function(eve){ (eve.target.result).createObjectStore(f) }\no.onsuccess = function(){ db = o.result }\no.onerror = function(eve){ console.log(eve||1); }\nind.put = function(key, data, cb){\n\tif(!db){ setTimeout(function(){ ind.put(key, data, cb) },9); return }\n\tvar tx = db.transaction([f], 'readwrite');\n\tvar obj = tx.objectStore(f);\n\tvar req = obj.put(data, ''+key);\n\treq.onsuccess = obj.onsuccess = tx.onsuccess = function(){ cb(null, 1) }\n\treq.onabort = obj.onabort = tx.onabort = function(eve){ cb(eve||2) }\n\treq.onerror = obj.onerror = tx.onerror = function(eve){ cb(eve||3) }\n}\nind.get = function(key, cb){\n\tif(!db){ setTimeout(function(){ ind.get(key, cb) },9); return }\n\tvar tx = db.transaction([f], 'readwrite');\n\tvar obj = tx.objectStore(f);\n\tvar req = obj.get(''+key);\n\treq.onsuccess = function(){ cb(null, req.result) }\n\treq.onabort = function(eve){ cb(eve||4) }\n\treq.onerror = function(eve){ cb(eve||5) }\n}\nwindow.ind = ind;\n}());\n\n;(function(){\nlocalStorage.clear();\nvar ls = localStorage, loc = {};\nloc.put = function(key, data, cb){ ls[''+key] = data; cb(null, 1) }\nloc.get = function(key, cb){ cb(null, ls[''+key]) }\nwindow.loc = loc;\n}());\n}());"
  },
  {
    "path": "test/rad/book.html",
    "content": "<!DOCTYPE html>\n<style>html, body, textarea { width: 100%; height: 100%; padding: 0; margin: 0; }</style>\n<ul id='list'></ul>\n<form id='form'>\n  <input id='who' placeholder='name'>\n  <input id='what' placeholder='say'>\n  <input type='submit' value='send'>\n</form>\n<script src=\"../../../gun/src/book.js\"></script>\n<script src=\"../../../gun/rad.js\"></script><script>\nsearch = setTimeout.RAD();\n\nform.onsubmit = (eve)=>{\n  search(+new Date, (who.value+') '+what.value));\n  eve.preventDefault(what.value = \"\");\n}\n\nsetInterval(async ()=>{\n  list.innerText = await search(+new Date).results();\n},99);\n</script>"
  },
  {
    "path": "test/rad/book.js",
    "content": "var root;\nvar Gun;\n(function(){\n  var env;\n  if(typeof global !== 'undefined'){ env = global }\n  if(typeof window !== 'undefined'){ env = window }\n  root = env.window? env.window : global;\n  try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n  //try{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n  if(root.Gun){\n    root.Gun = root.Gun;\n    root.Gun.TESTING = true;\n  } else {\n    try{ require('fs').unlinkSync('data.json') }catch(e){}\n    try{ require('../../lib/fsrm')('radatatest') }catch(e){}\n    root.Gun = require('../../gun');\n    root.Gun.TESTING = true;\n    require('../../lib/store');\n    require('../../lib/rfs');\n  }\n\n  try{ var expect = global.expect = require(\"../expect\") }catch(e){}\n\n}(this));\n\n;(function(){\nGun = root.Gun\n\ndescribe('RAD', function(){\n\nvar names = [\"Adalard\",\"Adora\",\"Aia\",\"Albertina\",\"Alfie\",\"Allyn\",\"Amabil\",\"Ammamaria\",\"Andy\",\"Anselme\",\"Ardeen\",\"Armand\",\"Ashelman\",\"Aube\",\"Averyl\",\"Baker\",\"Barger\",\"Baten\",\"Bee\",\"Benia\",\"Bernat\",\"Bevers\",\"Bittner\",\"Bobbe\",\"Bonny\",\"Boyce\",\"Breech\",\"Brittaney\",\"Bryn\",\"Burkitt\",\"Cadmann\",\"Campagna\",\"Carlee\",\"Carver\",\"Cavallaro\",\"Chainey\",\"Chaunce\",\"Ching\",\"Cianca\",\"Claudina\",\"Clyve\",\"Colon\",\"Cooke\",\"Corrina\",\"Crawley\",\"Cullie\",\"Dacy\",\"Daniela\",\"Daryn\",\"Deedee\",\"Denie\",\"Devland\",\"Dimitri\",\"Dolphin\",\"Dorinda\",\"Dream\",\"Dunham\",\"Eachelle\",\"Edina\",\"Eisenstark\",\"Elish\",\"Elvis\",\"Eng\",\"Erland\",\"Ethan\",\"Evelyn\",\"Fairman\",\"Faus\",\"Fenner\",\"Fillander\",\"Flip\",\"Foskett\",\"Fredette\",\"Fullerton\",\"Gamali\",\"Gaspar\",\"Gemina\",\"Germana\",\"Gilberto\",\"Giuditta\",\"Goer\",\"Gotcher\",\"Greenstein\",\"Grosvenor\",\"Guthrey\",\"Haldane\",\"Hankins\",\"Harriette\",\"Hayman\",\"Heise\",\"Hepsiba\",\"Hewie\",\"Hiroshi\",\"Holtorf\",\"Howlond\",\"Hurless\",\"Ieso\",\"Ingold\",\"Isidora\",\"Jacoba\",\"Janelle\",\"Jaye\",\"Jennee\",\"Jillana\",\"Johnson\",\"Josy\",\"Justinian\",\"Kannan\",\"Kast\",\"Keeley\",\"Kennett\",\"Kho\",\"Kiran\",\"Knowles\",\"Koser\",\"Kroll\",\"LaMori\",\"Lanctot\",\"Lasky\",\"Laverna\",\"Leff\",\"Leonanie\",\"Lewert\",\"Lilybel\",\"Lissak\",\"Longerich\",\"Lou\",\"Ludeman\",\"Lyman\",\"Madai\",\"Maia\",\"Malvina\",\"Marcy\",\"Maris\",\"Martens\",\"Mathilda\",\"Maye\",\"McLain\",\"Melamie\",\"Meras\",\"Micco\",\"Millburn\",\"Mittel\",\"Montfort\",\"Moth\",\"Mutz\",\"Nananne\",\"Nazler\",\"Nesta\",\"Nicolina\",\"Noellyn\",\"Nuli\",\"Ody\",\"Olympie\",\"Orlena\",\"Other\",\"Pain\",\"Parry\",\"Paynter\",\"Pentheas\",\"Pettifer\",\"Phyllida\",\"Plath\",\"Posehn\",\"Proulx\",\"Quinlan\",\"Raimes\",\"Ras\",\"Redmer\",\"Renelle\",\"Ricard\",\"Rior\",\"Rocky\",\"Ron\",\"Rosetta\",\"Rubia\",\"Ruttger\",\"Salbu\",\"Sandy\",\"Saw\",\"Scholz\",\"Secor\",\"September\",\"Shanleigh\",\"Shenan\",\"Sholes\",\"Sig\",\"Sisely\",\"Soble\",\"Spanos\",\"Stanwinn\",\"Stevie\",\"Stu\",\"Suzanne\",\"Tacy\",\"Tanney\",\"Tekla\",\"Thackeray\",\"Thomasin\",\"Tilla\",\"Tomas\",\"Tracay\",\"Tristis\",\"Ty\",\"Urana\",\"Valdis\",\"Vasta\",\"Vezza\",\"Vitoria\",\"Wait\",\"Warring\",\"Weissmann\",\"Whetstone\",\"Williamson\",\"Wittenburg\",\"Wymore\",\"Yoho\",\"Zamir\",\"Zimmermann\"];\n\n  var opt = {};\n  opt.file = 'radatatest';\n  var RAD = (setTimeout.RAD) || require('../../lib/radisk');\n  var Book = (setTimeout.Book) || require('../../lib/book');\n  //opt.store = ((Gun.window && Gun.window.RindexedDB) || require('../../lib/rfs'))(opt);\n  opt.chunk = 1000;\n  var rad = RAD(opt), esc = String.fromCharCode(27);\n\n  describe('Book', function(){\n    this.timeout(1000 * 9);\n\n    /*it('parse', function(done){\n        this.timeout(60000);\n        if(Gun.window){ return done() }\n        var raw = require('fs').readFileSync(__dirname + '/parse.rad').toString();\n        rad.parse('!', function(err, disk){\n            console.log(\"!!!!\", err);\n        }, raw);\n        return;\n    });*/\n\n    it('deleting old RAD tests (may take long time)', function(done){\n        done(); // Mocha doesn't print test until after its done, so show this first.\n    });\n\n    it('deleted', function(done){\n        this.timeout(60 * 1000);\n        if(!Gun.window){ return done() }\n        root.localStorage && root.localStorage.clear();\n        //await new Promise(function(res){ indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ res() } } );\n        indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ done() }\n    });\n\n    describe('Book Format', function(done){\n        var B = Book;\n        it('encode decode', function(){\n            expect(B.decode(B.encode(null))).to.be(null);\n            expect(B.decode(B.encode(false))).to.be(false);\n            expect(B.decode(B.encode(true))).to.be(true);\n            expect(B.decode(B.encode(0))).to.be(0);\n            expect(B.decode(B.encode(-Infinity))).to.be(-Infinity);\n            expect(B.decode(B.encode(Infinity))).to.be(Infinity);\n            expect(B.decode(B.encode(1))).to.be(1);\n            expect(B.decode(B.encode(2))).to.be(2);\n            expect(B.decode(B.encode(1.2))).to.be(1.2);\n            expect(B.decode(B.encode(1234.56789))).to.be(1234.56789);\n            expect(B.decode(B.encode(''))).to.be('');\n            expect(B.decode(B.encode(\"hello world\"))).to.be(\"hello world\");\n            expect(B.decode(B.encode(\"he||o\"))).to.be(\"he||o\");\n            expect(B.decode(B.encode(\"ho|y ha|o\"))).to.be(\"ho|y ha|o\");\n            expect(B.decode(B.encode(\"he||||y\"))).to.be(\"he||||y\");\n            expect(B.decode(B.encode(\"ho|\\|ow\"))).to.be(\"ho|\\|ow\");\n            expect(B.decode(B.encode(\"so\\\\rrow\"))).to.be(\"so\\\\rrow\");\n            expect(B.decode(B.encode(\"bo\\\\|\\|row\"))).to.be(\"bo\\\\|\\|row\");\n            expect(B.decode(B.encode(\"||\\áãbbçcddéẽffǵghhíĩj́jḱkĺlḿmńñóõṕpqqŕrśsttẃwúǘũxxýỹźzàbcdèfghìjklm̀ǹòpqrstùǜẁxỳz|\"))).to.be(\"||\\áãbbçcddéẽffǵghhíĩj́jḱkĺlḿmńñóõṕpqqŕrśsttẃwúǘũxxýỹźzàbcdèfghìjklm̀ǹòpqrstùǜẁxỳz|\");\n        });\n        it('heal', function(){\n            //var obj = {a: null, b: false, c: true, d: 0, e: 42, f: Infinity, h: \"hello\"};\n            var page = '| |-|+|'+B.encode('he||o!')+'|+0|+42.69|'+B.encode('he|p')+'|+Infinity|';\n            expect(B.slot(page)).to.be.eql([' ', '-', '+', '|2\"he||o!', '+0', '+42.69', '|1\"he|p', '+Infinity']);\n        });\n        it.skip('encode decode object', function(){\n            expect(B.decode(B.encode({foo: 'bar', a: 1}))).to.be.eql({foo: 'bar', a: 1})\n        });\n    });\n\n    describe('BASIC API', function(done){\n        // TODO: Mark return here, slot(\"\") slot(\"ab\") causes infinite loop with heal, so need to detect not corrupted yet.\n\n        it('write', function(done){\n            rad('hello', 'world', function(err, ok){\n                expect(err).to.not.be.ok();\n                done();\n            });\n        });\n\n        it('read', function(done){\n            rad('hello', function(page, err){\n                var val = page.get('hello');\n                expect(val).to.be('world');\n                done();\n            })\n        });\n    });\n\n    var prim = [\n      null,\n      'string',\n      728858,\n      BigInt(1000000000000000000000000000000000000000000000000000000000n),\n      true,\n      false,\n      -Infinity,\n      Infinity,\n      -0\n    ];\n    //var prim = ['alice', 'bob'];\n    //var prim = [null];\n    root.rad = rad;\n\n    describe('can in-memory write & read all primitives', done => { prim.forEach(function(type){\n        var b = setTimeout.Book();\n        it('save '+type, done => { setTimeout(function(){\n            b('type-'+type, type);\n            var val = b('type-'+type);\n            expect(val).to.be(type);\n            done();\n        },1); });\n    });});\n\n    describe('can disk write & read all primitives', done => { prim.forEach(function(type){\n        it('save '+type, done => { setTimeout(function(){\n            rad('type-'+type, type, function(err, ok){\n                expect(err).to.not.be.ok();\n                rad('type-'+type, function(page, err){\n                    var val = page.get('type-'+type);\n                    expect(val).to.be(type);\n                    done();\n                });\n            });\n        },1); });\n    });});\n\n    describe('error on invalid primitives', function(){\n        console.log(\"TODO: TESTS! Add invalid data type tests, error checking. HINT: Maybe also add invisible ASCII character tests here too.\");\n        it.skip('test invalid', done => {\n            rad('type-NaN', NaN, function(err, ok){\n                expect(err).to.be.ok();\n                done();\n            });\n        });\n    });\n\n    describe('Async Race Conditions', function(){\n\n        it('make sure word does not get duplicated when data is re-saved after read', done => {\n            var opt = {file: 'zadata'}\n            var prev = RAD(opt);\n\n            prev('helloz', 'world', function(err, ok){\n                prev('helloz', function(page, err){\n                    prev('zalice', 'yay', function(err){\n                        expect(page.text.split('helloz').length).to.be(2);\n                        done();\n                    });\n                });\n            });\n            /*\n                (A) READ ONLY: we receive a message, we READ only - parseless is important.\n                (B) READ & WRITE: we write a page, and it already exists on disk.\n                (C) WRITE ONLY: we write a page, and it is new to disk.\n            */\n        });\n\n        it('make sure word does not get duplicated when data is re-saved after read <', done => {\n            var opt = {file: 'azadata'}\n            var prev = RAD(opt);\n\n            prev('helloz', 'world', function(err, ok){\n                prev('helloz', function(page, err){\n                    prev('azalice', 'yay', function(err){\n                        expect(page.text.split('helloz').length).to.be(2);\n                        done();\n                    });\n                });\n            });\n            /*\n                (A) READ ONLY: we receive a message, we READ only - parseless is important.\n                (B) READ & WRITE: we write a page, and it already exists on disk.\n                (C) WRITE ONLY: we write a page, and it is new to disk.\n            */\n        });\n\n        it('test if adding an in-memory word merges with previously written disk data', done => {\n            var prev = RAD(opt);\n\n            prev('pa-alice', 'hello', function(err, ok){\n                expect(err).to.not.be.ok();\n\n                setTimeout(function(){\n                    var rad = RAD(opt);\n                    rad('pa-bob', 'banana', function(err, ok){\n                        expect(err).to.not.be.ok();\n                        var text = rad.book.list[0].text;\n                        var i = text.indexOf('pa-alice');\n                        expect(i).to.not.be(-1);\n                        var ii = text.indexOf('hello');\n                        expect((ii - i) < ('pa-alice'.length + 3)).to.be.ok();\n                        done();\n                    })\n                },99);\n            });\n        });\n\n        it('test if adding an in-memory word merges with previously written disk data <', done => {\n            var opt = {file: 'azadatab'}\n            var prev = RAD(opt);\n\n            prev('pa-alice', 'hello', function(err, ok){\n                expect(err).to.not.be.ok();\n\n                setTimeout(function(){\n                    var rad = RAD(opt);\n                    rad('pa-alex', 'banana', function(err, ok){\n                        expect(err).to.not.be.ok();\n                        var text = rad.book.list[0].text;\n                        var i = text.indexOf('pa-alice');\n                        expect(i).to.not.be(-1);\n                        var ii = text.indexOf('hello');\n                        expect((ii - i) < ('pa-alice'.length + 3)).to.be.ok();\n                        done();\n                    })\n                },99);\n            });\n        });\n\n        it('test if adding an in-memory escaped word merges with previously written disk data', done => {\n            var opt = {file:'badata'};\n            var prev = RAD(opt);\n\n            prev('ba-bob', 'hello', function(err, ok){\n                expect(err).to.not.be.ok();\n\n                setTimeout(function(){\n                    var rad = RAD(opt);\n                    rad('ba-a|ice', 'banana', function(err, ok){\n                        expect(err).to.not.be.ok();\n                        var text = rad.book.list[0].text;\n                        var i = text.indexOf('ba-a|ice');\n                        expect(i).to.not.be(-1);\n                        var ii = text.indexOf('banana');\n                        expect((ii - i) < ('ba-a|ice'.length + 3)).to.be.ok();\n                        var iii = text.indexOf('ba-bob');\n                        if(iii < i){ console.log(\"ERROR! Escaped word not sorted correctly!!!\") }\n                        expect(iii > i).to.be.ok();\n                        done();\n                    })\n                },99);\n            });\n        });\n\n        it('test if updating an in-memory word merges with previously written disk data', done => {\n            var opt = {file:'pu-data'};\n            var prev = RAD(opt);\n            prev('pu-zach', 'zap');\n            prev('pu-alex', 'yay');\n            prev('pu-alice', 'hello', function(err, ok){\n                expect(err).to.not.be.ok();\n\n                var rad = RAD(opt);\n                rad('pu-alice', 'cool', function(err, ok){\n                    expect(err).to.not.be.ok();\n                    var next = RAD(opt);\n                    next('pu-alice', function(page, err){\n                        expect('cool').to.be(page.get('pu-alice'));\n                        done();\n                    })\n                });\n            });\n        });\n\n    });\n\n    describe('Recursive Book Lookups', function(){\n\n        function gen(val){ return val + String.random(99,'a') }\n        var opt = {file: 'gen'}\n        var rad = RAD(opt);\n        it('Generate more than 1 page', done => {\n\n            var i = 0;\n            names.forEach(function(name){\n                name = name.toLowerCase();\n                rad(name, gen(name));\n\n                clearTimeout(done.c)\n                done.c = setTimeout(done, 99);\n            });\n\n        });\n\n        it('Make sure parseless lookup works with incrementally parsed values', done => {\n            rad = RAD(opt);\n            rad('adora', function(page, err){\n                var n = page.get('adora');\n                expect(gen('adora')).to.be(n);\n\n                rad('aia', function(page, err){\n                    var n = page.get('aia');\n                    expect(gen('aia')).to.be(n);\n                    done();\n                });\n            });\n\n        });\n\n        it('Read across the pages', done => {\n\n            rad = RAD(opt);\n            names.forEach(function(name){\n                name = name.toLowerCase();\n                rad(name+'a', function(page, err){\n                    var n = page.get(name);\n                    expect(gen(name)).to.be(n);\n\n                    clearTimeout(done.c);\n                    done.c = setTimeout(done, 99);\n                });\n            });\n\n        });\n\n\n        /*it.skip('Correctly calculate size', done => {\n\n            var r = String.random(1000);\n            rad('a', r);\n\n            r = String.random(2000);\n            rad('b', r);\n\n            r = String.random(3000);\n            rad('c', r);\n\n        });*/\n        \n        it.skip('index metadata', done => {\n            localStorage.clear();\n            var B = setTimeout.Book;\n            var r = setTimeout.RAD();\n            //r('hello', 'world');\n            //return;\n            var i = 200; while(--i){ r('store'+i, Math.random()+'r'+Math.random()) }\n            console.log('switch test to a test of replication, maybe with panic');\n            r('store150', function(page, err){\n                console.log(\"<<<<<<<<<\");\n                page.meta = 'https://localhost:9876,https://localhost:9877';\n            var i = 200; while(--i){ r('store'+i+'b', Math.random()+'r'+Math.random()) }\n                console.log(\">>>>>>>>>\");\n            })\n        });\n\n    });\n\n    describe('API usage checks', function(){\n        var opt = {file: 'search'}\n        var search = RAD(opt);\n        var b = Book();\n        it('read results from in-memory data', async done => {\n            b('hello', '1data');\n            var r = b.page('wat').read();\n            expect(r).to.be.eql(['1data']);\n            b('hello', '1dataZ');\n            r = b.page('wat').read();\n            expect(r).to.be.eql(['1dataZ']);\n            b('new', '2data');\n            r = b.page('wat').read();\n            expect(r).to.be.eql(['1dataZ','2data']);\n            done();\n        });\n\n    });\n\n    console.log(\"Performance Tests: 2023 Nov 12, 60M put/sec, 120M get/sec, 1M get/sec with splits.\");\n\n  });\n\n    var ntmp = names;\n  describe.skip('RAD + GUN', function(){ return;\n    this.timeout(1000 * 9);\n    var ochunk = 1000;\n    Gun.on('opt', function(root){\n        root.opt.localStorage = false;\n        Gun.window && console.log(\"RAD disabling localStorage during tests.\");\n        this.to.next(root);\n    })\n    var gun = Gun({chunk: ochunk});\n\n    /*it('deleting old tests (may take long time)', function(done){\n        done(); // Mocha doesn't print test until after its done, so show this first.\n    }); it('deleted', function(done){\n        this.timeout(60 * 1000);\n        if(!Gun.window){ return done() }\n        indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ done() }\n    });*/\n\n    it('write contacts', function(done){\n        var all = {}, to, start, tmp;\n        names.forEach(function(v,i){\n            all[++i] = true;\n            tmp = v.toLowerCase();\n            gun.get('names').get(tmp).put({name: v, age: i}, function(ack){\n                expect(ack.err).to.not.be.ok();\n                delete all[i];\n                if(!Object.empty(all)){ return }\n                done();\n            })\n        })\n    });\n\n  });\n\n});\n\n}());\n"
  },
  {
    "path": "test/rad/browser.html",
    "content": "<html>\n<body>\n<h1>RindexedDB</h1>\n\n<script src=\"../../../gun/gun.js\"></script>\n<script src=\"../../../gun/lib/radix.js\"></script>\n<script src=\"../../../gun/lib/radisk.js\"></script>\n<script src=\"../../../gun/lib/store.js\"></script>\n<script src=\"../../../gun/lib/rindexed.js\"></script>\n<!-- script src=\"../../../gun/lib/rls.js\"></script -->\n\n<button onclick=\"spam()\">spam</button>\n<button onclick=\"read()\">read</button>\n<input id=\"wait\" placeholder=\"wait\" type=\"number\">\n<input id=\"burst\" placeholder=\"burst\" type=\"number\">\n<div id='debugs'></div>\n<div id='debug'></div>\n\n<script src=\"../../../gun/test/rad/bench.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "test/rad/crash.js",
    "content": "var root;\nvar Gun;\n(function(){\n  var env;\n  if(typeof global !== 'undefined'){ env = global }\n  if(typeof window !== 'undefined'){ env = window }\n  root = env.window? env.window : global;\n  try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n  try{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n  if(root.Gun){\n    root.Gun = root.Gun;\n    root.Gun.TESTING = true;\n  } else {\n    try{ require('fs').unlinkSync('data.json') }catch(e){}\n    try{ require('../../lib/fsrm')('radatatest') }catch(e){}\n    root.Gun = require('../../gun');\n    root.Gun.TESTING = true;\n    //require('../lib/file');\n    require('../../lib/store');\n    require('../../lib/rfs');\n  }\n \n  try{ var expect = global.expect = require(\"../expect\") }catch(e){}\n \n}(this));\n \n;(function(){\nGun = root.Gun\n\nif(Gun.window && !Gun.window.RindexedDB){ return }\n \nvar opt = {};\nopt.file = 'radatatest';\nvar Radisk = (Gun.window && Gun.window.Radisk) || require('../../lib/radisk');\nopt.store = ((Gun.window && Gun.window.RindexedDB) || require('../../lib/rfs'))(opt);\nopt.chunk = 170;\nvar Radix = Radisk.Radix;\nvar rad = Radisk(opt), esc = String.fromCharCode(27);\n \ndescribe('RAD Crashes', function(){\n \n  describe('If Some of Split Fails, Keep Original Data', function(){\n    var gun = Gun({chunk: opt.chunk});\n \n    it('write initial', function(done){\n        var all = {}, to, start, tmp;\n        var names = ['al', 'alex', 'alexander', 'alice'];\n        names.forEach(function(v,i){\n            all[++i] = true;\n            tmp = v.toLowerCase();\n            gun.get('names').get(tmp).put(i, function(ack){\n                expect(ack.err).to.not.be.ok();\n                delete all[i];\n                if(!Gun.obj.empty(all)){ return }\n                done();\n            })\n        });\n    });\n\n    it('write alan', function(done){\n        var all = {}, to, start, tmp;\n        var names = ['alan'];\n        console.log(\"DID YOU ADD `Gun.CRASH` to Radisk f.swap?\");\n        Gun.CRASH = true; // add check for this in f.swap!\n        names.forEach(function(v,i){\n            all[++i] = true;\n            tmp = v.toLowerCase();\n            gun.get('names').get(tmp).put(i);\n        });\n        setTimeout(function(){\n            Gun.CRASH = false;\n            done();\n        }, 1000);\n    });\n\n    it('read names', function(done){\n        console.log(\"Better to .skip 1st run, .only 2nd run & prevent clearing radatatest.\");\n        var g = Gun();\n        var all = {al: 1, alex: 2, alexander: 3, alice: 4};\n        g.get('names').map().on(function(v,k){\n            //console.log(\"DATA:\", k, v);\n            if(all[k] === v){ delete all[k] }\n            if(!Gun.obj.empty(all)){ return }\n            done();\n        });\n    });\n \n  });\n \n});\n \n}());"
  },
  {
    "path": "test/rad/mocha.html",
    "content": "<html>\n\t<head>\n\t\t<title>Gun Tests</title>\n\t\t<link rel=\"stylesheet\" href=\"../mocha.css\"/>\n\t\t<style>\n\t\t</style>\n\t  </head>\n\t</head>\n\t<body>\n\t\tGun Tests\n\t\t<div id=\"debug\"></div>\n\t\t<div id=\"mocha\"></div>\n\t\t\n\t\t<script src=\"../json2.js\"></script>\n\t\t<script src=\"../mocha.js\"></script>\n\t\t<script>mocha.setup({ui:'bdd',globals:[]});</script>\n\t\t<script src=\"../expect.js\"></script>\n\t\t<script></script>\n\t\t<script src=\"../../gun.js\"></script>\n\t\t<script src=\"../../rad.js\"></script>\n\n\t\t<script src=\"./book.js\"></script>\n\t\t<script>\n\t\tif(location.search){\n\t\t\tGun.debug = true;\n\t\t\tconsole.log('async?', Gun.debug);\n\t\t}\n\t\tvar run = mocha.run(function(a,b,c){\n\t\t\tdocument.body.prepend(\"TODO: localStorage gun/gap ???\");return;\n\t\t\tvar yes = confirm(\"REFRESH BROWSER FOR ASYNC TESTS?\");\n\t\t\tif(yes){\n\t\t\t\tif(location.search){\n\t\t\t\t\tlocation.search = '';\n\t\t\t\t} else {\n\t\t\t\t\tlocation.search = '?async';\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t/*console.log(\"???????????\", a);\n\t\t\t//if(a !== 0){ return }\n\t\t\tdocument.getElementById('mocha-stats').id = 'mocha-stats2';\n\t\t\tdocument.getElementById('mocha-report').style.display = 'none';\n\t\t\tdocument.getElementById('mocha-report').id = 'mocha-report2';\n\t\t\tGun.debug = false;\n\t\t\tmocha.run();*/\n\t\t});\n\t\trun.on(\"fail\", function(test, err){\n\t\t\tconsole.log(\"!!!!!!!!!!!\", test, err);\n\t\t\t//alert(5);\n\t\t})\n\t\t</script>\n\t</body>\n</html>"
  },
  {
    "path": "test/rad/old2020json/!",
    "content": "{\"~\":{\"@testing123\\u001b~6LHYiwdkGMqW45nTBKAjUNO_OyxIauOltwNKF-9mJCQ.yqQrGr1yC-N0VBahwYnbnt9D9Y05OoaQbcPneDzM-3A\":{\"\":{\":\":{\"#\":\"~6LHYiwdkGMqW45nTBKAjUNO_OyxIauOltwNKF-9mJCQ.yqQrGr1yC-N0VBahwYnbnt9D9Y05OoaQbcPneDzM-3A\"},\">\":1620286970976}},\"6LHYiwdkGMqW45nTBKAjUNO_OyxIauOltwNKF-9mJCQ.yqQrGr1yC-N0VBahwYnbnt9D9Y05OoaQbcPneDzM-3A\":{\"\\u001b\":{\"pub\":{\"\":{\":\":\"6LHYiwdkGMqW45nTBKAjUNO_OyxIauOltwNKF-9mJCQ.yqQrGr1yC-N0VBahwYnbnt9D9Y05OoaQbcPneDzM-3A\",\">\":1620286970971}},\"epub\":{\"\":{\":\":\"{\\\":\\\":\\\"qIKEeDg23hc0ylkyTsPeXcsBwWwiR4spJZ4wbD2bcek.UN75LS5RWe3IStRPuDKXDt-ia2XCDLQbP9oVhYezF04\\\",\\\"~\\\":\\\"9NuEZuTzsBv8intGrpFb4rISVigiVMV9kxF9bAs3XGK/1A/E154XUJaFmergCIu6pINPao+3HAEYxfOV1HKqaA==\\\"}\",\">\":1620286970971}},\"a\":{\"lias\":{\"\":{\":\":\"{\\\":\\\":\\\"testing123\\\",\\\"~\\\":\\\"/UTDwurvc52XoZoNOoVaF6Uncc9VzRBomczHKidrnbMcJIIxbLJiezYHONGXe5RIWmVZoLWrGjqUYf/1DuRHJQ==\\\"}\",\">\":1620286970971}},\"uth\":{\"\":{\":\":\"{\\\":\\\":\\\"{\\\\\\\"ek\\\\\\\":{\\\\\\\"ct\\\\\\\":\\\\\\\"fmyGN0w0PFd/7K8+KjZW4id75XGpOn9MdbJIMbvJTHv2AdjEX3LHCMrykXdiAEZtwinJSMyE6qFE+q3AaelijOirYZoC1LicFWuoptFYqwKuiyEdchv1IoEglK4umLhFpb8LJ25oXXK2eTFJUrLWmqP4tE95IbdLyn5CLA==\\\\\\\",\\\\\\\"iv\\\\\\\":\\\\\\\"zK8ZPmlek+jlXHV1JSAG\\\\\\\",\\\\\\\"s\\\\\\\":\\\\\\\"jftXz+L2GhWh\\\\\\\"},\\\\\\\"s\\\\\\\":\\\\\\\"9P4PBBEXdj55gLTtHgkHis4ukesIEu5ULyogvnglH0pFpcPtKEWSgtb9jRCw42kt\\\\\\\"}\\\",\\\"~\\\":\\\"vQLL5kA1BXmingXaDyTD7s62ZQHzHbFz5u4OS6rWh0Y64xjYo7DiBGmXyUDkxX9UlB1PVdGAIapp6OWLwl3Gag==\\\"}\",\">\":1620286970971}}},\"said\":{\"\":{\":\":\"{\\\":\\\":{\\\"#\\\":\\\"~6LHYiwdkGMqW45nTBKAjUNO_OyxIauOltwNKF-9mJCQ.yqQrGr1yC-N0VBahwYnbnt9D9Y05OoaQbcPneDzM-3A/said\\\"},\\\"~\\\":\\\"Qm4q1ZLXnSeJ0KazwtWYuWqMMFzKWJIOuthAyVS5tpRnhV84VCjvtQBcbsivsh68oX+7fTa5038cAeiymwK8Xg==\\\"}\",\">\":1620286972880}}},\"/said\\u001bkoc\":{\"l1\":{\"2\":{\"a7X2NnZMH\":{\"\":{\":\":\"{\\\":\\\":\\\"b\\\",\\\"~\\\":\\\"/296iLEq5Rhl0xnw0PVOZnWmFb//tJa3fKmFf9zeuUk2vXo5aCA61Fn5V91oAPLSaQAOB4cMYeInTRq/wusxng==\\\"}\",\">\":1620286973647.001}},\"w0fVwD9SF\":{\"\":{\":\":\"{\\\":\\\":\\\"c\\\",\\\"~\\\":\\\"CR6+M3CnW+BdD4gISJvCDGaYHPnBUgUFTcLV6wHRjbIWrsXg1orxvMPFB/I0djggfQyIHTd7WbwneEt4BD/P2g==\\\"}\",\">\":1620286974432.001}}},\"1ov2HGy3pP\":{\"\":{\":\":\"{\\\":\\\":\\\"a\\\",\\\"~\\\":\\\"rxavUWplLfAH7yRRz7WOTeiqA5cVB5Pe0MBsaK85R3N9AmL81afktynkCmvIgu0C+Vd4dS3v/OG64lIwv7Kxow==\\\"}\",\">\":1620286972880}},\"a2msNGEG5j\":{\"\":{\":\":\"{\\\":\\\":\\\"cool\\\",\\\"~\\\":\\\"hIlAjwklp07vhR6qd0aHFHd988Sdz6RVIwfiV5gwdK7/Cy0LWdIE8N+8tK1rnZdkVA7DKzRuPClk+P5EdPbGHQ==\\\"}\",\">\":1620286983744}}},\"m2\":{\"rgfrjl4ph4\":{\"\":{\":\":\"{\\\":\\\":\\\"sweet\\\",\\\"~\\\":\\\"z4xeMjvp00yjuMiesSh3V4NenXiYbItmgLZbrtPjwmCQhsJev2BZB2TGTLd/xBTOMNEea3pPnB6M4iiflk3QvA==\\\"}\",\">\":1620288732544}},\"shv4QO5daU\":{\"\":{\":\":\"{\\\":\\\":\\\"neat\\\",\\\"~\\\":\\\"AzzHhVdxtT0ZZVRFWEWUYBP7Tm6eYFBTc7xTRiz6xyMoSeJsHSFvC65gSu5yTRG0N8ykSBQDxkCxECWb2XIJ4w==\\\"}\",\">\":1620288733891.001}},\"td2ZtiM4kP\":{\"\":{\":\":\"{\\\":\\\":\\\"cool\\\",\\\"~\\\":\\\"Sh8Hr491IAcTPI4sv0/bZG7hBCfyHGG2+mEqFzXoAbOmaUZqmcYSqeXuuMRpnQtIJFwwbTc8eC97gOAwABvwyQ==\\\"}\",\">\":1620288735014.001}}}}}},\"#\\u001buU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=\":{\"\":{\":\":\"hello world\",\">\":1620599842832}},\"test\\u001bpaste\":{\"\":{\":\":\"hello world!!!\",\">\":1629535024341}}}"
  },
  {
    "path": "test/rad/old2020json/%1C",
    "content": "{\"!\":{\"\":1}}"
  },
  {
    "path": "test/rad/parse.rad",
    "content": "\u001f+1\u001f#\u001f\"age\u001f:\u001f\"\u001b+29\u001b>\u001b+1549776205172\u001b\u001f\n\u001f+1\u001f#\u001f\"name\u001f:\u001f\"\u001b\"Bob!\u001b>\u001b+1549776205172\u001b\u001f\n\u001f+1\u001f#\u001f\"pet\u001f:\u001f\"\u001b#XAqxAKkRa6lTsfAElEjDweqt\u001b>\u001b+1549776205172\u001b\u001f\n\u001f+0\u001f#\u001f\"u/m\u001f\n\u001f+1\u001f#\u001f\"\u001b\u001f\n\u001f+2\u001f#\u001f\"alice\u001f:\u001f\"\u001b#dlgw87rue6oVQhsvc3XFLrOu\u001b>\u001b+1549776205172\u001b\u001f\n\u001f+2\u001f#\u001f\"bob\u001f:\u001f\"\u001b#nuTAd2Tn4S5SiDVA7nxNBbZt\u001b>\u001b+1549776205172\u001b\u001f\n\u001f+1\u001f#\u001f\"/p\u001b\u001f\n\u001f+2\u001f#\u001f\"alice\u001f:\u001f\"\u001b#USw3Dp7hTD7VMBLnd8dVBR4s\u001b>\u001b+1549776205200\u001b\u001f\n\u001f+2\u001f#\u001f\"bob\u001f:\u001f\"\u001b#1VwZRUw7vQ1hX8gspN1ZrHVj\u001b>\u001b+1549776205200\u001b\u001f\n"
  },
  {
    "path": "test/rad/rad.book.spec.js",
    "content": "/**\n * radisk3/book sanity tests\n * - long paths\n * - long data\n * - special characters\n * - escape sequences\n * - __proto__ pollution\n */\nconst expect = require('../expect');\nconst path = require('path');\nconst fs = require('fs');\n\nconst ENABLE_GUN_LOGGING = false;\n\nconst PATH_TO_TEST_FOLDER = path.resolve(__dirname, 'booktestdata');\nconst PATH_TO_OLD_DB = path.resolve(PATH_TO_TEST_FOLDER, 'oldradata');\nconst PATH_TO_TEST_DB = path.resolve(PATH_TO_TEST_FOLDER, 'radatatest');\nconst PATH_TO_TEST_DB2 = path.resolve(PATH_TO_TEST_FOLDER, 'radatatest2');\n\nif (!fs.existsSync(PATH_TO_TEST_FOLDER)) {\n  fs.mkdirSync(PATH_TO_TEST_FOLDER);\n}\nfs.rmdirSync(PATH_TO_TEST_DB, { recursive: true });\n\nconst BOOK_SPECIAL_CHARS = ['\\'|', '|\\'', '|', '\\'', '\\n'];\nconst BOOK_PAGE_SIZE = 3000;\n\nconst RAD_PATH_SEPARATORS = ['/', '.'];\nconst GUN_PRIMITIVES = [\n  null,\n  'string',\n  728858,\n  BigInt(1000000000000000000000000000000000000000000000000000000000n),\n  true,\n  false,\n  -Infinity,\n  Infinity,\n  NaN,\n  -0\n]\n\n\nvar root;\nvar Gun;\nvar Radix;\nvar Radisk;\nvar RFS;\n\n(function () {\n  var env;\n  if (typeof global !== 'undefined') { env = global }\n  if (typeof window !== 'undefined') { env = window }\n  root = env.window ? env.window : global;\n  try { env.window && root.localStorage && root.localStorage.clear() } catch (e) { }\n  //try{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n  if (root.Gun) {\n    root.Gun = root.Gun;\n    // root.Gun.TESTING = true;\n  } else {\n    try { require('fs').unlinkSync('data.json') } catch (e) { }\n    try { require('../../lib/fsrm')(PATH_TO_TEST_DB) } catch (e) { }\n    root.Gun = require('../../gun');\n    root.Gun.TESTING = true;\n  }\n\n  try { var expect = global.expect = require(\"../expect\") } catch (e) { }\n\n  if (!root.Gun.SEA) {\n    require('../../sea.js');\n  }\n}(this));\n\nGun = root.Gun;\nrequire(\"../../lib/book\");\nRadix = Gun?.window?.Radix || require(\"../../lib/radix\");\nRadisk = Gun?.window?.Radisk || require(\"../../lib/radisk3\");\nRFS = require('../../lib/rfs');\nrequire('../../lib/store');\nrequire('../../lib/rindexed');\n\nconst RE_UNPRINTABLE = /[^\\x20-\\x7E]/;\nconst RE_APOSTROPHES = /'/g;\n\nconst SKIP_CHARS = false;\nconst CHAR_MAX = 330;\nconst UNPRINTABLE_MAX = 128; //65536;\n\nconst DATA_LENGTHS = [\n  // 100,\n  // 1000, // 1kb\n  // 3000, // 3kb\n  // 10000,\n  100000,\n  1000000, // 1 mb\n  10000000, // 10mb\n  50000000, // 50mb\n  500000000, // 500mb\n];\nconst LONG_DATAS = DATA_LENGTHS.map(l => ''.padEnd(l, '012345'));\n\nconst ALL_CHARS = [];\nfor (let i = 0; i < CHAR_MAX; i++) {\n  ALL_CHARS.push(String.fromCharCode(i));\n}\nALL_CHARS.push('\\u001b');\nconst PRINTABLE_CHARS = ALL_CHARS.filter(c => !RE_UNPRINTABLE.test(c));\nconst UNPRINTABLE_CHARS = ALL_CHARS.filter(c => RE_UNPRINTABLE.test(c)).slice(0, UNPRINTABLE_MAX);\nconst ESCAPE_CHARS = [`\\0`, `\\u001b`, `\\\\`, `\\\\\\\\`, `\\\\\\\\\\\\`, `\\\\\\\\\\\\\\\\`];\nconst NORMAL_CHARS = ['A', 'B', 'C'];\n\nconst ESCAPE_FACTORIES = {\n  ESCAPE_AS_NODE: (before, ec, c, after) => {\n    ec = ec.length ? [ec] : [];\n    return [...before, ...ec, c, ...after];\n  },\n  ESCAPE_IN_PATH: (before, ec, c, after) => [...before, `${ec}${c}`, ...after],\n  ESCAPE_AT_END: (before, ec, c, after) => {\n    ec = ec.length ? [ec] : [];\n    return [...before, `${c}`, ...after, ...ec];\n  }\n};\n\n\nfunction buildSoul(separator, ...args) {\n  return args.join(separator);\n}\n\nconst SOUL_GAUNTLET = RAD_PATH_SEPARATORS\n  .reduce((pc, ps) => [...pc,\n  ...[...BOOK_SPECIAL_CHARS, ...ESCAPE_CHARS].reduce((pb, cb) =>\n    [...pb,\n    NORMAL_CHARS.map((nc) => `${nc}${cb}`),\n    NORMAL_CHARS.map((nc) => `${cb}${nc}`),\n    NORMAL_CHARS.map((nc) => `${cb}${cb}${nc}`),\n    ], [])], []);\n// console.log(SOUL_GAUNTLET);\n// const SOUL_GAUNTLET = [RAD_PATH_SEPARATORS, [PRINTABLE_CHARS], ESCAPE_FACTORIES, [BOOK_SPECIAL_CHARS, ESCAPE_CHARS]];\n// [\\x000/9.2%20b, ...]\n\n\nconst opt = {\n  file: PATH_TO_TEST_DB,\n  localStorage: false,\n  log: (msg, ...args) => {\n    if (ENABLE_GUN_LOGGING) {\n\n      console.log(`  ${msg}`, ...args);\n    }\n  },\n  chunk: 250\n};\nopt.store = RFS(opt);\n\nlet seq = 0;\n\ndescribe('radisk3 & book', () => {\n  let r;\n\n  beforeEach(() => {\n    // unpersist(opt);\n    // expect(testDirExists()).to.be.false();\n    r = buildRad(opt);\n  });\n\n  it('can read older file versions', done => {\n    done('not implemented');\n  });\n  it('creates a ! file', (done) => {\n    expect(testDirExists()).to.be.ok();\n    done('not implemented');\n  });\n  it('loads a ! file if one exists', done => {\n    // done();\n    const r2 = buildRad(opt);\n    // hmm\n    done('not implemented');\n  });\n\n  describe('path', () => {\n    it('supports arbitrarily long souls', done => {\n      done('not implemented');\n    });\n    it('uses path delimiters interchangeably', done => {\n      done('not implemented');\n    });\n    it('supports souls containing special characters', done => {\n      done('not implemented');\n    });\n  });\n\n  describe('data', () => {\n    it('can write & read data spanning multiple pages', done => {\n      done('not implemented');\n    });\n    it('can write & read all primitives', done => {\n      done('not implemented');\n    });\n    it('can write & read objects', done => {\n      done('not implemented');\n    })\n  })\n});\n\nconst soulpermutations = [];\ndescribe('RAD book', () => {\n  let r;\n\n  describe('node content length & paging', () => {\n    beforeEach(() => {\n      r = buildRad(opt);\n    })\n    LONG_DATAS.forEach((d) => {\n      it(`handles data length of ${d.length} bytes`, (done) => {\n        seq++;\n        const dk = `root.seq${seq}`;\n        console.log(`\\n#[${dk}]\\n`);\n        r(dk, d, (err, ok) => {\n          if (err) {\n            console.log('ERR! waiting for ${dk} to write', err);\n            done(false);\n          }\n        });\n        console.time('test');\n        r(dk, (err, res, o) => {\n          const value = getValueFromPage(dk, res);\n          if (!res) {\n            console.log('no result', { err, res, o });\n            done('nothing returned');\n            return;\n          }\n          if (d !== value) {\n            done('result did not match');\n            // TODO is this a failure, or because I'm not reading the result properly?\n            // TODO when a split() happens, should that affect the resulting page?\n            return;\n          }\n          done();\n        });\n        console.timeEnd('test');\n      });\n    });\n  });\n\n  const pathSegments = ['a', 'b'];\n  if (!SKIP_CHARS) {\n    RAD_PATH_SEPARATORS.forEach((d, di) => {\n      describe(`\\`${d}\\`-delimited paths`, () => {\n        beforeEach(() => {\n          r = buildRad(opt);\n        });\n\n        it('should separate two keys', (done) => {\n          seq++;\n          let soul = `a${seq}${d}a`;\n          let data = `data for '${soul}' ${seq}`;\n          r(soul, data);\n          r(soul, (err, res, o) => {\n            const rd = getValueFromPage(soul, res);\n            expect(rd).to.be.ok();\n            expect(rd).to.eql(data);\n            done();\n          });\n        });\n      });\n\n      describe('other delimited paths', () => {\n        const charCats = { PRINTABLE_CHARS };\n\n        Object.entries(charCats).forEach((ckv) => {\n          const PATH_CHARS = ckv[1];\n          Object.keys(ESCAPE_FACTORIES).forEach(escapeVariantKey => {\n            ESCAPE_CHARS.forEach(ec => {\n              describe(`${ckv[0]} '${escape(ec)}' ${escapeVariantKey}`, () => {\n                let rootKey;\n\n                beforeEach(() => {\n                  r = buildRad(opt);\n                });\n\n                PATH_CHARS.forEach((c, i) => {\n                  for (let si = 0; si <= pathSegments.length; si++) {\n                    const before = pathSegments.slice(0, si);\n                    const after = pathSegments.slice(si);\n                    const variant = [...ESCAPE_FACTORIES[escapeVariantKey](before, ec, c, after)];\n                    variant[0] = `${variant[0]}${seq}`;\n                    const rootKey = `${path[0]}${seq}`;\n                    const soul = variant.join(d);\n                    soulpermutations.push(soul);\n                    let data = `data for ${soul} ${seq}`;\n\n                    const numericSoul = soul.split('').map(x => `${x.charCodeAt(0)}`.padStart(6, ' ')).join('');\n\n                    it(`${seq} ${numericSoul} # (${soul}) => ${data}`, (done) => {\n                      seq++;\n                      r(soul, data);\n\n                      r(soul, (err, res, book) => {\n                        if (err) {\n                          done(err);\n                          return;\n                        }\n\n                        const value = book(soul); // getValueFromPage(soul, res); // TODO mark fix this\n\n                        if (value !== data) {\n                          debugger;\n                        }\n                        expect(value).to.eql(data);\n                        done();\n                      });\n                    });\n                  }\n                });\n              });\n            });\n          });\n        });\n      });\n    });\n  }\n  console.log(soulpermutations);\n});\n\nfunction getValueFromPage(soul, res) {\n  // return res;\n  // console.log(`getting ${soul} from`, res);\n  const bookList = res?.list || res?.book.list;\n  if (!bookList) {\n    return null;\n  }\n  const book = findInList(bookList, soul);\n  if (!book || !book.is) {\n    return null;\n  }\n  return book.is;\n}\n\nfunction findInList(list, word) {\n  return (list || []).find(b => b.word === word);\n}\n\n\nfunction testDirExists() {\n  return fs.readdirSync(PATH_TO_TEST_FOLDER).includes('radatatest');\n}\n\nfunction unpersist(opt) {\n  opt = opt || { file: PATH_TO_TEST_DB };\n  opt.file = opt.file || PATH_TO_TEST_DB;\n  fs.rmdirSync(opt.file, { recursive: true });\n}\n\nfunction buildRad(opt) {\n  return Radisk(opt);\n}"
  },
  {
    "path": "test/rad/rad.js",
    "content": "var root;\nvar Gun;\n(function(){\n  var env;\n  if(typeof global !== 'undefined'){ env = global }\n  if(typeof window !== 'undefined'){ env = window }\n  root = env.window? env.window : global;\n  try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n  //try{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n  if(root.Gun){\n    root.Gun = root.Gun;\n    root.Gun.TESTING = true;\n  } else {\n    try{ require('fs').unlinkSync('data.json') }catch(e){}\n    try{ require('../../lib/fsrm')('radatatest') }catch(e){}\n    root.Gun = require('../../gun');\n    root.Gun.TESTING = true;\n    require('../../lib/store');\n    require('../../lib/rfs');\n  }\n\n  try{ var expect = global.expect = require(\"../expect\") }catch(e){}\n\n}(this));\n\n;(function(){\nGun = root.Gun\n\nvar Radix = (Gun.window && Gun.window.Radix) || require('../../lib/radix');\n\ndescribe('RAD', function(){\n\nvar names = [\"Adalard\",\"Adora\",\"Aia\",\"Albertina\",\"Alfie\",\"Allyn\",\"Amabil\",\"Ammamaria\",\"Andy\",\"Anselme\",\"Ardeen\",\"Armand\",\"Ashelman\",\"Aube\",\"Averyl\",\"Baker\",\"Barger\",\"Baten\",\"Bee\",\"Benia\",\"Bernat\",\"Bevers\",\"Bittner\",\"Bobbe\",\"Bonny\",\"Boyce\",\"Breech\",\"Brittaney\",\"Bryn\",\"Burkitt\",\"Cadmann\",\"Campagna\",\"Carlee\",\"Carver\",\"Cavallaro\",\"Chainey\",\"Chaunce\",\"Ching\",\"Cianca\",\"Claudina\",\"Clyve\",\"Colon\",\"Cooke\",\"Corrina\",\"Crawley\",\"Cullie\",\"Dacy\",\"Daniela\",\"Daryn\",\"Deedee\",\"Denie\",\"Devland\",\"Dimitri\",\"Dolphin\",\"Dorinda\",\"Dream\",\"Dunham\",\"Eachelle\",\"Edina\",\"Eisenstark\",\"Elish\",\"Elvis\",\"Eng\",\"Erland\",\"Ethan\",\"Evelyn\",\"Fairman\",\"Faus\",\"Fenner\",\"Fillander\",\"Flip\",\"Foskett\",\"Fredette\",\"Fullerton\",\"Gamali\",\"Gaspar\",\"Gemina\",\"Germana\",\"Gilberto\",\"Giuditta\",\"Goer\",\"Gotcher\",\"Greenstein\",\"Grosvenor\",\"Guthrey\",\"Haldane\",\"Hankins\",\"Harriette\",\"Hayman\",\"Heise\",\"Hepsiba\",\"Hewie\",\"Hiroshi\",\"Holtorf\",\"Howlond\",\"Hurless\",\"Ieso\",\"Ingold\",\"Isidora\",\"Jacoba\",\"Janelle\",\"Jaye\",\"Jennee\",\"Jillana\",\"Johnson\",\"Josy\",\"Justinian\",\"Kannan\",\"Kast\",\"Keeley\",\"Kennett\",\"Kho\",\"Kiran\",\"Knowles\",\"Koser\",\"Kroll\",\"LaMori\",\"Lanctot\",\"Lasky\",\"Laverna\",\"Leff\",\"Leonanie\",\"Lewert\",\"Lilybel\",\"Lissak\",\"Longerich\",\"Lou\",\"Ludeman\",\"Lyman\",\"Madai\",\"Maia\",\"Malvina\",\"Marcy\",\"Maris\",\"Martens\",\"Mathilda\",\"Maye\",\"McLain\",\"Melamie\",\"Meras\",\"Micco\",\"Millburn\",\"Mittel\",\"Montfort\",\"Moth\",\"Mutz\",\"Nananne\",\"Nazler\",\"Nesta\",\"Nicolina\",\"Noellyn\",\"Nuli\",\"Ody\",\"Olympie\",\"Orlena\",\"Other\",\"Pain\",\"Parry\",\"Paynter\",\"Pentheas\",\"Pettifer\",\"Phyllida\",\"Plath\",\"Posehn\",\"Proulx\",\"Quinlan\",\"Raimes\",\"Ras\",\"Redmer\",\"Renelle\",\"Ricard\",\"Rior\",\"Rocky\",\"Ron\",\"Rosetta\",\"Rubia\",\"Ruttger\",\"Salbu\",\"Sandy\",\"Saw\",\"Scholz\",\"Secor\",\"September\",\"Shanleigh\",\"Shenan\",\"Sholes\",\"Sig\",\"Sisely\",\"Soble\",\"Spanos\",\"Stanwinn\",\"Stevie\",\"Stu\",\"Suzanne\",\"Tacy\",\"Tanney\",\"Tekla\",\"Thackeray\",\"Thomasin\",\"Tilla\",\"Tomas\",\"Tracay\",\"Tristis\",\"Ty\",\"Urana\",\"Valdis\",\"Vasta\",\"Vezza\",\"Vitoria\",\"Wait\",\"Warring\",\"Weissmann\",\"Whetstone\",\"Williamson\",\"Wittenburg\",\"Wymore\",\"Yoho\",\"Zamir\",\"Zimmermann\"];\n\n//console.log(\"HYPER TEST\");var z = 10000; while(--z){ names.push(Gun.text.random(7)) }this.timeout(9000);\n\n  describe('Radix', function(){\n    var radix = Radix();\n\n    it('unit', function(){\n        var rad = Radix();\n        rad('asdf.pub', 'yum');\n        rad('ablah', 'cool');\n        rad('ab', {yes: 1});\n        rad('node/circle.bob', 'awesome');\n\n        expect(JSON.parse(JSON.stringify(rad('asdf.')))).to.be.eql({pub: {'': 'yum'}});\n        expect(rad('nv/foo.bar')).to.be(undefined);\n        expect(rad('ab')).to.eql({yes: 1});\n        expect(JSON.parse(JSON.stringify(rad()))).to.be.eql({\"a\":{\"sdf.pub\":{\"\":\"yum\"},\"b\":{\"lah\":{\"\":\"cool\"},\"\":{\"yes\":1}}},\"node/circle.bob\":{\"\":\"awesome\"}});\n    });\n\n    it('radix write read', function(done){\n        var all = {};\n        names.forEach(function(v,i){\n            v = v.toLowerCase();\n            all[v] = v;\n            radix(v, i)\n        });\n        expect(Object.empty(all)).to.not.be.ok();\n        Radix.map(radix, function(v,k){\n            delete all[k];\n        });\n        expect(Object.empty(all)).to.be.ok();\n        done();\n    });\n\n    it('radix write read again', function(done){\n        var all = {};\n        names.forEach(function(v,i){\n            v = v.toLowerCase();\n            all[v] = v;\n            //rad(v, i)\n        });\n        expect(Object.empty(all)).to.not.be.ok();\n        Radix.map(radix, function(v,k){\n            delete all[k];\n        });\n        expect(Object.empty(all)).to.be.ok();\n        done();\n    });\n\n    it('radix read start end', function(done){\n        var all = {}, start = 'Warring'.toLowerCase(), end = 'Zamir'.toLowerCase();\n        names.forEach(function(v,i){\n            v = v.toLowerCase();\n            if(v < start){ return }\n            if(end < v){ return }\n            all[v] = v;\n            //rad(v, i)\n        });\n        expect(Object.empty(all)).to.not.be.ok();\n        Radix.map(radix, function(v,k, a,b){\n            //if(!all[k]){ throw \"out of range!\" }\n            delete all[k];\n        }, {start: start, end: end});\n        expect(Object.empty(all)).to.be.ok();\n        done();\n    });\n\n    it('radix read start- end+', function(done){\n        var all = {}, start = 'Warrinf'.toLowerCase(), end = 'Zamis'.toLowerCase();\n        names.forEach(function(v,i){\n            v = v.toLowerCase();\n            if(v < start){ return }\n            if(end < v){ return }\n            all[v] = v;\n            //rad(v, i)\n        });\n        expect(Object.empty(all)).to.not.be.ok();\n        Radix.map(radix, function(v,k, a,b){\n            //if(!all[k]){ throw \"out of range!\" }\n            delete all[k];\n        }, {start: start, end: end});\n        expect(Object.empty(all)).to.be.ok();\n        done();\n    });\n \n    it('radix reverse item', function(done){\n        var opt = {reverse: 1, end: 'iesogon'};\n        Radix.map(radix, function(v,k, a,b){\n            expect(k).to.be('ieso');\n            expect(v).to.be(96);\n            return true;\n        }, opt);\n        done();\n    });\n\n    it('radix reverse', function(done){\n        var r = Radix(), tmp;\n        r('alice', 1);r('bob', 2);r('carl', 3);r('carlo',4);\n        r('dave', 5);r('zach',6);r('zachary',7);\n        var by = ['alice','bob','carl','carlo','dave','zach','zachary'];\n        /*Object.keys(by).forEach(function(i){ var k = by[i]; console.log(k, i);\n            r(k,i);\n        });*/\n        Radix.map(r, function(v,k, a,b){\n            expect(by.pop()).to.be(k);\n            tmp = v;\n        }, {reverse: 1});\n        expect(tmp).to.be(1);\n        expect(by.length).to.be(0);\n        Radix.map(r, function(v,k, a,b){\n            tmp = v;\n        });\n        expect(tmp).to.be(7);\n        done();\n    });\n  });\n\n  if(Gun.window && !Gun.window.RindexedDB){ return }\n\n  var opt = {};\n  opt.file = 'radatatest';\n  var Radisk = (Gun.window && Gun.window.Radisk) || require('../../lib/radisk');\n  opt.store = ((Gun.window && Gun.window.RindexedDB) || require('../../lib/rfs'))(opt);\n  opt.chunk = 1000;\n  var rad = Radisk(opt), esc = String.fromCharCode(27);\n\n  describe('Radisk', function(){\n    this.timeout(1000 * 9);\n\n    /*it('parse', function(done){\n        this.timeout(60000);\n        if(Gun.window){ return done() }\n        var raw = require('fs').readFileSync(__dirname + '/parse.rad').toString();\n        rad.parse('!', function(err, disk){\n            console.log(\"!!!!\", err);\n        }, raw);\n        return;\n    });*/\n\n    it('deleting old RAD tests (may take long time)', function(done){\n        done(); // Mocha doesn't print test until after its done, so show this first.\n    });\n    it('deleted', function(done){\n        this.timeout(60 * 1000);\n        if(!Gun.window){ return done() }\n        //await new Promise(function(res){ indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ res() } } );\n        indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ done() }\n    });\n\n    it('write contacts', function(done){\n        var all = {}, to, start;\n        names.forEach(function(v,i){\n            v = v.toLowerCase();\n            all[v] = true;\n            rad(v, i, function(err, ok){\n                expect(err).to.not.be.ok();\n                delete all[v];\n                if(!Object.empty(all)){ return }\n                done();\n            })\n        })\n    });\n\n    it('read contacts reverse', function(done){\n        var opt = {};\n        opt.reverse = true;\n        opt.end = 'nothing';\n        opt.start = 'keeley';\n        var first, last;\n        var all = {}, start = opt.start.toLowerCase(), end = opt.end.toLowerCase();\n        names.forEach(function(v,i){\n            v = v.toLowerCase();\n            if(v < start){ return }\n            if(end < v){ return }\n            //console.log(v, i);\n            all[v] = v;\n            //rad(v, i)\n        });\n        rad('', function(err, data){\n            Radix.map(data, function(v,k){\n                //console.log(k, v);\n                delete all[k];\n            });\n            if(!Object.empty(all)){ return }\n            done();\n        }, opt);\n    });\n\n    it('read contacts range', function(done){\n        var opt = {};\n        opt.end = 'nothing';\n        opt.start = 'keeley';\n        var first, last;\n        var all = {}, start = opt.start.toLowerCase(), end = opt.end.toLowerCase();\n        names.forEach(function(v,i){\n            v = v.toLowerCase();\n            if(v < start){ return }\n            if(end < v){ return }\n            //console.log(v, i);\n            all[v] = v;\n            //rad(v, i)\n        });\n        rad('', function(err, data){\n            Radix.map(data, function(v,k){\n                //console.log(k, v);\n                delete all[k];\n            });\n            if(!Object.empty(all)){ return }\n            done();\n        }, opt);\n    });\n\n    it('read contacts start end', function(done){\n        var opt = {};\n        opt.start = 'Warring'.toLowerCase();\n        opt.end = 'Zamir'.toLowerCase();\n        var all = {}, find = '';\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v < opt.start){ return }\n            if(opt.end < v){ return }\n            if(v.indexOf(find) == 0){ all[v] = true }\n        });\n        rad(find, function(err, data, o){\n            Radix.map(data, function(v,k){\n                //console.log(find+k, v);\n                delete all[find+k];\n            });\n            if(!Object.empty(all)){ return }\n            if(!data){ return } // in case there is \"more\" that returned empty\n            done();\n        }, opt);\n    });\n\n    it('read contacts', function(done){\n        var all = {}, find = 'a';\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v.indexOf(find) == 0){ all[v] = true }\n        });\n        rad(find, function(err, data){\n            //console.log(\">>>>>>>>> KUNG FOO PANDA <<<<<<<<<<<\");\n            //console.debug.i=1;console.log(data);\n            Radix.map(data, function(v,k){\n                delete all[find+k];\n            });\n            if(!Object.empty(all)){ return }\n            done();\n        });\n    });\n\n    it('read again', function(done){\n        var all = {}, find = 'm';\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v.indexOf(find) == 0){ all[v] = true }\n        });\n        rad(find, function(err, data, info){\n            Radix.map(data, function(v,k){\n                delete all[find+k];\n            });\n            if(!Object.empty(all)){ return }\n            done();\n        });\n    });\n\n    it('read bytes', function(done){\n        var all = {}, find = 'm', to;\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v.indexOf(find) == 0){ all[v] = true }\n        });\n        rad(find, function(err, data, info){\n            expect(data).to.be.ok();\n            Radix.map(data, function(v,k){\n                delete all[find+k];\n            });\n            clearTimeout(to);\n            to = setTimeout(function(){\n                expect(Object.empty(all)).to.not.be.ok();\n                done();\n            },100);\n        }, {limit: 1});\n    });\n\n  });\n\n    var ntmp = names;\n  describe('RAD + GUN', function(){\n    this.timeout(1000 * 9);\n    var ochunk = 1000;\n    Gun.on('opt', function(root){\n        root.opt.localStorage = false;\n        Gun.window && console.log(\"RAD disabling localStorage during tests.\");\n        this.to.next(root);\n    })\n    var gun = Gun({chunk: ochunk});\n\n    /*it('deleting old tests (may take long time)', function(done){\n        done(); // Mocha doesn't print test until after its done, so show this first.\n    }); it('deleted', function(done){\n        this.timeout(60 * 1000);\n        if(!Gun.window){ return done() }\n        indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ done() }\n    });*/\n\n    /*it('write same', function(done){\n        var all = {}, to, start, tmp;\n        var names = [], c = 285;\n        while(--c){ names.push('bob') }\n        names.forEach(function(v,i){\n            all[++i] = true;\n            tmp = v.toLowerCase();\n            //console.only.i=1;console.log(\"save\", tmp, v, i);\n            gun.get('names').get(tmp).put({name: v, age: i}, function(ack){\n                //console.log(\"???\", ack);\n                expect(ack.err).to.not.be.ok();\n                delete all[i];\n                if(!Object.empty(all)){ return }\n                done();\n            })\n        });\n    });*/\n\n    it('write contacts', function(done){\n        var all = {}, to, start, tmp;\n        names.forEach(function(v,i){\n            all[++i] = true;\n            tmp = v.toLowerCase();\n            gun.get('names').get(tmp).put({name: v, age: i}, function(ack){\n                expect(ack.err).to.not.be.ok();\n                delete all[i];\n                if(!Object.empty(all)){ return }\n                done();\n            })\n        })\n    });\n\n    it('read one', function(done){\n        var g = Gun({chunk: ochunk});\n        //gun.get('names').get({'.': {'*': find}, '%': 1000 * 100}).once().map().once(function(data, key){\n        g.get('names').get('stu').once(function(data, key){ // on this chunk setting, Stu should be split between 2 files.\n            if(done.c){ return } done.c = 1;\n            expect(data.name).to.be.ok();\n            expect(data.age).to.be.ok();\n            done();\n        });\n    });\n\n    it('small range', function(done){\n        var check = {};\n        gun.get('users').get('alice').put({cool: 'beans'});\n        gun.get('users').get('alexander').put({nice: 'beans'});\n        gun.get('users').get('bob').put({lol: 'beans'});\n        //console.log(\"=================\");console.only.i=1;\n        gun.get('users').get({'.': {'*': 'a'}, '%': 1000 * 100}).map().on(function(d,k){\n            //console.log(\"small range:\", k, d);\n            expect('a' === k[0]).to.be.ok();\n            check[k] = d;\n            if(check.alice && check.alexander){\n                if(done.c){ return } done.c = 1;\n                done();\n            }\n        });\n    });\n\n    /*it.only('small range once TEST', function(done){\n        var gun = Gun({file: 'yuio'});\n        var check = {};\n        gun.get('people').get('alice').put({cool: 'beans'});\n        gun.get('people').get('alexander').put({nice: 'beans'});\n        gun.get('people').get('bob').put({lol: 'beans'});\n        //setTimeout(function(){\n        console.only.i=1;\n        console.log(\"==================\");\n        console.log(\"==================\");\n        console.log(\"==================\");\n        gun.get('people').get({'.': {'*': 'a'}, '%': 1000 * 100}).once().map().once(function(d,k){\n            console.log(\"***********\", k,d);\n            expect('a' === k[0]).to.be.ok();\n            check[k] = d;\n            if(check.alice && check.alexander){\n                if(done.c){ return } done.c = 1;\n                done();\n            }\n        });\n        //},500);\n    });*/\n\n    it('small range once', function(done){\n        var check = {};\n        gun.get('people').get('alice').put({cool: 'beans'});\n        gun.get('people').get('alexander').put({nice: 'beans'});\n        gun.get('people').get('bob').put({lol: 'beans'});\n        gun.get('people').get({'.': {'*': 'a'}, '%': 1000 * 100}).once().map().once(function(d,k){\n            expect('a' === k[0]).to.be.ok();\n            check[k] = d;\n            if(check.alice && check.alexander){\n                if(done.c){ return } done.c = 1;\n                done();\n            }\n        });\n    });\n    \n    it('small range twice', function(done){\n        var check = {};\n        var gun = Gun();\n        gun.get('peoplez').get('alice').put({cool: 'beans'});\n        gun.get('peoplez').get('alexander').put({nice: 'beans'});\n        gun.get('peoplez').get('bob').put({lol: 'beans'});\n        gun.get('peoplez').get({'.': {'*': 'a'}, '%': 1000 * 100}).once().map().once(function(d,k){\n            expect('a' === k[0]).to.be.ok();\n            check[k] = (check[k] || 0) + 1;\n            expect(check[k]).to.be(1);\n            if(check.alice && check.alexander){\n                if(next.c){ return } next.c = 1;\n                next();\n            }\n        });\n        function next(){\n        var neck = {};\n        gun.get('peoplez').get({'.': {'*': 'a'}, '%': 1000 * 100}).once().map().once(function(d,k){\n            expect('a' === k[0]).to.be.ok();\n            neck[k] = d;\n            if(neck.alice && neck.alexander){\n                if(done.c){ return } done.c = 1;\n                done();\n            }\n        });\n        }\n    });\n\n    it('read contacts', function(done){\n        var all = {}, find = 'm', to;\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v.indexOf(find) == 0){ all[v] = true }\n        });\n        gun.get('names').get({'.': {'*': find}, '%': 1000 * 100}).once().map().once(function(data, key){\n            expect(data.name).to.be.ok();\n            expect(data.age).to.be.ok();\n            expect('m' == key[0]).to.be.ok();\n            delete all[key];\n            clearTimeout(to);\n            to = setTimeout(function(){\n                expect(Object.empty(all)).to.be.ok();\n                done();\n            },100);\n        });\n    });\n\n    it('read contacts again', function(done){\n        var all = {}, find = 'a', to;\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v.indexOf(find) == 0){ all[v] = true }\n        });\n        gun.get('names').get({'.': {'*': find}, '%': 1000 * 100}).once().map().once(function(data, key){\n            //console.log(\"*******\", key, data, this._.back.get);\n            expect(data.name).to.be.ok();\n            expect(data.age).to.be.ok();\n            delete all[key];\n            clearTimeout(to);\n            to = setTimeout(function(){\n                expect(Object.empty(all)).to.be.ok();\n                done();\n            },300);\n        });\n    });\n\n    it('read contacts fresh', function(done){\n        var gun = Gun({chunk: ochunk});\n        var all = {}, find = 'b', to;\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v.indexOf(find) == 0){ all[v] = true }\n        });\n        gun.get('names').map().once(function(data, key){\n            expect(data.name).to.be.ok();\n            expect(data.age).to.be.ok();\n            delete all[key];\n            if(!Object.empty(all)){ return }\n            clearTimeout(to);\n            to = setTimeout(function(){\n                expect(Object.empty(all)).to.be.ok();\n                done();\n                setTimeout(function(){\n        gun.get('names').get({'.': {'*': find}, '%': 1000 * 100}).once().map().once(function(data, key){\n            expect(data.name).to.be.ok();\n            expect(data.age).to.be.ok();\n        });\n                },500);\n            },100);\n        });\n    });\n\n    it('read contacts smaller than cursor', function(done){ // TODO!!!\n        var all = {}, cursor = 'm', to;\n        names.forEach(function(v){\n            v = v.toLowerCase();\n            if(v < cursor){ all[v] = true }\n        });\n        gun.get('names').get({'.': {'<': cursor}, '%': 1000 * 100}).once().map().once(function(data, key){\n            expect(data.name).to.be.ok();\n            expect(data.age).to.be.ok();\n            //if(!all.hasOwnProperty(key)){console.error(key);}\n            expect(all.hasOwnProperty(key)).to.be.ok();\n            delete all[key];\n            clearTimeout(to);\n            to = setTimeout(function(){\n                expect(Object.empty(all)).to.be.ok();\n                done();\n            },100);\n        });\n    });\n\n    it.skip('read contacts in descending order', function(done){ // TODO!!!\n        var all = {}, to;\n        names.forEach(function(v){\n            all[v] = true;\n        });\n        gun.get('names').get({'.': {'-': 1}, '%': 1000 * 100, '-': 1}).once().map().once(function(data, key){\n            expect(data.name).to.be.ok();\n            expect(data.age).to.be.ok();\n            delete all[key];\n            clearTimeout(to);\n            to = setTimeout(function(){\n                expect(Object.empty(all)).to.be.ok();\n                done();\n            },100);\n        });\n    });\n\n  });\n\n});\n\n}());\n"
  },
  {
    "path": "test/rad/recover.js",
    "content": "var root;\nvar Gun;\n(function(){\n  var env;\n  if(typeof global !== 'undefined'){ env = global }\n  if(typeof window !== 'undefined'){ env = window }\n  root = env.window? env.window : global;\n  try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n  try{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n  if(root.Gun){\n    root.Gun = root.Gun;\n    root.Gun.TESTING = true;\n  } else {\n    try{ require('fs').unlinkSync('data.json') }catch(e){}\n    try{ require('../../lib/fsrm')('radatatest') }catch(e){}\n    root.Gun = require('../../gun');\n    root.Gun.TESTING = true;\n    //require('../lib/file');\n    require('../../lib/store');\n    require('../../lib/rfs');\n  }\n \n  try{ var expect = global.expect = require(\"../expect\") }catch(e){}\n \n}(this));\n \n;(function(){\nGun = root.Gun\n\nif(Gun.window && !Gun.window.RindexedDB){ return }\n \nvar opt = {};\nopt.file = 'radatatest';\nvar Radisk = (Gun.window && Gun.window.Radisk) || require('../../lib/radisk');\nopt.store = ((Gun.window && Gun.window.RindexedDB) || require('../../lib/rfs'))(opt);\nopt.chunk = 170;\nvar Radix = Radisk.Radix;\nvar rad = Radisk(opt), esc = String.fromCharCode(27);\n \ndescribe('RAD Crashes', function(){\n \n  describe('If No File Added to Index, Recover', function(){\n    var gun = Gun({chunk: opt.chunk});\n \n    it('write initial', function(done){\n        var all = {}, to, start, tmp;\n        var names = ['al', 'alex', 'alexander', 'alice'];\n        names.forEach(function(v,i){\n            all[++i] = true;\n            tmp = v.toLowerCase();\n            gun.get('names').get(tmp).put(i, function(ack){\n                expect(ack.err).to.not.be.ok();\n                delete all[i];\n                if(!Gun.obj.empty(all)){ return }\n                done();\n            })\n        });\n    });\n\n    it('write alan', function(done){\n        var all = {}, to, start, tmp;\n        var names = ['alan'];\n        console.log(\"DID YOU ADD `Gun.CRASH` != 1%C to Radisk f.write list.add callback?\");\n        Gun.CRASH = true; // add check for this in f.swap!\n        names.forEach(function(v,i){\n            all[++i] = true;\n            tmp = v.toLowerCase();\n            gun.get('names').get(tmp).put(i);\n        });\n        setTimeout(function(){\n            Gun.CRASH = false;\n            done();\n        }, 1000);\n    });\n\n    it('write zach', function(done){\n        gun.get('names').get('zach').put(9, function(ack){\n            expect(ack.err).to.not.be.ok();\n            done() ;\n        });\n    });\n\n    it('read names', function(done){\n        console.log(\"Better to .skip 1st run, .only 2nd run & prevent clearing radatatest.\");\n        var g = Gun();\n        var all = {al: 1, alex: 2, alexander: 3, alice: 4, zach: 9};\n        //g.get('names').get('zach').put(9, function(ack){ done() }); return;\n        g.get('names').map().on(function(v,k){\n            //console.log(\"DATA:\", k, v);\n            if(all[k] === v){ delete all[k] }\n            if(!Gun.obj.empty(all)){ return }\n            done();\n        });\n    });\n \n  });\n \n});\n \n}());"
  },
  {
    "path": "test/radix.js",
    "content": "var expect = global.expect = require(\"./expect\");\n\nvar Radix = require('../lib/radix');\nvar _ = String.fromCharCode(29);\n\ndescribe('Radix', function(){ // moved to ./rad/rad.js\n  it('read', function(){\n\t\tvar rad = Radix();\n\t\trad('asdf.pub', 'yum');\n\t\trad('ablah', 'cool');\n\t\trad('node/circle.bob', 'awesome');\n\n\t\texpect(rad('asdf.')).to.be.eql({pub: {'': 'yum'}});\n\t\texpect(rad('nv/foo.bar')).to.be(undefined);\n  });\n});"
  },
  {
    "path": "test/sea/nodeauth.js",
    "content": "const Gun = require(\"../../index.js\");\nconst SEA = require(\"../../sea.js\");\nconst expect = require(\"../expect\");\nconst http = require(\"http\");\nrequire(\"../../lib/promise\");\n\nlet gunClient, server;\n\n// MOVED TO SEA!!!!!!!\n\ndescribe(\"SEA node client auth\", () => {\n  it(\"should  start server\", done => {\n    server = http.createServer().listen(8765, done);\n\n    let gunConfig = {\n      web: server\n    };\n\n    Gun(gunConfig);\n    gunClient = Gun({\n      file: \"radataclient\",\n      peers: [\"http://localhost:8765/gun\"]\n    });\n  });\n\n  it(\"should create user\", done => {\n    gunClient.user().create(\"gun\", \"password\", res => {\n      //console.log({ res });\n      expect(res.err).to.equal(undefined);\n      done();\n    });\n  });\n\n  it(\"should not create new user when exists\", done => {\n    gunClient2 = Gun({\n      file: \"radataclient2\",\n      peers: [\"http://localhost:8765/gun\"]\n    });\n    gunClient2.user().create(\"gun\", \"password\", res => {\n      expect(res.err).to.equal(\"User already created!\");\n      done();\n    });\n  });\n\n  it(\"should auth user\", done => {\n    gunClient.user().auth(\"gun\", \"password\", res => {\n      expect(res.err).to.equal(undefined);\n      done();\n    });\n  });\n\n  it(\"should not stuck on null node\", async () => {\n    const r1 = await gunClient\n      .user()\n      //.once(console.log)\n      .get(\"test\")\n      .promPut({ z: 1 });\n\n    const r2 = await gunClient\n      .user()\n      .get(\"test\")\n      .promPut(null);\n    const res = await gunClient\n      .user()\n      .get(\"test\")\n      .get(\"w\");\n  });\n\n  after(() => {\n    server.close(() => {});\n    process.exit(-1);\n  });\n});\n"
  },
  {
    "path": "test/sea/sea-tmp.html",
    "content": "<script src=\"../gun.js\"></script>\n<script src=\"../lib/cryptomodules.js\"></script>\n<script src=\"../sea.js\"></script>\n<script>\n;(function(){\n\tlocalStorage.clear();\n\t\n\tvar gun = window.gun = Gun();\n\tvar user = gun.user();\n\n\tuser.create('alice', 'unsafepassword', login);\n\n\tfunction login(ack){\n\t\tconsole.log(\"login...\");\n\t\tuser.auth('alice', 'unsafepassword', write);\n\t}\n\n\tfunction write(data){\n\t\tconsole.log(\"write...\");\n\t\tuser.get('profile').get('said').set({\n\t\t\twhat: \"Hello world!\"\n\t\t}, get);\n\t}\n\n\tfunction get(){\n\t\tconsole.log(\"get...\");\n\t\tuser.get('profile').get('said').map().val(function(data){\n\t\t\tconsole.log(\"read...\", data);\n\t\t})\n\t}\n\n}());\n</script>"
  },
  {
    "path": "test/sea/sea.html",
    "content": "<script src=\"../../gun.js\"></script>\n<script src=\"../../lib/cryptomodules.js\"></script>\n<script src=\"../../sea.js\"></script>\n<script>\n;(function(){\n\tlocalStorage.clear();\n\t\n\tvar gun = window.gun = Gun();\n\tvar user = gun.user();\n\n\tuser.create('alice', 'unsafepassword', login);\n\n\tfunction login(ack){\n\t\tconsole.log(\"login...\");\n\t\tuser.auth('alice', 'unsafepassword', keys);\n\t}\n\n\tfunction keys(data){\n\t\tconsole.log(\"keys...\");\n\t\tconst keys = user.pair();\n\t\tconsole.log(keys);\n\t\tGun.SEA.keyid(keys.pub).then(function (keyid) {\n\t\t\tconsole.log(\"Public key KeyID (PGPv4): \" + keyid);\n\t\t\twrite(keys);\n\t\t});\n\t}\n\n\tfunction write(data){\n\t\tconsole.log(\"write...\");\n\t\tvar alice = {name: \"Alice\"};\n\t\talice.boss = {name: \"Fluffy\", slave: alice};\n\t\tuser.get('profile').put(alice, get);\n\t}\n\n\tfunction get(){\n\t\tconsole.log(\"get...\");\n\t\tuser.get('profile').get('boss').get('slave').get('name').val(function(data){\n\t\t\tconsole.log(\"The boss's slave's name is:\", data);\n\t\t})\n\t}\n\n}());\n</script>"
  },
  {
    "path": "test/sea/sea.js",
    "content": "var root;\nvar Gun;\n(function(){\n  var env;\n  if(typeof global !== 'undefined'){ env = global }\n  if(typeof window !== 'undefined'){ env = window }\n  root = env.window? env.window : global;\n  try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}\n  //try{ indexedDB.deleteDatabase('radatatest') }catch(e){}\n  if(root.Gun){\n    root.Gun = root.Gun;\n    root.Gun.TESTING = true;\n  } else {\n    try{ require('fs').unlinkSync('data.json') }catch(e){}\n    try{ require('../../lib/fsrm')('radatatest') }catch(e){}\n    root.Gun = require('../../gun');\n    root.Gun.TESTING = true;\n    require('../../lib/store');\n    require('../../lib/rfs');\n  }\n\n  try{ var expect = global.expect = require(\"../expect\") }catch(e){}\n\n  if(!root.Gun.SEA){\n    require('../../sea.js');\n  }\n}(this));\n\n\n;(function(){\nGun = root.Gun\nvar SEA = Gun.SEA\nif(!SEA){ return }\n\ndescribe('SEA', function(){\n  this.timeout(1000 * 9);\n  var user;\n  var gun;\n  var pub;\n\n  var prep = async function(d,k, n,s){ return {'#':s,'.':k,':': await SEA.opt.parse(d),'>':Gun.state.is(n, k)} }; // shim for old - prep for signing.\n  var pack = function(d,cb,k, n,s){ return new Promise(function(res, rej){ SEA.opt.pack(d, function(r){ res(r) }, k,n,s) }) }; // make easier to upgrade test, cb to await\n  describe('Utility', function(){\n    it('deleting old SEA tests (may take long time)', function(done){\n        done(); // Mocha doesn't print test until after its done, so show this first.\n    });\n    it('deleted', function(done){\n        this.timeout(60 * 1000);\n        if(!Gun.window){ return done() }\n        indexedDB.deleteDatabase('radatatest').onsuccess = function(e){ done() }\n    });\n    /*it('generates aeskey from jwk', function(done) { // DEPRECATED!!!\n      console.log(\"WARNING: THIS DOES NOT WORK IN BROWSER!!!! NEEDS FIX\");\n      SEA.opt.aeskey('x','x').then(k => {\n        //console.log(\"DATA\", k.data);\n        expect(k.data.toString('base64')).to.be('Xd6JaIf2dUybFb/jpEGuSAbfL96UABMR4IvxEGIuC74=')\n        done()\n      })\n    })*/\n    it('quickstart', function(done){\n      SEA.pair(function(pair){\n      SEA.encrypt('hello self', pair, function(enc){\n      SEA.sign(enc, pair, function(data){\n      SEA.verify(data, pair.pub, function(msg){\n      SEA.decrypt(msg, pair, function(dec){\n      expect(dec).to.be('hello self');\n      SEA.work(dec, pair, function(proof){\n      SEA.work('hello self', pair, function(check){\n      expect(proof).to.be(check);\n      SEA.pair(function(alice){\n      SEA.pair(function(bob){\n      SEA.secret(bob.epub, alice, function(aes){\n      SEA.encrypt('shared data', aes, function(enc){\n      SEA.secret(alice.epub, bob, function(aes){\n      SEA.decrypt(enc, aes, function(dec){\n      expect(dec).to.be('shared data');\n      done();\n      });});});});});});});});});});});});});\n    })\n\n    it('quickwrong', function(done){\n      SEA.pair(function(alice){\n      SEA.pair(function(bob){\n      SEA.sign('asdf', alice, function(data){\n      SEA.verify(data, bob.pub, function(msg){\n      expect(msg).to.be(undefined);\n      SEA.verify(data.slice(0,20)+data.slice(21), alice.pub, function(msg){\n      expect(msg).to.be(undefined);\n      SEA.encrypt('secret', alice, function(enc){\n      SEA.decrypt(enc, bob, function(dec){\n      expect(dec).to.be(undefined);\n      SEA.decrypt(enc.slice(0,20)+enc.slice(21), alice, function(dec){\n      expect(dec).to.be(undefined);\n      done();\n      });});});});});});});});\n    })\n\n    it('types', function(done){\n      var pair, s, v;\n      SEA.pair(function(pair){\n      SEA.sign(null, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect(null).to.be(v);\n      SEA.sign(true, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect(true).to.be(v);\n      SEA.sign(false, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect(false).to.be(v);\n      SEA.sign(0, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect(0).to.be(v);\n      SEA.sign(1, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect(1).to.be(v);\n      SEA.sign(1.01, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect(1.01).to.be(v);\n      SEA.sign('', pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect('').to.be(v);\n      SEA.sign('a', pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect('a').to.be(v);\n      SEA.sign([], pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect([]).to.eql(v);\n      SEA.sign([1], pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect([1]).to.eql(v);\n      SEA.sign({}, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect({}).to.eql(v);\n      SEA.sign({a:1}, pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect({a:1}).to.eql(v);\n      SEA.sign(JSON.stringify({a:1}), pair, function(s){\n      SEA.verify(s, pair, function(v){\n      expect({a:1}).to.eql(v);\n      done();\n      });});});});});});});});});});});});});});});});});});});});});});});});});});});\n    })\n\n    it('atypes', function(done){\n      var pair, s, v;\n      SEA.pair(function(pair){\n      SEA.encrypt(null, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect(null).to.be(v);\n      SEA.encrypt(true, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect(true).to.be(v);\n      SEA.encrypt(false, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect(false).to.be(v);\n      SEA.encrypt(0, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect(0).to.be(v);\n      SEA.encrypt(1, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect(1).to.be(v);\n      SEA.encrypt(1.01, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect(1.01).to.be(v);\n      SEA.encrypt('', pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect('').to.be(v);\n      SEA.encrypt('a', pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect('a').to.be(v);\n      SEA.encrypt([], pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect([]).to.eql(v);\n      SEA.encrypt([1], pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect([1]).to.eql(v);\n      SEA.encrypt({}, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect({}).to.eql(v);\n      SEA.encrypt({a:1}, pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect({a:1}).to.eql(v);\n      SEA.encrypt(JSON.stringify({a:1}), pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect({a:1}).to.eql(v);\n      done();\n      });});});});});});});});});});});});});});});});});});});});});});});});});});});\n    })\n    \n    /*it('DOESNT DECRYPT SCIENTIFIC NOTATION', function(done){\n      var pair, s, v;\n      SEA.pair(function(pair){\n      SEA.encrypt('4e2', pair, function(s){\n      SEA.decrypt(s, pair, function(v){\n      expect(400).to.be(v);\n      done();\n      });});});\n    })*/\n    \n    it('legacy', function(done){ (async function(){\n      var pw = 'test123';\n      // https://cdn.jsdelivr.net/npm/gun@0.9.99999/sea.js !\n      var old = JSON.parse(atob(\"eyJfIjp7IiMiOiJ+TkJhdDdKeUk0REw1ZDlPMEZNbWVFN0RacVZRZUVPblhKcldycDVUUGlyMC5PckV6WVIwc3h0NHRtV0tiajFQdHRaeW1HUmdyc1FVVDNHaTk1UE9vMUdBIiwiPiI6eyJwdWIiOjEsImFsaWFzIjoxLCJlcHViIjoxLCJhdXRoIjoxfX0sInB1YiI6Ik5CYXQ3SnlJNERMNWQ5TzBGTW1lRTdEWnFWUWVFT25YSnJXcnA1VFBpcjAuT3JFellSMHN4dDR0bVdLYmoxUHR0WnltR1JncnNRVVQzR2k5NVBPbzFHQSIsImFsaWFzIjoiU0VBe1wibVwiOlwiXFxcImJvYlxcXCJcIixcInNcIjpcIt4uXFx1MDAwNCpbcECT/sxe83eYe/M+bmBF+q5dQr7eYELndMJkXFx1MDAwYlxcbtFu6HNWUKh6XFxyfrWqwcRcXHUwMDE1e3BMv2poWlxcYktcXHUwMDEzZ5H/Z5VcIn0iLCJlcHViIjoiU0VBe1wibVwiOlwiXFxcIkdJUGY2dl8zeV9DZUpQMWtFZkt2OWpmZ3QwT2ZGeDRycHBKS01wSE9MLVEuTmM2dElDUlpwbGwxMG45V2NsRzhXNC1tdDFXZnI2cmh3c0JyN1pRTlduY1xcXCJcIixcInNcIjpcIlxcdTAwMTZcXHUwMDAwzVxcdTAwMGahrvVcXHUwMDBm9y77iP1V3IhkWOajKMxcXHUwMDEy/VxcdTAwMDHN+VxcbozxNWRcXHUwMDA1Zej5XFx1MDAwMpSOXFx1MDAwNny4IclB+lxcdTAwMWTgoXnR8S1OyuZcXHUwMDAx9PqwXFxiXFx1MDAwMFF3XCJ9IiwiYXV0aCI6IlNFQXtcIm1cIjpcIntcXFwiZWtcXFwiOlxcXCJTRUF7XFxcXFxcXCJjdFxcXFxcXFwiOlxcXFxcXFwiXFxcXFxcXFx1MDAwMGvAI6W0L03DwFxcXFxcXFxcdTAwMDZcXFxcXFxcXHUwMDA0ZibqQdE0XFxcXFxcXFx1MDAxY4VvtTZcXFxcXFxcXG7xXfBcXFxcXFxcXHUwMDAzo5xcXFxcXFxcXHUwMDE3XFxcXFxcXFx1MDAwMf9PXFxcXFxcXFx1MDAxMJhnXFxcXFxcXFx1MDAwNccti2pifouBhtu7qcw4/mPs1SHS4uyBTo1RTuReXFxcXFxcXFx1MDAxMK9W4clcXFxcXFxcXHUwMDBmYt1oSIRcXFxcXFxcXHUwMDE4PF5gxoRS2UYtV/1LwHn1SlxcXFxcXFxcXFxcXFxcXFyYuFU3cUVf09/AXFxcXFxcXFx1MDAwZlxcXFxcXFxcdTAwMDRQN8RlXFxcXFxcXFx1MDAwNlxcXFxcXFxcdTAwMGXM4G3fXFxcXFxcXFx1MDAxZt+eRoV9XFxcXFxcXCIsXFxcXFxcXCJpdlxcXFxcXFwiOlxcXFxcXFwiVU5Lv+Zko1xcXFxcXFxcdTAwMDOt1ET2JHhcXFxcXFxcXHUwMDE1/1xcXFxcXFwiLFxcXFxcXFwic1xcXFxcXFwiOlxcXFxcXFwiz0VOO9GwaJlcXFxcXFxcIn1cXFwiLFxcXCJzXFxcIjpcXFwiZ0F4TFJpa2dEakIzbXJDNGpucUFRak5NNEZXemF0a1Eyb2xDR2Z5TTc2amg3azNEUzAyRlp1MEV1eWg2RGFITlxcXCJ9XCIsXCJzXCI6XCKze+BcXHUwMDBilPlcXHUwMDA2z1srodVcXHUwMDA0P1xcXCJcXFwib2rndUadtqJcXHUwMDE2bFtf0PSvJNdcXHUwMDE2Y71nnlxcdTAwMWOZXFx1MDAwN1xcdTAwMTlcXHUwMDE36NZcXHUwMDA0Uk7DQK/y/oixrIr1XFx1MDAxZnVcXHUwMDE3oCBhXCJ9In0=\"));\n      var okey = {\"pub\":\"NBat7JyI4DL5d9O0FMmeE7DZqVQeEOnXJrWrp5TPir0.OrEzYR0sxt4tmWKbj1PttZymGRgrsQUT3Gi95POo1GA\",\"epub\":\"GIPf6v_3y_CeJP1kEfKv9jfgt0OfFx4rppJKMpHOL-Q.Nc6tICRZpll10n9WclG8W4-mt1Wfr6rhwsBr7ZQNWnc\",\"priv\":\"leIA-BOFLECsOOdT_B8B0s1Ii0VHZZGlHz8q_dK-xLs\",\"epriv\":\"1BTJpYdwSLesrtuB7pYQdsrFHsxKSJ-d9PXt2qp6NyQ\"}\n      var auth = await SEA.verify(old.auth, old.pub);\n      var proof = await SEA.work(pw, auth.s, null, {encode: 'utf8'});\n      var dec = await SEA.decrypt(auth.ek, proof, null);\n      expect(dec.priv).to.be(okey.priv);\n      expect(dec.epriv).to.be(okey.epriv);\n\n      var gun = Gun({super: true}), tmp = old._['#'];\n      var graph = {};\n      gun._.graph[tmp] = graph[tmp] = old;\n      var alias = await SEA.verify(old.alias, false);\n      expect(alias).to.be('bob');\n      alias = Gun.state.ify({}, tmp, 1, {'#': tmp}, tmp = '~@'+alias);\n      graph[tmp] = alias;\n      gun._.graph[tmp] = alias;//gun.on('test', {$: gun, put: graph});\n      var use = gun.user();\n      use.auth('bob', 'test123', function(ack){\n        expect(ack.err).to.not.be.ok();\n        done();\n      });\n    }())});\n    \n    it('legacy []', function(done){ (async function(){\n      var pw = 'test123';\n      // https://cdn.jsdelivr.net/npm/gun@0.9.99999/sea.js !\n      var old = JSON.parse(atob(\"eyJfIjp7IiMiOiJ+VThkS0dySFJhX01sMFZ1YlR5OUZBYTlQS1ZlYlh0eTFjS05zWWxnYjduNC5QeVd5cUVVb0ZpYVduUElOV0Nad0xBbzFobjN1MldPWTU3SzZHZnpsNjhVIiwiPiI6eyJwdWIiOjE1NDY5MDI1MDQ5NzksImFsaWFzIjoxNTQ2OTAyNTA0OTc5LCJlcHViIjoxNTQ2OTAyNTA0OTc5LCJhdXRoIjoxNTQ2OTAyNTA0OTc5fX0sInB1YiI6IlU4ZEtHckhSYV9NbDBWdWJUeTlGQWE5UEtWZWJYdHkxY0tOc1lsZ2I3bjQuUHlXeXFFVW9GaWFXblBJTldDWndMQW8xaG4zdTJXT1k1N0s2R2Z6bDY4VSIsImFsaWFzIjoiU0VBe1wibVwiOltcIn5VOGRLR3JIUmFfTWwwVnViVHk5RkFhOVBLVmViWHR5MWNLTnNZbGdiN240LlB5V3lxRVVvRmlhV25QSU5XQ1p3TEFvMWhuM3UyV09ZNTdLNkdmemw2OFVcIixcImFsaWFzXCIsXCJhbGljZVwiLDE1NDY5MDI1MDQ5NzldLFwic1wiOlwienpuaGtIZjhZdFpZM2lGd3FVd0lJUldMTjhZMmlHbmNkcnVTaStGNDNmU1BLYWpSZlI0VzhXVHM4bElSMDBndGJmTWJxS0NjQkpGN3VNSkdGRC9WV2c9PVwifSIsImVwdWIiOiJTRUF7XCJtXCI6W1wiflU4ZEtHckhSYV9NbDBWdWJUeTlGQWE5UEtWZWJYdHkxY0tOc1lsZ2I3bjQuUHlXeXFFVW9GaWFXblBJTldDWndMQW8xaG4zdTJXT1k1N0s2R2Z6bDY4VVwiLFwiZXB1YlwiLFwiRkRzM1VvNTNFZEp6eFNocEpDaVctRGZPQ3lUS0M2U3cxeS1PZVJxam5ZRS5xVGdyYTlFQk1maEpNdVlMVmNaejRZYklLRm85enNBMHpMcV82dEVPMHI0XCIsMTU0NjkwMjUwNDk3OV0sXCJzXCI6XCJPZzRVVjY4OTluSjE4dC9ybWVnV0lkdnNqN01KaEpFc29ranZYQmdteVVRUXVNVjFTdnh4cXJqOFoyV1o2Q25XSkZnTlVDbEVYYWxuMURjUFE3M1R6UT09XCJ9IiwiYXV0aCI6IlNFQXtcIm1cIjpbXCJ+VThkS0dySFJhX01sMFZ1YlR5OUZBYTlQS1ZlYlh0eTFjS05zWWxnYjduNC5QeVd5cUVVb0ZpYVduUElOV0Nad0xBbzFobjN1MldPWTU3SzZHZnpsNjhVXCIsXCJhdXRoXCIsXCJ7XFxcImVrXFxcIjpcXFwiU0VBe1xcXFxcXFwiY3RcXFxcXFxcIjpcXFxcXFxcIi94ZnNPdVNkQUtrNkJiR00zbUV6MnVlSjI3Y0tJNThYMEtUL1FsaExSZXpWcjRkNzVZb2M5QlZNRjkzejl4QXI4N080S2FDNjJUWGVoeERQN0FFa2V4N1paaEpYL2hsVm9kK1FIcVFaaUZMK2lVQzFvL2hpUEJGWElBZmtINGRrcklGOFdqcEVaU3NIVmRSOVRhY2ZzbTB3aHN5NGJXN1ZLSEUySGc9PVxcXFxcXFwiLFxcXFxcXFwiaXZcXFxcXFxcIjpcXFxcXFxcIjhWekduTStEc1lTUktIU3Z4cSszTGc9PVxcXFxcXFwiLFxcXFxcXFwic1xcXFxcXFwiOlxcXFxcXFwibVVSSlJ4TzUvdXM9XFxcXFxcXCJ9XFxcIixcXFwic1xcXCI6XFxcImE1SlA3VFpuVE9jYjEwMGJOejlscEU4dnpqcUE3TWl0NHcwN3pjQTdIOFV0bml1WnVHSmdpZnNNQlFNSGdRdE5cXFwifVwiLDE1NDY5MDI1MDQ5NzldLFwic1wiOlwiSGFzMytJaHFEZTYyN016cElXZVE1cVFrZ2NOMlk3WHRpNGw0TFU3T2JyaktxSlBnSllrVWE2bk9YdlRmQkFzV1BPVzVnemh4Q2RPVGNFQm5icWlpWXc9PVwifSJ9\"));\n      var okey = {\"pub\":\"U8dKGrHRa_Ml0VubTy9FAa9PKVebXty1cKNsYlgb7n4.PyWyqEUoFiaWnPINWCZwLAo1hn3u2WOY57K6Gfzl68U\",\"epub\":\"FDs3Uo53EdJzxShpJCiW-DfOCyTKC6Sw1y-OeRqjnYE.qTgra9EBMfhJMuYLVcZz4YbIKFo9zsA0zLq_6tEO0r4\",\"priv\":\"jMy7WfcldJ4esZEijAj4LTb99smtY_H0yKJLemJl2HI\",\"epriv\":\"1DszMh-85pGTPLYtRunG-Q-xB78AE4k07PPkbedYYwk\"}\n\n      var gun = Gun({super: true}), tmp = old._['#'];//Gun.node.soul(old);\n      var graph = {};\n      gun._.graph[tmp] = graph[tmp] = old;\n      var alias = SEA.opt.unpack(await SEA.verify(old.alias, false), 'alias', old);\n      expect(alias).to.be('alice');\n      alias = Gun.state.ify({}, tmp, 1, {'#': tmp}, tmp = '~@'+alias);\n      gun._.graph[tmp] = graph[tmp] = alias;\n      //gun.on('test', {$: gun, put: graph});\n      var use = gun.user();\n      use.auth('alice', 'test123', function(ack){\n        expect(ack.err).to.not.be.ok();\n        done();\n      });\n    }())})\n\n    it('JSON escape', function(done){ (async function(){\n      var plain = \"hello world\";\n      var json = JSON.stringify({hello:'world'});\n\n      var n1 = Gun.state.ify({}, 'key', 1, plain, 'soul');\n      var n2 = Gun.state.ify({}, 'key', 1, json, 'soul');\n      var tmp = await prep(plain, 'key', n1, 'soul');\n      expect(tmp[':']).to.be(\"hello world\");\n      tmp = await prep(json, 'key', n2, 'soul');\n      expect(tmp[':'].hello).to.be(\"world\");\n      tmp = SEA.opt.unpack(tmp);\n      expect(tmp.hello).to.be(\"world\");\n      done();\n    }())});\n\n    it('double sign', function(done){ (async function(){\n      var pair = await SEA.pair();\n      var sig = await SEA.sign('hello world', pair);\n      var dup = await SEA.sign(sig, pair);\n      expect(dup).to.be(sig);\n\n      var json = JSON.stringify({hello:'world'});\n      var n1 = Gun.state.ify({}, 'key', 1, json, 'soul');\n      var sig = await SEA.sign(await prep(json, 'key', n1, 'soul'), pair, null, {raw:1 , check: await pack(json, 'key', n1, 'soul')});\n      var dup = await SEA.sign(await prep(sig, 'key', n1, 'soul'), pair, null, {raw:1 , check: await pack(sig, 'key', n1, 'soul')});\n      expect(dup).to.be.eql(sig);\n\n      var json = JSON.stringify({hello:'world'});\n      var n1 = Gun.state.ify({}, 'key', 1, json, 'soul');\n      var bob = await SEA.pair();\n      var sig = await SEA.sign(await prep(json, 'key', n1, 'soul'), bob, null, {raw:1 , check: await pack(json, 'key', n1, 'soul')});\n      var dup = await SEA.sign(await prep(sig, 'key', n1, 'soul'), pair, null, {raw:1 , check: await pack(sig, 'key', n1, 'soul')});\n      expect(dup).to.not.be.eql(sig);\n\n      var json = JSON.stringify({hello:'world'});\n      var bob = await SEA.pair();\n      var sig = await SEA.sign(json, bob);\n      var dup = await SEA.sign(sig, pair);\n      expect(dup).to.not.be.eql(sig);\n      done();\n    }())})\n  });\n\n  describe('User', function(){\n    var gun = Gun(), gtmp;\n\n    it('test', function(done){\n      var g = Gun();\n      user = g.user();\n      var gid;\n      SEA.pair(function(p){\n        user.is = user._.sea = p;\n        gtmp = gid = 'test~'+p.pub;\n        g.get(gid).put({yo: 'hi'}, async function(ack){\n          var data = await SEA.opt.parse(g._.graph[gid].yo);\n          expect(data[':']).to.be('hi');\n          expect(data['~']).to.be.ok();\n          g.get(gid).get('yo').once(function(r){\n            expect(r).to.be('hi');\n            user.leave();\n            done();\n          })\n        })\n      })\n    });\n\n    it('is instantiable', function(done){\n      user.leave();\n      user = gun.user();\n      done();\n    })\n\n    it('register users', function(done){\n      user.create('carl', 'testing123', function(ack){\n        pub = '~'+ack.pub;\n        expect(ack.err).to.not.be.ok();\n        done();\n      })\n    });\n\n    it('login users', function(done){\n      user.auth('carl', 'testing123', function(ack){\n        expect(ack.err).to.not.be.ok();\n        done()\n      })\n    })\n\n    it('logout, login via {pub}', function(done){\n      var pub = user.is.pub;\n      user.leave();\n      user.auth({pub:pub}, 'testing123', function(ack){\n        expect(ack.err).to.not.be.ok();\n        done();\n      })\n    })\n\n    it('save data', function(done){\n      user.get('a').get('b').put(0, function(ack){\n        expect(ack.err).to.not.be.ok();\n        done();\n      });\n    })\n    it('read data', function(done){\n      user.get('a').get('b').once(function(data){\n        expect(data).to.be(0);\n        done();\n      });\n    })\n\n    it('save json', function(done){\n      user.get('a').get('c').put(JSON.stringify({hello:'world'}), function(ack){\n        expect(ack.err).to.not.be.ok();\n        done();\n      });\n    })\n\n    it('read json', function(done){\n      user.get('a').get('c').once(function(data){\n        expect(data).to.be(JSON.stringify({hello:'world'}));\n        done();\n      });\n    })\n\n    it('save & read encrypt', function(done){\n      SEA.encrypt('hi', user._.sea, function(data){\n        var is = data.slice();\n        user.get('a').get('d').put(data, function(ack){\n          expect(ack.err).to.not.be.ok();\n          setTimeout(function(){\n            user.get('a').get('d').once(function(data){\n              expect(data).to.be(is);\n              done();\n            });\n          })\n        });\n      })\n    })\n\n    it('refresh login', function(done){\n      this.timeout(9000);\n      setTimeout(function(){\n        gun = Gun();\n        user = gun.user();\n        user.auth('carl', 'testing123', function(ack){\n          expect(ack.err).to.not.be.ok();\n          done()\n        })\n      }, 800);\n    })\n\n    it('gun put JSON', function(done){\n      gun.get('x').get('y').put(JSON.stringify({hello:'world'}), function(ack){\n        expect(ack.err).to.not.be.ok();\n        done();\n      });\n    })\n\n    it('gun get JSON', function(done){\n      gun.get('x').get('y').once(function(data){\n        expect(data).to.be(JSON.stringify({hello:'world'}));\n        done();\n      });\n    })\n\n    it('set user ref should be found', function(done){\n      var gun = Gun();\n      var user = gun.user();\n      var msg = {what: 'hello world'};\n      user.create('zach', 'password');\n      gun.on('auth', function(){\n        var ref = user.get('who').get('all').set(msg);\n        user.get('who').get('said').set(ref);\n        user.get('who').get('said').map().once(function(data){\n          //console.log(\"*****\", data);\n          expect(data.what).to.be.ok();\n          done();\n        })\n      })\n    });\n\n    it('set user ref null override', function foo(done){\n      this.timeout(9000);\n      var gun = Gun();\n      //user.leave();\n      var user = gun.user();\n      var msg = {what: 'hello world'};\n      user.create('xavier', 'password');\n      gun.on('auth', function(){\n        //console.log(1);\n        if(done.a){ return } done.a = 1;\n        var ref = user.get('who').get('all').set(msg, A);\n        var stub = user.get('stub').put({});\n        function A(){\n          //console.log(2);\n          user.get('who').put(stub, B);\n          function B(){\n            //console.log(3);\n            var tmp = ref._.has || ref._.soul;\n            user.get('who').get('all').get(tmp).put({boom: 'ah'}, C);\n            function C(){\n              //console.log(4);\n              user.get('who').get('all').map().once(function(data){\n                //console.log(5);\n                expect(data).to.be.ok();\n                expect(data.what).to.not.be.ok();\n                done();\n              });\n            }\n          }\n        };\n      });\n    });\n\n    it(\"User's nodes must be signed when on user scope!\", function(done) {\n      /// https://github.com/amark/gun/issues/850\n      /// https://github.com/amark/gun/issues/616\n      this.timeout(9000);\n      var gun = Gun();\n      var user = gun.user();\n      user.create('xavier2', 'password2');\n      gun.on('auth', function(){\n        user.get(\"testauthed\").get(\"arumf\").set({\"this\": \"is\", \"an\": {\"obj2\": \"again2\"}}, function(ack) {\n          var notsigned = [];\n          //Gun.obj.map(gun._.graph, function(v,k) {\n          Object.keys(gun._.graph).forEach(function(k,v){ v = gun._.graph[k]; \n            if (k[0]==='~' || k.indexOf('~', 1)!==-1) { return; } /// ignore '~pubkey' and '~@alias'\n            notsigned.push(k);\n          });\n          expect(notsigned.length).to.be(0); /// all souls must have to be suffixed with the user's pubkey.\n          done();\n        });\n      });\n    });\n\n    describe('predictable souls', function(){\n      var alice = {\n        \"pub\": \"sT1s6lOaUgia5Aiy_Qg_Z4ubCCVFDyGVJsi-i0VmKJI.UTmwQrcKxkHfw0lFK2bkVDaYbd4_2T1Gj-MONFMostM\",\n        \"priv\": \"HUmmMsaphGuOsUHAGGg9HHrYOA5FCrsueY6QexE79AE\",\n        \"epub\": \"MIPYx3rdRJbJSvtan0ruwIjMYaB5W7t42MJ4U1Y2jsk.HFNKa-LoIp5MPI-KFXZhvANjhAxL8dzgXWzLVhewtuk\",\n        \"epriv\": \"7X9rN1NxDYi9jtNU7daIA33__KYEIw3bN5amI-Rc5sw\"\n      };\n      it(\"user's\", function(done){\n        var gun = Gun();\n        gun.on('auth', function(){\n          gun.user().get('z').get('y').get('x').put({c: {b: {a: 1}}}, function(ack){setTimeout(function(){\n            if(done.c){ return } done.c = 1;\n            var g = gun._.graph;\n            var p = '~'+alice.pub+'/';\n            //console.log(p, g);\n            expect(g[p+'z']).to.be.ok();\n            expect(g[p+'z/y']).to.be.ok();\n            expect(g[p+'z/y/x']).to.be.ok();\n            expect(g[p+'z/y/x/c']).to.be.ok();\n            expect(g[p+'z/y/x/c/b']).to.be.ok();\n            done();\n          },200)});\n        });\n        gun.user().auth(alice);\n      });\n\n      it('user mix', function(done){\n        var gun = Gun();\n        gun.on('auth', async function(){\n          if(done.a){ return } done.a = 1;\n          var c = 0, go = function(){ check(++c) }\n          var ref = gun.user().get('zasdf').put({a: 9}, go);\n          //ref._.REF = 'ref!';\n          //console.only.i=1;console.log(\"=================\");\n          var at = gun.user().get('zfdsa').get('y').get('x').get('c').put(ref, go);\n          //ref._.DAT = 'dat!';\n          at.get('foo').get('bar').put('yay', go);\n          ref.get('foo').get('ah').put(1, go);\n          function check(){\n            if(c !== 4){ return }\n            setTimeout(function(){\n            if(done.c){ return } done.c = 1;\n            var g = gun._.graph;\n            var p = '~'+alice.pub;\n            //console.log(g);\n            expect(Object.keys(g[p]).sort()).to.be.eql(['_', 'zasdf', 'zfdsa'].sort());\n            expect(Object.keys(g[p+'/zasdf']).sort()).to.be.eql(['_', 'a', 'foo'].sort());\n            expect(Object.keys(g[p+'/zasdf/foo']).sort()).to.be.eql(['_', 'bar', 'ah'].sort());\n            expect(Object.keys(g[p+'/zfdsa']).sort()).to.be.eql(['_', 'y'].sort());\n            expect(Object.keys(g[p+'/zfdsa/y']).sort()).to.be.eql(['_', 'x'].sort());\n            expect(Object.keys(g[p+'/zfdsa/y/x']).sort()).to.be.eql(['_', 'c'].sort());\n            expect(g[p+'/zfdsa'].y.indexOf('/zfdsa/y\"') > 0).to.be.ok();\n            expect(g[p+'/zfdsa/y'].x.indexOf('/zfdsa/y/x\"') > 0).to.be.ok();\n            expect(g[p+'/zfdsa/y/x'].c.indexOf('/zasdf\"') > 0).to.be.ok();\n            done();\n          },100)};\n        });\n        gun.user().auth(alice);\n      });\n      \n      it('user thread', function(done){\n        // grr this doesn't properly replicate the issue I saw before\n        var gun = Gun();\n        gun.on('auth', async function(){\n          if(done.a){ return } done.a = 1;\n          var to = gun.user().get('pchat').get('their.pub');\n          var enc = await SEA.encrypt('hi', 'secret');\n          var msg = { msg: enc };\n          to.get('2020').put(msg, function(){\n            if(done.c){ return } done.c = 1;\n            var g = gun._.graph;\n            var p = '~'+alice.pub+'/';\n            //console.log(p, Object.keys(g[p+'pchat/their.pub/2020']||{}).sort());\n            expect(Object.keys(g[p+'pchat/their.pub/2020']).sort()).to.be.eql(['_', 'msg'].sort());\n            expect(g[p+'2020']).to.not.be.ok();\n            done();\n          });\n        });\n        gun.user().auth(alice);\n      });\n    });\n\n    describe('node', function(){\n      var u;\n      if(''+u === typeof process){ return }\n      console.log(\"REMEMBER TO RUN mocha test/sea/nodeauth !!!!\");\n    });\n\n  });\n\n  describe('CERTIFY', function () {\n    var gun = Gun()\n    var user = gun.user()\n\n    it('Certify: Simple', function(done){(async function(){\n      var alice = await SEA.pair()\n      var bob = await SEA.pair()\n      var dave = await SEA.pair()\n      var cert = await SEA.certify(bob, {\"*\": \"private\"}, alice)\n      \n      user.leave()\n      user.auth(bob, () => {\n        var data = Gun.state().toString(36)\n        gun.get(\"~\" + alice.pub)\n          .get(\"private\")\n          .get(\"asdf\")\n          .get(\"qwerty\")\n          .put(data, () => {\n            // Bob reads\n            gun.get(\"~\" + alice.pub)\n            .get(\"private\")\n            .get(\"asdf\")\n            .get(\"qwerty\").once(_data=>{\n              expect(_data).to.be(data)\n              user.leave()\n              // everyone reads\n              gun.get(\"~\" + alice.pub)\n              .get(\"private\")\n              .get(\"asdf\")\n              .get(\"qwerty\").once(_data=>{\n                expect(_data).to.be(data)\n                user.auth(dave, () => {\n                  // Dave reads\n                  gun.get(\"~\" + alice.pub)\n                  .get(\"private\")\n                  .get(\"asdf\")\n                  .get(\"qwerty\").once(_data=>{\n                    expect(_data).to.be(data)\n                    user.leave()\n                    done()\n                  })\n                })\n              })\n            })\n          }, { opt: { cert } })\n      })\n    }())})\n\n    it('Certify: Attack', function(done){(async function(){\n      var alice = await SEA.pair()\n      var bob = await SEA.pair()\n      var cert = await SEA.certify(bob, {\"*\": \"private\"}, alice);\n      \n      user.leave()\n      user.auth(bob, () => {\n        var data = Gun.state().toString(36)\n        gun.get(\"~\" + alice.pub)\n          .get(\"wrongway\")\n          .get(\"asdf\")\n          .get(\"qwerty\")\n          .put(data, ack => {\n            expect(ack.err).to.be.ok()\n            user.leave()\n            done()\n          }, { opt: { cert } })\n      })\n    }())})\n\n    it('Certify: Public inbox', function(done){(async function(){\n      var alice = await SEA.pair()\n      var bob = await SEA.pair()\n      var cert = await SEA.certify('*', [{\"*\": \"test\", \"+\": \"*\"}, {\"*\": \"inbox\", \"+\": \"*\"}], alice)\n      user.leave()\n      user.auth(bob, () => {\n        var data = Gun.state().toString(36)\n        gun.get(\"~\" + alice.pub)\n          .get(\"inbox\")\n          .get(user.is.pub)\n          .put(data, ack => {\n            expect(ack.err).to.not.be.ok()\n            user.leave()\n            done()\n          }, { opt: { cert } })\n      })\n    }())});\n\n    it('Certify: Expiry', function(done){(async function(){\n      var alice = await SEA.pair()\n      var bob = await SEA.pair()\n      var cert = await SEA.certify(bob, {\"*\": \"private\"}, alice, null, {\n        expiry: Gun.state() - 100, // expired 100 milliseconds ago\n      })\n\n      user.leave()\n      user.auth(bob, () => {\n        var data = Gun.state().toString(36)\n        gun.get(\"~\" + alice.pub)\n          .get(\"private\")\n          .get(\"asdf\")\n          .get(\"qwerty\")\n          .put(data, ack => {\n            expect(ack.err).to.be.ok()\n            user.leave()\n            done()\n          }, { opt: { cert } })\n      })\n    }())})\n\n    it('Certify: Path or Key must contain Certificant Pub', function(done){(async function(){\n      var alice = await SEA.pair()\n      var bob = await SEA.pair()\n      var cert = await SEA.certify(bob, {\"*\": \"private\", \"+\": \"*\"}, alice)\n\n      user.leave()\n      user.auth(bob, () => {\n        var data = Gun.state().toString(36)\n        gun.get(\"~\" + alice.pub)\n          .get(\"private\")\n          .get('wrongway')\n          .put(data, ack => {\n            expect(ack.err).to.be.ok()\n            gun.get(\"~\" + alice.pub)\n            .get(\"private\")\n            .get(bob.pub)\n            .get('today')\n            .put(data, ack => {\n              expect(ack.err).to.not.be.ok()\n              gun.get(\"~\" + alice.pub)\n              .get(\"private\")\n              .get(bob.pub)\n              .get('today')\n              .once(_data => {\n                expect(_data).to.be(data)\n                user.leave();\n                done()\n              })\n            }, { opt: { cert } })\n          }, { opt: { cert } })\n      })\n    }())})\n\n    it('Certify: Advanced - Block', function(done){(async function(){\n      var alice = await SEA.pair()\n      var dave = await SEA.pair()\n      var bob = await SEA.pair()\n      var cert = await SEA.certify(bob, {\"*\": \"private\"}, alice, null, {\n        expiry: Gun.state() + 5000, // expires in 5 seconds\n        block: 'block' // path to block in Alice's graph\n      })\n\n      // Alice points her block to Dave's graph\n      await user.auth(alice)\n      if (user.is) {\n        await user.get('block').put({'#': '~'+dave.pub+'/block'});\n        await user.leave()\n      }\n\n      // Dave logins, he adds Bob to his block, which is connected to the certificate that Alice issued for Bob\n      await user.auth(dave)\n      if (user.is) {\n        await user.get('block').get(bob.pub).put(true)\n        await user.leave()\n      }\n\n      // Bob logins and tries to hack Alice\n      await user.auth(bob)\n      if (user.is) {\n        var data = Gun.state().toString(36)\n        gun.get(\"~\" + alice.pub)\n            .get(\"private\")\n            .get(\"asdf\")\n            .get(\"qwerty\")\n            .put(data, ack => {\n              expect(ack.err).to.be.ok()\n              user.leave()\n              done()\n            }, { opt: { cert } })\n      }\n    }())})\n\n  });\n\n  describe.skip('Frozen', function () {\n    it('Across spaces', function(done){\n      var gun = Gun();\n      var user = gun.user();\n\n      user.create('alice/as', 'password');\n      \n      gun.on('auth', async function(){\n\n        user.put({name: \"Alice\", country: \"USA\"});\n\n        var data = \"hello world\";\n        var hash = await SEA.work(data, null, null, {name: \"SHA-256\"});\n        gun.get('#users').get(hash).put(data);\n\n        console.log(1);\n        gun.get('#users').map()/*.get('country')*/.on(data => console.log(data));\n\n      });\n    });\n  });\n})\n\n}());\n\n"
  },
  {
    "path": "test/sea/sea_old.js",
    "content": "/* global Gun,describe,expect,it,beforeEach */\n/*eslint max-len: [\"error\", 95, { \"ignoreComments\": true }]*/\n/*eslint semi: [\"error\", \"always\", { \"omitLastInOneLineBlock\": true}]*/\n/*eslint object-curly-spacing: [\"error\", \"never\"]*/\n/*eslint node/no-deprecated-api: [error, {ignoreModuleItems: [\"new buffer.Buffer()\"]}] */\n\nvar root;\n(function(env){\n  root = env.window ? env.window : global;\n  env.window && root.localStorage && root.localStorage.clear();\n  try{ require('fs').unlinkSync('data.json') }catch(e){}\n  //root.Gun = root.Gun || require('../gun');\n  if(root.Gun){\n    root.Gun = root.Gun;\n  } else {\n    var expect = global.expect = require(\"./expect\");\n    root.Gun = require('../gun');\n    Gun.serve = require('../lib/serve');\n    //require('./s3');\n    //require('./uws');\n    //require('./wsp/server');\n    require('../lib/file');\n    require('../sea');\n  }\n}(this));\n\n;(function(){\n\nconst SEA = Gun.SEA\n\nif(!SEA){ return }\n\nconst { Buffer, EasyIndexedDB } = SEA\n\nconst seaIndexedDb = new SEA.EasyIndexedDB('SEA', 'GunDB', 1)\n\nconst checkIndexedDB = (key, prop, resolve_) => {\n  const doIt = (resolve, reject) => seaIndexedDb.get(key, prop)\n  .then(resolve).catch(reject)\n\n  if (resolve_) {\n    doIt(resolve_, (e) => { throw e })\n  } else {\n    return new Promise(doIt)\n  }\n}\n\nconst setIndexedDB = (key, auth, resolve_) => {\n  const doIt = (resolve, reject) => seaIndexedDb.put(key, { auth })\n  .then(resolve).catch(reject)\n\n  if (resolve_) {\n    doIt(resolve_, (e) => { throw e })\n  } else {\n    return new Promise(doIt)\n  }\n}\n\nSEA && describe('SEA', function(){\n  console.log('TODO: SEA! THIS IS AN EARLY ALPHA!!!');\n  var alias = 'dude';\n  var pass = 'my secret password';\n  var userKeys = ['pub', 'priv'];\n  var clearText = 'My precious secret!';\n  var encKeys = ['ct', 'iv', 's'];\n\n  const type = 'Promise'  // TODO: this is leftover...\n  it('proof', function(done){\n    var check = function(proof){\n      expect(proof).to.not.be(undefined);\n      expect(proof).to.not.be('');\n      done();\n    };\n    // proof - generates PBKDF2 hash from user's alias and password\n    // which is then used to decrypt user's auth record\n    SEA.proof(pass, Gun.text.random(64)).then(check).catch(done);\n  });\n\n  it('pair', function(done){\n    var check = function(key){\n      expect(key).to.not.be(undefined);\n      expect(key).to.not.be('');\n      expect(key).to.have.keys(userKeys);\n      userKeys.map(function(fld){\n        expect(key[fld]).to.not.be(undefined);\n        expect(key[fld]).to.not.be('');\n      });\n      done();\n    };\n    // pair - generates ECDH key pair (for new user when created)\n    SEA.pair().then(check).catch(done);\n  });\n\n  it('keyid', function(done){\n    SEA.pair().then(function(key){\n      var check = function(keyid){\n        expect(keyid).to.not.be(undefined);\n        expect(keyid).to.not.be('');\n        expect(keyid.length).to.eql(16);\n        done();\n      };\n      // keyid - creates 8 byte KeyID from public key\n      SEA.keyid(key.pub).then(check);\n    }).catch(function(e){done(e)});\n  });\n\n  it('enc', function(done){\n    SEA.pair().then(function(key){\n      var check = function(jsonSecret){\n        expect(jsonSecret).to.not.be(undefined);\n        expect(jsonSecret).to.not.be('');\n        expect(jsonSecret).to.not.eql(clearText);\n        var objSecret = JSON.parse(jsonSecret);\n        expect(objSecret).to.have.keys(encKeys);\n        encKeys.map(function(key){\n          expect(objSecret[key]).to.not.be(undefined);\n          expect(objSecret[key]).to.not.be('');\n        });\n        done();\n      };\n      // en - encrypts JSON data using user's private or derived ECDH key\n      SEA.enc(clearText, key.priv).then(check);\n    }).catch(function(e){done(e)});\n  });\n\n  it('sign', function(done){\n    SEA.pair().then(function(key){\n      var check = function(signature){\n        expect(signature).to.not.be(undefined);\n        expect(signature).to.not.be('');\n        expect(signature).to.not.eql(key.pub);\n        done();\n      };\n      // sign - calculates signature for data using user's private ECDH key\n      SEA.sign(key.pub, key).then(check);\n    }).catch(function(e){done(e)});\n  });\n\n  it('verify', function(done){\n    SEA.pair().then(function(key){\n      var check = function(ok){\n        expect(ok).to.not.be(undefined);\n        expect(ok).to.not.be('');\n        expect(ok).to.be(true);\n        done();\n      };\n      // sign - calculates signature for data using user's private ECDH key\n      SEA.sign(key.pub, key).then(function(signature){\n        SEA.verify(key.pub, key.pub, signature).then(check);\n      });\n    }).catch(function(e){done(e)});\n  });\n\n  it('dec', function(done){\n    SEA.pair().then(function(key){\n      var check = function(decText){\n        expect(decText).to.not.be(undefined);\n        expect(decText).to.not.be('');\n        expect(decText).to.be.eql(clearText);\n        done();\n      };\n      SEA.enc(clearText, key.priv).then(function(jsonSecret){\n        // de - decrypts JSON data using user's private or derived ECDH key\n        SEA.dec(jsonSecret, key.priv).then(check);\n      });\n    }).catch(function(e){done(e)});\n  });\n\n  it('derive', function(done){\n    SEA.pair().then(function(txKey){\n      return SEA.pair().then(function(rxKey){\n        return {tx: txKey, rx: rxKey};\n      });\n    }).then(function(keys){\n      var check = function(shared){\n        expect(shared).to.not.be(undefined);\n        expect(shared).to.not.be('');\n        [keys.rx.pub, keys.rx.priv, keys.tx.pub, keys.tx.priv]\n        .map(function(val){\n          expect(shared).to.not.eql(val);\n        });\n        done();\n      };\n      // derive - provides shared secret for both receiver and sender\n      // which can be used to encrypt or sign data\n      SEA.derive(keys.rx.pub, keys.tx).then(check);\n    }).catch(function(e){done(e)});\n  });\n\n  it('write', function(done){\n    SEA.pair().then(function(key){\n      SEA.sign(key.pub, key).then(function(signature){\n        var check = function(result){\n          var parts;\n          try{\n            expect(result).to.not.be(undefined);\n            expect(result).to.not.be('');\n            expect(result.slice(0, 4)).to.eql('SEA[');\n            parts = JSON.parse(result.slice(3));\n            expect(parts).to.not.be(undefined);\n            expect(parts[0]).to.be.eql(key.pub);\n            // expect(parts[1]).to.be.eql(signature);\n          }catch(e){ return done(e) }\n          SEA.verify(key.pub, key.pub, parts[1]).then(function(flag){\n            expect(flag).to.be.true;\n            done();\n          });\n        };\n        // write - wraps data to 'SEA[\"data\",\"signature\"]'\n        SEA.write(key.pub, key).then(check);\n      });\n    }).catch(function(e){done(e)});\n  });\n\n  it('read', function(done){\n    SEA.pair().then(function(key){\n      var check = function(result){\n        expect(result).to.not.be(undefined);\n        expect(result).to.not.be('');\n        expect(result).to.be.equal(key.pub);\n        done();\n      };\n      SEA.sign(key.pub, key).then(function(signature){\n        SEA.write(key.pub, key).then(function(signed){\n          // read - unwraps data from 'SEA[\"data\",\"signature\"]'\n          SEA.read(signed, key.pub).then(check);\n        });\n      });\n    }).catch(function(e){done(e)});\n  });\n});\n\nGun().user && describe('Gun', function(){\n  describe('User', function(){\n    console.log('TODO: User! THIS IS AN EARLY ALPHA!!!');\n    var alias = 'dude';\n    var pass = 'my secret password';\n    var gun = Gun();\n    var user = gun.user();\n    Gun.log.off = true;  // Suppress all console logging\n\n    const throwOutUser = (wipeStorageData, done) => {\n      // Get rid of authenticated Gun user\n      var user = gun.back(-1)._.user;\n      // TODO: is this correct way to 'logout' user from Gun.User ?\n      [ 'alias', 'sea', 'pub' ].forEach(function(key){\n        delete user._[key];\n      });\n      user._.is = user.is = {};\n\n      if(wipeStorageData){\n        // ... and persisted session\n        sessionStorage.removeItem('remember');\n        sessionStorage.removeItem('alias');\n        if (typeof done === 'function') {\n          seaIndexedDb.wipe().then(done)\n          return\n        } else {\n          return seaIndexedDb.wipe()\n        }\n      }\n      return Promise.resolve()\n    }\n\n    const type = 'Promise'  // TODO: this is leftover...\n    // Simulate browser reload\n    beforeEach((done) => { throwOutUser(true, done) })\n\n    describe('create', function(){\n\n      it('new', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.have.keys([ 'ok', 'pub' ]);\n          }catch(e){ done(e); return }\n          done();\n        };\n        // Gun.user.create - creates new user\n        user.create(alias+type, pass).then(check).catch(done);\n      });\n\n      it('conflict', function(done){\n        Gun.log.off = true;  // Suppress all console logging\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.have.key('err');\n            expect(ack.err).not.to.be(undefined);\n            expect(ack.err).not.to.be('');\n            expect(ack.err.toLowerCase().indexOf('already created')).not.to.be(-1);\n          }catch(e){ done(e); return }\n          done();\n        };\n        // Gun.user.create - fails to create existing user\n        user.create(alias+type, pass).then(function(ack){\n          done('Failed to decline creating existing user!');\n        }).catch(check);\n      });\n    });\n\n    describe('auth', function(){\n      const checkStorage = (done, notStored) => () => {\n        const checkValue = (data, val) => {\n          if (notStored) {\n            expect(typeof data !== 'undefined' && data !== null && data !== '')\n            .to.not.eql(true)\n          } else {\n            expect(data).to.not.be(undefined)\n            expect(data).to.not.be('')\n            if (val) {\n              expect(data).to.eql(val)\n            }\n          }\n        }\n        const alias = root.sessionStorage.getItem('user')\n        checkValue(alias)\n        checkValue(root.sessionStorage.getItem('remember'))\n        if (alias) {\n          checkIndexedDB(alias, 'auth').then((auth) => {\n            checkValue(auth)\n            done()\n          }).catch(done)\n        } else {\n          done()\n        }\n      }\n\n      it('login', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.key('err');\n          }catch(e){ done(e); return }\n          done();\n        };\n        // Gun.user.auth - authenticates existing user\n        user.auth(alias+type, pass).then(check).catch(done);\n      });\n\n      it('wrong password', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.have.key('err');\n            expect(ack.err).to.not.be(undefined);\n            expect(ack.err).to.not.be('');\n            expect(ack.err.toLowerCase().indexOf('failed to decrypt secret'))\n            .not.to.be(-1);\n          }catch(e){ done(e); return }\n          done();\n        };\n        user.auth(alias+type, pass+'not').then(function(ack){\n          done('Unexpected login success!');\n        }).catch(check);\n      });\n\n      it('unknown alias', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.have.key('err');\n            expect(ack.err).to.not.be(undefined);\n            expect(ack.err).to.not.be('');\n            expect(ack.err.toLowerCase().indexOf('no user')).not.to.be(-1);\n          }catch(e){ done(e); return }\n          done();\n        };\n        user.auth(alias+type+'not', pass).then(function(ack){\n          done('Unexpected login success!');\n        }).catch(check);\n      });\n\n      it('new password', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.key('err');\n          }catch(e){ done(e); return }\n          done();\n        };\n        // Gun.user.auth - with newpass props sets new password\n        user.auth(alias+type, pass, {newpass: pass+' new'}).then(check)\n        .catch(done);\n      });\n\n      it('failed new password', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.have.key('err');\n            expect(ack.err).to.not.be(undefined);\n            expect(ack.err).to.not.be('');\n            expect(ack.err.toLowerCase().indexOf('failed to decrypt secret'))\n            .not.to.be(-1);\n          }catch(e){ done(e); return }\n          done();\n        };\n        user.auth(alias+type, pass+'not', {newpass: pass+' new'})\n        .then(function(ack){\n          done('Unexpected password change success!');\n        }).catch(check);\n      });\n\n      it('without PIN auth session stored', function(done){\n        user.auth(alias+type, pass+' new').then(checkStorage(done)).catch(done);\n      });\n\n      it('with PIN auth session stored', function(done){\n        user.auth(alias+type, pass+' new', { pin: 'PIN' })\n        .then(checkStorage(done)).catch(done)\n      })\n\n      it('without PIN and zero validity no auth session storing', function(done){\n        user.recall(0).then(function(){\n          user.auth(alias+type, pass+' new')\n          .then(checkStorage(done, true)).catch(done);\n        });\n      });\n\n      it('with PIN and zero validity no auth session storing', function(done){\n        user.recall(0).then(function(){\n          user.auth(alias+type, pass+' new', {pin: 'PIN'})\n          .then(checkStorage(done, true)).catch(done);\n        });\n      });\n    });\n\n    describe('leave', function(){\n      it('valid session', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.key('err');\n            expect(ack).to.have.key('ok');\n            expect(gun.back(-1)._.user._).to.not.have.keys([ 'sea', 'pub' ]);\n            // expect(gun.back(-1)._.user).to.not.be.ok();\n          }catch(e){ done(e); return }\n          done();\n        };\n        var usr = alias+type+'leave';\n        user.create(usr, pass).then(function(ack){\n          expect(ack).to.not.be(undefined);\n          expect(ack).to.not.be('');\n          expect(ack).to.have.keys([ 'ok', 'pub' ]);\n          user.auth(usr, pass).then(function(usr){\n            try{\n              expect(usr).to.not.be(undefined);\n              expect(usr).to.not.be('');\n              expect(usr).to.not.have.key('err');\n              expect(usr).to.have.key('put');\n            }catch(e){ done(e); return }\n            // Gun.user.leave - performs logout for authenticated user\n            user.leave().then(check).catch(done);\n          }).catch(done);\n        }).catch(done);\n      });\n\n      it('no session', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.key('err');\n            expect(ack).to.have.key('ok');\n          }catch(e){ done(e); return }\n          done();\n        };\n        expect(gun.back(-1)._.user).to.not.have.keys([ 'sea', 'pub' ]);\n        user.leave().then(check).catch(done);\n      });\n    });\n\n    describe('delete', function(){\n      var usr = alias+type+'del';\n\n      var createUser = function(a, p){\n        return user.create(a, p).then(function(ack){\n          expect(ack).to.not.be(undefined);\n          expect(ack).to.not.be('');\n          expect(ack).to.have.keys([ 'ok', 'pub' ]);\n          return ack;\n        });\n      };\n      var check = function(done){\n        return function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.key('err');\n            expect(ack).to.have.key('ok');\n            expect(gun.back(-1)._.user).to.not.have.keys([ 'sea', 'pub' ]);\n          }catch(e){ done(e); return }\n          done();\n        };\n      };\n\n      it('existing authenticated user', function(done){\n        createUser(usr, pass).then(function(){\n          user.auth(usr, pass).then(function(ack){\n            try{\n              expect(ack).to.not.be(undefined);\n              expect(ack).to.not.be('');\n              expect(ack).to.not.have.key('err');\n              expect(ack).to.have.key('put');\n            }catch(e){ done(e); return }\n            // Gun.user.delete - deletes existing user account\n            user.delete(usr, pass).then(check(done)).catch(done);\n          }).catch(done);\n        }).catch(done);\n      });\n\n      it('unauthenticated existing user', function(done){\n        createUser(usr, pass).catch(function(){})\n        .then(function(){\n          user.delete(usr, pass).then(check(done)).catch(done);\n        });\n      });\n\n      it('non-existing user', function(done){\n        var notFound = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.key('put');\n            expect(ack).to.have.key('err');\n            expect(ack.err.toLowerCase().indexOf('no user')).not.to.be(-1);\n          }catch(e){ done(e); return }\n          done();\n        };\n        user.delete('someone', 'password guess').then(function(){\n          done('Unexpectedly deleted guessed user!');\n        }).catch(notFound);\n      });\n    });\n\n    describe('recall (from IndexedDB)', function(){\n      var doCheck = function(done, hasPin, wantAck){\n        expect(typeof done).to.be('function');\n        return function(ack){\n          var user = root.sessionStorage.getItem('user');\n          var sRemember = root.sessionStorage.getItem('remember');\n          expect(user).to.not.be(undefined);\n          expect(user).to.not.be('');\n          expect(sRemember).to.not.be(undefined);\n          expect(sRemember).to.not.be('');\n\n          var ret;\n          if(wantAck && ack){\n            ['err', 'pub', 'sea', 'alias', 'put'].forEach(function(key){\n              if(typeof ack[key] !== 'undefined'){\n                (ret = ret || {})[key] = ack[key];\n              }\n            });\n          }\n          // NOTE: done can be Promise returning function\n          return !hasPin || !wantAck || !ack ? done(ret)\n          : new Promise(function(resolve){\n            checkIndexedDB(ack.alias, 'auth', function(auth){\n              expect(auth).to.not.be(undefined);\n              expect(auth).to.not.be('');\n              resolve(done(wantAck && Object.assign(ret || {}, {auth: auth})));\n            });\n          });\n        };\n      };\n      // This re-constructs 'remember-me' data modified by manipulate func\n      var manipulateStorage = function(manipulate, pin){\n        expect(typeof manipulate).to.be('function');\n        // We'll use Gun internal User data\n        var usr = gun.back(-1)._.user;\n        expect(usr).to.not.be(undefined);\n        expect(usr).to.have.key('_');\n        expect(usr._).to.have.keys(['pub', 'sea']);\n        // ... to validate 'remember' data\n        pin = pin && Buffer.from(pin, 'utf8').toString('base64');\n        return !pin ? Promise.resolve(sessionStorage.getItem('remember'))\n        : new Promise(function(resolve){\n          checkIndexedDB(usr._.alias, 'auth', resolve);\n        }).then(function(remember){\n          return SEA.read(remember, usr._.pub).then(function(props){\n            return !pin ? props\n            : SEA.dec(props, pin);\n          });\n        }).then(function(props){\n          try{ props && (props = JSON.parse(props)) }catch(e){} //eslint-disable-line no-empty\n          return props;\n        }).then(manipulate).then(function(props){\n          expect(props).to.not.be(undefined);\n          expect(props).to.not.be('');\n          var keys = {pub: usr._.pub, priv: usr._.sea.priv};\n          return SEA.write(JSON.stringify(props), keys)\n          .then(function(remember){\n            return !pin ? sessionStorage.setItem('remember', remember)\n            : SEA.enc(remember, pin).then(function(encauth){\n              return new Promise(function(resolve){\n                setIndexedDB(usr._.alias, encauth, resolve);\n              });\n            });\n          });\n        });\n      };\n\n      it('with PIN auth session stores', function(done){\n        var doAction = function(){\n          user.auth(alias+type, pass+' new', {pin: 'PIN'})\n          .then(doCheck(done, true)).catch(done);\n        };\n        user.recall().then(doAction).catch(done);\n      });\n\n      it('without PIN auth session stores', function(done){\n        var doAction = function(){\n          user.auth(alias+type, pass+' new').then(doCheck(done));\n        };\n        user.leave().then(function(){\n          user.recall().then(doAction).catch(done);\n        }).catch(done);\n      });\n\n      it('no validity no session storing', function(done){\n        var doAction = function(){\n          user.auth(alias+type, pass+' new').then(doCheck(done)).catch(done);\n        };\n        user.recall(0).then(doAction).catch(done);\n      });\n\n      it('with validity but no PIN stores using random PIN', function(done){\n        var doAction = function(){\n          user.auth(alias+type, pass+' new').then(doCheck(done)).catch(done);\n        };\n        user.recall(12 * 60).then(doAction)\n        .catch(done);\n      });\n\n      it('validity and auth with PIN but storage empty', function(done){\n        user.auth(alias+type, pass+' new').then(function(usr){\n          var sUser;\n          var sRemember;\n          try{\n            expect(usr).to.not.be(undefined);\n            expect(usr).to.not.be('');\n            expect(usr).to.not.have.key('err');\n            expect(usr).to.have.key('put');\n\n            sUser = root.sessionStorage.getItem('user');\n            expect(sUser).to.be(alias+type);\n\n            sRemember = root.sessionStorage.getItem('remember');\n            expect(sRemember).to.not.be(undefined);\n            expect(sRemember).to.not.be('');\n          }catch(e){ done(e); return }\n          user.leave().then(function(ack){\n            try{\n              expect(ack).to.have.key('ok');\n              expect(gun.back(-1)._.user).to.not.have.keys([ 'sea', 'pub' ]);\n              expect(root.sessionStorage.getItem('user')).to.not.be(sUser);\n              expect(root.sessionStorage.getItem('remember')).to.not.be(sRemember);\n            }catch(e){ done(e); return }\n            // Restore but leave IndexedDB empty\n            root.sessionStorage.setItem('user', sUser);\n            root.sessionStorage.setItem('remember', sRemember);\n\n            user.recall(12 * 60).then(\n              doCheck(function(ack){\n                expect(ack).to.have.key('err');\n                expect(ack.err.toLowerCase().indexOf('no session')).to.not.be(-1);\n                  checkIndexedDB(alias+type, 'auth', function(auth){\n                    expect((typeof auth !== 'undefined' && auth !== null && auth !== ''))\n                    .to.not.eql(true);\n                    done();\n                  });\n              }, false, true))\n            .catch(done);\n          }).catch(done);\n        }).catch(done);\n      });\n\n      it('valid session bootstrap', function(done){\n        var sUser;\n        var sRemember;\n        var iAuth;\n        user.auth(alias+type, pass+' new', {pin: 'PIN'}).then(function(usr){\n          try{\n            expect(usr).to.not.be(undefined);\n            expect(usr).to.not.be('');\n            expect(usr).to.not.have.key('err');\n            expect(usr).to.have.key('put');\n            expect(root.sessionStorage.getItem('user')).to.be(alias+type);\n            expect(root.sessionStorage.getItem('remember')).to.not.be(undefined);\n            expect(root.sessionStorage.getItem('remember')).to.not.be('');\n\n            sUser = root.sessionStorage.getItem('user');\n            sRemember = root.sessionStorage.getItem('remember');\n          }catch(e){ done(e); return }\n\n          return new Promise(function(resolve){\n            checkIndexedDB(sUser, 'auth', function(auth){ resolve(iAuth = auth) });\n          });\n        }).then(function(){\n          return user.leave().then(function(ack){\n            try{\n              expect(ack).to.have.key('ok');\n              expect(gun.back(-1)._.user).to.not.have.keys([ 'sea', 'pub' ]);\n              expect(root.sessionStorage.getItem('user')).to.not.be(sUser);\n              expect(root.sessionStorage.getItem('remember')).to.not.be(sRemember);\n            }catch(e){ done(e); return }\n\n            return new Promise(function(resolve){\n              checkIndexedDB(sUser, 'auth', function(auth){\n                expect(auth).to.not.be(iAuth);\n                resolve();\n              });\n            });\n          }).then(function(){\n            root.sessionStorage.setItem('user', sUser);\n            root.sessionStorage.setItem('remember', sRemember);\n\n            return new Promise(function(resolve){\n              setIndexedDB(sUser, iAuth, resolve);\n            });\n          }).then(function(){\n            user.recall(12 * 60).then(doCheck(done))\n            .catch(done);\n          }).catch(done);\n        }).catch(done);\n      });\n\n      it('valid session bootstrap using alias & PIN', function(done){\n        let sRemember\n        user.recall(12 * 60).then(function(){\n          return user.auth(alias+type, pass+' new', {pin: 'PIN'});\n        }).then(doCheck(function(ack){\n          // Let's save remember props\n          var sUser = root.sessionStorage.getItem('user');\n          sRemember = root.sessionStorage.getItem('remember')\n          var iAuth = ack.auth;\n          return new Promise(function(resolve){\n            checkIndexedDB(sUser, 'auth', function(auth){\n              iAuth = auth;\n              resolve(user.leave());  // Then logout user\n            });\n          }).then(function(ack){\n            try{\n              expect(ack).to.have.key('ok');\n              expect(gun.back(-1)._.user).to.not.have.keys([ 'sea', 'pub' ]);\n              expect(root.sessionStorage.getItem('user')).to.not.be(sUser);\n              expect(root.sessionStorage.getItem('remember')).to.not.be(sRemember);\n            }catch(e){ done(e); return }\n            return new Promise(function(resolve){\n              checkIndexedDB(sUser, 'auth', function(auth){\n                try{ expect(auth).to.not.be(iAuth) }catch(e){ done(e) }\n                // Then restore IndexedDB but skip sessionStorage remember\n                setIndexedDB(sUser, iAuth, function(){\n                  root.sessionStorage.setItem('user', sUser);\n                  resolve(ack);\n                });\n              });\n            });\n          });\n        }, true, true)).then(function(){\n          // Then try to recall authentication\n          return user.recall(12 * 60).then(function(props){\n            try{\n              expect(props).to.not.be(undefined);\n              expect(props).to.not.be('');\n              expect(props).to.have.key('err');\n              // Which fails to missing PIN\n              expect(props.err.toLowerCase()\n              .indexOf('missing pin')).not.to.be(-1);\n            }catch(e){ done(e); return }\n            root.sessionStorage.setItem('remember', sRemember)\n            // Ok, time to try auth with alias & PIN\n            return user.auth(alias+type, undefined, {pin: 'PIN'});\n          });\n        }).then(doCheck(function(usr){\n          try{\n            expect(usr).to.not.be(undefined);\n            expect(usr).to.not.be('');\n            expect(usr).to.not.have.key('err');\n            expect(usr).to.have.key('put');\n          }catch(e){ done(e); return }\n          // We've recalled authenticated session using alias & PIN!\n          done();\n        }, true, true)).catch(done);\n      });\n\n      it('valid session fails to bootstrap with alias & wrong PIN',\n      function(done){\n        user.recall(12 * 60).then(function(){\n          return user.auth(alias+type, pass+' new', {pin: 'PIN'});\n        }).then(doCheck(function(ack){\n          var sUser = root.sessionStorage.getItem('user');\n          var sRemember = root.sessionStorage.getItem('remember');\n          var iAuth = ack.auth;\n          return new Promise(function(resolve){\n            checkIndexedDB(sUser, 'auth', function(auth){\n              iAuth = auth;\n              resolve(user.leave());  // Then logout user\n            });\n          }).then(function(ack){\n            try{\n              expect(ack).to.have.key('ok');\n              expect(gun.back(-1)._.user).to.not.have.keys([ 'sea', 'pub' ]);\n              expect(root.sessionStorage.getItem('user')).to.not.be(sUser);\n              expect(root.sessionStorage.getItem('remember')).to.not.be(sRemember);\n            }catch(e){ done(e); return }\n            return new Promise(function(resolve){\n              checkIndexedDB(sUser, 'auth', function(auth){\n                try{ expect(auth).to.not.be(iAuth) }catch(e){ done(e) }\n                // Then restore IndexedDB auth data, skip sessionStorage\n                setIndexedDB(sUser, iAuth, function(){\n                  root.sessionStorage.setItem('user', sUser);\n                  resolve(ack);\n                });\n              });\n            });\n          });\n        }, true, true)).then(function(){\n            // Ok, time to try auth with alias & PIN\n            return user.auth(alias+type, undefined, {pin: 'PiN'});\n        }).then(function(){\n          done('Unexpected login success!');\n        }).catch(function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.have.key('err');\n            expect(ack.err.toLowerCase()\n            .indexOf('no session data for alias & pin')).not.to.be(-1);\n          }catch(e){ done(e); return }\n          // We've recalled authenticated session using alias & PIN!\n          done();\n        });\n      });\n\n      it('expired session fails to bootstrap', function(done){\n        var pin = 'PIN';\n        user.recall(60).then(function(){\n          return user.auth(alias+type, pass+' new', {pin: pin});\n        }).then(doCheck(function(){\n          // Storage data OK, let's back up time of auth to exp + 65 seconds\n          return manipulateStorage(function(props){\n            var ret = Object.assign({}, props, {iat: props.iat - 65 - props.exp});\n            return ret;\n          }, pin);\n        })).then(() => throwOutUser(false)) // Simulate browser reload\n        .then(() => user.recall(60).then((ack) => {\n          expect(ack).to.not.be(undefined)\n          expect(ack).to.not.be('')\n          expect(ack).to.not.have.keys([ 'pub', 'sea' ])\n          expect(ack).to.have.key('err')\n          expect(ack.err).to.not.be(undefined)\n          expect(ack.err).to.not.be('')\n          expect(ack.err.toLowerCase()\n          .indexOf('no session')).not.to.be(-1)\n          done()\n        })).catch(done)\n      });\n\n      it('changed password', function(done){\n        var pin = 'PIN';\n        var sUser;\n        var sRemember;\n        var iAuth;\n        user.recall(60).then(function(){\n          return user.auth(alias+type, pass+' new', {pin: pin});\n        }).then(function(usr){\n          try{\n            expect(usr).to.not.be(undefined);\n            expect(usr).to.not.be('');\n            expect(usr).to.not.have.key('err');\n            expect(usr).to.have.key('put');\n\n            sUser = root.sessionStorage.getItem('user');\n            expect(sUser).to.be(alias+type);\n\n            sRemember = root.sessionStorage.getItem('remember');\n            expect(sRemember).to.not.be(undefined);\n            expect(sRemember).to.not.be('');\n          }catch(e){ done(e); return }\n\n          return new Promise(function(resolve){\n            checkIndexedDB(sUser, 'auth', function(auth){ resolve(iAuth = auth) });\n          });\n        }).then(function(){\n          return user.leave().then(function(ack){\n            try{ expect(ack).to.have.key('ok') }catch(e){ done(e); return }\n\n            return user.auth(alias+type, pass+' new', {newpass: pass, pin: pin})\n            .then(function(usr){ expect(usr).to.not.have.key('err') });\n          }).then(() => user.leave().then((ack) => {\n            try {\n              expect(ack).to.have.key('ok')\n            } catch (e) { done(e); return }\n            return throwOutUser(false)\n          })).then(function(){\n            // Simulate browser reload\n            // Call back pre-update remember...\n            root.sessionStorage.setItem('user', sUser);\n            root.sessionStorage.setItem('remember', sRemember);\n            // ... and IndexedDB auth\n            return new Promise(function(resolve){\n              setIndexedDB(sUser, iAuth, resolve);\n            });\n          }).then(function(){\n            user.recall(60).then(function(props){\n              expect(props).to.not.be(undefined);\n              expect(props).to.not.be('');\n              expect(props).to.have.key('err');\n              expect(props.err).to.not.be(undefined);\n              expect(props.err).to.not.be('');\n              expect(props.err.toLowerCase()\n              .indexOf('failed to decrypt')).not.to.be(-1);\n              done();\n            }).catch(done);\n          }).catch(done);\n        }).catch(done);\n      });\n\n      it('recall hook session manipulation', function(done){\n        var pin = 'PIN';\n        var exp;\n        var hookFunc = function(props){\n          exp = props.exp * 2;  // Doubles session expiration time\n          var ret = Object.assign({}, props, {exp: exp});\n          return new Promise(function(resolve){\n            resolve(ret); // Both callback & Promise methods here\n          });\n        };\n        user.recall(60, {hook: hookFunc}).then(function(){\n          return user.auth(alias+type, pass, {pin: pin});\n        }).then(function(){\n          return manipulateStorage(function(props){\n            expect(props).to.not.be(undefined);\n            expect(props).to.have.key('exp');\n            expect(props.exp).to.be(exp);\n            return props;\n          }, pin);\n        }).then(done).catch(done);\n      });\n    });\n\n    describe('alive', function(){\n      it('valid session', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.key('err');\n            expect(ack).to.have.keys([ 'sea', 'pub' ]);\n          }catch(e){ done(e); return }\n          done();\n        };\n        var aliveUser = alias+type+'alive';\n        user.create(aliveUser, pass).then(function(ack){\n          expect(ack).to.not.be(undefined);\n          expect(ack).to.not.be('');\n          expect(ack).to.have.keys([ 'ok', 'pub' ]);\n          user.auth(aliveUser, pass, {pin: 'PIN'}).then(function(usr){\n            try{\n              expect(usr).to.not.be(undefined);\n              expect(usr).to.not.be('');\n              expect(usr).to.not.have.key('err');\n              expect(usr).to.have.key('put');\n            }catch(e){ done(e); return }\n            // Gun.user.alive - keeps/checks User authentication state\n            user.alive().then(check).catch(done);\n          }).catch(done);\n        }).catch(done);\n      });\n\n      it('expired session', function(done){\n        var check = function(ack){\n          try{\n            expect(ack).to.not.be(undefined);\n            expect(ack).to.not.be('');\n            expect(ack).to.not.have.keys([ 'sea', 'pub' ]);\n            expect(ack).to.have.key('err');\n            expect(ack.err.toLowerCase().indexOf('no session')).not.to.be(-1);\n          }catch(e){ done(e); return }\n          done();\n        };\n        user.leave().catch(function(){}).then(function(){\n          user.alive().then(function(){\n            done('Unexpected alive session!');\n          }).catch(check);\n        }).catch(done);\n      });\n    });\n\n    process.env.SEA_CHANNEL && describe('User channel', function(){\n      it.skip('create');\n      it.skip('add member');\n    });\n\n    Gun.log.off = false;\n  });\n});\n\n}());\n"
  },
  {
    "path": "test/server/http.js",
    "content": "//client.js writes data up to a listening hub.js, which relays to a server.js that reads the data.\n\nvar http = require('http');\n\nvar Gun = require('../../index');\nvar gun = Gun({ \n\tfile: 'http.json'\n});\n\n\nvar server = http.createServer(function(req, res){});\ngun.wsp(server);\nserver.listen(8765);\n\nconsole.log('Server started on port ' + 8765 + ' with /gun');"
  },
  {
    "path": "test/server/node-client.js",
    "content": "var Gun = require('../../index');\n\nvar location = {host:\"localhost\"};\n\nvar gun = Gun( { file: 'read.json', peers: ['http://' + location.host + ':8765/gun'] });\n\ngun.get( 'data' ).path('stuff').map(function(val,field){ console.log( field, \"=\", val ); } );\n\nconsole.log( \"done... wait forever?\" );"
  },
  {
    "path": "test/server/node-write.js",
    "content": "var Gun = require('../../index');\n\nvar location = {host:\"localhost\"};\n\nvar gun = Gun( { file: 'write.json', peers: ['http://' + location.host + ':8765/gun'] });\n\ngun.get( 'data' ).path('stuff').put({a: {data: 1}, b: {data: 2}});"
  },
  {
    "path": "test/tmp/bigsync.js",
    "content": "var Gun = require('../../');\n\n/*var data = '';\nvar a = [], b = Gun.text.random(1000 * 1000 * 10), c;\nfor(var i = 0; i <= 7; i++){\n\tdata += b;\n}\n*/\ndata = 1;\n\nvar gun = Gun('http://localhost:8765/gun');\n//var gun = Gun();\n\nsetTimeout(function(){\n\t\n\t/*console.log(\"READ!\");\n\tgun.get('bigsync').get('raw').on(function(a,b){\n\t\tconsole.log('yay!', b, (a && a.slice && a.slice(0,20)) || a, a.length);\n\t});\n\treturn;*/\n\tconsole.log(\"SEND!\");\n\tgun.get('bigsync').get('raw').put(data, function(ack){console.log(ack)});\n\n\t/*var req = require('http').request({\n\t\thost: 'localhost'\n\t\t,port: '8080'\n\t\t,method: 'POST'\n\t}, function(res){\n\t\tconsole.log(\"GOT REPLY!\", res);\n\t\tres.on('data', function(chunk){\n\t\t\tconsole.log(\"!!!\", chunk);\n\t\t});\n\t\tres.on('error', function(err){\n\t\t\tconsole.log(\"ERROR\", err);\n\t\t})\n\t});\n\treq.write(data);\n\treq.end();*/\n}, 1000);"
  },
  {
    "path": "test/tmp/contact.html",
    "content": "<h1>PM</h1>\n\n<form id=\"sign\">\n  <input id=\"alias\" placeholder=\"username\">\n  <input id=\"pass\" type=\"password\" placeholder=\"passphrase\">\n  <input id=\"in\" type=\"submit\" value=\"sign in\">\n  <input id=\"up\" type=\"button\" value=\"sign up\">\n</form>\n\n<ul id=\"chats\"></ul>\n\n<form id=\"talk\" style=\"display: none;\">\n    To: <input id=\"to\" placeholder=\"public key\"> <b id=\"who\"></b><br/>\n    <input id=\"what\" placeholder=\"private message\">\n    <input id=\"send\" type=\"submit\" value=\"send\">\n    <p>Your public key:<br/><i id=\"pub\"></i></p>\n</form>\n\n<script src=\"../../examples/jquery.js\"></script>\n<script src=\"../../gun.js\"></script>\n<script src=\"../../sea.js\"></script>\n\n<script>\n/*\n  This is an early preview of a simple private messaging app.\n  Every possible UI/UX feature is left out, meaning you have\n  to manually copy&paste the public keys to send messages.\n\n  Note: This example app does not hide who you are talking to.\n  It does not hide when or the frequency of who you talk to.\n  Only the messages themselves are private between people.\n\n  This app does not order the messages, a real app would.\n*/\n//var gun = Gun();\nvar gun = Gun('http://localhost:8080/gun');\nvar user = gun.user();\n\n$('#up').on('click', function(){\n  user.create($('#alias').val(), $('#pass').val(), login);\n});\n\n$('#sign').on('submit', login);\nfunction login(){\n  user.auth($('#alias').val(), $('#pass').val());\n  return false;\n};\n\ngun.on('auth', async function(){\n  $('#sign').hide();\n\t$('#talk').show();\n  var pub = user.pair().pub;\n\t$('#pub').text(pub);\n});\n\n$('#to').on('blur', async function(){\n  if(!user.is){ return } // need to log in!\n  var pub = ($('#to').val()||'').trim();\n  if(!pub){ return }\n  var to = gun.user(pub);\n  var who = await to.then() || {};\n  $('#who').text(who.alias || \"User not found.\");\n  if(!who.alias){ return }\n  UI.dec = await Gun.SEA.secret(who.epub, user.pair());\n  user.get('chat').get(pub).map().once(UI);\n  to.get('chat').get(user.pair().pub).map().once(UI);\n});\n\n$('#talk').on('submit', async function(e){\n  e.preventDefault();\n  if(!user.is){ return } // need to log in!\n  var what = $('#what').val();\n  if(!what){ return }\n  var pub = ($('#to').val()||'').trim();\n  var who = await gun.user(pub).then();\n  var sec = await Gun.SEA.secret(who.epub, user.pair());\n  var enc = await Gun.SEA.encrypt(what, sec);\n  user.get('chat').get(pub).set(enc);\n  $('#what').val(\"\");\n});\n\nasync function UI(say, id){\n  say = await Gun.SEA.decrypt(say, UI.dec);\n  var li = $('#' + id).get(0) || $('<li>').attr('id', id).appendTo('ul');\n  $(li).text(say);\n};\n</script>"
  },
  {
    "path": "test/tmp/contacts.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t\t<script src=\"../../../gun/gun.js\"></script>\n\t\t<script src=\"../../../gun/examples/jquery.js\"></script>\n\t\t<script src=\"../../../gun/lib/radix.js\"></script>\n\t\t<script src=\"../../../gun/lib/radisk.js\"></script>\n\t\t<script src=\"../../../gun/lib/store.js\"></script>\n\t\t<script src=\"../../../gun/lib/rindexed.js\"></script>\n\t</head>\n\t<body>\n\t\t<button id=\"make\">make contacts</button>\n\t\t<input id=\"find\" placeholder=\"find contacts...\">\n\t\t<ul>\n\t\t</ul>\n\t\t<div id='debug'></div>\n\t\t<script>\n\t\t\t//try{localStorage.clear()}catch(e){};\n\t\t\t//indexedDB.deleteDatabase('radata');\n\t\t\t//var gun = Gun('http://localhost:8765/gun');\n\t\t\tvar gun = Gun({localStorage: false});\n\n\t\t\t$('#make').on('click', function(){\n\t\t\t\tvar all = {}, to, start, cbs = 0;\n\t\t\t\t$('ul').text('saving ' + names.length); start = Gun.state();\n\t\t\t\tnames.forEach(function(val, i){\n\t\t\t\t\tall[++i] = true;\n\t\t\t\t\t//console.log(val);\n\t\t\t\t\t//console.log(++cbs);\n\t\t\t\t\tgun.get('names').get(val.toLowerCase()).put({\n\t\t\t\t\t\tname: val,\n\t\t\t\t\t\tage: Math.abs(Math.floor(Math.random() * 100 - 30))\n\t\t\t\t\t}, function(ack){\n\t\t\t\t\t\tif(ack.err){ return console.log(i, val, ack.err) }\n\t\t\t\t\t\tdelete all[i];\n\t\t\t\t\t\tclearTimeout(to);\n\t\t\t\t\t\tto = setTimeout(function(){\n\t\t\t\t\t\t\t//console.log(\"!!!\", cbs, Object.keys(all).length);\n\t\t\t\t\t\t\tif(!Gun.obj.empty(all)){ return }\n\t\t\t\t\t\t\t$('ul').text('in '+ (((Gun.state() - 9) - start)/1000) +' seconds.');\n\t\t\t\t\t\t},9)\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\tconsole.log(\"end forEach:\", (+new Date) - start);\n\t\t\t});\n\n\t\t\tvar to;\n\t\t\t$('#find').on('keyup', function(){\n\t\t\t\tclearTimeout(to);\n\t\t\t\tto = setTimeout(function(){\n\t\t\t\t\tvar s = $('#find').val(), tmp;\n\t\t\t\t\tif(!s){ return }\n\t\t\t\t\ts = s.toLowerCase();\n\t\t\t\t\tvar start = Gun.state();\n\t\t\t\t\t/*\n\t\t\t\t\tgun.get('names').get({'.': {'*': s}, '%': 1000 * 10}).on(function(data){\n\t\t\t\t\t\tconsole.log('speed:', (Gun.state() - start)/1000, data);\n\t\t\t\t\t});\n\t\t\t\t\treturn;*/\n\t\t\t\t\tconsole.log(\"GET\", s);\n\t\t\t\t\tgun.get('names').get({'.': {'*': s}, '%': 2000, T: start}).once().map().once(function(data){\n\t\t\t\t\t\t//console.log(\"???\", tmp, data);\n\t\t\t\t\t\tif(!tmp){ tmp = $('ul').html(\"\") }\n\t\t\t\t\t\tif(!data){ tmp.append(\"Not Found.\"); return }\n\t\t\t\t\t\tvar dn = btoa(data.name).replace(/\\W/ig, '');\n\t\t\t\t\t\tif($('#'+dn).length){ return }\n\t\t\t    \t//tmp.append($('<li>').attr('id', dn).append($('<b>').text(data.name))).append(': ').append($('<i>').text(data.age)));\n\t\t\t\t\t\ttmp.append($('<li>').attr('id', dn).append($('<b>').text(data.name)).append(': ').append($('<i>').text(data.age)));\n\t\t\t\t\t});\n\t\t\t\t}, 300);\n\t\t\t\t//gun.get('names').off();\n\t\t\t})\n\nvar names = [\n\"Aaberg\"\n,\n\"Aalst\"\n,\n\"Aara\"\n,\n\"Aaren\"\n,\n\"Aarika\"\n,\n\"Aaron\"\n,\n\"Aaronson\"\n,\n\"Ab\"\n,\n\"Aba\"\n,\n\"Abad\"\n,\n\"Abagael\"\n,\n\"Abagail\"\n,\n\"Abana\"\n,\n\"Abate\"\n,\n\"Abba\"\n,\n\"Abbate\"\n,\n\"Abbe\"\n,\n\"Abbey\"\n,\n\"Abbi\"\n,\n\"Abbie\"\n,\n\"Abbot\"\n,\n\"Abbotsen\"\n,\n\"Abbotson\"\n,\n\"Abbotsun\"\n,\n\"Abbott\"\n,\n\"Abbottson\"\n,\n\"Abby\"\n,\n\"Abbye\"\n,\n\"Abdel\"\n,\n\"Abdella\"\n,\n\"Abdu\"\n,\n\"Abdul\"\n,\n\"Abdulla\"\n,\n\"Abe\"\n,\n\"Abebi\"\n,\n\"Abel\"\n,\n\"Abelard\"\n,\n\"Abell\"\n,\n\"Abercromby\"\n,\n\"Abernathy\"\n,\n\"Abernon\"\n,\n\"Abert\"\n,\n\"Abeu\"\n,\n\"Abey\"\n,\n\"Abie\"\n,\n\"Abigael\"\n,\n\"Abigail\"\n,\n\"Abigale\"\n,\n\"Abijah\"\n,\n\"Abisha\"\n,\n\"Abisia\"\n,\n\"Abixah\"\n,\n\"Abner\"\n,\n\"Aborn\"\n,\n\"Abott\"\n,\n\"Abra\"\n,\n\"Abraham\"\n,\n\"Abrahams\"\n,\n\"Abrahamsen\"\n,\n\"Abrahan\"\n,\n\"Abram\"\n,\n\"Abramo\"\n,\n\"Abrams\"\n,\n\"Abramson\"\n,\n\"Abran\"\n,\n\"Abroms\"\n,\n\"Absa\"\n,\n\"Absalom\"\n,\n\"Abshier\"\n,\n\"Acacia\"\n,\n\"Acalia\"\n,\n\"Accalia\"\n,\n\"Ace\"\n,\n\"Acey\"\n,\n\"Acherman\"\n,\n\"Achilles\"\n,\n\"Achorn\"\n,\n\"Acie\"\n,\n\"Acima\"\n,\n\"Acker\"\n,\n\"Ackerley\"\n,\n\"Ackerman\"\n,\n\"Ackler\"\n,\n\"Ackley\"\n,\n\"Acquah\"\n,\n\"Acus\"\n,\n\"Ad\"\n,\n\"Ada\"\n,\n\"Adabel\"\n,\n\"Adabelle\"\n,\n\"Adachi\"\n,\n\"Adah\"\n,\n\"Adaha\"\n,\n\"Adai\"\n,\n\"Adaiha\"\n,\n\"Adair\"\n,\n\"Adal\"\n,\n\"Adala\"\n,\n\"Adalai\"\n,\n\"Adalard\"\n,\n\"Adalbert\"\n,\n\"Adalheid\"\n,\n\"Adali\"\n,\n\"Adalia\"\n,\n\"Adaliah\"\n,\n\"Adalie\"\n,\n\"Adaline\"\n,\n\"Adall\"\n,\n\"Adallard\"\n,\n\"Adam\"\n,\n\"Adama\"\n,\n\"Adamec\"\n,\n\"Adamek\"\n,\n\"Adamik\"\n,\n\"Adamina\"\n,\n\"Adaminah\"\n,\n\"Adamis\"\n,\n\"Adamo\"\n,\n\"Adamok\"\n,\n\"Adams\"\n,\n\"Adamsen\"\n,\n\"Adamski\"\n,\n\"Adamson\"\n,\n\"Adamsun\"\n,\n\"Adan\"\n,\n\"Adao\"\n,\n\"Adar\"\n,\n\"Adara\"\n,\n\"Adaurd\"\n,\n\"Aday\"\n,\n\"Adda\"\n,\n\"Addam\"\n,\n\"Addi\"\n,\n\"Addia\"\n,\n\"Addie\"\n,\n\"Addiego\"\n,\n\"Addiel\"\n,\n\"Addis\"\n,\n\"Addison\"\n,\n\"Addy\"\n,\n\"Ade\"\n,\n\"Adebayo\"\n,\n\"Adel\"\n,\n\"Adela\"\n,\n\"Adelaida\"\n,\n\"Adelaide\"\n,\n\"Adelaja\"\n,\n\"Adelbert\"\n,\n\"Adele\"\n,\n\"Adelheid\"\n,\n\"Adelia\"\n,\n\"Adelice\"\n,\n\"Adelina\"\n,\n\"Adelind\"\n,\n\"Adeline\"\n,\n\"Adella\"\n,\n\"Adelle\"\n,\n\"Adelpho\"\n,\n\"Adelric\"\n,\n\"Adena\"\n,\n\"Ader\"\n,\n\"Adest\"\n,\n\"Adey\"\n,\n\"Adham\"\n,\n\"Adhamh\"\n,\n\"Adhern\"\n,\n\"Adi\"\n,\n\"Adiana\"\n,\n\"Adiel\"\n,\n\"Adiell\"\n,\n\"Adigun\"\n,\n\"Adila\"\n,\n\"Adim\"\n,\n\"Adin\"\n,\n\"Adina\"\n,\n\"Adine\"\n,\n\"Adis\"\n,\n\"Adkins\"\n,\n\"Adlai\"\n,\n\"Adlar\"\n,\n\"Adlare\"\n,\n\"Adlay\"\n,\n\"Adlee\"\n,\n\"Adlei\"\n,\n\"Adler\"\n,\n\"Adley\"\n,\n\"Adna\"\n,\n\"Adnah\"\n,\n\"Adne\"\n,\n\"Adnopoz\"\n,\n\"Ado\"\n,\n\"Adolf\"\n,\n\"Adolfo\"\n,\n\"Adolph\"\n,\n\"Adolphe\"\n,\n\"Adolpho\"\n,\n\"Adolphus\"\n,\n\"Adon\"\n,\n\"Adonis\"\n,\n\"Adora\"\n,\n\"Adore\"\n,\n\"Adoree\"\n,\n\"Adorl\"\n,\n\"Adorne\"\n,\n\"Adrea\"\n,\n\"Adrell\"\n,\n\"Adria\"\n,\n\"Adriaens\"\n,\n\"Adrial\"\n,\n\"Adrian\"\n,\n\"Adriana\"\n,\n\"Adriane\"\n,\n\"Adrianna\"\n,\n\"Adrianne\"\n,\n\"Adriano\"\n,\n\"Adriel\"\n,\n\"Adriell\"\n,\n\"Adrien\"\n,\n\"Adriena\"\n,\n\"Adriene\"\n,\n\"Adrienne\"\n,\n\"Adur\"\n,\n\"Aekerly\"\n,\n\"Aelber\"\n,\n\"Aenea\"\n,\n\"Aeneas\"\n,\n\"Aeneus\"\n,\n\"Aeniah\"\n,\n\"Aenneea\"\n,\n\"Aeriel\"\n,\n\"Aeriela\"\n,\n\"Aeriell\"\n,\n\"Affer\"\n,\n\"Affra\"\n,\n\"Affrica\"\n,\n\"Afra\"\n,\n\"Africa\"\n,\n\"Africah\"\n,\n\"Afrika\"\n,\n\"Afrikah\"\n,\n\"Afton\"\n,\n\"Ag\"\n,\n\"Agace\"\n,\n\"Agamemnon\"\n,\n\"Agan\"\n,\n\"Agata\"\n,\n\"Agate\"\n,\n\"Agatha\"\n,\n\"Agathe\"\n,\n\"Agathy\"\n,\n\"Agbogla\"\n,\n\"Agee\"\n,\n\"Aggappe\"\n,\n\"Aggappera\"\n,\n\"Aggappora\"\n,\n\"Aggarwal\"\n,\n\"Aggi\"\n,\n\"Aggie\"\n,\n\"Aggri\"\n,\n\"Aggy\"\n,\n\"Agle\"\n,\n\"Agler\"\n,\n\"Agna\"\n,\n\"Agnella\"\n,\n\"Agnes\"\n,\n\"Agnese\"\n,\n\"Agnesse\"\n,\n\"Agneta\"\n,\n\"Agnew\"\n,\n\"Agnola\"\n,\n\"Agostino\"\n,\n\"Agosto\"\n,\n\"Agretha\"\n,\n\"Agripina\"\n,\n\"Agrippina\"\n,\n\"Aguayo\"\n,\n\"Agueda\"\n,\n\"Aguie\"\n,\n\"Aguste\"\n,\n\"Agustin\"\n,\n\"Ahab\"\n,\n\"Aharon\"\n,\n\"Ahasuerus\"\n,\n\"Ahders\"\n,\n\"Ahearn\"\n,\n\"Ahern\"\n,\n\"Ahl\"\n,\n\"Ahlgren\"\n,\n\"Ahmad\"\n,\n\"Ahmar\"\n,\n\"Ahmed\"\n,\n\"Ahola\"\n,\n\"Aholah\"\n,\n\"Aholla\"\n,\n\"Ahoufe\"\n,\n\"Ahouh\"\n,\n\"Ahrendt\"\n,\n\"Ahrens\"\n,\n\"Ahron\"\n,\n\"Aia\"\n,\n\"Aida\"\n,\n\"Aidan\"\n,\n\"Aiden\"\n,\n\"Aiello\"\n,\n\"Aigneis\"\n,\n\"Aiken\"\n,\n\"Aila\"\n,\n\"Ailbert\"\n,\n\"Aile\"\n,\n\"Ailee\"\n,\n\"Aileen\"\n,\n\"Ailene\"\n,\n\"Ailey\"\n,\n\"Aili\"\n,\n\"Ailin\"\n,\n\"Ailina\"\n,\n\"Ailis\"\n,\n\"Ailsa\"\n,\n\"Ailssa\"\n,\n\"Ailsun\"\n,\n\"Ailyn\"\n,\n\"Aime\"\n,\n\"Aimee\"\n,\n\"Aimil\"\n,\n\"Aimo\"\n,\n\"Aindrea\"\n,\n\"Ainslee\"\n,\n\"Ainsley\"\n,\n\"Ainslie\"\n,\n\"Ainsworth\"\n,\n\"Airel\"\n,\n\"Aires\"\n,\n\"Airla\"\n,\n\"Airlee\"\n,\n\"Airlia\"\n,\n\"Airliah\"\n,\n\"Airlie\"\n,\n\"Aisha\"\n,\n\"Ajani\"\n,\n\"Ajax\"\n,\n\"Ajay\"\n,\n\"Ajit\"\n,\n\"Akanke\"\n,\n\"Akel\"\n,\n\"Akela\"\n,\n\"Aker\"\n,\n\"Akerboom\"\n,\n\"Akerley\"\n,\n\"Akers\"\n,\n\"Akeyla\"\n,\n\"Akeylah\"\n,\n\"Akili\"\n,\n\"Akim\"\n,\n\"Akin\"\n,\n\"Akins\"\n,\n\"Akira\"\n,\n\"Aklog\"\n,\n\"Aksel\"\n,\n\"Aksoyn\"\n,\n\"Al\"\n,\n\"Alabaster\"\n,\n\"Alage\"\n,\n\"Alain\"\n,\n\"Alaine\"\n,\n\"Alair\"\n,\n\"Alake\"\n,\n\"Alameda\"\n,\n\"Alan\"\n,\n\"Alana\"\n,\n\"Alanah\"\n,\n\"Aland\"\n,\n\"Alane\"\n,\n\"Alanna\"\n,\n\"Alano\"\n,\n\"Alansen\"\n,\n\"Alanson\"\n,\n\"Alard\"\n,\n\"Alaric\"\n,\n\"Alarice\"\n,\n\"Alarick\"\n,\n\"Alarise\"\n,\n\"Alasdair\"\n,\n\"Alastair\"\n,\n\"Alasteir\"\n,\n\"Alaster\"\n,\n\"Alatea\"\n,\n\"Alathia\"\n,\n\"Alayne\"\n,\n\"Alba\"\n,\n\"Alban\"\n,\n\"Albarran\"\n,\n\"Albemarle\"\n,\n\"Alben\"\n,\n\"Alber\"\n,\n\"Alberic\"\n,\n\"Alberik\"\n,\n\"Albers\"\n,\n\"Albert\"\n,\n\"Alberta\"\n,\n\"Albertina\"\n,\n\"Albertine\"\n,\n\"Alberto\"\n,\n\"Albertson\"\n,\n\"Albie\"\n,\n\"Albin\"\n,\n\"Albina\"\n,\n\"Albion\"\n,\n\"Alboran\"\n,\n\"Albrecht\"\n,\n\"Albric\"\n,\n\"Albright\"\n,\n\"Albur\"\n,\n\"Alburg\"\n,\n\"Alburga\"\n,\n\"Alby\"\n,\n\"Alcina\"\n,\n\"Alcine\"\n,\n\"Alcinia\"\n,\n\"Alcock\"\n,\n\"Alcot\"\n,\n\"Alcott\"\n,\n\"Alcus\"\n,\n\"Alda\"\n,\n\"Aldarcie\"\n,\n\"Aldarcy\"\n,\n\"Aldas\"\n,\n\"Alded\"\n,\n\"Alden\"\n,\n\"Aldercy\"\n,\n\"Alderman\"\n,\n\"Alderson\"\n,\n\"Aldin\"\n,\n\"Aldis\"\n,\n\"Aldo\"\n,\n\"Aldon\"\n,\n\"Aldora\"\n,\n\"Aldos\"\n,\n\"Aldous\"\n,\n\"Aldred\"\n,\n\"Aldredge\"\n,\n\"Aldric\"\n,\n\"Aldrich\"\n,\n\"Aldridge\"\n,\n\"Alduino\"\n,\n\"Aldus\"\n,\n\"Aldwin\"\n,\n\"Aldwon\"\n,\n\"Alec\"\n,\n\"Alecia\"\n,\n\"Aleck\"\n,\n\"Aleda\"\n,\n\"Aleece\"\n,\n\"Aleedis\"\n,\n\"Aleen\"\n,\n\"Aleetha\"\n,\n\"Alegre\"\n,\n\"Alejandra\"\n,\n\"Alejandrina\"\n,\n\"Alejandro\"\n,\n\"Alejo\"\n,\n\"Alejoa\"\n,\n\"Alek\"\n,\n\"Aleksandr\"\n,\n\"Alena\"\n,\n\"Alene\"\n,\n\"Alenson\"\n,\n\"Aleras\"\n,\n\"Aleris\"\n,\n\"Aleron\"\n,\n\"Alesandrini\"\n,\n\"Alessandra\"\n,\n\"Alessandro\"\n,\n\"Aleta\"\n,\n\"Aletha\"\n,\n\"Alethea\"\n,\n\"Alethia\"\n,\n\"Aletta\"\n,\n\"Alex\"\n,\n\"Alexa\"\n,\n\"Alexander\"\n,\n\"Alexandr\"\n,\n\"Alexandra\"\n,\n\"Alexandre\"\n,\n\"Alexandria\"\n,\n\"Alexandrina\"\n,\n\"Alexandro\"\n,\n\"Alexandros\"\n,\n\"Alexei\"\n,\n\"Alexi\"\n,\n\"Alexia\"\n,\n\"Alexina\"\n,\n\"Alexine\"\n,\n\"Alexio\"\n,\n\"Alexis\"\n,\n\"Aley\"\n,\n\"Aleydis\"\n,\n\"Alf\"\n,\n\"Alfeus\"\n,\n\"Alfi\"\n,\n\"Alfie\"\n,\n\"Alfons\"\n,\n\"Alfonse\"\n,\n\"Alfonso\"\n,\n\"Alfonzo\"\n,\n\"Alford\"\n,\n\"Alfred\"\n,\n\"Alfreda\"\n,\n\"Alfredo\"\n,\n\"Alfy\"\n,\n\"Algar\"\n,\n\"Alger\"\n,\n\"Algernon\"\n,\n\"Algie\"\n,\n\"Alguire\"\n,\n\"Algy\"\n,\n\"Ali\"\n,\n\"Alia\"\n,\n\"Aliber\"\n,\n\"Alic\"\n,\n\"Alica\"\n,\n\"Alice\"\n,\n\"Alicea\"\n,\n\"Alicia\"\n,\n\"Alick\"\n,\n\"Alida\"\n,\n\"Alidia\"\n,\n\"Alidis\"\n,\n\"Alidus\"\n,\n\"Alie\"\n,\n\"Alika\"\n,\n\"Alikee\"\n,\n\"Alina\"\n,\n\"Aline\"\n,\n\"Alinna\"\n,\n\"Alis\"\n,\n\"Alisa\"\n,\n\"Alisan\"\n,\n\"Alisander\"\n,\n\"Alisen\"\n,\n\"Alisha\"\n,\n\"Alisia\"\n,\n\"Alison\"\n,\n\"Alissa\"\n,\n\"Alistair\"\n,\n\"Alister\"\n,\n\"Alisun\"\n,\n\"Alita\"\n,\n\"Alitha\"\n,\n\"Alithea\"\n,\n\"Alithia\"\n,\n\"Alitta\"\n,\n\"Alius\"\n,\n\"Alix\"\n,\n\"Aliza\"\n,\n\"Alla\"\n,\n\"Allain\"\n,\n\"Allan\"\n,\n\"Allana\"\n,\n\"Allanson\"\n,\n\"Allard\"\n,\n\"Allare\"\n,\n\"Allayne\"\n,\n\"Allbee\"\n,\n\"Allcot\"\n,\n\"Alleen\"\n,\n\"Allegra\"\n,\n\"Allen\"\n,\n\"Allene\"\n,\n\"Alleras\"\n,\n\"Allerie\"\n,\n\"Alleris\"\n,\n\"Allerus\"\n,\n\"Alley\"\n,\n\"Alleyn\"\n,\n\"Alleyne\"\n,\n\"Alli\"\n,\n\"Allianora\"\n,\n\"Alliber\"\n,\n\"Allie\"\n,\n\"Allin\"\n,\n\"Allina\"\n,\n\"Allis\"\n,\n\"Allisan\"\n,\n\"Allison\"\n,\n\"Allissa\"\n,\n\"Allista\"\n,\n\"Allister\"\n,\n\"Allistir\"\n,\n\"Allix\"\n,\n\"Allmon\"\n,\n\"Allred\"\n,\n\"Allrud\"\n,\n\"Allsopp\"\n,\n\"Allsun\"\n,\n\"Allveta\"\n,\n\"Allwein\"\n,\n\"Allx\"\n,\n\"Ally\"\n,\n\"Allyce\"\n,\n\"Allyn\"\n,\n\"Allys\"\n,\n\"Allyson\"\n,\n\"Alma\"\n,\n\"Almallah\"\n,\n\"Almeda\"\n,\n\"Almeeta\"\n,\n\"Almeida\"\n,\n\"Almena\"\n,\n\"Almeria\"\n,\n\"Almeta\"\n,\n\"Almira\"\n,\n\"Almire\"\n,\n\"Almita\"\n,\n\"Almond\"\n,\n\"Almund\"\n,\n\"Alo\"\n,\n\"Alodee\"\n,\n\"Alodi\"\n,\n\"Alodie\"\n,\n\"Aloin\"\n,\n\"Aloise\"\n,\n\"Aloisia\"\n,\n\"Aloisius\"\n,\n\"Aloke\"\n,\n\"Alon\"\n,\n\"Alonso\"\n,\n\"Alonzo\"\n,\n\"Aloysia\"\n,\n\"Aloysius\"\n,\n\"Alper\"\n,\n\"Alpers\"\n,\n\"Alpert\"\n,\n\"Alphard\"\n,\n\"Alpheus\"\n,\n\"Alphonsa\"\n,\n\"Alphonse\"\n,\n\"Alphonsine\"\n,\n\"Alphonso\"\n,\n\"AlrZc\"\n,\n\"Alric\"\n,\n\"Alrich\"\n,\n\"Alrick\"\n,\n\"Alroi\"\n,\n\"Alroy\"\n,\n\"Also\"\n,\n\"Alston\"\n,\n\"Alsworth\"\n,\n\"Alta\"\n,\n\"Altaf\"\n,\n\"Alten\"\n,\n\"Althea\"\n,\n\"Althee\"\n,\n\"Altheta\"\n,\n\"Altis\"\n,\n\"Altman\"\n,\n\"Alton\"\n,\n\"Aluin\"\n,\n\"Aluino\"\n,\n\"Alurd\"\n,\n\"Alurta\"\n,\n\"Alva\"\n,\n\"Alvan\"\n,\n\"Alvar\"\n,\n\"Alvarez\"\n,\n\"Alver\"\n,\n\"Alvera\"\n,\n\"Alverson\"\n,\n\"Alverta\"\n,\n\"Alves\"\n,\n\"Alveta\"\n,\n\"Alviani\"\n,\n\"Alvie\"\n,\n\"Alvin\"\n,\n\"Alvina\"\n,\n\"Alvinia\"\n,\n\"Alvira\"\n,\n\"Alvis\"\n,\n\"Alvita\"\n,\n\"Alvord\"\n,\n\"Alvy\"\n,\n\"Alwin\"\n,\n\"Alwitt\"\n,\n\"Alwyn\"\n,\n\"Alyce\"\n,\n\"Alyda\"\n,\n\"Alyose\"\n,\n\"Alyosha\"\n,\n\"Alys\"\n,\n\"Alysa\"\n,\n\"Alyse\"\n,\n\"Alysia\"\n,\n\"Alyson\"\n,\n\"Alysoun\"\n,\n\"Alyss\"\n,\n\"Alyssa\"\n,\n\"Alyworth\"\n,\n\"Ama\"\n,\n\"Amabel\"\n,\n\"Amabelle\"\n,\n\"Amabil\"\n,\n\"Amadas\"\n,\n\"Amadeo\"\n,\n\"Amadeus\"\n,\n\"Amadis\"\n,\n\"Amado\"\n,\n\"Amador\"\n,\n\"Amadus\"\n,\n\"Amal\"\n,\n\"Amalbena\"\n,\n\"Amalberga\"\n,\n\"Amalbergas\"\n,\n\"Amalburga\"\n,\n\"Amalea\"\n,\n\"Amalee\"\n,\n\"Amaleta\"\n,\n\"Amalia\"\n,\n\"Amalie\"\n,\n\"Amalita\"\n,\n\"Amalle\"\n,\n\"Aman\"\n,\n\"Amand\"\n,\n\"Amanda\"\n,\n\"Amandi\"\n,\n\"Amandie\"\n,\n\"Amando\"\n,\n\"Amandy\"\n,\n\"Amann\"\n,\n\"Amar\"\n,\n\"Amara\"\n,\n\"Amaral\"\n,\n\"Amaras\"\n,\n\"Amarette\"\n,\n\"Amargo\"\n,\n\"Amari\"\n,\n\"Amarillas\"\n,\n\"Amarillis\"\n,\n\"Amaris\"\n,\n\"Amary\"\n,\n\"Amaryl\"\n,\n\"Amaryllis\"\n,\n\"Amasa\"\n,\n\"Amata\"\n,\n\"Amathist\"\n,\n\"Amathiste\"\n,\n\"Amati\"\n,\n\"Amato\"\n,\n\"Amatruda\"\n,\n\"Amaty\"\n,\n\"Amber\"\n,\n\"Amberly\"\n,\n\"Ambert\"\n,\n\"Ambie\"\n,\n\"Amble\"\n,\n\"Ambler\"\n,\n\"Ambrogino\"\n,\n\"Ambrogio\"\n,\n\"Ambros\"\n,\n\"Ambrosane\"\n,\n\"Ambrose\"\n,\n\"Ambrosi\"\n,\n\"Ambrosia\"\n,\n\"Ambrosine\"\n,\n\"Ambrosio\"\n,\n\"Ambrosius\"\n,\n\"Ambur\"\n,\n\"Amby\"\n,\n\"Ame\"\n,\n\"Amedeo\"\n,\n\"Amelia\"\n,\n\"Amelie\"\n,\n\"Amelina\"\n,\n\"Ameline\"\n,\n\"Amelita\"\n,\n\"Amena\"\n,\n\"Amend\"\n,\n\"Amerigo\"\n,\n\"Amero\"\n,\n\"Amersham\"\n,\n\"Amery\"\n,\n\"Ames\"\n,\n\"Amethist\"\n,\n\"Amethyst\"\n,\n\"Ami\"\n,\n\"Amias\"\n,\n\"Amice\"\n,\n\"Amick\"\n,\n\"Amie\"\n,\n\"Amiel\"\n,\n\"Amieva\"\n,\n\"Amii\"\n,\n\"Amil\"\n,\n\"Amin\"\n,\n\"Aminta\"\n,\n\"Amir\"\n,\n\"Amitie\"\n,\n\"Amity\"\n,\n\"Amling\"\n,\n\"Ammadas\"\n,\n\"Ammadis\"\n,\n\"Ammamaria\"\n,\n\"Ammann\"\n,\n\"Ammon\"\n,\n\"Amoakuh\"\n,\n\"Amor\"\n,\n\"Amora\"\n,\n\"Amoreta\"\n,\n\"Amorete\"\n,\n\"Amorette\"\n,\n\"Amorita\"\n,\n\"Amoritta\"\n,\n\"Amory\"\n,\n\"Amos\"\n,\n\"Amr\"\n,\n\"Amrita\"\n,\n\"Amsden\"\n,\n\"Amund\"\n,\n\"Amy\"\n,\n\"Amyas\"\n,\n\"Amye\"\n,\n\"Amolie\"\n,\n\"An\"\n,\n\"Ana\"\n,\n\"Anabal\"\n,\n\"Anabel\"\n,\n\"Anabella\"\n,\n\"Anabelle\"\n,\n\"Anagnos\"\n,\n\"Analiese\"\n,\n\"Analise\"\n,\n\"Anallese\"\n,\n\"Anallise\"\n,\n\"Anana\"\n,\n\"Ananna\"\n,\n\"Anastas\"\n,\n\"Anastase\"\n,\n\"Anastasia\"\n,\n\"Anastasie\"\n,\n\"Anastasio\"\n,\n\"Anastasius\"\n,\n\"Anastassia\"\n,\n\"Anastatius\"\n,\n\"Anastice\"\n,\n\"Anastos\"\n,\n\"Anatol\"\n,\n\"Anatola\"\n,\n\"Anatole\"\n,\n\"Anatolio\"\n,\n\"Anatollo\"\n,\n\"Ancalin\"\n,\n\"Ancel\"\n,\n\"Ancelin\"\n,\n\"Anceline\"\n,\n\"Ancell\"\n,\n\"Anchie\"\n,\n\"Ancier\"\n,\n\"Ancilin\"\n,\n\"Andee\"\n,\n\"Andeee\"\n,\n\"Andel\"\n,\n\"Ander\"\n,\n\"Anderea\"\n,\n\"Anderegg\"\n,\n\"Anderer\"\n,\n\"Anders\"\n,\n\"Andersen\"\n,\n\"Anderson\"\n,\n\"Andert\"\n,\n\"Andi\"\n,\n\"Andie\"\n,\n\"Andonis\"\n,\n\"Andra\"\n,\n\"Andrade\"\n,\n\"Andras\"\n,\n\"Andre\"\n,\n\"Andrea\"\n,\n\"Andreana\"\n,\n\"Andreas\"\n,\n\"Andree\"\n,\n\"Andrei\"\n,\n\"Andrej\"\n,\n\"Andrel\"\n,\n\"Andres\"\n,\n\"Andrew\"\n,\n\"Andrews\"\n,\n\"Andrey\"\n,\n\"Andri\"\n,\n\"Andria\"\n,\n\"Andriana\"\n,\n\"Andrien\"\n,\n\"Andriette\"\n,\n\"Andris\"\n,\n\"Andromache\"\n,\n\"Andromada\"\n,\n\"Andromeda\"\n,\n\"Andromede\"\n,\n\"Andros\"\n,\n\"Androw\"\n,\n\"Andrus\"\n,\n\"Andryc\"\n,\n\"Andy\"\n,\n\"Anestassia\"\n,\n\"Anet\"\n,\n\"Anett\"\n,\n\"Anetta\"\n,\n\"Anette\"\n,\n\"Aney\"\n,\n\"Angadreme\"\n,\n\"Angadresma\"\n,\n\"Ange\"\n,\n\"Angel\"\n,\n\"Angela\"\n,\n\"Angele\"\n,\n\"Angeli\"\n,\n\"Angelia\"\n,\n\"Angelica\"\n,\n\"Angelico\"\n,\n\"Angelika\"\n,\n\"Angelina\"\n,\n\"Angeline\"\n,\n\"Angelique\"\n,\n\"Angelis\"\n,\n\"Angelita\"\n,\n\"Angell\"\n,\n\"Angelle\"\n,\n\"Angelo\"\n,\n\"Angi\"\n,\n\"Angie\"\n,\n\"Angil\"\n,\n\"Angle\"\n,\n\"Anglim\"\n,\n\"Anglo\"\n,\n\"Angrist\"\n,\n\"Angus\"\n,\n\"Angy\"\n,\n\"Anh\"\n,\n\"Ania\"\n,\n\"Aniakudo\"\n,\n\"Anica\"\n,\n\"Aniela\"\n,\n\"Anil\"\n,\n\"Anis\"\n,\n\"Anissa\"\n,\n\"Anita\"\n,\n\"Anitra\"\n,\n\"Aniweta\"\n,\n\"Anjali\"\n,\n\"Anjanette\"\n,\n\"Anjela\"\n,\n\"Ankeny\"\n,\n\"Ankney\"\n,\n\"Ann\"\n,\n\"Ann-Marie\"\n,\n\"Anna\"\n,\n\"Anna-Diana\"\n,\n\"Anna-Diane\"\n,\n\"Anna-Maria\"\n,\n\"Annabal\"\n,\n\"Annabel\"\n,\n\"Annabela\"\n,\n\"Annabell\"\n,\n\"Annabella\"\n,\n\"Annabelle\"\n,\n\"Annadiana\"\n,\n\"Annadiane\"\n,\n\"Annalee\"\n,\n\"Annaliese\"\n,\n\"Annalise\"\n,\n\"Annamaria\"\n,\n\"Annamarie\"\n,\n\"Anne\"\n,\n\"Anne-Corinne\"\n,\n\"Anne-Marie\"\n,\n\"Annecorinne\"\n,\n\"Anneliese\"\n,\n\"Annelise\"\n,\n\"Annemarie\"\n,\n\"Annetta\"\n,\n\"Annette\"\n,\n\"Anni\"\n,\n\"Annia\"\n,\n\"Annice\"\n,\n\"Annie\"\n,\n\"Anniken\"\n,\n\"Annis\"\n,\n\"Annissa\"\n,\n\"Annmaria\"\n,\n\"Annmarie\"\n,\n\"Annnora\"\n,\n\"Annora\"\n,\n\"Annorah\"\n,\n\"Annunciata\"\n,\n\"Anny\"\n,\n\"Anora\"\n,\n\"Anse\"\n,\n\"Ansel\"\n,\n\"Ansela\"\n,\n\"Ansell\"\n,\n\"Anselm\"\n,\n\"Anselma\"\n,\n\"Anselme\"\n,\n\"Anselmi\"\n,\n\"Anselmo\"\n,\n\"Ansilma\"\n,\n\"Ansilme\"\n,\n\"Ansley\"\n,\n\"Anson\"\n,\n\"Anstice\"\n,\n\"Anstus\"\n,\n\"Antebi\"\n,\n\"Anthe\"\n,\n\"Anthea\"\n,\n\"Anthia\"\n,\n\"Anthiathia\"\n,\n\"Anthony\"\n,\n\"Antin\"\n,\n\"Antipas\"\n,\n\"Antipus\"\n,\n\"Antoine\"\n,\n\"Antoinetta\"\n,\n\"Antoinette\"\n,\n\"Anton\"\n,\n\"Antone\"\n,\n\"Antonella\"\n,\n\"Antonetta\"\n,\n\"Antoni\"\n,\n\"Antonia\"\n,\n\"Antonie\"\n,\n\"Antonietta\"\n,\n\"Antonin\"\n,\n\"Antonina\"\n,\n\"Antonino\"\n,\n\"Antonio\"\n,\n\"Antonius\"\n,\n\"Antons\"\n,\n\"Antony\"\n,\n\"Antrim\"\n,\n\"Anurag\"\n,\n\"Anuska\"\n,\n\"Any\"\n,\n\"Anya\"\n,\n\"Anyah\"\n,\n\"Anzovin\"\n,\n\"Apfel\"\n,\n\"Apfelstadt\"\n,\n\"Apgar\"\n,\n\"Aphra\"\n,\n\"Aphrodite\"\n,\n\"Apicella\"\n,\n\"Apollo\"\n,\n\"Apollus\"\n,\n\"Apostles\"\n,\n\"Appel\"\n,\n\"Apple\"\n,\n\"Appleby\"\n,\n\"Appledorf\"\n,\n\"Applegate\"\n,\n\"Appleton\"\n,\n\"Appolonia\"\n,\n\"Apps\"\n,\n\"April\"\n,\n\"Aprile\"\n,\n\"Aprilette\"\n,\n\"Apthorp\"\n,\n\"Apul\"\n,\n\"Ara\"\n,\n\"Arabeila\"\n,\n\"Arabel\"\n,\n\"Arabela\"\n,\n\"Arabele\"\n,\n\"Arabella\"\n,\n\"Arabelle\"\n,\n\"Arad\"\n,\n\"Arakawa\"\n,\n\"Araldo\"\n,\n\"Aramanta\"\n,\n\"Aramen\"\n,\n\"Aramenta\"\n,\n\"Araminta\"\n,\n\"Aran\"\n,\n\"Arand\"\n,\n\"Arathorn\"\n,\n\"Arbe\"\n,\n\"Arber\"\n,\n\"Arbuckle\"\n,\n\"Arch\"\n,\n\"Archaimbaud\"\n,\n\"Archambault\"\n,\n\"Archangel\"\n,\n\"Archer\"\n,\n\"Archibald\"\n,\n\"Archibaldo\"\n,\n\"Archibold\"\n,\n\"Archie\"\n,\n\"Archle\"\n,\n\"Archy\"\n,\n\"Ard\"\n,\n\"Arda\"\n,\n\"Ardath\"\n,\n\"Arde\"\n,\n\"Ardeen\"\n,\n\"Ardeha\"\n,\n\"Ardehs\"\n,\n\"Ardel\"\n,\n\"Ardelia\"\n,\n\"Ardelis\"\n,\n\"Ardell\"\n,\n\"Ardella\"\n,\n\"Ardelle\"\n,\n\"Arden\"\n,\n\"Ardene\"\n,\n\"Ardenia\"\n,\n\"Ardeth\"\n,\n\"Ardie\"\n,\n\"Ardin\"\n,\n\"Ardine\"\n,\n\"Ardis\"\n,\n\"Ardisj\"\n,\n\"Ardith\"\n,\n\"Ardme\"\n,\n\"Ardolino\"\n,\n\"Ardra\"\n,\n\"Ardrey\"\n,\n\"Ardussi\"\n,\n\"Ardy\"\n,\n\"Ardyce\"\n,\n\"Ardys\"\n,\n\"Ardyth\"\n,\n\"Arel\"\n,\n\"Arela\"\n,\n\"Arella\"\n,\n\"Arelus\"\n,\n\"Aret\"\n,\n\"Areta\"\n,\n\"Aretha\"\n,\n\"Aretina\"\n,\n\"Aretta\"\n,\n\"Arette\"\n,\n\"Arezzini\"\n,\n\"Argent\"\n,\n\"Argile\"\n,\n\"Argus\"\n,\n\"Argyle\"\n,\n\"Argyres\"\n,\n\"Arhna\"\n,\n\"Ari\"\n,\n\"Aria\"\n,\n\"Ariadne\"\n,\n\"Ariana\"\n,\n\"Ariane\"\n,\n\"Arianie\"\n,\n\"Arianna\"\n,\n\"Arianne\"\n,\n\"Aribold\"\n,\n\"Aric\"\n,\n\"Arica\"\n,\n\"Arick\"\n,\n\"Aridatha\"\n,\n\"Arie\"\n,\n\"Ariel\"\n,\n\"Ariela\"\n,\n\"Ariella\"\n,\n\"Arielle\"\n,\n\"Ariew\"\n,\n\"Arin\"\n,\n\"Ario\"\n,\n\"Arissa\"\n,\n\"Aristotle\"\n,\n\"Arita\"\n,\n\"Arjan\"\n,\n\"Arjun\"\n,\n\"Ark\"\n,\n\"Arlan\"\n,\n\"Arlana\"\n,\n\"Arlee\"\n,\n\"Arleen\"\n,\n\"Arlen\"\n,\n\"Arlena\"\n,\n\"Arlene\"\n,\n\"Arleta\"\n,\n\"Arlette\"\n,\n\"Arley\"\n,\n\"Arleyne\"\n,\n\"Arlie\"\n,\n\"Arliene\"\n,\n\"Arlin\"\n,\n\"Arlina\"\n,\n\"Arlinda\"\n,\n\"Arline\"\n,\n\"Arlo\"\n,\n\"Arlon\"\n,\n\"Arluene\"\n,\n\"Arly\"\n,\n\"Arlyn\"\n,\n\"Arlyne\"\n,\n\"Arlynne\"\n,\n\"Armalda\"\n,\n\"Armalla\"\n,\n\"Armallas\"\n,\n\"Arman\"\n,\n\"Armand\"\n,\n\"Armanda\"\n,\n\"Armando\"\n,\n\"Armbrecht\"\n,\n\"Armbruster\"\n,\n\"Armelda\"\n,\n\"Armil\"\n,\n\"Armilda\"\n,\n\"Armilla\"\n,\n\"Armillas\"\n,\n\"Armillda\"\n,\n\"Armillia\"\n,\n\"Armin\"\n,\n\"Armington\"\n,\n\"Armitage\"\n,\n\"Armond\"\n,\n\"Armstrong\"\n,\n\"Armyn\"\n,\n\"Arnaldo\"\n,\n\"Arnaud\"\n,\n\"Arndt\"\n,\n\"Arne\"\n,\n\"Arnelle\"\n,\n\"Arney\"\n,\n\"Arni\"\n,\n\"Arnie\"\n,\n\"Arno\"\n,\n\"Arnold\"\n,\n\"Arnoldo\"\n,\n\"Arnon\"\n,\n\"Arnst\"\n,\n\"Arnuad\"\n,\n\"Arnulfo\"\n,\n\"Arny\"\n,\n\"Arola\"\n,\n\"Aron\"\n,\n\"Arondel\"\n,\n\"Arondell\"\n,\n\"Aronoff\"\n,\n\"Aronow\"\n,\n\"Aronson\"\n,\n\"Arquit\"\n,\n\"Arratoon\"\n,\n\"Arri\"\n,\n\"Arria\"\n,\n\"Arrio\"\n,\n\"Arron\"\n,\n\"Arst\"\n,\n\"Art\"\n,\n\"Arta\"\n,\n\"Artair\"\n,\n\"Artamas\"\n,\n\"Arte\"\n,\n\"Artema\"\n,\n\"Artemas\"\n,\n\"Artemis\"\n,\n\"Artemisa\"\n,\n\"Artemisia\"\n,\n\"Artemus\"\n,\n\"Arther\"\n,\n\"Arthur\"\n,\n\"Artie\"\n,\n\"Artima\"\n,\n\"Artimas\"\n,\n\"Artina\"\n,\n\"Artur\"\n,\n\"Arturo\"\n,\n\"Artus\"\n,\n\"Arty\"\n,\n\"Aruabea\"\n,\n\"Arun\"\n,\n\"Arundel\"\n,\n\"Arundell\"\n,\n\"Arv\"\n,\n\"Arva\"\n,\n\"Arvad\"\n,\n\"Arvell\"\n,\n\"Arvid\"\n,\n\"Arvie\"\n,\n\"Arvin\"\n,\n\"Arvind\"\n,\n\"Arvo\"\n,\n\"Arvonio\"\n,\n\"Arvy\"\n,\n\"Ary\"\n,\n\"Aryn\"\n,\n\"As\"\n,\n\"Asa\"\n,\n\"Asabi\"\n,\n\"Asante\"\n,\n\"Asaph\"\n,\n\"Asare\"\n,\n\"Aschim\"\n,\n\"Ase\"\n,\n\"Asel\"\n,\n\"Ash\"\n,\n\"Asha\"\n,\n\"Ashbaugh\"\n,\n\"Ashbey\"\n,\n\"Ashby\"\n,\n\"Ashelman\"\n,\n\"Ashely\"\n,\n\"Asher\"\n,\n\"Ashford\"\n,\n\"Ashia\"\n,\n\"Ashien\"\n,\n\"Ashil\"\n,\n\"Ashjian\"\n,\n\"Ashla\"\n,\n\"Ashlan\"\n,\n\"Ashlee\"\n,\n\"Ashleigh\"\n,\n\"Ashlen\"\n,\n\"Ashley\"\n,\n\"Ashli\"\n,\n\"Ashlie\"\n,\n\"Ashlin\"\n,\n\"Ashling\"\n,\n\"Ashly\"\n,\n\"Ashman\"\n,\n\"Ashmead\"\n,\n\"Ashok\"\n,\n\"Ashraf\"\n,\n\"Ashti\"\n,\n\"Ashton\"\n,\n\"Ashwell\"\n,\n\"Ashwin\"\n,\n\"Asia\"\n,\n\"Askari\"\n,\n\"Askwith\"\n,\n\"Aslam\"\n,\n\"Asp\"\n,\n\"Aspa\"\n,\n\"Aspasia\"\n,\n\"Aspia\"\n,\n\"Asquith\"\n,\n\"Assisi\"\n,\n\"Asta\"\n,\n\"Astera\"\n,\n\"Asteria\"\n,\n\"Astor\"\n,\n\"Astra\"\n,\n\"Astraea\"\n,\n\"Astrahan\"\n,\n\"Astrea\"\n,\n\"Astred\"\n,\n\"Astri\"\n,\n\"Astrid\"\n,\n\"Astrix\"\n,\n\"Astto\"\n,\n\"Asuncion\"\n,\n\"Atal\"\n,\n\"Atalanta\"\n,\n\"Atalante\"\n,\n\"Atalanti\"\n,\n\"Atalaya\"\n,\n\"Atalayah\"\n,\n\"Atalee\"\n,\n\"Ataliah\"\n,\n\"Atalie\"\n,\n\"Atalya\"\n,\n\"Atcliffe\"\n,\n\"Athal\"\n,\n\"Athalee\"\n,\n\"Athalia\"\n,\n\"Athalie\"\n,\n\"Athalla\"\n,\n\"Athallia\"\n,\n\"Athelstan\"\n,\n\"Athena\"\n,\n\"Athene\"\n,\n\"Athenian\"\n,\n\"Athey\"\n,\n\"Athiste\"\n,\n\"Atiana\"\n,\n\"Atkins\"\n,\n\"Atkinson\"\n,\n\"Atlanta\"\n,\n\"Atlante\"\n,\n\"Atlas\"\n,\n\"Atlee\"\n,\n\"Atonsah\"\n,\n\"Atrice\"\n,\n\"Atronna\"\n,\n\"Attah\"\n,\n\"Attalanta\"\n,\n\"Attalie\"\n,\n\"Attenborough\"\n,\n\"Attenweiler\"\n,\n\"Atterbury\"\n,\n\"Atthia\"\n,\n\"Attlee\"\n,\n\"Attwood\"\n,\n\"Atul\"\n,\n\"Atwater\"\n,\n\"Atwekk\"\n,\n\"Atwood\"\n,\n\"Atworth\"\n,\n\"Au\"\n,\n\"Aubarta\"\n,\n\"Aube\"\n,\n\"Auberbach\"\n,\n\"Auberon\"\n,\n\"Aubert\"\n,\n\"Auberta\"\n,\n\"Aubigny\"\n,\n\"Aubin\"\n,\n\"Aubine\"\n,\n\"Aubree\"\n,\n\"Aubreir\"\n,\n\"Aubrette\"\n,\n\"Aubrey\"\n,\n\"Aubrie\"\n,\n\"Aubry\"\n,\n\"Auburn\"\n,\n\"Auburta\"\n,\n\"Aubyn\"\n,\n\"Audette\"\n,\n\"Audi\"\n,\n\"Audie\"\n,\n\"Audley\"\n,\n\"Audly\"\n,\n\"Audra\"\n,\n\"Audras\"\n,\n\"Audre\"\n,\n\"Audres\"\n,\n\"Audrey\"\n,\n\"Audri\"\n,\n\"Audrie\"\n,\n\"Audris\"\n,\n\"Audrit\"\n,\n\"Audry\"\n,\n\"Audrye\"\n,\n\"Audsley\"\n,\n\"Audun\"\n,\n\"Audwen\"\n,\n\"Audwin\"\n,\n\"Audy\"\n,\n\"Auerbach\"\n,\n\"Aufmann\"\n,\n\"Augie\"\n,\n\"August\"\n,\n\"Augusta\"\n,\n\"Auguste\"\n,\n\"Augustin\"\n,\n\"Augustina\"\n,\n\"Augustine\"\n,\n\"Augusto\"\n,\n\"Augustus\"\n,\n\"Augy\"\n,\n\"Aulea\"\n,\n\"Auliffe\"\n,\n\"Aun\"\n,\n\"Aundrea\"\n,\n\"Aunson\"\n,\n\"Aura\"\n,\n\"Aurea\"\n,\n\"Aurel\"\n,\n\"Aurelea\"\n,\n\"Aurelia\"\n,\n\"Aurelie\"\n,\n\"Aurelio\"\n,\n\"Aurelius\"\n,\n\"Auria\"\n,\n\"Auric\"\n,\n\"Aurie\"\n,\n\"Aurilia\"\n,\n\"Aurita\"\n,\n\"Aurlie\"\n,\n\"Auroora\"\n,\n\"Aurora\"\n,\n\"Aurore\"\n,\n\"Aurthur\"\n,\n\"Ause\"\n,\n\"Austen\"\n,\n\"Austin\"\n,\n\"Austina\"\n,\n\"Austine\"\n,\n\"Auston\"\n,\n\"Australia\"\n,\n\"Austreng\"\n,\n\"Autrey\"\n,\n\"Autry\"\n,\n\"Autum\"\n,\n\"Autumn\"\n,\n\"Auvil\"\n,\n\"Av\"\n,\n\"Ava\"\n,\n\"Avan\"\n,\n\"Avaria\"\n,\n\"Ave\"\n,\n\"Avelin\"\n,\n\"Aveline\"\n,\n\"Avera\"\n,\n\"Averell\"\n,\n\"Averi\"\n,\n\"Averil\"\n,\n\"Averill\"\n,\n\"Averir\"\n,\n\"Avery\"\n,\n\"Averyl\"\n,\n\"Avi\"\n,\n\"Avictor\"\n,\n\"Avie\"\n,\n\"Avigdor\"\n,\n\"Avilla\"\n,\n\"Avis\"\n,\n\"Avitzur\"\n,\n\"Aviv\"\n,\n\"Aviva\"\n,\n\"Avivah\"\n,\n\"Avner\"\n,\n\"Avra\"\n,\n\"Avraham\"\n,\n\"Avram\"\n,\n\"Avril\"\n,\n\"Avrit\"\n,\n\"Avrom\"\n,\n\"Avron\"\n,\n\"Avruch\"\n,\n\"Awad\"\n,\n\"Ax\"\n,\n\"Axe\"\n,\n\"Axel\"\n,\n\"Aylmar\"\n,\n\"Aylmer\"\n,\n\"Aylsworth\"\n,\n\"Aylward\"\n,\n\"Aymer\"\n,\n\"Ayn\"\n,\n\"Aynat\"\n,\n\"Ayo\"\n,\n\"Ayres\"\n,\n\"Azal\"\n,\n\"Azalea\"\n,\n\"Azaleah\"\n,\n\"Azar\"\n,\n\"Azarcon\"\n,\n\"Azaria\"\n,\n\"Azarria\"\n,\n\"Azelea\"\n,\n\"Azeria\"\n,\n\"Aziza\"\n,\n\"Azpurua\"\n,\n\"Azral\"\n,\n\"Azriel\"\n,\n\"Baal\"\n,\n\"Baalbeer\"\n,\n\"Baalman\"\n,\n\"Bab\"\n,\n\"Babara\"\n,\n\"Babb\"\n,\n\"Babbette\"\n,\n\"Babbie\"\n,\n\"Babby\"\n,\n\"Babcock\"\n,\n\"Babette\"\n,\n\"Babita\"\n,\n\"Babs\"\n,\n\"Bac\"\n,\n\"Bacchus\"\n,\n\"Bach\"\n,\n\"Bachman\"\n,\n\"Backer\"\n,\n\"Backler\"\n,\n\"Bacon\"\n,\n\"Badger\"\n,\n\"Badr\"\n,\n\"Baecher\"\n,\n\"Bael\"\n,\n\"Baelbeer\"\n,\n\"Baer\"\n,\n\"Baerl\"\n,\n\"Baerman\"\n,\n\"Baese\"\n,\n\"Bagger\"\n,\n\"Baggett\"\n,\n\"Baggott\"\n,\n\"Baggs\"\n,\n\"Bagley\"\n,\n\"Bahner\"\n,\n\"Bahr\"\n,\n\"Baiel\"\n,\n\"Bail\"\n,\n\"Bailar\"\n,\n\"Bailey\"\n,\n\"Bailie\"\n,\n\"Baillie\"\n,\n\"Baillieu\"\n,\n\"Baily\"\n,\n\"Bain\"\n,\n\"Bainbridge\"\n,\n\"Bainbrudge\"\n,\n\"Bainter\"\n,\n\"Baird\"\n,\n\"Baiss\"\n,\n\"Bajaj\"\n,\n\"Bak\"\n,\n\"Bakeman\"\n,\n\"Bakemeier\"\n,\n\"Baker\"\n,\n\"Bakerman\"\n,\n\"Bakki\"\n,\n\"Bal\"\n,\n\"Bala\"\n,\n\"Balas\"\n,\n\"Balbinder\"\n,\n\"Balbur\"\n,\n\"Balcer\"\n,\n\"Balch\"\n,\n\"Balcke\"\n,\n\"Bald\"\n,\n\"Baldridge\"\n,\n\"Balduin\"\n,\n\"Baldwin\"\n,\n\"Bale\"\n,\n\"Baler\"\n,\n\"Balf\"\n,\n\"Balfore\"\n,\n\"Balfour\"\n,\n\"Balkin\"\n,\n\"Ball\"\n,\n\"Ballard\"\n,\n\"Balliett\"\n,\n\"Balling\"\n,\n\"Ballinger\"\n,\n\"Balliol\"\n,\n\"Ballman\"\n,\n\"Ballou\"\n,\n\"Balmuth\"\n,\n\"Balough\"\n,\n\"Balsam\"\n,\n\"Balthasar\"\n,\n\"Balthazar\"\n,\n\"Bamberger\"\n,\n\"Bambi\"\n,\n\"Bambie\"\n,\n\"Bamby\"\n,\n\"Bamford\"\n,\n\"Ban\"\n,\n\"Bancroft\"\n,\n\"Bandeen\"\n,\n\"Bander\"\n,\n\"Bandler\"\n,\n\"Bandur\"\n,\n\"Banebrudge\"\n,\n\"Banerjee\"\n,\n\"Bang\"\n,\n\"Bank\"\n,\n\"Banks\"\n,\n\"Banky\"\n,\n\"Banna\"\n,\n\"Bannasch\"\n,\n\"Bannerman\"\n,\n\"Bannister\"\n,\n\"Bannon\"\n,\n\"Banquer\"\n,\n\"Banwell\"\n,\n\"Baptist\"\n,\n\"Baptista\"\n,\n\"Baptiste\"\n,\n\"Baptlsta\"\n,\n\"Bar\"\n,\n\"Bara\"\n,\n\"Barabas\"\n,\n\"Barabbas\"\n,\n\"Baram\"\n,\n\"Baras\"\n,\n\"Barayon\"\n,\n\"Barb\"\n,\n\"Barbabas\"\n,\n\"Barbabra\"\n,\n\"Barbara\"\n,\n\"Barbara-Anne\"\n,\n\"Barbaraanne\"\n,\n\"Barbarese\"\n,\n\"Barbaresi\"\n,\n\"Barbe\"\n,\n\"Barbee\"\n,\n\"Barber\"\n,\n\"Barbette\"\n,\n\"Barbey\"\n,\n\"Barbi\"\n,\n\"Barbie\"\n,\n\"Barbour\"\n,\n\"Barboza\"\n,\n\"Barbra\"\n,\n\"Barbur\"\n,\n\"Barbuto\"\n,\n\"Barby\"\n,\n\"Barcellona\"\n,\n\"Barclay\"\n,\n\"Barcot\"\n,\n\"Barcroft\"\n,\n\"Barcus\"\n,\n\"Bard\"\n,\n\"Barde\"\n,\n\"Barden\"\n,\n\"Bardo\"\n,\n\"Barfuss\"\n,\n\"Barger\"\n,\n\"Bari\"\n,\n\"Barimah\"\n,\n\"Barina\"\n,\n\"Barker\"\n,\n\"Barkley\"\n,\n\"Barling\"\n,\n\"Barlow\"\n,\n\"Barmen\"\n,\n\"Barn\"\n,\n\"Barna\"\n,\n\"Barnaba\"\n,\n\"Barnabas\"\n,\n\"Barnabe\"\n,\n\"Barnaby\"\n,\n\"Barnard\"\n,\n\"Barncard\"\n,\n\"Barnebas\"\n,\n\"Barnes\"\n,\n\"Barnet\"\n,\n\"Barnett\"\n,\n\"Barney\"\n,\n\"Barnie\"\n,\n\"Barnum\"\n,\n\"Barny\"\n,\n\"Barolet\"\n,\n\"Baron\"\n,\n\"Barr\"\n,\n\"Barra\"\n,\n\"Barrada\"\n,\n\"Barram\"\n,\n\"Barraza\"\n,\n\"Barren\"\n,\n\"Barret\"\n,\n\"Barrett\"\n,\n\"Barri\"\n,\n\"Barrie\"\n,\n\"Barrington\"\n,\n\"Barris\"\n,\n\"Barron\"\n,\n\"Barrow\"\n,\n\"Barrus\"\n,\n\"Barry\"\n,\n\"Barsky\"\n,\n\"Barstow\"\n,\n\"Bart\"\n,\n\"Barta\"\n,\n\"Bartel\"\n,\n\"Barth\"\n,\n\"Barthel\"\n,\n\"Barthelemy\"\n,\n\"Barthol\"\n,\n\"Barthold\"\n,\n\"Bartholemy\"\n,\n\"Bartholomeo\"\n,\n\"Bartholomeus\"\n,\n\"Bartholomew\"\n,\n\"Bartie\"\n,\n\"Bartko\"\n,\n\"Bartle\"\n,\n\"Bartlet\"\n,\n\"Bartlett\"\n,\n\"Bartley\"\n,\n\"Bartolemo\"\n,\n\"Bartolome\"\n,\n\"Bartolomeo\"\n,\n\"Barton\"\n,\n\"Bartosch\"\n,\n\"Bartram\"\n,\n\"Barty\"\n,\n\"Baruch\"\n,\n\"Barvick\"\n,\n\"Bary\"\n,\n\"Baryram\"\n,\n\"Bascio\"\n,\n\"Bascomb\"\n,\n\"Base\"\n,\n\"Baseler\"\n,\n\"Basham\"\n,\n\"Bashee\"\n,\n\"Bashemath\"\n,\n\"Bashemeth\"\n,\n\"Bashuk\"\n,\n\"Basia\"\n,\n\"Basil\"\n,\n\"Basile\"\n,\n\"Basilio\"\n,\n\"Basilius\"\n,\n\"Basir\"\n,\n\"Baskett\"\n,\n\"Bass\"\n,\n\"Basset\"\n,\n\"Bassett\"\n,\n\"Basso\"\n,\n\"Bast\"\n,\n\"Bastian\"\n,\n\"Bastien\"\n,\n\"Bat\"\n,\n\"Batchelor\"\n,\n\"Bate\"\n,\n\"Baten\"\n,\n\"Bates\"\n,\n\"Batha\"\n,\n\"Bathelda\"\n,\n\"Bathesda\"\n,\n\"Bathilda\"\n,\n\"Batholomew\"\n,\n\"Bathsheb\"\n,\n\"Bathsheba\"\n,\n\"Bathsheeb\"\n,\n\"Bathulda\"\n,\n\"Batish\"\n,\n\"Batista\"\n,\n\"Batory\"\n,\n\"Batruk\"\n,\n\"Batsheva\"\n,\n\"Battat\"\n,\n\"Battista\"\n,\n\"Battiste\"\n,\n\"Batty\"\n,\n\"Baudelaire\"\n,\n\"Baudin\"\n,\n\"Baudoin\"\n,\n\"Bauer\"\n,\n\"Baugh\"\n,\n\"Baum\"\n,\n\"Baumann\"\n,\n\"Baumbaugh\"\n,\n\"Baun\"\n,\n\"Bausch\"\n,\n\"Bauske\"\n,\n\"Bautista\"\n,\n\"Bautram\"\n,\n\"Bax\"\n,\n\"Baxie\"\n,\n\"Baxter\"\n,\n\"Baxy\"\n,\n\"Bay\"\n,\n\"Bayard\"\n,\n\"Bayer\"\n,\n\"Bayless\"\n,\n\"Baylor\"\n,\n\"Bayly\"\n,\n\"Baynebridge\"\n,\n\"Bazar\"\n,\n\"Bazil\"\n,\n\"Bazluke\"\n,\n\"Bea\"\n,\n\"Beach\"\n,\n\"Beacham\"\n,\n\"Beal\"\n,\n\"Beale\"\n,\n\"Beall\"\n,\n\"Bealle\"\n,\n\"Bean\"\n,\n\"Beane\"\n,\n\"Beaner\"\n,\n\"Bear\"\n,\n\"Bearce\"\n,\n\"Beard\"\n,\n\"Beare\"\n,\n\"Bearnard\"\n,\n\"Beasley\"\n,\n\"Beaston\"\n,\n\"Beata\"\n,\n\"Beatrice\"\n,\n\"Beatrisa\"\n,\n\"Beatrix\"\n,\n\"Beatriz\"\n,\n\"Beattie\"\n,\n\"Beatty\"\n,\n\"Beau\"\n,\n\"Beauchamp\"\n,\n\"Beaudoin\"\n,\n\"Beaufert\"\n,\n\"Beaufort\"\n,\n\"Beaulieu\"\n,\n\"Beaumont\"\n,\n\"Beauregard\"\n,\n\"Beauvais\"\n,\n\"Beaver\"\n,\n\"Bebe\"\n,\n\"Beberg\"\n,\n\"Becca\"\n,\n\"Bechler\"\n,\n\"Becht\"\n,\n\"Beck\"\n,\n\"Becka\"\n,\n\"Becker\"\n,\n\"Beckerman\"\n,\n\"Becket\"\n,\n\"Beckett\"\n,\n\"Becki\"\n,\n\"Beckie\"\n,\n\"Beckman\"\n,\n\"Becky\"\n,\n\"Bedad\"\n,\n\"Bedelia\"\n,\n\"Bedell\"\n,\n\"Bedwell\"\n,\n\"Bee\"\n,\n\"Beebe\"\n,\n\"Beeck\"\n,\n\"Beedon\"\n,\n\"Beekman\"\n,\n\"Beera\"\n,\n\"Beesley\"\n,\n\"Beeson\"\n,\n\"Beetner\"\n,\n\"Beffrey\"\n,\n\"Bega\"\n,\n\"Begga\"\n,\n\"Beghtol\"\n,\n\"Behah\"\n,\n\"Behka\"\n,\n\"Behl\"\n,\n\"Behlau\"\n,\n\"Behlke\"\n,\n\"Behm\"\n,\n\"Behn\"\n,\n\"Behnken\"\n,\n\"Behre\"\n,\n\"Behrens\"\n,\n\"Beichner\"\n,\n\"Beilul\"\n,\n\"Bein\"\n,\n\"Beisel\"\n,\n\"Beitch\"\n,\n\"Beitnes\"\n,\n\"Beitris\"\n,\n\"Beitz\"\n,\n\"Beka\"\n,\n\"Bekah\"\n,\n\"Bekelja\"\n,\n\"Beker\"\n,\n\"Bekha\"\n,\n\"Bekki\"\n,\n\"Bel\"\n,\n\"Bela\"\n,\n\"Belak\"\n,\n\"Belamy\"\n,\n\"Belanger\"\n,\n\"Belayneh\"\n,\n\"Belcher\"\n,\n\"Belda\"\n,\n\"Belden\"\n,\n\"Belding\"\n,\n\"Belen\"\n,\n\"Belford\"\n,\n\"Belia\"\n,\n\"Belicia\"\n,\n\"Belier\"\n,\n\"Belinda\"\n,\n\"Belita\"\n,\n\"Bell\"\n,\n\"Bella\"\n,\n\"Bellamy\"\n,\n\"Bellanca\"\n,\n\"Bellaude\"\n,\n\"Bellda\"\n,\n\"Belldame\"\n,\n\"Belldas\"\n,\n\"Belle\"\n,\n\"Beller\"\n,\n\"Bellew\"\n,\n\"Bellina\"\n,\n\"Bellis\"\n,\n\"Bello\"\n,\n\"Belloir\"\n,\n\"Belmonte\"\n,\n\"Belshin\"\n,\n\"Belsky\"\n,\n\"Belter\"\n,\n\"Beltran\"\n,\n\"Belva\"\n,\n\"Belvia\"\n,\n\"Ben\"\n,\n\"Bena\"\n,\n\"Bencion\"\n,\n\"Benco\"\n,\n\"Bender\"\n,\n\"Bendick\"\n,\n\"Bendicta\"\n,\n\"Bendicty\"\n,\n\"Bendite\"\n,\n\"Bendix\"\n,\n\"Benedetta\"\n,\n\"Benedetto\"\n,\n\"Benedic\"\n,\n\"Benedick\"\n,\n\"Benedict\"\n,\n\"Benedicta\"\n,\n\"Benedicto\"\n,\n\"Benedikt\"\n,\n\"Benedikta\"\n,\n\"Benedix\"\n,\n\"Benenson\"\n,\n\"Benetta\"\n,\n\"Benge\"\n,\n\"Bengt\"\n,\n\"Benia\"\n,\n\"Beniamino\"\n,\n\"Benil\"\n,\n\"Benilda\"\n,\n\"Benildas\"\n,\n\"Benildis\"\n,\n\"Benioff\"\n,\n\"Benis\"\n,\n\"Benisch\"\n,\n\"Benita\"\n,\n\"Benito\"\n,\n\"Benjamen\"\n,\n\"Benjamin\"\n,\n\"Benji\"\n,\n\"Benjie\"\n,\n\"Benjy\"\n,\n\"Benkley\"\n,\n\"Benn\"\n,\n\"Bennet\"\n,\n\"Bennett\"\n,\n\"Benni\"\n,\n\"Bennie\"\n,\n\"Bennink\"\n,\n\"Bennion\"\n,\n\"Bennir\"\n,\n\"Benny\"\n,\n\"Benoit\"\n,\n\"Benoite\"\n,\n\"Bensen\"\n,\n\"Bensky\"\n,\n\"Benson\"\n,\n\"Bent\"\n,\n\"Bentlee\"\n,\n\"Bentley\"\n,\n\"Bently\"\n,\n\"Benton\"\n,\n\"Benyamin\"\n,\n\"Benzel\"\n,\n\"Beora\"\n,\n\"Beore\"\n,\n\"Ber\"\n,\n\"Berard\"\n,\n\"Berardo\"\n,\n\"Berck\"\n,\n\"Berenice\"\n,\n\"Beret\"\n,\n\"Berey\"\n,\n\"Berfield\"\n,\n\"Berg\"\n,\n\"Berga\"\n,\n\"Bergeman\"\n,\n\"Bergen\"\n,\n\"Berger\"\n,\n\"Bergerac\"\n,\n\"Bergeron\"\n,\n\"Bergess\"\n,\n\"Berget\"\n,\n\"Bergh\"\n,\n\"Berghoff\"\n,\n\"Bergin\"\n,\n\"Berglund\"\n,\n\"Bergman\"\n,\n\"Bergmann\"\n,\n\"Bergmans\"\n,\n\"Bergquist\"\n,\n\"Bergren\"\n,\n\"Bergstein\"\n,\n\"Bergstrom\"\n,\n\"Bergwall\"\n,\n\"Berhley\"\n,\n\"Berk\"\n,\n\"Berke\"\n,\n\"Berkeley\"\n,\n\"Berkie\"\n,\n\"Berkin\"\n,\n\"Berkley\"\n,\n\"Berkly\"\n,\n\"Berkman\"\n,\n\"Berkow\"\n,\n\"Berkshire\"\n,\n\"Berky\"\n,\n\"Berl\"\n,\n\"Berlauda\"\n,\n\"Berlin\"\n,\n\"Berlinda\"\n,\n\"Berliner\"\n,\n\"Berlyn\"\n,\n\"Berman\"\n,\n\"Bern\"\n,\n\"Berna\"\n,\n\"Bernadene\"\n,\n\"Bernadette\"\n,\n\"Bernadina\"\n,\n\"Bernadine\"\n,\n\"Bernard\"\n,\n\"Bernardi\"\n,\n\"Bernardina\"\n,\n\"Bernardine\"\n,\n\"Bernardo\"\n,\n\"Bernarr\"\n,\n\"Bernat\"\n,\n\"Berne\"\n,\n\"Bernelle\"\n,\n\"Berner\"\n,\n\"Berners\"\n,\n\"Berneta\"\n,\n\"Bernete\"\n,\n\"Bernetta\"\n,\n\"Bernette\"\n,\n\"Bernhard\"\n,\n\"Berni\"\n,\n\"Bernice\"\n,\n\"Bernie\"\n,\n\"Bernita\"\n,\n\"Bernj\"\n,\n\"Berns\"\n,\n\"Bernstein\"\n,\n\"Bernt\"\n,\n\"Berny\"\n,\n\"Berri\"\n,\n\"Berrie\"\n,\n\"Berriman\"\n,\n\"Berry\"\n,\n\"Berstine\"\n,\n\"Bert\"\n,\n\"Berta\"\n,\n\"Bertasi\"\n,\n\"Berte\"\n,\n\"Bertelli\"\n,\n\"Bertero\"\n,\n\"Bertha\"\n,\n\"Berthe\"\n,\n\"Berthold\"\n,\n\"Berthoud\"\n,\n\"Berti\"\n,\n\"Bertie\"\n,\n\"Bertila\"\n,\n\"Bertilla\"\n,\n\"Bertina\"\n,\n\"Bertine\"\n,\n\"Bertle\"\n,\n\"Bertold\"\n,\n\"Bertolde\"\n,\n\"Berton\"\n,\n\"Bertram\"\n,\n\"Bertrand\"\n,\n\"Bertrando\"\n,\n\"Bertsche\"\n,\n\"Berty\"\n,\n\"Berwick\"\n,\n\"Beryl\"\n,\n\"Beryle\"\n,\n\"Beshore\"\n,\n\"Besnard\"\n,\n\"Bess\"\n,\n\"Besse\"\n,\n\"Bessie\"\n,\n\"Bessy\"\n,\n\"Best\"\n,\n\"Beth\"\n,\n\"Bethanne\"\n,\n\"Bethany\"\n,\n\"Bethel\"\n,\n\"Bethena\"\n,\n\"Bethesda\"\n,\n\"Bethesde\"\n,\n\"Bethezel\"\n,\n\"Bethina\"\n,\n\"Betsey\"\n,\n\"Betsy\"\n,\n\"Betta\"\n,\n\"Bette\"\n,\n\"Bette-Ann\"\n,\n\"Betteann\"\n,\n\"Betteanne\"\n,\n\"Bettencourt\"\n,\n\"Betthel\"\n,\n\"Betthezel\"\n,\n\"Betthezul\"\n,\n\"Betti\"\n,\n\"Bettina\"\n,\n\"Bettine\"\n,\n\"Betty\"\n,\n\"Bettye\"\n,\n\"Bettzel\"\n,\n\"Betz\"\n,\n\"Beulah\"\n,\n\"Beuthel\"\n,\n\"Beutler\"\n,\n\"Beutner\"\n,\n\"Bev\"\n,\n\"Bevan\"\n,\n\"Bevash\"\n,\n\"Bever\"\n,\n\"Beverie\"\n,\n\"Beverle\"\n,\n\"Beverlee\"\n,\n\"Beverley\"\n,\n\"Beverlie\"\n,\n\"Beverly\"\n,\n\"Bevers\"\n,\n\"Bevin\"\n,\n\"Bevis\"\n,\n\"Bevon\"\n,\n\"Bevus\"\n,\n\"Bevvy\"\n,\n\"Beyer\"\n,\n\"Bezanson\"\n,\n\"Bhatt\"\n,\n\"Bhayani\"\n,\n\"Biagi\"\n,\n\"Biagio\"\n,\n\"Biamonte\"\n,\n\"Bianca\"\n,\n\"Biancha\"\n,\n\"Bianchi\"\n,\n\"Bianka\"\n,\n\"Bibbie\"\n,\n\"Bibby\"\n,\n\"Bibbye\"\n,\n\"Bibeau\"\n,\n\"Bibi\"\n,\n\"Bible\"\n,\n\"Bick\"\n,\n\"Bickart\"\n,\n\"Bicknell\"\n,\n\"Biddick\"\n,\n\"Biddie\"\n,\n\"Biddle\"\n,\n\"Biddy\"\n,\n\"Bidget\"\n,\n\"Bidle\"\n,\n\"Biebel\"\n,\n\"Biegel\"\n,\n\"Bierman\"\n,\n\"Biernat\"\n,\n\"Bigelow\"\n,\n\"Bigford\"\n,\n\"Bigg\"\n,\n\"Biggs\"\n,\n\"Bigler\"\n,\n\"Bigner\"\n,\n\"Bigod\"\n,\n\"Bigot\"\n,\n\"Bik\"\n,\n\"Bikales\"\n,\n\"Bil\"\n,\n\"Bilbe\"\n,\n\"Bilek\"\n,\n\"Biles\"\n,\n\"Bili\"\n,\n\"Bilicki\"\n,\n\"Bill\"\n,\n\"Billat\"\n,\n\"Bille\"\n,\n\"Billen\"\n,\n\"Billi\"\n,\n\"Billie\"\n,\n\"Billmyre\"\n,\n\"Bills\"\n,\n\"Billy\"\n,\n\"Billye\"\n,\n\"Bilow\"\n,\n\"Bilski\"\n,\n\"Bina\"\n,\n\"Binah\"\n,\n\"Bindman\"\n,\n\"Binetta\"\n,\n\"Binette\"\n,\n\"Bing\"\n,\n\"Bink\"\n,\n\"Binky\"\n,\n\"Binni\"\n,\n\"Binnie\"\n,\n\"Binnings\"\n,\n\"Binny\"\n,\n\"Biondo\"\n,\n\"Birch\"\n,\n\"Birchard\"\n,\n\"Birck\"\n,\n\"Bird\"\n,\n\"Birdella\"\n,\n\"Birdie\"\n,\n\"Birdt\"\n,\n\"Birecree\"\n,\n\"Birgit\"\n,\n\"Birgitta\"\n,\n\"Birk\"\n,\n\"Birkett\"\n,\n\"Birkle\"\n,\n\"Birkner\"\n,\n\"Birmingham\"\n,\n\"Biron\"\n,\n\"Bish\"\n,\n\"Bishop\"\n,\n\"Bissell\"\n,\n\"Bisset\"\n,\n\"Bithia\"\n,\n\"Bittencourt\"\n,\n\"Bitthia\"\n,\n\"Bittner\"\n,\n\"Bivins\"\n,\n\"Bixby\"\n,\n\"Bixler\"\n,\n\"Bjork\"\n,\n\"Bjorn\"\n,\n\"Black\"\n,\n\"Blackburn\"\n,\n\"Blackington\"\n,\n\"Blackman\"\n,\n\"Blackmore\"\n,\n\"Blackmun\"\n,\n\"Blackstock\"\n,\n\"Blackwell\"\n,\n\"Blader\"\n,\n\"Blain\"\n,\n\"Blaine\"\n,\n\"Blainey\"\n,\n\"Blair\"\n,\n\"Blaire\"\n,\n\"Blaise\"\n,\n\"Blake\"\n,\n\"Blakelee\"\n,\n\"Blakeley\"\n,\n\"Blakely\"\n,\n\"Blalock\"\n,\n\"Blanc\"\n,\n\"Blanca\"\n,\n\"Blanch\"\n,\n\"Blancha\"\n,\n\"Blanchard\"\n,\n\"Blanche\"\n,\n\"Blanchette\"\n,\n\"Bland\"\n,\n\"Blandina\"\n,\n\"Blanding\"\n,\n\"Blane\"\n,\n\"Blank\"\n,\n\"Blanka\"\n,\n\"Blankenship\"\n,\n\"Blas\"\n,\n\"Blase\"\n,\n\"Blaseio\"\n,\n\"Blasien\"\n,\n\"Blasius\"\n,\n\"Blatman\"\n,\n\"Blatt\"\n,\n\"Blau\"\n,\n\"Blayne\"\n,\n\"Blayze\"\n,\n\"Blaze\"\n,\n\"Bledsoe\"\n,\n\"Bleier\"\n,\n\"Blen\"\n,\n\"Blessington\"\n,\n\"Blight\"\n,\n\"Blim\"\n,\n\"Blinni\"\n,\n\"Blinnie\"\n,\n\"Blinny\"\n,\n\"Bliss\"\n,\n\"Blisse\"\n,\n\"Blithe\"\n,\n\"Bloch\"\n,\n\"Block\"\n,\n\"Blockus\"\n,\n\"Blodget\"\n,\n\"Blodgett\"\n,\n\"Bloem\"\n,\n\"Blondell\"\n,\n\"Blondelle\"\n,\n\"Blondie\"\n,\n\"Blondy\"\n,\n\"Blood\"\n,\n\"Bloom\"\n,\n\"Bloomer\"\n,\n\"Blossom\"\n,\n\"Blount\"\n,\n\"Bloxberg\"\n,\n\"Bluefarb\"\n,\n\"Bluefield\"\n,\n\"Bluh\"\n,\n\"Bluhm\"\n,\n\"Blum\"\n,\n\"Bluma\"\n,\n\"Blumenfeld\"\n,\n\"Blumenthal\"\n,\n\"Blunk\"\n,\n\"Blunt\"\n,\n\"Blus\"\n,\n\"Blynn\"\n,\n\"Blythe\"\n,\n\"Bo\"\n,\n\"Boak\"\n,\n\"Boar\"\n,\n\"Boardman\"\n,\n\"Boarer\"\n,\n\"Boaten\"\n,\n\"Boatwright\"\n,\n\"Bob\"\n,\n\"Bobbe\"\n,\n\"Bobbee\"\n,\n\"Bobbette\"\n,\n\"Bobbi\"\n,\n\"Bobbie\"\n,\n\"Bobby\"\n,\n\"Bobbye\"\n,\n\"Bobette\"\n,\n\"Bobina\"\n,\n\"Bobine\"\n,\n\"Bobinette\"\n,\n\"Bobker\"\n,\n\"Bobseine\"\n,\n\"Bock\"\n,\n\"Bocock\"\n,\n\"Bodi\"\n,\n\"Bodkin\"\n,\n\"Bodnar\"\n,\n\"Bodrogi\"\n,\n\"Bodwell\"\n,\n\"Body\"\n,\n\"Boehike\"\n,\n\"Boehmer\"\n,\n\"Boeke\"\n,\n\"Boelter\"\n,\n\"Boesch\"\n,\n\"Boeschen\"\n,\n\"Boff\"\n,\n\"Boffa\"\n,\n\"Bogart\"\n,\n\"Bogey\"\n,\n\"Boggers\"\n,\n\"Boggs\"\n,\n\"Bogie\"\n,\n\"Bogoch\"\n,\n\"Bogosian\"\n,\n\"Bogusz\"\n,\n\"Bohannon\"\n,\n\"Bohaty\"\n,\n\"Bohi\"\n,\n\"Bohlen\"\n,\n\"Bohlin\"\n,\n\"Bohman\"\n,\n\"Bohner\"\n,\n\"Bohon\"\n,\n\"Bohrer\"\n,\n\"Bohs\"\n,\n\"Bohun\"\n,\n\"Boice\"\n,\n\"Boigie\"\n,\n\"Boiney\"\n,\n\"Bois\"\n,\n\"Bolan\"\n,\n\"Boland\"\n,\n\"Bolanger\"\n,\n\"Bolen\"\n,\n\"Boles\"\n,\n\"Boleslaw\"\n,\n\"Boleyn\"\n,\n\"Bolger\"\n,\n\"Bolitho\"\n,\n\"Bollay\"\n,\n\"Bollen\"\n,\n\"Bolling\"\n,\n\"Bollinger\"\n,\n\"Bolme\"\n,\n\"Bolt\"\n,\n\"Bolte\"\n,\n\"Bolten\"\n,\n\"Bolton\"\n,\n\"Bomke\"\n,\n\"Bonacci\"\n,\n\"Bonaparte\"\n,\n\"Bonar\"\n,\n\"Bond\"\n,\n\"Bondie\"\n,\n\"Bondon\"\n,\n\"Bondy\"\n,\n\"Bone\"\n,\n\"Boni\"\n,\n\"Boniface\"\n,\n\"Bonilla\"\n,\n\"Bonina\"\n,\n\"Bonine\"\n,\n\"Bonis\"\n,\n\"Bonita\"\n,\n\"Bonn\"\n,\n\"Bonne\"\n,\n\"Bonneau\"\n,\n\"Bonnee\"\n,\n\"Bonnell\"\n,\n\"Bonner\"\n,\n\"Bonnes\"\n,\n\"Bonnette\"\n,\n\"Bonney\"\n,\n\"Bonni\"\n,\n\"Bonnibelle\"\n,\n\"Bonnice\"\n,\n\"Bonnie\"\n,\n\"Bonns\"\n,\n\"Bonny\"\n,\n\"Bonucci\"\n,\n\"Booker\"\n,\n\"Booma\"\n,\n\"Boone\"\n,\n\"Boonie\"\n,\n\"Boony\"\n,\n\"Boor\"\n,\n\"Boorer\"\n,\n\"Boorman\"\n,\n\"Boot\"\n,\n\"Boote\"\n,\n\"Booth\"\n,\n\"Boothe\"\n,\n\"Boothman\"\n,\n\"Booze\"\n,\n\"Bopp\"\n,\n\"Bor\"\n,\n\"Bora\"\n,\n\"Borchers\"\n,\n\"Borchert\"\n,\n\"Bord\"\n,\n\"Borden\"\n,\n\"Bordie\"\n,\n\"Bordiuk\"\n,\n\"Bordy\"\n,\n\"Bore\"\n,\n\"Borek\"\n,\n\"Borer\"\n,\n\"Bores\"\n,\n\"Borg\"\n,\n\"Borgeson\"\n,\n\"Boris\"\n,\n\"Bork\"\n,\n\"Borlase\"\n,\n\"Borlow\"\n,\n\"Borman\"\n,\n\"Born\"\n,\n\"Bornie\"\n,\n\"Bornstein\"\n,\n\"Borras\"\n,\n\"Borrell\"\n,\n\"Borreri\"\n,\n\"Borries\"\n,\n\"Borroff\"\n,\n\"Borszcz\"\n,\n\"Bortman\"\n,\n\"Bortz\"\n,\n\"Boru\"\n,\n\"Bosch\"\n,\n\"Bose\"\n,\n\"Boser\"\n,\n\"Bosson\"\n,\n\"Bostow\"\n,\n\"Boswall\"\n,\n\"Boswell\"\n,\n\"Botnick\"\n,\n\"Botsford\"\n,\n\"Bottali\"\n,\n\"Botti\"\n,\n\"Botzow\"\n,\n\"Bouchard\"\n,\n\"Boucher\"\n,\n\"Bouchier\"\n,\n\"Boudreaux\"\n,\n\"Bough\"\n,\n\"Boulanger\"\n,\n\"Bouldon\"\n,\n\"Bouley\"\n,\n\"Bound\"\n,\n\"Bounds\"\n,\n\"Bourgeois\"\n,\n\"Bourke\"\n,\n\"Bourn\"\n,\n\"Bourne\"\n,\n\"Bourque\"\n,\n\"Boutis\"\n,\n\"Bouton\"\n,\n\"Bouzoun\"\n,\n\"Bove\"\n,\n\"Bovill\"\n,\n\"Bow\"\n,\n\"Bowden\"\n,\n\"Bowe\"\n,\n\"Bowen\"\n,\n\"Bower\"\n,\n\"Bowerman\"\n,\n\"Bowers\"\n,\n\"Bowes\"\n,\n\"Bowie\"\n,\n\"Bowlds\"\n,\n\"Bowler\"\n,\n\"Bowles\"\n,\n\"Bowman\"\n,\n\"Bowne\"\n,\n\"Bowra\"\n,\n\"Bowrah\"\n,\n\"Bowyer\"\n,\n\"Box\"\n,\n\"Boy\"\n,\n\"Boyce\"\n,\n\"Boycey\"\n,\n\"Boycie\"\n,\n\"Boyd\"\n,\n\"Boyden\"\n,\n\"Boyer\"\n,\n\"Boyes\"\n,\n\"Boykins\"\n,\n\"Boylan\"\n,\n\"Boylston\"\n,\n\"Boynton\"\n,\n\"Boys\"\n,\n\"Boyse\"\n,\n\"Boyt\"\n,\n\"Bozovich\"\n,\n\"Bozuwa\"\n,\n\"Braasch\"\n,\n\"Brabazon\"\n,\n\"Braca\"\n,\n\"Bracci\"\n,\n\"Brace\"\n,\n\"Brackely\"\n,\n\"Brackett\"\n,\n\"Brad\"\n,\n\"Bradan\"\n,\n\"Brade\"\n,\n\"Braden\"\n,\n\"Bradeord\"\n,\n\"Brader\"\n,\n\"Bradford\"\n,\n\"Bradlee\"\n,\n\"Bradleigh\"\n,\n\"Bradley\"\n,\n\"Bradly\"\n,\n\"Bradman\"\n,\n\"Bradney\"\n,\n\"Bradshaw\"\n,\n\"Bradski\"\n,\n\"Bradstreet\"\n,\n\"Bradway\"\n,\n\"Bradwell\"\n,\n\"Brady\"\n,\n\"Braeunig\"\n,\n\"Brag\"\n,\n\"Brahear\"\n,\n\"Brainard\"\n,\n\"Bram\"\n,\n\"Bramwell\"\n,\n\"Bran\"\n,\n\"Brana\"\n,\n\"Branca\"\n,\n\"Branch\"\n,\n\"Brand\"\n,\n\"Brandais\"\n,\n\"Brande\"\n,\n\"Brandea\"\n,\n\"Branden\"\n,\n\"Brandenburg\"\n,\n\"Brander\"\n,\n\"Brandes\"\n,\n\"Brandi\"\n,\n\"Brandice\"\n,\n\"Brandie\"\n,\n\"Brandise\"\n,\n\"Brandon\"\n,\n\"Brandt\"\n,\n\"Brandtr\"\n,\n\"Brandwein\"\n,\n\"Brandy\"\n,\n\"Brandyn\"\n,\n\"Branen\"\n,\n\"Branham\"\n,\n\"Brannon\"\n,\n\"Branscum\"\n,\n\"Brant\"\n,\n\"Brantley\"\n,\n\"Brasca\"\n,\n\"Brass\"\n,\n\"Braswell\"\n,\n\"Brathwaite\"\n,\n\"Bratton\"\n,\n\"Braun\"\n,\n\"Braunstein\"\n,\n\"Brause\"\n,\n\"Bravar\"\n,\n\"Bravin\"\n,\n\"Brawley\"\n,\n\"Brawner\"\n,\n\"Bray\"\n,\n\"Braynard\"\n,\n\"Brazee\"\n,\n\"Breana\"\n,\n\"Breanne\"\n,\n\"Brear\"\n,\n\"Breban\"\n,\n\"Brebner\"\n,\n\"Brecher\"\n,\n\"Brechtel\"\n,\n\"Bred\"\n,\n\"Bree\"\n,\n\"Breech\"\n,\n\"Breed\"\n,\n\"Breen\"\n,\n\"Breena\"\n,\n\"Breeze\"\n,\n\"Breger\"\n,\n\"Brelje\"\n,\n\"Bremble\"\n,\n\"Bremen\"\n,\n\"Bremer\"\n,\n\"Bremser\"\n,\n\"Bren\"\n,\n\"Brena\"\n,\n\"Brenan\"\n,\n\"Brenda\"\n,\n\"Brendan\"\n,\n\"Brenden\"\n,\n\"Brendin\"\n,\n\"Brendis\"\n,\n\"Brendon\"\n,\n\"Brenk\"\n,\n\"Brenn\"\n,\n\"Brenna\"\n,\n\"Brennan\"\n,\n\"Brennen\"\n,\n\"Brenner\"\n,\n\"Brent\"\n,\n\"Brenton\"\n,\n\"Brentt\"\n,\n\"Brenza\"\n,\n\"Bresee\"\n,\n\"Breskin\"\n,\n\"Brest\"\n,\n\"Bret\"\n,\n\"Brett\"\n,\n\"Brew\"\n,\n\"Brewer\"\n,\n\"Brewster\"\n,\n\"Brey\"\n,\n\"Brezin\"\n,\n\"Bria\"\n,\n\"Brian\"\n,\n\"Briana\"\n,\n\"Brianna\"\n,\n\"Brianne\"\n,\n\"Briano\"\n,\n\"Briant\"\n,\n\"Brice\"\n,\n\"Brick\"\n,\n\"Bricker\"\n,\n\"Bride\"\n,\n\"Bridge\"\n,\n\"Bridges\"\n,\n\"Bridget\"\n,\n\"Bridgette\"\n,\n\"Bridgid\"\n,\n\"Bridie\"\n,\n\"Bridwell\"\n,\n\"Brie\"\n,\n\"Brien\"\n,\n\"Brier\"\n,\n\"Brieta\"\n,\n\"Brietta\"\n,\n\"Brig\"\n,\n\"Brigette\"\n,\n\"Brigg\"\n,\n\"Briggs\"\n,\n\"Brigham\"\n,\n\"Bright\"\n,\n\"Brightman\"\n,\n\"Brighton\"\n,\n\"Brigid\"\n,\n\"Brigida\"\n,\n\"Brigit\"\n,\n\"Brigitta\"\n,\n\"Brigitte\"\n,\n\"Brill\"\n,\n\"Brina\"\n,\n\"Brindell\"\n,\n\"Brindle\"\n,\n\"Brine\"\n,\n\"Briney\"\n,\n\"Bringhurst\"\n,\n\"Brink\"\n,\n\"Brinkema\"\n,\n\"Brinn\"\n,\n\"Brinna\"\n,\n\"Brinson\"\n,\n\"Briny\"\n,\n\"Brion\"\n,\n\"Briscoe\"\n,\n\"Bristow\"\n,\n\"Brit\"\n,\n\"Brita\"\n,\n\"Britney\"\n,\n\"Britni\"\n,\n\"Britt\"\n,\n\"Britta\"\n,\n\"Brittain\"\n,\n\"Brittan\"\n,\n\"Brittaney\"\n,\n\"Brittani\"\n,\n\"Brittany\"\n,\n\"Britte\"\n,\n\"Britteny\"\n,\n\"Brittne\"\n,\n\"Brittnee\"\n,\n\"Brittney\"\n,\n\"Brittni\"\n,\n\"Britton\"\n,\n\"Brnaba\"\n,\n\"Brnaby\"\n,\n\"Broadbent\"\n,\n\"Brock\"\n,\n\"Brockie\"\n,\n\"Brocklin\"\n,\n\"Brockwell\"\n,\n\"Brocky\"\n,\n\"Brod\"\n,\n\"Broddie\"\n,\n\"Broddy\"\n,\n\"Brodench\"\n,\n\"Broder\"\n,\n\"Broderic\"\n,\n\"Broderick\"\n,\n\"Brodeur\"\n,\n\"Brodie\"\n,\n\"Brodsky\"\n,\n\"Brody\"\n,\n\"Broeder\"\n,\n\"Broek\"\n,\n\"Broeker\"\n,\n\"Brogle\"\n,\n\"Broida\"\n,\n\"Brok\"\n,\n\"Brom\"\n,\n\"Bromleigh\"\n,\n\"Bromley\"\n,\n\"Bron\"\n,\n\"Bronder\"\n,\n\"Bronez\"\n,\n\"Bronk\"\n,\n\"Bronnie\"\n,\n\"Bronny\"\n,\n\"Bronson\"\n,\n\"Bronwen\"\n,\n\"Bronwyn\"\n,\n\"Brook\"\n,\n\"Brooke\"\n,\n\"Brookes\"\n,\n\"Brookhouse\"\n,\n\"Brooking\"\n,\n\"Brookner\"\n,\n\"Brooks\"\n,\n\"Broome\"\n,\n\"Brose\"\n,\n\"Brosine\"\n,\n\"Brost\"\n,\n\"Brosy\"\n,\n\"Brote\"\n,\n\"Brothers\"\n,\n\"Brotherson\"\n,\n\"Brott\"\n,\n\"Brottman\"\n,\n\"Broucek\"\n,\n\"Brout\"\n,\n\"Brouwer\"\n,\n\"Brower\"\n,\n\"Brown\"\n,\n\"Browne\"\n,\n\"Browning\"\n,\n\"Brownley\"\n,\n\"Brownson\"\n,\n\"Brozak\"\n,\n\"Brubaker\"\n,\n\"Bruce\"\n,\n\"Brucie\"\n,\n\"Bruckner\"\n,\n\"Bruell\"\n,\n\"Brufsky\"\n,\n\"Bruis\"\n,\n\"Brunell\"\n,\n\"Brunella\"\n,\n\"Brunelle\"\n,\n\"Bruner\"\n,\n\"Brunhild\"\n,\n\"Brunhilda\"\n,\n\"Brunhilde\"\n,\n\"Bruni\"\n,\n\"Bruning\"\n,\n\"Brunk\"\n,\n\"Brunn\"\n,\n\"Bruno\"\n,\n\"Bruns\"\n,\n\"Bruyn\"\n,\n\"Bryan\"\n,\n\"Bryana\"\n,\n\"Bryant\"\n,\n\"Bryanty\"\n,\n\"Bryce\"\n,\n\"Bryn\"\n,\n\"Bryna\"\n,\n\"Bryner\"\n,\n\"Brynn\"\n,\n\"Brynna\"\n,\n\"Brynne\"\n,\n\"Bryon\"\n,\n\"Buatti\"\n,\n\"Bubalo\"\n,\n\"Bubb\"\n,\n\"Bucella\"\n,\n\"Buchalter\"\n,\n\"Buchanan\"\n,\n\"Buchbinder\"\n,\n\"Bucher\"\n,\n\"Buchheim\"\n,\n\"Buck\"\n,\n\"Buckden\"\n,\n\"Buckels\"\n,\n\"Buckie\"\n,\n\"Buckingham\"\n,\n\"Buckler\"\n,\n\"Buckley\"\n,\n\"Bucky\"\n,\n\"Bud\"\n,\n\"Budd\"\n,\n\"Budde\"\n,\n\"Buddie\"\n,\n\"Budding\"\n,\n\"Buddy\"\n,\n\"Buderus\"\n,\n\"Budge\"\n,\n\"Budwig\"\n,\n\"Budworth\"\n,\n\"Buehler\"\n,\n\"Buehrer\"\n,\n\"Buell\"\n,\n\"Buerger\"\n,\n\"Bueschel\"\n,\n\"Buff\"\n,\n\"Buffo\"\n,\n\"Buffum\"\n,\n\"Buffy\"\n,\n\"Buford\"\n,\n\"Bugbee\"\n,\n\"Buhler\"\n,\n\"Bui\"\n,\n\"Buine\"\n,\n\"Buiron\"\n,\n\"Buke\"\n,\n\"Bull\"\n,\n\"Bullard\"\n,\n\"Bullen\"\n,\n\"Buller\"\n,\n\"Bulley\"\n,\n\"Bullion\"\n,\n\"Bullis\"\n,\n\"Bullivant\"\n,\n\"Bullock\"\n,\n\"Bullough\"\n,\n\"Bully\"\n,\n\"Bultman\"\n,\n\"Bum\"\n,\n\"Bumgardner\"\n,\n\"Buna\"\n,\n\"Bunce\"\n,\n\"Bunch\"\n,\n\"Bunde\"\n,\n\"Bunder\"\n,\n\"Bundy\"\n,\n\"Bunker\"\n,\n\"Bunni\"\n,\n\"Bunnie\"\n,\n\"Bunns\"\n,\n\"Bunny\"\n,\n\"Bunow\"\n,\n\"Bunting\"\n,\n\"Buonomo\"\n,\n\"Buote\"\n,\n\"Burack\"\n,\n\"Burbank\"\n,\n\"Burch\"\n,\n\"Burchett\"\n,\n\"Burck\"\n,\n\"Burd\"\n,\n\"Burdelle\"\n,\n\"Burdett\"\n,\n\"Burford\"\n,\n\"Burg\"\n,\n\"Burgener\"\n,\n\"Burger\"\n,\n\"Burgess\"\n,\n\"Burget\"\n,\n\"Burgwell\"\n,\n\"Burhans\"\n,\n\"Burk\"\n,\n\"Burke\"\n,\n\"Burkhard\"\n,\n\"Burkhardt\"\n,\n\"Burkhart\"\n,\n\"Burkitt\"\n,\n\"Burkle\"\n,\n\"Burkley\"\n,\n\"Burl\"\n,\n\"Burleigh\"\n,\n\"Burley\"\n,\n\"Burlie\"\n,\n\"Burman\"\n,\n\"Burn\"\n,\n\"Burnaby\"\n,\n\"Burnard\"\n,\n\"Burne\"\n,\n\"Burner\"\n,\n\"Burnett\"\n,\n\"Burney\"\n,\n\"Burnham\"\n,\n\"Burnie\"\n,\n\"Burnight\"\n,\n\"Burnley\"\n,\n\"Burns\"\n,\n\"Burnsed\"\n,\n\"Burnside\"\n,\n\"Burny\"\n,\n\"Buroker\"\n,\n\"Burr\"\n,\n\"Burra\"\n,\n\"Burrell\"\n,\n\"Burrill\"\n,\n\"Burris\"\n,\n\"Burroughs\"\n,\n\"Burrow\"\n,\n\"Burrows\"\n,\n\"Burrton\"\n,\n\"Burrus\"\n,\n\"Burt\"\n,\n\"Burta\"\n,\n\"Burtie\"\n,\n\"Burtis\"\n,\n\"Burton\"\n,\n\"Burty\"\n,\n\"Burwell\"\n,\n\"Bury\"\n,\n\"Busby\"\n,\n\"Busch\"\n,\n\"Buschi\"\n,\n\"Buseck\"\n,\n\"Busey\"\n,\n\"Bush\"\n,\n\"Bushey\"\n,\n\"Bushore\"\n,\n\"Bushweller\"\n,\n\"Busiek\"\n,\n\"Buskirk\"\n,\n\"Buskus\"\n,\n\"Bussey\"\n,\n\"Bussy\"\n,\n\"Bust\"\n,\n\"Butch\"\n,\n\"Butcher\"\n,\n\"Butler\"\n,\n\"Butta\"\n,\n\"Buttaro\"\n,\n\"Butte\"\n,\n\"Butterfield\"\n,\n\"Butterworth\"\n,\n\"Button\"\n,\n\"Buxton\"\n,\n\"Buyer\"\n,\n\"Buyers\"\n,\n\"Buyse\"\n,\n\"Buzz\"\n,\n\"Buzzell\"\n,\n\"Byers\"\n,\n\"Byler\"\n,\n\"Byram\"\n,\n\"Byran\"\n,\n\"Byrann\"\n,\n\"Byrd\"\n,\n\"Byrdie\"\n,\n\"Byrle\"\n,\n\"Byrn\"\n,\n\"Byrne\"\n,\n\"Byrom\"\n,\n\"Byron\"\n,\n\"Bysshe\"\n,\n\"Bywaters\"\n,\n\"Bywoods\"\n,\n\"Cacia\"\n,\n\"Cacie\"\n,\n\"Cacilia\"\n,\n\"Cacilie\"\n,\n\"Cacka\"\n,\n\"Cad\"\n,\n\"Cadal\"\n,\n\"Caddaric\"\n,\n\"Caddric\"\n,\n\"Cade\"\n,\n\"Cadel\"\n,\n\"Cadell\"\n,\n\"Cadman\"\n,\n\"Cadmann\"\n,\n\"Cadmar\"\n,\n\"Cadmarr\"\n,\n\"Caesar\"\n,\n\"Caesaria\"\n,\n\"Caffrey\"\n,\n\"Cagle\"\n,\n\"Cahan\"\n,\n\"Cahilly\"\n,\n\"Cahn\"\n,\n\"Cahra\"\n,\n\"Cai\"\n,\n\"Caia\"\n,\n\"Caiaphas\"\n,\n\"Cailean\"\n,\n\"Cailly\"\n,\n\"Cain\"\n,\n\"Caine\"\n,\n\"Caines\"\n,\n\"Cairistiona\"\n,\n\"Cairns\"\n,\n\"Caitlin\"\n,\n\"Caitrin\"\n,\n\"Cal\"\n,\n\"Calabrese\"\n,\n\"Calabresi\"\n,\n\"Calan\"\n,\n\"Calandra\"\n,\n\"Calandria\"\n,\n\"Calbert\"\n,\n\"Caldeira\"\n,\n\"Calder\"\n,\n\"Caldera\"\n,\n\"Calderon\"\n,\n\"Caldwell\"\n,\n\"Cale\"\n,\n\"Caleb\"\n,\n\"Calen\"\n,\n\"Calendra\"\n,\n\"Calendre\"\n,\n\"Calesta\"\n,\n\"Calhoun\"\n,\n\"Calia\"\n,\n\"Calica\"\n,\n\"Calida\"\n,\n\"Calie\"\n,\n\"Calisa\"\n,\n\"Calise\"\n,\n\"Calista\"\n,\n\"Call\"\n,\n\"Calla\"\n,\n\"Callahan\"\n,\n\"Callan\"\n,\n\"Callas\"\n,\n\"Calle\"\n,\n\"Callean\"\n,\n\"Callery\"\n,\n\"Calley\"\n,\n\"Calli\"\n,\n\"Callida\"\n,\n\"Callie\"\n,\n\"Callista\"\n,\n\"Calloway\"\n,\n\"Callum\"\n,\n\"Cally\"\n,\n\"Calmas\"\n,\n\"Calondra\"\n,\n\"Calore\"\n,\n\"Calv\"\n,\n\"Calva\"\n,\n\"Calvano\"\n,\n\"Calvert\"\n,\n\"Calvin\"\n,\n\"Calvina\"\n,\n\"Calvinna\"\n,\n\"Calvo\"\n,\n\"Calypso\"\n,\n\"Calysta\"\n,\n\"Cam\"\n,\n\"Camala\"\n,\n\"Camarata\"\n,\n\"Camden\"\n,\n\"Camel\"\n,\n\"Camella\"\n,\n\"Camellia\"\n,\n\"Cameron\"\n,\n\"Camey\"\n,\n\"Camfort\"\n,\n\"Cami\"\n,\n\"Camila\"\n,\n\"Camile\"\n,\n\"Camilia\"\n,\n\"Camilla\"\n,\n\"Camille\"\n,\n\"Camilo\"\n,\n\"Camm\"\n,\n\"Cammi\"\n,\n\"Cammie\"\n,\n\"Cammy\"\n,\n\"Camp\"\n,\n\"Campagna\"\n,\n\"Campball\"\n,\n\"Campbell\"\n,\n\"Campman\"\n,\n\"Campney\"\n,\n\"Campos\"\n,\n\"Campy\"\n,\n\"Camus\"\n,\n\"Can\"\n,\n\"Canada\"\n,\n\"Canale\"\n,\n\"Cand\"\n,\n\"Candace\"\n,\n\"Candi\"\n,\n\"Candice\"\n,\n\"Candida\"\n,\n\"Candide\"\n,\n\"Candie\"\n,\n\"Candis\"\n,\n\"Candless\"\n,\n\"Candra\"\n,\n\"Candy\"\n,\n\"Candyce\"\n,\n\"Caneghem\"\n,\n\"Canfield\"\n,\n\"Canica\"\n,\n\"Canice\"\n,\n\"Caniff\"\n,\n\"Cann\"\n,\n\"Cannell\"\n,\n\"Cannice\"\n,\n\"Canning\"\n,\n\"Cannon\"\n,\n\"Canon\"\n,\n\"Canotas\"\n,\n\"Canter\"\n,\n\"Cantlon\"\n,\n\"Cantone\"\n,\n\"Cantu\"\n,\n\"Canty\"\n,\n\"Canute\"\n,\n\"Capello\"\n,\n\"Caplan\"\n,\n\"Capon\"\n,\n\"Capone\"\n,\n\"Capp\"\n,\n\"Cappella\"\n,\n\"Cappello\"\n,\n\"Capps\"\n,\n\"Caprice\"\n,\n\"Capriola\"\n,\n\"Caputo\"\n,\n\"Caputto\"\n,\n\"Capwell\"\n,\n\"Car\"\n,\n\"Cara\"\n,\n\"Caralie\"\n,\n\"Caras\"\n,\n\"Caravette\"\n,\n\"Caraviello\"\n,\n\"Carberry\"\n,\n\"Carbo\"\n,\n\"Carbone\"\n,\n\"Carboni\"\n,\n\"Carbrey\"\n,\n\"Carce\"\n,\n\"Card\"\n,\n\"Carder\"\n,\n\"Cardew\"\n,\n\"Cardie\"\n,\n\"Cardinal\"\n,\n\"Cardon\"\n,\n\"Cardwell\"\n,\n\"Care\"\n,\n\"Careaga\"\n,\n\"Caren\"\n,\n\"Carena\"\n,\n\"Caresa\"\n,\n\"Caressa\"\n,\n\"Caresse\"\n,\n\"Carew\"\n,\n\"Carey\"\n,\n\"Cargian\"\n,\n\"Carhart\"\n,\n\"Cari\"\n,\n\"Caria\"\n,\n\"Carie\"\n,\n\"Caril\"\n,\n\"Carilla\"\n,\n\"Carilyn\"\n,\n\"Carin\"\n,\n\"Carina\"\n,\n\"Carine\"\n,\n\"Cariotta\"\n,\n\"Carisa\"\n,\n\"Carissa\"\n,\n\"Carita\"\n,\n\"Caritta\"\n,\n\"Carl\"\n,\n\"Carla\"\n,\n\"Carlee\"\n,\n\"Carleen\"\n,\n\"Carlen\"\n,\n\"Carlene\"\n,\n\"Carleton\"\n,\n\"Carley\"\n,\n\"Carli\"\n,\n\"Carlick\"\n,\n\"Carlie\"\n,\n\"Carlile\"\n,\n\"Carlin\"\n,\n\"Carlina\"\n,\n\"Carline\"\n,\n\"Carling\"\n,\n\"Carlisle\"\n,\n\"Carlita\"\n,\n\"Carlo\"\n,\n\"Carlock\"\n,\n\"Carlos\"\n,\n\"Carlota\"\n,\n\"Carlotta\"\n,\n\"Carlson\"\n,\n\"Carlstrom\"\n,\n\"Carlton\"\n,\n\"Carly\"\n,\n\"Carlye\"\n,\n\"Carlyle\"\n,\n\"Carlyn\"\n,\n\"Carlynn\"\n,\n\"Carlynne\"\n,\n\"Carma\"\n,\n\"Carman\"\n,\n\"Carmel\"\n,\n\"Carmela\"\n,\n\"Carmelia\"\n,\n\"Carmelina\"\n,\n\"Carmelita\"\n,\n\"Carmella\"\n,\n\"Carmelle\"\n,\n\"Carmelo\"\n,\n\"Carmen\"\n,\n\"Carmena\"\n,\n\"Carmencita\"\n,\n\"Carmina\"\n,\n\"Carmine\"\n,\n\"Carmita\"\n,\n\"Carmon\"\n,\n\"Carn\"\n,\n\"Carnahan\"\n,\n\"Carnay\"\n,\n\"Carnes\"\n,\n\"Carney\"\n,\n\"Carny\"\n,\n\"Caro\"\n,\n\"Carol\"\n,\n\"Carol-Jean\"\n,\n\"Carola\"\n,\n\"Carolan\"\n,\n\"Carolann\"\n,\n\"Carole\"\n,\n\"Carolee\"\n,\n\"Carolin\"\n,\n\"Carolina\"\n,\n\"Caroline\"\n,\n\"Carolle\"\n,\n\"Carolus\"\n,\n\"Carolyn\"\n,\n\"Carolyne\"\n,\n\"Carolynn\"\n,\n\"Carolynne\"\n,\n\"Caron\"\n,\n\"Carothers\"\n,\n\"Carpenter\"\n,\n\"Carper\"\n,\n\"Carpet\"\n,\n\"Carpio\"\n,\n\"Carr\"\n,\n\"Carree\"\n,\n\"Carrel\"\n,\n\"Carrelli\"\n,\n\"Carrew\"\n,\n\"Carri\"\n,\n\"Carrick\"\n,\n\"Carrie\"\n,\n\"Carrillo\"\n,\n\"Carrington\"\n,\n\"Carrissa\"\n,\n\"Carrnan\"\n,\n\"Carrol\"\n,\n\"Carroll\"\n,\n\"Carry\"\n,\n\"Carson\"\n,\n\"Cart\"\n,\n\"Cartan\"\n,\n\"Carter\"\n,\n\"Carthy\"\n,\n\"Cartie\"\n,\n\"Cartwell\"\n,\n\"Cartwright\"\n,\n\"Caruso\"\n,\n\"Carver\"\n,\n\"Carvey\"\n,\n\"Cary\"\n,\n\"Caryl\"\n,\n\"Caryn\"\n,\n\"Cas\"\n,\n\"Casabonne\"\n,\n\"Casady\"\n,\n\"Casaleggio\"\n,\n\"Casandra\"\n,\n\"Casanova\"\n,\n\"Casar\"\n,\n\"Casavant\"\n,\n\"Case\"\n,\n\"Casey\"\n,\n\"Cash\"\n,\n\"Casi\"\n,\n\"Casia\"\n,\n\"Casie\"\n,\n\"Casilda\"\n,\n\"Casilde\"\n,\n\"Casimir\"\n,\n\"Casimire\"\n,\n\"Casmey\"\n,\n\"Caspar\"\n,\n\"Casper\"\n,\n\"Cass\"\n,\n\"Cassady\"\n,\n\"Cassandra\"\n,\n\"Cassandre\"\n,\n\"Cassandry\"\n,\n\"Cassaundra\"\n,\n\"Cassell\"\n,\n\"Cassella\"\n,\n\"Cassey\"\n,\n\"Cassi\"\n,\n\"Cassiani\"\n,\n\"Cassidy\"\n,\n\"Cassie\"\n,\n\"Cassil\"\n,\n\"Cassilda\"\n,\n\"Cassius\"\n,\n\"Cassondra\"\n,\n\"Cassy\"\n,\n\"Casta\"\n,\n\"Castara\"\n,\n\"Casteel\"\n,\n\"Castera\"\n,\n\"Castillo\"\n,\n\"Castle\"\n,\n\"Castor\"\n,\n\"Castora\"\n,\n\"Castorina\"\n,\n\"Castra\"\n,\n\"Castro\"\n,\n\"Caswell\"\n,\n\"Cataldo\"\n,\n\"Catarina\"\n,\n\"Cate\"\n,\n\"Caterina\"\n,\n\"Cates\"\n,\n\"Cath\"\n,\n\"Catha\"\n,\n\"Catharina\"\n,\n\"Catharine\"\n,\n\"Cathe\"\n,\n\"Cathee\"\n,\n\"Catherin\"\n,\n\"Catherina\"\n,\n\"Catherine\"\n,\n\"Cathey\"\n,\n\"Cathi\"\n,\n\"Cathie\"\n,\n\"Cathleen\"\n,\n\"Cathlene\"\n,\n\"Cathrin\"\n,\n\"Cathrine\"\n,\n\"Cathryn\"\n,\n\"Cathy\"\n,\n\"Cathyleen\"\n,\n\"Cati\"\n,\n\"Catie\"\n,\n\"Catima\"\n,\n\"Catina\"\n,\n\"Catlaina\"\n,\n\"Catlee\"\n,\n\"Catlin\"\n,\n\"Cato\"\n,\n\"Caton\"\n,\n\"Catrina\"\n,\n\"Catriona\"\n,\n\"Catt\"\n,\n\"Cattan\"\n,\n\"Cattier\"\n,\n\"Cattima\"\n,\n\"Catto\"\n,\n\"Catton\"\n,\n\"Caty\"\n,\n\"Caughey\"\n,\n\"Caundra\"\n,\n\"Cavallaro\"\n,\n\"Cavan\"\n,\n\"Cavanagh\"\n,\n\"Cavanaugh\"\n,\n\"Cave\"\n,\n\"Caves\"\n,\n\"Cavil\"\n,\n\"Cavill\"\n,\n\"Cavit\"\n,\n\"Cavuoto\"\n,\n\"Cawley\"\n,\n\"Caye\"\n,\n\"Cayla\"\n,\n\"Caylor\"\n,\n\"Cayser\"\n,\n\"Caz\"\n,\n\"Cazzie\"\n,\n\"Cchaddie\"\n,\n\"Cece\"\n,\n\"Cecelia\"\n,\n\"Cecil\"\n,\n\"Cecile\"\n,\n\"Ceciley\"\n,\n\"Cecilia\"\n,\n\"Cecilio\"\n,\n\"Cecilius\"\n,\n\"Cecilla\"\n,\n\"Cecily\"\n,\n\"Ced\"\n,\n\"Cedar\"\n,\n\"Cedell\"\n,\n\"Cedric\"\n,\n\"Ceevah\"\n,\n\"Ceil\"\n,\n\"Cele\"\n,\n\"Celene\"\n,\n\"Celeski\"\n,\n\"Celesta\"\n,\n\"Celeste\"\n,\n\"Celestia\"\n,\n\"Celestina\"\n,\n\"Celestine\"\n,\n\"Celestyn\"\n,\n\"Celestyna\"\n,\n\"Celia\"\n,\n\"Celie\"\n,\n\"Celik\"\n,\n\"Celin\"\n,\n\"Celina\"\n,\n\"Celinda\"\n,\n\"Celine\"\n,\n\"Celinka\"\n,\n\"Celio\"\n,\n\"Celisse\"\n,\n\"Celka\"\n,\n\"Celle\"\n,\n\"Cello\"\n,\n\"Celtic\"\n,\n\"Cenac\"\n,\n\"Cence\"\n,\n\"Centeno\"\n,\n\"Center\"\n,\n\"Centonze\"\n,\n\"Ceporah\"\n,\n\"Cerallua\"\n,\n\"Cerelia\"\n,\n\"Cerell\"\n,\n\"Cerellia\"\n,\n\"Cerelly\"\n,\n\"Cerf\"\n,\n\"Cerracchio\"\n,\n\"Certie\"\n,\n\"Cerveny\"\n,\n\"Cerys\"\n,\n\"Cesar\"\n,\n\"Cesare\"\n,\n\"Cesaria\"\n,\n\"Cesaro\"\n,\n\"Cestar\"\n,\n\"Cesya\"\n,\n\"Cha\"\n,\n\"Chabot\"\n,\n\"Chace\"\n,\n\"Chad\"\n,\n\"Chadabe\"\n,\n\"Chadbourne\"\n,\n\"Chadburn\"\n,\n\"Chadd\"\n,\n\"Chaddie\"\n,\n\"Chaddy\"\n,\n\"Chader\"\n,\n\"Chadwick\"\n,\n\"Chae\"\n,\n\"Chafee\"\n,\n\"Chaffee\"\n,\n\"Chaffin\"\n,\n\"Chaffinch\"\n,\n\"Chaiken\"\n,\n\"Chaille\"\n,\n\"Chaim\"\n,\n\"Chainey\"\n,\n\"Chaing\"\n,\n\"Chak\"\n,\n\"Chaker\"\n,\n\"Chally\"\n,\n\"Chalmer\"\n,\n\"Chalmers\"\n,\n\"Chamberlain\"\n,\n\"Chamberlin\"\n,\n\"Chambers\"\n,\n\"Chamkis\"\n,\n\"Champ\"\n,\n\"Champagne\"\n,\n\"Champaigne\"\n,\n\"Chan\"\n,\n\"Chance\"\n,\n\"Chancellor\"\n,\n\"Chancelor\"\n,\n\"Chancey\"\n,\n\"Chanda\"\n,\n\"Chandal\"\n,\n\"Chandler\"\n,\n\"Chandless\"\n,\n\"Chandos\"\n,\n\"Chandra\"\n,\n\"Chane\"\n,\n\"Chaney\"\n,\n\"Chang\"\n,\n\"Changaris\"\n,\n\"Channa\"\n,\n\"Channing\"\n,\n\"Chansoo\"\n,\n\"Chantal\"\n,\n\"Chantalle\"\n,\n\"Chao\"\n,\n\"Chap\"\n,\n\"Chapa\"\n,\n\"Chapel\"\n,\n\"Chapell\"\n,\n\"Chapen\"\n,\n\"Chapin\"\n,\n\"Chapland\"\n,\n\"Chapman\"\n,\n\"Chapnick\"\n,\n\"Chappelka\"\n,\n\"Chappell\"\n,\n\"Chappie\"\n,\n\"Chappy\"\n,\n\"Chara\"\n,\n\"Charbonneau\"\n,\n\"Charbonnier\"\n,\n\"Chard\"\n,\n\"Chari\"\n,\n\"Charie\"\n,\n\"Charil\"\n,\n\"Charin\"\n,\n\"Chariot\"\n,\n\"Charis\"\n,\n\"Charissa\"\n,\n\"Charisse\"\n,\n\"Charita\"\n,\n\"Charity\"\n,\n\"Charla\"\n,\n\"Charlean\"\n,\n\"Charleen\"\n,\n\"Charlena\"\n,\n\"Charlene\"\n,\n\"Charles\"\n,\n\"Charlet\"\n,\n\"Charleton\"\n,\n\"Charley\"\n,\n\"Charlie\"\n,\n\"Charline\"\n,\n\"Charlot\"\n,\n\"Charlotta\"\n,\n\"Charlotte\"\n,\n\"Charlton\"\n,\n\"Charmain\"\n,\n\"Charmaine\"\n,\n\"Charmane\"\n,\n\"Charmian\"\n,\n\"Charmine\"\n,\n\"Charmion\"\n,\n\"Charo\"\n,\n\"Charpentier\"\n,\n\"Charron\"\n,\n\"Charry\"\n,\n\"Charteris\"\n,\n\"Charters\"\n,\n\"Charyl\"\n,\n\"Chas\"\n,\n\"Chase\"\n,\n\"Chasse\"\n,\n\"Chassin\"\n,\n\"Chastain\"\n,\n\"Chastity\"\n,\n\"Chatav\"\n,\n\"Chatterjee\"\n,\n\"Chatwin\"\n,\n\"Chaudoin\"\n,\n\"Chaunce\"\n,\n\"Chauncey\"\n,\n\"Chavaree\"\n,\n\"Chaves\"\n,\n\"Chavey\"\n,\n\"Chavez\"\n,\n\"Chaworth\"\n,\n\"Che\"\n,\n\"Cheadle\"\n,\n\"Cheatham\"\n,\n\"Checani\"\n,\n\"Chee\"\n,\n\"Cheffetz\"\n,\n\"Cheke\"\n,\n\"Chellman\"\n,\n\"Chelsae\"\n,\n\"Chelsea\"\n,\n\"Chelsey\"\n,\n\"Chelsie\"\n,\n\"Chelsy\"\n,\n\"Chelton\"\n,\n\"Chem\"\n,\n\"Chema\"\n,\n\"Chemar\"\n,\n\"Chemaram\"\n,\n\"Chemarin\"\n,\n\"Chemash\"\n,\n\"Chemesh\"\n,\n\"Chemosh\"\n,\n\"Chemush\"\n,\n\"Chen\"\n,\n\"Chenay\"\n,\n\"Chenee\"\n,\n\"Cheney\"\n,\n\"Cheng\"\n,\n\"Cher\"\n,\n\"Chere\"\n,\n\"Cherey\"\n,\n\"Cheri\"\n,\n\"Cheria\"\n,\n\"Cherian\"\n,\n\"Cherianne\"\n,\n\"Cherice\"\n,\n\"Cherida\"\n,\n\"Cherie\"\n,\n\"Cherilyn\"\n,\n\"Cherilynn\"\n,\n\"Cherin\"\n,\n\"Cherise\"\n,\n\"Cherish\"\n,\n\"Cherlyn\"\n,\n\"Chernow\"\n,\n\"Cherri\"\n,\n\"Cherrita\"\n,\n\"Cherry\"\n,\n\"Chery\"\n,\n\"Cherye\"\n,\n\"Cheryl\"\n,\n\"Ches\"\n,\n\"Cheshire\"\n,\n\"Cheslie\"\n,\n\"Chesna\"\n,\n\"Chesney\"\n,\n\"Chesnut\"\n,\n\"Chessa\"\n,\n\"Chessy\"\n,\n\"Chester\"\n,\n\"Cheston\"\n,\n\"Chet\"\n,\n\"Cheung\"\n,\n\"Chev\"\n,\n\"Chevalier\"\n,\n\"Chevy\"\n,\n\"Chew\"\n,\n\"Cheyne\"\n,\n\"Cheyney\"\n,\n\"Chi\"\n,\n\"Chiaki\"\n,\n\"Chiang\"\n,\n\"Chiarra\"\n,\n\"Chic\"\n,\n\"Chick\"\n,\n\"Chickie\"\n,\n\"Chicky\"\n,\n\"Chico\"\n,\n\"Chicoine\"\n,\n\"Chien\"\n,\n\"Chil\"\n,\n\"Chilcote\"\n,\n\"Child\"\n,\n\"Childers\"\n,\n\"Childs\"\n,\n\"Chiles\"\n,\n\"Chill\"\n,\n\"Chilson\"\n,\n\"Chilt\"\n,\n\"Chilton\"\n,\n\"Chimene\"\n,\n\"Chin\"\n,\n\"China\"\n,\n\"Ching\"\n,\n\"Chinua\"\n,\n\"Chiou\"\n,\n\"Chip\"\n,\n\"Chipman\"\n,\n\"Chiquia\"\n,\n\"Chiquita\"\n,\n\"Chirlin\"\n,\n\"Chisholm\"\n,\n\"Chita\"\n,\n\"Chitkara\"\n,\n\"Chivers\"\n,\n\"Chladek\"\n,\n\"Chlo\"\n,\n\"Chloe\"\n,\n\"Chloette\"\n,\n\"Chloras\"\n,\n\"Chlores\"\n,\n\"Chlori\"\n,\n\"Chloris\"\n,\n\"Cho\"\n,\n\"Chobot\"\n,\n\"Chon\"\n,\n\"Chong\"\n,\n\"Choo\"\n,\n\"Choong\"\n,\n\"Chor\"\n,\n\"Chouest\"\n,\n\"Chow\"\n,\n\"Chretien\"\n,\n\"Chris\"\n,\n\"Chrisman\"\n,\n\"Chrisoula\"\n,\n\"Chrissa\"\n,\n\"Chrisse\"\n,\n\"Chrissie\"\n,\n\"Chrissy\"\n,\n\"Christa\"\n,\n\"Christabel\"\n,\n\"Christabella\"\n,\n\"Christabelle\"\n,\n\"Christal\"\n,\n\"Christalle\"\n,\n\"Christan\"\n,\n\"Christean\"\n,\n\"Christel\"\n,\n\"Christen\"\n,\n\"Christensen\"\n,\n\"Christenson\"\n,\n\"Christi\"\n,\n\"Christian\"\n,\n\"Christiana\"\n,\n\"Christiane\"\n,\n\"Christianity\"\n,\n\"Christianna\"\n,\n\"Christiano\"\n,\n\"Christiansen\"\n,\n\"Christianson\"\n,\n\"Christie\"\n,\n\"Christin\"\n,\n\"Christina\"\n,\n\"Christine\"\n,\n\"Christis\"\n,\n\"Christmann\"\n,\n\"Christmas\"\n,\n\"Christoffer\"\n,\n\"Christoforo\"\n,\n\"Christoper\"\n,\n\"Christoph\"\n,\n\"Christophe\"\n,\n\"Christopher\"\n,\n\"Christos\"\n,\n\"Christy\"\n,\n\"Christye\"\n,\n\"Christyna\"\n,\n\"Chrisy\"\n,\n\"Chrotoem\"\n,\n\"Chrysa\"\n,\n\"Chrysler\"\n,\n\"Chrystal\"\n,\n\"Chryste\"\n,\n\"Chrystel\"\n,\n\"Chu\"\n,\n\"Chuah\"\n,\n\"Chubb\"\n,\n\"Chuch\"\n,\n\"Chucho\"\n,\n\"Chuck\"\n,\n\"Chud\"\n,\n\"Chui\"\n,\n\"Chuipek\"\n,\n\"Chun\"\n,\n\"Chung\"\n,\n\"Chura\"\n,\n\"Church\"\n,\n\"Churchill\"\n,\n\"Chute\"\n,\n\"Chuu\"\n,\n\"Chyou\"\n,\n\"Cia\"\n,\n\"Cianca\"\n,\n\"Ciapas\"\n,\n\"Ciapha\"\n,\n\"Ciaphus\"\n,\n\"Cibis\"\n,\n\"Ciccia\"\n,\n\"Cicely\"\n,\n\"Cicenia\"\n,\n\"Cicero\"\n,\n\"Cichocki\"\n,\n\"Cicily\"\n,\n\"Cid\"\n,\n\"Cida\"\n,\n\"Ciel\"\n,\n\"Cila\"\n,\n\"Cilka\"\n,\n\"Cilla\"\n,\n\"Cilo\"\n,\n\"Cilurzo\"\n,\n\"Cima\"\n,\n\"Cimah\"\n,\n\"Cimbura\"\n,\n\"Cinda\"\n,\n\"Cindee\"\n,\n\"Cindelyn\"\n,\n\"Cinderella\"\n,\n\"Cindi\"\n,\n\"Cindie\"\n,\n\"Cindra\"\n,\n\"Cindy\"\n,\n\"Cinelli\"\n,\n\"Cini\"\n,\n\"Cinnamon\"\n,\n\"Cioban\"\n,\n\"Cioffred\"\n,\n\"Ciprian\"\n,\n\"Circosta\"\n,\n\"Ciri\"\n,\n\"Cirilla\"\n,\n\"Cirillo\"\n,\n\"Cirilo\"\n,\n\"Ciro\"\n,\n\"Cirone\"\n,\n\"Cirri\"\n,\n\"Cis\"\n,\n\"Cissie\"\n,\n\"Cissiee\"\n,\n\"Cissy\"\n,\n\"Cita\"\n,\n\"Citarella\"\n,\n\"Citron\"\n,\n\"Clabo\"\n,\n\"Claiborn\"\n,\n\"Claiborne\"\n,\n\"Clair\"\n,\n\"Claire\"\n,\n\"Claman\"\n,\n\"Clance\"\n,\n\"Clancy\"\n,\n\"Clapp\"\n,\n\"Clapper\"\n,\n\"Clara\"\n,\n\"Clarabelle\"\n,\n\"Clarance\"\n,\n\"Clardy\"\n,\n\"Clare\"\n,\n\"Clarence\"\n,\n\"Claresta\"\n,\n\"Clareta\"\n,\n\"Claretta\"\n,\n\"Clarette\"\n,\n\"Clarey\"\n,\n\"Clarhe\"\n,\n\"Clari\"\n,\n\"Claribel\"\n,\n\"Clarice\"\n,\n\"Clarie\"\n,\n\"Clarinda\"\n,\n\"Clarine\"\n,\n\"Clarisa\"\n,\n\"Clarise\"\n,\n\"Clarissa\"\n,\n\"Clarisse\"\n,\n\"Clarita\"\n,\n\"Clark\"\n,\n\"Clarke\"\n,\n\"Clarkin\"\n,\n\"Clarkson\"\n,\n\"Clary\"\n,\n\"Claud\"\n,\n\"Clauddetta\"\n,\n\"Claude\"\n,\n\"Claudell\"\n,\n\"Claudelle\"\n,\n\"Claudetta\"\n,\n\"Claudette\"\n,\n\"Claudia\"\n,\n\"Claudian\"\n,\n\"Claudianus\"\n,\n\"Claudie\"\n,\n\"Claudina\"\n,\n\"Claudine\"\n,\n\"Claudio\"\n,\n\"Claudius\"\n,\n\"Claudy\"\n,\n\"Claus\"\n,\n\"Clausen\"\n,\n\"Clava\"\n,\n\"Clawson\"\n,\n\"Clay\"\n,\n\"Clayberg\"\n,\n\"Clayborn\"\n,\n\"Clayborne\"\n,\n\"Claybourne\"\n,\n\"Clayson\"\n,\n\"Clayton\"\n,\n\"Clea\"\n,\n\"Cleary\"\n,\n\"Cleasta\"\n,\n\"Cleave\"\n,\n\"Cleaves\"\n,\n\"Cleavland\"\n,\n\"Clein\"\n,\n\"Cleland\"\n,\n\"Clellan\"\n,\n\"Clem\"\n,\n\"Clemen\"\n,\n\"Clemence\"\n,\n\"Clemens\"\n,\n\"Clement\"\n,\n\"Clementas\"\n,\n\"Clemente\"\n,\n\"Clementi\"\n,\n\"Clementia\"\n,\n\"Clementina\"\n,\n\"Clementine\"\n,\n\"Clementis\"\n,\n\"Clementius\"\n,\n\"Clements\"\n,\n\"Clemmie\"\n,\n\"Clemmy\"\n,\n\"Cleo\"\n,\n\"Cleodal\"\n,\n\"Cleodel\"\n,\n\"Cleodell\"\n,\n\"Cleon\"\n,\n\"Cleopatra\"\n,\n\"Cleopatre\"\n,\n\"Clerc\"\n,\n\"Clercq\"\n,\n\"Clere\"\n,\n\"Cleres\"\n,\n\"Clerissa\"\n,\n\"Clerk\"\n,\n\"Cleti\"\n,\n\"Cletis\"\n,\n\"Cletus\"\n,\n\"Cleve\"\n,\n\"Cleveland\"\n,\n\"Clevey\"\n,\n\"Clevie\"\n,\n\"Clie\"\n,\n\"Cliff\"\n,\n\"Cliffes\"\n,\n\"Clifford\"\n,\n\"Clift\"\n,\n\"Clifton\"\n,\n\"Clim\"\n,\n\"Cline\"\n,\n\"Clint\"\n,\n\"Clintock\"\n,\n\"Clinton\"\n,\n\"Clio\"\n,\n\"Clippard\"\n,\n\"Clite\"\n,\n\"Clive\"\n,\n\"Clo\"\n,\n\"Cloe\"\n,\n\"Cloots\"\n,\n\"Clorinda\"\n,\n\"Clorinde\"\n,\n\"Cloris\"\n,\n\"Close\"\n,\n\"Clothilde\"\n,\n\"Clotilda\"\n,\n\"Clotilde\"\n,\n\"Clough\"\n,\n\"Clougher\"\n,\n\"Cloutman\"\n,\n\"Clova\"\n,\n\"Clovah\"\n,\n\"Clover\"\n,\n\"Clovis\"\n,\n\"Clower\"\n,\n\"Clute\"\n,\n\"Cly\"\n,\n\"Clyde\"\n,\n\"Clymer\"\n,\n\"Clynes\"\n,\n\"Clyte\"\n,\n\"Clyve\"\n,\n\"Clywd\"\n,\n\"Cnut\"\n,\n\"Coad\"\n,\n\"Coady\"\n,\n\"Coates\"\n,\n\"Coats\"\n,\n\"Cob\"\n,\n\"Cobb\"\n,\n\"Cobbie\"\n,\n\"Cobby\"\n,\n\"Coben\"\n,\n\"Cochard\"\n,\n\"Cochran\"\n,\n\"Cochrane\"\n,\n\"Cock\"\n,\n\"Cockburn\"\n,\n\"Cocke\"\n,\n\"Cocks\"\n,\n\"Coco\"\n,\n\"Codd\"\n,\n\"Codding\"\n,\n\"Codee\"\n,\n\"Codel\"\n,\n\"Codi\"\n,\n\"Codie\"\n,\n\"Cody\"\n,\n\"Coe\"\n,\n\"Coffee\"\n,\n\"Coffeng\"\n,\n\"Coffey\"\n,\n\"Coffin\"\n,\n\"Cofsky\"\n,\n\"Cogan\"\n,\n\"Cogen\"\n,\n\"Cogswell\"\n,\n\"Coh\"\n,\n\"Cohbath\"\n,\n\"Cohberg\"\n,\n\"Cohbert\"\n,\n\"Cohby\"\n,\n\"Cohdwell\"\n,\n\"Cohe\"\n,\n\"Coheman\"\n,\n\"Cohen\"\n,\n\"Cohette\"\n,\n\"Cohin\"\n,\n\"Cohl\"\n,\n\"Cohla\"\n,\n\"Cohleen\"\n,\n\"Cohlette\"\n,\n\"Cohlier\"\n,\n\"Cohligan\"\n,\n\"Cohn\"\n,\n\"Cointon\"\n,\n\"Coit\"\n,\n\"Coke\"\n,\n\"Col\"\n,\n\"Colan\"\n,\n\"Colas\"\n,\n\"Colb\"\n,\n\"Colbert\"\n,\n\"Colburn\"\n,\n\"Colby\"\n,\n\"Colbye\"\n,\n\"Cole\"\n,\n\"Coleen\"\n,\n\"Coleman\"\n,\n\"Colene\"\n,\n\"Colet\"\n,\n\"Coletta\"\n,\n\"Colette\"\n,\n\"Coleville\"\n,\n\"Colfin\"\n,\n\"Colier\"\n,\n\"Colin\"\n,\n\"Colinson\"\n,\n\"Colis\"\n,\n\"Collar\"\n,\n\"Collayer\"\n,\n\"Collbaith\"\n,\n\"Colleen\"\n,\n\"Collen\"\n,\n\"Collete\"\n,\n\"Collette\"\n,\n\"Colley\"\n,\n\"Collie\"\n,\n\"Collier\"\n,\n\"Colligan\"\n,\n\"Collimore\"\n,\n\"Collin\"\n,\n\"Colline\"\n,\n\"Collins\"\n,\n\"Collis\"\n,\n\"Collum\"\n,\n\"Colly\"\n,\n\"Collyer\"\n,\n\"Colman\"\n,\n\"Colner\"\n,\n\"Colombi\"\n,\n\"Colon\"\n,\n\"Colp\"\n,\n\"Colpin\"\n,\n\"Colson\"\n,\n\"Colston\"\n,\n\"Colt\"\n,\n\"Coltin\"\n,\n\"Colton\"\n,\n\"Coltson\"\n,\n\"Coltun\"\n,\n\"Columba\"\n,\n\"Columbine\"\n,\n\"Columbus\"\n,\n\"Columbyne\"\n,\n\"Colver\"\n,\n\"Colvert\"\n,\n\"Colville\"\n,\n\"Colvin\"\n,\n\"Colwell\"\n,\n\"Colwen\"\n,\n\"Colwin\"\n,\n\"Colyer\"\n,\n\"Combe\"\n,\n\"Combes\"\n,\n\"Combs\"\n,\n\"Comfort\"\n,\n\"Compte\"\n,\n\"Comptom\"\n,\n\"Compton\"\n,\n\"Comras\"\n,\n\"Comstock\"\n,\n\"Comyns\"\n,\n\"Con\"\n,\n\"Conah\"\n,\n\"Conal\"\n,\n\"Conall\"\n,\n\"Conan\"\n,\n\"Conant\"\n,\n\"Conard\"\n,\n\"Concepcion\"\n,\n\"Concettina\"\n,\n\"Concha\"\n,\n\"Conchita\"\n,\n\"Concoff\"\n,\n\"Concordia\"\n,\n\"Condon\"\n,\n\"Coney\"\n,\n\"Congdon\"\n,\n\"Conger\"\n,\n\"Coniah\"\n,\n\"Conias\"\n,\n\"Conlan\"\n,\n\"Conlee\"\n,\n\"Conlen\"\n,\n\"Conley\"\n,\n\"Conlin\"\n,\n\"Conlon\"\n,\n\"Conn\"\n,\n\"Connel\"\n,\n\"Connell\"\n,\n\"Connelley\"\n,\n\"Connelly\"\n,\n\"Conner\"\n,\n\"Conners\"\n,\n\"Connett\"\n,\n\"Conney\"\n,\n\"Conni\"\n,\n\"Connie\"\n,\n\"Connolly\"\n,\n\"Connor\"\n,\n\"Connors\"\n,\n\"Conny\"\n,\n\"Conover\"\n,\n\"Conrad\"\n,\n\"Conrade\"\n,\n\"Conrado\"\n,\n\"Conroy\"\n,\n\"Consalve\"\n,\n\"Consolata\"\n,\n\"Constance\"\n,\n\"Constancia\"\n,\n\"Constancy\"\n,\n\"Constant\"\n,\n\"Constanta\"\n,\n\"Constantia\"\n,\n\"Constantin\"\n,\n\"Constantina\"\n,\n\"Constantine\"\n,\n\"Constantino\"\n,\n\"Consuela\"\n,\n\"Consuelo\"\n,\n\"Conte\"\n,\n\"Conti\"\n,\n\"Converse\"\n,\n\"Convery\"\n,\n\"Conway\"\n,\n\"Cony\"\n,\n\"Conyers\"\n,\n\"Cooe\"\n,\n\"Cook\"\n,\n\"Cooke\"\n,\n\"Cookie\"\n,\n\"Cooley\"\n,\n\"Coombs\"\n,\n\"Coonan\"\n,\n\"Coop\"\n,\n\"Cooper\"\n,\n\"Cooperman\"\n,\n\"Coopersmith\"\n,\n\"Cooperstein\"\n,\n\"Cope\"\n,\n\"Copeland\"\n,\n\"Copland\"\n,\n\"Coplin\"\n,\n\"Copp\"\n,\n\"Coppinger\"\n,\n\"Coppins\"\n,\n\"Coppock\"\n,\n\"Coppola\"\n,\n\"Cora\"\n,\n\"Corabel\"\n,\n\"Corabella\"\n,\n\"Corabelle\"\n,\n\"Coral\"\n,\n\"Coralie\"\n,\n\"Coraline\"\n,\n\"Coralyn\"\n,\n\"Coray\"\n,\n\"Corbet\"\n,\n\"Corbett\"\n,\n\"Corbie\"\n,\n\"Corbin\"\n,\n\"Corby\"\n,\n\"Cord\"\n,\n\"Cordalia\"\n,\n\"Cordeelia\"\n,\n\"Cordelia\"\n,\n\"Cordelie\"\n,\n\"Cordell\"\n,\n\"Corder\"\n,\n\"Cordey\"\n,\n\"Cordi\"\n,\n\"Cordie\"\n,\n\"Cordier\"\n,\n\"Cordle\"\n,\n\"Cordova\"\n,\n\"Cordula\"\n,\n\"Cordy\"\n,\n\"Coreen\"\n,\n\"Corel\"\n,\n\"Corell\"\n,\n\"Corella\"\n,\n\"Corena\"\n,\n\"Corenda\"\n,\n\"Corene\"\n,\n\"Coretta\"\n,\n\"Corette\"\n,\n\"Corey\"\n,\n\"Cori\"\n,\n\"Coridon\"\n,\n\"Corie\"\n,\n\"Corilla\"\n,\n\"Corin\"\n,\n\"Corina\"\n,\n\"Corine\"\n,\n\"Corinna\"\n,\n\"Corinne\"\n,\n\"Coriss\"\n,\n\"Corissa\"\n,\n\"Corkhill\"\n,\n\"Corley\"\n,\n\"Corliss\"\n,\n\"Corly\"\n,\n\"Cormac\"\n,\n\"Cormack\"\n,\n\"Cormick\"\n,\n\"Cormier\"\n,\n\"Cornall\"\n,\n\"Corneille\"\n,\n\"Cornel\"\n,\n\"Cornela\"\n,\n\"Cornelia\"\n,\n\"Cornelie\"\n,\n\"Cornelius\"\n,\n\"Cornell\"\n,\n\"Cornelle\"\n,\n\"Cornew\"\n,\n\"Corney\"\n,\n\"Cornia\"\n,\n\"Cornie\"\n,\n\"Cornish\"\n,\n\"Cornwall\"\n,\n\"Cornwell\"\n,\n\"Corny\"\n,\n\"Corotto\"\n,\n\"Correna\"\n,\n\"Correy\"\n,\n\"Corri\"\n,\n\"Corrianne\"\n,\n\"Corrie\"\n,\n\"Corrina\"\n,\n\"Corrine\"\n,\n\"Corrinne\"\n,\n\"Corron\"\n,\n\"Corry\"\n,\n\"Corsetti\"\n,\n\"Corsiglia\"\n,\n\"Corso\"\n,\n\"Corson\"\n,\n\"Cort\"\n,\n\"Cortie\"\n,\n\"Cortney\"\n,\n\"Corty\"\n,\n\"Corvese\"\n,\n\"Corvin\"\n,\n\"Corwin\"\n,\n\"Corwun\"\n,\n\"Cory\"\n,\n\"Coryden\"\n,\n\"Corydon\"\n,\n\"Cos\"\n,\n\"Cosenza\"\n,\n\"Cosetta\"\n,\n\"Cosette\"\n,\n\"Coshow\"\n,\n\"Cosimo\"\n,\n\"Cosma\"\n,\n\"Cosme\"\n,\n\"Cosmo\"\n,\n\"Cost\"\n,\n\"Costa\"\n,\n\"Costanza\"\n,\n\"Costanzia\"\n,\n\"Costello\"\n,\n\"Coster\"\n,\n\"Costin\"\n,\n\"Cote\"\n,\n\"Cotsen\"\n,\n\"Cott\"\n,\n\"Cotter\"\n,\n\"Cotterell\"\n,\n\"Cottle\"\n,\n\"Cottrell\"\n,\n\"Coucher\"\n,\n\"Couchman\"\n,\n\"Coughlin\"\n,\n\"Coulombe\"\n,\n\"Coulson\"\n,\n\"Coulter\"\n,\n\"Coumas\"\n,\n\"Countess\"\n,\n\"Courcy\"\n,\n\"Court\"\n,\n\"Courtenay\"\n,\n\"Courtland\"\n,\n\"Courtnay\"\n,\n\"Courtney\"\n,\n\"Courtund\"\n,\n\"Cousin\"\n,\n\"Cousins\"\n,\n\"Coussoule\"\n,\n\"Couture\"\n,\n\"Covell\"\n,\n\"Coveney\"\n,\n\"Cowan\"\n,\n\"Coward\"\n,\n\"Cowden\"\n,\n\"Cowen\"\n,\n\"Cower\"\n,\n\"Cowey\"\n,\n\"Cowie\"\n,\n\"Cowles\"\n,\n\"Cowley\"\n,\n\"Cown\"\n,\n\"Cox\"\n,\n\"Coy\"\n,\n\"Coyle\"\n,\n\"Cozmo\"\n,\n\"Cozza\"\n,\n\"Crabb\"\n,\n\"Craddock\"\n,\n\"Craggie\"\n,\n\"Craggy\"\n,\n\"Craig\"\n,\n\"Crain\"\n,\n\"Cralg\"\n,\n\"Cram\"\n,\n\"Cramer\"\n,\n\"Cran\"\n,\n\"Crandale\"\n,\n\"Crandall\"\n,\n\"Crandell\"\n,\n\"Crane\"\n,\n\"Craner\"\n,\n\"Cranford\"\n,\n\"Cranston\"\n,\n\"Crary\"\n,\n\"Craven\"\n,\n\"Craw\"\n,\n\"Crawford\"\n,\n\"Crawley\"\n,\n\"Creamer\"\n,\n\"Crean\"\n,\n\"Creath\"\n,\n\"Creedon\"\n,\n\"Creigh\"\n,\n\"Creight\"\n,\n\"Creighton\"\n,\n\"Crelin\"\n,\n\"Crellen\"\n,\n\"Crenshaw\"\n,\n\"Cresa\"\n,\n\"Crescantia\"\n,\n\"Crescen\"\n,\n\"Crescentia\"\n,\n\"Crescin\"\n,\n\"Crescint\"\n,\n\"Cresida\"\n,\n\"Crespi\"\n,\n\"Crespo\"\n,\n\"Cressi\"\n,\n\"Cressida\"\n,\n\"Cressler\"\n,\n\"Cressy\"\n,\n\"Crichton\"\n,\n\"Crifasi\"\n,\n\"Crim\"\n,\n\"Crin\"\n,\n\"Cris\"\n,\n\"Crisey\"\n,\n\"Crispa\"\n,\n\"Crispas\"\n,\n\"Crispen\"\n,\n\"Crispin\"\n,\n\"Crissie\"\n,\n\"Crissy\"\n,\n\"Crist\"\n,\n\"Crista\"\n,\n\"Cristabel\"\n,\n\"Cristal\"\n,\n\"Cristen\"\n,\n\"Cristi\"\n,\n\"Cristian\"\n,\n\"Cristiano\"\n,\n\"Cristie\"\n,\n\"Cristin\"\n,\n\"Cristina\"\n,\n\"Cristine\"\n,\n\"Cristiona\"\n,\n\"Cristionna\"\n,\n\"Cristobal\"\n,\n\"Cristoforo\"\n,\n\"Cristy\"\n,\n\"Criswell\"\n,\n\"Critchfield\"\n,\n\"Critta\"\n,\n\"Crocker\"\n,\n\"Crockett\"\n,\n\"Crofoot\"\n,\n\"Croft\"\n,\n\"Crofton\"\n,\n\"Croix\"\n,\n\"Crompton\"\n,\n\"Cromwell\"\n,\n\"Croner\"\n,\n\"Cronin\"\n,\n\"Crooks\"\n,\n\"Croom\"\n,\n\"Crosby\"\n,\n\"Crosley\"\n,\n\"Cross\"\n,\n\"Crosse\"\n,\n\"Croteau\"\n,\n\"Crotty\"\n,\n\"Crow\"\n,\n\"Crowe\"\n,\n\"Crowell\"\n,\n\"Crowley\"\n,\n\"Crowns\"\n,\n\"Croydon\"\n,\n\"Cruce\"\n,\n\"Crudden\"\n,\n\"Cruickshank\"\n,\n\"Crutcher\"\n,\n\"Cruz\"\n,\n\"Cryan\"\n,\n\"Crysta\"\n,\n\"Crystal\"\n,\n\"Crystie\"\n,\n\"Cthrine\"\n,\n\"Cuda\"\n,\n\"Cudlip\"\n,\n\"Culberson\"\n,\n\"Culbert\"\n,\n\"Culbertson\"\n,\n\"Culhert\"\n,\n\"Cull\"\n,\n\"Cullan\"\n,\n\"Cullen\"\n,\n\"Culley\"\n,\n\"Cullie\"\n,\n\"Cullin\"\n,\n\"Culliton\"\n,\n\"Cully\"\n,\n\"Culosio\"\n,\n\"Culver\"\n,\n\"Cumine\"\n,\n\"Cumings\"\n,\n\"Cummine\"\n,\n\"Cummings\"\n,\n\"Cummins\"\n,\n\"Cung\"\n,\n\"Cunningham\"\n,\n\"Cupo\"\n,\n\"Curcio\"\n,\n\"Curhan\"\n,\n\"Curkell\"\n,\n\"Curley\"\n,\n\"Curnin\"\n,\n\"Curr\"\n,\n\"Curran\"\n,\n\"Curren\"\n,\n\"Currey\"\n,\n\"Currie\"\n,\n\"Currier\"\n,\n\"Curry\"\n,\n\"Curson\"\n,\n\"Curt\"\n,\n\"Curtice\"\n,\n\"Curtis\"\n,\n\"Curzon\"\n,\n\"Cusack\"\n,\n\"Cusick\"\n,\n\"Custer\"\n,\n\"Cut\"\n,\n\"Cutcheon\"\n,\n\"Cutcliffe\"\n,\n\"Cuthbert\"\n,\n\"Cuthbertson\"\n,\n\"Cuthburt\"\n,\n\"Cutler\"\n,\n\"Cutlerr\"\n,\n\"Cutlip\"\n,\n\"Cutlor\"\n,\n\"Cutter\"\n,\n\"Cuttie\"\n,\n\"Cuttler\"\n,\n\"Cutty\"\n,\n\"Cuyler\"\n,\n\"Cy\"\n,\n\"Cyb\"\n,\n\"Cybil\"\n,\n\"Cybill\"\n,\n\"Cychosz\"\n,\n\"Cyd\"\n,\n\"Cykana\"\n,\n\"Cyler\"\n,\n\"Cyma\"\n,\n\"Cymbre\"\n,\n\"Cyn\"\n,\n\"Cyna\"\n,\n\"Cynar\"\n,\n\"Cynara\"\n,\n\"Cynarra\"\n,\n\"Cynde\"\n,\n\"Cyndi\"\n,\n\"Cyndia\"\n,\n\"Cyndie\"\n,\n\"Cyndy\"\n,\n\"Cynera\"\n,\n\"Cynth\"\n,\n\"Cynthea\"\n,\n\"Cynthia\"\n,\n\"Cynthie\"\n,\n\"Cynthla\"\n,\n\"Cynthy\"\n,\n\"Cyprian\"\n,\n\"Cyprio\"\n,\n\"Cypro\"\n,\n\"Cyprus\"\n,\n\"Cyrano\"\n,\n\"Cyrie\"\n,\n\"Cyril\"\n,\n\"Cyrill\"\n,\n\"Cyrilla\"\n,\n\"Cyrille\"\n,\n\"Cyrillus\"\n,\n\"Cyrus\"\n,\n\"Czarra\"\n,\n\"D'Arcy\"\n,\n\"Dabbs\"\n,\n\"Daberath\"\n,\n\"Dabney\"\n,\n\"Dace\"\n,\n\"Dacey\"\n,\n\"Dachi\"\n,\n\"Dachia\"\n,\n\"Dachy\"\n,\n\"Dacia\"\n,\n\"Dacie\"\n,\n\"Dacy\"\n,\n\"Daegal\"\n,\n\"Dael\"\n,\n\"Daffi\"\n,\n\"Daffie\"\n,\n\"Daffodil\"\n,\n\"Daffy\"\n,\n\"Dafna\"\n,\n\"Dafodil\"\n,\n\"Dag\"\n,\n\"Dagall\"\n,\n\"Daggett\"\n,\n\"Daggna\"\n,\n\"Dagley\"\n,\n\"Dagmar\"\n,\n\"Dagna\"\n,\n\"Dagnah\"\n,\n\"Dagney\"\n,\n\"Dagny\"\n,\n\"Dahl\"\n,\n\"Dahle\"\n,\n\"Dahlia\"\n,\n\"Dahlstrom\"\n,\n\"Daigle\"\n,\n\"Dail\"\n,\n\"Daile\"\n,\n\"Dailey\"\n,\n\"Daisey\"\n,\n\"Daisi\"\n,\n\"Daisie\"\n,\n\"Daisy\"\n,\n\"Daitzman\"\n,\n\"Dal\"\n,\n\"Dale\"\n,\n\"Dalenna\"\n,\n\"Daley\"\n,\n\"Dalia\"\n,\n\"Dalila\"\n,\n\"Dalis\"\n,\n\"Dall\"\n,\n\"Dallas\"\n,\n\"Dalli\"\n,\n\"Dallis\"\n,\n\"Dallman\"\n,\n\"Dallon\"\n,\n\"Daloris\"\n,\n\"Dalpe\"\n,\n\"Dalston\"\n,\n\"Dalt\"\n,\n\"Dalton\"\n,\n\"Dalury\"\n,\n\"Daly\"\n,\n\"Dam\"\n,\n\"Damal\"\n,\n\"Damalas\"\n,\n\"Damales\"\n,\n\"Damali\"\n,\n\"Damalis\"\n,\n\"Damalus\"\n,\n\"Damara\"\n,\n\"Damaris\"\n,\n\"Damarra\"\n,\n\"Dambro\"\n,\n\"Dame\"\n,\n\"Damek\"\n,\n\"Damian\"\n,\n\"Damiani\"\n,\n\"Damiano\"\n,\n\"Damick\"\n,\n\"Damicke\"\n,\n\"Damien\"\n,\n\"Damita\"\n,\n\"Damle\"\n,\n\"Damon\"\n,\n\"Damour\"\n,\n\"Dan\"\n,\n\"Dana\"\n,\n\"Danae\"\n,\n\"Danaher\"\n,\n\"Danais\"\n,\n\"Danas\"\n,\n\"Danby\"\n,\n\"Danczyk\"\n,\n\"Dane\"\n,\n\"Danell\"\n,\n\"Danella\"\n,\n\"Danelle\"\n,\n\"Danete\"\n,\n\"Danette\"\n,\n\"Daney\"\n,\n\"Danforth\"\n,\n\"Dang\"\n,\n\"Dani\"\n,\n\"Dania\"\n,\n\"Daniala\"\n,\n\"Danialah\"\n,\n\"Danica\"\n,\n\"Danice\"\n,\n\"Danie\"\n,\n\"Daniel\"\n,\n\"Daniela\"\n,\n\"Daniele\"\n,\n\"Daniell\"\n,\n\"Daniella\"\n,\n\"Danielle\"\n,\n\"Daniels\"\n,\n\"Danielson\"\n,\n\"Danieu\"\n,\n\"Danika\"\n,\n\"Danila\"\n,\n\"Danit\"\n,\n\"Danita\"\n,\n\"Daniyal\"\n,\n\"Dann\"\n,\n\"Danna\"\n,\n\"Dannel\"\n,\n\"Danni\"\n,\n\"Dannica\"\n,\n\"Dannie\"\n,\n\"Dannon\"\n,\n\"Danny\"\n,\n\"Dannye\"\n,\n\"Dante\"\n,\n\"Danuloff\"\n,\n\"Danya\"\n,\n\"Danyelle\"\n,\n\"Danyette\"\n,\n\"Danyluk\"\n,\n\"Danzig\"\n,\n\"Danziger\"\n,\n\"Dao\"\n,\n\"Daph\"\n,\n\"Daphene\"\n,\n\"Daphie\"\n,\n\"Daphna\"\n,\n\"Daphne\"\n,\n\"Dar\"\n,\n\"Dara\"\n,\n\"Darach\"\n,\n\"Darb\"\n,\n\"Darbee\"\n,\n\"Darbie\"\n,\n\"Darby\"\n,\n\"Darce\"\n,\n\"Darcee\"\n,\n\"Darcey\"\n,\n\"Darci\"\n,\n\"Darcia\"\n,\n\"Darcie\"\n,\n\"Darcy\"\n,\n\"Darda\"\n,\n\"Dardani\"\n,\n\"Dare\"\n,\n\"Dareece\"\n,\n\"Dareen\"\n,\n\"Darees\"\n,\n\"Darell\"\n,\n\"Darelle\"\n,\n\"Daren\"\n,\n\"Dari\"\n,\n\"Daria\"\n,\n\"Darian\"\n,\n\"Darice\"\n,\n\"Darill\"\n,\n\"Darin\"\n,\n\"Dario\"\n,\n\"Darius\"\n,\n\"Darken\"\n,\n\"Darla\"\n,\n\"Darleen\"\n,\n\"Darlene\"\n,\n\"Darline\"\n,\n\"Darlleen\"\n,\n\"Darmit\"\n,\n\"Darn\"\n,\n\"Darnall\"\n,\n\"Darnell\"\n,\n\"Daron\"\n,\n\"Darooge\"\n,\n\"Darra\"\n,\n\"Darrel\"\n,\n\"Darrell\"\n,\n\"Darrelle\"\n,\n\"Darren\"\n,\n\"Darrey\"\n,\n\"Darrick\"\n,\n\"Darrill\"\n,\n\"Darrin\"\n,\n\"Darrow\"\n,\n\"Darryl\"\n,\n\"Darryn\"\n,\n\"Darsey\"\n,\n\"Darsie\"\n,\n\"Dart\"\n,\n\"Darton\"\n,\n\"Darwen\"\n,\n\"Darwin\"\n,\n\"Darya\"\n,\n\"Daryl\"\n,\n\"Daryle\"\n,\n\"Daryn\"\n,\n\"Dash\"\n,\n\"Dasha\"\n,\n\"Dasi\"\n,\n\"Dasie\"\n,\n\"Dasteel\"\n,\n\"Dasya\"\n,\n\"Datha\"\n,\n\"Datnow\"\n,\n\"Daub\"\n,\n\"Daugherty\"\n,\n\"Daughtry\"\n,\n\"Daukas\"\n,\n\"Daune\"\n,\n\"Dav\"\n,\n\"Dave\"\n,\n\"Daveda\"\n,\n\"Daveen\"\n,\n\"Daven\"\n,\n\"Davena\"\n,\n\"Davenport\"\n,\n\"Daveta\"\n,\n\"Davey\"\n,\n\"David\"\n,\n\"Davida\"\n,\n\"Davidde\"\n,\n\"Davide\"\n,\n\"Davidoff\"\n,\n\"Davidson\"\n,\n\"Davie\"\n,\n\"Davies\"\n,\n\"Davilman\"\n,\n\"Davin\"\n,\n\"Davina\"\n,\n\"Davine\"\n,\n\"Davis\"\n,\n\"Davison\"\n,\n\"Davita\"\n,\n\"Davon\"\n,\n\"Davy\"\n,\n\"Dawes\"\n,\n\"Dawkins\"\n,\n\"Dawn\"\n,\n\"Dawna\"\n,\n\"Dawson\"\n,\n\"Day\"\n,\n\"Daye\"\n,\n\"Dayle\"\n,\n\"Dayna\"\n,\n\"Ddene\"\n,\n\"De\"\n,\n\"De Witt\"\n,\n\"Deach\"\n,\n\"Deacon\"\n,\n\"Deadman\"\n,\n\"Dean\"\n,\n\"Deana\"\n,\n\"Deane\"\n,\n\"Deaner\"\n,\n\"Deanna\"\n,\n\"Deanne\"\n,\n\"Dearborn\"\n,\n\"Dearden\"\n,\n\"Dearman\"\n,\n\"Dearr\"\n,\n\"Deb\"\n,\n\"Debarath\"\n,\n\"Debbee\"\n,\n\"Debbi\"\n,\n\"Debbie\"\n,\n\"Debbra\"\n,\n\"Debby\"\n,\n\"Debee\"\n,\n\"Debera\"\n,\n\"Debi\"\n,\n\"Debor\"\n,\n\"Debora\"\n,\n\"Deborah\"\n,\n\"Deborath\"\n,\n\"Debra\"\n,\n\"Decamp\"\n,\n\"Decato\"\n,\n\"Decca\"\n,\n\"December\"\n,\n\"Decima\"\n,\n\"Deck\"\n,\n\"Decker\"\n,\n\"Deckert\"\n,\n\"Declan\"\n,\n\"Dede\"\n,\n\"Deden\"\n,\n\"Dedie\"\n,\n\"Dedra\"\n,\n\"Dedric\"\n,\n\"Dedrick\"\n,\n\"Dee\"\n,\n\"Dee Dee\"\n,\n\"Deeann\"\n,\n\"Deeanne\"\n,\n\"Deedee\"\n,\n\"Deegan\"\n,\n\"Deena\"\n,\n\"Deenya\"\n,\n\"Deer\"\n,\n\"Deerdre\"\n,\n\"Deering\"\n,\n\"Deery\"\n,\n\"Deeyn\"\n,\n\"Defant\"\n,\n\"Dehlia\"\n,\n\"Dehnel\"\n,\n\"Deibel\"\n,\n\"Deidre\"\n,\n\"Deina\"\n,\n\"Deirdra\"\n,\n\"Deirdre\"\n,\n\"Dekeles\"\n,\n\"Dekow\"\n,\n\"Del\"\n,\n\"Dela\"\n,\n\"Delacourt\"\n,\n\"Delaine\"\n,\n\"Delainey\"\n,\n\"Delamare\"\n,\n\"Deland\"\n,\n\"Delaney\"\n,\n\"Delanie\"\n,\n\"Delano\"\n,\n\"Delanos\"\n,\n\"Delanty\"\n,\n\"Delaryd\"\n,\n\"Delastre\"\n,\n\"Delbert\"\n,\n\"Delcina\"\n,\n\"Delcine\"\n,\n\"Delfeena\"\n,\n\"Delfine\"\n,\n\"Delgado\"\n,\n\"Delia\"\n,\n\"Delija\"\n,\n\"Delila\"\n,\n\"Delilah\"\n,\n\"Delinda\"\n,\n\"Delisle\"\n,\n\"Dell\"\n,\n\"Della\"\n,\n\"Delle\"\n,\n\"Dellora\"\n,\n\"Delly\"\n,\n\"Delmar\"\n,\n\"Delmer\"\n,\n\"Delmor\"\n,\n\"Delmore\"\n,\n\"Delogu\"\n,\n\"Delora\"\n,\n\"Delorenzo\"\n,\n\"Delores\"\n,\n\"Deloria\"\n,\n\"Deloris\"\n,\n\"Delos\"\n,\n\"Delp\"\n,\n\"Delphina\"\n,\n\"Delphine\"\n,\n\"Delphinia\"\n,\n\"Delsman\"\n,\n\"Delwin\"\n,\n\"Delwyn\"\n,\n\"Demaggio\"\n,\n\"Demakis\"\n,\n\"Demaria\"\n,\n\"Demb\"\n,\n\"Demeter\"\n,\n\"Demetra\"\n,\n\"Demetre\"\n,\n\"Demetri\"\n,\n\"Demetria\"\n,\n\"Demetris\"\n,\n\"Demetrius\"\n,\n\"Demeyer\"\n,\n\"Deming\"\n,\n\"Demitria\"\n,\n\"Demmer\"\n,\n\"Demmy\"\n,\n\"Demodena\"\n,\n\"Demona\"\n,\n\"Demott\"\n,\n\"Demp\"\n,\n\"Dempsey\"\n,\n\"Dempster\"\n,\n\"Dempstor\"\n,\n\"Demy\"\n,\n\"Den\"\n,\n\"Dena\"\n,\n\"Denae\"\n,\n\"Denbrook\"\n,\n\"Denby\"\n,\n\"Dene\"\n,\n\"Deni\"\n,\n\"Denice\"\n,\n\"Denie\"\n,\n\"Denis\"\n,\n\"Denise\"\n,\n\"Denison\"\n,\n\"Denman\"\n,\n\"Denn\"\n,\n\"Denna\"\n,\n\"Dennard\"\n,\n\"Dennet\"\n,\n\"Dennett\"\n,\n\"Denney\"\n,\n\"Denni\"\n,\n\"Dennie\"\n,\n\"Dennis\"\n,\n\"Dennison\"\n,\n\"Denny\"\n,\n\"Denoting\"\n,\n\"Dent\"\n,\n\"Denten\"\n,\n\"Denton\"\n,\n\"Denver\"\n,\n\"Deny\"\n,\n\"Denys\"\n,\n\"Denyse\"\n,\n\"Denzil\"\n,\n\"Deonne\"\n,\n\"Depoliti\"\n,\n\"Deppy\"\n,\n\"Der\"\n,\n\"Deragon\"\n,\n\"Derayne\"\n,\n\"Derby\"\n,\n\"Dercy\"\n,\n\"Derek\"\n,\n\"Derian\"\n,\n\"Derick\"\n,\n\"Derina\"\n,\n\"Derinna\"\n,\n\"Derk\"\n,\n\"Derman\"\n,\n\"Dermot\"\n,\n\"Dermott\"\n,\n\"Derna\"\n,\n\"Deron\"\n,\n\"Deroo\"\n,\n\"Derr\"\n,\n\"Derrek\"\n,\n\"Derrick\"\n,\n\"Derriey\"\n,\n\"Derrik\"\n,\n\"Derril\"\n,\n\"Derron\"\n,\n\"Derry\"\n,\n\"Derte\"\n,\n\"Derward\"\n,\n\"Derwin\"\n,\n\"Derwon\"\n,\n\"Derwood\"\n,\n\"Deryl\"\n,\n\"Derzon\"\n,\n\"Des\"\n,\n\"Desai\"\n,\n\"Desberg\"\n,\n\"Descombes\"\n,\n\"Desdamona\"\n,\n\"Desdamonna\"\n,\n\"Desdee\"\n,\n\"Desdemona\"\n,\n\"Desi\"\n,\n\"Desimone\"\n,\n\"Desirae\"\n,\n\"Desirea\"\n,\n\"Desireah\"\n,\n\"Desiree\"\n,\n\"Desiri\"\n,\n\"Desma\"\n,\n\"Desmond\"\n,\n\"Desmund\"\n,\n\"Dessma\"\n,\n\"Desta\"\n,\n\"Deste\"\n,\n\"Destinee\"\n,\n\"Deth\"\n,\n\"Dett\"\n,\n\"Detta\"\n,\n\"Dettmer\"\n,\n\"Deuno\"\n,\n\"Deutsch\"\n,\n\"Dev\"\n,\n\"Deva\"\n,\n\"Devan\"\n,\n\"Devaney\"\n,\n\"Dever\"\n,\n\"Devi\"\n,\n\"Devin\"\n,\n\"Devina\"\n,\n\"Devine\"\n,\n\"Devinna\"\n,\n\"Devinne\"\n,\n\"Devitt\"\n,\n\"Devland\"\n,\n\"Devlen\"\n,\n\"Devlin\"\n,\n\"Devol\"\n,\n\"Devon\"\n,\n\"Devona\"\n,\n\"Devondra\"\n,\n\"Devonna\"\n,\n\"Devonne\"\n,\n\"Devora\"\n,\n\"Devy\"\n,\n\"Dew\"\n,\n\"Dewain\"\n,\n\"Dewar\"\n,\n\"Dewayne\"\n,\n\"Dewees\"\n,\n\"Dewey\"\n,\n\"Dewhirst\"\n,\n\"Dewhurst\"\n,\n\"Dewie\"\n,\n\"Dewitt\"\n,\n\"Dex\"\n,\n\"Dexter\"\n,\n\"Dey\"\n,\n\"Dhar\"\n,\n\"Dhiman\"\n,\n\"Dhiren\"\n,\n\"Dhruv\"\n,\n\"Dhu\"\n,\n\"Dhumma\"\n,\n\"Di\"\n,\n\"Diahann\"\n,\n\"Diamante\"\n,\n\"Diamond\"\n,\n\"Dian\"\n,\n\"Diana\"\n,\n\"Diandra\"\n,\n\"Diandre\"\n,\n\"Diane\"\n,\n\"Diane-Marie\"\n,\n\"Dianemarie\"\n,\n\"Diann\"\n,\n\"Dianna\"\n,\n\"Dianne\"\n,\n\"Diannne\"\n,\n\"Diantha\"\n,\n\"Dianthe\"\n,\n\"Diao\"\n,\n\"Diarmid\"\n,\n\"Diarmit\"\n,\n\"Diarmuid\"\n,\n\"Diaz\"\n,\n\"Dib\"\n,\n\"Diba\"\n,\n\"Dibb\"\n,\n\"Dibbell\"\n,\n\"Dibbrun\"\n,\n\"Dibri\"\n,\n\"Dibrin\"\n,\n\"Dibru\"\n,\n\"Dich\"\n,\n\"Dichy\"\n,\n\"Dick\"\n,\n\"Dickens\"\n,\n\"Dickenson\"\n,\n\"Dickerson\"\n,\n\"Dickey\"\n,\n\"Dickie\"\n,\n\"Dickinson\"\n,\n\"Dickman\"\n,\n\"Dicks\"\n,\n\"Dickson\"\n,\n\"Dicky\"\n,\n\"Didi\"\n,\n\"Didier\"\n,\n\"Dido\"\n,\n\"Dieball\"\n,\n\"Diego\"\n,\n\"Diehl\"\n,\n\"Diella\"\n,\n\"Dielle\"\n,\n\"Dielu\"\n,\n\"Diena\"\n,\n\"Dierdre\"\n,\n\"Dierolf\"\n,\n\"Diet\"\n,\n\"Dieter\"\n,\n\"Dieterich\"\n,\n\"Dietrich\"\n,\n\"Dietsche\"\n,\n\"Dietz\"\n,\n\"Dikmen\"\n,\n\"Dilan\"\n,\n\"Diley\"\n,\n\"Dilisio\"\n,\n\"Dilks\"\n,\n\"Dill\"\n,\n\"Dillie\"\n,\n\"Dillon\"\n,\n\"Dilly\"\n,\n\"Dimitri\"\n,\n\"Dimitris\"\n,\n\"Dimitry\"\n,\n\"Dimmick\"\n,\n\"Dimond\"\n,\n\"Dimphia\"\n,\n\"Dina\"\n,\n\"Dinah\"\n,\n\"Dinan\"\n,\n\"Dincolo\"\n,\n\"Dine\"\n,\n\"Dinerman\"\n,\n\"Dinesh\"\n,\n\"Dinin\"\n,\n\"Dinnage\"\n,\n\"Dinnie\"\n,\n\"Dinny\"\n,\n\"Dino\"\n,\n\"Dinsdale\"\n,\n\"Dinse\"\n,\n\"Dinsmore\"\n,\n\"Diogenes\"\n,\n\"Dion\"\n,\n\"Dione\"\n,\n\"Dionis\"\n,\n\"Dionisio\"\n,\n\"Dionne\"\n,\n\"Dionysus\"\n,\n\"Dippold\"\n,\n\"Dira\"\n,\n\"Dirk\"\n,\n\"Disario\"\n,\n\"Disharoon\"\n,\n\"Disini\"\n,\n\"Diskin\"\n,\n\"Diskson\"\n,\n\"Disraeli\"\n,\n\"Dita\"\n,\n\"Ditmore\"\n,\n\"Ditter\"\n,\n\"Dittman\"\n,\n\"Dituri\"\n,\n\"Ditzel\"\n,\n\"Diver\"\n,\n\"Divine\"\n,\n\"Dix\"\n,\n\"Dixie\"\n,\n\"Dixil\"\n,\n\"Dixon\"\n,\n\"Dmitri\"\n,\n\"Dniren\"\n,\n\"Doak\"\n,\n\"Doane\"\n,\n\"Dobb\"\n,\n\"Dobbins\"\n,\n\"Doble\"\n,\n\"Dobrinsky\"\n,\n\"Dobson\"\n,\n\"Docia\"\n,\n\"Docila\"\n,\n\"Docile\"\n,\n\"Docilla\"\n,\n\"Docilu\"\n,\n\"Dodd\"\n,\n\"Dodds\"\n,\n\"Dode\"\n,\n\"Dodge\"\n,\n\"Dodi\"\n,\n\"Dodie\"\n,\n\"Dodson\"\n,\n\"Dodwell\"\n,\n\"Dody\"\n,\n\"Doe\"\n,\n\"Doehne\"\n,\n\"Doelling\"\n,\n\"Doerrer\"\n,\n\"Doersten\"\n,\n\"Doggett\"\n,\n\"Dogs\"\n,\n\"Doherty\"\n,\n\"Doi\"\n,\n\"Doig\"\n,\n\"Dola\"\n,\n\"Dolan\"\n,\n\"Dole\"\n,\n\"Doley\"\n,\n\"Dolf\"\n,\n\"Dolhenty\"\n,\n\"Doll\"\n,\n\"Dollar\"\n,\n\"Dolley\"\n,\n\"Dolli\"\n,\n\"Dollie\"\n,\n\"Dolloff\"\n,\n\"Dolly\"\n,\n\"Dolora\"\n,\n\"Dolores\"\n,\n\"Dolorita\"\n,\n\"Doloritas\"\n,\n\"Dolph\"\n,\n\"Dolphin\"\n,\n\"Dom\"\n,\n\"Domash\"\n,\n\"Dombrowski\"\n,\n\"Domel\"\n,\n\"Domela\"\n,\n\"Domella\"\n,\n\"Domenech\"\n,\n\"Domenic\"\n,\n\"Domenico\"\n,\n\"Domeniga\"\n,\n\"Domineca\"\n,\n\"Dominga\"\n,\n\"Domingo\"\n,\n\"Domini\"\n,\n\"Dominic\"\n,\n\"Dominica\"\n,\n\"Dominick\"\n,\n\"Dominik\"\n,\n\"Dominique\"\n,\n\"Dominus\"\n,\n\"Dominy\"\n,\n\"Domonic\"\n,\n\"Domph\"\n,\n\"Don\"\n,\n\"Dona\"\n,\n\"Donadee\"\n,\n\"Donaghue\"\n,\n\"Donahoe\"\n,\n\"Donahue\"\n,\n\"Donal\"\n,\n\"Donald\"\n,\n\"Donaldson\"\n,\n\"Donall\"\n,\n\"Donalt\"\n,\n\"Donata\"\n,\n\"Donatelli\"\n,\n\"Donaugh\"\n,\n\"Donavon\"\n,\n\"Donegan\"\n,\n\"Donela\"\n,\n\"Donell\"\n,\n\"Donella\"\n,\n\"Donelle\"\n,\n\"Donelson\"\n,\n\"Donelu\"\n,\n\"Doner\"\n,\n\"Donetta\"\n,\n\"Dong\"\n,\n\"Donia\"\n,\n\"Donica\"\n,\n\"Donielle\"\n,\n\"Donn\"\n,\n\"Donna\"\n,\n\"Donnamarie\"\n,\n\"Donnell\"\n,\n\"Donnelly\"\n,\n\"Donnenfeld\"\n,\n\"Donni\"\n,\n\"Donnie\"\n,\n\"Donny\"\n,\n\"Donoghue\"\n,\n\"Donoho\"\n,\n\"Donohue\"\n,\n\"Donough\"\n,\n\"Donovan\"\n,\n\"Doolittle\"\n,\n\"Doone\"\n,\n\"Dopp\"\n,\n\"Dora\"\n,\n\"Doralia\"\n,\n\"Doralin\"\n,\n\"Doralyn\"\n,\n\"Doralynn\"\n,\n\"Doralynne\"\n,\n\"Doran\"\n,\n\"Dorca\"\n,\n\"Dorcas\"\n,\n\"Dorcea\"\n,\n\"Dorcia\"\n,\n\"Dorcus\"\n,\n\"Dorcy\"\n,\n\"Dore\"\n,\n\"Doreen\"\n,\n\"Dorelia\"\n,\n\"Dorella\"\n,\n\"Dorelle\"\n,\n\"Dorena\"\n,\n\"Dorene\"\n,\n\"Doretta\"\n,\n\"Dorette\"\n,\n\"Dorey\"\n,\n\"Dorfman\"\n,\n\"Dori\"\n,\n\"Doria\"\n,\n\"Dorian\"\n,\n\"Dorice\"\n,\n\"Dorie\"\n,\n\"Dorin\"\n,\n\"Dorina\"\n,\n\"Dorinda\"\n,\n\"Dorine\"\n,\n\"Dorion\"\n,\n\"Doris\"\n,\n\"Dorisa\"\n,\n\"Dorise\"\n,\n\"Dorison\"\n,\n\"Dorita\"\n,\n\"Dorkas\"\n,\n\"Dorkus\"\n,\n\"Dorlisa\"\n,\n\"Dorman\"\n,\n\"Dorn\"\n,\n\"Doro\"\n,\n\"Dorolice\"\n,\n\"Dorolisa\"\n,\n\"Dorotea\"\n,\n\"Doroteya\"\n,\n\"Dorothea\"\n,\n\"Dorothee\"\n,\n\"Dorothi\"\n,\n\"Dorothy\"\n,\n\"Dorr\"\n,\n\"Dorran\"\n,\n\"Dorree\"\n,\n\"Dorren\"\n,\n\"Dorri\"\n,\n\"Dorrie\"\n,\n\"Dorris\"\n,\n\"Dorry\"\n,\n\"Dorsey\"\n,\n\"Dorsman\"\n,\n\"Dorsy\"\n,\n\"Dorthea\"\n,\n\"Dorthy\"\n,\n\"Dorweiler\"\n,\n\"Dorwin\"\n,\n\"Dory\"\n,\n\"Doscher\"\n,\n\"Dosh\"\n,\n\"Dosi\"\n,\n\"Dosia\"\n,\n\"Doss\"\n,\n\"Dot\"\n,\n\"Doti\"\n,\n\"Dotson\"\n,\n\"Dott\"\n,\n\"Dotti\"\n,\n\"Dottie\"\n,\n\"Dotty\"\n,\n\"Doty\"\n,\n\"Doubler\"\n,\n\"Doug\"\n,\n\"Dougal\"\n,\n\"Dougald\"\n,\n\"Dougall\"\n,\n\"Dougherty\"\n,\n\"Doughman\"\n,\n\"Doughty\"\n,\n\"Dougie\"\n,\n\"Douglas\"\n,\n\"Douglass\"\n,\n\"Dougy\"\n,\n\"Douty\"\n,\n\"Douville\"\n,\n\"Dov\"\n,\n\"Dove\"\n,\n\"Dovev\"\n,\n\"Dow\"\n,\n\"Dowd\"\n,\n\"Dowdell\"\n,\n\"Dowell\"\n,\n\"Dowlen\"\n,\n\"Dowling\"\n,\n\"Down\"\n,\n\"Downall\"\n,\n\"Downe\"\n,\n\"Downes\"\n,\n\"Downey\"\n,\n\"Downing\"\n,\n\"Downs\"\n,\n\"Dowski\"\n,\n\"Dowzall\"\n,\n\"Doxia\"\n,\n\"Doy\"\n,\n\"Doykos\"\n,\n\"Doyle\"\n,\n\"Drabeck\"\n,\n\"Dragelin\"\n,\n\"Dragon\"\n,\n\"Dragone\"\n,\n\"Dragoon\"\n,\n\"Drain\"\n,\n\"Drais\"\n,\n\"Drake\"\n,\n\"Drandell\"\n,\n\"Drape\"\n,\n\"Draper\"\n,\n\"Dray\"\n,\n\"Dre\"\n,\n\"Dream\"\n,\n\"Dreda\"\n,\n\"Dreddy\"\n,\n\"Dredi\"\n,\n\"Dreeda\"\n,\n\"Dreher\"\n,\n\"Dremann\"\n,\n\"Drescher\"\n,\n\"Dressel\"\n,\n\"Dressler\"\n,\n\"Drew\"\n,\n\"Drewett\"\n,\n\"Drews\"\n,\n\"Drexler\"\n,\n\"Dreyer\"\n,\n\"Dric\"\n,\n\"Drice\"\n,\n\"Drida\"\n,\n\"Dripps\"\n,\n\"Driscoll\"\n,\n\"Driskill\"\n,\n\"Drisko\"\n,\n\"Drislane\"\n,\n\"Drobman\"\n,\n\"Drogin\"\n,\n\"Drolet\"\n,\n\"Drona\"\n,\n\"Dronski\"\n,\n\"Drooff\"\n,\n\"Dru\"\n,\n\"Druce\"\n,\n\"Druci\"\n,\n\"Drucie\"\n,\n\"Drucill\"\n,\n\"Drucilla\"\n,\n\"Drucy\"\n,\n\"Drud\"\n,\n\"Drue\"\n,\n\"Drugge\"\n,\n\"Drugi\"\n,\n\"Drummond\"\n,\n\"Drus\"\n,\n\"Drusi\"\n,\n\"Drusie\"\n,\n\"Drusilla\"\n,\n\"Drusus\"\n,\n\"Drusy\"\n,\n\"Dry\"\n,\n\"Dryden\"\n,\n\"Drye\"\n,\n\"Dryfoos\"\n,\n\"DuBois\"\n,\n\"Duane\"\n,\n\"Duarte\"\n,\n\"Duax\"\n,\n\"Dubenko\"\n,\n\"Dublin\"\n,\n\"Ducan\"\n,\n\"Duck\"\n,\n\"Dud\"\n,\n\"Dudden\"\n,\n\"Dudley\"\n,\n\"Duer\"\n,\n\"Duester\"\n,\n\"Duff\"\n,\n\"Duffie\"\n,\n\"Duffy\"\n,\n\"Dugaid\"\n,\n\"Dugald\"\n,\n\"Dugan\"\n,\n\"Dugas\"\n,\n\"Duggan\"\n,\n\"Duhl\"\n,\n\"Duke\"\n,\n\"Dukey\"\n,\n\"Dukie\"\n,\n\"Duky\"\n,\n\"Dulce\"\n,\n\"Dulcea\"\n,\n\"Dulci\"\n,\n\"Dulcia\"\n,\n\"Dulciana\"\n,\n\"Dulcie\"\n,\n\"Dulcine\"\n,\n\"Dulcinea\"\n,\n\"Dulcle\"\n,\n\"Dulcy\"\n,\n\"Duleba\"\n,\n\"Dulla\"\n,\n\"Dulsea\"\n,\n\"Duma\"\n,\n\"Dumah\"\n,\n\"Dumanian\"\n,\n\"Dumas\"\n,\n\"Dumm\"\n,\n\"Dumond\"\n,\n\"Dun\"\n,\n\"Dunaville\"\n,\n\"Dunc\"\n,\n\"Duncan\"\n,\n\"Dunham\"\n,\n\"Dunkin\"\n,\n\"Dunlavy\"\n,\n\"Dunn\"\n,\n\"Dunning\"\n,\n\"Dunseath\"\n,\n\"Dunson\"\n,\n\"Dunstan\"\n,\n\"Dunston\"\n,\n\"Dunton\"\n,\n\"Duntson\"\n,\n\"Duong\"\n,\n\"Dupaix\"\n,\n\"Dupin\"\n,\n\"Dupre\"\n,\n\"Dupuis\"\n,\n\"Dupuy\"\n,\n\"Duquette\"\n,\n\"Dur\"\n,\n\"Durand\"\n,\n\"Durant\"\n,\n\"Durante\"\n,\n\"Durarte\"\n,\n\"Durer\"\n,\n\"Durgy\"\n,\n\"Durham\"\n,\n\"Durkee\"\n,\n\"Durkin\"\n,\n\"Durman\"\n,\n\"Durnan\"\n,\n\"Durning\"\n,\n\"Durno\"\n,\n\"Durr\"\n,\n\"Durrace\"\n,\n\"Durrell\"\n,\n\"Durrett\"\n,\n\"Durst\"\n,\n\"Durstin\"\n,\n\"Durston\"\n,\n\"Durtschi\"\n,\n\"Durward\"\n,\n\"Durware\"\n,\n\"Durwin\"\n,\n\"Durwood\"\n,\n\"Durwyn\"\n,\n\"Dusa\"\n,\n\"Dusen\"\n,\n\"Dust\"\n,\n\"Dustan\"\n,\n\"Duster\"\n,\n\"Dustie\"\n,\n\"Dustin\"\n,\n\"Dustman\"\n,\n\"Duston\"\n,\n\"Dusty\"\n,\n\"Dusza\"\n,\n\"Dutch\"\n,\n\"Dutchman\"\n,\n\"Duthie\"\n,\n\"Duval\"\n,\n\"Duvall\"\n,\n\"Duwalt\"\n,\n\"Duwe\"\n,\n\"Duyne\"\n,\n\"Dwain\"\n,\n\"Dwaine\"\n,\n\"Dwan\"\n,\n\"Dwane\"\n,\n\"Dwayne\"\n,\n\"Dweck\"\n,\n\"Dwight\"\n,\n\"Dwinnell\"\n,\n\"Dworman\"\n,\n\"Dwyer\"\n,\n\"Dyal\"\n,\n\"Dyan\"\n,\n\"Dyana\"\n,\n\"Dyane\"\n,\n\"Dyann\"\n,\n\"Dyanna\"\n,\n\"Dyanne\"\n,\n\"Dyche\"\n,\n\"Dyer\"\n,\n\"Dygal\"\n,\n\"Dygall\"\n,\n\"Dygert\"\n,\n\"Dyke\"\n,\n\"Dyl\"\n,\n\"Dylan\"\n,\n\"Dylana\"\n,\n\"Dylane\"\n,\n\"Dymoke\"\n,\n\"Dympha\"\n,\n\"Dymphia\"\n,\n\"Dyna\"\n,\n\"Dynah\"\n,\n\"Dysart\"\n,\n\"Dyson\"\n,\n\"Dyun\"\n,\n\"Dzoba\"\n,\n\"Eachelle\"\n,\n\"Eachern\"\n,\n\"Eada\"\n,\n\"Eade\"\n,\n\"Eadie\"\n,\n\"Eadith\"\n,\n\"Eadmund\"\n,\n\"Eads\"\n,\n\"Eadwina\"\n,\n\"Eadwine\"\n,\n\"Eagle\"\n,\n\"Eal\"\n,\n\"Ealasaid\"\n,\n\"Eamon\"\n,\n\"Eanore\"\n,\n\"Earl\"\n,\n\"Earla\"\n,\n\"Earle\"\n,\n\"Earleen\"\n,\n\"Earlene\"\n,\n\"Earley\"\n,\n\"Earlie\"\n,\n\"Early\"\n,\n\"Eartha\"\n,\n\"Earvin\"\n,\n\"East\"\n,\n\"Easter\"\n,\n\"Eastlake\"\n,\n\"Eastman\"\n,\n\"Easton\"\n,\n\"Eaton\"\n,\n\"Eatton\"\n,\n\"Eaves\"\n,\n\"Eb\"\n,\n\"Eba\"\n,\n\"Ebarta\"\n,\n\"Ebba\"\n,\n\"Ebbarta\"\n,\n\"Ebberta\"\n,\n\"Ebbie\"\n,\n\"Ebby\"\n,\n\"Eben\"\n,\n\"Ebeneser\"\n,\n\"Ebenezer\"\n,\n\"Eberhard\"\n,\n\"Eberhart\"\n,\n\"Eberle\"\n,\n\"Eberly\"\n,\n\"Ebert\"\n,\n\"Eberta\"\n,\n\"Eberto\"\n,\n\"Ebner\"\n,\n\"Ebneter\"\n,\n\"Eboh\"\n,\n\"Ebonee\"\n,\n\"Ebony\"\n,\n\"Ebsen\"\n,\n\"Echikson\"\n,\n\"Echo\"\n,\n\"Eckardt\"\n,\n\"Eckart\"\n,\n\"Eckblad\"\n,\n\"Eckel\"\n,\n\"Eckhardt\"\n,\n\"Eckmann\"\n,\n\"Econah\"\n,\n\"Ed\"\n,\n\"Eda\"\n,\n\"Edan\"\n,\n\"Edana\"\n,\n\"Edbert\"\n,\n\"Edd\"\n,\n\"Edda\"\n,\n\"Eddana\"\n,\n\"Eddi\"\n,\n\"Eddie\"\n,\n\"Eddina\"\n,\n\"Eddra\"\n,\n\"Eddy\"\n,\n\"Ede\"\n,\n\"Edea\"\n,\n\"Edee\"\n,\n\"Edeline\"\n,\n\"Edelman\"\n,\n\"Edelson\"\n,\n\"Edelstein\"\n,\n\"Edelsten\"\n,\n\"Eden\"\n,\n\"Edette\"\n,\n\"Edgar\"\n,\n\"Edgard\"\n,\n\"Edgardo\"\n,\n\"Edge\"\n,\n\"Edgell\"\n,\n\"Edgerton\"\n,\n\"Edholm\"\n,\n\"Edi\"\n,\n\"Edie\"\n,\n\"Edik\"\n,\n\"Edin\"\n,\n\"Edina\"\n,\n\"Edison\"\n,\n\"Edita\"\n,\n\"Edith\"\n,\n\"Editha\"\n,\n\"Edithe\"\n,\n\"Ediva\"\n,\n\"Edla\"\n,\n\"Edlin\"\n,\n\"Edlun\"\n,\n\"Edlyn\"\n,\n\"Edmanda\"\n,\n\"Edme\"\n,\n\"Edmea\"\n,\n\"Edmead\"\n,\n\"Edmee\"\n,\n\"Edmon\"\n,\n\"Edmond\"\n,\n\"Edmonda\"\n,\n\"Edmondo\"\n,\n\"Edmonds\"\n,\n\"Edmund\"\n,\n\"Edmunda\"\n,\n\"Edna\"\n,\n\"Edny\"\n,\n\"Edora\"\n,\n\"Edouard\"\n,\n\"Edra\"\n,\n\"Edrea\"\n,\n\"Edrei\"\n,\n\"Edric\"\n,\n\"Edrick\"\n,\n\"Edris\"\n,\n\"Edrock\"\n,\n\"Edroi\"\n,\n\"Edsel\"\n,\n\"Edson\"\n,\n\"Eduard\"\n,\n\"Eduardo\"\n,\n\"Eduino\"\n,\n\"Edva\"\n,\n\"Edvard\"\n,\n\"Edveh\"\n,\n\"Edward\"\n,\n\"Edwards\"\n,\n\"Edwin\"\n,\n\"Edwina\"\n,\n\"Edwine\"\n,\n\"Edwyna\"\n,\n\"Edy\"\n,\n\"Edyth\"\n,\n\"Edythe\"\n,\n\"Effie\"\n,\n\"Effy\"\n,\n\"Efram\"\n,\n\"Efrem\"\n,\n\"Efren\"\n,\n\"Efron\"\n,\n\"Efthim\"\n,\n\"Egan\"\n,\n\"Egarton\"\n,\n\"Egbert\"\n,\n\"Egerton\"\n,\n\"Eggett\"\n,\n\"Eggleston\"\n,\n\"Egide\"\n,\n\"Egidio\"\n,\n\"Egidius\"\n,\n\"Egin\"\n,\n\"Eglanteen\"\n,\n\"Eglantine\"\n,\n\"Egon\"\n,\n\"Egor\"\n,\n\"Egwan\"\n,\n\"Egwin\"\n,\n\"Ehling\"\n,\n\"Ehlke\"\n,\n\"Ehman\"\n,\n\"Ehr\"\n,\n\"Ehrenberg\"\n,\n\"Ehrlich\"\n,\n\"Ehrman\"\n,\n\"Ehrsam\"\n,\n\"Ehud\"\n,\n\"Ehudd\"\n,\n\"Eichman\"\n,\n\"Eidson\"\n,\n\"Eiger\"\n,\n\"Eileen\"\n,\n\"Eilis\"\n,\n\"Eimile\"\n,\n\"Einberger\"\n,\n\"Einhorn\"\n,\n\"Eipper\"\n,\n\"Eirena\"\n,\n\"Eirene\"\n,\n\"Eisele\"\n,\n\"Eisen\"\n,\n\"Eisenberg\"\n,\n\"Eisenhart\"\n,\n\"Eisenstark\"\n,\n\"Eiser\"\n,\n\"Eisinger\"\n,\n\"Eisler\"\n,\n\"Eiten\"\n,\n\"Ekaterina\"\n,\n\"El\"\n,\n\"Ela\"\n,\n\"Elah\"\n,\n\"Elaina\"\n,\n\"Elaine\"\n,\n\"Elana\"\n,\n\"Elane\"\n,\n\"Elata\"\n,\n\"Elatia\"\n,\n\"Elayne\"\n,\n\"Elazaro\"\n,\n\"Elbart\"\n,\n\"Elberfeld\"\n,\n\"Elbert\"\n,\n\"Elberta\"\n,\n\"Elbertina\"\n,\n\"Elbertine\"\n,\n\"Elboa\"\n,\n\"Elbring\"\n,\n\"Elburr\"\n,\n\"Elburt\"\n,\n\"Elconin\"\n,\n\"Elda\"\n,\n\"Elden\"\n,\n\"Elder\"\n,\n\"Eldin\"\n,\n\"Eldon\"\n,\n\"Eldora\"\n,\n\"Eldorado\"\n,\n\"Eldoree\"\n,\n\"Eldoria\"\n,\n\"Eldred\"\n,\n\"Eldreda\"\n,\n\"Eldredge\"\n,\n\"Eldreeda\"\n,\n\"Eldrid\"\n,\n\"Eldrida\"\n,\n\"Eldridge\"\n,\n\"Eldwen\"\n,\n\"Eldwin\"\n,\n\"Eldwon\"\n,\n\"Eldwun\"\n,\n\"Eleanor\"\n,\n\"Eleanora\"\n,\n\"Eleanore\"\n,\n\"Eleazar\"\n,\n\"Electra\"\n,\n\"Eleen\"\n,\n\"Elena\"\n,\n\"Elene\"\n,\n\"Eleni\"\n,\n\"Elenore\"\n,\n\"Eleonora\"\n,\n\"Eleonore\"\n,\n\"Eleph\"\n,\n\"Elephus\"\n,\n\"Elery\"\n,\n\"Elexa\"\n,\n\"Elfie\"\n,\n\"Elfont\"\n,\n\"Elfreda\"\n,\n\"Elfrida\"\n,\n\"Elfrieda\"\n,\n\"Elfstan\"\n,\n\"Elga\"\n,\n\"Elgar\"\n,\n\"Eli\"\n,\n\"Elia\"\n,\n\"Eliades\"\n,\n\"Elianora\"\n,\n\"Elianore\"\n,\n\"Elias\"\n,\n\"Eliason\"\n,\n\"Eliath\"\n,\n\"Eliathan\"\n,\n\"Eliathas\"\n,\n\"Elicia\"\n,\n\"Elidad\"\n,\n\"Elie\"\n,\n\"Eliezer\"\n,\n\"Eliga\"\n,\n\"Elihu\"\n,\n\"Elijah\"\n,\n\"Elinor\"\n,\n\"Elinore\"\n,\n\"Eliot\"\n,\n\"Eliott\"\n,\n\"Elisa\"\n,\n\"Elisabet\"\n,\n\"Elisabeth\"\n,\n\"Elisabetta\"\n,\n\"Elise\"\n,\n\"Elisee\"\n,\n\"Eliseo\"\n,\n\"Elish\"\n,\n\"Elisha\"\n,\n\"Elison\"\n,\n\"Elissa\"\n,\n\"Elita\"\n,\n\"Eliza\"\n,\n\"Elizabet\"\n,\n\"Elizabeth\"\n,\n\"Elka\"\n,\n\"Elke\"\n,\n\"Elkin\"\n,\n\"Ella\"\n,\n\"Elladine\"\n,\n\"Ellan\"\n,\n\"Ellard\"\n,\n\"Ellary\"\n,\n\"Ellata\"\n,\n\"Elle\"\n,\n\"Ellen\"\n,\n\"Ellene\"\n,\n\"Ellerd\"\n,\n\"Ellerey\"\n,\n\"Ellersick\"\n,\n\"Ellery\"\n,\n\"Ellett\"\n,\n\"Ellette\"\n,\n\"Ellga\"\n,\n\"Elli\"\n,\n\"Ellicott\"\n,\n\"Ellie\"\n,\n\"Ellinger\"\n,\n\"Ellingston\"\n,\n\"Elliot\"\n,\n\"Elliott\"\n,\n\"Ellis\"\n,\n\"Ellison\"\n,\n\"Ellissa\"\n,\n\"Ellita\"\n,\n\"Ellmyer\"\n,\n\"Ellon\"\n,\n\"Ellora\"\n,\n\"Ellord\"\n,\n\"Ellswerth\"\n,\n\"Ellsworth\"\n,\n\"Ellwood\"\n,\n\"Elly\"\n,\n\"Ellyn\"\n,\n\"Ellynn\"\n,\n\"Elma\"\n,\n\"Elmajian\"\n,\n\"Elmaleh\"\n,\n\"Elman\"\n,\n\"Elmer\"\n,\n\"Elmina\"\n,\n\"Elmira\"\n,\n\"Elmo\"\n,\n\"Elmore\"\n,\n\"Elna\"\n,\n\"Elnar\"\n,\n\"Elnora\"\n,\n\"Elnore\"\n,\n\"Elo\"\n,\n\"Elodea\"\n,\n\"Elodia\"\n,\n\"Elodie\"\n,\n\"Eloisa\"\n,\n\"Eloise\"\n,\n\"Elon\"\n,\n\"Elonore\"\n,\n\"Elora\"\n,\n\"Elreath\"\n,\n\"Elrod\"\n,\n\"Elroy\"\n,\n\"Els\"\n,\n\"Elsa\"\n,\n\"Elsbeth\"\n,\n\"Else\"\n,\n\"Elset\"\n,\n\"Elsey\"\n,\n\"Elsi\"\n,\n\"Elsie\"\n,\n\"Elsinore\"\n,\n\"Elson\"\n,\n\"Elspet\"\n,\n\"Elspeth\"\n,\n\"Elstan\"\n,\n\"Elston\"\n,\n\"Elsworth\"\n,\n\"Elsy\"\n,\n\"Elton\"\n,\n\"Elum\"\n,\n\"Elurd\"\n,\n\"Elva\"\n,\n\"Elvah\"\n,\n\"Elvera\"\n,\n\"Elvia\"\n,\n\"Elvie\"\n,\n\"Elvin\"\n,\n\"Elvina\"\n,\n\"Elvira\"\n,\n\"Elvis\"\n,\n\"Elvyn\"\n,\n\"Elwaine\"\n,\n\"Elwee\"\n,\n\"Elwin\"\n,\n\"Elwina\"\n,\n\"Elwira\"\n,\n\"Elwood\"\n,\n\"Elwyn\"\n,\n\"Ely\"\n,\n\"Elyn\"\n,\n\"Elyse\"\n,\n\"Elysee\"\n,\n\"Elysha\"\n,\n\"Elysia\"\n,\n\"Elyssa\"\n,\n\"Em\"\n,\n\"Ema\"\n,\n\"Emad\"\n,\n\"Emalee\"\n,\n\"Emalia\"\n,\n\"Emanuel\"\n,\n\"Emanuela\"\n,\n\"Emanuele\"\n,\n\"Emarie\"\n,\n\"Embry\"\n,\n\"Emee\"\n,\n\"Emelda\"\n,\n\"Emelen\"\n,\n\"Emelia\"\n,\n\"Emelin\"\n,\n\"Emelina\"\n,\n\"Emeline\"\n,\n\"Emelita\"\n,\n\"Emelun\"\n,\n\"Emelyne\"\n,\n\"Emera\"\n,\n\"Emerald\"\n,\n\"Emeric\"\n,\n\"Emerick\"\n,\n\"Emersen\"\n,\n\"Emerson\"\n,\n\"Emery\"\n,\n\"Emie\"\n,\n\"Emil\"\n,\n\"Emile\"\n,\n\"Emilee\"\n,\n\"Emili\"\n,\n\"Emilia\"\n,\n\"Emilie\"\n,\n\"Emiline\"\n,\n\"Emilio\"\n,\n\"Emily\"\n,\n\"Emina\"\n,\n\"Emlen\"\n,\n\"Emlin\"\n,\n\"Emlyn\"\n,\n\"Emlynn\"\n,\n\"Emlynne\"\n,\n\"Emma\"\n,\n\"Emmalee\"\n,\n\"Emmaline\"\n,\n\"Emmalyn\"\n,\n\"Emmalynn\"\n,\n\"Emmalynne\"\n,\n\"Emmanuel\"\n,\n\"Emmeline\"\n,\n\"Emmer\"\n,\n\"Emmeram\"\n,\n\"Emmerich\"\n,\n\"Emmerie\"\n,\n\"Emmery\"\n,\n\"Emmet\"\n,\n\"Emmett\"\n,\n\"Emmey\"\n,\n\"Emmi\"\n,\n\"Emmie\"\n,\n\"Emmit\"\n,\n\"Emmons\"\n,\n\"Emmott\"\n,\n\"Emmuela\"\n,\n\"Emmy\"\n,\n\"Emmye\"\n,\n\"Emogene\"\n,\n\"Emory\"\n,\n\"Emrich\"\n,\n\"Emsmus\"\n,\n\"Emyle\"\n,\n\"Emylee\"\n,\n\"Enalda\"\n,\n\"Encrata\"\n,\n\"Encratia\"\n,\n\"Encratis\"\n,\n\"End\"\n,\n\"Ender\"\n,\n\"Endo\"\n,\n\"Endor\"\n,\n\"Endora\"\n,\n\"Endres\"\n,\n\"Enenstein\"\n,\n\"Eng\"\n,\n\"Engdahl\"\n,\n\"Engeddi\"\n,\n\"Engedi\"\n,\n\"Engedus\"\n,\n\"Engel\"\n,\n\"Engelbert\"\n,\n\"Engelhart\"\n,\n\"Engen\"\n,\n\"Engenia\"\n,\n\"England\"\n,\n\"Engle\"\n,\n\"Englebert\"\n,\n\"Engleman\"\n,\n\"Englis\"\n,\n\"English\"\n,\n\"Engracia\"\n,\n\"Engud\"\n,\n\"Engvall\"\n,\n\"Enid\"\n,\n\"Ennis\"\n,\n\"Eno\"\n,\n\"Enoch\"\n,\n\"Enos\"\n,\n\"Enrica\"\n,\n\"Enrichetta\"\n,\n\"Enrico\"\n,\n\"Enrika\"\n,\n\"Enrique\"\n,\n\"Enriqueta\"\n,\n\"Ensign\"\n,\n\"Ensoll\"\n,\n\"Entwistle\"\n,\n\"Enyedy\"\n,\n\"Eoin\"\n,\n\"Eolanda\"\n,\n\"Eolande\"\n,\n\"Eph\"\n,\n\"Ephraim\"\n,\n\"Ephram\"\n,\n\"Ephrayim\"\n,\n\"Ephrem\"\n,\n\"Epifano\"\n,\n\"Epner\"\n,\n\"Epp\"\n,\n\"Epperson\"\n,\n\"Eppes\"\n,\n\"Eppie\"\n,\n\"Epps\"\n,\n\"Epstein\"\n,\n\"Er\"\n,\n\"Eradis\"\n,\n\"Eran\"\n,\n\"Eras\"\n,\n\"Erasme\"\n,\n\"Erasmo\"\n,\n\"Erasmus\"\n,\n\"Erastatus\"\n,\n\"Eraste\"\n,\n\"Erastes\"\n,\n\"Erastus\"\n,\n\"Erb\"\n,\n\"Erbe\"\n,\n\"Erbes\"\n,\n\"Erda\"\n,\n\"Erdah\"\n,\n\"Erdda\"\n,\n\"Erde\"\n,\n\"Erdei\"\n,\n\"Erdman\"\n,\n\"Erdrich\"\n,\n\"Erek\"\n,\n\"Erelia\"\n,\n\"Erena\"\n,\n\"Erfert\"\n,\n\"Ergener\"\n,\n\"Erhard\"\n,\n\"Erhart\"\n,\n\"Eri\"\n,\n\"Eric\"\n,\n\"Erica\"\n,\n\"Erich\"\n,\n\"Ericha\"\n,\n\"Erick\"\n,\n\"Ericka\"\n,\n\"Ericksen\"\n,\n\"Erickson\"\n,\n\"Erida\"\n,\n\"Erie\"\n,\n\"Eriha\"\n,\n\"Erik\"\n,\n\"Erika\"\n,\n\"Erikson\"\n,\n\"Erin\"\n,\n\"Erina\"\n,\n\"Erine\"\n,\n\"Erinn\"\n,\n\"Erinna\"\n,\n\"Erkan\"\n,\n\"Erl\"\n,\n\"Erland\"\n,\n\"Erlandson\"\n,\n\"Erle\"\n,\n\"Erleena\"\n,\n\"Erlene\"\n,\n\"Erlewine\"\n,\n\"Erlin\"\n,\n\"Erlina\"\n,\n\"Erline\"\n,\n\"Erlinna\"\n,\n\"Erlond\"\n,\n\"Erma\"\n,\n\"Ermanno\"\n,\n\"Erme\"\n,\n\"Ermeena\"\n,\n\"Ermengarde\"\n,\n\"Ermentrude\"\n,\n\"Ermey\"\n,\n\"Ermin\"\n,\n\"Ermina\"\n,\n\"Ermine\"\n,\n\"Erminia\"\n,\n\"Erminie\"\n,\n\"Erminna\"\n,\n\"Ern\"\n,\n\"Erna\"\n,\n\"Ernald\"\n,\n\"Ernaldus\"\n,\n\"Ernaline\"\n,\n\"Ernest\"\n,\n\"Ernesta\"\n,\n\"Ernestine\"\n,\n\"Ernesto\"\n,\n\"Ernestus\"\n,\n\"Ernie\"\n,\n\"Ernst\"\n,\n\"Erny\"\n,\n\"Errecart\"\n,\n\"Errick\"\n,\n\"Errol\"\n,\n\"Erroll\"\n,\n\"Erskine\"\n,\n\"Ertha\"\n,\n\"Erund\"\n,\n\"Erv\"\n,\n\"Ervin\"\n,\n\"Ervine\"\n,\n\"Erving\"\n,\n\"Erwin\"\n,\n\"Eryn\"\n,\n\"Esau\"\n,\n\"Esbensen\"\n,\n\"Esbenshade\"\n,\n\"Esch\"\n,\n\"Esdras\"\n,\n\"Eshelman\"\n,\n\"Eshman\"\n,\n\"Eskil\"\n,\n\"Eskill\"\n,\n\"Esma\"\n,\n\"Esmaria\"\n,\n\"Esme\"\n,\n\"Esmeralda\"\n,\n\"Esmerelda\"\n,\n\"Esmerolda\"\n,\n\"Esmond\"\n,\n\"Espy\"\n,\n\"Esra\"\n,\n\"Essa\"\n,\n\"Essam\"\n,\n\"Essex\"\n,\n\"Essie\"\n,\n\"Essinger\"\n,\n\"Essy\"\n,\n\"Esta\"\n,\n\"Estas\"\n,\n\"Esteban\"\n,\n\"Estel\"\n,\n\"Estele\"\n,\n\"Estell\"\n,\n\"Estella\"\n,\n\"Estelle\"\n,\n\"Esten\"\n,\n\"Ester\"\n,\n\"Estes\"\n,\n\"Estevan\"\n,\n\"Estey\"\n,\n\"Esther\"\n,\n\"Estis\"\n,\n\"Estrella\"\n,\n\"Estrellita\"\n,\n\"Estren\"\n,\n\"Estrin\"\n,\n\"Estus\"\n,\n\"Eta\"\n,\n\"Etam\"\n,\n\"Etan\"\n,\n\"Etana\"\n,\n\"Etem\"\n,\n\"Ethan\"\n,\n\"Ethban\"\n,\n\"Ethben\"\n,\n\"Ethbin\"\n,\n\"Ethbinium\"\n,\n\"Ethbun\"\n,\n\"Ethe\"\n,\n\"Ethel\"\n,\n\"Ethelbert\"\n,\n\"Ethelda\"\n,\n\"Ethelin\"\n,\n\"Ethelind\"\n,\n\"Ethelinda\"\n,\n\"Etheline\"\n,\n\"Ethelred\"\n,\n\"Ethelstan\"\n,\n\"Ethelyn\"\n,\n\"Ethyl\"\n,\n\"Etienne\"\n,\n\"Etka\"\n,\n\"Etoile\"\n,\n\"Etom\"\n,\n\"Etra\"\n,\n\"Etrem\"\n,\n\"Etta\"\n,\n\"Ettari\"\n,\n\"Etti\"\n,\n\"Ettie\"\n,\n\"Ettinger\"\n,\n\"Ettore\"\n,\n\"Etty\"\n,\n\"Etz\"\n,\n\"Eudo\"\n,\n\"Eudoca\"\n,\n\"Eudocia\"\n,\n\"Eudora\"\n,\n\"Eudosia\"\n,\n\"Eudoxia\"\n,\n\"Euell\"\n,\n\"Eugen\"\n,\n\"Eugene\"\n,\n\"Eugenia\"\n,\n\"Eugenides\"\n,\n\"Eugenie\"\n,\n\"Eugenio\"\n,\n\"Eugenius\"\n,\n\"Eugeniusz\"\n,\n\"Eugenle\"\n,\n\"Eugine\"\n,\n\"Euh\"\n,\n\"Eula\"\n,\n\"Eulalee\"\n,\n\"Eulalia\"\n,\n\"Eulaliah\"\n,\n\"Eulalie\"\n,\n\"Eulau\"\n,\n\"Eunice\"\n,\n\"Eupheemia\"\n,\n\"Euphemia\"\n,\n\"Euphemiah\"\n,\n\"Euphemie\"\n,\n\"Euridice\"\n,\n\"Eurydice\"\n,\n\"Eusebio\"\n,\n\"Eustace\"\n,\n\"Eustache\"\n,\n\"Eustacia\"\n,\n\"Eustashe\"\n,\n\"Eustasius\"\n,\n\"Eustatius\"\n,\n\"Eustazio\"\n,\n\"Eustis\"\n,\n\"Euton\"\n,\n\"Ev\"\n,\n\"Eva\"\n,\n\"Evadne\"\n,\n\"Evadnee\"\n,\n\"Evaleen\"\n,\n\"Evalyn\"\n,\n\"Evan\"\n,\n\"Evander\"\n,\n\"Evangelia\"\n,\n\"Evangelin\"\n,\n\"Evangelina\"\n,\n\"Evangeline\"\n,\n\"Evangelist\"\n,\n\"Evania\"\n,\n\"Evanne\"\n,\n\"Evannia\"\n,\n\"Evans\"\n,\n\"Evante\"\n,\n\"Evanthe\"\n,\n\"Evars\"\n,\n\"Eve\"\n,\n\"Eveleen\"\n,\n\"Evelin\"\n,\n\"Evelina\"\n,\n\"Eveline\"\n,\n\"Evelinn\"\n,\n\"Evelunn\"\n,\n\"Evelyn\"\n,\n\"Even\"\n,\n\"Everara\"\n,\n\"Everard\"\n,\n\"Evered\"\n,\n\"Everest\"\n,\n\"Everett\"\n,\n\"Everick\"\n,\n\"Everrs\"\n,\n\"Evers\"\n,\n\"Eversole\"\n,\n\"Everson\"\n,\n\"Evetta\"\n,\n\"Evette\"\n,\n\"Evey\"\n,\n\"Evie\"\n,\n\"Evin\"\n,\n\"Evita\"\n,\n\"Evonne\"\n,\n\"Evoy\"\n,\n\"Evslin\"\n,\n\"Evvie\"\n,\n\"Evvy\"\n,\n\"Evy\"\n,\n\"Evyn\"\n,\n\"Ewald\"\n,\n\"Ewall\"\n,\n\"Ewan\"\n,\n\"Eward\"\n,\n\"Ewart\"\n,\n\"Ewell\"\n,\n\"Ewen\"\n,\n\"Ewens\"\n,\n\"Ewer\"\n,\n\"Ewold\"\n,\n\"Eyde\"\n,\n\"Eydie\"\n,\n\"Eyeleen\"\n,\n\"Eyla\"\n,\n\"Ez\"\n,\n\"Ezana\"\n,\n\"Ezar\"\n,\n\"Ezara\"\n,\n\"Ezaria\"\n,\n\"Ezarra\"\n,\n\"Ezarras\"\n,\n\"Ezechiel\"\n,\n\"Ezekiel\"\n,\n\"Ezequiel\"\n,\n\"Eziechiele\"\n,\n\"Ezmeralda\"\n,\n\"Ezra\"\n,\n\"Ezri\"\n,\n\"Ezzo\"\n,\n\"Fabe\"\n,\n\"Faber\"\n,\n\"Fabi\"\n,\n\"Fabian\"\n,\n\"Fabiano\"\n,\n\"Fabien\"\n,\n\"Fabio\"\n,\n\"Fabiola\"\n,\n\"Fabiolas\"\n,\n\"Fablan\"\n,\n\"Fabozzi\"\n,\n\"Fabri\"\n,\n\"Fabria\"\n,\n\"Fabriane\"\n,\n\"Fabrianna\"\n,\n\"Fabrianne\"\n,\n\"Fabrice\"\n,\n\"Fabrienne\"\n,\n\"Fabrin\"\n,\n\"Fabron\"\n,\n\"Fabyola\"\n,\n\"Fachan\"\n,\n\"Fachanan\"\n,\n\"Fachini\"\n,\n\"Fadden\"\n,\n\"Faden\"\n,\n\"Fadil\"\n,\n\"Fadiman\"\n,\n\"Fae\"\n,\n\"Fagaly\"\n,\n\"Fagan\"\n,\n\"Fagen\"\n,\n\"Fagin\"\n,\n\"Fahey\"\n,\n\"Fahland\"\n,\n\"Fahy\"\n,\n\"Fai\"\n,\n\"Faina\"\n,\n\"Fair\"\n,\n\"Fairbanks\"\n,\n\"Faires\"\n,\n\"Fairfax\"\n,\n\"Fairfield\"\n,\n\"Fairleigh\"\n,\n\"Fairley\"\n,\n\"Fairlie\"\n,\n\"Fairman\"\n,\n\"Fairweather\"\n,\n\"Faith\"\n,\n\"Fakieh\"\n,\n\"Falcone\"\n,\n\"Falconer\"\n,\n\"Falda\"\n,\n\"Faletti\"\n,\n\"Faline\"\n,\n\"Falito\"\n,\n\"Falk\"\n,\n\"Falkner\"\n,\n\"Fallon\"\n,\n\"Faludi\"\n,\n\"Falzetta\"\n,\n\"Fan\"\n,\n\"Fanchan\"\n,\n\"Fanchet\"\n,\n\"Fanchette\"\n,\n\"Fanchie\"\n,\n\"Fanchon\"\n,\n\"Fancie\"\n,\n\"Fancy\"\n,\n\"Fanechka\"\n,\n\"Fanestil\"\n,\n\"Fang\"\n,\n\"Fania\"\n,\n\"Fanni\"\n,\n\"Fannie\"\n,\n\"Fanning\"\n,\n\"Fanny\"\n,\n\"Fantasia\"\n,\n\"Fante\"\n,\n\"Fanya\"\n,\n\"Far\"\n,\n\"Fara\"\n,\n\"Farah\"\n,\n\"Farand\"\n,\n\"Farant\"\n,\n\"Farhi\"\n,\n\"Fari\"\n,\n\"Faria\"\n,\n\"Farica\"\n,\n\"Farika\"\n,\n\"Fariss\"\n,\n\"Farkas\"\n,\n\"Farl\"\n,\n\"Farland\"\n,\n\"Farlay\"\n,\n\"Farlee\"\n,\n\"Farleigh\"\n,\n\"Farley\"\n,\n\"Farlie\"\n,\n\"Farly\"\n,\n\"Farman\"\n,\n\"Farmann\"\n,\n\"Farmelo\"\n,\n\"Farmer\"\n,\n\"Farnham\"\n,\n\"Farnsworth\"\n,\n\"Farny\"\n,\n\"Faro\"\n,\n\"Farr\"\n,\n\"Farra\"\n,\n\"Farrah\"\n,\n\"Farrand\"\n,\n\"Farrar\"\n,\n\"Farrel\"\n,\n\"Farrell\"\n,\n\"Farrica\"\n,\n\"Farrington\"\n,\n\"Farris\"\n,\n\"Farrish\"\n,\n\"Farrison\"\n,\n\"Farro\"\n,\n\"Farron\"\n,\n\"Farrow\"\n,\n\"Faruq\"\n,\n\"Farver\"\n,\n\"Farwell\"\n,\n\"Fasano\"\n,\n\"Faso\"\n,\n\"Fassold\"\n,\n\"Fast\"\n,\n\"Fasta\"\n,\n\"Fasto\"\n,\n\"Fates\"\n,\n\"Fatima\"\n,\n\"Fatimah\"\n,\n\"Fatma\"\n,\n\"Fattal\"\n,\n\"Faubert\"\n,\n\"Faubion\"\n,\n\"Fauch\"\n,\n\"Faucher\"\n,\n\"Faulkner\"\n,\n\"Fauman\"\n,\n\"Faun\"\n,\n\"Faunia\"\n,\n\"Faunie\"\n,\n\"Faus\"\n,\n\"Faust\"\n,\n\"Fausta\"\n,\n\"Faustena\"\n,\n\"Faustina\"\n,\n\"Faustine\"\n,\n\"Faustus\"\n,\n\"Fauver\"\n,\n\"Faux\"\n,\n\"Favata\"\n,\n\"Favian\"\n,\n\"Favianus\"\n,\n\"Favien\"\n,\n\"Favin\"\n,\n\"Favrot\"\n,\n\"Fawcett\"\n,\n\"Fawcette\"\n,\n\"Fawn\"\n,\n\"Fawna\"\n,\n\"Fawne\"\n,\n\"Fawnia\"\n,\n\"Fax\"\n,\n\"Faxan\"\n,\n\"Faxen\"\n,\n\"Faxon\"\n,\n\"Faxun\"\n,\n\"Fay\"\n,\n\"Faydra\"\n,\n\"Faye\"\n,\n\"Fayette\"\n,\n\"Fayina\"\n,\n\"Fayola\"\n,\n\"Fayre\"\n,\n\"Fayth\"\n,\n\"Faythe\"\n,\n\"Fazeli\"\n,\n\"Fe\"\n,\n\"Featherstone\"\n,\n\"February\"\n,\n\"Fechter\"\n,\n\"Fedak\"\n,\n\"Federica\"\n,\n\"Federico\"\n,\n\"Fedirko\"\n,\n\"Fedora\"\n,\n\"Fee\"\n,\n\"Feeley\"\n,\n\"Feeney\"\n,\n\"Feer\"\n,\n\"Feigin\"\n,\n\"Feil\"\n,\n\"Fein\"\n,\n\"Feinberg\"\n,\n\"Feingold\"\n,\n\"Feinleib\"\n,\n\"Feinstein\"\n,\n\"Feld\"\n,\n\"Felder\"\n,\n\"Feldman\"\n,\n\"Feldstein\"\n,\n\"Feldt\"\n,\n\"Felecia\"\n,\n\"Feledy\"\n,\n\"Felic\"\n,\n\"Felicdad\"\n,\n\"Felice\"\n,\n\"Felicia\"\n,\n\"Felicidad\"\n,\n\"Felicie\"\n,\n\"Felicio\"\n,\n\"Felicity\"\n,\n\"Felicle\"\n,\n\"Felike\"\n,\n\"Feliks\"\n,\n\"Felipa\"\n,\n\"Felipe\"\n,\n\"Felise\"\n,\n\"Felisha\"\n,\n\"Felita\"\n,\n\"Felix\"\n,\n\"Feliza\"\n,\n\"Felizio\"\n,\n\"Fellner\"\n,\n\"Fellows\"\n,\n\"Felske\"\n,\n\"Felt\"\n,\n\"Felten\"\n,\n\"Feltie\"\n,\n\"Felton\"\n,\n\"Felty\"\n,\n\"Fem\"\n,\n\"Femi\"\n,\n\"Femmine\"\n,\n\"Fen\"\n,\n\"Fendig\"\n,\n\"Fenelia\"\n,\n\"Fenella\"\n,\n\"Fenn\"\n,\n\"Fennell\"\n,\n\"Fennelly\"\n,\n\"Fenner\"\n,\n\"Fennessy\"\n,\n\"Fennie\"\n,\n\"Fenny\"\n,\n\"Fenton\"\n,\n\"Fenwick\"\n,\n\"Feodor\"\n,\n\"Feodora\"\n,\n\"Feodore\"\n,\n\"Feola\"\n,\n\"Ferd\"\n,\n\"Ferde\"\n,\n\"Ferdie\"\n,\n\"Ferdinana\"\n,\n\"Ferdinand\"\n,\n\"Ferdinanda\"\n,\n\"Ferdinande\"\n,\n\"Ferdy\"\n,\n\"Fergus\"\n,\n\"Ferguson\"\n,\n\"Feriga\"\n,\n\"Ferino\"\n,\n\"Fermin\"\n,\n\"Fern\"\n,\n\"Ferna\"\n,\n\"Fernald\"\n,\n\"Fernand\"\n,\n\"Fernanda\"\n,\n\"Fernande\"\n,\n\"Fernandes\"\n,\n\"Fernandez\"\n,\n\"Fernandina\"\n,\n\"Fernando\"\n,\n\"Fernas\"\n,\n\"Ferne\"\n,\n\"Ferneau\"\n,\n\"Fernyak\"\n,\n\"Ferrand\"\n,\n\"Ferreby\"\n,\n\"Ferree\"\n,\n\"Ferrel\"\n,\n\"Ferrell\"\n,\n\"Ferren\"\n,\n\"Ferretti\"\n,\n\"Ferri\"\n,\n\"Ferrick\"\n,\n\"Ferrigno\"\n,\n\"Ferris\"\n,\n\"Ferriter\"\n,\n\"Ferro\"\n,\n\"Ferullo\"\n,\n\"Ferwerda\"\n,\n\"Festa\"\n,\n\"Festatus\"\n,\n\"Festus\"\n,\n\"Feucht\"\n,\n\"Feune\"\n,\n\"Fevre\"\n,\n\"Fey\"\n,\n\"Fi\"\n,\n\"Fia\"\n,\n\"Fiann\"\n,\n\"Fianna\"\n,\n\"Fidel\"\n,\n\"Fidela\"\n,\n\"Fidelas\"\n,\n\"Fidele\"\n,\n\"Fidelia\"\n,\n\"Fidelio\"\n,\n\"Fidelis\"\n,\n\"Fidelity\"\n,\n\"Fidellas\"\n,\n\"Fidellia\"\n,\n\"Fiden\"\n,\n\"Fidole\"\n,\n\"Fiedler\"\n,\n\"Fiedling\"\n,\n\"Field\"\n,\n\"Fielding\"\n,\n\"Fields\"\n,\n\"Fiertz\"\n,\n\"Fiester\"\n,\n\"Fife\"\n,\n\"Fifi\"\n,\n\"Fifine\"\n,\n\"Figge\"\n,\n\"Figone\"\n,\n\"Figueroa\"\n,\n\"Filbert\"\n,\n\"Filberte\"\n,\n\"Filberto\"\n,\n\"Filemon\"\n,\n\"Files\"\n,\n\"Filia\"\n,\n\"Filiano\"\n,\n\"Filide\"\n,\n\"Filip\"\n,\n\"Filipe\"\n,\n\"Filippa\"\n,\n\"Filippo\"\n,\n\"Fillander\"\n,\n\"Fillbert\"\n,\n\"Fillender\"\n,\n\"Filler\"\n,\n\"Fillian\"\n,\n\"Filmer\"\n,\n\"Filmore\"\n,\n\"Filomena\"\n,\n\"Fin\"\n,\n\"Fina\"\n,\n\"Finbar\"\n,\n\"Finbur\"\n,\n\"Findlay\"\n,\n\"Findley\"\n,\n\"Fine\"\n,\n\"Fineberg\"\n,\n\"Finegan\"\n,\n\"Finella\"\n,\n\"Fineman\"\n,\n\"Finer\"\n,\n\"Fini\"\n,\n\"Fink\"\n,\n\"Finkelstein\"\n,\n\"Finlay\"\n,\n\"Finley\"\n,\n\"Finn\"\n,\n\"Finnegan\"\n,\n\"Finnie\"\n,\n\"Finnigan\"\n,\n\"Finny\"\n,\n\"Finstad\"\n,\n\"Finzer\"\n,\n\"Fiona\"\n,\n\"Fionna\"\n,\n\"Fionnula\"\n,\n\"Fiora\"\n,\n\"Fiore\"\n,\n\"Fiorenza\"\n,\n\"Fiorenze\"\n,\n\"Firestone\"\n,\n\"Firman\"\n,\n\"Firmin\"\n,\n\"Firooc\"\n,\n\"Fisch\"\n,\n\"Fischer\"\n,\n\"Fish\"\n,\n\"Fishback\"\n,\n\"Fishbein\"\n,\n\"Fisher\"\n,\n\"Fishman\"\n,\n\"Fisk\"\n,\n\"Fiske\"\n,\n\"Fisken\"\n,\n\"Fitting\"\n,\n\"Fitton\"\n,\n\"Fitts\"\n,\n\"Fitz\"\n,\n\"Fitzger\"\n,\n\"Fitzgerald\"\n,\n\"Fitzhugh\"\n,\n\"Fitzpatrick\"\n,\n\"Fitzsimmons\"\n,\n\"Flagler\"\n,\n\"Flaherty\"\n,\n\"Flam\"\n,\n\"Flan\"\n,\n\"Flanagan\"\n,\n\"Flanders\"\n,\n\"Flanigan\"\n,\n\"Flann\"\n,\n\"Flanna\"\n,\n\"Flannery\"\n,\n\"Flatto\"\n,\n\"Flavia\"\n,\n\"Flavian\"\n,\n\"Flavio\"\n,\n\"Flavius\"\n,\n\"Fleck\"\n,\n\"Fleda\"\n,\n\"Fleece\"\n,\n\"Fleeman\"\n,\n\"Fleeta\"\n,\n\"Fleischer\"\n,\n\"Fleisher\"\n,\n\"Fleisig\"\n,\n\"Flem\"\n,\n\"Fleming\"\n,\n\"Flemings\"\n,\n\"Flemming\"\n,\n\"Flessel\"\n,\n\"Fleta\"\n,\n\"Fletch\"\n,\n\"Fletcher\"\n,\n\"Fleur\"\n,\n\"Fleurette\"\n,\n\"Flieger\"\n,\n\"Flight\"\n,\n\"Flin\"\n,\n\"Flinn\"\n,\n\"Flint\"\n,\n\"Flip\"\n,\n\"Flita\"\n,\n\"Flo\"\n,\n\"Floeter\"\n,\n\"Flor\"\n,\n\"Flora\"\n,\n\"Florance\"\n,\n\"Flore\"\n,\n\"Florella\"\n,\n\"Florence\"\n,\n\"Florencia\"\n,\n\"Florentia\"\n,\n\"Florenza\"\n,\n\"Florette\"\n,\n\"Flori\"\n,\n\"Floria\"\n,\n\"Florian\"\n,\n\"Florida\"\n,\n\"Floridia\"\n,\n\"Florie\"\n,\n\"Florin\"\n,\n\"Florina\"\n,\n\"Florinda\"\n,\n\"Florine\"\n,\n\"Florio\"\n,\n\"Floris\"\n,\n\"Floro\"\n,\n\"Florri\"\n,\n\"Florrie\"\n,\n\"Florry\"\n,\n\"Flory\"\n,\n\"Flosi\"\n,\n\"Floss\"\n,\n\"Flosser\"\n,\n\"Flossi\"\n,\n\"Flossie\"\n,\n\"Flossy\"\n,\n\"Flower\"\n,\n\"Flowers\"\n,\n\"Floyd\"\n,\n\"Flss\"\n,\n\"Flyn\"\n,\n\"Flynn\"\n,\n\"Foah\"\n,\n\"Fogarty\"\n,\n\"Fogel\"\n,\n\"Fogg\"\n,\n\"Fokos\"\n,\n\"Folberth\"\n,\n\"Foley\"\n,\n\"Folger\"\n,\n\"Follansbee\"\n,\n\"Follmer\"\n,\n\"Folly\"\n,\n\"Folsom\"\n,\n\"Fonda\"\n,\n\"Fondea\"\n,\n\"Fong\"\n,\n\"Fons\"\n,\n\"Fonseca\"\n,\n\"Fonsie\"\n,\n\"Fontana\"\n,\n\"Fontes\"\n,\n\"Fonville\"\n,\n\"Fonz\"\n,\n\"Fonzie\"\n,\n\"Foote\"\n,\n\"Forbes\"\n,\n\"Forcier\"\n,\n\"Ford\"\n,\n\"Fording\"\n,\n\"Forelli\"\n,\n\"Forest\"\n,\n\"Forester\"\n,\n\"Forkey\"\n,\n\"Forland\"\n,\n\"Forlini\"\n,\n\"Formenti\"\n,\n\"Formica\"\n,\n\"Fornof\"\n,\n\"Forras\"\n,\n\"Forrer\"\n,\n\"Forrest\"\n,\n\"Forrester\"\n,\n\"Forsta\"\n,\n\"Forster\"\n,\n\"Forsyth\"\n,\n\"Forta\"\n,\n\"Fortier\"\n,\n\"Fortin\"\n,\n\"Fortna\"\n,\n\"Fortuna\"\n,\n\"Fortunato\"\n,\n\"Fortune\"\n,\n\"Fortunia\"\n,\n\"Fortunio\"\n,\n\"Fortunna\"\n,\n\"Forward\"\n,\n\"Foscalina\"\n,\n\"Fosdick\"\n,\n\"Foskett\"\n,\n\"Fosque\"\n,\n\"Foss\"\n,\n\"Foster\"\n,\n\"Fotina\"\n,\n\"Fotinas\"\n,\n\"Fougere\"\n,\n\"Foulk\"\n,\n\"Four\"\n,\n\"Foushee\"\n,\n\"Fowkes\"\n,\n\"Fowle\"\n,\n\"Fowler\"\n,\n\"Fox\"\n,\n\"Foy\"\n,\n\"Fraase\"\n,\n\"Fradin\"\n,\n\"Frager\"\n,\n\"Frame\"\n,\n\"Fran\"\n,\n\"France\"\n,\n\"Francene\"\n,\n\"Frances\"\n,\n\"Francesca\"\n,\n\"Francesco\"\n,\n\"Franchot\"\n,\n\"Franci\"\n,\n\"Francie\"\n,\n\"Francine\"\n,\n\"Francis\"\n,\n\"Francisca\"\n,\n\"Franciscka\"\n,\n\"Francisco\"\n,\n\"Franciska\"\n,\n\"Franciskus\"\n,\n\"Franck\"\n,\n\"Francklin\"\n,\n\"Francklyn\"\n,\n\"Franckot\"\n,\n\"Francois\"\n,\n\"Francoise\"\n,\n\"Francyne\"\n,\n\"Franek\"\n,\n\"Frangos\"\n,\n\"Frank\"\n,\n\"Frankel\"\n,\n\"Frankhouse\"\n,\n\"Frankie\"\n,\n\"Franklin\"\n,\n\"Franklyn\"\n,\n\"Franky\"\n,\n\"Franni\"\n,\n\"Frannie\"\n,\n\"Franny\"\n,\n\"Frans\"\n,\n\"Fransen\"\n,\n\"Fransis\"\n,\n\"Fransisco\"\n,\n\"Frants\"\n,\n\"Frantz\"\n,\n\"Franz\"\n,\n\"Franza\"\n,\n\"Franzen\"\n,\n\"Franzoni\"\n,\n\"Frasch\"\n,\n\"Frasco\"\n,\n\"Fraser\"\n,\n\"Frasier\"\n,\n\"Frasquito\"\n,\n\"Fraya\"\n,\n\"Frayda\"\n,\n\"Frayne\"\n,\n\"Fraze\"\n,\n\"Frazer\"\n,\n\"Frazier\"\n,\n\"Frear\"\n,\n\"Freberg\"\n,\n\"Frech\"\n,\n\"Frechette\"\n,\n\"Fred\"\n,\n\"Freda\"\n,\n\"Freddi\"\n,\n\"Freddie\"\n,\n\"Freddy\"\n,\n\"Fredek\"\n,\n\"Fredel\"\n,\n\"Fredela\"\n,\n\"Fredelia\"\n,\n\"Fredella\"\n,\n\"Fredenburg\"\n,\n\"Frederic\"\n,\n\"Frederica\"\n,\n\"Frederich\"\n,\n\"Frederick\"\n,\n\"Fredericka\"\n,\n\"Frederico\"\n,\n\"Frederigo\"\n,\n\"Frederik\"\n,\n\"Frederiksen\"\n,\n\"Frederique\"\n,\n\"Fredette\"\n,\n\"Fredi\"\n,\n\"Fredia\"\n,\n\"Fredie\"\n,\n\"Fredkin\"\n,\n\"Fredra\"\n,\n\"Fredric\"\n,\n\"Fredrick\"\n,\n\"Fredrika\"\n,\n\"Free\"\n,\n\"Freeborn\"\n,\n\"Freed\"\n,\n\"Freedman\"\n,\n\"Freeland\"\n,\n\"Freeman\"\n,\n\"Freemon\"\n,\n\"Fregger\"\n,\n\"Freida\"\n,\n\"Freiman\"\n,\n\"Fremont\"\n,\n\"French\"\n,\n\"Frendel\"\n,\n\"Frentz\"\n,\n\"Frere\"\n,\n\"Frerichs\"\n,\n\"Fretwell\"\n,\n\"Freud\"\n,\n\"Freudberg\"\n,\n\"Frey\"\n,\n\"Freya\"\n,\n\"Freyah\"\n,\n\"Freytag\"\n,\n\"Frick\"\n,\n\"Fricke\"\n,\n\"Frida\"\n,\n\"Friday\"\n,\n\"Fridell\"\n,\n\"Fridlund\"\n,\n\"Fried\"\n,\n\"Frieda\"\n,\n\"Friedberg\"\n,\n\"Friede\"\n,\n\"Frieder\"\n,\n\"Friederike\"\n,\n\"Friedland\"\n,\n\"Friedlander\"\n,\n\"Friedly\"\n,\n\"Friedman\"\n,\n\"Friedrich\"\n,\n\"Friedrick\"\n,\n\"Friend\"\n,\n\"Frierson\"\n,\n\"Fries\"\n,\n\"Frisse\"\n,\n\"Frissell\"\n,\n\"Fritts\"\n,\n\"Fritz\"\n,\n\"Fritze\"\n,\n\"Fritzie\"\n,\n\"Fritzsche\"\n,\n\"Frodeen\"\n,\n\"Frodi\"\n,\n\"Frodin\"\n,\n\"Frodina\"\n,\n\"Frodine\"\n,\n\"Froehlich\"\n,\n\"Froemming\"\n,\n\"Froh\"\n,\n\"Frohman\"\n,\n\"Frohne\"\n,\n\"Frolick\"\n,\n\"Froma\"\n,\n\"Fromma\"\n,\n\"Fronia\"\n,\n\"Fronnia\"\n,\n\"Fronniah\"\n,\n\"Frost\"\n,\n\"Fruin\"\n,\n\"Frulla\"\n,\n\"Frum\"\n,\n\"Fruma\"\n,\n\"Fry\"\n,\n\"Fryd\"\n,\n\"Frydman\"\n,\n\"Frye\"\n,\n\"Frymire\"\n,\n\"Fu\"\n,\n\"Fuchs\"\n,\n\"Fugate\"\n,\n\"Fugazy\"\n,\n\"Fugere\"\n,\n\"Fuhrman\"\n,\n\"Fujio\"\n,\n\"Ful\"\n,\n\"Fulbert\"\n,\n\"Fulbright\"\n,\n\"Fulcher\"\n,\n\"Fuld\"\n,\n\"Fulks\"\n,\n\"Fuller\"\n,\n\"Fullerton\"\n,\n\"Fulmer\"\n,\n\"Fulmis\"\n,\n\"Fulton\"\n,\n\"Fulvi\"\n,\n\"Fulvia\"\n,\n\"Fulviah\"\n,\n\"Funch\"\n,\n\"Funda\"\n,\n\"Funk\"\n,\n\"Furey\"\n,\n\"Furgeson\"\n,\n\"Furie\"\n,\n\"Furiya\"\n,\n\"Furlani\"\n,\n\"Furlong\"\n,\n\"Furmark\"\n,\n\"Furnary\"\n,\n\"Furr\"\n,\n\"Furtek\"\n,\n\"Fusco\"\n,\n\"Gaal\"\n,\n\"Gabbert\"\n,\n\"Gabbey\"\n,\n\"Gabbi\"\n,\n\"Gabbie\"\n,\n\"Gabby\"\n,\n\"Gabe\"\n,\n\"Gabel\"\n,\n\"Gabey\"\n,\n\"Gabi\"\n,\n\"Gabie\"\n,\n\"Gable\"\n,\n\"Gabler\"\n,\n\"Gabor\"\n,\n\"Gabriel\"\n,\n\"Gabriela\"\n,\n\"Gabriele\"\n,\n\"Gabriell\"\n,\n\"Gabriella\"\n,\n\"Gabrielle\"\n,\n\"Gabrielli\"\n,\n\"Gabriellia\"\n,\n\"Gabriello\"\n,\n\"Gabrielson\"\n,\n\"Gabrila\"\n,\n\"Gaby\"\n,\n\"Gad\"\n,\n\"Gaddi\"\n,\n\"Gader\"\n,\n\"Gadmann\"\n,\n\"Gadmon\"\n,\n\"Gae\"\n,\n\"Gael\"\n,\n\"Gaelan\"\n,\n\"Gaeta\"\n,\n\"Gage\"\n,\n\"Gagliano\"\n,\n\"Gagne\"\n,\n\"Gagnon\"\n,\n\"Gahan\"\n,\n\"Gahl\"\n,\n\"Gaidano\"\n,\n\"Gaige\"\n,\n\"Gail\"\n,\n\"Gaile\"\n,\n\"Gaillard\"\n,\n\"Gainer\"\n,\n\"Gainor\"\n,\n\"Gaiser\"\n,\n\"Gaither\"\n,\n\"Gaivn\"\n,\n\"Gal\"\n,\n\"Gala\"\n,\n\"Galan\"\n,\n\"Galang\"\n,\n\"Galanti\"\n,\n\"Galasyn\"\n,\n\"Galatea\"\n,\n\"Galateah\"\n,\n\"Galatia\"\n,\n\"Gale\"\n,\n\"Galen\"\n,\n\"Galer\"\n,\n\"Galina\"\n,\n\"Galitea\"\n,\n\"Gall\"\n,\n\"Gallager\"\n,\n\"Gallagher\"\n,\n\"Gallard\"\n,\n\"Gallenz\"\n,\n\"Galliett\"\n,\n\"Galligan\"\n,\n\"Galloway\"\n,\n\"Gally\"\n,\n\"Galvan\"\n,\n\"Galven\"\n,\n\"Galvin\"\n,\n\"Gamages\"\n,\n\"Gamal\"\n,\n\"Gamali\"\n,\n\"Gamaliel\"\n,\n\"Gambell\"\n,\n\"Gamber\"\n,\n\"Gambrell\"\n,\n\"Gambrill\"\n,\n\"Gamin\"\n,\n\"Gan\"\n,\n\"Ganiats\"\n,\n\"Ganley\"\n,\n\"Gannes\"\n,\n\"Gannie\"\n,\n\"Gannon\"\n,\n\"Ganny\"\n,\n\"Gans\"\n,\n\"Gant\"\n,\n\"Gapin\"\n,\n\"Gar\"\n,\n\"Garald\"\n,\n\"Garate\"\n,\n\"Garaway\"\n,\n\"Garbe\"\n,\n\"Garber\"\n,\n\"Garbers\"\n,\n\"Garceau\"\n,\n\"Garcia\"\n,\n\"Garcon\"\n,\n\"Gard\"\n,\n\"Garda\"\n,\n\"Gardal\"\n,\n\"Gardas\"\n,\n\"Gardel\"\n,\n\"Gardell\"\n,\n\"Gardener\"\n,\n\"Gardia\"\n,\n\"Gardie\"\n,\n\"Gardiner\"\n,\n\"Gardner\"\n,\n\"Gardol\"\n,\n\"Gardy\"\n,\n\"Gare\"\n,\n\"Garek\"\n,\n\"Gareri\"\n,\n\"Gareth\"\n,\n\"Garett\"\n,\n\"Garey\"\n,\n\"Garfield\"\n,\n\"Garfinkel\"\n,\n\"Gargan\"\n,\n\"Garges\"\n,\n\"Garibald\"\n,\n\"Garibold\"\n,\n\"Garibull\"\n,\n\"Gariepy\"\n,\n\"Garik\"\n,\n\"Garin\"\n,\n\"Garlaand\"\n,\n\"Garlan\"\n,\n\"Garland\"\n,\n\"Garlanda\"\n,\n\"Garlen\"\n,\n\"Garlinda\"\n,\n\"Garling\"\n,\n\"Garmaise\"\n,\n\"Garneau\"\n,\n\"Garner\"\n,\n\"Garnes\"\n,\n\"Garnet\"\n,\n\"Garnett\"\n,\n\"Garnette\"\n,\n\"Garold\"\n,\n\"Garrard\"\n,\n\"Garratt\"\n,\n\"Garrek\"\n,\n\"Garret\"\n,\n\"Garreth\"\n,\n\"Garretson\"\n,\n\"Garrett\"\n,\n\"Garrick\"\n,\n\"Garrik\"\n,\n\"Garris\"\n,\n\"Garrison\"\n,\n\"Garrity\"\n,\n\"Garrot\"\n,\n\"Garrott\"\n,\n\"Garry\"\n,\n\"Garson\"\n,\n\"Garth\"\n,\n\"Garv\"\n,\n\"Garvey\"\n,\n\"Garvin\"\n,\n\"Garvy\"\n,\n\"Garwin\"\n,\n\"Garwood\"\n,\n\"Gary\"\n,\n\"Garzon\"\n,\n\"Gascony\"\n,\n\"Gaskill\"\n,\n\"Gaskin\"\n,\n\"Gaskins\"\n,\n\"Gaspar\"\n,\n\"Gaspard\"\n,\n\"Gasparo\"\n,\n\"Gasper\"\n,\n\"Gasperoni\"\n,\n\"Gass\"\n,\n\"Gasser\"\n,\n\"Gassman\"\n,\n\"Gastineau\"\n,\n\"Gaston\"\n,\n\"Gates\"\n,\n\"Gathard\"\n,\n\"Gathers\"\n,\n\"Gati\"\n,\n\"Gatian\"\n,\n\"Gatias\"\n,\n\"Gaudet\"\n,\n\"Gaudette\"\n,\n\"Gaughan\"\n,\n\"Gaul\"\n,\n\"Gauldin\"\n,\n\"Gaulin\"\n,\n\"Gault\"\n,\n\"Gaultiero\"\n,\n\"Gauntlett\"\n,\n\"Gausman\"\n,\n\"Gaut\"\n,\n\"Gautea\"\n,\n\"Gauthier\"\n,\n\"Gautier\"\n,\n\"Gautious\"\n,\n\"Gav\"\n,\n\"Gavan\"\n,\n\"Gaven\"\n,\n\"Gavette\"\n,\n\"Gavin\"\n,\n\"Gavini\"\n,\n\"Gavra\"\n,\n\"Gavrah\"\n,\n\"Gavriella\"\n,\n\"Gavrielle\"\n,\n\"Gavrila\"\n,\n\"Gavrilla\"\n,\n\"Gaw\"\n,\n\"Gawain\"\n,\n\"Gawen\"\n,\n\"Gawlas\"\n,\n\"Gay\"\n,\n\"Gaye\"\n,\n\"Gayel\"\n,\n\"Gayelord\"\n,\n\"Gayl\"\n,\n\"Gayla\"\n,\n\"Gayle\"\n,\n\"Gayleen\"\n,\n\"Gaylene\"\n,\n\"Gayler\"\n,\n\"Gaylor\"\n,\n\"Gaylord\"\n,\n\"Gayn\"\n,\n\"Gayner\"\n,\n\"Gaynor\"\n,\n\"Gazo\"\n,\n\"Gazzo\"\n,\n\"Geaghan\"\n,\n\"Gean\"\n,\n\"Geanine\"\n,\n\"Gearalt\"\n,\n\"Gearard\"\n,\n\"Gearhart\"\n,\n\"Gebelein\"\n,\n\"Gebhardt\"\n,\n\"Gebler\"\n,\n\"Geddes\"\n,\n\"Gee\"\n,\n\"Geehan\"\n,\n\"Geer\"\n,\n\"Geerts\"\n,\n\"Geesey\"\n,\n\"Gefell\"\n,\n\"Gefen\"\n,\n\"Geffner\"\n,\n\"Gehlbach\"\n,\n\"Gehman\"\n,\n\"Geibel\"\n,\n\"Geier\"\n,\n\"Geiger\"\n,\n\"Geilich\"\n,\n\"Geis\"\n,\n\"Geiss\"\n,\n\"Geithner\"\n,\n\"Gelasias\"\n,\n\"Gelasius\"\n,\n\"Gelb\"\n,\n\"Geldens\"\n,\n\"Gelhar\"\n,\n\"Geller\"\n,\n\"Gellman\"\n,\n\"Gelman\"\n,\n\"Gelya\"\n,\n\"Gemina\"\n,\n\"Gemini\"\n,\n\"Geminian\"\n,\n\"Geminius\"\n,\n\"Gemma\"\n,\n\"Gemmell\"\n,\n\"Gemoets\"\n,\n\"Gemperle\"\n,\n\"Gen\"\n,\n\"Gena\"\n,\n\"Genaro\"\n,\n\"Gene\"\n,\n\"Genesa\"\n,\n\"Genesia\"\n,\n\"Genet\"\n,\n\"Geneva\"\n,\n\"Genevieve\"\n,\n\"Genevra\"\n,\n\"Genia\"\n,\n\"Genie\"\n,\n\"Genisia\"\n,\n\"Genna\"\n,\n\"Gennaro\"\n,\n\"Genni\"\n,\n\"Gennie\"\n,\n\"Gennifer\"\n,\n\"Genny\"\n,\n\"Geno\"\n,\n\"Genovera\"\n,\n\"Gensler\"\n,\n\"Gensmer\"\n,\n\"Gent\"\n,\n\"Gentes\"\n,\n\"Gentilis\"\n,\n\"Gentille\"\n,\n\"Gentry\"\n,\n\"Genvieve\"\n,\n\"Geof\"\n,\n\"Geoff\"\n,\n\"Geoffrey\"\n,\n\"Geoffry\"\n,\n\"Georas\"\n,\n\"Geordie\"\n,\n\"Georg\"\n,\n\"George\"\n,\n\"Georgeanna\"\n,\n\"Georgeanne\"\n,\n\"Georgena\"\n,\n\"Georges\"\n,\n\"Georgeta\"\n,\n\"Georgetta\"\n,\n\"Georgette\"\n,\n\"Georgi\"\n,\n\"Georgia\"\n,\n\"Georgiana\"\n,\n\"Georgianna\"\n,\n\"Georgianne\"\n,\n\"Georgie\"\n,\n\"Georgina\"\n,\n\"Georgine\"\n,\n\"Georglana\"\n,\n\"Georgy\"\n,\n\"Ger\"\n,\n\"Geraint\"\n,\n\"Gerald\"\n,\n\"Geralda\"\n,\n\"Geraldina\"\n,\n\"Geraldine\"\n,\n\"Gerard\"\n,\n\"Gerardo\"\n,\n\"Geraud\"\n,\n\"Gerbold\"\n,\n\"Gerda\"\n,\n\"Gerdeen\"\n,\n\"Gerdi\"\n,\n\"Gerdy\"\n,\n\"Gere\"\n,\n\"Gerek\"\n,\n\"Gereld\"\n,\n\"Gereron\"\n,\n\"Gerfen\"\n,\n\"Gerge\"\n,\n\"Gerger\"\n,\n\"Gerhan\"\n,\n\"Gerhard\"\n,\n\"Gerhardine\"\n,\n\"Gerhardt\"\n,\n\"Geri\"\n,\n\"Gerianna\"\n,\n\"Gerianne\"\n,\n\"Gerick\"\n,\n\"Gerik\"\n,\n\"Gerita\"\n,\n\"Gerius\"\n,\n\"Gerkman\"\n,\n\"Gerlac\"\n,\n\"Gerladina\"\n,\n\"Germain\"\n,\n\"Germaine\"\n,\n\"German\"\n,\n\"Germana\"\n,\n\"Germann\"\n,\n\"Germano\"\n,\n\"Germaun\"\n,\n\"Germayne\"\n,\n\"Germin\"\n,\n\"Gernhard\"\n,\n\"Gerome\"\n,\n\"Gerrald\"\n,\n\"Gerrard\"\n,\n\"Gerri\"\n,\n\"Gerrie\"\n,\n\"Gerrilee\"\n,\n\"Gerrit\"\n,\n\"Gerry\"\n,\n\"Gersham\"\n,\n\"Gershom\"\n,\n\"Gershon\"\n,\n\"Gerson\"\n,\n\"Gerstein\"\n,\n\"Gerstner\"\n,\n\"Gert\"\n,\n\"Gerta\"\n,\n\"Gerti\"\n,\n\"Gertie\"\n,\n\"Gertrud\"\n,\n\"Gertruda\"\n,\n\"Gertrude\"\n,\n\"Gertrudis\"\n,\n\"Gerty\"\n,\n\"Gervais\"\n,\n\"Gervase\"\n,\n\"Gery\"\n,\n\"Gesner\"\n,\n\"Gessner\"\n,\n\"Getraer\"\n,\n\"Getter\"\n,\n\"Gettings\"\n,\n\"Gewirtz\"\n,\n\"Ghassan\"\n,\n\"Gherardi\"\n,\n\"Gherardo\"\n,\n\"Gherlein\"\n,\n\"Ghiselin\"\n,\n\"Giacamo\"\n,\n\"Giacinta\"\n,\n\"Giacobo\"\n,\n\"Giacomo\"\n,\n\"Giacopo\"\n,\n\"Giaimo\"\n,\n\"Giamo\"\n,\n\"Gian\"\n,\n\"Giana\"\n,\n\"Gianina\"\n,\n\"Gianna\"\n,\n\"Gianni\"\n,\n\"Giannini\"\n,\n\"Giarla\"\n,\n\"Giavani\"\n,\n\"Gib\"\n,\n\"Gibb\"\n,\n\"Gibbeon\"\n,\n\"Gibbie\"\n,\n\"Gibbon\"\n,\n\"Gibbons\"\n,\n\"Gibbs\"\n,\n\"Gibby\"\n,\n\"Gibe\"\n,\n\"Gibeon\"\n,\n\"Gibert\"\n,\n\"Gibrian\"\n,\n\"Gibson\"\n,\n\"Gibun\"\n,\n\"Giddings\"\n,\n\"Gide\"\n,\n\"Gideon\"\n,\n\"Giefer\"\n,\n\"Gies\"\n,\n\"Giesecke\"\n,\n\"Giess\"\n,\n\"Giesser\"\n,\n\"Giff\"\n,\n\"Giffard\"\n,\n\"Giffer\"\n,\n\"Gifferd\"\n,\n\"Giffie\"\n,\n\"Gifford\"\n,\n\"Giffy\"\n,\n\"Gigi\"\n,\n\"Giglio\"\n,\n\"Gignac\"\n,\n\"Giguere\"\n,\n\"Gil\"\n,\n\"Gilba\"\n,\n\"Gilbart\"\n,\n\"Gilbert\"\n,\n\"Gilberta\"\n,\n\"Gilberte\"\n,\n\"Gilbertina\"\n,\n\"Gilbertine\"\n,\n\"Gilberto\"\n,\n\"Gilbertson\"\n,\n\"Gilboa\"\n,\n\"Gilburt\"\n,\n\"Gilbye\"\n,\n\"Gilchrist\"\n,\n\"Gilcrest\"\n,\n\"Gilda\"\n,\n\"Gildas\"\n,\n\"Gildea\"\n,\n\"Gilder\"\n,\n\"Gildus\"\n,\n\"Gile\"\n,\n\"Gilead\"\n,\n\"Gilemette\"\n,\n\"Giles\"\n,\n\"Gilford\"\n,\n\"Gilges\"\n,\n\"Giliana\"\n,\n\"Giliane\"\n,\n\"Gill\"\n,\n\"Gillan\"\n,\n\"Gillead\"\n,\n\"Gilleod\"\n,\n\"Gilles\"\n,\n\"Gillespie\"\n,\n\"Gillett\"\n,\n\"Gilletta\"\n,\n\"Gillette\"\n,\n\"Gilli\"\n,\n\"Gilliam\"\n,\n\"Gillian\"\n,\n\"Gillie\"\n,\n\"Gilliette\"\n,\n\"Gilligan\"\n,\n\"Gillman\"\n,\n\"Gillmore\"\n,\n\"Gilly\"\n,\n\"Gilman\"\n,\n\"Gilmer\"\n,\n\"Gilmore\"\n,\n\"Gilmour\"\n,\n\"Gilpin\"\n,\n\"Gilroy\"\n,\n\"Gilson\"\n,\n\"Giltzow\"\n,\n\"Gilud\"\n,\n\"Gilus\"\n,\n\"Gimble\"\n,\n\"Gimpel\"\n,\n\"Gina\"\n,\n\"Ginder\"\n,\n\"Gine\"\n,\n\"Ginelle\"\n,\n\"Ginevra\"\n,\n\"Ginger\"\n,\n\"Gingras\"\n,\n\"Ginni\"\n,\n\"Ginnie\"\n,\n\"Ginnifer\"\n,\n\"Ginny\"\n,\n\"Gino\"\n,\n\"Ginsberg\"\n,\n\"Ginsburg\"\n,\n\"Gintz\"\n,\n\"Ginzburg\"\n,\n\"Gio\"\n,\n\"Giordano\"\n,\n\"Giorgi\"\n,\n\"Giorgia\"\n,\n\"Giorgio\"\n,\n\"Giovanna\"\n,\n\"Giovanni\"\n,\n\"Gipps\"\n,\n\"Gipson\"\n,\n\"Gipsy\"\n,\n\"Giralda\"\n,\n\"Giraldo\"\n,\n\"Girand\"\n,\n\"Girard\"\n,\n\"Girardi\"\n,\n\"Girardo\"\n,\n\"Giraud\"\n,\n\"Girhiny\"\n,\n\"Girish\"\n,\n\"Girovard\"\n,\n\"Girvin\"\n,\n\"Gisela\"\n,\n\"Giselbert\"\n,\n\"Gisele\"\n,\n\"Gisella\"\n,\n\"Giselle\"\n,\n\"Gish\"\n,\n\"Gisser\"\n,\n\"Gitel\"\n,\n\"Githens\"\n,\n\"Gitlow\"\n,\n\"Gitt\"\n,\n\"Gittel\"\n,\n\"Gittle\"\n,\n\"Giuditta\"\n,\n\"Giule\"\n,\n\"Giulia\"\n,\n\"Giuliana\"\n,\n\"Giulietta\"\n,\n\"Giulio\"\n,\n\"Giuseppe\"\n,\n\"Giustina\"\n,\n\"Giustino\"\n,\n\"Giusto\"\n,\n\"Given\"\n,\n\"Giverin\"\n,\n\"Giza\"\n,\n\"Gizela\"\n,\n\"Glaab\"\n,\n\"Glad\"\n,\n\"Gladdie\"\n,\n\"Gladdy\"\n,\n\"Gladi\"\n,\n\"Gladine\"\n,\n\"Gladis\"\n,\n\"Gladstone\"\n,\n\"Gladwin\"\n,\n\"Gladys\"\n,\n\"Glanti\"\n,\n\"Glantz\"\n,\n\"Glanville\"\n,\n\"Glarum\"\n,\n\"Glaser\"\n,\n\"Glasgo\"\n,\n\"Glass\"\n,\n\"Glassco\"\n,\n\"Glassman\"\n,\n\"Glaudia\"\n,\n\"Glavin\"\n,\n\"Gleason\"\n,\n\"Gleda\"\n,\n\"Gleeson\"\n,\n\"Gleich\"\n,\n\"Glen\"\n,\n\"Glenda\"\n,\n\"Glenden\"\n,\n\"Glendon\"\n,\n\"Glenine\"\n,\n\"Glenn\"\n,\n\"Glenna\"\n,\n\"Glennie\"\n,\n\"Glennis\"\n,\n\"Glennon\"\n,\n\"Glialentn\"\n,\n\"Glick\"\n,\n\"Glimp\"\n,\n\"Glinys\"\n,\n\"Glogau\"\n,\n\"Glori\"\n,\n\"Gloria\"\n,\n\"Gloriana\"\n,\n\"Gloriane\"\n,\n\"Glorianna\"\n,\n\"Glory\"\n,\n\"Glover\"\n,\n\"Glovsky\"\n,\n\"Gluck\"\n,\n\"Glyn\"\n,\n\"Glynas\"\n,\n\"Glynda\"\n,\n\"Glynias\"\n,\n\"Glynis\"\n,\n\"Glynn\"\n,\n\"Glynnis\"\n,\n\"Gmur\"\n,\n\"Gnni\"\n,\n\"Goar\"\n,\n\"Goat\"\n,\n\"Gobert\"\n,\n\"God\"\n,\n\"Goda\"\n,\n\"Godard\"\n,\n\"Godart\"\n,\n\"Godbeare\"\n,\n\"Godber\"\n,\n\"Goddard\"\n,\n\"Goddart\"\n,\n\"Godden\"\n,\n\"Godderd\"\n,\n\"Godding\"\n,\n\"Goddord\"\n,\n\"Godewyn\"\n,\n\"Godfree\"\n,\n\"Godfrey\"\n,\n\"Godfry\"\n,\n\"Godiva\"\n,\n\"Godliman\"\n,\n\"Godred\"\n,\n\"Godric\"\n,\n\"Godrich\"\n,\n\"Godspeed\"\n,\n\"Godwin\"\n,\n\"Goebel\"\n,\n\"Goeger\"\n,\n\"Goer\"\n,\n\"Goerke\"\n,\n\"Goeselt\"\n,\n\"Goetz\"\n,\n\"Goff\"\n,\n\"Goggin\"\n,\n\"Goines\"\n,\n\"Gokey\"\n,\n\"Golanka\"\n,\n\"Gold\"\n,\n\"Golda\"\n,\n\"Goldarina\"\n,\n\"Goldberg\"\n,\n\"Golden\"\n,\n\"Goldenberg\"\n,\n\"Goldfarb\"\n,\n\"Goldfinch\"\n,\n\"Goldi\"\n,\n\"Goldia\"\n,\n\"Goldie\"\n,\n\"Goldin\"\n,\n\"Goldina\"\n,\n\"Golding\"\n,\n\"Goldman\"\n,\n\"Goldner\"\n,\n\"Goldshell\"\n,\n\"Goldshlag\"\n,\n\"Goldsmith\"\n,\n\"Goldstein\"\n,\n\"Goldston\"\n,\n\"Goldsworthy\"\n,\n\"Goldwin\"\n,\n\"Goldy\"\n,\n\"Goles\"\n,\n\"Golightly\"\n,\n\"Gollin\"\n,\n\"Golliner\"\n,\n\"Golter\"\n,\n\"Goltz\"\n,\n\"Golub\"\n,\n\"Gomar\"\n,\n\"Gombach\"\n,\n\"Gombosi\"\n,\n\"Gomer\"\n,\n\"Gomez\"\n,\n\"Gona\"\n,\n\"Gonagle\"\n,\n\"Gone\"\n,\n\"Gonick\"\n,\n\"Gonnella\"\n,\n\"Gonroff\"\n,\n\"Gonsalve\"\n,\n\"Gonta\"\n,\n\"Gonyea\"\n,\n\"Gonzales\"\n,\n\"Gonzalez\"\n,\n\"Gonzalo\"\n,\n\"Goober\"\n,\n\"Good\"\n,\n\"Goodard\"\n,\n\"Goodden\"\n,\n\"Goode\"\n,\n\"Goodhen\"\n,\n\"Goodill\"\n,\n\"Goodkin\"\n,\n\"Goodman\"\n,\n\"Goodrich\"\n,\n\"Goodrow\"\n,\n\"Goodson\"\n,\n\"Goodspeed\"\n,\n\"Goodwin\"\n,\n\"Goody\"\n,\n\"Goodyear\"\n,\n\"Googins\"\n,\n\"Gora\"\n,\n\"Goran\"\n,\n\"Goraud\"\n,\n\"Gord\"\n,\n\"Gordan\"\n,\n\"Gorden\"\n,\n\"Gordie\"\n,\n\"Gordon\"\n,\n\"Gordy\"\n,\n\"Gore\"\n,\n\"Goren\"\n,\n\"Gorey\"\n,\n\"Gorga\"\n,\n\"Gorges\"\n,\n\"Gorlicki\"\n,\n\"Gorlin\"\n,\n\"Gorman\"\n,\n\"Gorrian\"\n,\n\"Gorrono\"\n,\n\"Gorski\"\n,\n\"Gorton\"\n,\n\"Gosnell\"\n,\n\"Gosney\"\n,\n\"Goss\"\n,\n\"Gosselin\"\n,\n\"Gosser\"\n,\n\"Gotcher\"\n,\n\"Goth\"\n,\n\"Gothar\"\n,\n\"Gothard\"\n,\n\"Gothart\"\n,\n\"Gothurd\"\n,\n\"Goto\"\n,\n\"Gottfried\"\n,\n\"Gotthard\"\n,\n\"Gotthelf\"\n,\n\"Gottlieb\"\n,\n\"Gottuard\"\n,\n\"Gottwald\"\n,\n\"Gough\"\n,\n\"Gould\"\n,\n\"Goulden\"\n,\n\"Goulder\"\n,\n\"Goulet\"\n,\n\"Goulette\"\n,\n\"Gove\"\n,\n\"Gow\"\n,\n\"Gower\"\n,\n\"Gowon\"\n,\n\"Gowrie\"\n,\n\"Graaf\"\n,\n\"Grace\"\n,\n\"Graces\"\n,\n\"Gracia\"\n,\n\"Gracie\"\n,\n\"Gracye\"\n,\n\"Gradeigh\"\n,\n\"Gradey\"\n,\n\"Grados\"\n,\n\"Grady\"\n,\n\"Grae\"\n,\n\"Graehl\"\n,\n\"Graehme\"\n,\n\"Graeme\"\n,\n\"Graf\"\n,\n\"Graff\"\n,\n\"Graham\"\n,\n\"Graig\"\n,\n\"Grail\"\n,\n\"Gram\"\n,\n\"Gran\"\n,\n\"Grand\"\n,\n\"Grane\"\n,\n\"Graner\"\n,\n\"Granese\"\n,\n\"Grange\"\n,\n\"Granger\"\n,\n\"Grani\"\n,\n\"Grania\"\n,\n\"Graniah\"\n,\n\"Graniela\"\n,\n\"Granlund\"\n,\n\"Grannia\"\n,\n\"Granniah\"\n,\n\"Grannias\"\n,\n\"Grannie\"\n,\n\"Granny\"\n,\n\"Granoff\"\n,\n\"Grant\"\n,\n\"Grantham\"\n,\n\"Granthem\"\n,\n\"Grantland\"\n,\n\"Grantley\"\n,\n\"Granville\"\n,\n\"Grassi\"\n,\n\"Grata\"\n,\n\"Grath\"\n,\n\"Grati\"\n,\n\"Gratia\"\n,\n\"Gratiana\"\n,\n\"Gratianna\"\n,\n\"Gratt\"\n,\n\"Graubert\"\n,\n\"Gravante\"\n,\n\"Graves\"\n,\n\"Gray\"\n,\n\"Graybill\"\n,\n\"Grayce\"\n,\n\"Grayson\"\n,\n\"Grazia\"\n,\n\"Greabe\"\n,\n\"Grearson\"\n,\n\"Gredel\"\n,\n\"Greeley\"\n,\n\"Green\"\n,\n\"Greenberg\"\n,\n\"Greenburg\"\n,\n\"Greene\"\n,\n\"Greenebaum\"\n,\n\"Greenes\"\n,\n\"Greenfield\"\n,\n\"Greenland\"\n,\n\"Greenleaf\"\n,\n\"Greenlee\"\n,\n\"Greenman\"\n,\n\"Greenquist\"\n,\n\"Greenstein\"\n,\n\"Greenwald\"\n,\n\"Greenwell\"\n,\n\"Greenwood\"\n,\n\"Greer\"\n,\n\"Greerson\"\n,\n\"Greeson\"\n,\n\"Grefe\"\n,\n\"Grefer\"\n,\n\"Greff\"\n,\n\"Greg\"\n,\n\"Grega\"\n,\n\"Gregg\"\n,\n\"Greggory\"\n,\n\"Greggs\"\n,\n\"Gregoire\"\n,\n\"Gregoor\"\n,\n\"Gregor\"\n,\n\"Gregorio\"\n,\n\"Gregorius\"\n,\n\"Gregory\"\n,\n\"Gregrory\"\n,\n\"Gregson\"\n,\n\"Greiner\"\n,\n\"Grekin\"\n,\n\"Grenier\"\n,\n\"Grenville\"\n,\n\"Gresham\"\n,\n\"Greta\"\n,\n\"Gretal\"\n,\n\"Gretchen\"\n,\n\"Grete\"\n,\n\"Gretel\"\n,\n\"Grethel\"\n,\n\"Gretna\"\n,\n\"Gretta\"\n,\n\"Grevera\"\n,\n\"Grew\"\n,\n\"Grewitz\"\n,\n\"Grey\"\n,\n\"Greyso\"\n,\n\"Greyson\"\n,\n\"Greysun\"\n,\n\"Grider\"\n,\n\"Gridley\"\n,\n\"Grier\"\n,\n\"Grieve\"\n,\n\"Griff\"\n,\n\"Griffie\"\n,\n\"Griffin\"\n,\n\"Griffis\"\n,\n\"Griffith\"\n,\n\"Griffiths\"\n,\n\"Griffy\"\n,\n\"Griggs\"\n,\n\"Grigson\"\n,\n\"Grim\"\n,\n\"Grimaldi\"\n,\n\"Grimaud\"\n,\n\"Grimbal\"\n,\n\"Grimbald\"\n,\n\"Grimbly\"\n,\n\"Grimes\"\n,\n\"Grimona\"\n,\n\"Grimonia\"\n,\n\"Grindlay\"\n,\n\"Grindle\"\n,\n\"Grinnell\"\n,\n\"Gris\"\n,\n\"Griselda\"\n,\n\"Griseldis\"\n,\n\"Grishilda\"\n,\n\"Grishilde\"\n,\n\"Grissel\"\n,\n\"Grissom\"\n,\n\"Gristede\"\n,\n\"Griswold\"\n,\n\"Griz\"\n,\n\"Grizel\"\n,\n\"Grizelda\"\n,\n\"Groark\"\n,\n\"Grobe\"\n,\n\"Grochow\"\n,\n\"Grodin\"\n,\n\"Grof\"\n,\n\"Grogan\"\n,\n\"Groh\"\n,\n\"Gromme\"\n,\n\"Grondin\"\n,\n\"Gronseth\"\n,\n\"Groome\"\n,\n\"Groos\"\n,\n\"Groot\"\n,\n\"Grory\"\n,\n\"Grosberg\"\n,\n\"Groscr\"\n,\n\"Grose\"\n,\n\"Grosmark\"\n,\n\"Gross\"\n,\n\"Grossman\"\n,\n\"Grosvenor\"\n,\n\"Grosz\"\n,\n\"Grote\"\n,\n\"Grounds\"\n,\n\"Grous\"\n,\n\"Grove\"\n,\n\"Groveman\"\n,\n\"Grover\"\n,\n\"Groves\"\n,\n\"Grubb\"\n,\n\"Grube\"\n,\n\"Gruber\"\n,\n\"Grubman\"\n,\n\"Gruchot\"\n,\n\"Grunberg\"\n,\n\"Grunenwald\"\n,\n\"Grussing\"\n,\n\"Gruver\"\n,\n\"Gschu\"\n,\n\"Guadalupe\"\n,\n\"Gualterio\"\n,\n\"Gualtiero\"\n,\n\"Guarino\"\n,\n\"Gudren\"\n,\n\"Gudrin\"\n,\n\"Gudrun\"\n,\n\"Guendolen\"\n,\n\"Guenevere\"\n,\n\"Guenna\"\n,\n\"Guenzi\"\n,\n\"Guerin\"\n,\n\"Guerra\"\n,\n\"Guevara\"\n,\n\"Guglielma\"\n,\n\"Guglielmo\"\n,\n\"Gui\"\n,\n\"Guibert\"\n,\n\"Guido\"\n,\n\"Guidotti\"\n,\n\"Guilbert\"\n,\n\"Guild\"\n,\n\"Guildroy\"\n,\n\"Guillaume\"\n,\n\"Guillema\"\n,\n\"Guillemette\"\n,\n\"Guillermo\"\n,\n\"Guimar\"\n,\n\"Guimond\"\n,\n\"Guinevere\"\n,\n\"Guinn\"\n,\n\"Guinna\"\n,\n\"Guise\"\n,\n\"Gujral\"\n,\n\"Gula\"\n,\n\"Gulgee\"\n,\n\"Gulick\"\n,\n\"Gun\"\n,\n\"Gunar\"\n,\n\"Gunas\"\n,\n\"Gundry\"\n,\n\"Gunilla\"\n,\n\"Gunn\"\n,\n\"Gunnar\"\n,\n\"Gunner\"\n,\n\"Gunning\"\n,\n\"Guntar\"\n,\n\"Gunter\"\n,\n\"Gunthar\"\n,\n\"Gunther\"\n,\n\"Gunzburg\"\n,\n\"Gupta\"\n,\n\"Gurango\"\n,\n\"Gurevich\"\n,\n\"Guria\"\n,\n\"Gurias\"\n,\n\"Gurl\"\n,\n\"Gurney\"\n,\n\"Gurolinick\"\n,\n\"Gurtner\"\n,\n\"Gus\"\n,\n\"Gusba\"\n,\n\"Gusella\"\n,\n\"Guss\"\n,\n\"Gussi\"\n,\n\"Gussie\"\n,\n\"Gussman\"\n,\n\"Gussy\"\n,\n\"Gusta\"\n,\n\"Gustaf\"\n,\n\"Gustafson\"\n,\n\"Gustafsson\"\n,\n\"Gustav\"\n,\n\"Gustave\"\n,\n\"Gustavo\"\n,\n\"Gustavus\"\n,\n\"Gusti\"\n,\n\"Gustie\"\n,\n\"Gustin\"\n,\n\"Gusty\"\n,\n\"Gut\"\n,\n\"Guthrey\"\n,\n\"Guthrie\"\n,\n\"Guthry\"\n,\n\"Gutow\"\n,\n\"Guttery\"\n,\n\"Guy\"\n,\n\"Guyer\"\n,\n\"Guyon\"\n,\n\"Guzel\"\n,\n\"Gwen\"\n,\n\"Gwendolen\"\n,\n\"Gwendolin\"\n,\n\"Gwendolyn\"\n,\n\"Gweneth\"\n,\n\"Gwenette\"\n,\n\"Gwenn\"\n,\n\"Gwenneth\"\n,\n\"Gwenni\"\n,\n\"Gwennie\"\n,\n\"Gwenny\"\n,\n\"Gwenora\"\n,\n\"Gwenore\"\n,\n\"Gwyn\"\n,\n\"Gwyneth\"\n,\n\"Gwynne\"\n,\n\"Gyasi\"\n,\n\"Gyatt\"\n,\n\"Gyimah\"\n,\n\"Gylys\"\n,\n\"Gypsie\"\n,\n\"Gypsy\"\n,\n\"Gytle\"\n,\n\"Ha\"\n,\n\"Haag\"\n,\n\"Haakon\"\n,\n\"Haas\"\n,\n\"Haase\"\n,\n\"Haberman\"\n,\n\"Hach\"\n,\n\"Hachman\"\n,\n\"Hachmann\"\n,\n\"Hachmin\"\n,\n\"Hackathorn\"\n,\n\"Hacker\"\n,\n\"Hackett\"\n,\n\"Hackney\"\n,\n\"Had\"\n,\n\"Haddad\"\n,\n\"Hadden\"\n,\n\"Haden\"\n,\n\"Hadik\"\n,\n\"Hadlee\"\n,\n\"Hadleigh\"\n,\n\"Hadley\"\n,\n\"Hadria\"\n,\n\"Hadrian\"\n,\n\"Hadsall\"\n,\n\"Hadwin\"\n,\n\"Hadwyn\"\n,\n\"Haeckel\"\n,\n\"Haerle\"\n,\n\"Haerr\"\n,\n\"Haff\"\n,\n\"Hafler\"\n,\n\"Hagai\"\n,\n\"Hagan\"\n,\n\"Hagar\"\n,\n\"Hagen\"\n,\n\"Hagerman\"\n,\n\"Haggai\"\n,\n\"Haggar\"\n,\n\"Haggerty\"\n,\n\"Haggi\"\n,\n\"Hagi\"\n,\n\"Hagood\"\n,\n\"Hahn\"\n,\n\"Hahnert\"\n,\n\"Hahnke\"\n,\n\"Haida\"\n,\n\"Haig\"\n,\n\"Haile\"\n,\n\"Hailee\"\n,\n\"Hailey\"\n,\n\"Haily\"\n,\n\"Haim\"\n,\n\"Haimes\"\n,\n\"Haines\"\n,\n\"Hak\"\n,\n\"Hakan\"\n,\n\"Hake\"\n,\n\"Hakeem\"\n,\n\"Hakim\"\n,\n\"Hako\"\n,\n\"Hakon\"\n,\n\"Hal\"\n,\n\"Haland\"\n,\n\"Halbeib\"\n,\n\"Halbert\"\n,\n\"Halda\"\n,\n\"Haldan\"\n,\n\"Haldane\"\n,\n\"Haldas\"\n,\n\"Haldeman\"\n,\n\"Halden\"\n,\n\"Haldes\"\n,\n\"Haldi\"\n,\n\"Haldis\"\n,\n\"Hale\"\n,\n\"Haleigh\"\n,\n\"Haletky\"\n,\n\"Haletta\"\n,\n\"Halette\"\n,\n\"Haley\"\n,\n\"Halfdan\"\n,\n\"Halfon\"\n,\n\"Halford\"\n,\n\"Hali\"\n,\n\"Halie\"\n,\n\"Halima\"\n,\n\"Halimeda\"\n,\n\"Hall\"\n,\n\"Halla\"\n,\n\"Hallagan\"\n,\n\"Hallam\"\n,\n\"Halland\"\n,\n\"Halle\"\n,\n\"Hallee\"\n,\n\"Hallerson\"\n,\n\"Hallett\"\n,\n\"Hallette\"\n,\n\"Halley\"\n,\n\"Halli\"\n,\n\"Halliday\"\n,\n\"Hallie\"\n,\n\"Hallock\"\n,\n\"Hallsy\"\n,\n\"Hallvard\"\n,\n\"Hally\"\n,\n\"Halona\"\n,\n\"Halonna\"\n,\n\"Halpern\"\n,\n\"Halsey\"\n,\n\"Halstead\"\n,\n\"Halsted\"\n,\n\"Halsy\"\n,\n\"Halvaard\"\n,\n\"Halverson\"\n,\n\"Ham\"\n,\n\"Hama\"\n,\n\"Hamachi\"\n,\n\"Hamal\"\n,\n\"Haman\"\n,\n\"Hamann\"\n,\n\"Hambley\"\n,\n\"Hamburger\"\n,\n\"Hamel\"\n,\n\"Hamer\"\n,\n\"Hamford\"\n,\n\"Hamforrd\"\n,\n\"Hamfurd\"\n,\n\"Hamid\"\n,\n\"Hamil\"\n,\n\"Hamilton\"\n,\n\"Hamish\"\n,\n\"Hamlani\"\n,\n\"Hamlen\"\n,\n\"Hamlet\"\n,\n\"Hamlin\"\n,\n\"Hammad\"\n,\n\"Hammel\"\n,\n\"Hammer\"\n,\n\"Hammerskjold\"\n,\n\"Hammock\"\n,\n\"Hammond\"\n,\n\"Hamner\"\n,\n\"Hamnet\"\n,\n\"Hamo\"\n,\n\"Hamon\"\n,\n\"Hampton\"\n,\n\"Hamrah\"\n,\n\"Hamrnand\"\n,\n\"Han\"\n,\n\"Hana\"\n,\n\"Hanae\"\n,\n\"Hanafee\"\n,\n\"Hanako\"\n,\n\"Hanan\"\n,\n\"Hance\"\n,\n\"Hancock\"\n,\n\"Handal\"\n,\n\"Handbook\"\n,\n\"Handel\"\n,\n\"Handler\"\n,\n\"Hands\"\n,\n\"Handy\"\n,\n\"Haney\"\n,\n\"Hanford\"\n,\n\"Hanforrd\"\n,\n\"Hanfurd\"\n,\n\"Hank\"\n,\n\"Hankins\"\n,\n\"Hanleigh\"\n,\n\"Hanley\"\n,\n\"Hanna\"\n,\n\"Hannah\"\n,\n\"Hannan\"\n,\n\"Hanni\"\n,\n\"Hannibal\"\n,\n\"Hannie\"\n,\n\"Hannis\"\n,\n\"Hannon\"\n,\n\"Hannover\"\n,\n\"Hannus\"\n,\n\"Hanny\"\n,\n\"Hanover\"\n,\n\"Hans\"\n,\n\"Hanschen\"\n,\n\"Hansel\"\n,\n\"Hanselka\"\n,\n\"Hansen\"\n,\n\"Hanser\"\n,\n\"Hanshaw\"\n,\n\"Hansiain\"\n,\n\"Hanson\"\n,\n\"Hanus\"\n,\n\"Hanway\"\n,\n\"Hanzelin\"\n,\n\"Happ\"\n,\n\"Happy\"\n,\n\"Hapte\"\n,\n\"Hara\"\n,\n\"Harald\"\n,\n\"Harbard\"\n,\n\"Harberd\"\n,\n\"Harbert\"\n,\n\"Harbird\"\n,\n\"Harbison\"\n,\n\"Harbot\"\n,\n\"Harbour\"\n,\n\"Harcourt\"\n,\n\"Hardan\"\n,\n\"Harday\"\n,\n\"Hardden\"\n,\n\"Hardej\"\n,\n\"Harden\"\n,\n\"Hardi\"\n,\n\"Hardie\"\n,\n\"Hardigg\"\n,\n\"Hardin\"\n,\n\"Harding\"\n,\n\"Hardman\"\n,\n\"Hardner\"\n,\n\"Hardunn\"\n,\n\"Hardwick\"\n,\n\"Hardy\"\n,\n\"Hare\"\n,\n\"Harelda\"\n,\n\"Harewood\"\n,\n\"Harhay\"\n,\n\"Harilda\"\n,\n\"Harim\"\n,\n\"Harl\"\n,\n\"Harlamert\"\n,\n\"Harlan\"\n,\n\"Harland\"\n,\n\"Harle\"\n,\n\"Harleigh\"\n,\n\"Harlen\"\n,\n\"Harlene\"\n,\n\"Harley\"\n,\n\"Harli\"\n,\n\"Harlie\"\n,\n\"Harlin\"\n,\n\"Harlow\"\n,\n\"Harman\"\n,\n\"Harmaning\"\n,\n\"Harmon\"\n,\n\"Harmonia\"\n,\n\"Harmonie\"\n,\n\"Harmony\"\n,\n\"Harms\"\n,\n\"Harned\"\n,\n\"Harneen\"\n,\n\"Harness\"\n,\n\"Harod\"\n,\n\"Harold\"\n,\n\"Harolda\"\n,\n\"Haroldson\"\n,\n\"Haroun\"\n,\n\"Harp\"\n,\n\"Harper\"\n,\n\"Harpole\"\n,\n\"Harpp\"\n,\n\"Harragan\"\n,\n\"Harrell\"\n,\n\"Harri\"\n,\n\"Harrie\"\n,\n\"Harriet\"\n,\n\"Harriett\"\n,\n\"Harrietta\"\n,\n\"Harriette\"\n,\n\"Harriman\"\n,\n\"Harrington\"\n,\n\"Harriot\"\n,\n\"Harriott\"\n,\n\"Harris\"\n,\n\"Harrison\"\n,\n\"Harrod\"\n,\n\"Harrow\"\n,\n\"Harrus\"\n,\n\"Harry\"\n,\n\"Harshman\"\n,\n\"Harsho\"\n,\n\"Hart\"\n,\n\"Harte\"\n,\n\"Hartfield\"\n,\n\"Hartill\"\n,\n\"Hartley\"\n,\n\"Hartman\"\n,\n\"Hartmann\"\n,\n\"Hartmunn\"\n,\n\"Hartnett\"\n,\n\"Harts\"\n,\n\"Hartwell\"\n,\n\"Harty\"\n,\n\"Hartzel\"\n,\n\"Hartzell\"\n,\n\"Hartzke\"\n,\n\"Harv\"\n,\n\"Harvard\"\n,\n\"Harve\"\n,\n\"Harvey\"\n,\n\"Harvie\"\n,\n\"Harvison\"\n,\n\"Harwell\"\n,\n\"Harwill\"\n,\n\"Harwilll\"\n,\n\"Harwin\"\n,\n\"Hasan\"\n,\n\"Hasen\"\n,\n\"Hasheem\"\n,\n\"Hashim\"\n,\n\"Hashimoto\"\n,\n\"Hashum\"\n,\n\"Hasin\"\n,\n\"Haskel\"\n,\n\"Haskell\"\n,\n\"Haskins\"\n,\n\"Haslam\"\n,\n\"Haslett\"\n,\n\"Hasseman\"\n,\n\"Hassett\"\n,\n\"Hassi\"\n,\n\"Hassin\"\n,\n\"Hastie\"\n,\n\"Hastings\"\n,\n\"Hasty\"\n,\n\"Haswell\"\n,\n\"Hatch\"\n,\n\"Hatcher\"\n,\n\"Hatfield\"\n,\n\"Hathaway\"\n,\n\"Hathcock\"\n,\n\"Hatti\"\n,\n\"Hattie\"\n,\n\"Hatty\"\n,\n\"Hau\"\n,\n\"Hauck\"\n,\n\"Hauge\"\n,\n\"Haugen\"\n,\n\"Hauger\"\n,\n\"Haughay\"\n,\n\"Haukom\"\n,\n\"Hauser\"\n,\n\"Hausmann\"\n,\n\"Hausner\"\n,\n\"Havard\"\n,\n\"Havelock\"\n,\n\"Haveman\"\n,\n\"Haven\"\n,\n\"Havener\"\n,\n\"Havens\"\n,\n\"Havstad\"\n,\n\"Hawger\"\n,\n\"Hawk\"\n,\n\"Hawken\"\n,\n\"Hawker\"\n,\n\"Hawkie\"\n,\n\"Hawkins\"\n,\n\"Hawley\"\n,\n\"Hawthorn\"\n,\n\"Hax\"\n,\n\"Hay\"\n,\n\"Haya\"\n,\n\"Hayashi\"\n,\n\"Hayden\"\n,\n\"Haydon\"\n,\n\"Haye\"\n,\n\"Hayes\"\n,\n\"Hayley\"\n,\n\"Hayman\"\n,\n\"Haymes\"\n,\n\"Haymo\"\n,\n\"Hayne\"\n,\n\"Haynes\"\n,\n\"Haynor\"\n,\n\"Hayott\"\n,\n\"Hays\"\n,\n\"Hayse\"\n,\n\"Hayton\"\n,\n\"Hayward\"\n,\n\"Haywood\"\n,\n\"Hayyim\"\n,\n\"Hazaki\"\n,\n\"Hazard\"\n,\n\"Haze\"\n,\n\"Hazeghi\"\n,\n\"Hazel\"\n,\n\"Hazelton\"\n,\n\"Hazem\"\n,\n\"Hazen\"\n,\n\"Hazlett\"\n,\n\"Hazlip\"\n,\n\"Head\"\n,\n\"Heady\"\n,\n\"Healey\"\n,\n\"Healion\"\n,\n\"Heall\"\n,\n\"Healy\"\n,\n\"Heaps\"\n,\n\"Hearn\"\n,\n\"Hearsh\"\n,\n\"Heater\"\n,\n\"Heath\"\n,\n\"Heathcote\"\n,\n\"Heather\"\n,\n\"Hebbe\"\n,\n\"Hebe\"\n,\n\"Hebel\"\n,\n\"Heber\"\n,\n\"Hebert\"\n,\n\"Hebner\"\n,\n\"Hebrew\"\n,\n\"Hecht\"\n,\n\"Heck\"\n,\n\"Hecker\"\n,\n\"Hecklau\"\n,\n\"Hector\"\n,\n\"Heda\"\n,\n\"Hedberg\"\n,\n\"Hedda\"\n,\n\"Heddi\"\n,\n\"Heddie\"\n,\n\"Heddy\"\n,\n\"Hedelman\"\n,\n\"Hedgcock\"\n,\n\"Hedges\"\n,\n\"Hedi\"\n,\n\"Hedley\"\n,\n\"Hedva\"\n,\n\"Hedvah\"\n,\n\"Hedve\"\n,\n\"Hedveh\"\n,\n\"Hedvig\"\n,\n\"Hedvige\"\n,\n\"Hedwig\"\n,\n\"Hedwiga\"\n,\n\"Hedy\"\n,\n\"Heeley\"\n,\n\"Heer\"\n,\n\"Heffron\"\n,\n\"Hefter\"\n,\n\"Hegarty\"\n,\n\"Hege\"\n,\n\"Heger\"\n,\n\"Hegyera\"\n,\n\"Hehre\"\n,\n\"Heid\"\n,\n\"Heida\"\n,\n\"Heidi\"\n,\n\"Heidie\"\n,\n\"Heidt\"\n,\n\"Heidy\"\n,\n\"Heigho\"\n,\n\"Heigl\"\n,\n\"Heilman\"\n,\n\"Heilner\"\n,\n\"Heim\"\n,\n\"Heimer\"\n,\n\"Heimlich\"\n,\n\"Hein\"\n,\n\"Heindrick\"\n,\n\"Heiner\"\n,\n\"Heiney\"\n,\n\"Heinrich\"\n,\n\"Heinrick\"\n,\n\"Heinrik\"\n,\n\"Heinrike\"\n,\n\"Heins\"\n,\n\"Heintz\"\n,\n\"Heise\"\n,\n\"Heisel\"\n,\n\"Heiskell\"\n,\n\"Heisser\"\n,\n\"Hekker\"\n,\n\"Hekking\"\n,\n\"Helaina\"\n,\n\"Helaine\"\n,\n\"Helali\"\n,\n\"Helban\"\n,\n\"Helbon\"\n,\n\"Helbona\"\n,\n\"Helbonia\"\n,\n\"Helbonna\"\n,\n\"Helbonnah\"\n,\n\"Helbonnas\"\n,\n\"Held\"\n,\n\"Helen\"\n,\n\"Helena\"\n,\n\"Helene\"\n,\n\"Helenka\"\n,\n\"Helfand\"\n,\n\"Helfant\"\n,\n\"Helga\"\n,\n\"Helge\"\n,\n\"Helgeson\"\n,\n\"Hellene\"\n,\n\"Heller\"\n,\n\"Helli\"\n,\n\"Hellman\"\n,\n\"Helm\"\n,\n\"Helman\"\n,\n\"Helmer\"\n,\n\"Helms\"\n,\n\"Helmut\"\n,\n\"Heloise\"\n,\n\"Helprin\"\n,\n\"Helsa\"\n,\n\"Helse\"\n,\n\"Helsell\"\n,\n\"Helsie\"\n,\n\"Helve\"\n,\n\"Helyn\"\n,\n\"Heman\"\n,\n\"Hembree\"\n,\n\"Hemingway\"\n,\n\"Hemminger\"\n,\n\"Hemphill\"\n,\n\"Hen\"\n,\n\"Hendel\"\n,\n\"Henden\"\n,\n\"Henderson\"\n,\n\"Hendon\"\n,\n\"Hendren\"\n,\n\"Hendrick\"\n,\n\"Hendricks\"\n,\n\"Hendrickson\"\n,\n\"Hendrik\"\n,\n\"Hendrika\"\n,\n\"Hendrix\"\n,\n\"Hendry\"\n,\n\"Henebry\"\n,\n\"Heng\"\n,\n\"Hengel\"\n,\n\"Henghold\"\n,\n\"Henig\"\n,\n\"Henigman\"\n,\n\"Henka\"\n,\n\"Henke\"\n,\n\"Henleigh\"\n,\n\"Henley\"\n,\n\"Henn\"\n,\n\"Hennahane\"\n,\n\"Hennebery\"\n,\n\"Hennessey\"\n,\n\"Hennessy\"\n,\n\"Henni\"\n,\n\"Hennie\"\n,\n\"Henning\"\n,\n\"Henri\"\n,\n\"Henricks\"\n,\n\"Henrie\"\n,\n\"Henrieta\"\n,\n\"Henrietta\"\n,\n\"Henriette\"\n,\n\"Henriha\"\n,\n\"Henrik\"\n,\n\"Henrion\"\n,\n\"Henrique\"\n,\n\"Henriques\"\n,\n\"Henry\"\n,\n\"Henryetta\"\n,\n\"Henryk\"\n,\n\"Henryson\"\n,\n\"Henson\"\n,\n\"Hentrich\"\n,\n\"Hephzibah\"\n,\n\"Hephzipa\"\n,\n\"Hephzipah\"\n,\n\"Heppman\"\n,\n\"Hepsiba\"\n,\n\"Hepsibah\"\n,\n\"Hepza\"\n,\n\"Hepzi\"\n,\n\"Hera\"\n,\n\"Herald\"\n,\n\"Herb\"\n,\n\"Herbert\"\n,\n\"Herbie\"\n,\n\"Herbst\"\n,\n\"Herby\"\n,\n\"Herc\"\n,\n\"Hercule\"\n,\n\"Hercules\"\n,\n\"Herculie\"\n,\n\"Hereld\"\n,\n\"Heriberto\"\n,\n\"Heringer\"\n,\n\"Herm\"\n,\n\"Herman\"\n,\n\"Hermann\"\n,\n\"Hermes\"\n,\n\"Hermia\"\n,\n\"Hermie\"\n,\n\"Hermina\"\n,\n\"Hermine\"\n,\n\"Herminia\"\n,\n\"Hermione\"\n,\n\"Hermon\"\n,\n\"Hermosa\"\n,\n\"Hermy\"\n,\n\"Hernandez\"\n,\n\"Hernando\"\n,\n\"Hernardo\"\n,\n\"Herod\"\n,\n\"Herodias\"\n,\n\"Herold\"\n,\n\"Heron\"\n,\n\"Herr\"\n,\n\"Herra\"\n,\n\"Herrah\"\n,\n\"Herrera\"\n,\n\"Herrick\"\n,\n\"Herries\"\n,\n\"Herring\"\n,\n\"Herrington\"\n,\n\"Herriott\"\n,\n\"Herrle\"\n,\n\"Herrmann\"\n,\n\"Herrod\"\n,\n\"Hersch\"\n,\n\"Herschel\"\n,\n\"Hersh\"\n,\n\"Hershel\"\n,\n\"Hershell\"\n,\n\"Herson\"\n,\n\"Herstein\"\n,\n\"Herta\"\n,\n\"Hertberg\"\n,\n\"Hertha\"\n,\n\"Hertz\"\n,\n\"Hertzfeld\"\n,\n\"Hertzog\"\n,\n\"Herv\"\n,\n\"Herve\"\n,\n\"Hervey\"\n,\n\"Herwick\"\n,\n\"Herwig\"\n,\n\"Herwin\"\n,\n\"Herzberg\"\n,\n\"Herzel\"\n,\n\"Herzen\"\n,\n\"Herzig\"\n,\n\"Herzog\"\n,\n\"Hescock\"\n,\n\"Heshum\"\n,\n\"Hesketh\"\n,\n\"Hesky\"\n,\n\"Hesler\"\n,\n\"Hesper\"\n,\n\"Hess\"\n,\n\"Hessler\"\n,\n\"Hessney\"\n,\n\"Hesta\"\n,\n\"Hester\"\n,\n\"Hesther\"\n,\n\"Hestia\"\n,\n\"Heti\"\n,\n\"Hett\"\n,\n\"Hetti\"\n,\n\"Hettie\"\n,\n\"Hetty\"\n,\n\"Heurlin\"\n,\n\"Heuser\"\n,\n\"Hew\"\n,\n\"Hewart\"\n,\n\"Hewe\"\n,\n\"Hewes\"\n,\n\"Hewet\"\n,\n\"Hewett\"\n,\n\"Hewie\"\n,\n\"Hewitt\"\n,\n\"Hey\"\n,\n\"Heyde\"\n,\n\"Heydon\"\n,\n\"Heyer\"\n,\n\"Heyes\"\n,\n\"Heyman\"\n,\n\"Heymann\"\n,\n\"Heyward\"\n,\n\"Heywood\"\n,\n\"Hezekiah\"\n,\n\"Hi\"\n,\n\"Hibben\"\n,\n\"Hibbert\"\n,\n\"Hibbitts\"\n,\n\"Hibbs\"\n,\n\"Hickey\"\n,\n\"Hickie\"\n,\n\"Hicks\"\n,\n\"Hidie\"\n,\n\"Hieronymus\"\n,\n\"Hiett\"\n,\n\"Higbee\"\n,\n\"Higginbotham\"\n,\n\"Higgins\"\n,\n\"Higginson\"\n,\n\"Higgs\"\n,\n\"High\"\n,\n\"Highams\"\n,\n\"Hightower\"\n,\n\"Higinbotham\"\n,\n\"Higley\"\n,\n\"Hijoung\"\n,\n\"Hike\"\n,\n\"Hilaire\"\n,\n\"Hilar\"\n,\n\"Hilaria\"\n,\n\"Hilario\"\n,\n\"Hilarius\"\n,\n\"Hilary\"\n,\n\"Hilbert\"\n,\n\"Hild\"\n,\n\"Hilda\"\n,\n\"Hildagard\"\n,\n\"Hildagarde\"\n,\n\"Hilde\"\n,\n\"Hildebrandt\"\n,\n\"Hildegaard\"\n,\n\"Hildegard\"\n,\n\"Hildegarde\"\n,\n\"Hildick\"\n,\n\"Hildie\"\n,\n\"Hildy\"\n,\n\"Hilel\"\n,\n\"Hill\"\n,\n\"Hillard\"\n,\n\"Hillari\"\n,\n\"Hillary\"\n,\n\"Hilleary\"\n,\n\"Hillegass\"\n,\n\"Hillel\"\n,\n\"Hillell\"\n,\n\"Hiller\"\n,\n\"Hillery\"\n,\n\"Hillhouse\"\n,\n\"Hilliard\"\n,\n\"Hilliary\"\n,\n\"Hillie\"\n,\n\"Hillier\"\n,\n\"Hillinck\"\n,\n\"Hillman\"\n,\n\"Hills\"\n,\n\"Hilly\"\n,\n\"Hillyer\"\n,\n\"Hiltan\"\n,\n\"Hilten\"\n,\n\"Hiltner\"\n,\n\"Hilton\"\n,\n\"Him\"\n,\n\"Hime\"\n,\n\"Himelman\"\n,\n\"Hinch\"\n,\n\"Hinckley\"\n,\n\"Hinda\"\n,\n\"Hindorff\"\n,\n\"Hindu\"\n,\n\"Hines\"\n,\n\"Hinkel\"\n,\n\"Hinkle\"\n,\n\"Hinman\"\n,\n\"Hinson\"\n,\n\"Hintze\"\n,\n\"Hinze\"\n,\n\"Hippel\"\n,\n\"Hirai\"\n,\n\"Hiram\"\n,\n\"Hirasuna\"\n,\n\"Hiro\"\n,\n\"Hiroko\"\n,\n\"Hiroshi\"\n,\n\"Hirsch\"\n,\n\"Hirschfeld\"\n,\n\"Hirsh\"\n,\n\"Hirst\"\n,\n\"Hirz\"\n,\n\"Hirza\"\n,\n\"Hisbe\"\n,\n\"Hitchcock\"\n,\n\"Hite\"\n,\n\"Hitoshi\"\n,\n\"Hitt\"\n,\n\"Hittel\"\n,\n\"Hizar\"\n,\n\"Hjerpe\"\n,\n\"Hluchy\"\n,\n\"Ho\"\n,\n\"Hoag\"\n,\n\"Hoagland\"\n,\n\"Hoang\"\n,\n\"Hoashis\"\n,\n\"Hoban\"\n,\n\"Hobard\"\n,\n\"Hobart\"\n,\n\"Hobbie\"\n,\n\"Hobbs\"\n,\n\"Hobey\"\n,\n\"Hobie\"\n,\n\"Hochman\"\n,\n\"Hock\"\n,\n\"Hocker\"\n,\n\"Hodess\"\n,\n\"Hodge\"\n,\n\"Hodges\"\n,\n\"Hodgkinson\"\n,\n\"Hodgson\"\n,\n\"Hodosh\"\n,\n\"Hoebart\"\n,\n\"Hoeg\"\n,\n\"Hoehne\"\n,\n\"Hoem\"\n,\n\"Hoenack\"\n,\n\"Hoes\"\n,\n\"Hoeve\"\n,\n\"Hoffarth\"\n,\n\"Hoffer\"\n,\n\"Hoffert\"\n,\n\"Hoffman\"\n,\n\"Hoffmann\"\n,\n\"Hofmann\"\n,\n\"Hofstetter\"\n,\n\"Hogan\"\n,\n\"Hogarth\"\n,\n\"Hogen\"\n,\n\"Hogg\"\n,\n\"Hogle\"\n,\n\"Hogue\"\n,\n\"Hoi\"\n,\n\"Hoisch\"\n,\n\"Hokanson\"\n,\n\"Hola\"\n,\n\"Holbrook\"\n,\n\"Holbrooke\"\n,\n\"Holcman\"\n,\n\"Holcomb\"\n,\n\"Holden\"\n,\n\"Holder\"\n,\n\"Holds\"\n,\n\"Hole\"\n,\n\"Holey\"\n,\n\"Holladay\"\n,\n\"Hollah\"\n,\n\"Holland\"\n,\n\"Hollander\"\n,\n\"Holle\"\n,\n\"Hollenbeck\"\n,\n\"Holleran\"\n,\n\"Hollerman\"\n,\n\"Holli\"\n,\n\"Hollie\"\n,\n\"Hollinger\"\n,\n\"Hollingsworth\"\n,\n\"Hollington\"\n,\n\"Hollis\"\n,\n\"Hollister\"\n,\n\"Holloway\"\n,\n\"Holly\"\n,\n\"Holly-Anne\"\n,\n\"Hollyanne\"\n,\n\"Holman\"\n,\n\"Holmann\"\n,\n\"Holmen\"\n,\n\"Holmes\"\n,\n\"Holms\"\n,\n\"Holmun\"\n,\n\"Holna\"\n,\n\"Holofernes\"\n,\n\"Holsworth\"\n,\n\"Holt\"\n,\n\"Holton\"\n,\n\"Holtorf\"\n,\n\"Holtz\"\n,\n\"Holub\"\n,\n\"Holzman\"\n,\n\"Homans\"\n,\n\"Home\"\n,\n\"Homer\"\n,\n\"Homere\"\n,\n\"Homerus\"\n,\n\"Homovec\"\n,\n\"Honan\"\n,\n\"Honebein\"\n,\n\"Honey\"\n,\n\"Honeyman\"\n,\n\"Honeywell\"\n,\n\"Hong\"\n,\n\"Honig\"\n,\n\"Honna\"\n,\n\"Honniball\"\n,\n\"Honor\"\n,\n\"Honora\"\n,\n\"Honoria\"\n,\n\"Honorine\"\n,\n\"Hoo\"\n,\n\"Hooge\"\n,\n\"Hook\"\n,\n\"Hooke\"\n,\n\"Hooker\"\n,\n\"Hoon\"\n,\n\"Hoopen\"\n,\n\"Hooper\"\n,\n\"Hoopes\"\n,\n\"Hootman\"\n,\n\"Hoover\"\n,\n\"Hope\"\n,\n\"Hopfinger\"\n,\n\"Hopkins\"\n,\n\"Hoppe\"\n,\n\"Hopper\"\n,\n\"Horace\"\n,\n\"Horacio\"\n,\n\"Horan\"\n,\n\"Horatia\"\n,\n\"Horatio\"\n,\n\"Horatius\"\n,\n\"Horbal\"\n,\n\"Horgan\"\n,\n\"Horick\"\n,\n\"Horlacher\"\n,\n\"Horn\"\n,\n\"Horne\"\n,\n\"Horner\"\n,\n\"Hornstein\"\n,\n\"Horodko\"\n,\n\"Horowitz\"\n,\n\"Horsey\"\n,\n\"Horst\"\n,\n\"Hort\"\n,\n\"Horten\"\n,\n\"Hortensa\"\n,\n\"Hortense\"\n,\n\"Hortensia\"\n,\n\"Horter\"\n,\n\"Horton\"\n,\n\"Horvitz\"\n,\n\"Horwath\"\n,\n\"Horwitz\"\n,\n\"Hosbein\"\n,\n\"Hose\"\n,\n\"Hosea\"\n,\n\"Hoseia\"\n,\n\"Hosfmann\"\n,\n\"Hoshi\"\n,\n\"Hoskinson\"\n,\n\"Hospers\"\n,\n\"Hotchkiss\"\n,\n\"Hotze\"\n,\n\"Hough\"\n,\n\"Houghton\"\n,\n\"Houlberg\"\n,\n\"Hound\"\n,\n\"Hourigan\"\n,\n\"Hourihan\"\n,\n\"Housen\"\n,\n\"Houser\"\n,\n\"Houston\"\n,\n\"Housum\"\n,\n\"Hovey\"\n,\n\"How\"\n,\n\"Howard\"\n,\n\"Howarth\"\n,\n\"Howe\"\n,\n\"Howell\"\n,\n\"Howenstein\"\n,\n\"Howes\"\n,\n\"Howey\"\n,\n\"Howie\"\n,\n\"Howlan\"\n,\n\"Howland\"\n,\n\"Howlend\"\n,\n\"Howlond\"\n,\n\"Howlyn\"\n,\n\"Howund\"\n,\n\"Howzell\"\n,\n\"Hoxie\"\n,\n\"Hoxsie\"\n,\n\"Hoy\"\n,\n\"Hoye\"\n,\n\"Hoyt\"\n,\n\"Hrutkay\"\n,\n\"Hsu\"\n,\n\"Hu\"\n,\n\"Huai\"\n,\n\"Huan\"\n,\n\"Huang\"\n,\n\"Huba\"\n,\n\"Hubbard\"\n,\n\"Hubble\"\n,\n\"Hube\"\n,\n\"Huber\"\n,\n\"Huberman\"\n,\n\"Hubert\"\n,\n\"Huberto\"\n,\n\"Huberty\"\n,\n\"Hubey\"\n,\n\"Hubie\"\n,\n\"Hubing\"\n,\n\"Hubsher\"\n,\n\"Huckaby\"\n,\n\"Huda\"\n,\n\"Hudgens\"\n,\n\"Hudis\"\n,\n\"Hudnut\"\n,\n\"Hudson\"\n,\n\"Huebner\"\n,\n\"Huei\"\n,\n\"Huesman\"\n,\n\"Hueston\"\n,\n\"Huey\"\n,\n\"Huff\"\n,\n\"Hufnagel\"\n,\n\"Huggins\"\n,\n\"Hugh\"\n,\n\"Hughes\"\n,\n\"Hughett\"\n,\n\"Hughie\"\n,\n\"Hughmanick\"\n,\n\"Hugibert\"\n,\n\"Hugo\"\n,\n\"Hugon\"\n,\n\"Hugues\"\n,\n\"Hui\"\n,\n\"Hujsak\"\n,\n\"Hukill\"\n,\n\"Hulbard\"\n,\n\"Hulbert\"\n,\n\"Hulbig\"\n,\n\"Hulburt\"\n,\n\"Hulda\"\n,\n\"Huldah\"\n,\n\"Hulen\"\n,\n\"Hull\"\n,\n\"Hullda\"\n,\n\"Hultgren\"\n,\n\"Hultin\"\n,\n\"Hulton\"\n,\n\"Hum\"\n,\n\"Humbert\"\n,\n\"Humberto\"\n,\n\"Humble\"\n,\n\"Hume\"\n,\n\"Humfrey\"\n,\n\"Humfrid\"\n,\n\"Humfried\"\n,\n\"Hummel\"\n,\n\"Humo\"\n,\n\"Hump\"\n,\n\"Humpage\"\n,\n\"Humph\"\n,\n\"Humphrey\"\n,\n\"Hun\"\n,\n\"Hunfredo\"\n,\n\"Hung\"\n,\n\"Hungarian\"\n,\n\"Hunger\"\n,\n\"Hunley\"\n,\n\"Hunsinger\"\n,\n\"Hunt\"\n,\n\"Hunter\"\n,\n\"Huntingdon\"\n,\n\"Huntington\"\n,\n\"Huntlee\"\n,\n\"Huntley\"\n,\n\"Huoh\"\n,\n\"Huppert\"\n,\n\"Hurd\"\n,\n\"Hurff\"\n,\n\"Hurlbut\"\n,\n\"Hurlee\"\n,\n\"Hurleigh\"\n,\n\"Hurless\"\n,\n\"Hurley\"\n,\n\"Hurlow\"\n,\n\"Hurst\"\n,\n\"Hurty\"\n,\n\"Hurwit\"\n,\n\"Hurwitz\"\n,\n\"Husain\"\n,\n\"Husch\"\n,\n\"Husein\"\n,\n\"Husha\"\n,\n\"Huskamp\"\n,\n\"Huskey\"\n,\n\"Hussar\"\n,\n\"Hussein\"\n,\n\"Hussey\"\n,\n\"Huston\"\n,\n\"Hut\"\n,\n\"Hutchings\"\n,\n\"Hutchins\"\n,\n\"Hutchinson\"\n,\n\"Hutchison\"\n,\n\"Hutner\"\n,\n\"Hutson\"\n,\n\"Hutt\"\n,\n\"Huttan\"\n,\n\"Hutton\"\n,\n\"Hux\"\n,\n\"Huxham\"\n,\n\"Huxley\"\n,\n\"Hwang\"\n,\n\"Hwu\"\n,\n\"Hy\"\n,\n\"Hyacinth\"\n,\n\"Hyacintha\"\n,\n\"Hyacinthe\"\n,\n\"Hyacinthia\"\n,\n\"Hyacinthie\"\n,\n\"Hyams\"\n,\n\"Hyatt\"\n,\n\"Hyde\"\n,\n\"Hylan\"\n,\n\"Hyland\"\n,\n\"Hylton\"\n,\n\"Hyman\"\n,\n\"Hymen\"\n,\n\"Hymie\"\n,\n\"Hynda\"\n,\n\"Hynes\"\n,\n\"Hyo\"\n,\n\"Hyozo\"\n,\n\"Hyps\"\n,\n\"Hyrup\"\n,\n\"Iago\"\n,\n\"Iain\"\n,\n\"Iams\"\n,\n\"Ian\"\n,\n\"Iand\"\n,\n\"Ianteen\"\n,\n\"Ianthe\"\n,\n\"Iaria\"\n,\n\"Iaverne\"\n,\n\"Ib\"\n,\n\"Ibbetson\"\n,\n\"Ibbie\"\n,\n\"Ibbison\"\n,\n\"Ibby\"\n,\n\"Ibrahim\"\n,\n\"Ibson\"\n,\n\"Ichabod\"\n,\n\"Icken\"\n,\n\"Id\"\n,\n\"Ida\"\n,\n\"Idalia\"\n,\n\"Idalina\"\n,\n\"Idaline\"\n,\n\"Idalla\"\n,\n\"Idden\"\n,\n\"Iddo\"\n,\n\"Ide\"\n,\n\"Idel\"\n,\n\"Idelia\"\n,\n\"Idell\"\n,\n\"Idelle\"\n,\n\"Idelson\"\n,\n\"Iden\"\n,\n\"Idette\"\n,\n\"Idleman\"\n,\n\"Idola\"\n,\n\"Idolah\"\n,\n\"Idolla\"\n,\n\"Idona\"\n,\n\"Idonah\"\n,\n\"Idonna\"\n,\n\"Idou\"\n,\n\"Idoux\"\n,\n\"Idzik\"\n,\n\"Iene\"\n,\n\"Ier\"\n,\n\"Ierna\"\n,\n\"Ieso\"\n,\n\"Ietta\"\n,\n\"Iey\"\n,\n\"Ifill\"\n,\n\"Igal\"\n,\n\"Igenia\"\n,\n\"Iggie\"\n,\n\"Iggy\"\n,\n\"Iglesias\"\n,\n\"Ignace\"\n,\n\"Ignacia\"\n,\n\"Ignacio\"\n,\n\"Ignacius\"\n,\n\"Ignatia\"\n,\n\"Ignatius\"\n,\n\"Ignatz\"\n,\n\"Ignatzia\"\n,\n\"Ignaz\"\n,\n\"Ignazio\"\n,\n\"Igor\"\n,\n\"Ihab\"\n,\n\"Iiette\"\n,\n\"Iila\"\n,\n\"Iinde\"\n,\n\"Iinden\"\n,\n\"Iives\"\n,\n\"Ike\"\n,\n\"Ikeda\"\n,\n\"Ikey\"\n,\n\"Ikkela\"\n,\n\"Ilaire\"\n,\n\"Ilan\"\n,\n\"Ilana\"\n,\n\"Ilario\"\n,\n\"Ilarrold\"\n,\n\"Ilbert\"\n,\n\"Ileana\"\n,\n\"Ileane\"\n,\n\"Ilene\"\n,\n\"Iline\"\n,\n\"Ilise\"\n,\n\"Ilka\"\n,\n\"Ilke\"\n,\n\"Illa\"\n,\n\"Illene\"\n,\n\"Illona\"\n,\n\"Illyes\"\n,\n\"Ilona\"\n,\n\"Ilonka\"\n,\n\"Ilowell\"\n,\n\"Ilsa\"\n,\n\"Ilse\"\n,\n\"Ilwain\"\n,\n\"Ilysa\"\n,\n\"Ilyse\"\n,\n\"Ilyssa\"\n,\n\"Im\"\n,\n\"Ima\"\n,\n\"Imalda\"\n,\n\"Iman\"\n,\n\"Imelda\"\n,\n\"Imelida\"\n,\n\"Imena\"\n,\n\"Immanuel\"\n,\n\"Imogen\"\n,\n\"Imogene\"\n,\n\"Imojean\"\n,\n\"Imray\"\n,\n\"Imre\"\n,\n\"Imtiaz\"\n,\n\"Ina\"\n,\n\"Incrocci\"\n,\n\"Indihar\"\n,\n\"Indira\"\n,\n\"Inerney\"\n,\n\"Ines\"\n,\n\"Inesita\"\n,\n\"Ineslta\"\n,\n\"Inessa\"\n,\n\"Inez\"\n,\n\"Infeld\"\n,\n\"Infield\"\n,\n\"Ing\"\n,\n\"Inga\"\n,\n\"Ingaberg\"\n,\n\"Ingaborg\"\n,\n\"Ingalls\"\n,\n\"Ingamar\"\n,\n\"Ingar\"\n,\n\"Inge\"\n,\n\"Ingeberg\"\n,\n\"Ingeborg\"\n,\n\"Ingelbert\"\n,\n\"Ingemar\"\n,\n\"Inger\"\n,\n\"Ingham\"\n,\n\"Inglebert\"\n,\n\"Ingles\"\n,\n\"Inglis\"\n,\n\"Ingmar\"\n,\n\"Ingold\"\n,\n\"Ingra\"\n,\n\"Ingraham\"\n,\n\"Ingram\"\n,\n\"Ingrid\"\n,\n\"Ingrim\"\n,\n\"Ingunna\"\n,\n\"Ingvar\"\n,\n\"Inigo\"\n,\n\"Inkster\"\n,\n\"Inman\"\n,\n\"Inna\"\n,\n\"Innes\"\n,\n\"Inness\"\n,\n\"Innis\"\n,\n\"Inoue\"\n,\n\"Intisar\"\n,\n\"Intosh\"\n,\n\"Intyre\"\n,\n\"Inverson\"\n,\n\"Iny\"\n,\n\"Ioab\"\n,\n\"Iolande\"\n,\n\"Iolanthe\"\n,\n\"Iolenta\"\n,\n\"Ion\"\n,\n\"Iona\"\n,\n\"Iong\"\n,\n\"Iorgo\"\n,\n\"Iorgos\"\n,\n\"Iorio\"\n,\n\"Iormina\"\n,\n\"Iosep\"\n,\n\"Ioved\"\n,\n\"Iover\"\n,\n\"Ioves\"\n,\n\"Iow\"\n,\n\"Ioyal\"\n,\n\"Iphagenia\"\n,\n\"Iphigenia\"\n,\n\"Iphigeniah\"\n,\n\"Iphlgenia\"\n,\n\"Ira\"\n,\n\"Iran\"\n,\n\"Irby\"\n,\n\"Iredale\"\n,\n\"Ireland\"\n,\n\"Irena\"\n,\n\"Irene\"\n,\n\"Irfan\"\n,\n\"Iridis\"\n,\n\"Iridissa\"\n,\n\"Irina\"\n,\n\"Iris\"\n,\n\"Irisa\"\n,\n\"Irish\"\n,\n\"Irita\"\n,\n\"Irma\"\n,\n\"Irme\"\n,\n\"Irmgard\"\n,\n\"Irmina\"\n,\n\"Irmine\"\n,\n\"Irra\"\n,\n\"Irv\"\n,\n\"Irvin\"\n,\n\"Irvine\"\n,\n\"Irving\"\n,\n\"Irwin\"\n,\n\"Irwinn\"\n,\n\"Isa\"\n,\n\"Isaac\"\n,\n\"Isaacs\"\n,\n\"Isaacson\"\n,\n\"Isaak\"\n,\n\"Isabea\"\n,\n\"Isabeau\"\n,\n\"Isabel\"\n,\n\"Isabelita\"\n,\n\"Isabella\"\n,\n\"Isabelle\"\n,\n\"Isac\"\n,\n\"Isacco\"\n,\n\"Isador\"\n,\n\"Isadora\"\n,\n\"Isadore\"\n,\n\"Isahella\"\n,\n\"Isaiah\"\n,\n\"Isak\"\n,\n\"Isbel\"\n,\n\"Isbella\"\n,\n\"Isborne\"\n,\n\"Iseabal\"\n,\n\"Isherwood\"\n,\n\"Ishii\"\n,\n\"Ishmael\"\n,\n\"Ishmul\"\n,\n\"Isia\"\n,\n\"Isiah\"\n,\n\"Isiahi\"\n,\n\"Isidor\"\n,\n\"Isidora\"\n,\n\"Isidore\"\n,\n\"Isidoro\"\n,\n\"Isidro\"\n,\n\"Isis\"\n,\n\"Isla\"\n,\n\"Islaen\"\n,\n\"Island\"\n,\n\"Isle\"\n,\n\"Islean\"\n,\n\"Isleana\"\n,\n\"Isleen\"\n,\n\"Islek\"\n,\n\"Isma\"\n,\n\"Isman\"\n,\n\"Isobel\"\n,\n\"Isola\"\n,\n\"Isolda\"\n,\n\"Isolde\"\n,\n\"Isolt\"\n,\n\"Israel\"\n,\n\"Israeli\"\n,\n\"Issi\"\n,\n\"Issiah\"\n,\n\"Issie\"\n,\n\"Issy\"\n,\n\"Ita\"\n,\n\"Itagaki\"\n,\n\"Itch\"\n,\n\"Ithaman\"\n,\n\"Ithnan\"\n,\n\"Itin\"\n,\n\"Iva\"\n,\n\"Ivah\"\n,\n\"Ivan\"\n,\n\"Ivana\"\n,\n\"Ivanah\"\n,\n\"Ivanna\"\n,\n\"Ivar\"\n,\n\"Ivatts\"\n,\n\"Ive\"\n,\n\"Ivens\"\n,\n\"Iver\"\n,\n\"Ivers\"\n,\n\"Iverson\"\n,\n\"Ives\"\n,\n\"Iveson\"\n,\n\"Ivett\"\n,\n\"Ivette\"\n,\n\"Ivetts\"\n,\n\"Ivey\"\n,\n\"Ivie\"\n,\n\"Ivo\"\n,\n\"Ivon\"\n,\n\"Ivonne\"\n,\n\"Ivor\"\n,\n\"Ivory\"\n,\n\"Ivy\"\n,\n\"Iy\"\n,\n\"Iyre\"\n,\n\"Iz\"\n,\n\"Izaak\"\n,\n\"Izabel\"\n,\n\"Izak\"\n,\n\"Izawa\"\n,\n\"Izy\"\n,\n\"Izzy\"\n,\n\"Ja\"\n,\n\"Jaal\"\n,\n\"Jaala\"\n,\n\"Jaan\"\n,\n\"Jaban\"\n,\n\"Jabe\"\n,\n\"Jabez\"\n,\n\"Jabin\"\n,\n\"Jablon\"\n,\n\"Jabon\"\n,\n\"Jac\"\n,\n\"Jacenta\"\n,\n\"Jacey\"\n,\n\"Jacie\"\n,\n\"Jacinda\"\n,\n\"Jacinta\"\n,\n\"Jacintha\"\n,\n\"Jacinthe\"\n,\n\"Jacinto\"\n,\n\"Jack\"\n,\n\"Jackelyn\"\n,\n\"Jacki\"\n,\n\"Jackie\"\n,\n\"Jacklin\"\n,\n\"Jacklyn\"\n,\n\"Jackquelin\"\n,\n\"Jackqueline\"\n,\n\"Jackson\"\n,\n\"Jacky\"\n,\n\"Jaclin\"\n,\n\"Jaclyn\"\n,\n\"Jaco\"\n,\n\"Jacob\"\n,\n\"Jacoba\"\n,\n\"Jacobah\"\n,\n\"Jacobba\"\n,\n\"Jacobina\"\n,\n\"Jacobine\"\n,\n\"Jacobo\"\n,\n\"Jacobs\"\n,\n\"Jacobsen\"\n,\n\"Jacobsohn\"\n,\n\"Jacobson\"\n,\n\"Jacoby\"\n,\n\"Jacquelin\"\n,\n\"Jacqueline\"\n,\n\"Jacquelyn\"\n,\n\"Jacquelynn\"\n,\n\"Jacquenetta\"\n,\n\"Jacquenette\"\n,\n\"Jacques\"\n,\n\"Jacquet\"\n,\n\"Jacquetta\"\n,\n\"Jacquette\"\n,\n\"Jacqui\"\n,\n\"Jacquie\"\n,\n\"Jacy\"\n,\n\"Jacynth\"\n,\n\"Jada\"\n,\n\"Jadd\"\n,\n\"Jadda\"\n,\n\"Jaddan\"\n,\n\"Jaddo\"\n,\n\"Jade\"\n,\n\"Jadwiga\"\n,\n\"Jae\"\n,\n\"Jaeger\"\n,\n\"Jaehne\"\n,\n\"Jael\"\n,\n\"Jaela\"\n,\n\"Jaella\"\n,\n\"Jaenicke\"\n,\n\"Jaf\"\n,\n\"Jaffe\"\n,\n\"Jagir\"\n,\n\"Jago\"\n,\n\"Jahdai\"\n,\n\"Jahdal\"\n,\n\"Jahdiel\"\n,\n\"Jahdol\"\n,\n\"Jahn\"\n,\n\"Jahncke\"\n,\n\"Jaime\"\n,\n\"Jaime \"\n,\n\"Jaimie\"\n,\n\"Jain\"\n,\n\"Jaine\"\n,\n\"Jair\"\n,\n\"Jairia\"\n,\n\"Jake\"\n,\n\"Jakie\"\n,\n\"Jakob\"\n,\n\"Jakoba\"\n,\n\"Jala\"\n,\n\"Jalbert\"\n,\n\"Jallier\"\n,\n\"Jamaal\"\n,\n\"Jamal\"\n,\n\"Jamel\"\n,\n\"James\"\n,\n\"Jameson\"\n,\n\"Jamesy\"\n,\n\"Jamey\"\n,\n\"Jami\"\n,\n\"Jamie\"\n,\n\"Jamieson\"\n,\n\"Jamil\"\n,\n\"Jamila\"\n,\n\"Jamill\"\n,\n\"Jamilla\"\n,\n\"Jamille\"\n,\n\"Jamima\"\n,\n\"Jamin\"\n,\n\"Jamison\"\n,\n\"Jammal\"\n,\n\"Jammie\"\n,\n\"Jammin\"\n,\n\"Jamnes\"\n,\n\"Jamnis\"\n,\n\"Jan\"\n,\n\"Jana\"\n,\n\"Janaya\"\n,\n\"Janaye\"\n,\n\"Jandel\"\n,\n\"Jandy\"\n,\n\"Jane\"\n,\n\"Janean\"\n,\n\"Janeczka\"\n,\n\"Janeen\"\n,\n\"Janek\"\n,\n\"Janel\"\n,\n\"Janela\"\n,\n\"Janella\"\n,\n\"Janelle\"\n,\n\"Janene\"\n,\n\"Janenna\"\n,\n\"Janerich\"\n,\n\"Janessa\"\n,\n\"Janet\"\n,\n\"Janeta\"\n,\n\"Janetta\"\n,\n\"Janette\"\n,\n\"Janeva\"\n,\n\"Janey\"\n,\n\"Jangro\"\n,\n\"Jania\"\n,\n\"Janice\"\n,\n\"Janicki\"\n,\n\"Janie\"\n,\n\"Janifer\"\n,\n\"Janik\"\n,\n\"Janina\"\n,\n\"Janine\"\n,\n\"Janis\"\n,\n\"Janith\"\n,\n\"Janiuszck\"\n,\n\"Janka\"\n,\n\"Jankell\"\n,\n\"Jankey\"\n,\n\"Jann\"\n,\n\"Janna\"\n,\n\"Jannel\"\n,\n\"Jannelle\"\n,\n\"Jannery\"\n,\n\"Janos\"\n,\n\"Janot\"\n,\n\"Jansen\"\n,\n\"Jansson\"\n,\n\"Januarius\"\n,\n\"January\"\n,\n\"Januisz\"\n,\n\"Janus\"\n,\n\"Jany\"\n,\n\"Janyte\"\n,\n\"Japeth\"\n,\n\"Japha\"\n,\n\"Japheth\"\n,\n\"Jaqitsch\"\n,\n\"Jaquelin\"\n,\n\"Jaquelyn\"\n,\n\"Jaquenetta\"\n,\n\"Jaquenette\"\n,\n\"Jaquiss\"\n,\n\"Jaquith\"\n,\n\"Jara\"\n,\n\"Jarad\"\n,\n\"Jard\"\n,\n\"Jardena\"\n,\n\"Jareb\"\n,\n\"Jared\"\n,\n\"Jarek\"\n,\n\"Jaret\"\n,\n\"Jari\"\n,\n\"Jariah\"\n,\n\"Jarib\"\n,\n\"Jarid\"\n,\n\"Jarietta\"\n,\n\"Jarita\"\n,\n\"Jarl\"\n,\n\"Jarlath\"\n,\n\"Jarlathus\"\n,\n\"Jarlen\"\n,\n\"Jarnagin\"\n,\n\"Jarrad\"\n,\n\"Jarred\"\n,\n\"Jarrell\"\n,\n\"Jarret\"\n,\n\"Jarrett\"\n,\n\"Jarrid\"\n,\n\"Jarrod\"\n,\n\"Jarrow\"\n,\n\"Jarv\"\n,\n\"Jarvey\"\n,\n\"Jarvis\"\n,\n\"Jary\"\n,\n\"Jase\"\n,\n\"Jasen\"\n,\n\"Jasik\"\n,\n\"Jasisa\"\n,\n\"Jasmin\"\n,\n\"Jasmina\"\n,\n\"Jasmine\"\n,\n\"Jason\"\n,\n\"Jasper\"\n,\n\"Jasun\"\n,\n\"Jauch\"\n,\n\"Jaunita\"\n,\n\"Javed\"\n,\n\"Javier\"\n,\n\"Javler\"\n,\n\"Jaworski\"\n,\n\"Jay\"\n,\n\"Jaycee\"\n,\n\"Jaye\"\n,\n\"Jaylene\"\n,\n\"Jayme\"\n,\n\"Jaymee\"\n,\n\"Jaymie\"\n,\n\"Jayne\"\n,\n\"Jaynell\"\n,\n\"Jaynes\"\n,\n\"Jayson\"\n,\n\"Jazmin\"\n,\n\"Jdavie\"\n,\n\"Jea\"\n,\n\"Jean\"\n,\n\"Jean-Claude\"\n,\n\"Jeana\"\n,\n\"Jeane\"\n,\n\"Jeanelle\"\n,\n\"Jeanette\"\n,\n\"Jeanie\"\n,\n\"Jeanine\"\n,\n\"Jeanna\"\n,\n\"Jeanne\"\n,\n\"Jeannette\"\n,\n\"Jeannie\"\n,\n\"Jeannine\"\n,\n\"Jeavons\"\n,\n\"Jeaz\"\n,\n\"Jeb\"\n,\n\"Jecho\"\n,\n\"Jecoa\"\n,\n\"Jecon\"\n,\n\"Jeconiah\"\n,\n\"Jed\"\n,\n\"Jedd\"\n,\n\"Jeddy\"\n,\n\"Jedediah\"\n,\n\"Jedidiah\"\n,\n\"Jedlicka\"\n,\n\"Jedthus\"\n,\n\"Jeff\"\n,\n\"Jeffcott\"\n,\n\"Jefferey\"\n,\n\"Jeffers\"\n,\n\"Jefferson\"\n,\n\"Jeffery\"\n,\n\"Jeffie\"\n,\n\"Jeffrey\"\n,\n\"Jeffries\"\n,\n\"Jeffry\"\n,\n\"Jeffy\"\n,\n\"Jegar\"\n,\n\"Jeggar\"\n,\n\"Jegger\"\n,\n\"Jehanna\"\n,\n\"Jehiah\"\n,\n\"Jehial\"\n,\n\"Jehias\"\n,\n\"Jehiel\"\n,\n\"Jehius\"\n,\n\"Jehoash\"\n,\n\"Jehovah\"\n,\n\"Jehu\"\n,\n\"Jelena\"\n,\n\"Jelene\"\n,\n\"Jelks\"\n,\n\"Jelle\"\n,\n\"Jelsma\"\n,\n\"Jem\"\n,\n\"Jemena\"\n,\n\"Jemie\"\n,\n\"Jemima\"\n,\n\"Jemimah\"\n,\n\"Jemina\"\n,\n\"Jeminah\"\n,\n\"Jemine\"\n,\n\"Jemma\"\n,\n\"Jemmie\"\n,\n\"Jemmy\"\n,\n\"Jempty\"\n,\n\"Jemy\"\n,\n\"Jen\"\n,\n\"Jena\"\n,\n\"Jenda\"\n,\n\"Jenei\"\n,\n\"Jenelle\"\n,\n\"Jenesia\"\n,\n\"Jenette\"\n,\n\"Jeni\"\n,\n\"Jenica\"\n,\n\"Jeniece\"\n,\n\"Jenifer\"\n,\n\"Jeniffer\"\n,\n\"Jenilee\"\n,\n\"Jenine\"\n,\n\"Jenkel\"\n,\n\"Jenkins\"\n,\n\"Jenks\"\n,\n\"Jenn\"\n,\n\"Jenna\"\n,\n\"Jenne\"\n,\n\"Jennee\"\n,\n\"Jenness\"\n,\n\"Jennette\"\n,\n\"Jenni\"\n,\n\"Jennica\"\n,\n\"Jennie\"\n,\n\"Jennifer\"\n,\n\"Jennilee\"\n,\n\"Jennine\"\n,\n\"Jennings\"\n,\n\"Jenny\"\n,\n\"Jeno\"\n,\n\"Jens\"\n,\n\"Jensen\"\n,\n\"Jentoft\"\n,\n\"Jephthah\"\n,\n\"Jephum\"\n,\n\"Jepson\"\n,\n\"Jepum\"\n,\n\"Jer\"\n,\n\"Jerad\"\n,\n\"Jerald\"\n,\n\"Jeraldine\"\n,\n\"Jeralee\"\n,\n\"Jeramey\"\n,\n\"Jeramie\"\n,\n\"Jere\"\n,\n\"Jereld\"\n,\n\"Jereme\"\n,\n\"Jeremiah\"\n,\n\"Jeremias\"\n,\n\"Jeremie\"\n,\n\"Jeremy\"\n,\n\"Jeri\"\n,\n\"Jeritah\"\n,\n\"Jermain\"\n,\n\"Jermaine\"\n,\n\"Jerman\"\n,\n\"Jermayne\"\n,\n\"Jermyn\"\n,\n\"Jerol\"\n,\n\"Jerold\"\n,\n\"Jeroma\"\n,\n\"Jerome\"\n,\n\"Jeromy\"\n,\n\"Jerri\"\n,\n\"Jerrie\"\n,\n\"Jerrilee\"\n,\n\"Jerrilyn\"\n,\n\"Jerrine\"\n,\n\"Jerrol\"\n,\n\"Jerrold\"\n,\n\"Jerroll\"\n,\n\"Jerrome\"\n,\n\"Jerry\"\n,\n\"Jerrylee\"\n,\n\"Jerusalem\"\n,\n\"Jervis\"\n,\n\"Jerz\"\n,\n\"Jesh\"\n,\n\"Jesher\"\n,\n\"Jess\"\n,\n\"Jessa\"\n,\n\"Jessabell\"\n,\n\"Jessalin\"\n,\n\"Jessalyn\"\n,\n\"Jessamine\"\n,\n\"Jessamyn\"\n,\n\"Jesse\"\n,\n\"Jessee\"\n,\n\"Jesselyn\"\n,\n\"Jessen\"\n,\n\"Jessey\"\n,\n\"Jessi\"\n,\n\"Jessica\"\n,\n\"Jessie\"\n,\n\"Jessika\"\n,\n\"Jessy\"\n,\n\"Jestude\"\n,\n\"Jesus\"\n,\n\"Jeth\"\n,\n\"Jethro\"\n,\n\"Jeu\"\n,\n\"Jeunesse\"\n,\n\"Jeuz\"\n,\n\"Jevon\"\n,\n\"Jew\"\n,\n\"Jewel\"\n,\n\"Jewell\"\n,\n\"Jewelle\"\n,\n\"Jewett\"\n,\n\"Jews\"\n,\n\"Jez\"\n,\n\"Jezabel\"\n,\n\"Jezabella\"\n,\n\"Jezabelle\"\n,\n\"Jezebel\"\n,\n\"Jezreel\"\n,\n\"Ji\"\n,\n\"Jill\"\n,\n\"Jillana\"\n,\n\"Jillane\"\n,\n\"Jillayne\"\n,\n\"Jilleen\"\n,\n\"Jillene\"\n,\n\"Jilli\"\n,\n\"Jillian\"\n,\n\"Jillie\"\n,\n\"Jilly\"\n,\n\"Jim\"\n,\n\"Jimmie\"\n,\n\"Jimmy\"\n,\n\"Jinny\"\n,\n\"Jit\"\n,\n\"Jo\"\n,\n\"Joab\"\n,\n\"Joachim\"\n,\n\"Joachima\"\n,\n\"Joacima\"\n,\n\"Joacimah\"\n,\n\"Joan\"\n,\n\"Joana\"\n,\n\"Joane\"\n,\n\"Joanie\"\n,\n\"Joann\"\n,\n\"Joanna\"\n,\n\"Joanne\"\n,\n\"Joannes\"\n,\n\"Joao\"\n,\n\"Joappa\"\n,\n\"Joaquin\"\n,\n\"Joash\"\n,\n\"Joashus\"\n,\n\"Job\"\n,\n\"Jobe\"\n,\n\"Jobey\"\n,\n\"Jobi\"\n,\n\"Jobie\"\n,\n\"Jobina\"\n,\n\"Joby\"\n,\n\"Jobye\"\n,\n\"Jobyna\"\n,\n\"Jocelin\"\n,\n\"Joceline\"\n,\n\"Jocelyn\"\n,\n\"Jocelyne\"\n,\n\"Jochbed\"\n,\n\"Jochebed\"\n,\n\"Jock\"\n,\n\"Jocko\"\n,\n\"Jodee\"\n,\n\"Jodi\"\n,\n\"Jodie\"\n,\n\"Jodoin\"\n,\n\"Jody\"\n,\n\"Joe\"\n,\n\"Joeann\"\n,\n\"Joed\"\n,\n\"Joel\"\n,\n\"Joela\"\n,\n\"Joelie\"\n,\n\"Joell\"\n,\n\"Joella\"\n,\n\"Joelle\"\n,\n\"Joellen\"\n,\n\"Joelly\"\n,\n\"Joellyn\"\n,\n\"Joelynn\"\n,\n\"Joerg\"\n,\n\"Joete\"\n,\n\"Joette\"\n,\n\"Joey\"\n,\n\"Joh\"\n,\n\"Johan\"\n,\n\"Johanan\"\n,\n\"Johann\"\n,\n\"Johanna\"\n,\n\"Johannah\"\n,\n\"Johannes\"\n,\n\"Johannessen\"\n,\n\"Johansen\"\n,\n\"Johathan\"\n,\n\"Johen\"\n,\n\"Johiah\"\n,\n\"Johm\"\n,\n\"John\"\n,\n\"Johna\"\n,\n\"Johnath\"\n,\n\"Johnathan\"\n,\n\"Johnathon\"\n,\n\"Johnette\"\n,\n\"Johnna\"\n,\n\"Johnnie\"\n,\n\"Johnny\"\n,\n\"Johns\"\n,\n\"Johnson\"\n,\n\"Johnsson\"\n,\n\"Johnsten\"\n,\n\"Johnston\"\n,\n\"Johnstone\"\n,\n\"Johny\"\n,\n\"Johppa\"\n,\n\"Johppah\"\n,\n\"Johst\"\n,\n\"Joice\"\n,\n\"Joiner\"\n,\n\"Jojo\"\n,\n\"Joktan\"\n,\n\"Jola\"\n,\n\"Jolanta\"\n,\n\"Jolda\"\n,\n\"Jolee\"\n,\n\"Joleen\"\n,\n\"Jolene\"\n,\n\"Jolenta\"\n,\n\"Joletta\"\n,\n\"Joli\"\n,\n\"Jolie\"\n,\n\"Joliet\"\n,\n\"Joline\"\n,\n\"Jollanta\"\n,\n\"Jollenta\"\n,\n\"Joly\"\n,\n\"Jolyn\"\n,\n\"Jolynn\"\n,\n\"Jon\"\n,\n\"Jona\"\n,\n\"Jonah\"\n,\n\"Jonas\"\n,\n\"Jonathan\"\n,\n\"Jonathon\"\n,\n\"Jonati\"\n,\n\"Jone\"\n,\n\"Jonell\"\n,\n\"Jones\"\n,\n\"Jonette\"\n,\n\"Joni\"\n,\n\"Jonie\"\n,\n\"Jonina\"\n,\n\"Jonis\"\n,\n\"Jonme\"\n,\n\"Jonna\"\n,\n\"Jonny\"\n,\n\"Joo\"\n,\n\"Joon\"\n,\n\"Joost\"\n,\n\"Jopa\"\n,\n\"Jordain\"\n,\n\"Jordan\"\n,\n\"Jordana\"\n,\n\"Jordanna\"\n,\n\"Jordans\"\n,\n\"Jordanson\"\n,\n\"Jordison\"\n,\n\"Jordon\"\n,\n\"Jorey\"\n,\n\"Jorgan\"\n,\n\"Jorge\"\n,\n\"Jorgensen\"\n,\n\"Jorgenson\"\n,\n\"Jori\"\n,\n\"Jorie\"\n,\n\"Jorin\"\n,\n\"Joris\"\n,\n\"Jorrie\"\n,\n\"Jorry\"\n,\n\"Jory\"\n,\n\"Jos\"\n,\n\"Joscelin\"\n,\n\"Jose\"\n,\n\"Josee\"\n,\n\"Josefa\"\n,\n\"Josefina\"\n,\n\"Joseito\"\n,\n\"Joselow\"\n,\n\"Joselyn\"\n,\n\"Joseph\"\n,\n\"Josepha\"\n,\n\"Josephina\"\n,\n\"Josephine\"\n,\n\"Josephson\"\n,\n\"Joses\"\n,\n\"Josey\"\n,\n\"Josh\"\n,\n\"Joshi\"\n,\n\"Joshia\"\n,\n\"Joshua\"\n,\n\"Joshuah\"\n,\n\"Josi\"\n,\n\"Josiah\"\n,\n\"Josias\"\n,\n\"Josie\"\n,\n\"Josler\"\n,\n\"Joslyn\"\n,\n\"Josselyn\"\n,\n\"Josy\"\n,\n\"Jotham\"\n,\n\"Joub\"\n,\n\"Joung\"\n,\n\"Jourdain\"\n,\n\"Jourdan\"\n,\n\"Jovi\"\n,\n\"Jovia\"\n,\n\"Jovita\"\n,\n\"Jovitah\"\n,\n\"Jovitta\"\n,\n\"Jowett\"\n,\n\"Joy\"\n,\n\"Joya\"\n,\n\"Joyan\"\n,\n\"Joyann\"\n,\n\"Joyce\"\n,\n\"Joycelin\"\n,\n\"Joye\"\n,\n\"Jozef\"\n,\n\"Jsandye\"\n,\n\"Juan\"\n,\n\"Juana\"\n,\n\"Juanita\"\n,\n\"Juanne\"\n,\n\"Juback\"\n,\n\"Jud\"\n,\n\"Judah\"\n,\n\"Judas\"\n,\n\"Judd\"\n,\n\"Jude\"\n,\n\"Judenberg\"\n,\n\"Judi\"\n,\n\"Judie\"\n,\n\"Judith\"\n,\n\"Juditha\"\n,\n\"Judon\"\n,\n\"Judsen\"\n,\n\"Judson\"\n,\n\"Judus\"\n,\n\"Judy\"\n,\n\"Judye\"\n,\n\"Jueta\"\n,\n\"Juetta\"\n,\n\"Juieta\"\n,\n\"Jule\"\n,\n\"Julee\"\n,\n\"Jules\"\n,\n\"Juley\"\n,\n\"Juli\"\n,\n\"Julia\"\n,\n\"Julian\"\n,\n\"Juliana\"\n,\n\"Juliane\"\n,\n\"Juliann\"\n,\n\"Julianna\"\n,\n\"Julianne\"\n,\n\"Juliano\"\n,\n\"Julide\"\n,\n\"Julie\"\n,\n\"Julienne\"\n,\n\"Juliet\"\n,\n\"Julieta\"\n,\n\"Julietta\"\n,\n\"Juliette\"\n,\n\"Julina\"\n,\n\"Juline\"\n,\n\"Julio\"\n,\n\"Julis\"\n,\n\"Julissa\"\n,\n\"Julita\"\n,\n\"Julius\"\n,\n\"Jumbala\"\n,\n\"Jump\"\n,\n\"Jun\"\n,\n\"Juna\"\n,\n\"June\"\n,\n\"Junette\"\n,\n\"Jung\"\n,\n\"Juni\"\n,\n\"Junia\"\n,\n\"Junie\"\n,\n\"Junieta\"\n,\n\"Junina\"\n,\n\"Junius\"\n,\n\"Junji\"\n,\n\"Junko\"\n,\n\"Junna\"\n,\n\"Junno\"\n,\n\"Juno\"\n,\n\"Jurdi\"\n,\n\"Jurgen\"\n,\n\"Jurkoic\"\n,\n\"Just\"\n,\n\"Justen\"\n,\n\"Juster\"\n,\n\"Justicz\"\n,\n\"Justin\"\n,\n\"Justina\"\n,\n\"Justine\"\n,\n\"Justinian\"\n,\n\"Justinn\"\n,\n\"Justino\"\n,\n\"Justis\"\n,\n\"Justus\"\n,\n\"Juta\"\n,\n\"Jutta\"\n,\n\"Juxon\"\n,\n\"Jyoti\"\n,\n\"Kablesh\"\n,\n\"Kacerek\"\n,\n\"Kacey\"\n,\n\"Kachine\"\n,\n\"Kacie\"\n,\n\"Kacy\"\n,\n\"Kaczer\"\n,\n\"Kaden\"\n,\n\"Kadner\"\n,\n\"Kado\"\n,\n\"Kaela\"\n,\n\"Kaenel\"\n,\n\"Kaete\"\n,\n\"Kafka\"\n,\n\"Kahaleel\"\n,\n\"Kahl\"\n,\n\"Kahle\"\n,\n\"Kahler\"\n,\n\"Kahlil\"\n,\n\"Kahn\"\n,\n\"Kai\"\n,\n\"Kaia\"\n,\n\"Kaila\"\n,\n\"Kaile\"\n,\n\"Kailey\"\n,\n\"Kain\"\n,\n\"Kaine\"\n,\n\"Kaiser\"\n,\n\"Kaitlin\"\n,\n\"Kaitlyn\"\n,\n\"Kaitlynn\"\n,\n\"Kaiulani\"\n,\n\"Kaja\"\n,\n\"Kajdan\"\n,\n\"Kakalina\"\n,\n\"Kal\"\n,\n\"Kala\"\n,\n\"Kalagher\"\n,\n\"Kalasky\"\n,\n\"Kalb\"\n,\n\"Kalbli\"\n,\n\"Kale\"\n,\n\"Kaleb\"\n,\n\"Kaleena\"\n,\n\"Kalfas\"\n,\n\"Kali\"\n,\n\"Kalie\"\n,\n\"Kalikow\"\n,\n\"Kalil\"\n,\n\"Kalila\"\n,\n\"Kalin\"\n,\n\"Kalina\"\n,\n\"Kalinda\"\n,\n\"Kalindi\"\n,\n\"Kaliope\"\n,\n\"Kaliski\"\n,\n\"Kalk\"\n,\n\"Kall\"\n,\n\"Kalle\"\n,\n\"Kalli\"\n,\n\"Kallick\"\n,\n\"Kallista\"\n,\n\"Kallman\"\n,\n\"Kally\"\n,\n\"Kalman\"\n,\n\"Kalmick\"\n,\n\"Kaltman\"\n,\n\"Kalvin\"\n,\n\"Kalvn\"\n,\n\"Kam\"\n,\n\"Kama\"\n,\n\"Kamal\"\n,\n\"Kamaria\"\n,\n\"Kamat\"\n,\n\"Kameko\"\n,\n\"Kamerman\"\n,\n\"Kamila\"\n,\n\"Kamilah\"\n,\n\"Kamillah\"\n,\n\"Kamin\"\n,\n\"Kammerer\"\n,\n\"Kamp\"\n,\n\"Kampmann\"\n,\n\"Kampmeier\"\n,\n\"Kan\"\n,\n\"Kanal\"\n,\n\"Kancler\"\n,\n\"Kandace\"\n,\n\"Kandy\"\n,\n\"Kane\"\n,\n\"Kania\"\n,\n\"Kannan\"\n,\n\"Kannry\"\n,\n\"Kano\"\n,\n\"Kant\"\n,\n\"Kanter\"\n,\n\"Kantor\"\n,\n\"Kantos\"\n,\n\"Kanya\"\n,\n\"Kape\"\n,\n\"Kaplan\"\n,\n\"Kapoor\"\n,\n\"Kapor\"\n,\n\"Kappel\"\n,\n\"Kappenne\"\n,\n\"Kara\"\n,\n\"Kara-Lynn\"\n,\n\"Karalee\"\n,\n\"Karalynn\"\n,\n\"Karame\"\n,\n\"Karas\"\n,\n\"Karb\"\n,\n\"Kare\"\n,\n\"Karee\"\n,\n\"Kareem\"\n,\n\"Karel\"\n,\n\"Karen\"\n,\n\"Karena\"\n,\n\"Kari\"\n,\n\"Karia\"\n,\n\"Karie\"\n,\n\"Karil\"\n,\n\"Karilla\"\n,\n\"Karilynn\"\n,\n\"Karim\"\n,\n\"Karin\"\n,\n\"Karina\"\n,\n\"Karine\"\n,\n\"Kariotta\"\n,\n\"Karisa\"\n,\n\"Karissa\"\n,\n\"Karita\"\n,\n\"Karl\"\n,\n\"Karla\"\n,\n\"Karlan\"\n,\n\"Karlee\"\n,\n\"Karleen\"\n,\n\"Karlen\"\n,\n\"Karlene\"\n,\n\"Karlens\"\n,\n\"Karli\"\n,\n\"Karlie\"\n,\n\"Karlik\"\n,\n\"Karlin\"\n,\n\"Karlis\"\n,\n\"Karlise\"\n,\n\"Karlotta\"\n,\n\"Karlotte\"\n,\n\"Karlow\"\n,\n\"Karly\"\n,\n\"Karlyn\"\n,\n\"Karmen\"\n,\n\"Karna\"\n,\n\"Karney\"\n,\n\"Karol\"\n,\n\"Karola\"\n,\n\"Karole\"\n,\n\"Karolina\"\n,\n\"Karoline\"\n,\n\"Karoly\"\n,\n\"Karolyn\"\n,\n\"Karon\"\n,\n\"Karp\"\n,\n\"Karr\"\n,\n\"Karrah\"\n,\n\"Karrie\"\n,\n\"Karry\"\n,\n\"Karsten\"\n,\n\"Kartis\"\n,\n\"Karwan\"\n,\n\"Kary\"\n,\n\"Karyl\"\n,\n\"Karylin\"\n,\n\"Karyn\"\n,\n\"Kasevich\"\n,\n\"Kasey\"\n,\n\"Kashden\"\n,\n\"Kask\"\n,\n\"Kaslik\"\n,\n\"Kaspar\"\n,\n\"Kasper\"\n,\n\"Kass\"\n,\n\"Kassab\"\n,\n\"Kassandra\"\n,\n\"Kassaraba\"\n,\n\"Kassel\"\n,\n\"Kassey\"\n,\n\"Kassi\"\n,\n\"Kassia\"\n,\n\"Kassie\"\n,\n\"Kassity\"\n,\n\"Kast\"\n,\n\"Kat\"\n,\n\"Kata\"\n,\n\"Katalin\"\n,\n\"Kataway\"\n,\n\"Kate\"\n,\n\"Katee\"\n,\n\"Katerina\"\n,\n\"Katerine\"\n,\n\"Katey\"\n,\n\"Kath\"\n,\n\"Katha\"\n,\n\"Katharina\"\n,\n\"Katharine\"\n,\n\"Katharyn\"\n,\n\"Kathe\"\n,\n\"Katherin\"\n,\n\"Katherina\"\n,\n\"Katherine\"\n,\n\"Katheryn\"\n,\n\"Kathi\"\n,\n\"Kathie\"\n,\n\"Kathleen\"\n,\n\"Kathlene\"\n,\n\"Kathlin\"\n,\n\"Kathrine\"\n,\n\"Kathryn\"\n,\n\"Kathryne\"\n,\n\"Kathy\"\n,\n\"Kathye\"\n,\n\"Kati\"\n,\n\"Katie\"\n,\n\"Katina\"\n,\n\"Katine\"\n,\n\"Katinka\"\n,\n\"Katlaps\"\n,\n\"Katleen\"\n,\n\"Katlin\"\n,\n\"Kato\"\n,\n\"Katonah\"\n,\n\"Katrina\"\n,\n\"Katrine\"\n,\n\"Katrinka\"\n,\n\"Katsuyama\"\n,\n\"Katt\"\n,\n\"Katti\"\n,\n\"Kattie\"\n,\n\"Katuscha\"\n,\n\"Katusha\"\n,\n\"Katushka\"\n,\n\"Katy\"\n,\n\"Katya\"\n,\n\"Katz\"\n,\n\"Katzen\"\n,\n\"Katzir\"\n,\n\"Katzman\"\n,\n\"Kauffman\"\n,\n\"Kauffmann\"\n,\n\"Kaufman\"\n,\n\"Kaufmann\"\n,\n\"Kaule\"\n,\n\"Kauppi\"\n,\n\"Kauslick\"\n,\n\"Kavanagh\"\n,\n\"Kavanaugh\"\n,\n\"Kavita\"\n,\n\"Kawai\"\n,\n\"Kawasaki\"\n,\n\"Kay\"\n,\n\"Kaya\"\n,\n\"Kaycee\"\n,\n\"Kaye\"\n,\n\"Kayla\"\n,\n\"Kayle\"\n,\n\"Kaylee\"\n,\n\"Kayley\"\n,\n\"Kaylil\"\n,\n\"Kaylyn\"\n,\n\"Kayne\"\n,\n\"Kaz\"\n,\n\"Kazim\"\n,\n\"Kazimir\"\n,\n\"Kazmirci\"\n,\n\"Kazue\"\n,\n\"Kealey\"\n,\n\"Kean\"\n,\n\"Keane\"\n,\n\"Keare\"\n,\n\"Kearney\"\n,\n\"Keary\"\n,\n\"Keating\"\n,\n\"Keavy\"\n,\n\"Kee\"\n,\n\"Keefe\"\n,\n\"Keefer\"\n,\n\"Keegan\"\n,\n\"Keel\"\n,\n\"Keelby\"\n,\n\"Keele\"\n,\n\"Keeler\"\n,\n\"Keeley\"\n,\n\"Keelia\"\n,\n\"Keelin\"\n,\n\"Keely\"\n,\n\"Keen\"\n,\n\"Keenan\"\n,\n\"Keene\"\n,\n\"Keener\"\n,\n\"Keese\"\n,\n\"Keeton\"\n,\n\"Keever\"\n,\n\"Keffer\"\n,\n\"Keg\"\n,\n\"Kegan\"\n,\n\"Keheley\"\n,\n\"Kehoe\"\n,\n\"Kehr\"\n,\n\"Kei\"\n,\n\"Keifer\"\n,\n\"Keiko\"\n,\n\"Keil\"\n,\n\"Keily\"\n,\n\"Keir\"\n,\n\"Keisling\"\n,\n\"Keith\"\n,\n\"Keithley\"\n,\n\"Kela\"\n,\n\"Kelbee\"\n,\n\"Kelby\"\n,\n\"Kelcey\"\n,\n\"Kelci\"\n,\n\"Kelcie\"\n,\n\"Kelcy\"\n,\n\"Kelda\"\n,\n\"Keldah\"\n,\n\"Keldon\"\n,\n\"Kele\"\n,\n\"Keli\"\n,\n\"Keligot\"\n,\n\"Kelila\"\n,\n\"Kella\"\n,\n\"Kellby\"\n,\n\"Kellda\"\n,\n\"Kelleher\"\n,\n\"Kellen\"\n,\n\"Kellene\"\n,\n\"Keller\"\n,\n\"Kelley\"\n,\n\"Kelli\"\n,\n\"Kellia\"\n,\n\"Kellie\"\n,\n\"Kellina\"\n,\n\"Kellsie\"\n,\n\"Kelly\"\n,\n\"Kellyann\"\n,\n\"Kellyn\"\n,\n\"Kelsey\"\n,\n\"Kelsi\"\n,\n\"Kelson\"\n,\n\"Kelsy\"\n,\n\"Kelton\"\n,\n\"Kelula\"\n,\n\"Kelvin\"\n,\n\"Kelwen\"\n,\n\"Kelwin\"\n,\n\"Kelwunn\"\n,\n\"Kemble\"\n,\n\"Kemeny\"\n,\n\"Kemme\"\n,\n\"Kemp\"\n,\n\"Kempe\"\n,\n\"Kemppe\"\n,\n\"Ken\"\n,\n\"Kenay\"\n,\n\"Kenaz\"\n,\n\"Kendal\"\n,\n\"Kendall\"\n,\n\"Kendell\"\n,\n\"Kendra\"\n,\n\"Kendrah\"\n,\n\"Kendre\"\n,\n\"Kendrick\"\n,\n\"Kendricks\"\n,\n\"Kendry\"\n,\n\"Kendy\"\n,\n\"Kendyl\"\n,\n\"Kenelm\"\n,\n\"Kenison\"\n,\n\"Kenji\"\n,\n\"Kenlay\"\n,\n\"Kenlee\"\n,\n\"Kenleigh\"\n,\n\"Kenley\"\n,\n\"Kenn\"\n,\n\"Kenna\"\n,\n\"Kennan\"\n,\n\"Kennard\"\n,\n\"Kennedy\"\n,\n\"Kennet\"\n,\n\"Kenneth\"\n,\n\"Kennett\"\n,\n\"Kenney\"\n,\n\"Kennie\"\n,\n\"Kennith\"\n,\n\"Kenny\"\n,\n\"Kenon\"\n,\n\"Kenric\"\n,\n\"Kenrick\"\n,\n\"Kensell\"\n,\n\"Kent\"\n,\n\"Kenta\"\n,\n\"Kenti\"\n,\n\"Kentiga\"\n,\n\"Kentigera\"\n,\n\"Kentigerma\"\n,\n\"Kentiggerma\"\n,\n\"Kenton\"\n,\n\"Kenward\"\n,\n\"Kenway\"\n,\n\"Kenwee\"\n,\n\"Kenweigh\"\n,\n\"Kenwood\"\n,\n\"Kenwrick\"\n,\n\"Kenyon\"\n,\n\"Kenzi\"\n,\n\"Kenzie\"\n,\n\"Keon\"\n,\n\"Kepner\"\n,\n\"Keppel\"\n,\n\"Ker\"\n,\n\"Kerby\"\n,\n\"Kerek\"\n,\n\"Kerekes\"\n,\n\"Kerge\"\n,\n\"Keri\"\n,\n\"Keriann\"\n,\n\"Kerianne\"\n,\n\"Kerin\"\n,\n\"Kerk\"\n,\n\"Kerman\"\n,\n\"Kermie\"\n,\n\"Kermit\"\n,\n\"Kermy\"\n,\n\"Kern\"\n,\n\"Kernan\"\n,\n\"Kerns\"\n,\n\"Kerr\"\n,\n\"Kerri\"\n,\n\"Kerrie\"\n,\n\"Kerril\"\n,\n\"Kerrill\"\n,\n\"Kerrin\"\n,\n\"Kerrison\"\n,\n\"Kerry\"\n,\n\"Kersten\"\n,\n\"Kerstin\"\n,\n\"Kerwin\"\n,\n\"Kerwinn\"\n,\n\"Kerwon\"\n,\n\"Kery\"\n,\n\"Kesia\"\n,\n\"Kesley\"\n,\n\"Keslie\"\n,\n\"Kessel\"\n,\n\"Kessia\"\n,\n\"Kessiah\"\n,\n\"Kessler\"\n,\n\"Kester\"\n,\n\"Ketchan\"\n,\n\"Ketchum\"\n,\n\"Ketti\"\n,\n\"Kettie\"\n,\n\"Ketty\"\n,\n\"Keung\"\n,\n\"Kev\"\n,\n\"Kevan\"\n,\n\"Keven\"\n,\n\"Keverian\"\n,\n\"Keverne\"\n,\n\"Kevin\"\n,\n\"Kevina\"\n,\n\"Kevon\"\n,\n\"Kevyn\"\n,\n\"Key\"\n,\n\"Keyek\"\n,\n\"Keyes\"\n,\n\"Keynes\"\n,\n\"Keyser\"\n,\n\"Keyte\"\n,\n\"Kezer\"\n,\n\"Khai\"\n,\n\"Khajeh\"\n,\n\"Khalid\"\n,\n\"Khalil\"\n,\n\"Khalin\"\n,\n\"Khalsa\"\n,\n\"Khan\"\n,\n\"Khanna\"\n,\n\"Khano\"\n,\n\"Khichabia\"\n,\n\"Kho\"\n,\n\"Khorma\"\n,\n\"Khosrow\"\n,\n\"Khoury\"\n,\n\"Khudari\"\n,\n\"Ki\"\n,\n\"Kiah\"\n,\n\"Kial\"\n,\n\"Kidd\"\n,\n\"Kidder\"\n,\n\"Kiefer\"\n,\n\"Kieffer\"\n,\n\"Kieger\"\n,\n\"Kiehl\"\n,\n\"Kiel\"\n,\n\"Kiele\"\n,\n\"Kielty\"\n,\n\"Kienan\"\n,\n\"Kier\"\n,\n\"Kieran\"\n,\n\"Kiernan\"\n,\n\"Kiersten\"\n,\n\"Kikelia\"\n,\n\"Kiker\"\n,\n\"Kiki\"\n,\n\"Kila\"\n,\n\"Kilah\"\n,\n\"Kilan\"\n,\n\"Kilar\"\n,\n\"Kilbride\"\n,\n\"Kilby\"\n,\n\"Kile\"\n,\n\"Kiley\"\n,\n\"Kilgore\"\n,\n\"Kilian\"\n,\n\"Kilk\"\n,\n\"Killam\"\n,\n\"Killarney\"\n,\n\"Killen\"\n,\n\"Killian\"\n,\n\"Killie\"\n,\n\"Killigrew\"\n,\n\"Killion\"\n,\n\"Killoran\"\n,\n\"Killy\"\n,\n\"Kilmarx\"\n,\n\"Kilroy\"\n,\n\"Kim\"\n,\n\"Kimball\"\n,\n\"Kimbell\"\n,\n\"Kimber\"\n,\n\"Kimberlee\"\n,\n\"Kimberley\"\n,\n\"Kimberli\"\n,\n\"Kimberly\"\n,\n\"Kimberlyn\"\n,\n\"Kimble\"\n,\n\"Kimbra\"\n,\n\"Kimitri\"\n,\n\"Kimmel\"\n,\n\"Kimmi\"\n,\n\"Kimmie\"\n,\n\"Kimmy\"\n,\n\"Kimon\"\n,\n\"Kimura\"\n,\n\"Kin\"\n,\n\"Kinata\"\n,\n\"Kincaid\"\n,\n\"Kinch\"\n,\n\"Kinchen\"\n,\n\"Kind\"\n,\n\"Kindig\"\n,\n\"Kinelski\"\n,\n\"King\"\n,\n\"Kingdon\"\n,\n\"Kinghorn\"\n,\n\"Kingsbury\"\n,\n\"Kingsley\"\n,\n\"Kingsly\"\n,\n\"Kingston\"\n,\n\"Kinna\"\n,\n\"Kinnard\"\n,\n\"Kinney\"\n,\n\"Kinnie\"\n,\n\"Kinnon\"\n,\n\"Kinny\"\n,\n\"Kinsler\"\n,\n\"Kinsley\"\n,\n\"Kinsman\"\n,\n\"Kinson\"\n,\n\"Kinzer\"\n,\n\"Kiona\"\n,\n\"Kip\"\n,\n\"Kipp\"\n,\n\"Kippar\"\n,\n\"Kipper\"\n,\n\"Kippie\"\n,\n\"Kippy\"\n,\n\"Kipton\"\n,\n\"Kira\"\n,\n\"Kiran\"\n,\n\"Kirbee\"\n,\n\"Kirbie\"\n,\n\"Kirby\"\n,\n\"Kirch\"\n,\n\"Kirchner\"\n,\n\"Kiri\"\n,\n\"Kirima\"\n,\n\"Kirimia\"\n,\n\"Kirit\"\n,\n\"Kirk\"\n,\n\"Kirkpatrick\"\n,\n\"Kirkwood\"\n,\n\"Kironde\"\n,\n\"Kirsch\"\n,\n\"Kirschner\"\n,\n\"Kirshbaum\"\n,\n\"Kirst\"\n,\n\"Kirsten\"\n,\n\"Kirsteni\"\n,\n\"Kirsti\"\n,\n\"Kirstin\"\n,\n\"Kirstyn\"\n,\n\"Kirt\"\n,\n\"Kirtley\"\n,\n\"Kirven\"\n,\n\"Kirwin\"\n,\n\"Kisor\"\n,\n\"Kissee\"\n,\n\"Kissel\"\n,\n\"Kissiah\"\n,\n\"Kissie\"\n,\n\"Kissner\"\n,\n\"Kistner\"\n,\n\"Kisung\"\n,\n\"Kit\"\n,\n\"Kitchen\"\n,\n\"Kitti\"\n,\n\"Kittie\"\n,\n\"Kitty\"\n,\n\"Kiyohara\"\n,\n\"Kiyoshi\"\n,\n\"Kizzee\"\n,\n\"Kizzie\"\n,\n\"Kjersti\"\n,\n\"Klapp\"\n,\n\"Klara\"\n,\n\"Klarika\"\n,\n\"Klarrisa\"\n,\n\"Klatt\"\n,\n\"Klaus\"\n,\n\"Klayman\"\n,\n\"Klecka\"\n,\n\"Kleeman\"\n,\n\"Klehm\"\n,\n\"Kleiman\"\n,\n\"Klein\"\n,\n\"Kleinstein\"\n,\n\"Klemens\"\n,\n\"Klement\"\n,\n\"Klemm\"\n,\n\"Klemperer\"\n,\n\"Klenk\"\n,\n\"Kleon\"\n,\n\"Klepac\"\n,\n\"Kleper\"\n,\n\"Kletter\"\n,\n\"Kliber\"\n,\n\"Kliman\"\n,\n\"Kliment\"\n,\n\"Klimesh\"\n,\n\"Klina\"\n,\n\"Kline\"\n,\n\"Kling\"\n,\n\"Klingel\"\n,\n\"Klinger\"\n,\n\"Klinges\"\n,\n\"Klockau\"\n,\n\"Kloman\"\n,\n\"Klos\"\n,\n\"Kloster\"\n,\n\"Klotz\"\n,\n\"Klug\"\n,\n\"Kluge\"\n,\n\"Klump\"\n,\n\"Klusek\"\n,\n\"Klute\"\n,\n\"Knapp\"\n,\n\"Kneeland\"\n,\n\"Knepper\"\n,\n\"Knick\"\n,\n\"Knight\"\n,\n\"Knighton\"\n,\n\"Knipe\"\n,\n\"Knitter\"\n,\n\"Knobloch\"\n,\n\"Knoll\"\n,\n\"Knorring\"\n,\n\"Knowland\"\n,\n\"Knowle\"\n,\n\"Knowles\"\n,\n\"Knowling\"\n,\n\"Knowlton\"\n,\n\"Knox\"\n,\n\"Knudson\"\n,\n\"Knut\"\n,\n\"Knute\"\n,\n\"Knuth\"\n,\n\"Knutson\"\n,\n\"Ko\"\n,\n\"Koa\"\n,\n\"Koah\"\n,\n\"Koal\"\n,\n\"Koball\"\n,\n\"Kobe\"\n,\n\"Kobi\"\n,\n\"Koblas\"\n,\n\"Koblick\"\n,\n\"Koby\"\n,\n\"Kobylak\"\n,\n\"Koch\"\n,\n\"Koehler\"\n,\n\"Koenig\"\n,\n\"Koeninger\"\n,\n\"Koenraad\"\n,\n\"Koeppel\"\n,\n\"Koerlin\"\n,\n\"Koerner\"\n,\n\"Koetke\"\n,\n\"Koffler\"\n,\n\"Koffman\"\n,\n\"Koh\"\n,\n\"Kohl\"\n,\n\"Kohler\"\n,\n\"Kohn\"\n,\n\"Kokaras\"\n,\n\"Kokoruda\"\n,\n\"Kolb\"\n,\n\"Kolivas\"\n,\n\"Kolk\"\n,\n\"Koller\"\n,\n\"Kolnick\"\n,\n\"Kolnos\"\n,\n\"Kolodgie\"\n,\n\"Kolosick\"\n,\n\"Koloski\"\n,\n\"Kolva\"\n,\n\"Komara\"\n,\n\"Komarek\"\n,\n\"Komsa\"\n,\n\"Kondon\"\n,\n\"Kone\"\n,\n\"Kong\"\n,\n\"Konikow\"\n,\n\"Kono\"\n,\n\"Konopka\"\n,\n\"Konrad\"\n,\n\"Konstance\"\n,\n\"Konstantin\"\n,\n\"Konstantine\"\n,\n\"Konstanze\"\n,\n\"Konyn\"\n,\n\"Koo\"\n,\n\"Kooima\"\n,\n\"Koosis\"\n,\n\"Kopans\"\n,\n\"Kopaz\"\n,\n\"Kopp\"\n,\n\"Koppel\"\n,\n\"Kopple\"\n,\n\"Kora\"\n,\n\"Koral\"\n,\n\"Koralie\"\n,\n\"Koralle\"\n,\n\"Koran\"\n,\n\"Kordula\"\n,\n\"Kore\"\n,\n\"Korella\"\n,\n\"Koren\"\n,\n\"Korenblat\"\n,\n\"Koressa\"\n,\n\"Korey\"\n,\n\"Korff\"\n,\n\"Korfonta\"\n,\n\"Kori\"\n,\n\"Korie\"\n,\n\"Korman\"\n,\n\"Korney\"\n,\n\"Kornher\"\n,\n\"Korns\"\n,\n\"Korrie\"\n,\n\"Korry\"\n,\n\"Kort\"\n,\n\"Korten\"\n,\n\"Korwin\"\n,\n\"Korwun\"\n,\n\"Kory\"\n,\n\"Kosak\"\n,\n\"Kosaka\"\n,\n\"Kosel\"\n,\n\"Koser\"\n,\n\"Kosey\"\n,\n\"Kosiur\"\n,\n\"Koslo\"\n,\n\"Koss\"\n,\n\"Kosse\"\n,\n\"Kostival\"\n,\n\"Kostman\"\n,\n\"Kotick\"\n,\n\"Kotta\"\n,\n\"Kotto\"\n,\n\"Kotz\"\n,\n\"Kovacev\"\n,\n\"Kovacs\"\n,\n\"Koval\"\n,\n\"Kovar\"\n,\n\"Kowal\"\n,\n\"Kowalski\"\n,\n\"Kowatch\"\n,\n\"Kowtko\"\n,\n\"Koy\"\n,\n\"Koziara\"\n,\n\"Koziarz\"\n,\n\"Koziel\"\n,\n\"Kozloski\"\n,\n\"Kraft\"\n,\n\"Kragh\"\n,\n\"Krahling\"\n,\n\"Krahmer\"\n,\n\"Krakow\"\n,\n\"Krall\"\n,\n\"Kramer\"\n,\n\"Kramlich\"\n,\n\"Krantz\"\n,\n\"Kraska\"\n,\n\"Krasner\"\n,\n\"Krasnoff\"\n,\n\"Kraul\"\n,\n\"Kraus\"\n,\n\"Krause\"\n,\n\"Krauss\"\n,\n\"Kravits\"\n,\n\"Krawczyk\"\n,\n\"Kreager\"\n,\n\"Krebs\"\n,\n\"Kreda\"\n,\n\"Kreegar\"\n,\n\"Krefetz\"\n,\n\"Kreg\"\n,\n\"Kreiker\"\n,\n\"Krein\"\n,\n\"Kreindler\"\n,\n\"Kreiner\"\n,\n\"Kreis\"\n,\n\"Kreit\"\n,\n\"Kreitman\"\n,\n\"Krell\"\n,\n\"Kremer\"\n,\n\"Krenek\"\n,\n\"Krenn\"\n,\n\"Kresic\"\n,\n\"Kress\"\n,\n\"Krever\"\n,\n\"Kries\"\n,\n\"Krigsman\"\n,\n\"Krilov\"\n,\n\"Kris\"\n,\n\"Krischer\"\n,\n\"Krisha\"\n,\n\"Krishna\"\n,\n\"Krishnah\"\n,\n\"Krispin\"\n,\n\"Kriss\"\n,\n\"Krissie\"\n,\n\"Krissy\"\n,\n\"Krista\"\n,\n\"Kristal\"\n,\n\"Kristan\"\n,\n\"Kriste\"\n,\n\"Kristel\"\n,\n\"Kristen\"\n,\n\"Kristi\"\n,\n\"Kristian\"\n,\n\"Kristianson\"\n,\n\"Kristie\"\n,\n\"Kristien\"\n,\n\"Kristin\"\n,\n\"Kristina\"\n,\n\"Kristine\"\n,\n\"Kristo\"\n,\n\"Kristof\"\n,\n\"Kristofer\"\n,\n\"Kristoffer\"\n,\n\"Kristofor\"\n,\n\"Kristoforo\"\n,\n\"Kristopher\"\n,\n\"Kristos\"\n,\n\"Kristy\"\n,\n\"Kristyn\"\n,\n\"Krock\"\n,\n\"Kroll\"\n,\n\"Kronfeld\"\n,\n\"Krongold\"\n,\n\"Kronick\"\n,\n\"Kroo\"\n,\n\"Krucik\"\n,\n\"Krueger\"\n,\n\"Krug\"\n,\n\"Kruger\"\n,\n\"Krum\"\n,\n\"Krusche\"\n,\n\"Kruse\"\n,\n\"Krute\"\n,\n\"Kruter\"\n,\n\"Krutz\"\n,\n\"Krys\"\n,\n\"Kryska\"\n,\n\"Krysta\"\n,\n\"Krystal\"\n,\n\"Krystalle\"\n,\n\"Krystin\"\n,\n\"Krystle\"\n,\n\"Krystyna\"\n,\n\"Ku\"\n,\n\"Kubetz\"\n,\n\"Kubiak\"\n,\n\"Kubis\"\n,\n\"Kucik\"\n,\n\"Kudva\"\n,\n\"Kuebbing\"\n,\n\"Kuehn\"\n,\n\"Kuehnel\"\n,\n\"Kuhlman\"\n,\n\"Kuhn\"\n,\n\"Kulda\"\n,\n\"Kulseth\"\n,\n\"Kulsrud\"\n,\n\"Kumagai\"\n,\n\"Kumar\"\n,\n\"Kumler\"\n,\n\"Kung\"\n,\n\"Kunin\"\n,\n\"Kunkle\"\n,\n\"Kunz\"\n,\n\"Kuo\"\n,\n\"Kurland\"\n,\n\"Kurman\"\n,\n\"Kurr\"\n,\n\"Kursh\"\n,\n\"Kurt\"\n,\n\"Kurth\"\n,\n\"Kurtis\"\n,\n\"Kurtz\"\n,\n\"Kurtzig\"\n,\n\"Kurtzman\"\n,\n\"Kurys\"\n,\n\"Kurzawa\"\n,\n\"Kus\"\n,\n\"Kushner\"\n,\n\"Kusin\"\n,\n\"Kuska\"\n,\n\"Kussell\"\n,\n\"Kuster\"\n,\n\"Kutchins\"\n,\n\"Kuth\"\n,\n\"Kutzenco\"\n,\n\"Kutzer\"\n,\n\"Kwabena\"\n,\n\"Kwan\"\n,\n\"Kwang\"\n,\n\"Kwapong\"\n,\n\"Kwarteng\"\n,\n\"Kwasi\"\n,\n\"Kwei\"\n,\n\"Kwok\"\n,\n\"Kwon\"\n,\n\"Ky\"\n,\n\"Kyd\"\n,\n\"Kyl\"\n,\n\"Kyla\"\n,\n\"Kylah\"\n,\n\"Kylander\"\n,\n\"Kyle\"\n,\n\"Kylen\"\n,\n\"Kylie\"\n,\n\"Kylila\"\n,\n\"Kylstra\"\n,\n\"Kylynn\"\n,\n\"Kym\"\n,\n\"Kynan\"\n,\n\"Kyne\"\n,\n\"Kynthia\"\n,\n\"Kyriako\"\n,\n\"Kyrstin\"\n,\n\"Kyte\"\n,\n\"La\"\n,\n\"La Verne\"\n,\n\"LaBaw\"\n,\n\"LaMee\"\n,\n\"LaMonica\"\n,\n\"LaMori\"\n,\n\"LaRue\"\n,\n\"LaSorella\"\n,\n\"Laaspere\"\n,\n\"Laban\"\n,\n\"Labana\"\n,\n\"Laband\"\n,\n\"Labanna\"\n,\n\"Labannah\"\n,\n\"Labors\"\n,\n\"Lacagnia\"\n,\n\"Lacee\"\n,\n\"Lacefield\"\n,\n\"Lacey\"\n,\n\"Lach\"\n,\n\"Lachance\"\n,\n\"Lachish\"\n,\n\"Lachlan\"\n,\n\"Lachman\"\n,\n\"Lachus\"\n,\n\"Lacie\"\n,\n\"Lacombe\"\n,\n\"Lacy\"\n,\n\"Lad\"\n,\n\"Ladd\"\n,\n\"Laddie\"\n,\n\"Laddy\"\n,\n\"Laden\"\n,\n\"Ladew\"\n,\n\"Ladonna\"\n,\n\"Lady\"\n,\n\"Lael\"\n,\n\"Laetitia\"\n,\n\"Laflam\"\n,\n\"Lafleur\"\n,\n\"Laforge\"\n,\n\"Lagas\"\n,\n\"Lagasse\"\n,\n\"Lahey\"\n,\n\"Lai\"\n,\n\"Laidlaw\"\n,\n\"Lail\"\n,\n\"Laina\"\n,\n\"Laine\"\n,\n\"Lainey\"\n,\n\"Laing\"\n,\n\"Laird\"\n,\n\"Lais\"\n,\n\"Laise\"\n,\n\"Lait\"\n,\n\"Laith\"\n,\n\"Laius\"\n,\n\"Lakin\"\n,\n\"Laks\"\n,\n\"Laktasic\"\n,\n\"Lal\"\n,\n\"Lala\"\n,\n\"Lalage\"\n,\n\"Lali\"\n,\n\"Lalise\"\n,\n\"Lalita\"\n,\n\"Lalitta\"\n,\n\"Lalittah\"\n,\n\"Lalla\"\n,\n\"Lallage\"\n,\n\"Lally\"\n,\n\"Lalo\"\n,\n\"Lam\"\n,\n\"Lamar\"\n,\n\"Lamarre\"\n,\n\"Lamb\"\n,\n\"Lambard\"\n,\n\"Lambart\"\n,\n\"Lambert\"\n,\n\"Lamberto\"\n,\n\"Lambertson\"\n,\n\"Lambrecht\"\n,\n\"Lamdin\"\n,\n\"Lammond\"\n,\n\"Lamond\"\n,\n\"Lamont\"\n,\n\"Lamoree\"\n,\n\"Lamoureux\"\n,\n\"Lamp\"\n,\n\"Lampert\"\n,\n\"Lamphere\"\n,\n\"Lamprey\"\n,\n\"Lamrert\"\n,\n\"Lamrouex\"\n,\n\"Lamson\"\n,\n\"Lan\"\n,\n\"Lana\"\n,\n\"Lanae\"\n,\n\"Lanam\"\n,\n\"Lananna\"\n,\n\"Lancaster\"\n,\n\"Lance\"\n,\n\"Lancelle\"\n,\n\"Lancelot\"\n,\n\"Lancey\"\n,\n\"Lanctot\"\n,\n\"Land\"\n,\n\"Landa\"\n,\n\"Landahl\"\n,\n\"Landan\"\n,\n\"Landau\"\n,\n\"Landbert\"\n,\n\"Landel\"\n,\n\"Lander\"\n,\n\"Landers\"\n,\n\"Landes\"\n,\n\"Landing\"\n,\n\"Landis\"\n,\n\"Landmeier\"\n,\n\"Landon\"\n,\n\"Landre\"\n,\n\"Landri\"\n,\n\"Landrum\"\n,\n\"Landry\"\n,\n\"Landsman\"\n,\n\"Landy\"\n,\n\"Lane\"\n,\n\"Lanette\"\n,\n\"Laney\"\n,\n\"Lanford\"\n,\n\"Lanfri\"\n,\n\"Lang\"\n,\n\"Langan\"\n,\n\"Langbehn\"\n,\n\"Langdon\"\n,\n\"Lange\"\n,\n\"Langelo\"\n,\n\"Langer\"\n,\n\"Langham\"\n,\n\"Langill\"\n,\n\"Langille\"\n,\n\"Langley\"\n,\n\"Langsdon\"\n,\n\"Langston\"\n,\n\"Lani\"\n,\n\"Lanie\"\n,\n\"Lanita\"\n,\n\"Lankton\"\n,\n\"Lanna\"\n,\n\"Lanni\"\n,\n\"Lannie\"\n,\n\"Lanny\"\n,\n\"Lansing\"\n,\n\"Lanta\"\n,\n\"Lantha\"\n,\n\"Lanti\"\n,\n\"Lantz\"\n,\n\"Lanza\"\n,\n\"Lapham\"\n,\n\"Lapides\"\n,\n\"Lapointe\"\n,\n\"Lapotin\"\n,\n\"Lara\"\n,\n\"Laraine\"\n,\n\"Larcher\"\n,\n\"Lardner\"\n,\n\"Lareena\"\n,\n\"Lareine\"\n,\n\"Larena\"\n,\n\"Larentia\"\n,\n\"Laresa\"\n,\n\"Largent\"\n,\n\"Lari\"\n,\n\"Larianna\"\n,\n\"Larimer\"\n,\n\"Larimor\"\n,\n\"Larimore\"\n,\n\"Larina\"\n,\n\"Larine\"\n,\n\"Laris\"\n,\n\"Larisa\"\n,\n\"Larissa\"\n,\n\"Lark\"\n,\n\"Larkin\"\n,\n\"Larkins\"\n,\n\"Larner\"\n,\n\"Larochelle\"\n,\n\"Laroy\"\n,\n\"Larrabee\"\n,\n\"Larrie\"\n,\n\"Larrisa\"\n,\n\"Larry\"\n,\n\"Lars\"\n,\n\"Larsen\"\n,\n\"Larson\"\n,\n\"Laryssa\"\n,\n\"Lasala\"\n,\n\"Lash\"\n,\n\"Lashar\"\n,\n\"Lashoh\"\n,\n\"Lashond\"\n,\n\"Lashonda\"\n,\n\"Lashonde\"\n,\n\"Lashondra\"\n,\n\"Lasko\"\n,\n\"Lasky\"\n,\n\"Lasley\"\n,\n\"Lasonde\"\n,\n\"Laspisa\"\n,\n\"Lasser\"\n,\n\"Lassiter\"\n,\n\"Laszlo\"\n,\n\"Lat\"\n,\n\"Latashia\"\n,\n\"Latea\"\n,\n\"Latham\"\n,\n\"Lathan\"\n,\n\"Lathe\"\n,\n\"Lathrop\"\n,\n\"Lathrope\"\n,\n\"Lati\"\n,\n\"Latia\"\n,\n\"Latif\"\n,\n\"Latimer\"\n,\n\"Latimore\"\n,\n\"Latin\"\n,\n\"Latini\"\n,\n\"Latisha\"\n,\n\"Latona\"\n,\n\"Latonia\"\n,\n\"Latoniah\"\n,\n\"Latouche\"\n,\n\"Latoya\"\n,\n\"Latoye\"\n,\n\"Latoyia\"\n,\n\"Latreece\"\n,\n\"Latreese\"\n,\n\"Latrell\"\n,\n\"Latrena\"\n,\n\"Latreshia\"\n,\n\"Latrice\"\n,\n\"Latricia\"\n,\n\"Latrina\"\n,\n\"Latt\"\n,\n\"Latta\"\n,\n\"Latterll\"\n,\n\"Lattie\"\n,\n\"Lattimer\"\n,\n\"Latton\"\n,\n\"Lattonia\"\n,\n\"Latty\"\n,\n\"Latvina\"\n,\n\"Lau\"\n,\n\"Lauber\"\n,\n\"Laubin\"\n,\n\"Laud\"\n,\n\"Lauder\"\n,\n\"Lauer\"\n,\n\"Laufer\"\n,\n\"Laughlin\"\n,\n\"Laughry\"\n,\n\"Laughton\"\n,\n\"Launce\"\n,\n\"Launcelot\"\n,\n\"Laundes\"\n,\n\"Laura\"\n,\n\"Lauraine\"\n,\n\"Laural\"\n,\n\"Lauralee\"\n,\n\"Laurance\"\n,\n\"Laure\"\n,\n\"Lauree\"\n,\n\"Laureen\"\n,\n\"Laurel\"\n,\n\"Laurella\"\n,\n\"Lauren\"\n,\n\"Laurena\"\n,\n\"Laurence\"\n,\n\"Laurene\"\n,\n\"Laurens\"\n,\n\"Laurent\"\n,\n\"Laurentia\"\n,\n\"Laurentium\"\n,\n\"Lauretta\"\n,\n\"Laurette\"\n,\n\"Lauri\"\n,\n\"Laurianne\"\n,\n\"Laurice\"\n,\n\"Laurie\"\n,\n\"Laurin\"\n,\n\"Laurinda\"\n,\n\"Laurita\"\n,\n\"Lauritz\"\n,\n\"Lauro\"\n,\n\"Lauryn\"\n,\n\"Lauter\"\n,\n\"Laux\"\n,\n\"Lauzon\"\n,\n\"Laval\"\n,\n\"Laveen\"\n,\n\"Lavella\"\n,\n\"Lavelle\"\n,\n\"Laven\"\n,\n\"Lavena\"\n,\n\"Lavern\"\n,\n\"Laverna\"\n,\n\"Laverne\"\n,\n\"Lavery\"\n,\n\"Lavina\"\n,\n\"Lavine\"\n,\n\"Lavinia\"\n,\n\"Lavinie\"\n,\n\"Lavoie\"\n,\n\"Lavona\"\n,\n\"Law\"\n,\n\"Lawford\"\n,\n\"Lawler\"\n,\n\"Lawley\"\n,\n\"Lawlor\"\n,\n\"Lawrence\"\n,\n\"Lawrenson\"\n,\n\"Lawry\"\n,\n\"Laws\"\n,\n\"Lawson\"\n,\n\"Lawton\"\n,\n\"Lawtun\"\n,\n\"Lay\"\n,\n\"Layla\"\n,\n\"Layman\"\n,\n\"Layne\"\n,\n\"Layney\"\n,\n\"Layton\"\n,\n\"Lazar\"\n,\n\"Lazare\"\n,\n\"Lazaro\"\n,\n\"Lazaruk\"\n,\n\"Lazarus\"\n,\n\"Lazes\"\n,\n\"Lazor\"\n,\n\"Lazos\"\n,\n\"Le\"\n,\n\"LeCroy\"\n,\n\"LeDoux\"\n,\n\"LeMay\"\n,\n\"LeRoy\"\n,\n\"LeVitus\"\n,\n\"Lea\"\n,\n\"Leach\"\n,\n\"Leacock\"\n,\n\"Leah\"\n,\n\"Leahey\"\n,\n\"Leake\"\n,\n\"Leal\"\n,\n\"Lean\"\n,\n\"Leanard\"\n,\n\"Leander\"\n,\n\"Leandra\"\n,\n\"Leandre\"\n,\n\"Leandro\"\n,\n\"Leann\"\n,\n\"Leanna\"\n,\n\"Leanne\"\n,\n\"Leanor\"\n,\n\"Leanora\"\n,\n\"Leaper\"\n,\n\"Lear\"\n,\n\"Leary\"\n,\n\"Leasia\"\n,\n\"Leatri\"\n,\n\"Leatrice\"\n,\n\"Leavelle\"\n,\n\"Leavitt\"\n,\n\"Leavy\"\n,\n\"Leban\"\n,\n\"Lebar\"\n,\n\"Lebaron\"\n,\n\"Lebbie\"\n,\n\"Leblanc\"\n,\n\"Lebna\"\n,\n\"Leboff\"\n,\n\"Lechner\"\n,\n\"Lecia\"\n,\n\"Leckie\"\n,\n\"Leclair\"\n,\n\"Lectra\"\n,\n\"Leda\"\n,\n\"Ledah\"\n,\n\"Ledda\"\n,\n\"Leddy\"\n,\n\"Ledeen\"\n,\n\"Lederer\"\n,\n\"Lee\"\n,\n\"LeeAnn\"\n,\n\"Leeann\"\n,\n\"Leeanne\"\n,\n\"Leede\"\n,\n\"Leeke\"\n,\n\"Leela\"\n,\n\"Leelah\"\n,\n\"Leeland\"\n,\n\"Leena\"\n,\n\"Leesa\"\n,\n\"Leese\"\n,\n\"Leesen\"\n,\n\"Leeth\"\n,\n\"Leff\"\n,\n\"Leffen\"\n,\n\"Leffert\"\n,\n\"Lefkowitz\"\n,\n\"Lefton\"\n,\n\"Leftwich\"\n,\n\"Lefty\"\n,\n\"Leggat\"\n,\n\"Legge\"\n,\n\"Leggett\"\n,\n\"Legra\"\n,\n\"Lehet\"\n,\n\"Lehman\"\n,\n\"Lehmann\"\n,\n\"Lehrer\"\n,\n\"Leia\"\n,\n\"Leibman\"\n,\n\"Leicester\"\n,\n\"Leid\"\n,\n\"Leif\"\n,\n\"Leifer\"\n,\n\"Leifeste\"\n,\n\"Leigh\"\n,\n\"Leigha\"\n,\n\"Leighland\"\n,\n\"Leighton\"\n,\n\"Leila\"\n,\n\"Leilah\"\n,\n\"Leilani\"\n,\n\"Leipzig\"\n,\n\"Leis\"\n,\n\"Leiser\"\n,\n\"Leisha\"\n,\n\"Leitao\"\n,\n\"Leith\"\n,\n\"Leitman\"\n,\n\"Lejeune\"\n,\n\"Lek\"\n,\n\"Lela\"\n,\n\"Lelah\"\n,\n\"Leland\"\n,\n\"Leler\"\n,\n\"Lelia\"\n,\n\"Lelith\"\n,\n\"Lello\"\n,\n\"Lem\"\n,\n\"Lema\"\n,\n\"Lemaceon\"\n,\n\"Lemal\"\n,\n\"Lemar\"\n,\n\"Lemcke\"\n,\n\"Lemieux\"\n,\n\"Lemire\"\n,\n\"Lemkul\"\n,\n\"Lemmie\"\n,\n\"Lemmuela\"\n,\n\"Lemmueu\"\n,\n\"Lemmy\"\n,\n\"Lemon\"\n,\n\"Lempres\"\n,\n\"Lemuel\"\n,\n\"Lemuela\"\n,\n\"Lemuelah\"\n,\n\"Len\"\n,\n\"Lena\"\n,\n\"Lenard\"\n,\n\"Lenci\"\n,\n\"Lenee\"\n,\n\"Lenes\"\n,\n\"Lenette\"\n,\n\"Lengel\"\n,\n\"Lenhard\"\n,\n\"Lenhart\"\n,\n\"Lenka\"\n,\n\"Lenna\"\n,\n\"Lennard\"\n,\n\"Lenni\"\n,\n\"Lennie\"\n,\n\"Lenno\"\n,\n\"Lennon\"\n,\n\"Lennox\"\n,\n\"Lenny\"\n,\n\"Leno\"\n,\n\"Lenora\"\n,\n\"Lenore\"\n,\n\"Lenox\"\n,\n\"Lenrow\"\n,\n\"Lenssen\"\n,\n\"Lentha\"\n,\n\"Lenwood\"\n,\n\"Lenz\"\n,\n\"Lenzi\"\n,\n\"Leo\"\n,\n\"Leod\"\n,\n\"Leodora\"\n,\n\"Leoine\"\n,\n\"Leola\"\n,\n\"Leoline\"\n,\n\"Leon\"\n,\n\"Leona\"\n,\n\"Leonanie\"\n,\n\"Leonard\"\n,\n\"Leonardi\"\n,\n\"Leonardo\"\n,\n\"Leone\"\n,\n\"Leonelle\"\n,\n\"Leonerd\"\n,\n\"Leong\"\n,\n\"Leonhard\"\n,\n\"Leoni\"\n,\n\"Leonid\"\n,\n\"Leonidas\"\n,\n\"Leonie\"\n,\n\"Leonor\"\n,\n\"Leonora\"\n,\n\"Leonore\"\n,\n\"Leonsis\"\n,\n\"Leonteen\"\n,\n\"Leontina\"\n,\n\"Leontine\"\n,\n\"Leontyne\"\n,\n\"Leopold\"\n,\n\"Leopoldeen\"\n,\n\"Leopoldine\"\n,\n\"Leor\"\n,\n\"Leora\"\n,\n\"Leotie\"\n,\n\"Lepine\"\n,\n\"Lepley\"\n,\n\"Lepp\"\n,\n\"Lepper\"\n,\n\"Lerner\"\n,\n\"Leroi\"\n,\n\"Leroy\"\n,\n\"Les\"\n,\n\"Lesak\"\n,\n\"Leschen\"\n,\n\"Lesh\"\n,\n\"Leshia\"\n,\n\"Lesko\"\n,\n\"Leslee\"\n,\n\"Lesley\"\n,\n\"Lesli\"\n,\n\"Leslie\"\n,\n\"Lesly\"\n,\n\"Lessard\"\n,\n\"Lesser\"\n,\n\"Lesslie\"\n,\n\"Lester\"\n,\n\"Lesya\"\n,\n\"Let\"\n,\n\"Leta\"\n,\n\"Letch\"\n,\n\"Letha\"\n,\n\"Lethia\"\n,\n\"Leticia\"\n,\n\"Letisha\"\n,\n\"Letitia\"\n,\n\"Letizia\"\n,\n\"Letreece\"\n,\n\"Letrice\"\n,\n\"Letsou\"\n,\n\"Letta\"\n,\n\"Lette\"\n,\n\"Letti\"\n,\n\"Lettie\"\n,\n\"Letty\"\n,\n\"Leund\"\n,\n\"Leupold\"\n,\n\"Lev\"\n,\n\"Levan\"\n,\n\"Levana\"\n,\n\"Levania\"\n,\n\"Levenson\"\n,\n\"Leventhal\"\n,\n\"Leventis\"\n,\n\"Leverett\"\n,\n\"Leverick\"\n,\n\"Leveridge\"\n,\n\"Leveroni\"\n,\n\"Levesque\"\n,\n\"Levey\"\n,\n\"Levi\"\n,\n\"Levin\"\n,\n\"Levina\"\n,\n\"Levine\"\n,\n\"Levins\"\n,\n\"Levinson\"\n,\n\"Levison\"\n,\n\"Levitan\"\n,\n\"Levitt\"\n,\n\"Levon\"\n,\n\"Levona\"\n,\n\"Levy\"\n,\n\"Lew\"\n,\n\"Lewak\"\n,\n\"Lewan\"\n,\n\"Lewanna\"\n,\n\"Lewellen\"\n,\n\"Lewendal\"\n,\n\"Lewert\"\n,\n\"Lewes\"\n,\n\"Lewie\"\n,\n\"Lewin\"\n,\n\"Lewis\"\n,\n\"Lewison\"\n,\n\"Lewiss\"\n,\n\"Lewls\"\n,\n\"Lewse\"\n,\n\"Lexi\"\n,\n\"Lexie\"\n,\n\"Lexine\"\n,\n\"Lexis\"\n,\n\"Lexy\"\n,\n\"Ley\"\n,\n\"Leyes\"\n,\n\"Leyla\"\n,\n\"Lezley\"\n,\n\"Lezlie\"\n,\n\"Lhary\"\n,\n\"Li\"\n,\n\"Lia\"\n,\n\"Liam\"\n,\n\"Lian\"\n,\n\"Liana\"\n,\n\"Liane\"\n,\n\"Lianna\"\n,\n\"Lianne\"\n,\n\"Lias\"\n,\n\"Liatrice\"\n,\n\"Liatris\"\n,\n\"Lib\"\n,\n\"Liba\"\n,\n\"Libb\"\n,\n\"Libbey\"\n,\n\"Libbi\"\n,\n\"Libbie\"\n,\n\"Libbna\"\n,\n\"Libby\"\n,\n\"Libenson\"\n,\n\"Liberati\"\n,\n\"Libna\"\n,\n\"Libnah\"\n,\n\"Liborio\"\n,\n\"Libove\"\n,\n\"Libre\"\n,\n\"Licastro\"\n,\n\"Licha\"\n,\n\"Licht\"\n,\n\"Lichtenfeld\"\n,\n\"Lichter\"\n,\n\"Licko\"\n,\n\"Lida\"\n,\n\"Lidah\"\n,\n\"Lidda\"\n,\n\"Liddie\"\n,\n\"Liddle\"\n,\n\"Liddy\"\n,\n\"Lidia\"\n,\n\"Lidstone\"\n,\n\"Lieberman\"\n,\n\"Liebermann\"\n,\n\"Liebman\"\n,\n\"Liebowitz\"\n,\n\"Liederman\"\n,\n\"Lief\"\n,\n\"Lienhard\"\n,\n\"Liesa\"\n,\n\"Lietman\"\n,\n\"Liew\"\n,\n\"Lifton\"\n,\n\"Ligetti\"\n,\n\"Liggett\"\n,\n\"Liggitt\"\n,\n\"Light\"\n,\n\"Lightfoot\"\n,\n\"Lightman\"\n,\n\"Lil\"\n,\n\"Lila\"\n,\n\"Lilac\"\n,\n\"Lilah\"\n,\n\"Lilas\"\n,\n\"Lili\"\n,\n\"Lilia\"\n,\n\"Lilian\"\n,\n\"Liliane\"\n,\n\"Lilias\"\n,\n\"Lilith\"\n,\n\"Lilithe\"\n,\n\"Lilla\"\n,\n\"Lilli\"\n,\n\"Lillian\"\n,\n\"Lillie\"\n,\n\"Lillis\"\n,\n\"Lillith\"\n,\n\"Lilllie\"\n,\n\"Lilly\"\n,\n\"Lillywhite\"\n,\n\"Lily\"\n,\n\"Lilyan\"\n,\n\"Lilybel\"\n,\n\"Lilybelle\"\n,\n\"Lim\"\n,\n\"Liman\"\n,\n\"Limann\"\n,\n\"Limber\"\n,\n\"Limbert\"\n,\n\"Limemann\"\n,\n\"Limoli\"\n,\n\"Lin\"\n,\n\"Lina\"\n,\n\"Linc\"\n,\n\"Lincoln\"\n,\n\"Lind\"\n,\n\"Linda\"\n,\n\"Lindahl\"\n,\n\"Lindberg\"\n,\n\"Lindblad\"\n,\n\"Lindbom\"\n,\n\"Lindeberg\"\n,\n\"Lindell\"\n,\n\"Lindemann\"\n,\n\"Linden\"\n,\n\"Linder\"\n,\n\"Linders\"\n,\n\"Lindgren\"\n,\n\"Lindholm\"\n,\n\"Lindi\"\n,\n\"Lindie\"\n,\n\"Lindley\"\n,\n\"Lindly\"\n,\n\"Lindner\"\n,\n\"Lindo\"\n,\n\"Lindon\"\n,\n\"Lindsay\"\n,\n\"Lindsey\"\n,\n\"Lindsley\"\n,\n\"Lindsy\"\n,\n\"Lindy\"\n,\n\"Line\"\n,\n\"Linea\"\n,\n\"Linehan\"\n,\n\"Linell\"\n,\n\"Linet\"\n,\n\"Linetta\"\n,\n\"Linette\"\n,\n\"Ling\"\n,\n\"Lingwood\"\n,\n\"Linis\"\n,\n\"Link\"\n,\n\"Linker\"\n,\n\"Linkoski\"\n,\n\"Linn\"\n,\n\"Linnea\"\n,\n\"Linnell\"\n,\n\"Linneman\"\n,\n\"Linnet\"\n,\n\"Linnette\"\n,\n\"Linnie\"\n,\n\"Linoel\"\n,\n\"Linsk\"\n,\n\"Linskey\"\n,\n\"Linson\"\n,\n\"Linus\"\n,\n\"Linzer\"\n,\n\"Linzy\"\n,\n\"Lion\"\n,\n\"Lionel\"\n,\n\"Lionello\"\n,\n\"Lipcombe\"\n,\n\"Lipfert\"\n,\n\"Lipinski\"\n,\n\"Lipkin\"\n,\n\"Lipman\"\n,\n\"Liponis\"\n,\n\"Lipp\"\n,\n\"Lippold\"\n,\n\"Lipps\"\n,\n\"Lipscomb\"\n,\n\"Lipsey\"\n,\n\"Lipski\"\n,\n\"Lipson\"\n,\n\"Lira\"\n,\n\"Liris\"\n,\n\"Lisa\"\n,\n\"Lisabet\"\n,\n\"Lisabeth\"\n,\n\"Lisan\"\n,\n\"Lisandra\"\n,\n\"Lisbeth\"\n,\n\"Liscomb\"\n,\n\"Lise\"\n,\n\"Lisetta\"\n,\n\"Lisette\"\n,\n\"Lisha\"\n,\n\"Lishe\"\n,\n\"Lisk\"\n,\n\"Lisle\"\n,\n\"Liss\"\n,\n\"Lissa\"\n,\n\"Lissak\"\n,\n\"Lissi\"\n,\n\"Lissie\"\n,\n\"Lissner\"\n,\n\"Lissy\"\n,\n\"Lister\"\n,\n\"Lita\"\n,\n\"Litch\"\n,\n\"Litha\"\n,\n\"Lithea\"\n,\n\"Litman\"\n,\n\"Litt\"\n,\n\"Litta\"\n,\n\"Littell\"\n,\n\"Little\"\n,\n\"Littlejohn\"\n,\n\"Littman\"\n,\n\"Litton\"\n,\n\"Liu\"\n,\n\"Liuka\"\n,\n\"Liv\"\n,\n\"Liva\"\n,\n\"Livesay\"\n,\n\"Livi\"\n,\n\"Livia\"\n,\n\"Livingston\"\n,\n\"Livingstone\"\n,\n\"Livvi\"\n,\n\"Livvie\"\n,\n\"Livvy\"\n,\n\"Livvyy\"\n,\n\"Livy\"\n,\n\"Liz\"\n,\n\"Liza\"\n,\n\"Lizabeth\"\n,\n\"Lizbeth\"\n,\n\"Lizette\"\n,\n\"Lizzie\"\n,\n\"Lizzy\"\n,\n\"Ljoka\"\n,\n\"Llewellyn\"\n,\n\"Llovera\"\n,\n\"Lloyd\"\n,\n\"Llywellyn\"\n,\n\"Loar\"\n,\n\"Loats\"\n,\n\"Lobel\"\n,\n\"Lobell\"\n,\n\"Lochner\"\n,\n\"Lock\"\n,\n\"Locke\"\n,\n\"Lockhart\"\n,\n\"Locklin\"\n,\n\"Lockwood\"\n,\n\"Lodge\"\n,\n\"Lodhia\"\n,\n\"Lodi\"\n,\n\"Lodie\"\n,\n\"Lodmilla\"\n,\n\"Lodovico\"\n,\n\"Lody\"\n,\n\"Loeb\"\n,\n\"Loella\"\n,\n\"Loesceke\"\n,\n\"Loferski\"\n,\n\"Loftis\"\n,\n\"Loftus\"\n,\n\"Logan\"\n,\n\"Loggia\"\n,\n\"Loggins\"\n,\n\"Loginov\"\n,\n\"Lohman\"\n,\n\"Lohner\"\n,\n\"Lohrman\"\n,\n\"Lohse\"\n,\n\"Lois\"\n,\n\"Loise\"\n,\n\"Lola\"\n,\n\"Lolande\"\n,\n\"Lolanthe\"\n,\n\"Lole\"\n,\n\"Loleta\"\n,\n\"Lolita\"\n,\n\"Lolly\"\n,\n\"Loma\"\n,\n\"Lomasi\"\n,\n\"Lomax\"\n,\n\"Lombard\"\n,\n\"Lombardi\"\n,\n\"Lombardo\"\n,\n\"Lombardy\"\n,\n\"Lon\"\n,\n\"Lona\"\n,\n\"London\"\n,\n\"Londoner\"\n,\n\"Lonee\"\n,\n\"Lonergan\"\n,\n\"Long\"\n,\n\"Longan\"\n,\n\"Longawa\"\n,\n\"Longerich\"\n,\n\"Longfellow\"\n,\n\"Longley\"\n,\n\"Longmire\"\n,\n\"Longo\"\n,\n\"Longtin\"\n,\n\"Longwood\"\n,\n\"Loni\"\n,\n\"Lonier\"\n,\n\"Lonna\"\n,\n\"Lonnard\"\n,\n\"Lonne\"\n,\n\"Lonni\"\n,\n\"Lonnie\"\n,\n\"Lonny\"\n,\n\"Lontson\"\n,\n\"Loomis\"\n,\n\"Loos\"\n,\n\"Lopes\"\n,\n\"Lopez\"\n,\n\"Lora\"\n,\n\"Lorain\"\n,\n\"Loraine\"\n,\n\"Loralee\"\n,\n\"Loralie\"\n,\n\"Loralyn\"\n,\n\"Loram\"\n,\n\"Lorant\"\n,\n\"Lord\"\n,\n\"Lordan\"\n,\n\"Loredana\"\n,\n\"Loredo\"\n,\n\"Loree\"\n,\n\"Loreen\"\n,\n\"Lorelei\"\n,\n\"Lorelie\"\n,\n\"Lorelle\"\n,\n\"Loren\"\n,\n\"Lorena\"\n,\n\"Lorene\"\n,\n\"Lorens\"\n,\n\"Lorenz\"\n,\n\"Lorenza\"\n,\n\"Lorenzana\"\n,\n\"Lorenzo\"\n,\n\"Loresz\"\n,\n\"Loretta\"\n,\n\"Lorette\"\n,\n\"Lori\"\n,\n\"Loria\"\n,\n\"Lorianna\"\n,\n\"Lorianne\"\n,\n\"Lorie\"\n,\n\"Lorien\"\n,\n\"Lorilee\"\n,\n\"Lorilyn\"\n,\n\"Lorimer\"\n,\n\"Lorin\"\n,\n\"Lorinda\"\n,\n\"Lorine\"\n,\n\"Loriner\"\n,\n\"Loring\"\n,\n\"Loris\"\n,\n\"Lorita\"\n,\n\"Lorn\"\n,\n\"Lorna\"\n,\n\"Lorne\"\n,\n\"Lorola\"\n,\n\"Lorolla\"\n,\n\"Lorollas\"\n,\n\"Lorou\"\n,\n\"Lorraine\"\n,\n\"Lorrayne\"\n,\n\"Lorri\"\n,\n\"Lorrie\"\n,\n\"Lorrimer\"\n,\n\"Lorrimor\"\n,\n\"Lorrin\"\n,\n\"Lorry\"\n,\n\"Lorsung\"\n,\n\"Lorusso\"\n,\n\"Lory\"\n,\n\"Lose\"\n,\n\"Loseff\"\n,\n\"Loss\"\n,\n\"Lossa\"\n,\n\"Losse\"\n,\n\"Lot\"\n,\n\"Lothair\"\n,\n\"Lothaire\"\n,\n\"Lothar\"\n,\n\"Lothario\"\n,\n\"Lotson\"\n,\n\"Lotta\"\n,\n\"Lotte\"\n,\n\"Lotti\"\n,\n\"Lottie\"\n,\n\"Lotty\"\n,\n\"Lotus\"\n,\n\"Lotz\"\n,\n\"Lou\"\n,\n\"Louanna\"\n,\n\"Louanne\"\n,\n\"Louella\"\n,\n\"Lough\"\n,\n\"Lougheed\"\n,\n\"Loughlin\"\n,\n\"Louie\"\n,\n\"Louis\"\n,\n\"Louisa\"\n,\n\"Louise\"\n,\n\"Louisette\"\n,\n\"Louls\"\n,\n\"Lounge\"\n,\n\"Lourdes\"\n,\n\"Lourie\"\n,\n\"Louth\"\n,\n\"Loutitia\"\n,\n\"Loux\"\n,\n\"Lovash\"\n,\n\"Lovato\"\n,\n\"Love\"\n,\n\"Lovel\"\n,\n\"Lovell\"\n,\n\"Loveridge\"\n,\n\"Lovering\"\n,\n\"Lovett\"\n,\n\"Lovich\"\n,\n\"Lovmilla\"\n,\n\"Low\"\n,\n\"Lowe\"\n,\n\"Lowell\"\n,\n\"Lowenstein\"\n,\n\"Lowenstern\"\n,\n\"Lower\"\n,\n\"Lowery\"\n,\n\"Lowis\"\n,\n\"Lowndes\"\n,\n\"Lowney\"\n,\n\"Lowrance\"\n,\n\"Lowrie\"\n,\n\"Lowry\"\n,\n\"Lowson\"\n,\n\"Loy\"\n,\n\"Loyce\"\n,\n\"Loydie\"\n,\n\"Lozano\"\n,\n\"Lozar\"\n,\n\"Lu\"\n,\n\"Luana\"\n,\n\"Luane\"\n,\n\"Luann\"\n,\n\"Luanne\"\n,\n\"Luanni\"\n,\n\"Luba\"\n,\n\"Lubba\"\n,\n\"Lubbi\"\n,\n\"Lubbock\"\n,\n\"Lubeck\"\n,\n\"Luben\"\n,\n\"Lubet\"\n,\n\"Lubin\"\n,\n\"Lubow\"\n,\n\"Luby\"\n,\n\"Luca\"\n,\n\"Lucais\"\n,\n\"Lucania\"\n,\n\"Lucas\"\n,\n\"Lucchesi\"\n,\n\"Luce\"\n,\n\"Lucey\"\n,\n\"Lucho\"\n,\n\"Luci\"\n,\n\"Lucia\"\n,\n\"Lucian\"\n,\n\"Luciana\"\n,\n\"Luciano\"\n,\n\"Lucias\"\n,\n\"Lucic\"\n,\n\"Lucie\"\n,\n\"Lucien\"\n,\n\"Lucienne\"\n,\n\"Lucier\"\n,\n\"Lucila\"\n,\n\"Lucilia\"\n,\n\"Lucilla\"\n,\n\"Lucille\"\n,\n\"Lucina\"\n,\n\"Lucinda\"\n,\n\"Lucine\"\n,\n\"Lucio\"\n,\n\"Lucita\"\n,\n\"Lucius\"\n,\n\"Luckett\"\n,\n\"Luckin\"\n,\n\"Lucky\"\n,\n\"Lucrece\"\n,\n\"Lucretia\"\n,\n\"Lucy\"\n,\n\"Lud\"\n,\n\"Ludeman\"\n,\n\"Ludewig\"\n,\n\"Ludie\"\n,\n\"Ludlew\"\n,\n\"Ludlow\"\n,\n\"Ludly\"\n,\n\"Ludmilla\"\n,\n\"Ludovick\"\n,\n\"Ludovico\"\n,\n\"Ludovika\"\n,\n\"Ludvig\"\n,\n\"Ludwig\"\n,\n\"Ludwigg\"\n,\n\"Ludwog\"\n,\n\"Luebke\"\n,\n\"Luedtke\"\n,\n\"Luehrmann\"\n,\n\"Luella\"\n,\n\"Luelle\"\n,\n\"Lugar\"\n,\n\"Lugo\"\n,\n\"Luhe\"\n,\n\"Luhey\"\n,\n\"Luht\"\n,\n\"Luigi\"\n,\n\"Luigino\"\n,\n\"Luing\"\n,\n\"Luis\"\n,\n\"Luisa\"\n,\n\"Luise\"\n,\n\"Luiza\"\n,\n\"Lukas\"\n,\n\"Lukash\"\n,\n\"Lukasz\"\n,\n\"Luke\"\n,\n\"Lukey\"\n,\n\"Lukin\"\n,\n\"Lula\"\n,\n\"Lulita\"\n,\n\"Lull\"\n,\n\"Lulu\"\n,\n\"Lumbard\"\n,\n\"Lumbye\"\n,\n\"Lumpkin\"\n,\n\"Luna\"\n,\n\"Lund\"\n,\n\"Lundberg\"\n,\n\"Lundeen\"\n,\n\"Lundell\"\n,\n\"Lundgren\"\n,\n\"Lundin\"\n,\n\"Lundquist\"\n,\n\"Lundt\"\n,\n\"Lune\"\n,\n\"Lunetta\"\n,\n\"Lunette\"\n,\n\"Lunn\"\n,\n\"Lunna\"\n,\n\"Lunneta\"\n,\n\"Lunnete\"\n,\n\"Lunseth\"\n,\n\"Lunsford\"\n,\n\"Lunt\"\n,\n\"Luo\"\n,\n\"Lupe\"\n,\n\"Lupee\"\n,\n\"Lupien\"\n,\n\"Lupita\"\n,\n\"Lura\"\n,\n\"Lurette\"\n,\n\"Lurie\"\n,\n\"Lurleen\"\n,\n\"Lurlene\"\n,\n\"Lurline\"\n,\n\"Lusa\"\n,\n\"Lussi\"\n,\n\"Lussier\"\n,\n\"Lust\"\n,\n\"Lustick\"\n,\n\"Lustig\"\n,\n\"Lusty\"\n,\n\"Lutero\"\n,\n\"Luthanen\"\n,\n\"Luther\"\n,\n\"Luttrell\"\n,\n\"Luwana\"\n,\n\"Lux\"\n,\n\"Luz\"\n,\n\"Luzader\"\n,\n\"Ly\"\n,\n\"Lyall\"\n,\n\"Lyckman\"\n,\n\"Lyda\"\n,\n\"Lydell\"\n,\n\"Lydia\"\n,\n\"Lydie\"\n,\n\"Lydon\"\n,\n\"Lyell\"\n,\n\"Lyford\"\n,\n\"Lyle\"\n,\n\"Lyman\"\n,\n\"Lymann\"\n,\n\"Lymn\"\n,\n\"Lyn\"\n,\n\"Lynch\"\n,\n\"Lynd\"\n,\n\"Lynda\"\n,\n\"Lynde\"\n,\n\"Lyndel\"\n,\n\"Lyndell\"\n,\n\"Lynden\"\n,\n\"Lyndes\"\n,\n\"Lyndon\"\n,\n\"Lyndsay\"\n,\n\"Lyndsey\"\n,\n\"Lyndsie\"\n,\n\"Lyndy\"\n,\n\"Lynea\"\n,\n\"Lynelle\"\n,\n\"Lynett\"\n,\n\"Lynette\"\n,\n\"Lynn\"\n,\n\"Lynna\"\n,\n\"Lynne\"\n,\n\"Lynnea\"\n,\n\"Lynnell\"\n,\n\"Lynnelle\"\n,\n\"Lynnet\"\n,\n\"Lynnett\"\n,\n\"Lynnette\"\n,\n\"Lynnworth\"\n,\n\"Lyns\"\n,\n\"Lynsey\"\n,\n\"Lynus\"\n,\n\"Lyon\"\n,\n\"Lyons\"\n,\n\"Lyontine\"\n,\n\"Lyris\"\n,\n\"Lysander\"\n,\n\"Lyssa\"\n,\n\"Lytle\"\n,\n\"Lytton\"\n,\n\"Lyudmila\"\n,\n\"Ma\"\n,\n\"Maag\"\n,\n\"Mab\"\n,\n\"Mabel\"\n,\n\"Mabelle\"\n,\n\"Mable\"\n,\n\"Mac\"\n,\n\"MacCarthy\"\n,\n\"MacDermot\"\n,\n\"MacDonald\"\n,\n\"MacDonell\"\n,\n\"MacDougall\"\n,\n\"MacEgan\"\n,\n\"MacFadyn\"\n,\n\"MacFarlane\"\n,\n\"MacGregor\"\n,\n\"MacGuiness\"\n,\n\"MacIlroy\"\n,\n\"MacIntosh\"\n,\n\"MacIntyre\"\n,\n\"MacKay\"\n,\n\"MacKenzie\"\n,\n\"MacLaine\"\n,\n\"MacLay\"\n,\n\"MacLean\"\n,\n\"MacLeod\"\n,\n\"MacMahon\"\n,\n\"MacMillan\"\n,\n\"MacMullin\"\n,\n\"MacNair\"\n,\n\"MacNamara\"\n,\n\"MacPherson\"\n,\n\"MacRae\"\n,\n\"MacSwan\"\n,\n\"Macario\"\n,\n\"Maccarone\"\n,\n\"Mace\"\n,\n\"Macegan\"\n,\n\"Macey\"\n,\n\"Machos\"\n,\n\"Machute\"\n,\n\"Machutte\"\n,\n\"Mack\"\n,\n\"Mackenie\"\n,\n\"Mackenzie\"\n,\n\"Mackey\"\n,\n\"Mackie\"\n,\n\"Mackintosh\"\n,\n\"Mackler\"\n,\n\"Macknair\"\n,\n\"Mackoff\"\n,\n\"Macnair\"\n,\n\"Macomber\"\n,\n\"Macri\"\n,\n\"Macur\"\n,\n\"Macy\"\n,\n\"Mada\"\n,\n\"Madai\"\n,\n\"Madaih\"\n,\n\"Madalena\"\n,\n\"Madalyn\"\n,\n\"Madancy\"\n,\n\"Madaras\"\n,\n\"Maddalena\"\n,\n\"Madden\"\n,\n\"Maddeu\"\n,\n\"Maddi\"\n,\n\"Maddie\"\n,\n\"Maddis\"\n,\n\"Maddock\"\n,\n\"Maddocks\"\n,\n\"Maddox\"\n,\n\"Maddy\"\n,\n\"Madea\"\n,\n\"Madel\"\n,\n\"Madelaine\"\n,\n\"Madeleine\"\n,\n\"Madelena\"\n,\n\"Madelene\"\n,\n\"Madelin\"\n,\n\"Madelina\"\n,\n\"Madeline\"\n,\n\"Madella\"\n,\n\"Madelle\"\n,\n\"Madelon\"\n,\n\"Madelyn\"\n,\n\"Madge\"\n,\n\"Madi\"\n,\n\"Madian\"\n,\n\"Madid\"\n,\n\"Madigan\"\n,\n\"Madison\"\n,\n\"Madlen\"\n,\n\"Madlin\"\n,\n\"Madoc\"\n,\n\"Madonia\"\n,\n\"Madonna\"\n,\n\"Madora\"\n,\n\"Madox\"\n,\n\"Madra\"\n,\n\"Madriene\"\n,\n\"Madson\"\n,\n\"Mady\"\n,\n\"Mae\"\n,\n\"Maegan\"\n,\n\"Maeve\"\n,\n\"Mafala\"\n,\n\"Mafalda\"\n,\n\"Maffa\"\n,\n\"Maffei\"\n,\n\"Mag\"\n,\n\"Magan\"\n,\n\"Magas\"\n,\n\"Magavern\"\n,\n\"Magbie\"\n,\n\"Magda\"\n,\n\"Magdaia\"\n,\n\"Magdala\"\n,\n\"Magdalen\"\n,\n\"Magdalena\"\n,\n\"Magdalene\"\n,\n\"Magdau\"\n,\n\"Magee\"\n,\n\"Magel\"\n,\n\"Magen\"\n,\n\"Magena\"\n,\n\"Mages\"\n,\n\"Maggee\"\n,\n\"Maggi\"\n,\n\"Maggie\"\n,\n\"Maggio\"\n,\n\"Maggs\"\n,\n\"Maggy\"\n,\n\"Maghutte\"\n,\n\"Magill\"\n,\n\"Magna\"\n,\n\"Magner\"\n,\n\"Magnien\"\n,\n\"Magnolia\"\n,\n\"Magnum\"\n,\n\"Magnus\"\n,\n\"Magnuson\"\n,\n\"Magnusson\"\n,\n\"Magocsi\"\n,\n\"Magree\"\n,\n\"Maguire\"\n,\n\"Magulac\"\n,\n\"Mahala\"\n,\n\"Mahalia\"\n,\n\"Mahan\"\n,\n\"Mahau\"\n,\n\"Maher\"\n,\n\"Mahla\"\n,\n\"Mahmoud\"\n,\n\"Mahmud\"\n,\n\"Mahon\"\n,\n\"Mahoney\"\n,\n\"Maia\"\n,\n\"Maiah\"\n,\n\"Maibach\"\n,\n\"Maible\"\n,\n\"Maice\"\n,\n\"Maida\"\n,\n\"Maidel\"\n,\n\"Maidie\"\n,\n\"Maidy\"\n,\n\"Maier\"\n,\n\"Maiga\"\n,\n\"Maighdiln\"\n,\n\"Maighdlin\"\n,\n\"Mailand\"\n,\n\"Main\"\n,\n\"Mainis\"\n,\n\"Maiocco\"\n,\n\"Mair\"\n,\n\"Maire\"\n,\n\"Maise\"\n,\n\"Maisel\"\n,\n\"Maisey\"\n,\n\"Maisie\"\n,\n\"Maison\"\n,\n\"Maite\"\n,\n\"Maitilde\"\n,\n\"Maitland\"\n,\n\"Maitund\"\n,\n\"Maje\"\n,\n\"Majka\"\n,\n\"Major\"\n,\n\"Mak\"\n,\n\"Makell\"\n,\n\"Maker\"\n,\n\"Mal\"\n,\n\"Mala\"\n,\n\"Malachi\"\n,\n\"Malachy\"\n,\n\"Malamud\"\n,\n\"Malamut\"\n,\n\"Malan\"\n,\n\"Malanie\"\n,\n\"Malarkey\"\n,\n\"Malaspina\"\n,\n\"Malca\"\n,\n\"Malcah\"\n,\n\"Malchus\"\n,\n\"Malchy\"\n,\n\"Malcolm\"\n,\n\"Malcom\"\n,\n\"Malda\"\n,\n\"Maleeny\"\n,\n\"Malek\"\n,\n\"Maleki\"\n,\n\"Malena\"\n,\n\"Malet\"\n,\n\"Maletta\"\n,\n\"Mali\"\n,\n\"Malia\"\n,\n\"Malik\"\n,\n\"Malin\"\n,\n\"Malina\"\n,\n\"Malinda\"\n,\n\"Malinde\"\n,\n\"Malinin\"\n,\n\"Malinowski\"\n,\n\"Malissa\"\n,\n\"Malissia\"\n,\n\"Malita\"\n,\n\"Malka\"\n,\n\"Malkah\"\n,\n\"Malkin\"\n,\n\"Mall\"\n,\n\"Mallen\"\n,\n\"Maller\"\n,\n\"Malley\"\n,\n\"Mallin\"\n,\n\"Mallina\"\n,\n\"Mallis\"\n,\n\"Mallissa\"\n,\n\"Malloch\"\n,\n\"Mallon\"\n,\n\"Mallorie\"\n,\n\"Mallory\"\n,\n\"Malloy\"\n,\n\"Malo\"\n,\n\"Malone\"\n,\n\"Maloney\"\n,\n\"Malonis\"\n,\n\"Malony\"\n,\n\"Malorie\"\n,\n\"Malory\"\n,\n\"Maloy\"\n,\n\"Malti\"\n,\n\"Maltz\"\n,\n\"Maltzman\"\n,\n\"Malva\"\n,\n\"Malvia\"\n,\n\"Malvie\"\n,\n\"Malvin\"\n,\n\"Malvina\"\n,\n\"Malvino\"\n,\n\"Malynda\"\n,\n\"Mame\"\n,\n\"Mamie\"\n,\n\"Mamoun\"\n,\n\"Man\"\n,\n\"Manaker\"\n,\n\"Manara\"\n,\n\"Manard\"\n,\n\"Manchester\"\n,\n\"Mancino\"\n,\n\"Manda\"\n,\n\"Mandal\"\n,\n\"Mandel\"\n,\n\"Mandelbaum\"\n,\n\"Mandell\"\n,\n\"Mandeville\"\n,\n\"Mandi\"\n,\n\"Mandie\"\n,\n\"Mandle\"\n,\n\"Mandler\"\n,\n\"Mandy\"\n,\n\"Mandych\"\n,\n\"Manella\"\n,\n\"Manfred\"\n,\n\"Manheim\"\n,\n\"Mani\"\n,\n\"Manley\"\n,\n\"Manlove\"\n,\n\"Manly\"\n,\n\"Mann\"\n,\n\"Mannes\"\n,\n\"Mannie\"\n,\n\"Manning\"\n,\n\"Manno\"\n,\n\"Mannos\"\n,\n\"Mannuela\"\n,\n\"Manny\"\n,\n\"Mano\"\n,\n\"Manoff\"\n,\n\"Manolo\"\n,\n\"Manon\"\n,\n\"Manouch\"\n,\n\"Mansfield\"\n,\n\"Manson\"\n,\n\"Mansoor\"\n,\n\"Mansur\"\n,\n\"Manthei\"\n,\n\"Manton\"\n,\n\"Manuel\"\n,\n\"Manuela\"\n,\n\"Manus\"\n,\n\"Manvel\"\n,\n\"Manvell\"\n,\n\"Manvil\"\n,\n\"Manville\"\n,\n\"Manwell\"\n,\n\"Manya\"\n,\n\"Mapel\"\n,\n\"Mapes\"\n,\n\"Maples\"\n,\n\"Mar\"\n,\n\"Mara\"\n,\n\"Marabel\"\n,\n\"Marabelle\"\n,\n\"Marala\"\n,\n\"Marasco\"\n,\n\"Marashio\"\n,\n\"Marbut\"\n,\n\"Marc\"\n,\n\"Marceau\"\n,\n\"Marcel\"\n,\n\"Marcela\"\n,\n\"Marcelia\"\n,\n\"Marcell\"\n,\n\"Marcella\"\n,\n\"Marcelle\"\n,\n\"Marcellina\"\n,\n\"Marcelline\"\n,\n\"Marcello\"\n,\n\"Marcellus\"\n,\n\"Marcelo\"\n,\n\"March\"\n,\n\"Marchak\"\n,\n\"Marchal\"\n,\n\"Marchall\"\n,\n\"Marchelle\"\n,\n\"Marchese\"\n,\n\"Marci\"\n,\n\"Marcia\"\n,\n\"Marciano\"\n,\n\"Marcie\"\n,\n\"Marcile\"\n,\n\"Marcille\"\n,\n\"Marcin\"\n,\n\"Marco\"\n,\n\"Marcos\"\n,\n\"Marcoux\"\n,\n\"Marcus\"\n,\n\"Marcy\"\n,\n\"Marden\"\n,\n\"Marder\"\n,\n\"Marduk\"\n,\n\"Mareah\"\n,\n\"Marek\"\n,\n\"Marela\"\n,\n\"Mareld\"\n,\n\"Marelda\"\n,\n\"Marella\"\n,\n\"Marelya\"\n,\n\"Maren\"\n,\n\"Marena\"\n,\n\"Marentic\"\n,\n\"Maressa\"\n,\n\"Maretz\"\n,\n\"Marga\"\n,\n\"Margalit\"\n,\n\"Margalo\"\n,\n\"Margaret\"\n,\n\"Margareta\"\n,\n\"Margarete\"\n,\n\"Margaretha\"\n,\n\"Margarethe\"\n,\n\"Margaretta\"\n,\n\"Margarette\"\n,\n\"Margarida\"\n,\n\"Margarita\"\n,\n\"Margaux\"\n,\n\"Marge\"\n,\n\"Margeaux\"\n,\n\"Margery\"\n,\n\"Marget\"\n,\n\"Margette\"\n,\n\"Margetts\"\n,\n\"Margherita\"\n,\n\"Margi\"\n,\n\"Margie\"\n,\n\"Margit\"\n,\n\"Margo\"\n,\n\"Margot\"\n,\n\"Margret\"\n,\n\"Margreta\"\n,\n\"Marguerie\"\n,\n\"Marguerita\"\n,\n\"Marguerite\"\n,\n\"Margy\"\n,\n\"Mari\"\n,\n\"Maria\"\n,\n\"Mariam\"\n,\n\"Marian\"\n,\n\"Mariana\"\n,\n\"Mariand\"\n,\n\"Mariande\"\n,\n\"Mariandi\"\n,\n\"Mariann\"\n,\n\"Marianna\"\n,\n\"Marianne\"\n,\n\"Mariano\"\n,\n\"Maribel\"\n,\n\"Maribelle\"\n,\n\"Maribeth\"\n,\n\"Marice\"\n,\n\"Maridel\"\n,\n\"Marie\"\n,\n\"Marie-Ann\"\n,\n\"Marie-Jeanne\"\n,\n\"Marieann\"\n,\n\"Mariejeanne\"\n,\n\"Mariel\"\n,\n\"Mariele\"\n,\n\"Marielle\"\n,\n\"Mariellen\"\n,\n\"Marienthal\"\n,\n\"Marietta\"\n,\n\"Mariette\"\n,\n\"Marigold\"\n,\n\"Marigolda\"\n,\n\"Marigolde\"\n,\n\"Marijane\"\n,\n\"Marijn\"\n,\n\"Marijo\"\n,\n\"Marika\"\n,\n\"Mariken\"\n,\n\"Mariko\"\n,\n\"Maril\"\n,\n\"Marilee\"\n,\n\"Marilin\"\n,\n\"Marilla\"\n,\n\"Marillin\"\n,\n\"Marilou\"\n,\n\"Marilyn\"\n,\n\"Marin\"\n,\n\"Marina\"\n,\n\"Marinelli\"\n,\n\"Marinna\"\n,\n\"Marino\"\n,\n\"Mario\"\n,\n\"Marion\"\n,\n\"Mariquilla\"\n,\n\"Maris\"\n,\n\"Marisa\"\n,\n\"Mariska\"\n,\n\"Marissa\"\n,\n\"Marita\"\n,\n\"Maritsa\"\n,\n\"Marius\"\n,\n\"Mariya\"\n,\n\"Marj\"\n,\n\"Marja\"\n,\n\"Marjana\"\n,\n\"Marje\"\n,\n\"Marji\"\n,\n\"Marjie\"\n,\n\"Marjorie\"\n,\n\"Marjory\"\n,\n\"Marjy\"\n,\n\"Mark\"\n,\n\"Market\"\n,\n\"Marketa\"\n,\n\"Markland\"\n,\n\"Markman\"\n,\n\"Marko\"\n,\n\"Markos\"\n,\n\"Markowitz\"\n,\n\"Marks\"\n,\n\"Markson\"\n,\n\"Markus\"\n,\n\"Marl\"\n,\n\"Marla\"\n,\n\"Marlane\"\n,\n\"Marlea\"\n,\n\"Marleah\"\n,\n\"Marlee\"\n,\n\"Marleen\"\n,\n\"Marlen\"\n,\n\"Marlena\"\n,\n\"Marlene\"\n,\n\"Marler\"\n,\n\"Marlette\"\n,\n\"Marley\"\n,\n\"Marlie\"\n,\n\"Marlin\"\n,\n\"Marline\"\n,\n\"Marlo\"\n,\n\"Marlon\"\n,\n\"Marlow\"\n,\n\"Marlowe\"\n,\n\"Marlyn\"\n,\n\"Marmaduke\"\n,\n\"Marmawke\"\n,\n\"Marmion\"\n,\n\"Marna\"\n,\n\"Marne\"\n,\n\"Marney\"\n,\n\"Marni\"\n,\n\"Marnia\"\n,\n\"Marnie\"\n,\n\"Maro\"\n,\n\"Marola\"\n,\n\"Marolda\"\n,\n\"Maroney\"\n,\n\"Marou\"\n,\n\"Marozas\"\n,\n\"Marozik\"\n,\n\"Marpet\"\n,\n\"Marquardt\"\n,\n\"Marquet\"\n,\n\"Marquez\"\n,\n\"Marquis\"\n,\n\"Marquita\"\n,\n\"Marr\"\n,\n\"Marra\"\n,\n\"Marras\"\n,\n\"Marrilee\"\n,\n\"Marrin\"\n,\n\"Marriott\"\n,\n\"Marris\"\n,\n\"Marrissa\"\n,\n\"Marron\"\n,\n\"Mars\"\n,\n\"Marsden\"\n,\n\"Marsh\"\n,\n\"Marsha\"\n,\n\"Marshal\"\n,\n\"Marshall\"\n,\n\"Marsiella\"\n,\n\"Marsland\"\n,\n\"Marston\"\n,\n\"Mart\"\n,\n\"Marta\"\n,\n\"Martainn\"\n,\n\"Marte\"\n,\n\"Marteena\"\n,\n\"Martel\"\n,\n\"Martell\"\n,\n\"Martella\"\n,\n\"Martelle\"\n,\n\"Martelli\"\n,\n\"Marten\"\n,\n\"Martens\"\n,\n\"Martguerita\"\n,\n\"Martha\"\n,\n\"Marthe\"\n,\n\"Marthena\"\n,\n\"Marti\"\n,\n\"Martica\"\n,\n\"Martie\"\n,\n\"Martijn\"\n,\n\"Martin\"\n,\n\"Martina\"\n,\n\"Martine\"\n,\n\"Martineau\"\n,\n\"Martinelli\"\n,\n\"Martinez\"\n,\n\"Martinic\"\n,\n\"Martino\"\n,\n\"Martinsen\"\n,\n\"Martinson\"\n,\n\"Martita\"\n,\n\"Martres\"\n,\n\"Martsen\"\n,\n\"Marty\"\n,\n\"Martyn\"\n,\n\"Martynne\"\n,\n\"Martz\"\n,\n\"Marucci\"\n,\n\"Marutani\"\n,\n\"Marv\"\n,\n\"Marva\"\n,\n\"Marve\"\n,\n\"Marvel\"\n,\n\"Marvella\"\n,\n\"Marven\"\n,\n\"Marvin\"\n,\n\"Marwin\"\n,\n\"Marx\"\n,\n\"Mary\"\n,\n\"Marya\"\n,\n\"Maryann\"\n,\n\"Maryanna\"\n,\n\"Maryanne\"\n,\n\"Marybella\"\n,\n\"Marybelle\"\n,\n\"Marybeth\"\n,\n\"Maryellen\"\n,\n\"Maryjane\"\n,\n\"Maryjo\"\n,\n\"Maryl\"\n,\n\"Marylee\"\n,\n\"Marylin\"\n,\n\"Marylinda\"\n,\n\"Marylou\"\n,\n\"Maryly\"\n,\n\"Marylynne\"\n,\n\"Maryn\"\n,\n\"Maryrose\"\n,\n\"Marys\"\n,\n\"Marysa\"\n,\n\"Marzi\"\n,\n\"Mas\"\n,\n\"Masao\"\n,\n\"Mascia\"\n,\n\"Masera\"\n,\n\"Masha\"\n,\n\"Mashe\"\n,\n\"Mason\"\n,\n\"Masry\"\n,\n\"Massarelli\"\n,\n\"Massey\"\n,\n\"Massie\"\n,\n\"Massimiliano\"\n,\n\"Massimo\"\n,\n\"Massingill\"\n,\n\"Masson\"\n,\n\"Mast\"\n,\n\"Mastat\"\n,\n\"Masterson\"\n,\n\"Mastic\"\n,\n\"Mastrianni\"\n,\n\"Mat\"\n,\n\"Mata\"\n,\n\"Matazzoni\"\n,\n\"Matejka\"\n,\n\"Matelda\"\n,\n\"Mateo\"\n,\n\"Materi\"\n,\n\"Materse\"\n,\n\"Mateusz\"\n,\n\"Mateya\"\n,\n\"Mathe\"\n,\n\"Matheny\"\n,\n\"Mather\"\n,\n\"Matheson\"\n,\n\"Mathew\"\n,\n\"Mathews\"\n,\n\"Mathi\"\n,\n\"Mathia\"\n,\n\"Mathian\"\n,\n\"Mathias\"\n,\n\"Mathilda\"\n,\n\"Mathilde\"\n,\n\"Mathis\"\n,\n\"Mathre\"\n,\n\"Mathur\"\n,\n\"Matias\"\n,\n\"Matilda\"\n,\n\"Matilde\"\n,\n\"Matland\"\n,\n\"Matless\"\n,\n\"Matlick\"\n,\n\"Matrona\"\n,\n\"Matronna\"\n,\n\"Matt\"\n,\n\"Matta\"\n,\n\"Mattah\"\n,\n\"Matteo\"\n,\n\"Matthaeus\"\n,\n\"Matthaus\"\n,\n\"Matthei\"\n,\n\"Mattheus\"\n,\n\"Matthew\"\n,\n\"Matthews\"\n,\n\"Matthia\"\n,\n\"Matthias\"\n,\n\"Matthieu\"\n,\n\"Matthiew\"\n,\n\"Matthus\"\n,\n\"Matti\"\n,\n\"Mattias\"\n,\n\"Mattie\"\n,\n\"Mattland\"\n,\n\"Mattox\"\n,\n\"Mattson\"\n,\n\"Matty\"\n,\n\"Matusow\"\n,\n\"Mauceri\"\n,\n\"Mauchi\"\n,\n\"Maud\"\n,\n\"Maude\"\n,\n\"Maudie\"\n,\n\"Mauer\"\n,\n\"Mauldon\"\n,\n\"Maunsell\"\n,\n\"Maupin\"\n,\n\"Maura\"\n,\n\"Mauralia\"\n,\n\"Maure\"\n,\n\"Maureen\"\n,\n\"Maureene\"\n,\n\"Maurene\"\n,\n\"Maurer\"\n,\n\"Mauretta\"\n,\n\"Maurey\"\n,\n\"Mauri\"\n,\n\"Maurice\"\n,\n\"Mauricio\"\n,\n\"Maurie\"\n,\n\"Maurili\"\n,\n\"Maurilia\"\n,\n\"Maurilla\"\n,\n\"Maurine\"\n,\n\"Maurise\"\n,\n\"Maurita\"\n,\n\"Maurits\"\n,\n\"Maurizia\"\n,\n\"Maurizio\"\n,\n\"Mauro\"\n,\n\"Maurreen\"\n,\n\"Maury\"\n,\n\"Mauve\"\n,\n\"Mavilia\"\n,\n\"Mavis\"\n,\n\"Mavra\"\n,\n\"Max\"\n,\n\"Maxa\"\n,\n\"Maxama\"\n,\n\"Maxantia\"\n,\n\"Maxentia\"\n,\n\"Maxey\"\n,\n\"Maxfield\"\n,\n\"Maxi\"\n,\n\"Maxia\"\n,\n\"Maxie\"\n,\n\"Maxim\"\n,\n\"Maxima\"\n,\n\"Maximilian\"\n,\n\"Maximilianus\"\n,\n\"Maximilien\"\n,\n\"Maximo\"\n,\n\"Maxine\"\n,\n\"Maxma\"\n,\n\"Maxwell\"\n,\n\"Maxy\"\n,\n\"May\"\n,\n\"Maya\"\n,\n\"Maybelle\"\n,\n\"Mayberry\"\n,\n\"Mayce\"\n,\n\"Mayda\"\n,\n\"Maye\"\n,\n\"Mayeda\"\n,\n\"Mayer\"\n,\n\"Mayes\"\n,\n\"Mayfield\"\n,\n\"Mayhew\"\n,\n\"Mayman\"\n,\n\"Maynard\"\n,\n\"Mayne\"\n,\n\"Maynord\"\n,\n\"Mayor\"\n,\n\"Mays\"\n,\n\"Mayworm\"\n,\n\"Maze\"\n,\n\"Mazel\"\n,\n\"Maziar\"\n,\n\"Mazlack\"\n,\n\"Mazman\"\n,\n\"Mazonson\"\n,\n\"Mazur\"\n,\n\"Mazurek\"\n,\n\"McAdams\"\n,\n\"McAfee\"\n,\n\"McAllister\"\n,\n\"McArthur\"\n,\n\"McBride\"\n,\n\"McCafferty\"\n,\n\"McCahill\"\n,\n\"McCall\"\n,\n\"McCallion\"\n,\n\"McCallum\"\n,\n\"McCandless\"\n,\n\"McCartan\"\n,\n\"McCarthy\"\n,\n\"McCarty\"\n,\n\"McClain\"\n,\n\"McClary\"\n,\n\"McClees\"\n,\n\"McClelland\"\n,\n\"McClenaghan\"\n,\n\"McClenon\"\n,\n\"McClimans\"\n,\n\"McClish\"\n,\n\"McClure\"\n,\n\"McCollum\"\n,\n\"McComb\"\n,\n\"McConaghy\"\n,\n\"McConnell\"\n,\n\"McCord\"\n,\n\"McCormac\"\n,\n\"McCormick\"\n,\n\"McCourt\"\n,\n\"McCowyn\"\n,\n\"McCoy\"\n,\n\"McCready\"\n,\n\"McCreary\"\n,\n\"McCreery\"\n,\n\"McCulloch\"\n,\n\"McCullough\"\n,\n\"McCully\"\n,\n\"McCurdy\"\n,\n\"McCutcheon\"\n,\n\"McDade\"\n,\n\"McDermott\"\n,\n\"McDonald\"\n,\n\"McDougall\"\n,\n\"McDowell\"\n,\n\"McEvoy\"\n,\n\"McFadden\"\n,\n\"McFarland\"\n,\n\"McFerren\"\n,\n\"McGannon\"\n,\n\"McGaw\"\n,\n\"McGean\"\n,\n\"McGee\"\n,\n\"McGill\"\n,\n\"McGinnis\"\n,\n\"McGrath\"\n,\n\"McGraw\"\n,\n\"McGray\"\n,\n\"McGregor\"\n,\n\"McGrody\"\n,\n\"McGruter\"\n,\n\"McGuire\"\n,\n\"McGurn\"\n,\n\"McHail\"\n,\n\"McHale\"\n,\n\"McHenry\"\n,\n\"McHugh\"\n,\n\"McIlroy\"\n,\n\"McIntosh\"\n,\n\"McIntyre\"\n,\n\"McKale\"\n,\n\"McKay\"\n,\n\"McKee\"\n,\n\"McKenna\"\n,\n\"McKenzie\"\n,\n\"McKeon\"\n,\n\"McKinney\"\n,\n\"McKnight\"\n,\n\"McLain\"\n,\n\"McLaughlin\"\n,\n\"McLaurin\"\n,\n\"McLeod\"\n,\n\"McLeroy\"\n,\n\"McLoughlin\"\n,\n\"McLyman\"\n,\n\"McMahon\"\n,\n\"McMaster\"\n,\n\"McMath\"\n,\n\"McMillan\"\n,\n\"McMullan\"\n,\n\"McMurry\"\n,\n\"McNair\"\n,\n\"McNalley\"\n,\n\"McNally\"\n,\n\"McNamara\"\n,\n\"McNamee\"\n,\n\"McNeely\"\n,\n\"McNeil\"\n,\n\"McNelly\"\n,\n\"McNully\"\n,\n\"McNutt\"\n,\n\"McQuade\"\n,\n\"McQuillin\"\n,\n\"McQuoid\"\n,\n\"McRipley\"\n,\n\"McRoberts\"\n,\n\"McSpadden\"\n,\n\"McTyre\"\n,\n\"McWherter\"\n,\n\"McWilliams\"\n,\n\"Mead\"\n,\n\"Meade\"\n,\n\"Meador\"\n,\n\"Meadow\"\n,\n\"Meadows\"\n,\n\"Meagan\"\n,\n\"Meaghan\"\n,\n\"Meagher\"\n,\n\"Meakem\"\n,\n\"Means\"\n,\n\"Meara\"\n,\n\"Meares\"\n,\n\"Mears\"\n,\n\"Meave\"\n,\n\"Mechelle\"\n,\n\"Mechling\"\n,\n\"Mecke\"\n,\n\"Meda\"\n,\n\"Medarda\"\n,\n\"Medardas\"\n,\n\"Medea\"\n,\n\"Medeah\"\n,\n\"Medin\"\n,\n\"Medina\"\n,\n\"Medlin\"\n,\n\"Medor\"\n,\n\"Medora\"\n,\n\"Medorra\"\n,\n\"Medovich\"\n,\n\"Medrek\"\n,\n\"Medwin\"\n,\n\"Meece\"\n,\n\"Meehan\"\n,\n\"Meek\"\n,\n\"Meeker\"\n,\n\"Meeks\"\n,\n\"Meenen\"\n,\n\"Meg\"\n,\n\"Megan\"\n,\n\"Megargee\"\n,\n\"Megdal\"\n,\n\"Megen\"\n,\n\"Meggi\"\n,\n\"Meggie\"\n,\n\"Meggs\"\n,\n\"Meggy\"\n,\n\"Meghan\"\n,\n\"Meghann\"\n,\n\"Mehala\"\n,\n\"Mehalek\"\n,\n\"Mehalick\"\n,\n\"Mehetabel\"\n,\n\"Mehitable\"\n,\n\"Mehta\"\n,\n\"Mei\"\n,\n\"Meibers\"\n,\n\"Meier\"\n,\n\"Meijer\"\n,\n\"Meilen\"\n,\n\"Meill\"\n,\n\"Meingolda\"\n,\n\"Meingoldas\"\n,\n\"Meir\"\n,\n\"Meisel\"\n,\n\"Meit\"\n,\n\"Mel\"\n,\n\"Mela\"\n,\n\"Melamed\"\n,\n\"Melamie\"\n,\n\"Melan\"\n,\n\"Melania\"\n,\n\"Melanie\"\n,\n\"Melantha\"\n,\n\"Melany\"\n,\n\"Melar\"\n,\n\"Melba\"\n,\n\"Melborn\"\n,\n\"Melbourne\"\n,\n\"Melburn\"\n,\n\"Melcher\"\n,\n\"Melda\"\n,\n\"Meldoh\"\n,\n\"Meldon\"\n,\n\"Melena\"\n,\n\"Melentha\"\n,\n\"Melesa\"\n,\n\"Melessa\"\n,\n\"Meletius\"\n,\n\"Melgar\"\n,\n\"Meli\"\n,\n\"Melia\"\n,\n\"Melicent\"\n,\n\"Melina\"\n,\n\"Melinda\"\n,\n\"Melinde\"\n,\n\"Melisa\"\n,\n\"Melisande\"\n,\n\"Melisandra\"\n,\n\"Melise\"\n,\n\"Melisenda\"\n,\n\"Melisent\"\n,\n\"Melissa\"\n,\n\"Melisse\"\n,\n\"Melita\"\n,\n\"Melitta\"\n,\n\"Mell\"\n,\n\"Mella\"\n,\n\"Mellar\"\n,\n\"Mellen\"\n,\n\"Melleta\"\n,\n\"Mellette\"\n,\n\"Melli\"\n,\n\"Mellicent\"\n,\n\"Mellie\"\n,\n\"Mellins\"\n,\n\"Mellisa\"\n,\n\"Mellisent\"\n,\n\"Mellitz\"\n,\n\"Mellman\"\n,\n\"Mello\"\n,\n\"Melloney\"\n,\n\"Melly\"\n,\n\"Melmon\"\n,\n\"Melnick\"\n,\n\"Melodee\"\n,\n\"Melodie\"\n,\n\"Melody\"\n,\n\"Melone\"\n,\n\"Melonie\"\n,\n\"Melony\"\n,\n\"Melosa\"\n,\n\"Melquist\"\n,\n\"Melton\"\n,\n\"Melva\"\n,\n\"Melvena\"\n,\n\"Melville\"\n,\n\"Melvin\"\n,\n\"Melvina\"\n,\n\"Melvyn\"\n,\n\"Memberg\"\n,\n\"Memory\"\n,\n\"Mena\"\n,\n\"Menard\"\n,\n\"Menashem\"\n,\n\"Mencher\"\n,\n\"Mendel\"\n,\n\"Mendelsohn\"\n,\n\"Mendelson\"\n,\n\"Mendes\"\n,\n\"Mendez\"\n,\n\"Mendie\"\n,\n\"Mendive\"\n,\n\"Mendoza\"\n,\n\"Mendy\"\n,\n\"Meneau\"\n,\n\"Menedez\"\n,\n\"Menell\"\n,\n\"Menendez\"\n,\n\"Meng\"\n,\n\"Menides\"\n,\n\"Menis\"\n,\n\"Menken\"\n,\n\"Menon\"\n,\n\"Mensch\"\n,\n\"Menzies\"\n,\n\"Mera\"\n,\n\"Meraree\"\n,\n\"Merari\"\n,\n\"Meras\"\n,\n\"Merat\"\n,\n\"Merc\"\n,\n\"Mercado\"\n,\n\"Merce\"\n,\n\"Mercedes\"\n,\n\"Merceer\"\n,\n\"Mercer\"\n,\n\"Merchant\"\n,\n\"Merci\"\n,\n\"Mercie\"\n,\n\"Mercier\"\n,\n\"Mercola\"\n,\n\"Mercorr\"\n,\n\"Mercuri\"\n,\n\"Mercy\"\n,\n\"Merdith\"\n,\n\"Meredeth\"\n,\n\"Meredi\"\n,\n\"Meredith\"\n,\n\"Meredithe\"\n,\n\"Merell\"\n,\n\"Merete\"\n,\n\"Meri\"\n,\n\"Meridel\"\n,\n\"Merideth\"\n,\n\"Meridith\"\n,\n\"Meriel\"\n,\n\"Merilee\"\n,\n\"Merill\"\n,\n\"Merilyn\"\n,\n\"Meris\"\n,\n\"Merissa\"\n,\n\"Merkle\"\n,\n\"Merkley\"\n,\n\"Merl\"\n,\n\"Merla\"\n,\n\"Merle\"\n,\n\"Merlin\"\n,\n\"Merlina\"\n,\n\"Merline\"\n,\n\"Merna\"\n,\n\"Merola\"\n,\n\"Merow\"\n,\n\"Merralee\"\n,\n\"Merras\"\n,\n\"Merrel\"\n,\n\"Merrell\"\n,\n\"Merri\"\n,\n\"Merriam\"\n,\n\"Merrick\"\n,\n\"Merridie\"\n,\n\"Merrie\"\n,\n\"Merrielle\"\n,\n\"Merril\"\n,\n\"Merrile\"\n,\n\"Merrilee\"\n,\n\"Merrili\"\n,\n\"Merrill\"\n,\n\"Merrily\"\n,\n\"Merriman\"\n,\n\"Merriott\"\n,\n\"Merritt\"\n,\n\"Merrow\"\n,\n\"Merry\"\n,\n\"Mersey\"\n,\n\"Mert\"\n,\n\"Merta\"\n,\n\"Merth\"\n,\n\"Merton\"\n,\n\"Merv\"\n,\n\"Mervin\"\n,\n\"Merwin\"\n,\n\"Merwyn\"\n,\n\"Meryl\"\n,\n\"Mesics\"\n,\n\"Messere\"\n,\n\"Messing\"\n,\n\"Meta\"\n,\n\"Metabel\"\n,\n\"Metcalf\"\n,\n\"Meter\"\n,\n\"Methuselah\"\n,\n\"Metsky\"\n,\n\"Mettah\"\n,\n\"Metts\"\n,\n\"Metzgar\"\n,\n\"Metzger\"\n,\n\"Meunier\"\n,\n\"Meurer\"\n,\n\"Meuse\"\n,\n\"Meuser\"\n,\n\"Meyer\"\n,\n\"Meyeroff\"\n,\n\"Meyers\"\n,\n\"Mezoff\"\n,\n\"Mia\"\n,\n\"Mic\"\n,\n\"Micaela\"\n,\n\"Micah\"\n,\n\"Micco\"\n,\n\"Mich\"\n,\n\"Michael\"\n,\n\"Michaela\"\n,\n\"Michaele\"\n,\n\"Michaelina\"\n,\n\"Michaeline\"\n,\n\"Michaella\"\n,\n\"Michaeu\"\n,\n\"Michail\"\n,\n\"Michal\"\n,\n\"Michale\"\n,\n\"Michaud\"\n,\n\"Miche\"\n,\n\"Micheal\"\n,\n\"Micheil\"\n,\n\"Michel\"\n,\n\"Michele\"\n,\n\"Michelina\"\n,\n\"Micheline\"\n,\n\"Michell\"\n,\n\"Michella\"\n,\n\"Michelle\"\n,\n\"Michelsen\"\n,\n\"Michey\"\n,\n\"Michi\"\n,\n\"Michigan\"\n,\n\"Michiko\"\n,\n\"Michon\"\n,\n\"Mick\"\n,\n\"Mickelson\"\n,\n\"Mickey\"\n,\n\"Micki\"\n,\n\"Mickie\"\n,\n\"Micky\"\n,\n\"Micro\"\n,\n\"Miculek\"\n,\n\"Midas\"\n,\n\"Middendorf\"\n,\n\"Middle\"\n,\n\"Middlesworth\"\n,\n\"Middleton\"\n,\n\"Mide\"\n,\n\"Midge\"\n,\n\"Midian\"\n,\n\"Midis\"\n,\n\"Mientao\"\n,\n\"Miett\"\n,\n\"Migeon\"\n,\n\"Mighell\"\n,\n\"Mignon\"\n,\n\"Mignonne\"\n,\n\"Miguel\"\n,\n\"Miguela\"\n,\n\"Miguelita\"\n,\n\"Mihalco\"\n,\n\"Mihe\"\n,\n\"Mika\"\n,\n\"Mikael\"\n,\n\"Mikaela\"\n,\n\"Mikal\"\n,\n\"Mike\"\n,\n\"Mikel\"\n,\n\"Mikes\"\n,\n\"Mikey\"\n,\n\"Miki\"\n,\n\"Mikihisa\"\n,\n\"Mikiso\"\n,\n\"Mikkanen\"\n,\n\"Mikkel\"\n,\n\"Miko\"\n,\n\"Mikol\"\n,\n\"Miksen\"\n,\n\"Mil\"\n,\n\"Mila\"\n,\n\"Milan\"\n,\n\"Milano\"\n,\n\"Milburn\"\n,\n\"Milburr\"\n,\n\"Milburt\"\n,\n\"Milda\"\n,\n\"Milde\"\n,\n\"Mildred\"\n,\n\"Mildrid\"\n,\n\"Mile\"\n,\n\"Milena\"\n,\n\"Miles\"\n,\n\"Milewski\"\n,\n\"Milford\"\n,\n\"Milicent\"\n,\n\"Milinda\"\n,\n\"Milissa\"\n,\n\"Milissent\"\n,\n\"Milka\"\n,\n\"Milks\"\n,\n\"Mill\"\n,\n\"Milla\"\n,\n\"Millan\"\n,\n\"Millar\"\n,\n\"Millard\"\n,\n\"Millburn\"\n,\n\"Millda\"\n,\n\"Miller\"\n,\n\"Millford\"\n,\n\"Millham\"\n,\n\"Millhon\"\n,\n\"Milli\"\n,\n\"Millian\"\n,\n\"Millicent\"\n,\n\"Millie\"\n,\n\"Millisent\"\n,\n\"Millman\"\n,\n\"Mills\"\n,\n\"Millur\"\n,\n\"Millwater\"\n,\n\"Milly\"\n,\n\"Milman\"\n,\n\"Milo\"\n,\n\"Milon\"\n,\n\"Milone\"\n,\n\"Milore\"\n,\n\"Milson\"\n,\n\"Milstone\"\n,\n\"Milt\"\n,\n\"Miltie\"\n,\n\"Milton\"\n,\n\"Milty\"\n,\n\"Milurd\"\n,\n\"Milzie\"\n,\n\"Mima\"\n,\n\"Mimi\"\n,\n\"Min\"\n,\n\"Mina\"\n,\n\"Minabe\"\n,\n\"Minardi\"\n,\n\"Minda\"\n,\n\"Mindi\"\n,\n\"Mindy\"\n,\n\"Miner\"\n,\n\"Minerva\"\n,\n\"Mines\"\n,\n\"Minetta\"\n,\n\"Minette\"\n,\n\"Ming\"\n,\n\"Mingche\"\n,\n\"Mini\"\n,\n\"Minica\"\n,\n\"Minier\"\n,\n\"Minna\"\n,\n\"Minnaminnie\"\n,\n\"Minne\"\n,\n\"Minni\"\n,\n\"Minnie\"\n,\n\"Minnnie\"\n,\n\"Minny\"\n,\n\"Minor\"\n,\n\"Minoru\"\n,\n\"Minsk\"\n,\n\"Minta\"\n,\n\"Minton\"\n,\n\"Mintun\"\n,\n\"Mintz\"\n,\n\"Miof Mela\"\n,\n\"Miquela\"\n,\n\"Mir\"\n,\n\"Mira\"\n,\n\"Mirabel\"\n,\n\"Mirabella\"\n,\n\"Mirabelle\"\n,\n\"Miran\"\n,\n\"Miranda\"\n,\n\"Mireielle\"\n,\n\"Mireille\"\n,\n\"Mirella\"\n,\n\"Mirelle\"\n,\n\"Miriam\"\n,\n\"Mirielle\"\n,\n\"Mirilla\"\n,\n\"Mirisola\"\n,\n\"Mirna\"\n,\n\"Mirth\"\n,\n\"Miru\"\n,\n\"Mischa\"\n,\n\"Misha\"\n,\n\"Mishaan\"\n,\n\"Missi\"\n,\n\"Missie\"\n,\n\"Missy\"\n,\n\"Misti\"\n,\n\"Mistrot\"\n,\n\"Misty\"\n,\n\"Mita\"\n,\n\"Mitch\"\n,\n\"Mitchael\"\n,\n\"Mitchel\"\n,\n\"Mitchell\"\n,\n\"Mitchiner\"\n,\n\"Mitinger\"\n,\n\"Mitman\"\n,\n\"Mitran\"\n,\n\"Mittel\"\n,\n\"Mitzi\"\n,\n\"Mitzie\"\n,\n\"Mitzl\"\n,\n\"Miun\"\n,\n\"Mixie\"\n,\n\"Miyasawa\"\n,\n\"Mizuki\"\n,\n\"Mlawsky\"\n,\n\"Mllly\"\n,\n\"Moazami\"\n,\n\"Moberg\"\n,\n\"Mobley\"\n,\n\"Mochun\"\n,\n\"Mode\"\n,\n\"Modern\"\n,\n\"Modesta\"\n,\n\"Modeste\"\n,\n\"Modestia\"\n,\n\"Modestine\"\n,\n\"Modesty\"\n,\n\"Modie\"\n,\n\"Modla\"\n,\n\"Moe\"\n,\n\"Moersch\"\n,\n\"Moffat\"\n,\n\"Moffit\"\n,\n\"Moffitt\"\n,\n\"Mogerly\"\n,\n\"Moguel\"\n,\n\"Mohamed\"\n,\n\"Mohammad\"\n,\n\"Mohammed\"\n,\n\"Mohandas\"\n,\n\"Mohandis\"\n,\n\"Mohl\"\n,\n\"Mohn\"\n,\n\"Mohr\"\n,\n\"Mohsen\"\n,\n\"Mohun\"\n,\n\"Moia\"\n,\n\"Moina\"\n,\n\"Moir\"\n,\n\"Moira\"\n,\n\"Moise\"\n,\n\"Moises\"\n,\n\"Moishe\"\n,\n\"Moitoso\"\n,\n\"Mojgan\"\n,\n\"Mok\"\n,\n\"Mokas\"\n,\n\"Molini\"\n,\n\"Moll\"\n,\n\"Mollee\"\n,\n\"Molli\"\n,\n\"Mollie\"\n,\n\"Molloy\"\n,\n\"Molly\"\n,\n\"Molton\"\n,\n\"Mommy\"\n,\n\"Mona\"\n,\n\"Monaco\"\n,\n\"Monafo\"\n,\n\"Monagan\"\n,\n\"Monah\"\n,\n\"Monahan\"\n,\n\"Monahon\"\n,\n\"Monarski\"\n,\n\"Moncear\"\n,\n\"Mond\"\n,\n\"Monda\"\n,\n\"Moneta\"\n,\n\"Monetta\"\n,\n\"Mongeau\"\n,\n\"Monia\"\n,\n\"Monica\"\n,\n\"Monie\"\n,\n\"Monika\"\n,\n\"Monique\"\n,\n\"Monjan\"\n,\n\"Monjo\"\n,\n\"Monk\"\n,\n\"Monney\"\n,\n\"Monreal\"\n,\n\"Monro\"\n,\n\"Monroe\"\n,\n\"Monroy\"\n,\n\"Monson\"\n,\n\"Monsour\"\n,\n\"Mont\"\n,\n\"Montagna\"\n,\n\"Montagu\"\n,\n\"Montague\"\n,\n\"Montana\"\n,\n\"Montanez\"\n,\n\"Montano\"\n,\n\"Monte\"\n,\n\"Monteith\"\n,\n\"Monteria\"\n,\n\"Montford\"\n,\n\"Montfort\"\n,\n\"Montgomery\"\n,\n\"Monti\"\n,\n\"Monto\"\n,\n\"Monty\"\n,\n\"Moody\"\n,\n\"Mook\"\n,\n\"Moon\"\n,\n\"Mooney\"\n,\n\"Moonier\"\n,\n\"Moor\"\n,\n\"Moore\"\n,\n\"Moorefield\"\n,\n\"Moorish\"\n,\n\"Mor\"\n,\n\"Mora\"\n,\n\"Moran\"\n,\n\"Mord\"\n,\n\"Mordecai\"\n,\n\"Mordy\"\n,\n\"Moreen\"\n,\n\"Morehouse\"\n,\n\"Morel\"\n,\n\"Moreland\"\n,\n\"Morell\"\n,\n\"Morena\"\n,\n\"Moreno\"\n,\n\"Morentz\"\n,\n\"Moreta\"\n,\n\"Moretta\"\n,\n\"Morette\"\n,\n\"Moreville\"\n,\n\"Morey\"\n,\n\"Morez\"\n,\n\"Morgan\"\n,\n\"Morgana\"\n,\n\"Morganica\"\n,\n\"Morganne\"\n,\n\"Morganstein\"\n,\n\"Morgen\"\n,\n\"Morgenthaler\"\n,\n\"Morgun\"\n,\n\"Mori\"\n,\n\"Moria\"\n,\n\"Moriah\"\n,\n\"Moriarty\"\n,\n\"Morice\"\n,\n\"Morie\"\n,\n\"Morissa\"\n,\n\"Morita\"\n,\n\"Moritz\"\n,\n\"Moriyama\"\n,\n\"Morlee\"\n,\n\"Morley\"\n,\n\"Morly\"\n,\n\"Morna\"\n,\n\"Morocco\"\n,\n\"Morra\"\n,\n\"Morrell\"\n,\n\"Morrie\"\n,\n\"Morril\"\n,\n\"Morrill\"\n,\n\"Morris\"\n,\n\"Morrison\"\n,\n\"Morrissey\"\n,\n\"Morry\"\n,\n\"Morse\"\n,\n\"Mort\"\n,\n\"Morten\"\n,\n\"Mortensen\"\n,\n\"Mortie\"\n,\n\"Mortimer\"\n,\n\"Morton\"\n,\n\"Morty\"\n,\n\"Morven\"\n,\n\"Morville\"\n,\n\"Morvin\"\n,\n\"Mosa\"\n,\n\"Mosby\"\n,\n\"Moscow\"\n,\n\"Mose\"\n,\n\"Moseley\"\n,\n\"Moselle\"\n,\n\"Mosenthal\"\n,\n\"Moser\"\n,\n\"Mosera\"\n,\n\"Moses\"\n,\n\"Moshe\"\n,\n\"Moshell\"\n,\n\"Mosier\"\n,\n\"Mosira\"\n,\n\"Moskow\"\n,\n\"Mosley\"\n,\n\"Mosora\"\n,\n\"Mosra\"\n,\n\"Moss\"\n,\n\"Mossberg\"\n,\n\"Mossman\"\n,\n\"Most\"\n,\n\"Motch\"\n,\n\"Moth\"\n,\n\"Mott\"\n,\n\"Motteo\"\n,\n\"Mou\"\n,\n\"Moulden\"\n,\n\"Mouldon\"\n,\n\"Moule\"\n,\n\"Moulton\"\n,\n\"Mount\"\n,\n\"Mountford\"\n,\n\"Mountfort\"\n,\n\"Mourant\"\n,\n\"Moureaux\"\n,\n\"Mowbray\"\n,\n\"Moya\"\n,\n\"Moyer\"\n,\n\"Moyers\"\n,\n\"Moyna\"\n,\n\"Moynahan\"\n,\n\"Moyra\"\n,\n\"Mozart\"\n,\n\"Mozelle\"\n,\n\"Mozes\"\n,\n\"Mozza\"\n,\n\"Mraz\"\n,\n\"Mroz\"\n,\n\"Mueller\"\n,\n\"Muffin\"\n,\n\"Mufi\"\n,\n\"Mufinella\"\n,\n\"Muhammad\"\n,\n\"Muir\"\n,\n\"Muire\"\n,\n\"Muirhead\"\n,\n\"Mukerji\"\n,\n\"Mukul\"\n,\n\"Mukund\"\n,\n\"Mulcahy\"\n,\n\"Mulderig\"\n,\n\"Muldon\"\n,\n\"Mulford\"\n,\n\"Mullane\"\n,\n\"Mullen\"\n,\n\"Muller\"\n,\n\"Mulligan\"\n,\n\"Mullins\"\n,\n\"Mulloy\"\n,\n\"Mulry\"\n,\n\"Mulvihill\"\n,\n\"Mumford\"\n,\n\"Mun\"\n,\n\"Muna\"\n,\n\"Munafo\"\n,\n\"Muncey\"\n,\n\"Mundford\"\n,\n\"Mundt\"\n,\n\"Mundy\"\n,\n\"Munford\"\n,\n\"Mungo\"\n,\n\"Mungovan\"\n,\n\"Munmro\"\n,\n\"Munn\"\n,\n\"Munniks\"\n,\n\"Munro\"\n,\n\"Munroe\"\n,\n\"Muns\"\n,\n\"Munsey\"\n,\n\"Munshi\"\n,\n\"Munson\"\n,\n\"Munster\"\n,\n\"Munt\"\n,\n\"Mur\"\n,\n\"Murage\"\n,\n\"Muraida\"\n,\n\"Murat\"\n,\n\"Murdocca\"\n,\n\"Murdoch\"\n,\n\"Murdock\"\n,\n\"Mureil\"\n,\n\"Muriah\"\n,\n\"Murial\"\n,\n\"Muriel\"\n,\n\"Murielle\"\n,\n\"Murphy\"\n,\n\"Murrah\"\n,\n\"Murray\"\n,\n\"Murrell\"\n,\n\"Murry\"\n,\n\"Murtagh\"\n,\n\"Murtha\"\n,\n\"Murton\"\n,\n\"Murvyn\"\n,\n\"Musa\"\n,\n\"Muscolo\"\n,\n\"Musetta\"\n,\n\"Musette\"\n,\n\"Mushro\"\n,\n\"Muslim\"\n,\n\"Musser\"\n,\n\"Mussman\"\n,\n\"Mutz\"\n,\n\"My\"\n,\n\"Mya\"\n,\n\"Myca\"\n,\n\"Mycah\"\n,\n\"Mychael\"\n,\n\"Mychal\"\n,\n\"Myer\"\n,\n\"Myers\"\n,\n\"Myke\"\n,\n\"Mylan\"\n,\n\"Mylander\"\n,\n\"Myles\"\n,\n\"Mylo\"\n,\n\"Mylor\"\n,\n\"Myna\"\n,\n\"Myo\"\n,\n\"Myra\"\n,\n\"Myrah\"\n,\n\"Myranda\"\n,\n\"Myriam\"\n,\n\"Myrilla\"\n,\n\"Myrle\"\n,\n\"Myrlene\"\n,\n\"Myrna\"\n,\n\"Myron\"\n,\n\"Myrt\"\n,\n\"Myrta\"\n,\n\"Myrtia\"\n,\n\"Myrtice\"\n,\n\"Myrtie\"\n,\n\"Myrtle\"\n,\n\"Myrvyn\"\n,\n\"Myrwyn\"\n,\n\"Na\"\n,\n\"Naam\"\n,\n\"Naaman\"\n,\n\"Naamana\"\n,\n\"Naamann\"\n,\n\"Naara\"\n,\n\"Naarah\"\n,\n\"Naashom\"\n,\n\"Nabal\"\n,\n\"Nabala\"\n,\n\"Nabalas\"\n,\n\"Nabila\"\n,\n\"Nace\"\n,\n\"Nachison\"\n,\n\"Nada\"\n,\n\"Nadab\"\n,\n\"Nadaba\"\n,\n\"Nadabas\"\n,\n\"Nadabb\"\n,\n\"Nadabus\"\n,\n\"Nadaha\"\n,\n\"Nadbus\"\n,\n\"Nadda\"\n,\n\"Nadean\"\n,\n\"Nadeau\"\n,\n\"Nadeen\"\n,\n\"Nader\"\n,\n\"Nadia\"\n,\n\"Nadine\"\n,\n\"Nadiya\"\n,\n\"Nadler\"\n,\n\"Nador\"\n,\n\"Nady\"\n,\n\"Nadya\"\n,\n\"Nafis\"\n,\n\"Naga\"\n,\n\"Nagel\"\n,\n\"Nagey\"\n,\n\"Nagle\"\n,\n\"Nagy\"\n,\n\"Nahama\"\n,\n\"Nahamas\"\n,\n\"Nahshon\"\n,\n\"Nahshu\"\n,\n\"Nahshun\"\n,\n\"Nahshunn\"\n,\n\"Nahtanha\"\n,\n\"Nahum\"\n,\n\"Naiditch\"\n,\n\"Naima\"\n,\n\"Naji\"\n,\n\"Nakada\"\n,\n\"Nakashima\"\n,\n\"Nakasuji\"\n,\n\"Nalani\"\n,\n\"Nalda\"\n,\n\"Naldo\"\n,\n\"Nalepka\"\n,\n\"Nally\"\n,\n\"Nalor\"\n,\n\"Nam\"\n,\n\"Naman\"\n,\n\"Namara\"\n,\n\"Names\"\n,\n\"Nan\"\n,\n\"Nana\"\n,\n\"Nananne\"\n,\n\"Nance\"\n,\n\"Nancee\"\n,\n\"Nancey\"\n,\n\"Nanci\"\n,\n\"Nancie\"\n,\n\"Nancy\"\n,\n\"Nandor\"\n,\n\"Nanete\"\n,\n\"Nanette\"\n,\n\"Nani\"\n,\n\"Nanice\"\n,\n\"Nanine\"\n,\n\"Nanji\"\n,\n\"Nannette\"\n,\n\"Nanni\"\n,\n\"Nannie\"\n,\n\"Nanny\"\n,\n\"Nanon\"\n,\n\"Naoma\"\n,\n\"Naomi\"\n,\n\"Naor\"\n,\n\"Nap\"\n,\n\"Napier\"\n,\n\"Naples\"\n,\n\"Napoleon\"\n,\n\"Nappie\"\n,\n\"Nappy\"\n,\n\"Naquin\"\n,\n\"Nara\"\n,\n\"Narah\"\n,\n\"Narayan\"\n,\n\"Narcho\"\n,\n\"Narcis\"\n,\n\"Narcissus\"\n,\n\"Narda\"\n,\n\"Naresh\"\n,\n\"Nari\"\n,\n\"Nariko\"\n,\n\"Narine\"\n,\n\"Narra\"\n,\n\"Narton\"\n,\n\"Nary\"\n,\n\"Nash\"\n,\n\"Nashbar\"\n,\n\"Nashner\"\n,\n\"Nasho\"\n,\n\"Nashom\"\n,\n\"Nashoma\"\n,\n\"Nasia\"\n,\n\"Nason\"\n,\n\"Nassi\"\n,\n\"Nassir\"\n,\n\"Nastassia\"\n,\n\"Nasya\"\n,\n\"Nat\"\n,\n\"Nata\"\n,\n\"Natal\"\n,\n\"Natala\"\n,\n\"Natale\"\n,\n\"Natalee\"\n,\n\"Natalia\"\n,\n\"Natalie\"\n,\n\"Natalina\"\n,\n\"Nataline\"\n,\n\"Natalya\"\n,\n\"Nataniel\"\n,\n\"Natascha\"\n,\n\"Natasha\"\n,\n\"Natassia\"\n,\n\"Nate\"\n,\n\"Natelson\"\n,\n\"Nath\"\n,\n\"Nathalia\"\n,\n\"Nathalie\"\n,\n\"Nathan\"\n,\n\"Nathanael\"\n,\n\"Nathanial\"\n,\n\"Nathaniel\"\n,\n\"Nathanil\"\n,\n\"Nathanson\"\n,\n\"Natica\"\n,\n\"Natie\"\n,\n\"Natiha\"\n,\n\"Natika\"\n,\n\"Nations\"\n,\n\"Natividad\"\n,\n\"Natka\"\n,\n\"Nattie\"\n,\n\"Natty\"\n,\n\"Nava\"\n,\n\"Navada\"\n,\n\"Naval\"\n,\n\"Navarro\"\n,\n\"Nawrocki\"\n,\n\"Nay\"\n,\n\"Naylor\"\n,\n\"Nazar\"\n,\n\"Nazario\"\n,\n\"Nazarius\"\n,\n\"Nazler\"\n,\n\"Nea\"\n,\n\"Neal\"\n,\n\"Neala\"\n,\n\"Nealah\"\n,\n\"Neale\"\n,\n\"Nealey\"\n,\n\"Neall\"\n,\n\"Nealon\"\n,\n\"Nealson\"\n,\n\"Nealy\"\n,\n\"Neau\"\n,\n\"Ned\"\n,\n\"Neda\"\n,\n\"Nedda\"\n,\n\"Neddie\"\n,\n\"Neddra\"\n,\n\"Neddy\"\n,\n\"Nedi\"\n,\n\"Nedra\"\n,\n\"Nedrah\"\n,\n\"Nedrud\"\n,\n\"Nedry\"\n,\n\"Nee\"\n,\n\"Neel\"\n,\n\"Neela\"\n,\n\"Neelon\"\n,\n\"Neely\"\n,\n\"Neeoma\"\n,\n\"Nefen\"\n,\n\"Neff\"\n,\n\"Negris\"\n,\n\"Nehemiah\"\n,\n\"Neibart\"\n,\n\"Neidhardt\"\n,\n\"Neil\"\n,\n\"Neila\"\n,\n\"Neile\"\n,\n\"Neill\"\n,\n\"Neilla\"\n,\n\"Neille\"\n,\n\"Neils\"\n,\n\"Neilson\"\n,\n\"Neiman\"\n,\n\"Neisa\"\n,\n\"Nel\"\n,\n\"Nela\"\n,\n\"Nelan\"\n,\n\"Nelda\"\n,\n\"Nelia\"\n,\n\"Nelie\"\n,\n\"Nell\"\n,\n\"Nella\"\n,\n\"Nellda\"\n,\n\"Nelle\"\n,\n\"Nelli\"\n,\n\"Nellie\"\n,\n\"Nellir\"\n,\n\"Nelly\"\n,\n\"Nelrsa\"\n,\n\"Nels\"\n,\n\"Nelsen\"\n,\n\"Nelson\"\n,\n\"Nema\"\n,\n\"Nemhauser\"\n,\n\"Nena\"\n,\n\"Nenney\"\n,\n\"Neo\"\n,\n\"Neom\"\n,\n\"Neoma\"\n,\n\"Neomah\"\n,\n\"Neona\"\n,\n\"Nepean\"\n,\n\"Nepil\"\n,\n\"Nereen\"\n,\n\"Nereids\"\n,\n\"Nereus\"\n,\n\"Neri\"\n,\n\"Nerin\"\n,\n\"Nerine\"\n,\n\"Nerissa\"\n,\n\"Nerita\"\n,\n\"Nerland\"\n,\n\"Nero\"\n,\n\"Neron\"\n,\n\"Nert\"\n,\n\"Nerta\"\n,\n\"Nerte\"\n,\n\"Nerti\"\n,\n\"Nertie\"\n,\n\"Nerty\"\n,\n\"Nesbitt\"\n,\n\"Nesline\"\n,\n\"Neslund\"\n,\n\"Ness\"\n,\n\"Nessa\"\n,\n\"Nessi\"\n,\n\"Nessie\"\n,\n\"Nessim\"\n,\n\"Nessy\"\n,\n\"Nesta\"\n,\n\"Nester\"\n,\n\"Nesto\"\n,\n\"Nestor\"\n,\n\"Nett\"\n,\n\"Netta\"\n,\n\"Nette\"\n,\n\"Netti\"\n,\n\"Nettie\"\n,\n\"Nettle\"\n,\n\"Netty\"\n,\n\"Neu\"\n,\n\"Neuberger\"\n,\n\"Neuburger\"\n,\n\"Neufer\"\n,\n\"Neukam\"\n,\n\"Neumann\"\n,\n\"Neumark\"\n,\n\"Neumeyer\"\n,\n\"Neurath\"\n,\n\"Nev\"\n,\n\"Neva\"\n,\n\"Nevada\"\n,\n\"Nevai\"\n,\n\"Neve\"\n,\n\"Neveda\"\n,\n\"Nevil\"\n,\n\"Nevile\"\n,\n\"Neville\"\n,\n\"Nevin\"\n,\n\"Nevins\"\n,\n\"Nevlin\"\n,\n\"Nevsa\"\n,\n\"New\"\n,\n\"Newberry\"\n,\n\"Newbill\"\n,\n\"Newbold\"\n,\n\"Newby\"\n,\n\"Newcomb\"\n,\n\"Newcomer\"\n,\n\"Newel\"\n,\n\"Newell\"\n,\n\"Newfeld\"\n,\n\"Newhall\"\n,\n\"Newkirk\"\n,\n\"Newlin\"\n,\n\"Newman\"\n,\n\"Newmann\"\n,\n\"Newmark\"\n,\n\"Newsom\"\n,\n\"Newton\"\n,\n\"Neysa\"\n,\n\"Ng\"\n,\n\"Ngo\"\n,\n\"Nguyen\"\n,\n\"Niabi\"\n,\n\"Nial\"\n,\n\"Niall\"\n,\n\"Nibbs\"\n,\n\"Nic\"\n,\n\"Nica\"\n,\n\"Niccolo\"\n,\n\"Nich\"\n,\n\"Nichani\"\n,\n\"Nichol\"\n,\n\"Nichola\"\n,\n\"Nicholas\"\n,\n\"Nichole\"\n,\n\"Nicholl\"\n,\n\"Nicholle\"\n,\n\"Nichols\"\n,\n\"Nicholson\"\n,\n\"Nichy\"\n,\n\"Nick\"\n,\n\"Nickelsen\"\n,\n\"Nickerson\"\n,\n\"Nickey\"\n,\n\"Nicki\"\n,\n\"Nickie\"\n,\n\"Nickles\"\n,\n\"Nicko\"\n,\n\"Nickola\"\n,\n\"Nickolai\"\n,\n\"Nickolas\"\n,\n\"Nickolaus\"\n,\n\"Nicks\"\n,\n\"Nicky\"\n,\n\"Nico\"\n,\n\"Nicodemus\"\n,\n\"Nicol\"\n,\n\"Nicola\"\n,\n\"Nicolai\"\n,\n\"Nicolais\"\n,\n\"Nicolas\"\n,\n\"Nicolau\"\n,\n\"Nicole\"\n,\n\"Nicolea\"\n,\n\"Nicolella\"\n,\n\"Nicolette\"\n,\n\"Nicoli\"\n,\n\"Nicolina\"\n,\n\"Nicoline\"\n,\n\"Nicolis\"\n,\n\"Nicolle\"\n,\n\"Nidia\"\n,\n\"Nidorf\"\n,\n\"Nieberg\"\n,\n\"Niehaus\"\n,\n\"Niel\"\n,\n\"Niela\"\n,\n\"Niels\"\n,\n\"Nielsen\"\n,\n\"Nielson\"\n,\n\"Nierman\"\n,\n\"Nies\"\n,\n\"Nievelt\"\n,\n\"Nigel\"\n,\n\"Nightingale\"\n,\n\"Nihhi\"\n,\n\"Nihi\"\n,\n\"Nika\"\n,\n\"Nikaniki\"\n,\n\"Nike\"\n,\n\"Niki\"\n,\n\"Nikita\"\n,\n\"Nikki\"\n,\n\"Nikkie\"\n,\n\"Niklaus\"\n,\n\"Niko\"\n,\n\"Nikola\"\n,\n\"Nikolai\"\n,\n\"Nikolaos\"\n,\n\"Nikolas\"\n,\n\"Nikolaus\"\n,\n\"Nikoletta\"\n,\n\"Nikolia\"\n,\n\"Nikolos\"\n,\n\"Nikos\"\n,\n\"Nil\"\n,\n\"Nila\"\n,\n\"Nile\"\n,\n\"Niles\"\n,\n\"Nilla\"\n,\n\"Nils\"\n,\n\"Nilson\"\n,\n\"Nimesh\"\n,\n\"Nimocks\"\n,\n\"Nims\"\n,\n\"Nina\"\n,\n\"Nine\"\n,\n\"Ninetta\"\n,\n\"Ninette\"\n,\n\"Ninnetta\"\n,\n\"Ninnette\"\n,\n\"Nino\"\n,\n\"Ninon\"\n,\n\"Ninos\"\n,\n\"Niobe\"\n,\n\"Nipha\"\n,\n\"Niple\"\n,\n\"Nisa\"\n,\n\"Nisbet\"\n,\n\"Nisen\"\n,\n\"Nishi\"\n,\n\"Nissa\"\n,\n\"Nisse\"\n,\n\"Nissensohn\"\n,\n\"Nissie\"\n,\n\"Nissy\"\n,\n\"Nita\"\n,\n\"Nitin\"\n,\n\"Nitz\"\n,\n\"Nitza\"\n,\n\"Niu\"\n,\n\"Niven\"\n,\n\"Nixie\"\n,\n\"Nixon\"\n,\n\"Noach\"\n,\n\"Noah\"\n,\n\"Noak\"\n,\n\"Noakes\"\n,\n\"Noam\"\n,\n\"Noami\"\n,\n\"Nobe\"\n,\n\"Nobel\"\n,\n\"Nobell\"\n,\n\"Nobie\"\n,\n\"Nobile\"\n,\n\"Noble\"\n,\n\"Noby\"\n,\n\"Nochur\"\n,\n\"Nodab\"\n,\n\"Nodababus\"\n,\n\"Nodarse\"\n,\n\"Noe\"\n,\n\"Noel\"\n,\n\"Noelani\"\n,\n\"Noell\"\n,\n\"Noella\"\n,\n\"Noelle\"\n,\n\"Noellyn\"\n,\n\"Noelyn\"\n,\n\"Noemi\"\n,\n\"Nogas\"\n,\n\"Noguchi\"\n,\n\"Nola\"\n,\n\"Nolan\"\n,\n\"Nolana\"\n,\n\"Noland\"\n,\n\"Nole\"\n,\n\"Noleta\"\n,\n\"Noletta\"\n,\n\"Noli\"\n,\n\"Nolie\"\n,\n\"Nolita\"\n,\n\"Nolitta\"\n,\n\"Noll\"\n,\n\"Nollie\"\n,\n\"Nolly\"\n,\n\"Nolte\"\n,\n\"Noma\"\n,\n\"Noman\"\n,\n\"Nomi\"\n,\n\"Nona\"\n,\n\"Nonah\"\n,\n\"Noni\"\n,\n\"Nonie\"\n,\n\"Nonna\"\n,\n\"Nonnah\"\n,\n\"Noonan\"\n,\n\"Noonberg\"\n,\n\"Nor\"\n,\n\"Nora\"\n,\n\"Norah\"\n,\n\"Norbert\"\n,\n\"Norbie\"\n,\n\"Norby\"\n,\n\"Nord\"\n,\n\"Nordgren\"\n,\n\"Nordin\"\n,\n\"Nordine\"\n,\n\"Nore\"\n,\n\"Norean\"\n,\n\"Noreen\"\n,\n\"Norene\"\n,\n\"Norford\"\n,\n\"Norina\"\n,\n\"Norine\"\n,\n\"Norita\"\n,\n\"Nork\"\n,\n\"Norling\"\n,\n\"Norm\"\n,\n\"Norma\"\n,\n\"Normalie\"\n,\n\"Norman\"\n,\n\"Normand\"\n,\n\"Normandy\"\n,\n\"Normi\"\n,\n\"Normie\"\n,\n\"Normy\"\n,\n\"Norri\"\n,\n\"Norrie\"\n,\n\"Norris\"\n,\n\"Norrv\"\n,\n\"Norry\"\n,\n\"Norse\"\n,\n\"North\"\n,\n\"Northey\"\n,\n\"Northington\"\n,\n\"Northrop\"\n,\n\"Northrup\"\n,\n\"Northway\"\n,\n\"Norton\"\n,\n\"Norty\"\n,\n\"Norval\"\n,\n\"Norvall\"\n,\n\"Norvan\"\n,\n\"Norvell\"\n,\n\"Norven\"\n,\n\"Norvil\"\n,\n\"Norvin\"\n,\n\"Norvol\"\n,\n\"Norvun\"\n,\n\"Norward\"\n,\n\"Norwood\"\n,\n\"Norword\"\n,\n\"Nottage\"\n,\n\"Nova\"\n,\n\"Novah\"\n,\n\"Novak\"\n,\n\"Novelia\"\n,\n\"Novello\"\n,\n\"Novia\"\n,\n\"Novick\"\n,\n\"Novikoff\"\n,\n\"Nowell\"\n,\n\"Noyes\"\n,\n\"Nozicka\"\n,\n\"Nudd\"\n,\n\"Nugent\"\n,\n\"Nuli\"\n,\n\"Nunci\"\n,\n\"Nuncia\"\n,\n\"Nunciata\"\n,\n\"Nunes\"\n,\n\"Nunnery\"\n,\n\"Nur\"\n,\n\"Nuri\"\n,\n\"Nuriel\"\n,\n\"Nuris\"\n,\n\"Nurse\"\n,\n\"Nussbaum\"\n,\n\"Nutter\"\n,\n\"Nuzzi\"\n,\n\"Nyberg\"\n,\n\"Nydia\"\n,\n\"Nye\"\n,\n\"Nyhagen\"\n,\n\"Nysa\"\n,\n\"Nyssa\"\n,\n\"O'Hara\"\n,\n\"O'Neill\"\n,\n\"Oak\"\n,\n\"Oakes\"\n,\n\"Oakie\"\n,\n\"Oakleil\"\n,\n\"Oakley\"\n,\n\"Oakman\"\n,\n\"Oaks\"\n,\n\"Oates\"\n,\n\"Oatis\"\n,\n\"Oba\"\n,\n\"Obadiah\"\n,\n\"Obadias\"\n,\n\"Obala\"\n,\n\"Oballa\"\n,\n\"Obara\"\n,\n\"Obau\"\n,\n\"Obaza\"\n,\n\"Obbard\"\n,\n\"Obe\"\n,\n\"Obed\"\n,\n\"Obeded\"\n,\n\"Obediah\"\n,\n\"Obel\"\n,\n\"Obelia\"\n,\n\"Obellia\"\n,\n\"Obeng\"\n,\n\"Ober\"\n,\n\"Oberg\"\n,\n\"Oberheim\"\n,\n\"Oberon\"\n,\n\"Oberstone\"\n,\n\"Obidiah\"\n,\n\"Obie\"\n,\n\"Obla\"\n,\n\"Obola\"\n,\n\"Obrien\"\n,\n\"Oby\"\n,\n\"Oca\"\n,\n\"Ocana\"\n,\n\"Ochs\"\n,\n\"Ocker\"\n,\n\"Ocko\"\n,\n\"Oconnor\"\n,\n\"Octave\"\n,\n\"Octavia\"\n,\n\"Octavian\"\n,\n\"Octavie\"\n,\n\"Octavius\"\n,\n\"Octavla\"\n,\n\"Octavus\"\n,\n\"Odab\"\n,\n\"Odawa\"\n,\n\"Ode\"\n,\n\"Odeen\"\n,\n\"Odel\"\n,\n\"Odele\"\n,\n\"Odelet\"\n,\n\"Odelia\"\n,\n\"Odelinda\"\n,\n\"Odell\"\n,\n\"Odella\"\n,\n\"Odelle\"\n,\n\"Odericus\"\n,\n\"Odessa\"\n,\n\"Odetta\"\n,\n\"Odette\"\n,\n\"Odey\"\n,\n\"Odie\"\n,\n\"Odilia\"\n,\n\"Odille\"\n,\n\"Odilo\"\n,\n\"Odin\"\n,\n\"Odine\"\n,\n\"Odlo\"\n,\n\"Odo\"\n,\n\"Odom\"\n,\n\"Odoric\"\n,\n\"Odrick\"\n,\n\"Ody\"\n,\n\"Odysseus\"\n,\n\"Odyssey\"\n,\n\"Oech\"\n,\n\"Oeflein\"\n,\n\"Oehsen\"\n,\n\"Ofelia\"\n,\n\"Ofella\"\n,\n\"Offen\"\n,\n\"Ofilia\"\n,\n\"Ofori\"\n,\n\"Og\"\n,\n\"Ogata\"\n,\n\"Ogawa\"\n,\n\"Ogdan\"\n,\n\"Ogden\"\n,\n\"Ogdon\"\n,\n\"Ogg\"\n,\n\"Ogilvie\"\n,\n\"Ogilvy\"\n,\n\"Oglesby\"\n,\n\"Ogren\"\n,\n\"Ohara\"\n,\n\"Ohare\"\n,\n\"Ohaus\"\n,\n\"Ohl\"\n,\n\"Oilla\"\n,\n\"Oina\"\n,\n\"Oira\"\n,\n\"Okajima\"\n,\n\"Okechuku\"\n,\n\"Okubo\"\n,\n\"Okun\"\n,\n\"Okwu\"\n,\n\"Ola\"\n,\n\"Olaf\"\n,\n\"Olag\"\n,\n\"Olatha\"\n,\n\"Olathe\"\n,\n\"Olav\"\n,\n\"Olcott\"\n,\n\"Old\"\n,\n\"Older\"\n,\n\"Olds\"\n,\n\"Ole\"\n,\n\"Oleg\"\n,\n\"Olen\"\n,\n\"Olenka\"\n,\n\"Olenolin\"\n,\n\"Olenta\"\n,\n\"Oler\"\n,\n\"Oleta\"\n,\n\"Oletha\"\n,\n\"Olethea\"\n,\n\"Oletta\"\n,\n\"Olette\"\n,\n\"Olfe\"\n,\n\"Olga\"\n,\n\"Olia\"\n,\n\"Oliana\"\n,\n\"Olimpia\"\n,\n\"Olin\"\n,\n\"Olinde\"\n,\n\"Oliva\"\n,\n\"Olivann\"\n,\n\"Olive\"\n,\n\"Oliver\"\n,\n\"Olivero\"\n,\n\"Olivette\"\n,\n\"Olivia\"\n,\n\"Olivie\"\n,\n\"Olivier\"\n,\n\"Oliviero\"\n,\n\"Oliy\"\n,\n\"Ollayos\"\n,\n\"Olli\"\n,\n\"Ollie\"\n,\n\"Olly\"\n,\n\"Olmstead\"\n,\n\"Olmsted\"\n,\n\"Olnay\"\n,\n\"Olnee\"\n,\n\"Olnek\"\n,\n\"Olney\"\n,\n\"Olnton\"\n,\n\"Olodort\"\n,\n\"Olpe\"\n,\n\"Olsen\"\n,\n\"Olsewski\"\n,\n\"Olshausen\"\n,\n\"Olson\"\n,\n\"Olsson\"\n,\n\"Olva\"\n,\n\"Olvan\"\n,\n\"Olwen\"\n,\n\"Olwena\"\n,\n\"Oly\"\n,\n\"Olympe\"\n,\n\"Olympia\"\n,\n\"Olympias\"\n,\n\"Olympie\"\n,\n\"Olympium\"\n,\n\"Om\"\n,\n\"Oman\"\n,\n\"Omar\"\n,\n\"Omari\"\n,\n\"Omarr\"\n,\n\"Omer\"\n,\n\"Omero\"\n,\n\"Omidyar\"\n,\n\"Omland\"\n,\n\"Omor\"\n,\n\"Omora\"\n,\n\"Omura\"\n,\n\"On\"\n,\n\"Ona\"\n,\n\"Onder\"\n,\n\"Ondine\"\n,\n\"Ondrea\"\n,\n\"Ondrej\"\n,\n\"Oneal\"\n,\n\"Oneida\"\n,\n\"Oneil\"\n,\n\"Oneill\"\n,\n\"Onfre\"\n,\n\"Onfroi\"\n,\n\"Ong\"\n,\n\"Ongun\"\n,\n\"Oni\"\n,\n\"Onia\"\n,\n\"Onida\"\n,\n\"Oniskey\"\n,\n\"Onofredo\"\n,\n\"Onstad\"\n,\n\"Ontina\"\n,\n\"Ontine\"\n,\n\"Onyx\"\n,\n\"Oona\"\n,\n\"Opal\"\n,\n\"Opalina\"\n,\n\"Opaline\"\n,\n\"Ophelia\"\n,\n\"Ophelie\"\n,\n\"Oppen\"\n,\n\"Opportina\"\n,\n\"Opportuna\"\n,\n\"Ora\"\n,\n\"Orabel\"\n,\n\"Orabelle\"\n,\n\"Oralee\"\n,\n\"Oralia\"\n,\n\"Oralie\"\n,\n\"Oralla\"\n,\n\"Oralle\"\n,\n\"Oram\"\n,\n\"Oran\"\n,\n\"Orazio\"\n,\n\"Orbadiah\"\n,\n\"Orban\"\n,\n\"Ordway\"\n,\n\"Orel\"\n,\n\"Orelee\"\n,\n\"Orelia\"\n,\n\"Orelie\"\n,\n\"Orella\"\n,\n\"Orelle\"\n,\n\"Orelu\"\n,\n\"Oren\"\n,\n\"Orest\"\n,\n\"Oreste\"\n,\n\"Orestes\"\n,\n\"Orferd\"\n,\n\"Orfield\"\n,\n\"Orfinger\"\n,\n\"Orford\"\n,\n\"Orfurd\"\n,\n\"Orgel\"\n,\n\"Orgell\"\n,\n\"Ori\"\n,\n\"Oria\"\n,\n\"Orian\"\n,\n\"Oriana\"\n,\n\"Oriane\"\n,\n\"Orianna\"\n,\n\"Oribel\"\n,\n\"Oribella\"\n,\n\"Oribelle\"\n,\n\"Oriel\"\n,\n\"Orin\"\n,\n\"Oringa\"\n,\n\"Oringas\"\n,\n\"Oriole\"\n,\n\"Orion\"\n,\n\"Orit\"\n,\n\"Orji\"\n,\n\"Orlan\"\n,\n\"Orland\"\n,\n\"Orlando\"\n,\n\"Orlanta\"\n,\n\"Orlantha\"\n,\n\"Orlena\"\n,\n\"Orlene\"\n,\n\"Orlina\"\n,\n\"Orling\"\n,\n\"Orlosky\"\n,\n\"Orlov\"\n,\n\"Orly\"\n,\n\"Orman\"\n,\n\"Ormand\"\n,\n\"Orme\"\n,\n\"Ormiston\"\n,\n\"Ormond\"\n,\n\"Orms\"\n,\n\"Ormsby\"\n,\n\"Orna\"\n,\n\"Ornas\"\n,\n\"Ornie\"\n,\n\"Ornstead\"\n,\n\"Orola\"\n,\n\"Orose\"\n,\n\"Orozco\"\n,\n\"Orpah\"\n,\n\"Orpha\"\n,\n\"Orpheus\"\n,\n\"Orr\"\n,\n\"Orran\"\n,\n\"Orren\"\n,\n\"Orrin\"\n,\n\"Orsa\"\n,\n\"Orsay\"\n,\n\"Orsini\"\n,\n\"Orsino\"\n,\n\"Orsola\"\n,\n\"Orson\"\n,\n\"Orten\"\n,\n\"Ortensia\"\n,\n\"Orth\"\n,\n\"Orthman\"\n,\n\"Ortiz\"\n,\n\"Orton\"\n,\n\"Ortrud\"\n,\n\"Ortrude\"\n,\n\"Oruntha\"\n,\n\"Orv\"\n,\n\"Orva\"\n,\n\"Orvah\"\n,\n\"Orvan\"\n,\n\"Orvas\"\n,\n\"Orvie\"\n,\n\"Orvil\"\n,\n\"Orville\"\n,\n\"Orwin\"\n,\n\"Os\"\n,\n\"Osana\"\n,\n\"Osanna\"\n,\n\"Osber\"\n,\n\"Osbert\"\n,\n\"Osborn\"\n,\n\"Osborne\"\n,\n\"Osbourn\"\n,\n\"Osbourne\"\n,\n\"Oscar\"\n,\n\"Osei\"\n,\n\"Osgood\"\n,\n\"Osher\"\n,\n\"Oshinski\"\n,\n\"Osi\"\n,\n\"Osithe\"\n,\n\"Oskar\"\n,\n\"Osman\"\n,\n\"Osmen\"\n,\n\"Osmo\"\n,\n\"Osmond\"\n,\n\"Osmund\"\n,\n\"Osric\"\n,\n\"Osrick\"\n,\n\"Osrock\"\n,\n\"Ossie\"\n,\n\"Osswald\"\n,\n\"Ossy\"\n,\n\"Ostap\"\n,\n\"Oster\"\n,\n\"Osterhus\"\n,\n\"Ostler\"\n,\n\"Ostraw\"\n,\n\"Osugi\"\n,\n\"Oswal\"\n,\n\"Oswald\"\n,\n\"Oswell\"\n,\n\"Oswin\"\n,\n\"Osy\"\n,\n\"Osyth\"\n,\n\"Ot\"\n,\n\"Otero\"\n,\n\"Otes\"\n,\n\"Otha\"\n,\n\"Othe\"\n,\n\"Othelia\"\n,\n\"Othella\"\n,\n\"Othello\"\n,\n\"Other\"\n,\n\"Othilia\"\n,\n\"Othilie\"\n,\n\"Otho\"\n,\n\"Otila\"\n,\n\"Otilia\"\n,\n\"Otina\"\n,\n\"Otis\"\n,\n\"Ott\"\n,\n\"Ottavia\"\n,\n\"Otte\"\n,\n\"Otter\"\n,\n\"Otti\"\n,\n\"Ottie\"\n,\n\"Ottilie\"\n,\n\"Ottillia\"\n,\n\"Ottinger\"\n,\n\"Otto\"\n,\n\"Oulman\"\n,\n\"Outhe\"\n,\n\"Outlaw\"\n,\n\"Ovid\"\n,\n\"Ovida\"\n,\n\"Owades\"\n,\n\"Owain\"\n,\n\"Owen\"\n,\n\"Owena\"\n,\n\"Owens\"\n,\n\"Oxford\"\n,\n\"Oxley\"\n,\n\"Oys\"\n,\n\"Oz\"\n,\n\"Oza\"\n,\n\"Ozan\"\n,\n\"Ozen\"\n,\n\"Ozkum\"\n,\n\"Ozmo\"\n,\n\"Ozzie\"\n,\n\"Ozzy\"\n,\n\"O'Brien\"\n,\n\"O'Callaghan\"\n,\n\"O'Carroll\"\n,\n\"O'Connell\"\n,\n\"O'Conner\"\n,\n\"O'Connor\"\n,\n\"O'Dell\"\n,\n\"O'Doneven\"\n,\n\"O'Donnell\"\n,\n\"O'Donoghue\"\n,\n\"O'Donovan\"\n,\n\"O'Driscoll\"\n,\n\"O'Gowan\"\n,\n\"O'Grady\"\n,\n\"O'Hara\"\n,\n\"O'Kelly\"\n,\n\"O'Mahony\"\n,\n\"O'Malley\"\n,\n\"O'Meara\"\n,\n\"O'Neil\"\n,\n\"O'Neill\"\n,\n\"O'Reilly\"\n,\n\"O'Rourke\"\n,\n\"O'Shee\"\n,\n\"O'Toole\"\n,\n\"Paapanen\"\n,\n\"Pablo\"\n,\n\"Pace\"\n,\n\"Pacheco\"\n,\n\"Pachston\"\n,\n\"Pachton\"\n,\n\"Pacian\"\n,\n\"Pacien\"\n,\n\"Pacifa\"\n,\n\"Pacifica\"\n,\n\"Pacificas\"\n,\n\"Pacificia\"\n,\n\"Pack\"\n,\n\"Packer\"\n,\n\"Packston\"\n,\n\"Packton\"\n,\n\"Paco\"\n,\n\"Pacorro\"\n,\n\"Paddie\"\n,\n\"Paddy\"\n,\n\"Padegs\"\n,\n\"Paderna\"\n,\n\"Padget\"\n,\n\"Padgett\"\n,\n\"Padraic\"\n,\n\"Padraig\"\n,\n\"Padriac\"\n,\n\"Paff\"\n,\n\"Pagas\"\n,\n\"Page\"\n,\n\"Pages\"\n,\n\"Paget\"\n,\n\"Pahl\"\n,\n\"Paige\"\n,\n\"Paik\"\n,\n\"Pail\"\n,\n\"Pain\"\n,\n\"Paine\"\n,\n\"Painter\"\n,\n\"Palecek\"\n,\n\"Palermo\"\n,\n\"Palestine\"\n,\n\"Paley\"\n,\n\"Palgrave\"\n,\n\"Palila\"\n,\n\"Pall\"\n,\n\"Palla\"\n,\n\"Palladin\"\n,\n\"Pallas\"\n,\n\"Pallaten\"\n,\n\"Pallaton\"\n,\n\"Pallua\"\n,\n\"Palm\"\n,\n\"Palma\"\n,\n\"Palmer\"\n,\n\"Palmira\"\n,\n\"Palmore\"\n,\n\"Palocz\"\n,\n\"Paloma\"\n,\n\"Pals\"\n,\n\"Palua\"\n,\n\"Paluas\"\n,\n\"Palumbo\"\n,\n\"Pam\"\n,\n\"Pamela\"\n,\n\"Pamelina\"\n,\n\"Pamella\"\n,\n\"Pammi\"\n,\n\"Pammie\"\n,\n\"Pammy\"\n,\n\"Pampuch\"\n,\n\"Pan\"\n,\n\"Panaggio\"\n,\n\"Panayiotis\"\n,\n\"Panchito\"\n,\n\"Pancho\"\n,\n\"Pandich\"\n,\n\"Pandolfi\"\n,\n\"Pandora\"\n,\n\"Pang\"\n,\n\"Pangaro\"\n,\n\"Pani\"\n,\n\"Pansie\"\n,\n\"Pansir\"\n,\n\"Pansy\"\n,\n\"Panta\"\n,\n\"Panter\"\n,\n\"Panthea\"\n,\n\"Pantheas\"\n,\n\"Panther\"\n,\n\"Panthia\"\n,\n\"Pantia\"\n,\n\"Pantin\"\n,\n\"Paola\"\n,\n\"Paolina\"\n,\n\"Paolo\"\n,\n\"Papagena\"\n,\n\"Papageno\"\n,\n\"Pape\"\n,\n\"Papert\"\n,\n\"Papke\"\n,\n\"Papotto\"\n,\n\"Papp\"\n,\n\"Pappano\"\n,\n\"Pappas\"\n,\n\"Papst\"\n,\n\"Paquito\"\n,\n\"Par\"\n,\n\"Paradies\"\n,\n\"Parcel\"\n,\n\"Pardew\"\n,\n\"Pardner\"\n,\n\"Pardo\"\n,\n\"Pardoes\"\n,\n\"Pare\"\n,\n\"Parent\"\n,\n\"Paresh\"\n,\n\"Parette\"\n,\n\"Parfitt\"\n,\n\"Parhe\"\n,\n\"Parik\"\n,\n\"Paris\"\n,\n\"Parish\"\n,\n\"Park\"\n,\n\"Parke\"\n,\n\"Parker\"\n,\n\"Parks\"\n,\n\"Parlin\"\n,\n\"Parnas\"\n,\n\"Parnell\"\n,\n\"Parrie\"\n,\n\"Parris\"\n,\n\"Parrisch\"\n,\n\"Parrish\"\n,\n\"Parrnell\"\n,\n\"Parrott\"\n,\n\"Parry\"\n,\n\"Parsaye\"\n,\n\"Parshall\"\n,\n\"Parsifal\"\n,\n\"Parsons\"\n,\n\"Partan\"\n,\n\"Parthen\"\n,\n\"Parthena\"\n,\n\"Parthenia\"\n,\n\"Parthinia\"\n,\n\"Particia\"\n,\n\"Partridge\"\n,\n\"Paryavi\"\n,\n\"Pas\"\n,\n\"Pasadis\"\n,\n\"Pasahow\"\n,\n\"Pascal\"\n,\n\"Pascale\"\n,\n\"Pascasia\"\n,\n\"Pascha\"\n,\n\"Paschasia\"\n,\n\"Pascia\"\n,\n\"Pasco\"\n,\n\"Pascoe\"\n,\n\"Pasho\"\n,\n\"Pasia\"\n,\n\"Paske\"\n,\n\"Pasol\"\n,\n\"Pasquale\"\n,\n\"Pass\"\n,\n\"Past\"\n,\n\"Pastelki\"\n,\n\"Pat\"\n,\n\"Pate\"\n,\n\"Paten\"\n,\n\"Paterson\"\n,\n\"Pathe\"\n,\n\"Patience\"\n,\n\"Patin\"\n,\n\"Patman\"\n,\n\"Patnode\"\n,\n\"Paton\"\n,\n\"Patric\"\n,\n\"Patrica\"\n,\n\"Patrice\"\n,\n\"Patrich\"\n,\n\"Patricia\"\n,\n\"Patricio\"\n,\n\"Patrick\"\n,\n\"Patrizia\"\n,\n\"Patrizio\"\n,\n\"Patrizius\"\n,\n\"Patsis\"\n,\n\"Patsy\"\n,\n\"Patt\"\n,\n\"Pattani\"\n,\n\"Patten\"\n,\n\"Patterman\"\n,\n\"Patterson\"\n,\n\"Patti\"\n,\n\"Pattie\"\n,\n\"Pattin\"\n,\n\"Pattison\"\n,\n\"Patton\"\n,\n\"Patty\"\n,\n\"Paucker\"\n,\n\"Paugh\"\n,\n\"Pauiie\"\n,\n\"Paul\"\n,\n\"Paula\"\n,\n\"Paule\"\n,\n\"Pauletta\"\n,\n\"Paulette\"\n,\n\"Pauli\"\n,\n\"Paulie\"\n,\n\"Paulina\"\n,\n\"Pauline\"\n,\n\"Paulita\"\n,\n\"Paulo\"\n,\n\"Paulsen\"\n,\n\"Paulson\"\n,\n\"Pauly\"\n,\n\"Pauwles\"\n,\n\"Pavel\"\n,\n\"Paver\"\n,\n\"Pavia\"\n,\n\"Pavier\"\n,\n\"Pavior\"\n,\n\"Paviour\"\n,\n\"Pavkovic\"\n,\n\"Pavla\"\n,\n\"Pavlish\"\n,\n\"Pavlov\"\n,\n\"Pavyer\"\n,\n\"Pawsner\"\n,\n\"Pax\"\n,\n\"Paxon\"\n,\n\"Paxton\"\n,\n\"Paymar\"\n,\n\"Payne\"\n,\n\"Paynter\"\n,\n\"Payson\"\n,\n\"Payton\"\n,\n\"Paz\"\n,\n\"Paza\"\n,\n\"Pazia\"\n,\n\"Pazice\"\n,\n\"Pazit\"\n,\n\"Peace\"\n,\n\"Peacock\"\n,\n\"Peadar\"\n,\n\"Peale\"\n,\n\"Pearce\"\n,\n\"Pearl\"\n,\n\"Pearla\"\n,\n\"Pearle\"\n,\n\"Pearline\"\n,\n\"Pearlman\"\n,\n\"Pearlstein\"\n,\n\"Pearman\"\n,\n\"Pears\"\n,\n\"Pearse\"\n,\n\"Pearson\"\n,\n\"Pease\"\n,\n\"Peatroy\"\n,\n\"Pebrook\"\n,\n\"Peck\"\n,\n\"Peckham\"\n,\n\"Pedaiah\"\n,\n\"Pedaias\"\n,\n\"Peddada\"\n,\n\"Peder\"\n,\n\"Pedersen\"\n,\n\"Pederson\"\n,\n\"Pedrick\"\n,\n\"Pedro\"\n,\n\"Pedrotti\"\n,\n\"Pedroza\"\n,\n\"Peer\"\n,\n\"Peers\"\n,\n\"Peery\"\n,\n\"Peg\"\n,\n\"Pega\"\n,\n\"Pegasus\"\n,\n\"Pegeen\"\n,\n\"Pegg\"\n,\n\"Peggi\"\n,\n\"Peggie\"\n,\n\"Peggir\"\n,\n\"Peggy\"\n,\n\"Pegma\"\n,\n\"Peh\"\n,\n\"Peirce\"\n,\n\"Peirsen\"\n,\n\"Peisch\"\n,\n\"Pejsach\"\n,\n\"Pelag\"\n,\n\"Pelaga\"\n,\n\"Pelage\"\n,\n\"Pelagi\"\n,\n\"Pelagia\"\n,\n\"Pelagias\"\n,\n\"Pell\"\n,\n\"Pellegrini\"\n,\n\"Pellet\"\n,\n\"Pelletier\"\n,\n\"Pelligrini\"\n,\n\"Pellikka\"\n,\n\"Pelmas\"\n,\n\"Pelpel\"\n,\n\"Pelson\"\n,\n\"Peltier\"\n,\n\"Peltz\"\n,\n\"Pember\"\n,\n\"Pembroke\"\n,\n\"Pembrook\"\n,\n\"Pen\"\n,\n\"Pena\"\n,\n\"Pence\"\n,\n\"Pendergast\"\n,\n\"Pendleton\"\n,\n\"Penelopa\"\n,\n\"Penelope\"\n,\n\"Pengelly\"\n,\n\"Penhall\"\n,\n\"Penland\"\n,\n\"Penman\"\n,\n\"Penn\"\n,\n\"Pennebaker\"\n,\n\"Penney\"\n,\n\"Penni\"\n,\n\"Pennie\"\n,\n\"Pennington\"\n,\n\"Penny\"\n,\n\"Penoyer\"\n,\n\"Penrod\"\n,\n\"Penrose\"\n,\n\"Pentha\"\n,\n\"Penthea\"\n,\n\"Pentheam\"\n,\n\"Pentheas\"\n,\n\"Peonir\"\n,\n\"Peony\"\n,\n\"Peoples\"\n,\n\"Pepe\"\n,\n\"Peper\"\n,\n\"Pepi\"\n,\n\"Pepillo\"\n,\n\"Pepin\"\n,\n\"Pepita\"\n,\n\"Pepito\"\n,\n\"Peppard\"\n,\n\"Peppel\"\n,\n\"Pepper\"\n,\n\"Peppi\"\n,\n\"Peppie\"\n,\n\"Peppy\"\n,\n\"Per\"\n,\n\"Perce\"\n,\n\"Perceval\"\n,\n\"Percival\"\n,\n\"Percy\"\n,\n\"Perdita\"\n,\n\"Peregrine\"\n,\n\"Pergrim\"\n,\n\"Peri\"\n,\n\"Peria\"\n,\n\"Perice\"\n,\n\"Perkin\"\n,\n\"Perkins\"\n,\n\"Perkoff\"\n,\n\"Perl\"\n,\n\"Perla\"\n,\n\"Perle\"\n,\n\"Perlie\"\n,\n\"Perlis\"\n,\n\"Perlman\"\n,\n\"Perloff\"\n,\n\"Pernas\"\n,\n\"Pernell\"\n,\n\"Perni\"\n,\n\"Pernick\"\n,\n\"Pero\"\n,\n\"Perot\"\n,\n\"Perpetua\"\n,\n\"Perr\"\n,\n\"Perreault\"\n,\n\"Perren\"\n,\n\"Perretta\"\n,\n\"Perri\"\n,\n\"Perrie\"\n,\n\"Perrin\"\n,\n\"Perrine\"\n,\n\"Perrins\"\n,\n\"Perron\"\n,\n\"Perry\"\n,\n\"Persas\"\n,\n\"Perseus\"\n,\n\"Persian\"\n,\n\"Persis\"\n,\n\"Persons\"\n,\n\"Persse\"\n,\n\"Persson\"\n,\n\"Perusse\"\n,\n\"Perzan\"\n,\n\"Pesek\"\n,\n\"Peskoff\"\n,\n\"Pessa\"\n,\n\"Pestana\"\n,\n\"Pet\"\n,\n\"Peta\"\n,\n\"Pete\"\n,\n\"Peter\"\n,\n\"Peterec\"\n,\n\"Peterman\"\n,\n\"Peters\"\n,\n\"Petersen\"\n,\n\"Peterson\"\n,\n\"Peterus\"\n,\n\"Petes\"\n,\n\"Petey\"\n,\n\"Peti\"\n,\n\"Petie\"\n,\n\"Petigny\"\n,\n\"Petit\"\n,\n\"Petite\"\n,\n\"Petr\"\n,\n\"Petra\"\n,\n\"Petracca\"\n,\n\"Petras\"\n,\n\"Petrick\"\n,\n\"Petrie\"\n,\n\"Petrina\"\n,\n\"Petrine\"\n,\n\"Petromilli\"\n,\n\"Petronella\"\n,\n\"Petronia\"\n,\n\"Petronilla\"\n,\n\"Petronille\"\n,\n\"Petta\"\n,\n\"Pettifer\"\n,\n\"Pettiford\"\n,\n\"Pettit\"\n,\n\"Petty\"\n,\n\"Petua\"\n,\n\"Petula\"\n,\n\"Petulah\"\n,\n\"Petulia\"\n,\n\"Petunia\"\n,\n\"Petuu\"\n,\n\"Peugia\"\n,\n\"Peursem\"\n,\n\"Pevzner\"\n,\n\"Peyter\"\n,\n\"Peyton\"\n,\n\"Pfaff\"\n,\n\"Pfeffer\"\n,\n\"Pfeifer\"\n,\n\"Pfister\"\n,\n\"Pfosi\"\n,\n\"Phaedra\"\n,\n\"Phaidra\"\n,\n\"Phaih\"\n,\n\"Phail\"\n,\n\"Phalan\"\n,\n\"Pharaoh\"\n,\n\"Phare\"\n,\n\"Phares\"\n,\n\"Phebe\"\n,\n\"Phedra\"\n,\n\"Phelan\"\n,\n\"Phelgen\"\n,\n\"Phelgon\"\n,\n\"Phelia\"\n,\n\"Phelips\"\n,\n\"Phelps\"\n,\n\"Phemia\"\n,\n\"Phene\"\n,\n\"Pheni\"\n,\n\"Phenica\"\n,\n\"Phenice\"\n,\n\"Phi\"\n,\n\"Phia\"\n,\n\"Phil\"\n,\n\"Phila\"\n,\n\"Philan\"\n,\n\"Philana\"\n,\n\"Philander\"\n,\n\"Philbert\"\n,\n\"Philbin\"\n,\n\"Philbo\"\n,\n\"Philbrook\"\n,\n\"Philcox\"\n,\n\"Philemol\"\n,\n\"Philemon\"\n,\n\"Philender\"\n,\n\"Philina\"\n,\n\"Philine\"\n,\n\"Philip\"\n,\n\"Philipa\"\n,\n\"Philipines\"\n,\n\"Philipp\"\n,\n\"Philippa\"\n,\n\"Philippe\"\n,\n\"Philippine\"\n,\n\"Philipps\"\n,\n\"Philips\"\n,\n\"Philipson\"\n,\n\"Philis\"\n,\n\"Phillada\"\n,\n\"Phillane\"\n,\n\"Phillida\"\n,\n\"Phillie\"\n,\n\"Phillip\"\n,\n\"Phillipe\"\n,\n\"Phillipp\"\n,\n\"Phillips\"\n,\n\"Phillis\"\n,\n\"Philly\"\n,\n\"Philo\"\n,\n\"Philomena\"\n,\n\"Philoo\"\n,\n\"Philpot\"\n,\n\"Philps\"\n,\n\"Phina\"\n,\n\"Phineas\"\n,\n\"Phio\"\n,\n\"Phiona\"\n,\n\"Phionna\"\n,\n\"Phip\"\n,\n\"Phippen\"\n,\n\"Phipps\"\n,\n\"Phira\"\n,\n\"Phoebe\"\n,\n\"Phonsa\"\n,\n\"Photima\"\n,\n\"Photina\"\n,\n\"Phox\"\n,\n\"Phyl\"\n,\n\"Phylis\"\n,\n\"Phyllida\"\n,\n\"Phyllis\"\n,\n\"Phyllys\"\n,\n\"Phylys\"\n,\n\"Pia\"\n,\n\"Piane\"\n,\n\"Picardi\"\n,\n\"Picco\"\n,\n\"Pich\"\n,\n\"Pickar\"\n,\n\"Pickard\"\n,\n\"Pickens\"\n,\n\"Picker\"\n,\n\"Pickering\"\n,\n\"Pickett\"\n,\n\"Pickford\"\n,\n\"Piderit\"\n,\n\"Piefer\"\n,\n\"Piegari\"\n,\n\"Pier\"\n,\n\"Pierce\"\n,\n\"Pierette\"\n,\n\"Piero\"\n,\n\"Pierpont\"\n,\n\"Pierre\"\n,\n\"Pierrepont\"\n,\n\"Pierrette\"\n,\n\"Pierro\"\n,\n\"Piers\"\n,\n\"Pierson\"\n,\n\"Pieter\"\n,\n\"Pietje\"\n,\n\"Pietra\"\n,\n\"Pietrek\"\n,\n\"Pietro\"\n,\n\"Pigeon\"\n,\n\"Piggy\"\n,\n\"Pike\"\n,\n\"Pilar\"\n,\n\"Pilloff\"\n,\n\"Pillow\"\n,\n\"Pillsbury\"\n,\n\"Pimbley\"\n,\n\"Pincas\"\n,\n\"Pinchas\"\n,\n\"Pincince\"\n,\n\"Pinckney\"\n,\n\"Pincus\"\n,\n\"Pine\"\n,\n\"Pinebrook\"\n,\n\"Pineda\"\n,\n\"Pinelli\"\n,\n\"Pinette\"\n,\n\"Ping\"\n,\n\"Pinkerton\"\n,\n\"Pinkham\"\n,\n\"Pinsky\"\n,\n\"Pinter\"\n,\n\"Pinto\"\n,\n\"Pinzler\"\n,\n\"Piotr\"\n,\n\"Pip\"\n,\n\"Piper\"\n,\n\"Pippa\"\n,\n\"Pippas\"\n,\n\"Pippo\"\n,\n\"Pippy\"\n,\n\"Pirali\"\n,\n\"Pirbhai\"\n,\n\"Pirnot\"\n,\n\"Pironi\"\n,\n\"Pirozzo\"\n,\n\"Pirri\"\n,\n\"Pirzada\"\n,\n\"Pisano\"\n,\n\"Pisarik\"\n,\n\"Piscatelli\"\n,\n\"Piselli\"\n,\n\"Pish\"\n,\n\"Pitarys\"\n,\n\"Pitchford\"\n,\n\"Pitt\"\n,\n\"Pittel\"\n,\n\"Pittman\"\n,\n\"Pitts\"\n,\n\"Pitzer\"\n,\n\"Pius\"\n,\n\"Piwowar\"\n,\n\"Pizor\"\n,\n\"Placeeda\"\n,\n\"Placia\"\n,\n\"Placida\"\n,\n\"Placidia\"\n,\n\"Placido\"\n,\n\"Plafker\"\n,\n\"Plank\"\n,\n\"Plantagenet\"\n,\n\"Plante\"\n,\n\"Platas\"\n,\n\"Plate\"\n,\n\"Plath\"\n,\n\"Plato\"\n,\n\"Platon\"\n,\n\"Platt\"\n,\n\"Platto\"\n,\n\"Platus\"\n,\n\"Player\"\n,\n\"Pleasant\"\n,\n\"Pleione\"\n,\n\"Plerre\"\n,\n\"Pliam\"\n,\n\"Pliner\"\n,\n\"Pliske\"\n,\n\"Ploch\"\n,\n\"Ploss\"\n,\n\"Plossl\"\n,\n\"Plotkin\"\n,\n\"Plumbo\"\n,\n\"Plume\"\n,\n\"Plunkett\"\n,\n\"Plusch\"\n,\n\"Podvin\"\n,\n\"Pogue\"\n,\n\"Poirer\"\n,\n\"Pokorny\"\n,\n\"Pol\"\n,\n\"Polad\"\n,\n\"Polak\"\n,\n\"Poland\"\n,\n\"Polard\"\n,\n\"Polash\"\n,\n\"Poler\"\n,\n\"Poliard\"\n,\n\"Polik\"\n,\n\"Polinski\"\n,\n\"Polish\"\n,\n\"Politi\"\n,\n\"Polito\"\n,\n\"Polivy\"\n,\n\"Polk\"\n,\n\"Polky\"\n,\n\"Poll\"\n,\n\"Pollack\"\n,\n\"Pollak\"\n,\n\"Pollard\"\n,\n\"Pollerd\"\n,\n\"Pollie\"\n,\n\"Pollitt\"\n,\n\"Polloch\"\n,\n\"Pollock\"\n,\n\"Pollux\"\n,\n\"Polly\"\n,\n\"Pollyanna\"\n,\n\"Pomcroy\"\n,\n\"Pomeroy\"\n,\n\"Pomfret\"\n,\n\"Pomfrey\"\n,\n\"Pomona\"\n,\n\"Pompea\"\n,\n\"Pompei\"\n,\n\"Ponce\"\n,\n\"Pond\"\n,\n\"Pontias\"\n,\n\"Pontius\"\n,\n\"Ponton\"\n,\n\"Pontone\"\n,\n\"Pontus\"\n,\n\"Ponzo\"\n,\n\"Poock\"\n,\n\"Pooh\"\n,\n\"Pooi\"\n,\n\"Pool\"\n,\n\"Poole\"\n,\n\"Pooley\"\n,\n\"Poore\"\n,\n\"Pope\"\n,\n\"Popele\"\n,\n\"Popelka\"\n,\n\"Poppas\"\n,\n\"Popper\"\n,\n\"Poppo\"\n,\n\"Poppy\"\n,\n\"Porche\"\n,\n\"Porcia\"\n,\n\"Poree\"\n,\n\"Porett\"\n,\n\"Port\"\n,\n\"Porta\"\n,\n\"Porte\"\n,\n\"Porter\"\n,\n\"Portia\"\n,\n\"Portie\"\n,\n\"Portingale\"\n,\n\"Portland\"\n,\n\"Portugal\"\n,\n\"Portuna\"\n,\n\"Portwin\"\n,\n\"Portwine\"\n,\n\"Porty\"\n,\n\"Porush\"\n,\n\"Posehn\"\n,\n\"Posner\"\n,\n\"Possing\"\n,\n\"Post\"\n,\n\"Postman\"\n,\n\"Potash\"\n,\n\"Potter\"\n,\n\"Potts\"\n,\n\"Poucher\"\n,\n\"Poul\"\n,\n\"Poulter\"\n,\n\"Pouncey\"\n,\n\"Pournaras\"\n,\n\"Powder\"\n,\n\"Powe\"\n,\n\"Powel\"\n,\n\"Powell\"\n,\n\"Power\"\n,\n\"Powers\"\n,\n\"Pownall\"\n,\n\"Poyssick\"\n,\n\"Pozzy\"\n,\n\"Pradeep\"\n,\n\"Prader\"\n,\n\"Prady\"\n,\n\"Prager\"\n,\n\"Prakash\"\n,\n\"Prasad\"\n,\n\"Pratt\"\n,\n\"Pratte\"\n,\n\"Pravit\"\n,\n\"Prebo\"\n,\n\"Preciosa\"\n,\n\"Preiser\"\n,\n\"Prem\"\n,\n\"Premer\"\n,\n\"Pren\"\n,\n\"Prendergast\"\n,\n\"Prent\"\n,\n\"Prentice\"\n,\n\"Prentiss\"\n,\n\"Presber\"\n,\n\"Prescott\"\n,\n\"Presley\"\n,\n\"Press\"\n,\n\"Pressey\"\n,\n\"Pressman\"\n,\n\"Prestige\"\n,\n\"Preston\"\n,\n\"Pretrice\"\n,\n\"Preuss\"\n,\n\"Previdi\"\n,\n\"Prevot\"\n,\n\"Price\"\n,\n\"Prichard\"\n,\n\"Pricilla\"\n,\n\"Pride\"\n,\n\"Priebe\"\n,\n\"Priest\"\n,\n\"Priestley\"\n,\n\"Prima\"\n,\n\"Primalia\"\n,\n\"Primavera\"\n,\n\"Primaveras\"\n,\n\"Primaveria\"\n,\n\"Primo\"\n,\n\"Primrosa\"\n,\n\"Primrose\"\n,\n\"Prince\"\n,\n\"Princess\"\n,\n\"Prinz\"\n,\n\"Prior\"\n,\n\"Pris\"\n,\n\"Prisca\"\n,\n\"Priscella\"\n,\n\"Priscilla\"\n,\n\"Prisilla\"\n,\n\"Prissie\"\n,\n\"Prissy\"\n,\n\"Pritchard\"\n,\n\"Pritchett\"\n,\n\"Prober\"\n,\n\"Prochora\"\n,\n\"Prochoras\"\n,\n\"Procora\"\n,\n\"Procter\"\n,\n\"Procto\"\n,\n\"Proctor\"\n,\n\"Profant\"\n,\n\"Proffitt\"\n,\n\"Pronty\"\n,\n\"Pros\"\n,\n\"Prosper\"\n,\n\"Prospero\"\n,\n\"Prosperus\"\n,\n\"Prosser\"\n,\n\"Proud\"\n,\n\"Proudfoot\"\n,\n\"Proudlove\"\n,\n\"Proudman\"\n,\n\"Proulx\"\n,\n\"Prouty\"\n,\n\"Prowel\"\n,\n\"Pru\"\n,\n\"Pruchno\"\n,\n\"Prud\"\n,\n\"Prudence\"\n,\n\"Prudhoe\"\n,\n\"Prudi\"\n,\n\"Prudie\"\n,\n\"Prudy\"\n,\n\"Prue\"\n,\n\"Prunella\"\n,\n\"Prussian\"\n,\n\"Pruter\"\n,\n\"Pry\"\n,\n\"Pryce\"\n,\n\"Pryor\"\n,\n\"Psyche\"\n,\n\"Pubilis\"\n,\n\"Publea\"\n,\n\"Publia\"\n,\n\"Publias\"\n,\n\"Publius\"\n,\n\"Publus\"\n,\n\"Pucida\"\n,\n\"Pudendas\"\n,\n\"Pudens\"\n,\n\"Puduns\"\n,\n\"Puett\"\n,\n\"Pufahl\"\n,\n\"Puff\"\n,\n\"Pugh\"\n,\n\"Puglia\"\n,\n\"Puiia\"\n,\n\"Puklich\"\n,\n\"Pul\"\n,\n\"Pulcheria\"\n,\n\"Pulchi\"\n,\n\"Pulchia\"\n,\n\"Pulling\"\n,\n\"Pulsifer\"\n,\n\"Pump\"\n,\n\"Punak\"\n,\n\"Punke\"\n,\n\"Purcell\"\n,\n\"Purdum\"\n,\n\"Purdy\"\n,\n\"Puri\"\n,\n\"Purington\"\n,\n\"Puritan\"\n,\n\"Purity\"\n,\n\"Purpura\"\n,\n\"Purse\"\n,\n\"Purvis\"\n,\n\"Putnam\"\n,\n\"Putnem\"\n,\n\"Puto\"\n,\n\"Putscher\"\n,\n\"Puttergill\"\n,\n\"Py\"\n,\n\"Pyle\"\n,\n\"Pylle\"\n,\n\"Pyne\"\n,\n\"Pyotr\"\n,\n\"Pyszka\"\n,\n\"Pytlik\"\n,\n\"Quackenbush\"\n,\n\"Quar\"\n,\n\"Quarta\"\n,\n\"Quartana\"\n,\n\"Quartas\"\n,\n\"Quartet\"\n,\n\"Quartis\"\n,\n\"Quartus\"\n,\n\"Queen\"\n,\n\"Queena\"\n,\n\"Queenie\"\n,\n\"Quenby\"\n,\n\"Quenna\"\n,\n\"Quennie\"\n,\n\"Quent\"\n,\n\"Quentin\"\n,\n\"Queri\"\n,\n\"Querida\"\n,\n\"Queridas\"\n,\n\"Questa\"\n,\n\"Queston\"\n,\n\"Quick\"\n,\n\"Quickel\"\n,\n\"Quickman\"\n,\n\"Quigley\"\n,\n\"Quill\"\n,\n\"Quillan\"\n,\n\"Quillon\"\n,\n\"Quin\"\n,\n\"Quinby\"\n,\n\"Quince\"\n,\n\"Quincey\"\n,\n\"Quincy\"\n,\n\"Quinlan\"\n,\n\"Quinn\"\n,\n\"Quint\"\n,\n\"Quinta\"\n,\n\"Quintana\"\n,\n\"Quintessa\"\n,\n\"Quintie\"\n,\n\"Quintilla\"\n,\n\"Quintin\"\n,\n\"Quintina\"\n,\n\"Quinton\"\n,\n\"Quintus\"\n,\n\"Quirita\"\n,\n\"Quirk\"\n,\n\"Quita\"\n,\n\"Quiteri\"\n,\n\"Quiteria\"\n,\n\"Quiteris\"\n,\n\"Quitt\"\n,\n\"Qulllon\"\n,\n\"Raab\"\n,\n\"Raama\"\n,\n\"Raasch\"\n,\n\"Rab\"\n,\n\"Rabah\"\n,\n\"Rabassa\"\n,\n\"Rabbi\"\n,\n\"Rabelais\"\n,\n\"Rabi\"\n,\n\"Rabiah\"\n,\n\"Rabin\"\n,\n\"Rabjohn\"\n,\n\"Rabkin\"\n,\n\"Rabush\"\n,\n\"Race\"\n,\n\"Rachaba\"\n,\n\"Rachael\"\n,\n\"Rachel\"\n,\n\"Rachele\"\n,\n\"Rachelle\"\n,\n\"Racklin\"\n,\n\"Rad\"\n,\n\"Radack\"\n,\n\"Radborne\"\n,\n\"Radbourne\"\n,\n\"Radbun\"\n,\n\"Radburn\"\n,\n\"Radcliffe\"\n,\n\"Raddatz\"\n,\n\"Raddi\"\n,\n\"Raddie\"\n,\n\"Raddy\"\n,\n\"Radferd\"\n,\n\"Radford\"\n,\n\"Radie\"\n,\n\"Radke\"\n,\n\"Radley\"\n,\n\"Radloff\"\n,\n\"Radman\"\n,\n\"Radmen\"\n,\n\"Radmilla\"\n,\n\"Radu\"\n,\n\"Rae\"\n,\n\"Raeann\"\n,\n\"Raf\"\n,\n\"Rafa\"\n,\n\"Rafael\"\n,\n\"Rafaela\"\n,\n\"Rafaelia\"\n,\n\"Rafaelita\"\n,\n\"Rafaelle\"\n,\n\"Rafaellle\"\n,\n\"Rafaello\"\n,\n\"Rafaelof\"\n,\n\"Rafat\"\n,\n\"Rafe\"\n,\n\"Raff\"\n,\n\"Raffaello\"\n,\n\"Raffarty\"\n,\n\"Rafferty\"\n,\n\"Raffin\"\n,\n\"Raffo\"\n,\n\"Rafi\"\n,\n\"Rafiq\"\n,\n\"Rafter\"\n,\n\"Ragan\"\n,\n\"Ragen\"\n,\n\"Ragg\"\n,\n\"Ragland\"\n,\n\"Ragnar\"\n,\n\"Ragouzis\"\n,\n\"Ragucci\"\n,\n\"Rahal\"\n,\n\"Rahel\"\n,\n\"Rahm\"\n,\n\"Rahman\"\n,\n\"Rahmann\"\n,\n\"Rahr\"\n,\n\"Rai\"\n,\n\"Raila\"\n,\n\"Raimes\"\n,\n\"Raimondo\"\n,\n\"Raimund\"\n,\n\"Raimundo\"\n,\n\"Raina\"\n,\n\"Rainah\"\n,\n\"Raine\"\n,\n\"Rainer\"\n,\n\"Raines\"\n,\n\"Rainger\"\n,\n\"Rainie\"\n,\n\"Rains\"\n,\n\"Rainwater\"\n,\n\"Rajewski\"\n,\n\"Raji\"\n,\n\"Rajiv\"\n,\n\"Rakel\"\n,\n\"Rakia\"\n,\n\"Ralaigh\"\n,\n\"Raleigh\"\n,\n\"Ralf\"\n,\n\"Ralfston\"\n,\n\"Ralina\"\n,\n\"Ralleigh\"\n,\n\"Ralli\"\n,\n\"Ralph\"\n,\n\"Ralston\"\n,\n\"Ram\"\n,\n\"Rama\"\n,\n\"Ramah\"\n,\n\"Raman\"\n,\n\"Ramberg\"\n,\n\"Rambert\"\n,\n\"Rambort\"\n,\n\"Rambow\"\n,\n\"Ramburt\"\n,\n\"Rame\"\n,\n\"Ramey\"\n,\n\"Ramiah\"\n,\n\"Ramin\"\n,\n\"Ramon\"\n,\n\"Ramona\"\n,\n\"Ramonda\"\n,\n\"Ramos\"\n,\n\"Ramsay\"\n,\n\"Ramsdell\"\n,\n\"Ramsden\"\n,\n\"Ramses\"\n,\n\"Ramsey\"\n,\n\"Ramunni\"\n,\n\"Ran\"\n,\n\"Rana\"\n,\n\"Rance\"\n,\n\"Rancell\"\n,\n\"Ranchod\"\n,\n\"Rand\"\n,\n\"Randa\"\n,\n\"Randal\"\n,\n\"Randall\"\n,\n\"Randee\"\n,\n\"Randell\"\n,\n\"Randene\"\n,\n\"Randi\"\n,\n\"Randie\"\n,\n\"Randolf\"\n,\n\"Randolph\"\n,\n\"Randy\"\n,\n\"Ranee\"\n,\n\"Raney\"\n,\n\"Range\"\n,\n\"Rangel\"\n,\n\"Ranger\"\n,\n\"Rani\"\n,\n\"Rania\"\n,\n\"Ranice\"\n,\n\"Ranie\"\n,\n\"Ranique\"\n,\n\"Ranit\"\n,\n\"Ranita\"\n,\n\"Ranite\"\n,\n\"Ranitta\"\n,\n\"Ranjiv\"\n,\n\"Rankin\"\n,\n\"Rann\"\n,\n\"Ranna\"\n,\n\"Ransell\"\n,\n\"Ransom\"\n,\n\"Ransome\"\n,\n\"Ranson\"\n,\n\"Ranzini\"\n,\n\"Rao\"\n,\n\"Raouf\"\n,\n\"Raoul\"\n,\n\"Rap\"\n,\n\"Rape\"\n,\n\"Raphael\"\n,\n\"Raphaela\"\n,\n\"Rapp\"\n,\n\"Raquel\"\n,\n\"Raquela\"\n,\n\"Ras\"\n,\n\"Raseda\"\n,\n\"Raseta\"\n,\n\"Rashida\"\n,\n\"Rashidi\"\n,\n\"Rasia\"\n,\n\"Rask\"\n,\n\"Raskin\"\n,\n\"Raskind\"\n,\n\"Rasla\"\n,\n\"Rasmussen\"\n,\n\"Rastus\"\n,\n\"Rasure\"\n,\n\"Ratcliff\"\n,\n\"Ratcliffe\"\n,\n\"Ratha\"\n,\n\"Rather\"\n,\n\"Ratib\"\n,\n\"Rattan\"\n,\n\"Rattray\"\n,\n\"Rauch\"\n,\n\"Raul\"\n,\n\"Rausch\"\n,\n\"Rauscher\"\n,\n\"Raveaux\"\n,\n\"Raven\"\n,\n\"Ravens\"\n,\n\"Ravi\"\n,\n\"Ravid\"\n,\n\"Raviv\"\n,\n\"Ravo\"\n,\n\"Rawdan\"\n,\n\"Rawden\"\n,\n\"Rawdin\"\n,\n\"Rawdon\"\n,\n\"Rawley\"\n,\n\"Rawlinson\"\n,\n\"Ray\"\n,\n\"Raybin\"\n,\n\"Raybourne\"\n,\n\"Rayburn\"\n,\n\"Raychel\"\n,\n\"Raycher\"\n,\n\"Raye\"\n,\n\"Rayford\"\n,\n\"Rayle\"\n,\n\"Raymond\"\n,\n\"Raymonds\"\n,\n\"Raymund\"\n,\n\"Rayna\"\n,\n\"Raynah\"\n,\n\"Raynard\"\n,\n\"Raynata\"\n,\n\"Raynell\"\n,\n\"Rayner\"\n,\n\"Raynold\"\n,\n\"Raynor\"\n,\n\"Rayshell\"\n,\n\"Razid\"\n,\n\"Rea\"\n,\n\"Reace\"\n,\n\"Read\"\n,\n\"Reade\"\n,\n\"Readus\"\n,\n\"Ready\"\n,\n\"Reagan\"\n,\n\"Reagen\"\n,\n\"Reahard\"\n,\n\"Reames\"\n,\n\"Reamonn\"\n,\n\"Reamy\"\n,\n\"Reave\"\n,\n\"Reba\"\n,\n\"Rebah\"\n,\n\"Rebak\"\n,\n\"Rebane\"\n,\n\"Rebba\"\n,\n\"Rebbecca\"\n,\n\"Rebe\"\n,\n\"Rebeca\"\n,\n\"Rebecca\"\n,\n\"Rebecka\"\n,\n\"Rebeka\"\n,\n\"Rebekah\"\n,\n\"Rebekkah\"\n,\n\"Rebel\"\n,\n\"Rebhun\"\n,\n\"Rech\"\n,\n\"Recha\"\n,\n\"Rechaba\"\n,\n\"Reckford\"\n,\n\"Recor\"\n,\n\"Rector\"\n,\n\"Red\"\n,\n\"Redd\"\n,\n\"Reddin\"\n,\n\"Reddy\"\n,\n\"Redfield\"\n,\n\"Redford\"\n,\n\"Redman\"\n,\n\"Redmer\"\n,\n\"Redmond\"\n,\n\"Redmund\"\n,\n\"Redvers\"\n,\n\"Redwine\"\n,\n\"Ree\"\n,\n\"Reeba\"\n,\n\"Reece\"\n,\n\"Reed\"\n,\n\"Reede\"\n,\n\"Reedy\"\n,\n\"Reeher\"\n,\n\"Reel\"\n,\n\"Reena\"\n,\n\"Rees\"\n,\n\"Reese\"\n,\n\"Reeta\"\n,\n\"Reeva\"\n,\n\"Reeve\"\n,\n\"Reeves\"\n,\n\"Reg\"\n,\n\"Regan\"\n,\n\"Regazzi\"\n,\n\"Regen\"\n,\n\"Reger\"\n,\n\"Reggi\"\n,\n\"Reggie\"\n,\n\"Reggis\"\n,\n\"Reggy\"\n,\n\"Regina\"\n,\n\"Reginald\"\n,\n\"Reginauld\"\n,\n\"Regine\"\n,\n\"Rego\"\n,\n\"Rehm\"\n,\n\"Rehnberg\"\n,\n\"Reich\"\n,\n\"Reiche\"\n,\n\"Reichel\"\n,\n\"Reichert\"\n,\n\"Reid\"\n,\n\"Reidar\"\n,\n\"Reider\"\n,\n\"Reifel\"\n,\n\"Reiko\"\n,\n\"Reilly\"\n,\n\"Reimer\"\n,\n\"Rein\"\n,\n\"Reina\"\n,\n\"Reinald\"\n,\n\"Reinaldo\"\n,\n\"Reinaldos\"\n,\n\"Reine\"\n,\n\"Reiner\"\n,\n\"Reiners\"\n,\n\"Reinert\"\n,\n\"Reinertson\"\n,\n\"Reinhard\"\n,\n\"Reinhardt\"\n,\n\"Reinhart\"\n,\n\"Reinhold\"\n,\n\"Reinke\"\n,\n\"Reinold\"\n,\n\"Reinwald\"\n,\n\"Reis\"\n,\n\"Reisch\"\n,\n\"Reiser\"\n,\n\"Reisfield\"\n,\n\"Reisinger\"\n,\n\"Reisman\"\n,\n\"Reiss\"\n,\n\"Reiter\"\n,\n\"Reitman\"\n,\n\"Reld\"\n,\n\"Rella\"\n,\n\"Rellia\"\n,\n\"Relly\"\n,\n\"Rem\"\n,\n\"Rema\"\n,\n\"Remde\"\n,\n\"Remington\"\n,\n\"Remmer\"\n,\n\"Rempe\"\n,\n\"Remsen\"\n,\n\"Remus\"\n,\n\"Remy\"\n,\n\"Rena\"\n,\n\"Renado\"\n,\n\"Renae\"\n,\n\"Renaldo\"\n,\n\"Renard\"\n,\n\"Renata\"\n,\n\"Renate\"\n,\n\"Renato\"\n,\n\"Renaud\"\n,\n\"Renault\"\n,\n\"Renckens\"\n,\n\"Rene\"\n,\n\"Renee\"\n,\n\"Renell\"\n,\n\"Renelle\"\n,\n\"Reneta\"\n,\n\"Renferd\"\n,\n\"Renfred\"\n,\n\"Reni\"\n,\n\"Renick\"\n,\n\"Renie\"\n,\n\"Renita\"\n,\n\"Reniti\"\n,\n\"Rennane\"\n,\n\"Renner\"\n,\n\"Rennie\"\n,\n\"Rennold\"\n,\n\"Renny\"\n,\n\"Rento\"\n,\n\"Rentsch\"\n,\n\"Rentschler\"\n,\n\"Renwick\"\n,\n\"Renzo\"\n,\n\"Reo\"\n,\n\"Resa\"\n,\n\"Rese\"\n,\n\"Reseda\"\n,\n\"Resee\"\n,\n\"Reseta\"\n,\n\"Resor\"\n,\n\"Ress\"\n,\n\"Ressler\"\n,\n\"Reste\"\n,\n\"Restivo\"\n,\n\"Reta\"\n,\n\"Retha\"\n,\n\"Rett\"\n,\n\"Rettig\"\n,\n\"Rettke\"\n,\n\"Reube\"\n,\n\"Reuben\"\n,\n\"Reuven\"\n,\n\"Revell\"\n,\n\"Reviel\"\n,\n\"Reviere\"\n,\n\"Revkah\"\n,\n\"Rew\"\n,\n\"Rex\"\n,\n\"Rexana\"\n,\n\"Rexanna\"\n,\n\"Rexanne\"\n,\n\"Rexer\"\n,\n\"Rexferd\"\n,\n\"Rexford\"\n,\n\"Rexfourd\"\n,\n\"Rey\"\n,\n\"Reyna\"\n,\n\"Reynard\"\n,\n\"Reynold\"\n,\n\"Reynolds\"\n,\n\"Rezzani\"\n,\n\"Rhea\"\n,\n\"Rheba\"\n,\n\"Rhee\"\n,\n\"Rheims\"\n,\n\"Rheingold\"\n,\n\"Rheinlander\"\n,\n\"Rheta\"\n,\n\"Rhett\"\n,\n\"Rhetta\"\n,\n\"Rhiamon\"\n,\n\"Rhiana\"\n,\n\"Rhianna\"\n,\n\"Rhianon\"\n,\n\"Rhine\"\n,\n\"Rhines\"\n,\n\"Rhoades\"\n,\n\"Rhoads\"\n,\n\"Rhoda\"\n,\n\"Rhodes\"\n,\n\"Rhodia\"\n,\n\"Rhodie\"\n,\n\"Rhody\"\n,\n\"Rhona\"\n,\n\"Rhonda\"\n,\n\"Rhu\"\n,\n\"Rhynd\"\n,\n\"Rhyne\"\n,\n\"Rhyner\"\n,\n\"Rhys\"\n,\n\"Ri\"\n,\n\"Ria\"\n,\n\"Riana\"\n,\n\"Riancho\"\n,\n\"Riane\"\n,\n\"Rianna\"\n,\n\"Riannon\"\n,\n\"Rianon\"\n,\n\"Riba\"\n,\n\"Ribal\"\n,\n\"Ribaudo\"\n,\n\"Ribble\"\n,\n\"Ric\"\n,\n\"Rica\"\n,\n\"Ricard\"\n,\n\"Ricarda\"\n,\n\"Ricardama\"\n,\n\"Ricardo\"\n,\n\"Ricca\"\n,\n\"Riccardo\"\n,\n\"Riccio\"\n,\n\"Rice\"\n,\n\"Rich\"\n,\n\"Richara\"\n,\n\"Richard\"\n,\n\"Richarda\"\n,\n\"Richardo\"\n,\n\"Richards\"\n,\n\"Richardson\"\n,\n\"Richart\"\n,\n\"Richel\"\n,\n\"Richela\"\n,\n\"Richella\"\n,\n\"Richelle\"\n,\n\"Richer\"\n,\n\"Richers\"\n,\n\"Richey\"\n,\n\"Richia\"\n,\n\"Richie\"\n,\n\"Richlad\"\n,\n\"Richma\"\n,\n\"Richmal\"\n,\n\"Richman\"\n,\n\"Richmond\"\n,\n\"Richmound\"\n,\n\"Richter\"\n,\n\"Richy\"\n,\n\"Rici\"\n,\n\"Rick\"\n,\n\"Rickard\"\n,\n\"Rickart\"\n,\n\"Ricker\"\n,\n\"Rickert\"\n,\n\"Ricketts\"\n,\n\"Rickey\"\n,\n\"Ricki\"\n,\n\"Rickie\"\n,\n\"Ricky\"\n,\n\"Rico\"\n,\n\"Ricoriki\"\n,\n\"Rida\"\n,\n\"Riddle\"\n,\n\"Rider\"\n,\n\"Ridglea\"\n,\n\"Ridglee\"\n,\n\"Ridgley\"\n,\n\"Ridinger\"\n,\n\"Ridley\"\n,\n\"Rie\"\n,\n\"Riebling\"\n,\n\"Riedel\"\n,\n\"Riegel\"\n,\n\"Rieger\"\n,\n\"Riehl\"\n,\n\"Riella\"\n,\n\"Ries\"\n,\n\"Riesman\"\n,\n\"Riess\"\n,\n\"Rieth\"\n,\n\"Riffle\"\n,\n\"Rifkin\"\n,\n\"Rigby\"\n,\n\"Rigdon\"\n,\n\"Riggall\"\n,\n\"Riggins\"\n,\n\"Riggs\"\n,\n\"Riha\"\n,\n\"Rihana\"\n,\n\"Rik\"\n,\n\"Rika\"\n,\n\"Riker\"\n,\n\"Riki\"\n,\n\"Rikki\"\n,\n\"Rilda\"\n,\n\"Riley\"\n,\n\"Rillings\"\n,\n\"Rillis\"\n,\n\"Rima\"\n,\n\"Rimas\"\n,\n\"Rimma\"\n,\n\"Rimola\"\n,\n\"Rina\"\n,\n\"Rinaldo\"\n,\n\"Rind\"\n,\n\"Rinee\"\n,\n\"Ring\"\n,\n\"Ringe\"\n,\n\"Ringler\"\n,\n\"Ringo\"\n,\n\"Ringsmuth\"\n,\n\"Rinna\"\n,\n\"Rintoul\"\n,\n\"Riobard\"\n,\n\"Riocard\"\n,\n\"Rior\"\n,\n\"Riordan\"\n,\n\"Riorsson\"\n,\n\"Rip\"\n,\n\"Ripleigh\"\n,\n\"Riplex\"\n,\n\"Ripley\"\n,\n\"Ripp\"\n,\n\"Risa\"\n,\n\"Rise\"\n,\n\"Risley\"\n,\n\"Rissa\"\n,\n\"Risser\"\n,\n\"Rist\"\n,\n\"Risteau\"\n,\n\"Rita\"\n,\n\"Ritch\"\n,\n\"Ritchie\"\n,\n\"Riti\"\n,\n\"Ritter\"\n,\n\"Ritz\"\n,\n\"Riva\"\n,\n\"Rivalee\"\n,\n\"Rivard\"\n,\n\"River\"\n,\n\"Rivera\"\n,\n\"Rivers\"\n,\n\"Rives\"\n,\n\"Rivi\"\n,\n\"Rivkah\"\n,\n\"Rivy\"\n,\n\"Rizas\"\n,\n\"Rizika\"\n,\n\"Rizzi\"\n,\n\"Rizzo\"\n,\n\"Ro\"\n,\n\"Roach\"\n,\n\"Roana\"\n,\n\"Roane\"\n,\n\"Roanna\"\n,\n\"Roanne\"\n,\n\"Roarke\"\n,\n\"Roath\"\n,\n\"Rob\"\n,\n\"Robaina\"\n,\n\"Robb\"\n,\n\"Robbert\"\n,\n\"Robbi\"\n,\n\"Robbie\"\n,\n\"Robbin\"\n,\n\"Robbins\"\n,\n\"Robby\"\n,\n\"Robbyn\"\n,\n\"Robena\"\n,\n\"Robenia\"\n,\n\"Robers\"\n,\n\"Roberson\"\n,\n\"Robert\"\n,\n\"Roberta\"\n,\n\"Roberto\"\n,\n\"Roberts\"\n,\n\"Robertson\"\n,\n\"Robet\"\n,\n\"Robi\"\n,\n\"Robillard\"\n,\n\"Robin\"\n,\n\"Robina\"\n,\n\"Robinet\"\n,\n\"Robinett\"\n,\n\"Robinetta\"\n,\n\"Robinette\"\n,\n\"Robinia\"\n,\n\"Robins\"\n,\n\"Robinson\"\n,\n\"Robison\"\n,\n\"Robson\"\n,\n\"Roby\"\n,\n\"Robyn\"\n,\n\"Rocca\"\n,\n\"Rocco\"\n,\n\"Roch\"\n,\n\"Roche\"\n,\n\"Rochell\"\n,\n\"Rochella\"\n,\n\"Rochelle\"\n,\n\"Rochemont\"\n,\n\"Rocher\"\n,\n\"Rochester\"\n,\n\"Rochette\"\n,\n\"Rochkind\"\n,\n\"Rochus\"\n,\n\"Rock\"\n,\n\"Rockafellow\"\n,\n\"Rockefeller\"\n,\n\"Rockel\"\n,\n\"Rocker\"\n,\n\"Rockey\"\n,\n\"Rockie\"\n,\n\"Rockwell\"\n,\n\"Rockwood\"\n,\n\"Rocky\"\n,\n\"Rocray\"\n,\n\"Rod\"\n,\n\"Roda\"\n,\n\"Rodd\"\n,\n\"Roddie\"\n,\n\"Roddy\"\n,\n\"Rodenhouse\"\n,\n\"Roderic\"\n,\n\"Roderica\"\n,\n\"Roderich\"\n,\n\"Roderick\"\n,\n\"Roderigo\"\n,\n\"Rodge\"\n,\n\"Rodger\"\n,\n\"Rodgers\"\n,\n\"Rodi\"\n,\n\"Rodie\"\n,\n\"Rodina\"\n,\n\"Rodl\"\n,\n\"Rodman\"\n,\n\"Rodmann\"\n,\n\"Rodmun\"\n,\n\"Rodmur\"\n,\n\"Rodney\"\n,\n\"Rodolfo\"\n,\n\"Rodolph\"\n,\n\"Rodolphe\"\n,\n\"Rodrich\"\n,\n\"Rodrick\"\n,\n\"Rodrigo\"\n,\n\"Rodriguez\"\n,\n\"Rodrique\"\n,\n\"Roe\"\n,\n\"Roede\"\n,\n\"Roee\"\n,\n\"Roehm\"\n,\n\"Roer\"\n,\n\"Roeser\"\n,\n\"Rog\"\n,\n\"Roger\"\n,\n\"Rogerio\"\n,\n\"Rogers\"\n,\n\"Rogerson\"\n,\n\"Rogovy\"\n,\n\"Rogozen\"\n,\n\"Rohn\"\n,\n\"Roi\"\n,\n\"Roice\"\n,\n\"Roid\"\n,\n\"Rois\"\n,\n\"Rojas\"\n,\n\"Rokach\"\n,\n\"Rola\"\n,\n\"Rolan\"\n,\n\"Roland\"\n,\n\"Rolanda\"\n,\n\"Rolando\"\n,\n\"Rolandson\"\n,\n\"Roldan\"\n,\n\"Roley\"\n,\n\"Rolf\"\n,\n\"Rolfe\"\n,\n\"Rolfston\"\n,\n\"Rolland\"\n,\n\"Rollet\"\n,\n\"Rollie\"\n,\n\"Rollin\"\n,\n\"Rollins\"\n,\n\"Rollo\"\n,\n\"Rolo\"\n,\n\"Rolph\"\n,\n\"Roma\"\n,\n\"Romain\"\n,\n\"Romaine\"\n,\n\"Romalda\"\n,\n\"Roman\"\n,\n\"Romanas\"\n,\n\"Romano\"\n,\n\"Rombert\"\n,\n\"Rome\"\n,\n\"Romelda\"\n,\n\"Romelle\"\n,\n\"Romeo\"\n,\n\"Romeon\"\n,\n\"Romeu\"\n,\n\"Romeyn\"\n,\n\"Romie\"\n,\n\"Romilda\"\n,\n\"Romilly\"\n,\n\"Romina\"\n,\n\"Romine\"\n,\n\"Romito\"\n,\n\"Romney\"\n,\n\"Romo\"\n,\n\"Romola\"\n,\n\"Romona\"\n,\n\"Romonda\"\n,\n\"Romulus\"\n,\n\"Romy\"\n,\n\"Ron\"\n,\n\"Rona\"\n,\n\"Ronal\"\n,\n\"Ronald\"\n,\n\"Ronalda\"\n,\n\"Ronda\"\n,\n\"Rondi\"\n,\n\"Rondon\"\n,\n\"Ronel\"\n,\n\"Ronen\"\n,\n\"Ronica\"\n,\n\"Ronn\"\n,\n\"Ronna\"\n,\n\"Ronnholm\"\n,\n\"Ronni\"\n,\n\"Ronnica\"\n,\n\"Ronnie\"\n,\n\"Ronny\"\n,\n\"Roobbie\"\n,\n\"Rooke\"\n,\n\"Rooker\"\n,\n\"Rooney\"\n,\n\"Roos\"\n,\n\"Roose\"\n,\n\"Roosevelt\"\n,\n\"Root\"\n,\n\"Roots\"\n,\n\"Roper\"\n,\n\"Roque\"\n,\n\"Rora\"\n,\n\"Rori\"\n,\n\"Rorie\"\n,\n\"Rorke\"\n,\n\"Rorry\"\n,\n\"Rorrys\"\n,\n\"Rory\"\n,\n\"Ros\"\n,\n\"Rosa\"\n,\n\"Rosabel\"\n,\n\"Rosabella\"\n,\n\"Rosabelle\"\n,\n\"Rosalba\"\n,\n\"Rosalee\"\n,\n\"Rosaleen\"\n,\n\"Rosalia\"\n,\n\"Rosalie\"\n,\n\"Rosalind\"\n,\n\"Rosalinda\"\n,\n\"Rosalinde\"\n,\n\"Rosaline\"\n,\n\"Rosalyn\"\n,\n\"Rosalynd\"\n,\n\"Rosamond\"\n,\n\"Rosamund\"\n,\n\"Rosana\"\n,\n\"Rosane\"\n,\n\"Rosanna\"\n,\n\"Rosanne\"\n,\n\"Rosario\"\n,\n\"Rosati\"\n,\n\"Rosco\"\n,\n\"Roscoe\"\n,\n\"Rose\"\n,\n\"Roseann\"\n,\n\"Roseanna\"\n,\n\"Roseanne\"\n,\n\"Rosecan\"\n,\n\"Rosel\"\n,\n\"Roselane\"\n,\n\"Roselani\"\n,\n\"Roselba\"\n,\n\"Roselia\"\n,\n\"Roselin\"\n,\n\"Roseline\"\n,\n\"Rosella\"\n,\n\"Roselle\"\n,\n\"Roselyn\"\n,\n\"Rosemare\"\n,\n\"Rosemari\"\n,\n\"Rosemaria\"\n,\n\"Rosemarie\"\n,\n\"Rosemary\"\n,\n\"Rosemonde\"\n,\n\"Rosen\"\n,\n\"Rosena\"\n,\n\"Rosenbaum\"\n,\n\"Rosenberg\"\n,\n\"Rosenberger\"\n,\n\"Rosenblast\"\n,\n\"Rosenblatt\"\n,\n\"Rosenblum\"\n,\n\"Rosene\"\n,\n\"Rosenfeld\"\n,\n\"Rosenkrantz\"\n,\n\"Rosenkranz\"\n,\n\"Rosenquist\"\n,\n\"Rosenstein\"\n,\n\"Rosenthal\"\n,\n\"Rosenwald\"\n,\n\"Rosenzweig\"\n,\n\"Rosetta\"\n,\n\"Rosette\"\n,\n\"Roshan\"\n,\n\"Roshelle\"\n,\n\"Rosie\"\n,\n\"Rosina\"\n,\n\"Rosinski\"\n,\n\"Rosio\"\n,\n\"Rosita\"\n,\n\"Roskes\"\n,\n\"Roslyn\"\n,\n\"Rosmarin\"\n,\n\"Rosmunda\"\n,\n\"Rosner\"\n,\n\"Rosol\"\n,\n\"Ross\"\n,\n\"Rosse\"\n,\n\"Rossen\"\n,\n\"Rossi\"\n,\n\"Rossie\"\n,\n\"Rossing\"\n,\n\"Rossner\"\n,\n\"Rossuck\"\n,\n\"Rossy\"\n,\n\"Rostand\"\n,\n\"Roswald\"\n,\n\"Roswell\"\n,\n\"Rosy\"\n,\n\"Rotberg\"\n,\n\"Roter\"\n,\n\"Roth\"\n,\n\"Rothberg\"\n,\n\"Rothenberg\"\n,\n\"Rother\"\n,\n\"Rothmuller\"\n,\n\"Rothschild\"\n,\n\"Rothstein\"\n,\n\"Rothwell\"\n,\n\"Roti\"\n,\n\"Rotman\"\n,\n\"Rotow\"\n,\n\"Roumell\"\n,\n\"Rourke\"\n,\n\"Routh\"\n,\n\"Rouvin\"\n,\n\"Roux\"\n,\n\"Rovelli\"\n,\n\"Rovit\"\n,\n\"Rovner\"\n,\n\"Row\"\n,\n\"Rowan\"\n,\n\"Rowe\"\n,\n\"Rowell\"\n,\n\"Rowen\"\n,\n\"Rowena\"\n,\n\"Rowland\"\n,\n\"Rowley\"\n,\n\"Rowney\"\n,\n\"Rox\"\n,\n\"Roxana\"\n,\n\"Roxane\"\n,\n\"Roxanna\"\n,\n\"Roxanne\"\n,\n\"Roxi\"\n,\n\"Roxie\"\n,\n\"Roxine\"\n,\n\"Roxy\"\n,\n\"Roy\"\n,\n\"Royal\"\n,\n\"Royall\"\n,\n\"Roybn\"\n,\n\"Royce\"\n,\n\"Royd\"\n,\n\"Roydd\"\n,\n\"Royden\"\n,\n\"Roye\"\n,\n\"Royo\"\n,\n\"Roz\"\n,\n\"Rozalie\"\n,\n\"Rozalin\"\n,\n\"Rozamond\"\n,\n\"Rozanna\"\n,\n\"Rozanne\"\n,\n\"Roze\"\n,\n\"Rozek\"\n,\n\"Rozele\"\n,\n\"Rozella\"\n,\n\"Rozelle\"\n,\n\"Rozina\"\n,\n\"Rriocard\"\n,\n\"Ru\"\n,\n\"Rubbico\"\n,\n\"Rube\"\n,\n\"Rubel\"\n,\n\"Ruben\"\n,\n\"Rubens\"\n,\n\"Rubenstein\"\n,\n\"Ruberta\"\n,\n\"Rubetta\"\n,\n\"Rubi\"\n,\n\"Rubia\"\n,\n\"Rubie\"\n,\n\"Rubin\"\n,\n\"Rubina\"\n,\n\"Rubinstein\"\n,\n\"Rubio\"\n,\n\"Ruby\"\n,\n\"Rucker\"\n,\n\"Ruckman\"\n,\n\"Rudd\"\n,\n\"Ruddie\"\n,\n\"Ruddy\"\n,\n\"Rudelson\"\n,\n\"Ruder\"\n,\n\"Rudich\"\n,\n\"Rudie\"\n,\n\"Rudiger\"\n,\n\"Rudin\"\n,\n\"Rudman\"\n,\n\"Rudolf\"\n,\n\"Rudolfo\"\n,\n\"Rudolph\"\n,\n\"Rudwik\"\n,\n\"Rudy\"\n,\n\"Rudyard\"\n,\n\"Rue\"\n,\n\"Ruel\"\n,\n\"Ruella\"\n,\n\"Ruelle\"\n,\n\"Ruelu\"\n,\n\"Rufe\"\n,\n\"Rufena\"\n,\n\"Ruff\"\n,\n\"Ruffi\"\n,\n\"Ruffin\"\n,\n\"Ruffina\"\n,\n\"Ruffo\"\n,\n\"Rufford\"\n,\n\"Rufina\"\n,\n\"Ruford\"\n,\n\"Rufus\"\n,\n\"Rugen\"\n,\n\"Rugg\"\n,\n\"Ruggiero\"\n,\n\"Ruhl\"\n,\n\"Ruhnke\"\n,\n\"Ruiz\"\n,\n\"Rumery\"\n,\n\"Rumilly\"\n,\n\"Rumney\"\n,\n\"Rumpf\"\n,\n\"Runck\"\n,\n\"Rundgren\"\n,\n\"Runkel\"\n,\n\"Runkle\"\n,\n\"Runstadler\"\n,\n\"Rupert\"\n,\n\"Ruperta\"\n,\n\"Ruperto\"\n,\n\"Ruphina\"\n,\n\"Ruprecht\"\n,\n\"Rurik\"\n,\n\"Rus\"\n,\n\"Ruscher\"\n,\n\"Ruscio\"\n,\n\"Rusel\"\n,\n\"Rusell\"\n,\n\"Rusert\"\n,\n\"Rush\"\n,\n\"Rushing\"\n,\n\"Ruskin\"\n,\n\"Russ\"\n,\n\"Russel\"\n,\n\"Russell\"\n,\n\"Russi\"\n,\n\"Russia\"\n,\n\"Russian\"\n,\n\"Russo\"\n,\n\"Russom\"\n,\n\"Russon\"\n,\n\"Rust\"\n,\n\"Rustice\"\n,\n\"Rusticus\"\n,\n\"Rustie\"\n,\n\"Rustin\"\n,\n\"Rusty\"\n,\n\"Rutan\"\n,\n\"Rutger\"\n,\n\"Ruth\"\n,\n\"Ruthann\"\n,\n\"Ruthanne\"\n,\n\"Ruthe\"\n,\n\"Rutherford\"\n,\n\"Rutherfurd\"\n,\n\"Ruthi\"\n,\n\"Ruthie\"\n,\n\"Ruthven\"\n,\n\"Ruthy\"\n,\n\"Rutledge\"\n,\n\"Rutter\"\n,\n\"Ruttger\"\n,\n\"Ruvolo\"\n,\n\"Ruy\"\n,\n\"Ruyle\"\n,\n\"Ruzich\"\n,\n\"Ryan\"\n,\n\"Ryann\"\n,\n\"Rycca\"\n,\n\"Rydder\"\n,\n\"Ryder\"\n,\n\"Rye\"\n,\n\"Ryle\"\n,\n\"Ryley\"\n,\n\"Ryon\"\n,\n\"Rysler\"\n,\n\"Ryter\"\n,\n\"Ryun\"\n,\n\"Saba\"\n,\n\"Sabah\"\n,\n\"Sabba\"\n,\n\"Sabec\"\n,\n\"Sabella\"\n,\n\"Sabelle\"\n,\n\"Saber\"\n,\n\"Saberhagen\"\n,\n\"Saberio\"\n,\n\"Sabian\"\n,\n\"Sabina\"\n,\n\"Sabine\"\n,\n\"Sabino\"\n,\n\"Sabir\"\n,\n\"Sabra\"\n,\n\"Sabrina\"\n,\n\"Sabsay\"\n,\n\"Sabu\"\n,\n\"Sacci\"\n,\n\"Sacha\"\n,\n\"Sachi\"\n,\n\"Sachiko\"\n,\n\"Sachs\"\n,\n\"Sachsse\"\n,\n\"Sacken\"\n,\n\"Sackey\"\n,\n\"Sackman\"\n,\n\"Sacks\"\n,\n\"Sacksen\"\n,\n\"Sackville\"\n,\n\"Sacttler\"\n,\n\"Sad\"\n,\n\"Sada\"\n,\n\"Saddler\"\n,\n\"Sadella\"\n,\n\"Sadick\"\n,\n\"Sadie\"\n,\n\"Sadira\"\n,\n\"Sadirah\"\n,\n\"Sadiras\"\n,\n\"Sadler\"\n,\n\"Sadoc\"\n,\n\"Sadoff\"\n,\n\"Sadonia\"\n,\n\"Sadowski\"\n,\n\"Sadye\"\n,\n\"Saeger\"\n,\n\"Saffian\"\n,\n\"Saffier\"\n,\n\"Saffren\"\n,\n\"Safier\"\n,\n\"Safir\"\n,\n\"Safire\"\n,\n\"Safko\"\n,\n\"Sage\"\n,\n\"Sager\"\n,\n\"Sagerman\"\n,\n\"Saidee\"\n,\n\"Saidel\"\n,\n\"Saideman\"\n,\n\"Saied\"\n,\n\"Saiff\"\n,\n\"Sailesh\"\n,\n\"Saimon\"\n,\n\"Saint\"\n,\n\"Sair\"\n,\n\"Saire\"\n,\n\"Saito\"\n,\n\"Sajovich\"\n,\n\"Sakhuja\"\n,\n\"Sakmar\"\n,\n\"Sakovich\"\n,\n\"Saks\"\n,\n\"Sal\"\n,\n\"Salahi\"\n,\n\"Salaidh\"\n,\n\"Salamanca\"\n,\n\"Salamone\"\n,\n\"Salangi\"\n,\n\"Salangia\"\n,\n\"Salas\"\n,\n\"Salazar\"\n,\n\"Salba\"\n,\n\"Salbu\"\n,\n\"Salchunas\"\n,\n\"Sale\"\n,\n\"Saleem\"\n,\n\"Salem\"\n,\n\"Salema\"\n,\n\"Saleme\"\n,\n\"Salena\"\n,\n\"Salene\"\n,\n\"Salesin\"\n,\n\"Salim\"\n,\n\"Salina\"\n,\n\"Salinas\"\n,\n\"Salisbarry\"\n,\n\"Salisbury\"\n,\n\"Salita\"\n,\n\"Sall\"\n,\n\"Sallee\"\n,\n\"Salli\"\n,\n\"Sallie\"\n,\n\"Sally\"\n,\n\"Sallyann\"\n,\n\"Sallyanne\"\n,\n\"Salman\"\n,\n\"Salmon\"\n,\n\"Saloma\"\n,\n\"Salome\"\n,\n\"Salomi\"\n,\n\"Salomie\"\n,\n\"Salomo\"\n,\n\"Salomon\"\n,\n\"Salomone\"\n,\n\"Salot\"\n,\n\"Salsbury\"\n,\n\"Salter\"\n,\n\"Saltsman\"\n,\n\"Saltzman\"\n,\n\"Salvador\"\n,\n\"Salvadore\"\n,\n\"Salvatore\"\n,\n\"Salvay\"\n,\n\"Salvidor\"\n,\n\"Salvucci\"\n,\n\"Salzhauer\"\n,\n\"Sam\"\n,\n\"Sama\"\n,\n\"Samal\"\n,\n\"Samala\"\n,\n\"Samale\"\n,\n\"Samalla\"\n,\n\"Samantha\"\n,\n\"Samanthia\"\n,\n\"Samara\"\n,\n\"Samaria\"\n,\n\"Samau\"\n,\n\"Samella\"\n,\n\"Samford\"\n,\n\"Sami\"\n,\n\"Samira\"\n,\n\"Sammer\"\n,\n\"Sammie\"\n,\n\"Sammons\"\n,\n\"Sammy\"\n,\n\"Samp\"\n,\n\"Sampson\"\n,\n\"Sams\"\n,\n\"Samson\"\n,\n\"Samuel\"\n,\n\"Samuela\"\n,\n\"Samuele\"\n,\n\"Samuella\"\n,\n\"Samuelson\"\n,\n\"Samul\"\n,\n\"Samy\"\n,\n\"Sanalda\"\n,\n\"Sanbo\"\n,\n\"Sanborn\"\n,\n\"Sanborne\"\n,\n\"Sanburn\"\n,\n\"Sancha\"\n,\n\"Sanchez\"\n,\n\"Sancho\"\n,\n\"Sand\"\n,\n\"Sandberg\"\n,\n\"Sande\"\n,\n\"Sandeep\"\n,\n\"Sandell\"\n,\n\"Sander\"\n,\n\"Sanders\"\n,\n\"Sanderson\"\n,\n\"Sandi\"\n,\n\"Sandie\"\n,\n\"Sandler\"\n,\n\"Sandon\"\n,\n\"Sandor\"\n,\n\"Sandra\"\n,\n\"Sandro\"\n,\n\"Sandry\"\n,\n\"Sands\"\n,\n\"Sandstrom\"\n,\n\"Sandy\"\n,\n\"Sandye\"\n,\n\"Sanferd\"\n,\n\"Sanfo\"\n,\n\"Sanford\"\n,\n\"Sanfourd\"\n,\n\"Sanfred\"\n,\n\"Sang\"\n,\n\"Sanger\"\n,\n\"Sanjay\"\n,\n\"Sanjiv\"\n,\n\"Sankaran\"\n,\n\"Sankey\"\n,\n\"Sansbury\"\n,\n\"Sansen\"\n,\n\"Sanson\"\n,\n\"Sansone\"\n,\n\"Santa\"\n,\n\"Santana\"\n,\n\"Santiago\"\n,\n\"Santini\"\n,\n\"Santoro\"\n,\n\"Santos\"\n,\n\"Sanyu\"\n,\n\"Sapers\"\n,\n\"Saphra\"\n,\n\"Sapienza\"\n,\n\"Sapowith\"\n,\n\"Sapphera\"\n,\n\"Sapphira\"\n,\n\"Sapphire\"\n,\n\"Sara\"\n,\n\"Sara-Ann\"\n,\n\"Saraann\"\n,\n\"Sarad\"\n,\n\"Sarah\"\n,\n\"Saraiya\"\n,\n\"Sarajane\"\n,\n\"Sarazen\"\n,\n\"Sarchet\"\n,\n\"Sardella\"\n,\n\"Saree\"\n,\n\"Sarena\"\n,\n\"Sarene\"\n,\n\"Saretta\"\n,\n\"Sarette\"\n,\n\"Sarge\"\n,\n\"Sargent\"\n,\n\"Sari\"\n,\n\"Sarid\"\n,\n\"Sarilda\"\n,\n\"Sarina\"\n,\n\"Sarine\"\n,\n\"Sarita\"\n,\n\"Sarkaria\"\n,\n\"Sarnoff\"\n,\n\"Sarson\"\n,\n\"Sartin\"\n,\n\"Sascha\"\n,\n\"Sasha\"\n,\n\"Sashenka\"\n,\n\"Sasnett\"\n,\n\"Sass\"\n,\n\"Sassan\"\n,\n\"Sateia\"\n,\n\"Sathrum\"\n,\n\"Sato\"\n,\n\"Satterfield\"\n,\n\"Satterlee\"\n,\n\"Saturday\"\n,\n\"Saucy\"\n,\n\"Sauder\"\n,\n\"Saudra\"\n,\n\"Sauer\"\n,\n\"Sauers\"\n,\n\"Saul\"\n,\n\"Sauls\"\n,\n\"Saum\"\n,\n\"Sauncho\"\n,\n\"Saunder\"\n,\n\"Saunders\"\n,\n\"Saunderson\"\n,\n\"Saundra\"\n,\n\"Sausa\"\n,\n\"Sauveur\"\n,\n\"Savadove\"\n,\n\"Savage\"\n,\n\"Saval\"\n,\n\"Savanna\"\n,\n\"Savannah\"\n,\n\"Savdeep\"\n,\n\"Savell\"\n,\n\"Savick\"\n,\n\"Savil\"\n,\n\"Savill\"\n,\n\"Saville\"\n,\n\"Savina\"\n,\n\"Savior\"\n,\n\"Savitt\"\n,\n\"Savory\"\n,\n\"Saw\"\n,\n\"Sawtelle\"\n,\n\"Sawyer\"\n,\n\"Sawyere\"\n,\n\"Sawyor\"\n,\n\"Sax\"\n,\n\"Saxe\"\n,\n\"Saxen\"\n,\n\"Saxena\"\n,\n\"Saxon\"\n,\n\"Say\"\n,\n\"Sayce\"\n,\n\"Sayed\"\n,\n\"Sayer\"\n,\n\"Sayers\"\n,\n\"Sayette\"\n,\n\"Sayles\"\n,\n\"Saylor\"\n,\n\"Sayre\"\n,\n\"Sayres\"\n,\n\"Scales\"\n,\n\"Scammon\"\n,\n\"Scandura\"\n,\n\"Scarface\"\n,\n\"Scarito\"\n,\n\"Scarlet\"\n,\n\"Scarlett\"\n,\n\"Scarrow\"\n,\n\"Scever\"\n,\n\"Scevo\"\n,\n\"Scevor\"\n,\n\"Scevour\"\n,\n\"Schaab\"\n,\n\"Schaaff\"\n,\n\"Schach\"\n,\n\"Schacker\"\n,\n\"Schaefer\"\n,\n\"Schaeffer\"\n,\n\"Schafer\"\n,\n\"Schaffel\"\n,\n\"Schaffer\"\n,\n\"Schalles\"\n,\n\"Schaper\"\n,\n\"Schapira\"\n,\n\"Scharaga\"\n,\n\"Scharf\"\n,\n\"Scharff\"\n,\n\"Schargel\"\n,\n\"Schatz\"\n,\n\"Schaumberger\"\n,\n\"Schear\"\n,\n\"Schechinger\"\n,\n\"Schechter\"\n,\n\"Scheck\"\n,\n\"Schecter\"\n,\n\"Scheer\"\n,\n\"Scheers\"\n,\n\"Scheider\"\n,\n\"Scheld\"\n,\n\"Schell\"\n,\n\"Schellens\"\n,\n\"Schenck\"\n,\n\"Scherle\"\n,\n\"Scherman\"\n,\n\"Schertz\"\n,\n\"Schick\"\n,\n\"Schiff\"\n,\n\"Schiffman\"\n,\n\"Schifra\"\n,\n\"Schild\"\n,\n\"Schilit\"\n,\n\"Schilling\"\n,\n\"Schilt\"\n,\n\"Schindler\"\n,\n\"Schinica\"\n,\n\"Schiro\"\n,\n\"Schlenger\"\n,\n\"Schlesinger\"\n,\n\"Schlessel\"\n,\n\"Schlessinger\"\n,\n\"Schlicher\"\n,\n\"Schlosser\"\n,\n\"Schluter\"\n,\n\"Schmeltzer\"\n,\n\"Schmidt\"\n,\n\"Schmitt\"\n,\n\"Schmitz\"\n,\n\"Schnabel\"\n,\n\"Schnapp\"\n,\n\"Schnell\"\n,\n\"Schnorr\"\n,\n\"Schnur\"\n,\n\"Schnurr\"\n,\n\"Schober\"\n,\n\"Schoenberg\"\n,\n\"Schoenburg\"\n,\n\"Schoenfelder\"\n,\n\"Schoening\"\n,\n\"Schofield\"\n,\n\"Scholem\"\n,\n\"Scholz\"\n,\n\"Schonfeld\"\n,\n\"Schonfield\"\n,\n\"Schonthal\"\n,\n\"Schoof\"\n,\n\"Schott\"\n,\n\"Schou\"\n,\n\"Schouten\"\n,\n\"Schrader\"\n,\n\"Schram\"\n,\n\"Schramke\"\n,\n\"Schreck\"\n,\n\"Schreib\"\n,\n\"Schreibe\"\n,\n\"Schreiber\"\n,\n\"Schreibman\"\n,\n\"Schrick\"\n,\n\"Schriever\"\n,\n\"Schroder\"\n,\n\"Schroeder\"\n,\n\"Schroer\"\n,\n\"Schroth\"\n,\n\"Schubert\"\n,\n\"Schug\"\n,\n\"Schuh\"\n,\n\"Schulein\"\n,\n\"Schuler\"\n,\n\"Schulman\"\n,\n\"Schultz\"\n,\n\"Schulz\"\n,\n\"Schulze\"\n,\n\"Schuman\"\n,\n\"Schumer\"\n,\n\"Schurman\"\n,\n\"Schuster\"\n,\n\"Schuyler\"\n,\n\"Schwab\"\n,\n\"Schwartz\"\n,\n\"Schwarz\"\n,\n\"Schweiker\"\n,\n\"Schweitzer\"\n,\n\"Schwejda\"\n,\n\"Schwenk\"\n,\n\"Schwerin\"\n,\n\"Schwing\"\n,\n\"Schwinn\"\n,\n\"Schwitzer\"\n,\n\"Scibert\"\n,\n\"Sclar\"\n,\n\"Sclater\"\n,\n\"Scoles\"\n,\n\"Scopp\"\n,\n\"Scornik\"\n,\n\"Scot\"\n,\n\"Scoter\"\n,\n\"Scotney\"\n,\n\"Scott\"\n,\n\"Scotti\"\n,\n\"Scottie\"\n,\n\"Scotty\"\n,\n\"Scoville\"\n,\n\"Screens\"\n,\n\"Scribner\"\n,\n\"Scriven\"\n,\n\"Scrivenor\"\n,\n\"Scrivens\"\n,\n\"Scrivings\"\n,\n\"Scrogan\"\n,\n\"Scrope\"\n,\n\"Sculley\"\n,\n\"Scully\"\n,\n\"Scurlock\"\n,\n\"Scutt\"\n,\n\"Seabrook\"\n,\n\"Seabrooke\"\n,\n\"Seabury\"\n,\n\"Seaddon\"\n,\n\"Seaden\"\n,\n\"Seadon\"\n,\n\"Seafowl\"\n,\n\"Seagrave\"\n,\n\"Seagraves\"\n,\n\"Seale\"\n,\n\"Seaman\"\n,\n\"Seamus\"\n,\n\"Sean\"\n,\n\"Seana\"\n,\n\"Searby\"\n,\n\"Searcy\"\n,\n\"Searle\"\n,\n\"Sears\"\n,\n\"Season\"\n,\n\"Seaton\"\n,\n\"Seaver\"\n,\n\"Seavey\"\n,\n\"Seavir\"\n,\n\"Sebastian\"\n,\n\"Sebastiano\"\n,\n\"Sebastien\"\n,\n\"Sebbie\"\n,\n\"Secor\"\n,\n\"Secrest\"\n,\n\"Secunda\"\n,\n\"Secundas\"\n,\n\"Seda\"\n,\n\"Sedberry\"\n,\n\"Sedda\"\n,\n\"Sedgewake\"\n,\n\"Sedgewick\"\n,\n\"Sedgewinn\"\n,\n\"Sedlik\"\n,\n\"See\"\n,\n\"Seebeck\"\n,\n\"Seed\"\n,\n\"Seedman\"\n,\n\"Seel\"\n,\n\"Seely\"\n,\n\"Seem\"\n,\n\"Seema\"\n,\n\"Seen\"\n,\n\"Seena\"\n,\n\"Seessel\"\n,\n\"Seeto\"\n,\n\"Seften\"\n,\n\"Sefton\"\n,\n\"Seftton\"\n,\n\"Segal\"\n,\n\"Segalman\"\n,\n\"Seiber\"\n,\n\"Seibold\"\n,\n\"Seidel\"\n,\n\"Seiden\"\n,\n\"Seidler\"\n,\n\"Seidule\"\n,\n\"Seif\"\n,\n\"Seigel\"\n,\n\"Seigler\"\n,\n\"Seiter\"\n,\n\"Seitz\"\n,\n\"Seka\"\n,\n\"Seko\"\n,\n\"Sekofski\"\n,\n\"Sekyere\"\n,\n\"Sela\"\n,\n\"Selassie\"\n,\n\"Selby\"\n,\n\"Selda\"\n,\n\"Seldan\"\n,\n\"Selden\"\n,\n\"Seldon\"\n,\n\"Seldun\"\n,\n\"Selemas\"\n,\n\"Selena\"\n,\n\"Selene\"\n,\n\"Selestina\"\n,\n\"Seleta\"\n,\n\"Selfridge\"\n,\n\"Selhorst\"\n,\n\"Selia\"\n,\n\"Selie\"\n,\n\"Selig\"\n,\n\"Seligman\"\n,\n\"Seligmann\"\n,\n\"Selima\"\n,\n\"Selimah\"\n,\n\"Selina\"\n,\n\"Selinda\"\n,\n\"Seline\"\n,\n\"Selinski\"\n,\n\"Sell\"\n,\n\"Sella\"\n,\n\"Selle\"\n,\n\"Sellers\"\n,\n\"Sellma\"\n,\n\"Sello\"\n,\n\"Sells\"\n,\n\"Selma\"\n,\n\"Selmner\"\n,\n\"Selmore\"\n,\n\"Selry\"\n,\n\"Seltzer\"\n,\n\"Selway\"\n,\n\"Selwin\"\n,\n\"Selwyn\"\n,\n\"Semela\"\n,\n\"Semele\"\n,\n\"Semmes\"\n,\n\"Sena\"\n,\n\"Senalda\"\n,\n\"Sender\"\n,\n\"Senecal\"\n,\n\"Senhauser\"\n,\n\"Senior\"\n,\n\"Senn\"\n,\n\"Sension\"\n,\n\"Senskell\"\n,\n\"Senzer\"\n,\n\"Seow\"\n,\n\"Sephira\"\n,\n\"Seppala\"\n,\n\"September\"\n,\n\"Septima\"\n,\n\"Sera\"\n,\n\"Serafina\"\n,\n\"Serafine\"\n,\n\"Seraphim\"\n,\n\"Seraphina\"\n,\n\"Seraphine\"\n,\n\"Serena\"\n,\n\"Serene\"\n,\n\"Serg\"\n,\n\"Serge\"\n,\n\"Sergeant\"\n,\n\"Sergei\"\n,\n\"Sergent\"\n,\n\"Sergias\"\n,\n\"Sergio\"\n,\n\"Sergius\"\n,\n\"Sergo\"\n,\n\"Sergu\"\n,\n\"Serica\"\n,\n\"Serilda\"\n,\n\"Serle\"\n,\n\"Serles\"\n,\n\"Seroka\"\n,\n\"Serra\"\n,\n\"Serrano\"\n,\n\"Serrell\"\n,\n\"Servais\"\n,\n\"Server\"\n,\n\"Servetnick\"\n,\n\"Service\"\n,\n\"Sessler\"\n,\n\"Seta\"\n,\n\"Seth\"\n,\n\"Sethi\"\n,\n\"Sethrida\"\n,\n\"Seto\"\n,\n\"Seton\"\n,\n\"Settera\"\n,\n\"Settle\"\n,\n\"Seumas\"\n,\n\"Sev\"\n,\n\"Seve\"\n,\n\"Severen\"\n,\n\"Severin\"\n,\n\"Severn\"\n,\n\"Severson\"\n,\n\"Sevik\"\n,\n\"Seward\"\n,\n\"Sewel\"\n,\n\"Sewell\"\n,\n\"Sewellyn\"\n,\n\"Sewole\"\n,\n\"Sewoll\"\n,\n\"Sexton\"\n,\n\"Seyler\"\n,\n\"Seymour\"\n,\n\"Seys\"\n,\n\"Sezen\"\n,\n\"Shabbir\"\n,\n\"Shaddock\"\n,\n\"Shadow\"\n,\n\"Shae\"\n,\n\"Shaefer\"\n,\n\"Shaeffer\"\n,\n\"Shaer\"\n,\n\"Shafer\"\n,\n\"Shaff\"\n,\n\"Shaffer\"\n,\n\"Shaffert\"\n,\n\"Shah\"\n,\n\"Shaia\"\n,\n\"Shaikh\"\n,\n\"Shaina\"\n,\n\"Shaine\"\n,\n\"Shakespeare\"\n,\n\"Shakti\"\n,\n\"Shalna\"\n,\n\"Shalne\"\n,\n\"Shalom\"\n,\n\"Shama\"\n,\n\"Shamma\"\n,\n\"Shamrao\"\n,\n\"Shamus\"\n,\n\"Shana\"\n,\n\"Shanahan\"\n,\n\"Shanan\"\n,\n\"Shanda\"\n,\n\"Shandee\"\n,\n\"Shandeigh\"\n,\n\"Shandie\"\n,\n\"Shandra\"\n,\n\"Shandy\"\n,\n\"Shane\"\n,\n\"Shaner\"\n,\n\"Shani\"\n,\n\"Shanie\"\n,\n\"Shank\"\n,\n\"Shanks\"\n,\n\"Shanleigh\"\n,\n\"Shanley\"\n,\n\"Shanly\"\n,\n\"Shanna\"\n,\n\"Shannah\"\n,\n\"Shannan\"\n,\n\"Shannen\"\n,\n\"Shanney\"\n,\n\"Shannon\"\n,\n\"Shanon\"\n,\n\"Shanta\"\n,\n\"Shantee\"\n,\n\"Shantha\"\n,\n\"Shaper\"\n,\n\"Shapiro\"\n,\n\"Shara\"\n,\n\"Sharai\"\n,\n\"Shargel\"\n,\n\"Shari\"\n,\n\"Sharia\"\n,\n\"Sharity\"\n,\n\"Sharl\"\n,\n\"Sharla\"\n,\n\"Sharleen\"\n,\n\"Sharlene\"\n,\n\"Sharline\"\n,\n\"Sharma\"\n,\n\"Sharman\"\n,\n\"Sharon\"\n,\n\"Sharona\"\n,\n\"Sharos\"\n,\n\"Sharp\"\n,\n\"Sharpe\"\n,\n\"Sharron\"\n,\n\"Sharyl\"\n,\n\"Shatzer\"\n,\n\"Shaughn\"\n,\n\"Shaughnessy\"\n,\n\"Shaum\"\n,\n\"Shaun\"\n,\n\"Shauna\"\n,\n\"Shaver\"\n,\n\"Shaw\"\n,\n\"Shawn\"\n,\n\"Shawna\"\n,\n\"Shawnee\"\n,\n\"Shay\"\n,\n\"Shaya\"\n,\n\"Shayla\"\n,\n\"Shaylah\"\n,\n\"Shaylyn\"\n,\n\"Shaylynn\"\n,\n\"Shayn\"\n,\n\"Shayna\"\n,\n\"Shayne\"\n,\n\"Shea\"\n,\n\"Sheaff\"\n,\n\"Shear\"\n,\n\"Sheba\"\n,\n\"Shedd\"\n,\n\"Sheeb\"\n,\n\"Sheedy\"\n,\n\"Sheehan\"\n,\n\"Sheela\"\n,\n\"Sheelagh\"\n,\n\"Sheelah\"\n,\n\"Sheena\"\n,\n\"Sheepshanks\"\n,\n\"Sheeran\"\n,\n\"Sheeree\"\n,\n\"Sheets\"\n,\n\"Sheff\"\n,\n\"Sheffie\"\n,\n\"Sheffield\"\n,\n\"Sheffy\"\n,\n\"Sheila\"\n,\n\"Sheilah\"\n,\n\"Shel\"\n,\n\"Shela\"\n,\n\"Shelagh\"\n,\n\"Shelah\"\n,\n\"Shelba\"\n,\n\"Shelbi\"\n,\n\"Shelburne\"\n,\n\"Shelby\"\n,\n\"Shelden\"\n,\n\"Sheldon\"\n,\n\"Sheley\"\n,\n\"Shelia\"\n,\n\"Sheline\"\n,\n\"Shell\"\n,\n\"Shellans\"\n,\n\"Shelley\"\n,\n\"Shelli\"\n,\n\"Shellie\"\n,\n\"Shelly\"\n,\n\"Shelman\"\n,\n\"Shelton\"\n,\n\"Shem\"\n,\n\"Shena\"\n,\n\"Shenan\"\n,\n\"Sheng\"\n,\n\"Shep\"\n,\n\"Shepard\"\n,\n\"Shepherd\"\n,\n\"Shepley\"\n,\n\"Sheply\"\n,\n\"Shepp\"\n,\n\"Sheppard\"\n,\n\"Shepperd\"\n,\n\"Sher\"\n,\n\"Sherar\"\n,\n\"Sherard\"\n,\n\"Sherborn\"\n,\n\"Sherborne\"\n,\n\"Sherburn\"\n,\n\"Sherburne\"\n,\n\"Shere\"\n,\n\"Sheree\"\n,\n\"Sherer\"\n,\n\"Shererd\"\n,\n\"Sherfield\"\n,\n\"Sheri\"\n,\n\"Sheridan\"\n,\n\"Sherie\"\n,\n\"Sherill\"\n,\n\"Sherilyn\"\n,\n\"Sherj\"\n,\n\"Sherl\"\n,\n\"Sherline\"\n,\n\"Sherlock\"\n,\n\"Sherlocke\"\n,\n\"Sherm\"\n,\n\"Sherman\"\n,\n\"Shermie\"\n,\n\"Shermy\"\n,\n\"Sherourd\"\n,\n\"Sherr\"\n,\n\"Sherrard\"\n,\n\"Sherrer\"\n,\n\"Sherri\"\n,\n\"Sherrie\"\n,\n\"Sherrill\"\n,\n\"Sherris\"\n,\n\"Sherrod\"\n,\n\"Sherry\"\n,\n\"Sherurd\"\n,\n\"Sherwin\"\n,\n\"Sherwood\"\n,\n\"Sherwynd\"\n,\n\"Sherye\"\n,\n\"Sheryl\"\n,\n\"Sheryle\"\n,\n\"Shetrit\"\n,\n\"Shevlo\"\n,\n\"Shewchuk\"\n,\n\"Shewmaker\"\n,\n\"Sheya\"\n,\n\"Shiau\"\n,\n\"Shieh\"\n,\n\"Shiekh\"\n,\n\"Shields\"\n,\n\"Shien\"\n,\n\"Shiff\"\n,\n\"Shifra\"\n,\n\"Shifrah\"\n,\n\"Shig\"\n,\n\"Shih\"\n,\n\"Shiller\"\n,\n\"Shimberg\"\n,\n\"Shimkus\"\n,\n\"Shina\"\n,\n\"Shinberg\"\n,\n\"Shing\"\n,\n\"Shipley\"\n,\n\"Shipman\"\n,\n\"Shipp\"\n,\n\"Shippee\"\n,\n\"Shir\"\n,\n\"Shira\"\n,\n\"Shirah\"\n,\n\"Shirberg\"\n,\n\"Shiri\"\n,\n\"Shirk\"\n,\n\"Shirl\"\n,\n\"Shirlee\"\n,\n\"Shirleen\"\n,\n\"Shirlene\"\n,\n\"Shirley\"\n,\n\"Shirlie\"\n,\n\"Shirline\"\n,\n\"Shiroma\"\n,\n\"Shishko\"\n,\n\"Shiverick\"\n,\n\"Shivers\"\n,\n\"Shlomo\"\n,\n\"Shoemaker\"\n,\n\"Shoifet\"\n,\n\"Sholeen\"\n,\n\"Sholem\"\n,\n\"Sholes\"\n,\n\"Sholley\"\n,\n\"Sholom\"\n,\n\"Shore\"\n,\n\"Shornick\"\n,\n\"Short\"\n,\n\"Shorter\"\n,\n\"Shoshana\"\n,\n\"Shoshanna\"\n,\n\"Shotton\"\n,\n\"Showker\"\n,\n\"Shreeves\"\n,\n\"Shreve\"\n,\n\"Shrier\"\n,\n\"Shriner\"\n,\n\"Shriver\"\n,\n\"Shu\"\n,\n\"Shue\"\n,\n\"Shugart\"\n,\n\"Shulamith\"\n,\n\"Shulem\"\n,\n\"Shuler\"\n,\n\"Shulins\"\n,\n\"Shull\"\n,\n\"Shulman\"\n,\n\"Shulock\"\n,\n\"Shult\"\n,\n\"Shultz\"\n,\n\"Shum\"\n,\n\"Shuma\"\n,\n\"Shuman\"\n,\n\"Shumway\"\n,\n\"Shuping\"\n,\n\"Shurlock\"\n,\n\"Shurlocke\"\n,\n\"Shurwood\"\n,\n\"Shushan\"\n,\n\"Shute\"\n,\n\"Shutz\"\n,\n\"Shwalb\"\n,\n\"Shyamal\"\n,\n\"Si\"\n,\n\"Siana\"\n,\n\"Sianna\"\n,\n\"Sib\"\n,\n\"Sibbie\"\n,\n\"Sibby\"\n,\n\"Sibeal\"\n,\n\"Sibel\"\n,\n\"Sibell\"\n,\n\"Sibella\"\n,\n\"Sibelle\"\n,\n\"Siberson\"\n,\n\"Sibie\"\n,\n\"Sibilla\"\n,\n\"Sible\"\n,\n\"Siblee\"\n,\n\"Sibley\"\n,\n\"Sibyl\"\n,\n\"Sibylla\"\n,\n\"Sibylle\"\n,\n\"Sibyls\"\n,\n\"Sicard\"\n,\n\"Sices\"\n,\n\"Siclari\"\n,\n\"Sicular\"\n,\n\"Sid\"\n,\n\"Sida\"\n,\n\"Siddon\"\n,\n\"Siddra\"\n,\n\"Sidell\"\n,\n\"Sidhu\"\n,\n\"Sidky\"\n,\n\"Sidman\"\n,\n\"Sidnee\"\n,\n\"Sidney\"\n,\n\"Sidoma\"\n,\n\"Sidon\"\n,\n\"Sidoney\"\n,\n\"Sidonia\"\n,\n\"Sidonie\"\n,\n\"Sidonius\"\n,\n\"Sidonnie\"\n,\n\"Sidoon\"\n,\n\"Sidra\"\n,\n\"Sidran\"\n,\n\"Sidras\"\n,\n\"Sidwel\"\n,\n\"Sidwell\"\n,\n\"Sidwohl\"\n,\n\"Sieber\"\n,\n\"Siegel\"\n,\n\"Siegfried\"\n,\n\"Siegler\"\n,\n\"Sielen\"\n,\n\"Sieracki\"\n,\n\"Sierra\"\n,\n\"Siesser\"\n,\n\"Sievert\"\n,\n\"Siffre\"\n,\n\"Sig\"\n,\n\"Sigfrid\"\n,\n\"Sigfried\"\n,\n\"Sigismond\"\n,\n\"Sigismondo\"\n,\n\"Sigismund\"\n,\n\"Sigismundo\"\n,\n\"Sigler\"\n,\n\"Sigmund\"\n,\n\"Signe\"\n,\n\"Sigrid\"\n,\n\"Sigsmond\"\n,\n\"Sigvard\"\n,\n\"Sihon\"\n,\n\"Sihonn\"\n,\n\"Sihun\"\n,\n\"Sihunn\"\n,\n\"Sik\"\n,\n\"Sikata\"\n,\n\"Sikes\"\n,\n\"Sikko\"\n,\n\"Sikorski\"\n,\n\"Sil\"\n,\n\"Silas\"\n,\n\"Silber\"\n,\n\"Silberman\"\n,\n\"Silda\"\n,\n\"Silden\"\n,\n\"Sile\"\n,\n\"Sileas\"\n,\n\"Silin\"\n,\n\"Sill\"\n,\n\"Sillsby\"\n,\n\"Silma\"\n,\n\"Siloa\"\n,\n\"Siloam\"\n,\n\"Siloum\"\n,\n\"Silsby\"\n,\n\"Silsbye\"\n,\n\"Silva\"\n,\n\"Silvain\"\n,\n\"Silvan\"\n,\n\"Silvana\"\n,\n\"Silvano\"\n,\n\"Silvanus\"\n,\n\"Silver\"\n,\n\"Silverman\"\n,\n\"Silvers\"\n,\n\"Silverstein\"\n,\n\"Silverts\"\n,\n\"Silvester\"\n,\n\"Silvestro\"\n,\n\"Silvia\"\n,\n\"Silvie\"\n,\n\"Silvio\"\n,\n\"Sim\"\n,\n\"Sima\"\n,\n\"Simah\"\n,\n\"Simdars\"\n,\n\"Simeon\"\n,\n\"Simmie\"\n,\n\"Simmonds\"\n,\n\"Simmons\"\n,\n\"Simon\"\n,\n\"Simona\"\n,\n\"Simone\"\n,\n\"Simonetta\"\n,\n\"Simonette\"\n,\n\"Simonne\"\n,\n\"Simons\"\n,\n\"Simonsen\"\n,\n\"Simpkins\"\n,\n\"Simpson\"\n,\n\"Sims\"\n,\n\"Simsar\"\n,\n\"Simson\"\n,\n\"Sinai\"\n,\n\"Sinclair\"\n,\n\"Sinclare\"\n,\n\"Sindee\"\n,\n\"Sine\"\n,\n\"Sinegold\"\n,\n\"Singband\"\n,\n\"Singer\"\n,\n\"Singh\"\n,\n\"Singhal\"\n,\n\"Singleton\"\n,\n\"Sink\"\n,\n\"Sinnard\"\n,\n\"Siobhan\"\n,\n\"Sion\"\n,\n\"Sioux\"\n,\n\"Siouxie\"\n,\n\"Sipple\"\n,\n\"Sirkin\"\n,\n\"Sirmons\"\n,\n\"Sirois\"\n,\n\"Sirotek\"\n,\n\"Sisak\"\n,\n\"Sisco\"\n,\n\"Sisely\"\n,\n\"Sisile\"\n,\n\"Siskind\"\n,\n\"Sissel\"\n,\n\"Sissie\"\n,\n\"Sisson\"\n,\n\"Sissy\"\n,\n\"Sisto\"\n,\n\"Sitarski\"\n,\n\"Sitnik\"\n,\n\"Sitra\"\n,\n\"Siubhan\"\n,\n\"Siusan\"\n,\n\"Sivia\"\n,\n\"Sivie\"\n,\n\"Siward\"\n,\n\"Sjoberg\"\n,\n\"Skantze\"\n,\n\"Skardol\"\n,\n\"Skees\"\n,\n\"Skeie\"\n,\n\"Skell\"\n,\n\"Skelly\"\n,\n\"Skelton\"\n,\n\"Skerl\"\n,\n\"Skiba\"\n,\n\"Skier\"\n,\n\"Skiest\"\n,\n\"Skilken\"\n,\n\"Skill\"\n,\n\"Skillern\"\n,\n\"Skinner\"\n,\n\"Skip\"\n,\n\"Skipp\"\n,\n\"Skipper\"\n,\n\"Skippie\"\n,\n\"Skippy\"\n,\n\"Skipton\"\n,\n\"Sklar\"\n,\n\"Skolnik\"\n,\n\"Skricki\"\n,\n\"Skurnik\"\n,\n\"Skutchan\"\n,\n\"Skvorak\"\n,\n\"Sky\"\n,\n\"Skye\"\n,\n\"Skyla\"\n,\n\"Skylar\"\n,\n\"Skyler\"\n,\n\"Slaby\"\n,\n\"Slack\"\n,\n\"Slade\"\n,\n\"Sladen\"\n,\n\"Slater\"\n,\n\"Slaughter\"\n,\n\"Slavic\"\n,\n\"Slavin\"\n,\n\"Slayton\"\n,\n\"Sldney\"\n,\n\"Slemmer\"\n,\n\"Sletten\"\n,\n\"Slifka\"\n,\n\"Slinkman\"\n,\n\"Sliwa\"\n,\n\"Sloan\"\n,\n\"Sloane\"\n,\n\"Sloatman\"\n,\n\"Slocum\"\n,\n\"Slosberg\"\n,\n\"Slotnick\"\n,\n\"Sluiter\"\n,\n\"Sly\"\n,\n\"Slyke\"\n,\n\"Smail\"\n,\n\"Small\"\n,\n\"Smalley\"\n,\n\"Smallman\"\n,\n\"Smart\"\n,\n\"Smiga\"\n,\n\"Smiley\"\n,\n\"Smith\"\n,\n\"Smitt\"\n,\n\"Smitty\"\n,\n\"Smoot\"\n,\n\"Smukler\"\n,\n\"Snapp\"\n,\n\"Snashall\"\n,\n\"Sneed\"\n,\n\"Snell\"\n,\n\"Snider\"\n,\n\"Snoddy\"\n,\n\"Snodgrass\"\n,\n\"Snook\"\n,\n\"Snow\"\n,\n\"Snowber\"\n,\n\"Snowman\"\n,\n\"Snyder\"\n,\n\"So\"\n,\n\"Soane\"\n,\n\"Sobel\"\n,\n\"Soble\"\n,\n\"Socha\"\n,\n\"Socher\"\n,\n\"Sochor\"\n,\n\"Socrates\"\n,\n\"Soelch\"\n,\n\"Sofer\"\n,\n\"Sofia\"\n,\n\"Sofie\"\n,\n\"Sofko\"\n,\n\"Soinski\"\n,\n\"Sokil\"\n,\n\"Sokul\"\n,\n\"Sol\"\n,\n\"Sola\"\n,\n\"Solana\"\n,\n\"Solange\"\n,\n\"Solberg\"\n,\n\"Solenne\"\n,\n\"Solis\"\n,\n\"Solita\"\n,\n\"Solitta\"\n,\n\"Soll\"\n,\n\"Sollars\"\n,\n\"Solley\"\n,\n\"Sollie\"\n,\n\"Sollows\"\n,\n\"Solly\"\n,\n\"Solnit\"\n,\n\"Soloma\"\n,\n\"Soloman\"\n,\n\"Solomon\"\n,\n\"Solon\"\n,\n\"Soluk\"\n,\n\"Som\"\n,\n\"Somerset\"\n,\n\"Somerville\"\n,\n\"Sommer\"\n,\n\"Sommers\"\n,\n\"Son\"\n,\n\"Sondra\"\n,\n\"Soneson\"\n,\n\"Song\"\n,\n\"Soni\"\n,\n\"Sonia\"\n,\n\"Sonja\"\n,\n\"Sonni\"\n,\n\"Sonnie\"\n,\n\"Sonnnie\"\n,\n\"Sonny\"\n,\n\"Sonstrom\"\n,\n\"Sontag\"\n,\n\"Sontich\"\n,\n\"Sonya\"\n,\n\"Soo\"\n,\n\"Soph\"\n,\n\"Sopher\"\n,\n\"Sophey\"\n,\n\"Sophi\"\n,\n\"Sophia\"\n,\n\"Sophie\"\n,\n\"Sophronia\"\n,\n\"Sophy\"\n,\n\"Soracco\"\n,\n\"Soraya\"\n,\n\"Sorce\"\n,\n\"Sorcha\"\n,\n\"Sorci\"\n,\n\"Sorcim\"\n,\n\"Sorel\"\n,\n\"Soren\"\n,\n\"Sorensen\"\n,\n\"Sorenson\"\n,\n\"Sorilda\"\n,\n\"Sorkin\"\n,\n\"Sorrows\"\n,\n\"Sosanna\"\n,\n\"Sosna\"\n,\n\"Sosthena\"\n,\n\"Sosthenna\"\n,\n\"Sosthina\"\n,\n\"Sothena\"\n,\n\"Sotos\"\n,\n\"Sou\"\n,\n\"Soule\"\n,\n\"Soulier\"\n,\n\"Sousa\"\n,\n\"Southard\"\n,\n\"Southworth\"\n,\n\"Soutor\"\n,\n\"Souvaine\"\n,\n\"Souza\"\n,\n\"Sowell\"\n,\n\"Sower\"\n,\n\"Spada\"\n,\n\"Spain\"\n,\n\"Spalding\"\n,\n\"Spalla\"\n,\n\"Spancake\"\n,\n\"Spanjian\"\n,\n\"Spanos\"\n,\n\"Sparhawk\"\n,\n\"Spark\"\n,\n\"Sparke\"\n,\n\"Sparkie\"\n,\n\"Sparks\"\n,\n\"Sparky\"\n,\n\"Sparrow\"\n,\n\"Spatola\"\n,\n\"Spatz\"\n,\n\"Spaulding\"\n,\n\"Spear\"\n,\n\"Spearing\"\n,\n\"Spearman\"\n,\n\"Spears\"\n,\n\"Specht\"\n,\n\"Spector\"\n,\n\"Spence\"\n,\n\"Spencer\"\n,\n\"Spense\"\n,\n\"Spenser\"\n,\n\"Sperling\"\n,\n\"Speroni\"\n,\n\"Sperry\"\n,\n\"Spevek\"\n,\n\"Spiegel\"\n,\n\"Spiegelman\"\n,\n\"Spiegleman\"\n,\n\"Spieler\"\n,\n\"Spielman\"\n,\n\"Spiers\"\n,\n\"Spike\"\n,\n\"Spillar\"\n,\n\"Spindell\"\n,\n\"Spiro\"\n,\n\"Spiros\"\n,\n\"Spitzer\"\n,\n\"Spohr\"\n,\n\"Spooner\"\n,\n\"Spoor\"\n,\n\"Spracklen\"\n,\n\"Sprage\"\n,\n\"Spragens\"\n,\n\"Sprague\"\n,\n\"Spratt\"\n,\n\"Spring\"\n,\n\"Springer\"\n,\n\"Sproul\"\n,\n\"Sprung\"\n,\n\"Spurgeon\"\n,\n\"Squier\"\n,\n\"Squire\"\n,\n\"Squires\"\n,\n\"Srini\"\n,\n\"Staal\"\n,\n\"Stace\"\n,\n\"Stacee\"\n,\n\"Stacey\"\n,\n\"Staci\"\n,\n\"Stacia\"\n,\n\"Stacie\"\n,\n\"Stacy\"\n,\n\"Stafani\"\n,\n\"Staffan\"\n,\n\"Staffard\"\n,\n\"Stafford\"\n,\n\"Staford\"\n,\n\"Stag\"\n,\n\"Stagg\"\n,\n\"Stahl\"\n,\n\"Stalder\"\n,\n\"Staley\"\n,\n\"Stalk\"\n,\n\"Stalker\"\n,\n\"Stallworth\"\n,\n\"Stamata\"\n,\n\"Stambaugh\"\n,\n\"Stan\"\n,\n\"Stander\"\n,\n\"Standford\"\n,\n\"Standice\"\n,\n\"Standing\"\n,\n\"Standish\"\n,\n\"Standley\"\n,\n\"Standush\"\n,\n\"Stanfield\"\n,\n\"Stanfill\"\n,\n\"Stanford\"\n,\n\"Stanhope\"\n,\n\"Stanislas\"\n,\n\"Stanislaus\"\n,\n\"Stanislaw\"\n,\n\"Stanleigh\"\n,\n\"Stanley\"\n,\n\"Stanly\"\n,\n\"Stannfield\"\n,\n\"Stannwood\"\n,\n\"Stanton\"\n,\n\"Stanway\"\n,\n\"Stanwin\"\n,\n\"Stanwinn\"\n,\n\"Stanwood\"\n,\n\"Stanzel\"\n,\n\"Star\"\n,\n\"Starbuck\"\n,\n\"Stargell\"\n,\n\"Starinsky\"\n,\n\"Stark\"\n,\n\"Starkey\"\n,\n\"Starks\"\n,\n\"Starla\"\n,\n\"Starlene\"\n,\n\"Starlin\"\n,\n\"Starling\"\n,\n\"Starobin\"\n,\n\"Starr\"\n,\n\"Stasny\"\n,\n\"Staten\"\n,\n\"Statis\"\n,\n\"Stauder\"\n,\n\"Stauffer\"\n,\n\"Stav\"\n,\n\"Stavro\"\n,\n\"Stavros\"\n,\n\"Staw\"\n,\n\"Stclair\"\n,\n\"Stead\"\n,\n\"Steady\"\n,\n\"Stearn\"\n,\n\"Stearne\"\n,\n\"Stearns\"\n,\n\"Steck\"\n,\n\"Steddman\"\n,\n\"Stedman\"\n,\n\"Stedmann\"\n,\n\"Stedt\"\n,\n\"Steel\"\n,\n\"Steele\"\n,\n\"Steen\"\n,\n\"Steep\"\n,\n\"Steere\"\n,\n\"Stefa\"\n,\n\"Stefan\"\n,\n\"Stefanac\"\n,\n\"Stefania\"\n,\n\"Stefanie\"\n,\n\"Stefano\"\n,\n\"Steffane\"\n,\n\"Steffen\"\n,\n\"Steffi\"\n,\n\"Steffie\"\n,\n\"Steffin\"\n,\n\"Steffy\"\n,\n\"Stegman\"\n,\n\"Stein\"\n,\n\"Steinberg\"\n,\n\"Steiner\"\n,\n\"Steinke\"\n,\n\"Steinman\"\n,\n\"Steinway\"\n,\n\"Stella\"\n,\n\"Stelle\"\n,\n\"Stelmach\"\n,\n\"Stelu\"\n,\n\"Stempien\"\n,\n\"Stempson\"\n,\n\"Stenger\"\n,\n\"Stent\"\n,\n\"Stepha\"\n,\n\"Stephan\"\n,\n\"Stephana\"\n,\n\"Stephani\"\n,\n\"Stephania\"\n,\n\"Stephanie\"\n,\n\"Stephannie\"\n,\n\"Stephanus\"\n,\n\"Stephen\"\n,\n\"Stephenie\"\n,\n\"Stephens\"\n,\n\"Stephenson\"\n,\n\"Stephi\"\n,\n\"Stephie\"\n,\n\"Stephine\"\n,\n\"Sterling\"\n,\n\"Stern\"\n,\n\"Sternberg\"\n,\n\"Sterne\"\n,\n\"Sterner\"\n,\n\"Sternick\"\n,\n\"Sternlight\"\n,\n\"Sterrett\"\n,\n\"Stesha\"\n,\n\"Stets\"\n,\n\"Stetson\"\n,\n\"Stevana\"\n,\n\"Steve\"\n,\n\"Steven\"\n,\n\"Stevena\"\n,\n\"Stevens\"\n,\n\"Stevenson\"\n,\n\"Stevie\"\n,\n\"Stevy\"\n,\n\"Stew\"\n,\n\"Steward\"\n,\n\"Stewardson\"\n,\n\"Stewart\"\n,\n\"Stich\"\n,\n\"Stichter\"\n,\n\"Stickney\"\n,\n\"Stiegler\"\n,\n\"Stieglitz\"\n,\n\"Stier\"\n,\n\"Stig\"\n,\n\"Stila\"\n,\n\"Stiles\"\n,\n\"Still\"\n,\n\"Stilla\"\n,\n\"Stillas\"\n,\n\"Stillman\"\n,\n\"Stillmann\"\n,\n\"Stilu\"\n,\n\"Stilwell\"\n,\n\"Stimson\"\n,\n\"Stine\"\n,\n\"Stinky\"\n,\n\"Stinson\"\n,\n\"Stirling\"\n,\n\"Stoat\"\n,\n\"Stochmal\"\n,\n\"Stock\"\n,\n\"Stockmon\"\n,\n\"Stockton\"\n,\n\"Stockwell\"\n,\n\"Stoddard\"\n,\n\"Stoddart\"\n,\n\"Stodder\"\n,\n\"Stoeber\"\n,\n\"Stoecker\"\n,\n\"Stoffel\"\n,\n\"Stokes\"\n,\n\"Stoll\"\n,\n\"Stoller\"\n,\n\"Stolzer\"\n,\n\"Stone\"\n,\n\"Stoneham\"\n,\n\"Stoneman\"\n,\n\"Stonwin\"\n,\n\"Stoops\"\n,\n\"Storer\"\n,\n\"Storfer\"\n,\n\"Storm\"\n,\n\"Stormi\"\n,\n\"Stormie\"\n,\n\"Stormy\"\n,\n\"Stortz\"\n,\n\"Story\"\n,\n\"Storz\"\n,\n\"Stouffer\"\n,\n\"Stoughton\"\n,\n\"Stout\"\n,\n\"Stovall\"\n,\n\"Stover\"\n,\n\"Strade\"\n,\n\"Strader\"\n,\n\"Strage\"\n,\n\"Strain\"\n,\n\"Strait\"\n,\n\"Stralka\"\n,\n\"Strander\"\n,\n\"Strang\"\n,\n\"Stranger\"\n,\n\"Stratton\"\n,\n\"Straub\"\n,\n\"Straus\"\n,\n\"Strauss\"\n,\n\"Strawn\"\n,\n\"Streeter\"\n,\n\"Streetman\"\n,\n\"Streeto\"\n,\n\"Strenta\"\n,\n\"Strep\"\n,\n\"Strephon\"\n,\n\"Strephonn\"\n,\n\"Strepphon\"\n,\n\"Stretch\"\n,\n\"Stricklan\"\n,\n\"Strickland\"\n,\n\"Strickler\"\n,\n\"Strickman\"\n,\n\"Stringer\"\n,\n\"Strohbehn\"\n,\n\"Strohben\"\n,\n\"Strohl\"\n,\n\"Stromberg\"\n,\n\"Strong\"\n,\n\"Stronski\"\n,\n\"Stroud\"\n,\n\"Stroup\"\n,\n\"Struve\"\n,\n\"Stryker\"\n,\n\"Stu\"\n,\n\"Stuart\"\n,\n\"Stubbs\"\n,\n\"Stubstad\"\n,\n\"Stucker\"\n,\n\"Stuckey\"\n,\n\"Studdard\"\n,\n\"Studley\"\n,\n\"Studner\"\n,\n\"Studnia\"\n,\n\"Stulin\"\n,\n\"Stultz\"\n,\n\"Stuppy\"\n,\n\"Sturdivant\"\n,\n\"Sturges\"\n,\n\"Sturrock\"\n,\n\"Stutman\"\n,\n\"Stutsman\"\n,\n\"Stutzman\"\n,\n\"Styles\"\n,\n\"Su\"\n,\n\"Suanne\"\n,\n\"Subak\"\n,\n\"Subir\"\n,\n\"Sublett\"\n,\n\"Suchta\"\n,\n\"Suckow\"\n,\n\"Sucy\"\n,\n\"Sudbury\"\n,\n\"Sudderth\"\n,\n\"Sudhir\"\n,\n\"Sudnor\"\n,\n\"Sue\"\n,\n\"Suellen\"\n,\n\"Suelo\"\n,\n\"Sugar\"\n,\n\"Sugden\"\n,\n\"Sugihara\"\n,\n\"Suh\"\n,\n\"Suhail\"\n,\n\"Suilmann\"\n,\n\"Suk\"\n,\n\"Sukey\"\n,\n\"Sukhum\"\n,\n\"Suki\"\n,\n\"Sukin\"\n,\n\"Sula\"\n,\n\"Sulamith\"\n,\n\"Sullivan\"\n,\n\"Sully\"\n,\n\"Sum\"\n,\n\"Sumer\"\n,\n\"Sumerlin\"\n,\n\"Summer\"\n,\n\"Summers\"\n,\n\"Summons\"\n,\n\"Sumner\"\n,\n\"Sunda\"\n,\n\"Sunday\"\n,\n\"Sundberg\"\n,\n\"Sunderland\"\n,\n\"Sundin\"\n,\n\"Sundstrom\"\n,\n\"Suneya\"\n,\n\"Sung\"\n,\n\"Sunil\"\n,\n\"Sunny\"\n,\n\"Sunshine\"\n,\n\"Sup\"\n,\n\"Supat\"\n,\n\"Supen\"\n,\n\"Supple\"\n,\n\"Sura\"\n,\n\"Surbeck\"\n,\n\"Surovy\"\n,\n\"Survance\"\n,\n\"Susan\"\n,\n\"Susana\"\n,\n\"Susanetta\"\n,\n\"Susann\"\n,\n\"Susanna\"\n,\n\"Susannah\"\n,\n\"Susanne\"\n,\n\"Susette\"\n,\n\"Susi\"\n,\n\"Susie\"\n,\n\"Sussi\"\n,\n\"Sussman\"\n,\n\"Sussna\"\n,\n\"Susumu\"\n,\n\"Susy\"\n,\n\"Suter\"\n,\n\"Sutherlan\"\n,\n\"Sutherland\"\n,\n\"Sutphin\"\n,\n\"Sutton\"\n,\n\"Suu\"\n,\n\"Suzan\"\n,\n\"Suzann\"\n,\n\"Suzanna\"\n,\n\"Suzanne\"\n,\n\"Suzetta\"\n,\n\"Suzette\"\n,\n\"Suzi\"\n,\n\"Suzie\"\n,\n\"Suzy\"\n,\n\"Suzzy\"\n,\n\"Sven\"\n,\n\"Svend\"\n,\n\"Svensen\"\n,\n\"Sverre\"\n,\n\"Svetlana\"\n,\n\"Svoboda\"\n,\n\"Swagerty\"\n,\n\"Swain\"\n,\n\"Swaine\"\n,\n\"Swainson\"\n,\n\"Swamy\"\n,\n\"Swan\"\n,\n\"Swane\"\n,\n\"Swanhilda\"\n,\n\"Swanhildas\"\n,\n\"Swann\"\n,\n\"Swanson\"\n,\n\"Swart\"\n,\n\"Swarts\"\n,\n\"Swartz\"\n,\n\"Swayder\"\n,\n\"Swayne\"\n,\n\"Sweatt\"\n,\n\"Swec\"\n,\n\"Swee\"\n,\n\"Sweeney\"\n,\n\"Sweet\"\n,\n\"Swen\"\n,\n\"Swenson\"\n,\n\"Swetiana\"\n,\n\"Swetlana\"\n,\n\"Sweyn\"\n,\n\"Swiercz\"\n,\n\"Swift\"\n,\n\"Swigart\"\n,\n\"Swihart\"\n,\n\"Swinton\"\n,\n\"Swirsky\"\n,\n\"Swisher\"\n,\n\"Swithbart\"\n,\n\"Swithbert\"\n,\n\"Swithin\"\n,\n\"Switzer\"\n,\n\"Swope\"\n,\n\"Swor\"\n,\n\"Swords\"\n,\n\"Sy\"\n,\n\"Sybil\"\n,\n\"Sybila\"\n,\n\"Sybilla\"\n,\n\"Sybille\"\n,\n\"Sybley\"\n,\n\"Sybyl\"\n,\n\"Syck\"\n,\n\"Syd\"\n,\n\"Sydel\"\n,\n\"Sydelle\"\n,\n\"Sydney\"\n,\n\"Sykes\"\n,\n\"Syl\"\n,\n\"Sylas\"\n,\n\"Sylvan\"\n,\n\"Sylvanus\"\n,\n\"Sylvester\"\n,\n\"Sylvia\"\n,\n\"Sylvie\"\n,\n\"Syman\"\n,\n\"Symer\"\n,\n\"Symon\"\n,\n\"Symons\"\n,\n\"Synn\"\n,\n\"Syst\"\n,\n\"Syverson\"\n,\n\"TEirtza\"\n,\n\"Taam\"\n,\n\"Tab\"\n,\n\"Tabatha\"\n,\n\"Tabb\"\n,\n\"Tabbatha\"\n,\n\"Tabber\"\n,\n\"Tabbi\"\n,\n\"Tabbie\"\n,\n\"Tabbitha\"\n,\n\"Tabby\"\n,\n\"Taber\"\n,\n\"Tabib\"\n,\n\"Tabina\"\n,\n\"Tabitha\"\n,\n\"Tabor\"\n,\n\"Tabshey\"\n,\n\"Tace\"\n,\n\"Tacita\"\n,\n\"Tacklind\"\n,\n\"Tacy\"\n,\n\"Tacye\"\n,\n\"Tad\"\n,\n\"Tada\"\n,\n\"Tadashi\"\n,\n\"Tadd\"\n,\n\"Taddeo\"\n,\n\"Taddeusz\"\n,\n\"Tade\"\n,\n\"Tadeas\"\n,\n\"Tadeo\"\n,\n\"Tades\"\n,\n\"Tadich\"\n,\n\"Tadio\"\n,\n\"Taffy\"\n,\n\"Taft\"\n,\n\"Tager\"\n,\n\"Taggart\"\n,\n\"Tahmosh\"\n,\n\"Tai\"\n,\n\"Tailor\"\n,\n\"Taima\"\n,\n\"Taimi\"\n,\n\"Tait\"\n,\n\"Taite\"\n,\n\"Tak\"\n,\n\"Taka\"\n,\n\"Takakura\"\n,\n\"Takara\"\n,\n\"Takashi\"\n,\n\"Takeo\"\n,\n\"Takeshi\"\n,\n\"Takken\"\n,\n\"Tal\"\n,\n\"Tala\"\n,\n\"Talanian\"\n,\n\"Talanta\"\n,\n\"Talbert\"\n,\n\"Talbot\"\n,\n\"Talbott\"\n,\n\"Tali\"\n,\n\"Talia\"\n,\n\"Talich\"\n,\n\"Talie\"\n,\n\"Tallbot\"\n,\n\"Tallbott\"\n,\n\"Talley\"\n,\n\"Tallia\"\n,\n\"Tallie\"\n,\n\"Tallou\"\n,\n\"Tallu\"\n,\n\"Tallula\"\n,\n\"Tallulah\"\n,\n\"Tally\"\n,\n\"Talmud\"\n,\n\"Talya\"\n,\n\"Talyah\"\n,\n\"Tam\"\n,\n\"Tama\"\n,\n\"Tamah\"\n,\n\"Tamanaha\"\n,\n\"Tamar\"\n,\n\"Tamara\"\n,\n\"Tamarah\"\n,\n\"Tamarra\"\n,\n\"Tamaru\"\n,\n\"Tamas\"\n,\n\"Tamberg\"\n,\n\"Tamer\"\n,\n\"Tamera\"\n,\n\"Tami\"\n,\n\"Tamiko\"\n,\n\"Tamis\"\n,\n\"Tamma\"\n,\n\"Tammany\"\n,\n\"Tammara\"\n,\n\"Tammi\"\n,\n\"Tammie\"\n,\n\"Tammy\"\n,\n\"Tamqrah\"\n,\n\"Tamra\"\n,\n\"Tamsky\"\n,\n\"Tan\"\n,\n\"Tana\"\n,\n\"Tanah\"\n,\n\"Tanaka\"\n,\n\"Tanberg\"\n,\n\"Tandi\"\n,\n\"Tandie\"\n,\n\"Tandy\"\n,\n\"Tanhya\"\n,\n\"Tani\"\n,\n\"Tania\"\n,\n\"Tanitansy\"\n,\n\"Tankoos\"\n,\n\"Tann\"\n,\n\"Tannen\"\n,\n\"Tannenbaum\"\n,\n\"Tannenwald\"\n,\n\"Tanner\"\n,\n\"Tanney\"\n,\n\"Tannie\"\n,\n\"Tanny\"\n,\n\"Tansey\"\n,\n\"Tansy\"\n,\n\"Tanya\"\n,\n\"Tapes\"\n,\n\"Tara\"\n,\n\"Tarabar\"\n,\n\"Tarah\"\n,\n\"Taran\"\n,\n\"Tarazi\"\n,\n\"Tare\"\n,\n\"Tareyn\"\n,\n\"Targett\"\n,\n\"Tarkany\"\n,\n\"Taro\"\n,\n\"Tarr\"\n,\n\"Tarra\"\n,\n\"Tarrah\"\n,\n\"Tarrance\"\n,\n\"Tarrant\"\n,\n\"Tarrel\"\n,\n\"Tarrsus\"\n,\n\"Tarryn\"\n,\n\"Tarsus\"\n,\n\"Tarsuss\"\n,\n\"Tartaglia\"\n,\n\"Tartan\"\n,\n\"Tarton\"\n,\n\"Tarttan\"\n,\n\"Taryn\"\n,\n\"Taryne\"\n,\n\"Tasha\"\n,\n\"Tasia\"\n,\n\"Tasiana\"\n,\n\"Tat\"\n,\n\"Tate\"\n,\n\"Tati\"\n,\n\"Tatia\"\n,\n\"Tatiana\"\n,\n\"Tatianas\"\n,\n\"Tatiania\"\n,\n\"Tatianna\"\n,\n\"Tatman\"\n,\n\"Tattan\"\n,\n\"Tatum\"\n,\n\"Taub\"\n,\n\"Tav\"\n,\n\"Taveda\"\n,\n\"Tavey\"\n,\n\"Tavi\"\n,\n\"Tavia\"\n,\n\"Tavie\"\n,\n\"Tavis\"\n,\n\"Tavish\"\n,\n\"Tavy\"\n,\n\"Tawney\"\n,\n\"Tawnya\"\n,\n\"Tawsha\"\n,\n\"Tay\"\n,\n\"Tayib\"\n,\n\"Tayler\"\n,\n\"Taylor\"\n,\n\"Tayyebeb\"\n,\n\"Tchao\"\n,\n\"Teador\"\n,\n\"Teagan\"\n,\n\"Teage\"\n,\n\"Teague\"\n,\n\"Teahan\"\n,\n\"Teak\"\n,\n\"Tearle\"\n,\n\"Tecla\"\n,\n\"Tecu\"\n,\n\"Ted\"\n,\n\"Tedd\"\n,\n\"Tedda\"\n,\n\"Tedder\"\n,\n\"Teddi\"\n,\n\"Teddie\"\n,\n\"Teddman\"\n,\n\"Teddy\"\n,\n\"Tedi\"\n,\n\"Tedie\"\n,\n\"Tedman\"\n,\n\"Tedmann\"\n,\n\"Tedmund\"\n,\n\"Tedra\"\n,\n\"Tedric\"\n,\n\"Teece\"\n,\n\"Teena\"\n,\n\"Teerell\"\n,\n\"Teeter\"\n,\n\"Teevens\"\n,\n\"Teferi\"\n,\n\"Tega\"\n,\n\"Tegan\"\n,\n\"Teillo\"\n,\n\"Teilo\"\n,\n\"Tekla\"\n,\n\"Telfer\"\n,\n\"Telford\"\n,\n\"Telfore\"\n,\n\"Tella\"\n,\n\"Tellford\"\n,\n\"Tem\"\n,\n\"Tema\"\n,\n\"Temp\"\n,\n\"Tempa\"\n,\n\"Tempest\"\n,\n\"Templa\"\n,\n\"Templas\"\n,\n\"Temple\"\n,\n\"Templer\"\n,\n\"Templeton\"\n,\n\"Templia\"\n,\n\"Ten\"\n,\n\"Tena\"\n,\n\"Tench\"\n,\n\"Tenenbaum\"\n,\n\"Tengdin\"\n,\n\"Tengler\"\n,\n\"Tenn\"\n,\n\"Tenner\"\n,\n\"Tennes\"\n,\n\"Tenney\"\n,\n\"Tennies\"\n,\n\"Teodoor\"\n,\n\"Teodor\"\n,\n\"Teodora\"\n,\n\"Teodorico\"\n,\n\"Teodoro\"\n,\n\"Teplica\"\n,\n\"Teplitz\"\n,\n\"Tepper\"\n,\n\"Tera\"\n,\n\"Terbecki\"\n,\n\"Terchie\"\n,\n\"Terena\"\n,\n\"Terence\"\n,\n\"Terencio\"\n,\n\"Teresa\"\n,\n\"Terese\"\n,\n\"Teresina\"\n,\n\"Teresita\"\n,\n\"Teressa\"\n,\n\"Terhune\"\n,\n\"Teri\"\n,\n\"Teria\"\n,\n\"Teriann\"\n,\n\"Terina\"\n,\n\"Terle\"\n,\n\"Ternan\"\n,\n\"Terpstra\"\n,\n\"Terr\"\n,\n\"Terra\"\n,\n\"Terrance\"\n,\n\"Terrel\"\n,\n\"Terrell\"\n,\n\"Terrena\"\n,\n\"Terrence\"\n,\n\"Terrene\"\n,\n\"Terri\"\n,\n\"Terrie\"\n,\n\"Terrijo\"\n,\n\"Terrill\"\n,\n\"Terrilyn\"\n,\n\"Terris\"\n,\n\"Terriss\"\n,\n\"Territus\"\n,\n\"Terry\"\n,\n\"Terrye\"\n,\n\"Terryl\"\n,\n\"Terryn\"\n,\n\"Tersina\"\n,\n\"Terti\"\n,\n\"Tertia\"\n,\n\"Tertias\"\n,\n\"Tertius\"\n,\n\"Teryl\"\n,\n\"Teryn\"\n,\n\"Terza\"\n,\n\"Terzas\"\n,\n\"Tesler\"\n,\n\"Tess\"\n,\n\"Tessa\"\n,\n\"Tessi\"\n,\n\"Tessie\"\n,\n\"Tessler\"\n,\n\"Tessy\"\n,\n\"Teteak\"\n,\n\"Teufert\"\n,\n\"Teuton\"\n,\n\"Tevis\"\n,\n\"Tewell\"\n,\n\"Tewfik\"\n,\n\"Tews\"\n,\n\"Thacher\"\n,\n\"Thacker\"\n,\n\"Thackeray\"\n,\n\"Thad\"\n,\n\"Thaddaus\"\n,\n\"Thaddeus\"\n,\n\"Thaddus\"\n,\n\"Thadeus\"\n,\n\"Thagard\"\n,\n\"Thain\"\n,\n\"Thaine\"\n,\n\"Thais\"\n,\n\"Thalassa\"\n,\n\"Thalia\"\n,\n\"Tham\"\n,\n\"Thamora\"\n,\n\"Thamos\"\n,\n\"Thanasi\"\n,\n\"Thane\"\n,\n\"Thanh\"\n,\n\"Thanos\"\n,\n\"Thant\"\n,\n\"Thapa\"\n,\n\"Thar\"\n,\n\"Tharp\"\n,\n\"Thatch\"\n,\n\"Thatcher\"\n,\n\"Thaxter\"\n,\n\"Thay\"\n,\n\"Thayer\"\n,\n\"Thayne\"\n,\n\"The\"\n,\n\"Thea\"\n,\n\"Theadora\"\n,\n\"Theall\"\n,\n\"Thebault\"\n,\n\"Thecla\"\n,\n\"Theda\"\n,\n\"Thedric\"\n,\n\"Thedrick\"\n,\n\"Theis\"\n,\n\"Thekla\"\n,\n\"Thelma\"\n,\n\"Thema\"\n,\n\"Themis\"\n,\n\"Thenna\"\n,\n\"Theo\"\n,\n\"Theobald\"\n,\n\"Theodor\"\n,\n\"Theodora\"\n,\n\"Theodore\"\n,\n\"Theodoric\"\n,\n\"Theodosia\"\n,\n\"Theola\"\n,\n\"Theona\"\n,\n\"Theone\"\n,\n\"Thera\"\n,\n\"Theran\"\n,\n\"Theresa\"\n,\n\"Therese\"\n,\n\"Theresina\"\n,\n\"Theresita\"\n,\n\"Theressa\"\n,\n\"Therine\"\n,\n\"Theron\"\n,\n\"Therron\"\n,\n\"Thesda\"\n,\n\"Thessa\"\n,\n\"Theta\"\n,\n\"Thetes\"\n,\n\"Thetis\"\n,\n\"Thetisa\"\n,\n\"Thetos\"\n,\n\"Theurer\"\n,\n\"Theurich\"\n,\n\"Thevenot\"\n,\n\"Thia\"\n,\n\"Thibaud\"\n,\n\"Thibault\"\n,\n\"Thibaut\"\n,\n\"Thielen\"\n,\n\"Thier\"\n,\n\"Thierry\"\n,\n\"Thilda\"\n,\n\"Thilde\"\n,\n\"Thill\"\n,\n\"Thin\"\n,\n\"Thinia\"\n,\n\"Thirion\"\n,\n\"Thirza\"\n,\n\"Thirzi\"\n,\n\"Thirzia\"\n,\n\"Thisbe\"\n,\n\"Thisbee\"\n,\n\"Thissa\"\n,\n\"Thistle\"\n,\n\"Thoer\"\n,\n\"Thom\"\n,\n\"Thoma\"\n,\n\"Thomajan\"\n,\n\"Thomas\"\n,\n\"Thomasa\"\n,\n\"Thomasin\"\n,\n\"Thomasina\"\n,\n\"Thomasine\"\n,\n\"Thomey\"\n,\n\"Thompson\"\n,\n\"Thomsen\"\n,\n\"Thomson\"\n,\n\"Thor\"\n,\n\"Thora\"\n,\n\"Thorbert\"\n,\n\"Thordia\"\n,\n\"Thordis\"\n,\n\"Thorfinn\"\n,\n\"Thorin\"\n,\n\"Thorlay\"\n,\n\"Thorley\"\n,\n\"Thorlie\"\n,\n\"Thorma\"\n,\n\"Thorman\"\n,\n\"Thormora\"\n,\n\"Thorn\"\n,\n\"Thornburg\"\n,\n\"Thorncombe\"\n,\n\"Thorndike\"\n,\n\"Thorne\"\n,\n\"Thorner\"\n,\n\"Thornie\"\n,\n\"Thornton\"\n,\n\"Thorny\"\n,\n\"Thorpe\"\n,\n\"Thorr\"\n,\n\"Thorrlow\"\n,\n\"Thorstein\"\n,\n\"Thorsten\"\n,\n\"Thorvald\"\n,\n\"Thorwald\"\n,\n\"Thrasher\"\n,\n\"Three\"\n,\n\"Threlkeld\"\n,\n\"Thrift\"\n,\n\"Thun\"\n,\n\"Thunell\"\n,\n\"Thurber\"\n,\n\"Thurlough\"\n,\n\"Thurlow\"\n,\n\"Thurman\"\n,\n\"Thurmann\"\n,\n\"Thurmond\"\n,\n\"Thurnau\"\n,\n\"Thursby\"\n,\n\"Thurstan\"\n,\n\"Thurston\"\n,\n\"Thury\"\n,\n\"Thynne\"\n,\n\"Tia\"\n,\n\"Tiana\"\n,\n\"Tibbetts\"\n,\n\"Tibbitts\"\n,\n\"Tibbs\"\n,\n\"Tibold\"\n,\n\"Tica\"\n,\n\"Tice\"\n,\n\"Tichon\"\n,\n\"Tichonn\"\n,\n\"Ticknor\"\n,\n\"Ticon\"\n,\n\"Tidwell\"\n,\n\"Tiebold\"\n,\n\"Tiebout\"\n,\n\"Tiedeman\"\n,\n\"Tiemroth\"\n,\n\"Tien\"\n,\n\"Tiena\"\n,\n\"Tierell\"\n,\n\"Tiernan\"\n,\n\"Tierney\"\n,\n\"Tiersten\"\n,\n\"Tiertza\"\n,\n\"Tierza\"\n,\n\"Tifanie\"\n,\n\"Tiff\"\n,\n\"Tiffa\"\n,\n\"Tiffani\"\n,\n\"Tiffanie\"\n,\n\"Tiffanle\"\n,\n\"Tiffany\"\n,\n\"Tiffi\"\n,\n\"Tiffie\"\n,\n\"Tiffy\"\n,\n\"Tiga\"\n,\n\"Tigges\"\n,\n\"Tila\"\n,\n\"Tilda\"\n,\n\"Tilden\"\n,\n\"Tildi\"\n,\n\"Tildie\"\n,\n\"Tildy\"\n,\n\"Tiler\"\n,\n\"Tilford\"\n,\n\"Till\"\n,\n\"Tilla\"\n,\n\"Tillford\"\n,\n\"Tillfourd\"\n,\n\"Tillie\"\n,\n\"Tillinger\"\n,\n\"Tillio\"\n,\n\"Tillion\"\n,\n\"Tillman\"\n,\n\"Tillo\"\n,\n\"Tilly\"\n,\n\"Tilney\"\n,\n\"Tiloine\"\n,\n\"Tim\"\n,\n\"Tima\"\n,\n\"Timi\"\n,\n\"Timmi\"\n,\n\"Timmie\"\n,\n\"Timmons\"\n,\n\"Timms\"\n,\n\"Timmy\"\n,\n\"Timofei\"\n,\n\"Timon\"\n,\n\"Timoteo\"\n,\n\"Timothea\"\n,\n\"Timothee\"\n,\n\"Timotheus\"\n,\n\"Timothy\"\n,\n\"Tina\"\n,\n\"Tinaret\"\n,\n\"Tindall\"\n,\n\"Tine\"\n,\n\"Tingey\"\n,\n\"Tingley\"\n,\n\"Tini\"\n,\n\"Tiny\"\n,\n\"Tinya\"\n,\n\"Tiossem\"\n,\n\"Tiphane\"\n,\n\"Tiphani\"\n,\n\"Tiphanie\"\n,\n\"Tiphany\"\n,\n\"Tippets\"\n,\n\"Tips\"\n,\n\"Tipton\"\n,\n\"Tirrell\"\n,\n\"Tirza\"\n,\n\"Tirzah\"\n,\n\"Tisbe\"\n,\n\"Tisbee\"\n,\n\"Tisdale\"\n,\n\"Tish\"\n,\n\"Tisha\"\n,\n\"Tisman\"\n,\n\"Tita\"\n,\n\"Titania\"\n,\n\"Tito\"\n,\n\"Titos\"\n,\n\"Titus\"\n,\n\"Tizes\"\n,\n\"Tjaden\"\n,\n\"Tjader\"\n,\n\"Tjon\"\n,\n\"Tletski\"\n,\n\"Toback\"\n,\n\"Tobe\"\n,\n\"Tobey\"\n,\n\"Tobi\"\n,\n\"Tobiah\"\n,\n\"Tobias\"\n,\n\"Tobie\"\n,\n\"Tobin\"\n,\n\"Tobit\"\n,\n\"Toby\"\n,\n\"Tobye\"\n,\n\"Tocci\"\n,\n\"Tod\"\n,\n\"Todd\"\n,\n\"Toddie\"\n,\n\"Toddy\"\n,\n\"Todhunter\"\n,\n\"Toffey\"\n,\n\"Toffic\"\n,\n\"Toft\"\n,\n\"Toh\"\n,\n\"Toiboid\"\n,\n\"Toinette\"\n,\n\"Tol\"\n,\n\"Toland\"\n,\n\"Tolkan\"\n,\n\"Toll\"\n,\n\"Tolland\"\n,\n\"Tolley\"\n,\n\"Tolliver\"\n,\n\"Tollman\"\n,\n\"Tollmann\"\n,\n\"Tolmach\"\n,\n\"Tolman\"\n,\n\"Tolmann\"\n,\n\"Tom\"\n,\n\"Toma\"\n,\n\"Tomas\"\n,\n\"Tomasina\"\n,\n\"Tomasine\"\n,\n\"Tomaso\"\n,\n\"Tomasz\"\n,\n\"Tombaugh\"\n,\n\"Tomchay\"\n,\n\"Tome\"\n,\n\"Tomi\"\n,\n\"Tomkiel\"\n,\n\"Tomkin\"\n,\n\"Tomkins\"\n,\n\"Tomlin\"\n,\n\"Tomlinson\"\n,\n\"Tommi\"\n,\n\"Tommie\"\n,\n\"Tommy\"\n,\n\"Tompkins\"\n,\n\"Toms\"\n,\n\"Toney\"\n,\n\"Tongue\"\n,\n\"Toni\"\n,\n\"Tonia\"\n,\n\"Tonie\"\n,\n\"Tonina\"\n,\n\"Tonjes\"\n,\n\"Tonkin\"\n,\n\"Tonl\"\n,\n\"Tonneson\"\n,\n\"Tonnie\"\n,\n\"Tonry\"\n,\n\"Tony\"\n,\n\"Tonya\"\n,\n\"Tonye\"\n,\n\"Toogood\"\n,\n\"Toole\"\n,\n\"Tooley\"\n,\n\"Toolis\"\n,\n\"Toomay\"\n,\n\"Toombs\"\n,\n\"Toomin\"\n,\n\"Toor\"\n,\n\"Tootsie\"\n,\n\"Topliffe\"\n,\n\"Topper\"\n,\n\"Topping\"\n,\n\"Tor\"\n,\n\"Torbart\"\n,\n\"Torbert\"\n,\n\"Tore\"\n,\n\"Torey\"\n,\n\"Torhert\"\n,\n\"Tori\"\n,\n\"Torie\"\n,\n\"Torin\"\n,\n\"Tormoria\"\n,\n\"Torosian\"\n,\n\"Torp\"\n,\n\"Torr\"\n,\n\"Torrance\"\n,\n\"Torras\"\n,\n\"Torray\"\n,\n\"Torre\"\n,\n\"Torrell\"\n,\n\"Torrence\"\n,\n\"Torres\"\n,\n\"Torrey\"\n,\n\"Torrie\"\n,\n\"Torrin\"\n,\n\"Torrlow\"\n,\n\"Torruella\"\n,\n\"Torry\"\n,\n\"Torto\"\n,\n\"Tortosa\"\n,\n\"Tory\"\n,\n\"Toscano\"\n,\n\"Tosch\"\n,\n\"Toshiko\"\n,\n\"Toth\"\n,\n\"Touber\"\n,\n\"Toulon\"\n,\n\"Tound\"\n,\n\"Tova\"\n,\n\"Tove\"\n,\n\"Towbin\"\n,\n\"Tower\"\n,\n\"Towers\"\n,\n\"Towill\"\n,\n\"Towland\"\n,\n\"Town\"\n,\n\"Towne\"\n,\n\"Towney\"\n,\n\"Townie\"\n,\n\"Townsend\"\n,\n\"Townshend\"\n,\n\"Towny\"\n,\n\"Towrey\"\n,\n\"Towroy\"\n,\n\"Toy\"\n,\n\"Trabue\"\n,\n\"Tracay\"\n,\n\"Trace\"\n,\n\"Tracee\"\n,\n\"Tracey\"\n,\n\"Traci\"\n,\n\"Tracie\"\n,\n\"Tracy\"\n,\n\"Trager\"\n,\n\"Trahern\"\n,\n\"Trahurn\"\n,\n\"Trainer\"\n,\n\"Trainor\"\n,\n\"Trakas\"\n,\n\"Trammel\"\n,\n\"Tran\"\n,\n\"Tranquada\"\n,\n\"Trant\"\n,\n\"Trask\"\n,\n\"Tratner\"\n,\n\"Trauner\"\n,\n\"Trautman\"\n,\n\"Travax\"\n,\n\"Traver\"\n,\n\"Travers\"\n,\n\"Travis\"\n,\n\"Travus\"\n,\n\"Traweek\"\n,\n\"Tray\"\n,\n\"Treacy\"\n,\n\"Treat\"\n,\n\"Trefler\"\n,\n\"Trefor\"\n,\n\"Treharne\"\n,\n\"Treiber\"\n,\n\"Trela\"\n,\n\"Trella\"\n,\n\"Trellas\"\n,\n\"Trelu\"\n,\n\"Tremain\"\n,\n\"Tremaine\"\n,\n\"Tremann\"\n,\n\"Tremayne\"\n,\n\"Trembly\"\n,\n\"Tremml\"\n,\n\"Trenna\"\n,\n\"Trent\"\n,\n\"Trenton\"\n,\n\"Tresa\"\n,\n\"Trescha\"\n,\n\"Trescott\"\n,\n\"Tressa\"\n,\n\"Tressia\"\n,\n\"Treulich\"\n,\n\"Trev\"\n,\n\"Treva\"\n,\n\"Trevah\"\n,\n\"Trevar\"\n,\n\"Trever\"\n,\n\"Trevethick\"\n,\n\"Trevor\"\n,\n\"Trevorr\"\n,\n\"Trey\"\n,\n\"Tri\"\n,\n\"Trici\"\n,\n\"Tricia\"\n,\n\"Trilbee\"\n,\n\"Trilbi\"\n,\n\"Trilbie\"\n,\n\"Trilby\"\n,\n\"Triley\"\n,\n\"Trill\"\n,\n\"Trillbee\"\n,\n\"Trillby\"\n,\n\"Trilley\"\n,\n\"Trilly\"\n,\n\"Trimble\"\n,\n\"Trimmer\"\n,\n\"Trin\"\n,\n\"Trina\"\n,\n\"Trinatte\"\n,\n\"Trinee\"\n,\n\"Trinetta\"\n,\n\"Trinette\"\n,\n\"Trini\"\n,\n\"Trinia\"\n,\n\"Trinidad\"\n,\n\"Trinity\"\n,\n\"Trinl\"\n,\n\"Triny\"\n,\n\"Trip\"\n,\n\"Triplett\"\n,\n\"Tripp\"\n,\n\"Tris\"\n,\n\"Trisa\"\n,\n\"Trish\"\n,\n\"Trisha\"\n,\n\"Trista\"\n,\n\"Tristam\"\n,\n\"Tristan\"\n,\n\"Tristas\"\n,\n\"Tristis\"\n,\n\"Tristram\"\n,\n\"Trix\"\n,\n\"Trixi\"\n,\n\"Trixie\"\n,\n\"Trixy\"\n,\n\"Trocki\"\n,\n\"Trojan\"\n,\n\"Trometer\"\n,\n\"Tronna\"\n,\n\"Troth\"\n,\n\"Trotta\"\n,\n\"Trotter\"\n,\n\"Trout\"\n,\n\"Trovillion\"\n,\n\"Trow\"\n,\n\"Troxell\"\n,\n\"Troy\"\n,\n\"Troyes\"\n,\n\"Trstram\"\n,\n\"Trubow\"\n,\n\"Truc\"\n,\n\"Truda\"\n,\n\"Trude\"\n,\n\"Trudey\"\n,\n\"Trudi\"\n,\n\"Trudie\"\n,\n\"Trudnak\"\n,\n\"Trudy\"\n,\n\"True\"\n,\n\"Trueblood\"\n,\n\"Truelove\"\n,\n\"Trueman\"\n,\n\"Truitt\"\n,\n\"Trula\"\n,\n\"Trumaine\"\n,\n\"Truman\"\n,\n\"Trumann\"\n,\n\"Truscott\"\n,\n\"Trust\"\n,\n\"Trutko\"\n,\n\"Tryck\"\n,\n\"Trygve\"\n,\n\"Tsai\"\n,\n\"Tsan\"\n,\n\"Tse\"\n,\n\"Tseng\"\n,\n\"Tshombe\"\n,\n\"Tsuda\"\n,\n\"Tsui\"\n,\n\"Tu\"\n,\n\"Tubb\"\n,\n\"Tuchman\"\n,\n\"Tuck\"\n,\n\"Tucker\"\n,\n\"Tuckie\"\n,\n\"Tucky\"\n,\n\"Tuddor\"\n,\n\"Tudela\"\n,\n\"Tudor\"\n,\n\"Tuesday\"\n,\n\"Tufts\"\n,\n\"Tugman\"\n,\n\"Tuinenga\"\n,\n\"Tull\"\n,\n\"Tulley\"\n,\n\"Tullius\"\n,\n\"Tullus\"\n,\n\"Tullusus\"\n,\n\"Tully\"\n,\n\"Tumer\"\n,\n\"Tuneberg\"\n,\n\"Tung\"\n,\n\"Tunnell\"\n,\n\"Tupler\"\n,\n\"Tuppeny\"\n,\n\"Turino\"\n,\n\"Turk\"\n,\n\"Turley\"\n,\n\"Turmel\"\n,\n\"Turnbull\"\n,\n\"Turne\"\n,\n\"Turner\"\n,\n\"Turnheim\"\n,\n\"Turoff\"\n,\n\"Turpin\"\n,\n\"Turrell\"\n,\n\"Turro\"\n,\n\"Turtle\"\n,\n\"Tut\"\n,\n\"Tutankhamen\"\n,\n\"Tutt\"\n,\n\"Tuttle\"\n,\n\"Tutto\"\n,\n\"Twedy\"\n,\n\"Twelve\"\n,\n\"Twila\"\n,\n\"Twitt\"\n,\n\"Twum\"\n,\n\"Twyla\"\n,\n\"Ty\"\n,\n\"Tybald\"\n,\n\"Tybalt\"\n,\n\"Tybi\"\n,\n\"Tybie\"\n,\n\"Tychon\"\n,\n\"Tychonn\"\n,\n\"Tye\"\n,\n\"Tyika\"\n,\n\"Tyler\"\n,\n\"Tymes\"\n,\n\"Tymon\"\n,\n\"Tymothy\"\n,\n\"Tynan\"\n,\n\"Tyne\"\n,\n\"Tyra\"\n,\n\"Tyre\"\n,\n\"Tyree\"\n,\n\"Tyrone\"\n,\n\"Tyrrell\"\n,\n\"Tyrus\"\n,\n\"Tyson\"\n,\n\"Tzong\"\n,\n\"Ubald\"\n,\n\"Uball\"\n,\n\"Ubana\"\n,\n\"Ube\"\n,\n\"Uchida\"\n,\n\"Uchish\"\n,\n\"Uda\"\n,\n\"Udale\"\n,\n\"Udall\"\n,\n\"Udela\"\n,\n\"Udele\"\n,\n\"Udell\"\n,\n\"Udella\"\n,\n\"Udelle\"\n,\n\"Uel\"\n,\n\"Uela\"\n,\n\"Uella\"\n,\n\"Ugo\"\n,\n\"Uird\"\n,\n\"Uis\"\n,\n\"Uke\"\n,\n\"Ul\"\n,\n\"Ula\"\n,\n\"Ulah\"\n,\n\"Ulane\"\n,\n\"Ulani\"\n,\n\"Ulberto\"\n,\n\"Ulda\"\n,\n\"Ule\"\n,\n\"Ulick\"\n,\n\"Ulises\"\n,\n\"Ulita\"\n,\n\"Ulla\"\n,\n\"Ulland\"\n,\n\"Ullman\"\n,\n\"Ullund\"\n,\n\"Ullyot\"\n,\n\"Ulphi\"\n,\n\"Ulphia\"\n,\n\"Ulphiah\"\n,\n\"Ulric\"\n,\n\"Ulrica\"\n,\n\"Ulrich\"\n,\n\"Ulrick\"\n,\n\"Ulrika\"\n,\n\"Ulrikaumeko\"\n,\n\"Ulrike\"\n,\n\"Ultan\"\n,\n\"Ultann\"\n,\n\"Ultima\"\n,\n\"Ultun\"\n,\n\"Ulu\"\n,\n\"Ulund\"\n,\n\"Ulysses\"\n,\n\"Umberto\"\n,\n\"Ume\"\n,\n\"Umeh\"\n,\n\"Umeko\"\n,\n\"Ummersen\"\n,\n\"Umont\"\n,\n\"Un\"\n,\n\"Una\"\n,\n\"Unders\"\n,\n\"Underwood\"\n,\n\"Undine\"\n,\n\"Undis\"\n,\n\"Undry\"\n,\n\"Une\"\n,\n\"Ungley\"\n,\n\"Uni\"\n,\n\"Unity\"\n,\n\"Unni\"\n,\n\"Uno\"\n,\n\"Upali\"\n,\n\"Uphemia\"\n,\n\"Upshaw\"\n,\n\"Upton\"\n,\n\"Urana\"\n,\n\"Urania\"\n,\n\"Uranie\"\n,\n\"Urata\"\n,\n\"Urba\"\n,\n\"Urbai\"\n,\n\"Urbain\"\n,\n\"Urban\"\n,\n\"Urbana\"\n,\n\"Urbani\"\n,\n\"Urbanna\"\n,\n\"Urbannai\"\n,\n\"Urbannal\"\n,\n\"Urbano\"\n,\n\"Urbanus\"\n,\n\"Urbas\"\n,\n\"Uri\"\n,\n\"Uria\"\n,\n\"Uriah\"\n,\n\"Urial\"\n,\n\"Urian\"\n,\n\"Urias\"\n,\n\"Uriel\"\n,\n\"Urien\"\n,\n\"Uriia\"\n,\n\"Uriiah\"\n,\n\"Uriisa\"\n,\n\"Urina\"\n,\n\"Urion\"\n,\n\"Urissa\"\n,\n\"Urita\"\n,\n\"Urquhart\"\n,\n\"Ursa\"\n,\n\"Ursal\"\n,\n\"Ursala\"\n,\n\"Ursas\"\n,\n\"Ursel\"\n,\n\"Ursi\"\n,\n\"Ursola\"\n,\n\"Urson\"\n,\n\"Ursula\"\n,\n\"Ursulette\"\n,\n\"Ursulina\"\n,\n\"Ursuline\"\n,\n\"Ury\"\n,\n\"Usanis\"\n,\n\"Ushijima\"\n,\n\"Uta\"\n,\n\"Utas\"\n,\n\"Ute\"\n,\n\"Utham\"\n,\n\"Uthrop\"\n,\n\"Utica\"\n,\n\"Uticas\"\n,\n\"Utimer\"\n,\n\"Utley\"\n,\n\"Utta\"\n,\n\"Uttasta\"\n,\n\"Utter\"\n,\n\"Uttica\"\n,\n\"Uuge\"\n,\n\"Uund\"\n,\n\"Uwton\"\n,\n\"Uyekawa\"\n,\n\"Uzia\"\n,\n\"Uzial\"\n,\n\"Uziel\"\n,\n\"Uzzi\"\n,\n\"Uzzia\"\n,\n\"Uzzial\"\n,\n\"Uzziel\"\n,\n\"Va\"\n,\n\"Vaas\"\n,\n\"Vaasta\"\n,\n\"Vachel\"\n,\n\"Vachell\"\n,\n\"Vachil\"\n,\n\"Vachill\"\n,\n\"Vacla\"\n,\n\"Vaclav\"\n,\n\"Vaclava\"\n,\n\"Vacuva\"\n,\n\"Vada\"\n,\n\"Vaden\"\n,\n\"Vadim\"\n,\n\"Vadnee\"\n,\n\"Vaenfila\"\n,\n\"Vahe\"\n,\n\"Vaientina\"\n,\n\"Vail\"\n,\n\"Vaios\"\n,\n\"Vaish\"\n,\n\"Val\"\n,\n\"Vala\"\n,\n\"Valaree\"\n,\n\"Valaria\"\n,\n\"Valda\"\n,\n\"Valdas\"\n,\n\"Valdemar\"\n,\n\"Valdes\"\n,\n\"Valdis\"\n,\n\"Vale\"\n,\n\"Valeda\"\n,\n\"Valenba\"\n,\n\"Valencia\"\n,\n\"Valene\"\n,\n\"Valenka\"\n,\n\"Valenta\"\n,\n\"Valente\"\n,\n\"Valentia\"\n,\n\"Valentijn\"\n,\n\"Valentin\"\n,\n\"Valentina\"\n,\n\"Valentine\"\n,\n\"Valentino\"\n,\n\"Valenza\"\n,\n\"Valer\"\n,\n\"Valera\"\n,\n\"Valeria\"\n,\n\"Valerian\"\n,\n\"Valerie\"\n,\n\"Valerio\"\n,\n\"Valerlan\"\n,\n\"Valerle\"\n,\n\"Valery\"\n,\n\"Valerye\"\n,\n\"Valeta\"\n,\n\"Valiant\"\n,\n\"Valida\"\n,\n\"Valina\"\n,\n\"Valle\"\n,\n\"Valleau\"\n,\n\"Vallery\"\n,\n\"Valley\"\n,\n\"Valli\"\n,\n\"Vallie\"\n,\n\"Vallo\"\n,\n\"Vallonia\"\n,\n\"Vally\"\n,\n\"Valma\"\n,\n\"Valonia\"\n,\n\"Valoniah\"\n,\n\"Valora\"\n,\n\"Valorie\"\n,\n\"Valry\"\n,\n\"Valtin\"\n,\n\"Van\"\n,\n\"VanHook\"\n,\n\"Vance\"\n,\n\"Vanda\"\n,\n\"Vanden\"\n,\n\"Vander\"\n,\n\"Vanderhoek\"\n,\n\"Vandervelde\"\n,\n\"Vandyke\"\n,\n\"Vanessa\"\n,\n\"Vange\"\n,\n\"Vanhomrigh\"\n,\n\"Vani\"\n,\n\"Vania\"\n,\n\"Vanna\"\n,\n\"Vanni\"\n,\n\"Vannie\"\n,\n\"Vanny\"\n,\n\"Vano\"\n,\n\"Vanthe\"\n,\n\"Vanya\"\n,\n\"Vanzant\"\n,\n\"Varden\"\n,\n\"Vardon\"\n,\n\"Vareck\"\n,\n\"Vargas\"\n,\n\"Varhol\"\n,\n\"Varian\"\n,\n\"Varick\"\n,\n\"Varien\"\n,\n\"Varini\"\n,\n\"Varion\"\n,\n\"Varipapa\"\n,\n\"Varney\"\n,\n\"Varrian\"\n,\n\"Vary\"\n,\n\"Vas\"\n,\n\"Vashtee\"\n,\n\"Vashti\"\n,\n\"Vashtia\"\n,\n\"Vasileior\"\n,\n\"Vasilek\"\n,\n\"Vasili\"\n,\n\"Vasiliki\"\n,\n\"Vasilis\"\n,\n\"Vasiliu\"\n,\n\"Vasily\"\n,\n\"Vasos\"\n,\n\"Vasquez\"\n,\n\"Vassar\"\n,\n\"Vassaux\"\n,\n\"Vassell\"\n,\n\"Vassili\"\n,\n\"Vassily\"\n,\n\"Vasta\"\n,\n\"Vastah\"\n,\n\"Vastha\"\n,\n\"Vasti\"\n,\n\"Vasya\"\n,\n\"Vasyuta\"\n,\n\"Vaughan\"\n,\n\"Vaughn\"\n,\n\"Vaules\"\n,\n\"Veal\"\n,\n\"Veator\"\n,\n\"Veats\"\n,\n\"Veda\"\n,\n\"Vedetta\"\n,\n\"Vedette\"\n,\n\"Vedi\"\n,\n\"Vedis\"\n,\n\"Veedis\"\n,\n\"Velasco\"\n,\n\"Velda\"\n,\n\"Veleda\"\n,\n\"Velick\"\n,\n\"Veljkov\"\n,\n\"Velleman\"\n,\n\"Velma\"\n,\n\"Velvet\"\n,\n\"Vena\"\n,\n\"Venable\"\n,\n\"Venator\"\n,\n\"Venditti\"\n,\n\"Veneaux\"\n,\n\"Venetia\"\n,\n\"Venetis\"\n,\n\"Venezia\"\n,\n\"Venice\"\n,\n\"Venita\"\n,\n\"Venn\"\n,\n\"Veno\"\n,\n\"Venola\"\n,\n\"Venterea\"\n,\n\"Vento\"\n,\n\"Ventre\"\n,\n\"Ventura\"\n,\n\"Venu\"\n,\n\"Venus\"\n,\n\"Venuti\"\n,\n\"Ver\"\n,\n\"Vera\"\n,\n\"Verada\"\n,\n\"Veradi\"\n,\n\"Veradia\"\n,\n\"Veradis\"\n,\n\"Verbenia\"\n,\n\"Verda\"\n,\n\"Verdha\"\n,\n\"Verdi\"\n,\n\"Verdie\"\n,\n\"Vere\"\n,\n\"Verena\"\n,\n\"Verene\"\n,\n\"Verge\"\n,\n\"Verger\"\n,\n\"Vergil\"\n,\n\"Vergne\"\n,\n\"Vergos\"\n,\n\"Veriee\"\n,\n\"Verile\"\n,\n\"Verina\"\n,\n\"Verine\"\n,\n\"Verity\"\n,\n\"Verla\"\n,\n\"Verlee\"\n,\n\"Verlie\"\n,\n\"Vern\"\n,\n\"Verna\"\n,\n\"Verne\"\n,\n\"Vernen\"\n,\n\"Verner\"\n,\n\"Verneuil\"\n,\n\"Verney\"\n,\n\"Vernice\"\n,\n\"Vernier\"\n,\n\"Vernita\"\n,\n\"Vernon\"\n,\n\"Vernor\"\n,\n\"Veron\"\n,\n\"Veronica\"\n,\n\"Veronika\"\n,\n\"Veronike\"\n,\n\"Veronique\"\n,\n\"Verras\"\n,\n\"Vershen\"\n,\n\"Vescuso\"\n,\n\"Vesta\"\n,\n\"Veta\"\n,\n\"Vetter\"\n,\n\"Vevay\"\n,\n\"Vevina\"\n,\n\"Vevine\"\n,\n\"Vey\"\n,\n\"Vezza\"\n,\n\"Vharat\"\n,\n\"Vi\"\n,\n\"Viafore\"\n,\n\"Vial\"\n,\n\"Vic\"\n,\n\"Viccora\"\n,\n\"Vick\"\n,\n\"Vickey\"\n,\n\"Vicki\"\n,\n\"Vickie\"\n,\n\"Vicky\"\n,\n\"Victoir\"\n,\n\"Victor\"\n,\n\"Victoria\"\n,\n\"Victorie\"\n,\n\"Victorine\"\n,\n\"Victory\"\n,\n\"Vida\"\n,\n\"Vidal\"\n,\n\"Vidda\"\n,\n\"Viddah\"\n,\n\"Vidovic\"\n,\n\"Vidovik\"\n,\n\"Viehmann\"\n,\n\"Viens\"\n,\n\"Vierno\"\n,\n\"Vieva\"\n,\n\"Vig\"\n,\n\"Vigen\"\n,\n\"Viglione\"\n,\n\"Vigor\"\n,\n\"Viguerie\"\n,\n\"Viki\"\n,\n\"Viking\"\n,\n\"Vikki\"\n,\n\"Vikky\"\n,\n\"Vilberg\"\n,\n\"Vilhelmina\"\n,\n\"Villada\"\n,\n\"Villiers\"\n,\n\"Vilma\"\n,\n\"Vin\"\n,\n\"Vina\"\n,\n\"Vinaya\"\n,\n\"Vince\"\n,\n\"Vincelette\"\n,\n\"Vincent\"\n,\n\"Vincenta\"\n,\n\"Vincentia\"\n,\n\"Vincents\"\n,\n\"Vincenty\"\n,\n\"Vincenz\"\n,\n\"Vine\"\n,\n\"Vinia\"\n,\n\"Vinita\"\n,\n\"Vinn\"\n,\n\"Vinna\"\n,\n\"Vinni\"\n,\n\"Vinnie\"\n,\n\"Vinny\"\n,\n\"Vins\"\n,\n\"Vinson\"\n,\n\"Viola\"\n,\n\"Violante\"\n,\n\"Viole\"\n,\n\"Violet\"\n,\n\"Violeta\"\n,\n\"Violetta\"\n,\n\"Violette\"\n,\n\"Vipul\"\n,\n\"Viquelia\"\n,\n\"Viradis\"\n,\n\"Virendra\"\n,\n\"Virg\"\n,\n\"Virge\"\n,\n\"Virgel\"\n,\n\"Virgie\"\n,\n\"Virgil\"\n,\n\"Virgilia\"\n,\n\"Virgilio\"\n,\n\"Virgin\"\n,\n\"Virgina\"\n,\n\"Virginia\"\n,\n\"Virginie\"\n,\n\"Virgy\"\n,\n\"Viridi\"\n,\n\"Viridis\"\n,\n\"Viridissa\"\n,\n\"Virnelli\"\n,\n\"Viscardi\"\n,\n\"Vish\"\n,\n\"Vita\"\n,\n\"Vitale\"\n,\n\"Vitalis\"\n,\n\"Vite\"\n,\n\"Vitek\"\n,\n\"Vitia\"\n,\n\"Vitkun\"\n,\n\"Vito\"\n,\n\"Vitoria\"\n,\n\"Vittoria\"\n,\n\"Vittorio\"\n,\n\"Vitus\"\n,\n\"Viv\"\n,\n\"Viva\"\n,\n\"Viveca\"\n,\n\"Vivi\"\n,\n\"Vivia\"\n,\n\"Vivian\"\n,\n\"Viviana\"\n,\n\"Viviane\"\n,\n\"Vivianna\"\n,\n\"Vivianne\"\n,\n\"Vivica\"\n,\n\"Vivie\"\n,\n\"Vivien\"\n,\n\"Viviene\"\n,\n\"Vivienne\"\n,\n\"Viviyan\"\n,\n\"Vivl\"\n,\n\"Vivle\"\n,\n\"Vivyan\"\n,\n\"Vivyanne\"\n,\n\"Vizza\"\n,\n\"Vizzone\"\n,\n\"Vlad\"\n,\n\"Vlada\"\n,\n\"Vladamar\"\n,\n\"Vladamir\"\n,\n\"Vladi\"\n,\n\"Vladimar\"\n,\n\"Vladimir\"\n,\n\"Voccola\"\n,\n\"Voe\"\n,\n\"Vogel\"\n,\n\"Vogele\"\n,\n\"Vogeley\"\n,\n\"Vola\"\n,\n\"Volding\"\n,\n\"Voleta\"\n,\n\"Voletta\"\n,\n\"Volin\"\n,\n\"Volkan\"\n,\n\"Volnak\"\n,\n\"Volnay\"\n,\n\"Volney\"\n,\n\"Volny\"\n,\n\"Volotta\"\n,\n\"Volpe\"\n,\n\"Voltmer\"\n,\n\"Voltz\"\n,\n\"Von\"\n,\n\"Vona\"\n,\n\"Vonni\"\n,\n\"Vonnie\"\n,\n\"Vonny\"\n,\n\"Vookles\"\n,\n\"Voorhis\"\n,\n\"Vorfeld\"\n,\n\"Vories\"\n,\n\"Vorster\"\n,\n\"Voss\"\n,\n\"Votaw\"\n,\n\"Vowel\"\n,\n\"Vrablik\"\n,\n\"Vtarj\"\n,\n\"Vtehsta\"\n,\n\"Vudimir\"\n,\n\"Vullo\"\n,\n\"Vyky\"\n,\n\"Vyner\"\n,\n\"Vyse\"\n,\n\"Waal\"\n,\n\"Wachtel\"\n,\n\"Wachter\"\n,\n\"Wack\"\n,\n\"Waddell\"\n,\n\"Waddington\"\n,\n\"Waddle\"\n,\n\"Wade\"\n,\n\"Wadell\"\n,\n\"Wadesworth\"\n,\n\"Wadleigh\"\n,\n\"Wadlinger\"\n,\n\"Wadsworth\"\n,\n\"Waechter\"\n,\n\"Waers\"\n,\n\"Wager\"\n,\n\"Wagner\"\n,\n\"Wagoner\"\n,\n\"Wagshul\"\n,\n\"Wagstaff\"\n,\n\"Wahkuna\"\n,\n\"Wahl\"\n,\n\"Wahlstrom\"\n,\n\"Wailoo\"\n,\n\"Wain\"\n,\n\"Waine\"\n,\n\"Wainwright\"\n,\n\"Wait\"\n,\n\"Waite\"\n,\n\"Waiter\"\n,\n\"Wake\"\n,\n\"Wakeen\"\n,\n\"Wakefield\"\n,\n\"Wakerly\"\n,\n\"Waki\"\n,\n\"Walburga\"\n,\n\"Walcoff\"\n,\n\"Walcott\"\n,\n\"Walczak\"\n,\n\"Wald\"\n,\n\"Waldack\"\n,\n\"Waldemar\"\n,\n\"Walden\"\n,\n\"Waldman\"\n,\n\"Waldner\"\n,\n\"Waldo\"\n,\n\"Waldon\"\n,\n\"Waldos\"\n,\n\"Waldron\"\n,\n\"Wales\"\n,\n\"Walford\"\n,\n\"Waligore\"\n,\n\"Walke\"\n,\n\"Walker\"\n,\n\"Walkling\"\n,\n\"Wall\"\n,\n\"Wallace\"\n,\n\"Wallach\"\n,\n\"Wallache\"\n,\n\"Wallack\"\n,\n\"Wallas\"\n,\n\"Waller\"\n,\n\"Walley\"\n,\n\"Wallford\"\n,\n\"Walli\"\n,\n\"Wallie\"\n,\n\"Walling\"\n,\n\"Wallinga\"\n,\n\"Wallis\"\n,\n\"Walliw\"\n,\n\"Wallraff\"\n,\n\"Walls\"\n,\n\"Wally\"\n,\n\"Walrath\"\n,\n\"Walsh\"\n,\n\"Walston\"\n,\n\"Walt\"\n,\n\"Walter\"\n,\n\"Walters\"\n,\n\"Walther\"\n,\n\"Waltner\"\n,\n\"Walton\"\n,\n\"Walworth\"\n,\n\"Waly\"\n,\n\"Wampler\"\n,\n\"Wamsley\"\n,\n\"Wan\"\n,\n\"Wanda\"\n,\n\"Wandie\"\n,\n\"Wandis\"\n,\n\"Wandy\"\n,\n\"Wane\"\n,\n\"Waneta\"\n,\n\"Wanfried\"\n,\n\"Wang\"\n,\n\"Wanids\"\n,\n\"Wanonah\"\n,\n\"Wanyen\"\n,\n\"Wappes\"\n,\n\"Warchaw\"\n,\n\"Ward\"\n,\n\"Warde\"\n,\n\"Warden\"\n,\n\"Warder\"\n,\n\"Wardieu\"\n,\n\"Wardlaw\"\n,\n\"Wardle\"\n,\n\"Ware\"\n,\n\"Wareing\"\n,\n\"Warenne\"\n,\n\"Warfeld\"\n,\n\"Warfield\"\n,\n\"Warfold\"\n,\n\"Warford\"\n,\n\"Warfore\"\n,\n\"Warfourd\"\n,\n\"Warga\"\n,\n\"Warila\"\n,\n\"Waring\"\n,\n\"Warms\"\n,\n\"Warner\"\n,\n\"Warp\"\n,\n\"Warram\"\n,\n\"Warren\"\n,\n\"Warrenne\"\n,\n\"Warrick\"\n,\n\"Warrin\"\n,\n\"Warring\"\n,\n\"Warthman\"\n,\n\"Warton\"\n,\n\"Wartow\"\n,\n\"Warwick\"\n,\n\"Wash\"\n,\n\"Washburn\"\n,\n\"Washington\"\n,\n\"Washko\"\n,\n\"Wasserman\"\n,\n\"Wasson\"\n,\n\"Wassyngton\"\n,\n\"Wat\"\n,\n\"Watanabe\"\n,\n\"Waterer\"\n,\n\"Waterman\"\n,\n\"Waters\"\n,\n\"Watkin\"\n,\n\"Watkins\"\n,\n\"Watson\"\n,\n\"Watt\"\n,\n\"Wattenberg\"\n,\n\"Watters\"\n,\n\"Watts\"\n,\n\"Waugh\"\n,\n\"Wauters\"\n,\n\"Wavell\"\n,\n\"Waverley\"\n,\n\"Waverly\"\n,\n\"Wawro\"\n,\n\"Waxler\"\n,\n\"Waxman\"\n,\n\"Way\"\n,\n\"Waylan\"\n,\n\"Wayland\"\n,\n\"Waylen\"\n,\n\"Waylin\"\n,\n\"Waylon\"\n,\n\"Waynant\"\n,\n\"Wayne\"\n,\n\"Wayolle\"\n,\n\"Weaks\"\n,\n\"Wearing\"\n,\n\"Weasner\"\n,\n\"Weatherby\"\n,\n\"Weatherley\"\n,\n\"Weathers\"\n,\n\"Weaver\"\n,\n\"Web\"\n,\n\"Webb\"\n,\n\"Webber\"\n,\n\"Weber\"\n,\n\"Webster\"\n,\n\"Wedurn\"\n,\n\"Weed\"\n,\n\"Weeks\"\n,\n\"Wehner\"\n,\n\"Wehrle\"\n,\n\"Wei\"\n,\n\"Weibel\"\n,\n\"Weidar\"\n,\n\"Weide\"\n,\n\"Weider\"\n,\n\"Weidman\"\n,\n\"Weidner\"\n,\n\"Weig\"\n,\n\"Weight\"\n,\n\"Weigle\"\n,\n\"Weihs\"\n,\n\"Weikert\"\n,\n\"Weil\"\n,\n\"Weiler\"\n,\n\"Weiman\"\n,\n\"Wein\"\n,\n\"Weinberg\"\n,\n\"Weiner\"\n,\n\"Weinert\"\n,\n\"Weingarten\"\n,\n\"Weingartner\"\n,\n\"Weinhardt\"\n,\n\"Weinman\"\n,\n\"Weinreb\"\n,\n\"Weinrich\"\n,\n\"Weinshienk\"\n,\n\"Weinstein\"\n,\n\"Weinstock\"\n,\n\"Weintrob\"\n,\n\"Weir\"\n,\n\"Weirick\"\n,\n\"Weisbart\"\n,\n\"Weisberg\"\n,\n\"Weisbrodt\"\n,\n\"Weisburgh\"\n,\n\"Weiser\"\n,\n\"Weisler\"\n,\n\"Weisman\"\n,\n\"Weismann\"\n,\n\"Weiss\"\n,\n\"Weissberg\"\n,\n\"Weissman\"\n,\n\"Weissmann\"\n,\n\"Weitman\"\n,\n\"Weitzman\"\n,\n\"Weixel\"\n,\n\"Weksler\"\n,\n\"Welbie\"\n,\n\"Welby\"\n,\n\"Welch\"\n,\n\"Welcher\"\n,\n\"Welcome\"\n,\n\"Welcy\"\n,\n\"Weld\"\n,\n\"Weldon\"\n,\n\"Welford\"\n,\n\"Welker\"\n,\n\"Welles\"\n,\n\"Wellesley\"\n,\n\"Wellington\"\n,\n\"Wells\"\n,\n\"Welsh\"\n,\n\"Welton\"\n,\n\"Wenda\"\n,\n\"Wendall\"\n,\n\"Wendalyn\"\n,\n\"Wende\"\n,\n\"Wendel\"\n,\n\"Wendelin\"\n,\n\"Wendelina\"\n,\n\"Wendeline\"\n,\n\"Wendell\"\n,\n\"Wendi\"\n,\n\"Wendie\"\n,\n\"Wendin\"\n,\n\"Wendolyn\"\n,\n\"Wendt\"\n,\n\"Wendy\"\n,\n\"Wendye\"\n,\n\"Wenger\"\n,\n\"Wengert\"\n,\n\"Wenn\"\n,\n\"Wennerholn\"\n,\n\"Wenoa\"\n,\n\"Wenona\"\n,\n\"Wenonah\"\n,\n\"Wentworth\"\n,\n\"Wenz\"\n,\n\"Wera\"\n,\n\"Werbel\"\n,\n\"Werby\"\n,\n\"Werner\"\n,\n\"Wernher\"\n,\n\"Wernick\"\n,\n\"Wernsman\"\n,\n\"Werra\"\n,\n\"Wershba\"\n,\n\"Wertheimer\"\n,\n\"Wertz\"\n,\n\"Wes\"\n,\n\"Wesa\"\n,\n\"Wescott\"\n,\n\"Wesla\"\n,\n\"Wesle\"\n,\n\"Weslee\"\n,\n\"Wesley\"\n,\n\"Wessling\"\n,\n\"West\"\n,\n\"Westberg\"\n,\n\"Westbrook\"\n,\n\"Westbrooke\"\n,\n\"Wester\"\n,\n\"Westerfield\"\n,\n\"Westfahl\"\n,\n\"Westfall\"\n,\n\"Westhead\"\n,\n\"Westland\"\n,\n\"Westleigh\"\n,\n\"Westley\"\n,\n\"Westlund\"\n,\n\"Westmoreland\"\n,\n\"Westney\"\n,\n\"Weston\"\n,\n\"Westphal\"\n,\n\"Wetzel\"\n,\n\"Wetzell\"\n,\n\"Wexler\"\n,\n\"Wey\"\n,\n\"Weyermann\"\n,\n\"Weylin\"\n,\n\"Weywadt\"\n,\n\"Whale\"\n,\n\"Whalen\"\n,\n\"Whall\"\n,\n\"Whallon\"\n,\n\"Whang\"\n,\n\"Wharton\"\n,\n\"Whatley\"\n,\n\"Wheaton\"\n,\n\"Wheeler\"\n,\n\"Wheelwright\"\n,\n\"Whelan\"\n,\n\"Whetstone\"\n,\n\"Whiffen\"\n,\n\"Whiney\"\n,\n\"Whipple\"\n,\n\"Whit\"\n,\n\"Whitaker\"\n,\n\"Whitby\"\n,\n\"Whitcher\"\n,\n\"Whitcomb\"\n,\n\"White\"\n,\n\"Whitebook\"\n,\n\"Whitehouse\"\n,\n\"Whitehurst\"\n,\n\"Whitelaw\"\n,\n\"Whiteley\"\n,\n\"Whitford\"\n,\n\"Whiting\"\n,\n\"Whitman\"\n,\n\"Whitnell\"\n,\n\"Whitney\"\n,\n\"Whitson\"\n,\n\"Whittaker\"\n,\n\"Whittemore\"\n,\n\"Whitten\"\n,\n\"Whitver\"\n,\n\"Whorton\"\n,\n\"Whyte\"\n,\n\"Wiatt\"\n,\n\"Wiburg\"\n,\n\"Wichern\"\n,\n\"Wichman\"\n,\n\"Wickham\"\n,\n\"Wickman\"\n,\n\"Wickner\"\n,\n\"Wicks\"\n,\n\"Widera\"\n,\n\"Wie\"\n,\n\"Wiebmer\"\n,\n\"Wieche\"\n,\n\"Wiedmann\"\n,\n\"Wiencke\"\n,\n\"Wiener\"\n,\n\"Wier\"\n,\n\"Wieren\"\n,\n\"Wiersma\"\n,\n\"Wiese\"\n,\n\"Wiggins\"\n,\n\"Wight\"\n,\n\"Wightman\"\n,\n\"Wil\"\n,\n\"Wilber\"\n,\n\"Wilbert\"\n,\n\"Wilbur\"\n,\n\"Wilburn\"\n,\n\"Wilburt\"\n,\n\"Wilcox\"\n,\n\"Wilda\"\n,\n\"Wilde\"\n,\n\"Wildee\"\n,\n\"Wilden\"\n,\n\"Wilder\"\n,\n\"Wildermuth\"\n,\n\"Wildon\"\n,\n\"Wileen\"\n,\n\"Wilek\"\n,\n\"Wilen\"\n,\n\"Wiles\"\n,\n\"Wiley\"\n,\n\"Wilfred\"\n,\n\"Wilfreda\"\n,\n\"Wilfrid\"\n,\n\"Wilhelm\"\n,\n\"Wilhelmina\"\n,\n\"Wilhelmine\"\n,\n\"Wilhide\"\n,\n\"Wilie\"\n,\n\"Wilinski\"\n,\n\"Wilkens\"\n,\n\"Wilkey\"\n,\n\"Wilkie\"\n,\n\"Wilkins\"\n,\n\"Wilkinson\"\n,\n\"Wilkison\"\n,\n\"Will\"\n,\n\"Willa\"\n,\n\"Willabella\"\n,\n\"Willamina\"\n,\n\"Willard\"\n,\n\"Willcox\"\n,\n\"Willdon\"\n,\n\"Willem\"\n,\n\"Willet\"\n,\n\"Willett\"\n,\n\"Willetta\"\n,\n\"Willette\"\n,\n\"Willey\"\n,\n\"Willi\"\n,\n\"William\"\n,\n\"Williams\"\n,\n\"Williamsen\"\n,\n\"Williamson\"\n,\n\"Willie\"\n,\n\"Willin\"\n,\n\"Willing\"\n,\n\"Willis\"\n,\n\"Willman\"\n,\n\"Willmert\"\n,\n\"Willms\"\n,\n\"Willner\"\n,\n\"Willock\"\n,\n\"Willow\"\n,\n\"Wills\"\n,\n\"Willtrude\"\n,\n\"Willumsen\"\n,\n\"Willy\"\n,\n\"Willyt\"\n,\n\"Wilma\"\n,\n\"Wilmar\"\n,\n\"Wilmer\"\n,\n\"Wilmette\"\n,\n\"Wilmott\"\n,\n\"Wilona\"\n,\n\"Wilonah\"\n,\n\"Wilone\"\n,\n\"Wilow\"\n,\n\"Wilscam\"\n,\n\"Wilser\"\n,\n\"Wilsey\"\n,\n\"Wilson\"\n,\n\"Wilt\"\n,\n\"Wilterdink\"\n,\n\"Wilton\"\n,\n\"Wiltsey\"\n,\n\"Wiltshire\"\n,\n\"Wiltz\"\n,\n\"Wimsatt\"\n,\n\"Win\"\n,\n\"Wina\"\n,\n\"Wincer\"\n,\n\"Winchell\"\n,\n\"Winchester\"\n,\n\"Wind\"\n,\n\"Windham\"\n,\n\"Windsor\"\n,\n\"Windy\"\n,\n\"Windzer\"\n,\n\"Winebaum\"\n,\n\"Winer\"\n,\n\"Winfield\"\n,\n\"Winfred\"\n,\n\"Winfrid\"\n,\n\"Wing\"\n,\n\"Wini\"\n,\n\"Winifield\"\n,\n\"Winifred\"\n,\n\"Winikka\"\n,\n\"Winn\"\n,\n\"Winna\"\n,\n\"Winnah\"\n,\n\"Winne\"\n,\n\"Winni\"\n,\n\"Winnick\"\n,\n\"Winnie\"\n,\n\"Winnifred\"\n,\n\"Winny\"\n,\n\"Winograd\"\n,\n\"Winola\"\n,\n\"Winona\"\n,\n\"Winonah\"\n,\n\"Winou\"\n,\n\"Winser\"\n,\n\"Winshell\"\n,\n\"Winslow\"\n,\n\"Winson\"\n,\n\"Winsor\"\n,\n\"Winston\"\n,\n\"Winstonn\"\n,\n\"Winter\"\n,\n\"Winterbottom\"\n,\n\"Winters\"\n,\n\"Winther\"\n,\n\"Winthorpe\"\n,\n\"Winthrop\"\n,\n\"Winton\"\n,\n\"Winwaloe\"\n,\n\"Winzler\"\n,\n\"Wira\"\n,\n\"Wirth\"\n,\n\"Wise\"\n,\n\"Wiseman\"\n,\n\"Wiskind\"\n,\n\"Wisnicki\"\n,\n\"Wistrup\"\n,\n\"Wit\"\n,\n\"Witcher\"\n,\n\"Witha\"\n,\n\"Witherspoon\"\n,\n\"Witkin\"\n,\n\"Witt\"\n,\n\"Witte\"\n,\n\"Wittenburg\"\n,\n\"Wittie\"\n,\n\"Witty\"\n,\n\"Wivestad\"\n,\n\"Wivina\"\n,\n\"Wivinah\"\n,\n\"Wivinia\"\n,\n\"Wixted\"\n,\n\"Woehick\"\n,\n\"Woermer\"\n,\n\"Wohlen\"\n,\n\"Wohlert\"\n,\n\"Wojak\"\n,\n\"Wojcik\"\n,\n\"Wolbrom\"\n,\n\"Wolcott\"\n,\n\"Wolenik\"\n,\n\"Wolf\"\n,\n\"Wolfe\"\n,\n\"Wolff\"\n,\n\"Wolfgang\"\n,\n\"Wolfgram\"\n,\n\"Wolfie\"\n,\n\"Wolford\"\n,\n\"Wolfort\"\n,\n\"Wolfram\"\n,\n\"Wolfson\"\n,\n\"Wolfy\"\n,\n\"Wolgast\"\n,\n\"Wolk\"\n,\n\"Woll\"\n,\n\"Wollis\"\n,\n\"Wolpert\"\n,\n\"Wolsky\"\n,\n\"Womack\"\n,\n\"Won\"\n,\n\"Wonacott\"\n,\n\"Wong\"\n,\n\"Woo\"\n,\n\"Wood\"\n,\n\"Woodall\"\n,\n\"Woodberry\"\n,\n\"Woodcock\"\n,\n\"Woodford\"\n,\n\"Woodhead\"\n,\n\"Woodhouse\"\n,\n\"Woodie\"\n,\n\"Woodley\"\n,\n\"Woodman\"\n,\n\"Woodring\"\n,\n\"Woodrow\"\n,\n\"Woodruff\"\n,\n\"Woods\"\n,\n\"Woodson\"\n,\n\"Woodsum\"\n,\n\"Woodward\"\n,\n\"Woody\"\n,\n\"Woolcott\"\n,\n\"Wooldridge\"\n,\n\"Woolley\"\n,\n\"Woolson\"\n,\n\"Wooster\"\n,\n\"Wootan\"\n,\n\"Woothen\"\n,\n\"Wootten\"\n,\n\"Worden\"\n,\n\"Worl\"\n,\n\"Worlock\"\n,\n\"Worrell\"\n,\n\"Worsham\"\n,\n\"Worth\"\n,\n\"Worthington\"\n,\n\"Worthy\"\n,\n\"Wrand\"\n,\n\"Wren\"\n,\n\"Wrench\"\n,\n\"Wrennie\"\n,\n\"Wright\"\n,\n\"Wrightson\"\n,\n\"Wrigley\"\n,\n\"Wsan\"\n,\n\"Wu\"\n,\n\"Wulf\"\n,\n\"Wulfe\"\n,\n\"Wun\"\n,\n\"Wunder\"\n,\n\"Wurst\"\n,\n\"Wurster\"\n,\n\"Wurtz\"\n,\n\"Wyatan\"\n,\n\"Wyatt\"\n,\n\"Wyck\"\n,\n\"Wycoff\"\n,\n\"Wye\"\n,\n\"Wylde\"\n,\n\"Wylen\"\n,\n\"Wyler\"\n,\n\"Wylie\"\n,\n\"Wylma\"\n,\n\"Wyly\"\n,\n\"Wymore\"\n,\n\"Wyn\"\n,\n\"Wyndham\"\n,\n\"Wyne\"\n,\n\"Wynn\"\n,\n\"Wynne\"\n,\n\"Wynnie\"\n,\n\"Wynny\"\n,\n\"Wyon\"\n,\n\"Wystand\"\n,\n\"Xantha\"\n,\n\"Xanthe\"\n,\n\"Xanthus\"\n,\n\"Xavier\"\n,\n\"Xaviera\"\n,\n\"Xavler\"\n,\n\"Xena\"\n,\n\"Xenia\"\n,\n\"Xeno\"\n,\n\"Xenophon\"\n,\n\"Xenos\"\n,\n\"Xerxes\"\n,\n\"Xever\"\n,\n\"Ximena\"\n,\n\"Ximenes\"\n,\n\"Ximenez\"\n,\n\"Xylia\"\n,\n\"Xylina\"\n,\n\"Xylon\"\n,\n\"Xymenes\"\n,\n\"Yaakov\"\n,\n\"Yablon\"\n,\n\"Yacano\"\n,\n\"Yacov\"\n,\n\"Yaeger\"\n,\n\"Yael\"\n,\n\"Yager\"\n,\n\"Yahiya\"\n,\n\"Yaker\"\n,\n\"Yale\"\n,\n\"Yalonda\"\n,\n\"Yam\"\n,\n\"Yamauchi\"\n,\n\"Yanaton\"\n,\n\"Yance\"\n,\n\"Yancey\"\n,\n\"Yancy\"\n,\n\"Yand\"\n,\n\"Yank\"\n,\n\"Yankee\"\n,\n\"Yann\"\n,\n\"Yarak\"\n,\n\"Yard\"\n,\n\"Yardley\"\n,\n\"Yaron\"\n,\n\"Yarvis\"\n,\n\"Yasmeen\"\n,\n\"Yasmin\"\n,\n\"Yasmine\"\n,\n\"Yasu\"\n,\n\"Yasui\"\n,\n\"Yate\"\n,\n\"Yates\"\n,\n\"Yatzeck\"\n,\n\"Yaya\"\n,\n\"Yazbak\"\n,\n\"Yeargain\"\n,\n\"Yearwood\"\n,\n\"Yeaton\"\n,\n\"Yecies\"\n,\n\"Yee\"\n,\n\"Yeh\"\n,\n\"Yehudi\"\n,\n\"Yehudit\"\n,\n\"Yelena\"\n,\n\"Yelich\"\n,\n\"Yelmene\"\n,\n\"Yemane\"\n,\n\"Yeo\"\n,\n\"Yeorgi\"\n,\n\"Yerga\"\n,\n\"Yerkovich\"\n,\n\"Yerxa\"\n,\n\"Yesima\"\n,\n\"Yeta\"\n,\n\"Yetac\"\n,\n\"Yetah\"\n,\n\"Yetta\"\n,\n\"Yetti\"\n,\n\"Yettie\"\n,\n\"Yetty\"\n,\n\"Yeung\"\n,\n\"Yevette\"\n,\n\"Yi\"\n,\n\"Yila\"\n,\n\"Yim\"\n,\n\"Yirinec\"\n,\n\"Ylla\"\n,\n\"Ynes\"\n,\n\"Ynez\"\n,\n\"Yoho\"\n,\n\"Yoko\"\n,\n\"Yokoyama\"\n,\n\"Yokum\"\n,\n\"Yolanda\"\n,\n\"Yolande\"\n,\n\"Yolane\"\n,\n\"Yolanthe\"\n,\n\"Yona\"\n,\n\"Yonah\"\n,\n\"Yonatan\"\n,\n\"Yong\"\n,\n\"Yonina\"\n,\n\"Yonit\"\n,\n\"Yonita\"\n,\n\"Yoo\"\n,\n\"Yoong\"\n,\n\"Yordan\"\n,\n\"Yorgen\"\n,\n\"Yorgo\"\n,\n\"Yorgos\"\n,\n\"Yorick\"\n,\n\"York\"\n,\n\"Yorke\"\n,\n\"Yorker\"\n,\n\"Yoshi\"\n,\n\"Yoshiko\"\n,\n\"Yoshio\"\n,\n\"Youlton\"\n,\n\"Young\"\n,\n\"Younger\"\n,\n\"Younglove\"\n,\n\"Youngman\"\n,\n\"Youngran\"\n,\n\"Yousuf\"\n,\n\"Yovonnda\"\n,\n\"Ysabel\"\n,\n\"Yseult\"\n,\n\"Yseulta\"\n,\n\"Yseulte\"\n,\n\"Yuhas\"\n,\n\"Yuille\"\n,\n\"Yuji\"\n,\n\"Yuk\"\n,\n\"Yukio\"\n,\n\"Yul\"\n,\n\"Yule\"\n,\n\"Yulma\"\n,\n\"Yuma\"\n,\n\"Yumuk\"\n,\n\"Yun\"\n,\n\"Yunfei\"\n,\n\"Yung\"\n,\n\"Yunick\"\n,\n\"Yup\"\n,\n\"Yuri\"\n,\n\"Yuria\"\n,\n\"Yurik\"\n,\n\"Yursa\"\n,\n\"Yurt\"\n,\n\"Yusem\"\n,\n\"Yusuk\"\n,\n\"Yuu\"\n,\n\"Yuzik\"\n,\n\"Yves\"\n,\n\"Yvette\"\n,\n\"Yvon\"\n,\n\"Yvonne\"\n,\n\"Yvonner\"\n,\n\"Yvor\"\n,\n\"Zabrina\"\n,\n\"Zabrine\"\n,\n\"Zacarias\"\n,\n\"Zaccaria\"\n,\n\"Zacek\"\n,\n\"Zach\"\n,\n\"Zachar\"\n,\n\"Zacharia\"\n,\n\"Zachariah\"\n,\n\"Zacharias\"\n,\n\"Zacharie\"\n,\n\"Zachary\"\n,\n\"Zacherie\"\n,\n\"Zachery\"\n,\n\"Zack\"\n,\n\"Zackariah\"\n,\n\"Zacks\"\n,\n\"Zadack\"\n,\n\"Zadoc\"\n,\n\"Zahara\"\n,\n\"Zahavi\"\n,\n\"Zaid\"\n,\n\"Zailer\"\n,\n\"Zak\"\n,\n\"Zakaria\"\n,\n\"Zakarias\"\n,\n\"Zalea\"\n,\n\"Zales\"\n,\n\"Zaller\"\n,\n\"Zalucki\"\n,\n\"Zamir\"\n,\n\"Zamora\"\n,\n\"Zampardi\"\n,\n\"Zampino\"\n,\n\"Zandra\"\n,\n\"Zandt\"\n,\n\"Zane\"\n,\n\"Zaneski\"\n,\n\"Zaneta\"\n,\n\"Zannini\"\n,\n\"Zantos\"\n,\n\"Zanze\"\n,\n\"Zara\"\n,\n\"Zaragoza\"\n,\n\"Zarah\"\n,\n\"Zared\"\n,\n\"Zaremski\"\n,\n\"Zarger\"\n,\n\"Zaria\"\n,\n\"Zarla\"\n,\n\"Zashin\"\n,\n\"Zaslow\"\n,\n\"Zasuwa\"\n,\n\"Zavala\"\n,\n\"Zavras\"\n,\n\"Zawde\"\n,\n\"Zea\"\n,\n\"Zealand\"\n,\n\"Zeb\"\n,\n\"Zeba\"\n,\n\"Zebada\"\n,\n\"Zebadiah\"\n,\n\"Zebapda\"\n,\n\"Zebe\"\n,\n\"Zebedee\"\n,\n\"Zebulen\"\n,\n\"Zebulon\"\n,\n\"Zechariah\"\n,\n\"Zeculon\"\n,\n\"Zed\"\n,\n\"Zedekiah\"\n,\n\"Zeeba\"\n,\n\"Zeena\"\n,\n\"Zehe\"\n,\n\"Zeidman\"\n,\n\"Zeiger\"\n,\n\"Zeiler\"\n,\n\"Zeitler\"\n,\n\"Zeke\"\n,\n\"Zel\"\n,\n\"Zela\"\n,\n\"Zelazny\"\n,\n\"Zelda\"\n,\n\"Zelde\"\n,\n\"Zelig\"\n,\n\"Zelikow\"\n,\n\"Zelle\"\n,\n\"Zellner\"\n,\n\"Zelma\"\n,\n\"Zelten\"\n,\n\"Zena\"\n,\n\"Zenas\"\n,\n\"Zenda\"\n,\n\"Zendah\"\n,\n\"Zenger\"\n,\n\"Zenia\"\n,\n\"Zennas\"\n,\n\"Zennie\"\n,\n\"Zenobia\"\n,\n\"Zeph\"\n,\n\"Zephan\"\n,\n\"Zephaniah\"\n,\n\"Zeralda\"\n,\n\"Zerelda\"\n,\n\"Zerk\"\n,\n\"Zerla\"\n,\n\"Zerlina\"\n,\n\"Zerline\"\n,\n\"Zeta\"\n,\n\"Zetana\"\n,\n\"Zetes\"\n,\n\"Zetta\"\n,\n\"Zeus\"\n,\n\"Zhang\"\n,\n\"Zia\"\n,\n\"Ziagos\"\n,\n\"Zicarelli\"\n,\n\"Ziegler\"\n,\n\"Zielsdorf\"\n,\n\"Zigmund\"\n,\n\"Zigrang\"\n,\n\"Ziguard\"\n,\n\"Zilber\"\n,\n\"Zildjian\"\n,\n\"Zilla\"\n,\n\"Zillah\"\n,\n\"Zilvia\"\n,\n\"Zima\"\n,\n\"Zimmer\"\n,\n\"Zimmerman\"\n,\n\"Zimmermann\"\n,\n\"Zina\"\n,\n\"Zinah\"\n,\n\"Zinck\"\n,\n\"Zindman\"\n,\n\"Zingale\"\n,\n\"Zingg\"\n,\n\"Zink\"\n,\n\"Zinn\"\n,\n\"Zinnes\"\n,\n\"Zins\"\n,\n\"Zipah\"\n,\n\"Zipnick\"\n,\n\"Zippel\"\n,\n\"Zippora\"\n,\n\"Zipporah\"\n,\n\"Zirkle\"\n,\n\"Zischke\"\n,\n\"Zita\"\n,\n\"Zitah\"\n,\n\"Zitella\"\n,\n\"Zitvaa\"\n,\n\"Ziwot\"\n,\n\"Zoa\"\n,\n\"Zoara\"\n,\n\"Zoarah\"\n,\n\"Zoba\"\n,\n\"Zobe\"\n,\n\"Zobias\"\n,\n\"Zobkiw\"\n,\n\"Zoe\"\n,\n\"Zoeller\"\n,\n\"Zoellick\"\n,\n\"Zoes\"\n,\n\"Zoha\"\n,\n\"Zohar\"\n,\n\"Zohara\"\n,\n\"Zoi\"\n,\n\"Zoie\"\n,\n\"Zoila\"\n,\n\"Zoilla\"\n,\n\"Zola\"\n,\n\"Zoldi\"\n,\n\"Zoller\"\n,\n\"Zollie\"\n,\n\"Zolly\"\n,\n\"Zolnay\"\n,\n\"Zolner\"\n,\n\"Zoltai\"\n,\n\"Zonda\"\n,\n\"Zondra\"\n,\n\"Zonnya\"\n,\n\"Zora\"\n,\n\"Zorah\"\n,\n\"Zorana\"\n,\n\"Zorina\"\n,\n\"Zorine\"\n,\n\"Zosema\"\n,\n\"Zosi\"\n,\n\"Zosima\"\n,\n\"Zoubek\"\n,\n\"Zrike\"\n,\n\"Zsa\"\n,\n\"Zsa Zsa\"\n,\n\"Zsazsa\"\n,\n\"Zsolway\"\n,\n\"Zubkoff\"\n,\n\"Zucker\"\n,\n\"Zuckerman\"\n,\n\"Zug\"\n,\n\"Zulch\"\n,\n\"Zuleika\"\n,\n\"Zulema\"\n,\n\"Zullo\"\n,\n\"Zumstein\"\n,\n\"Zumwalt\"\n,\n\"Zurek\"\n,\n\"Zurheide\"\n,\n\"Zurkow\"\n,\n\"Zurn\"\n,\n\"Zusman\"\n,\n\"Zuzana\"\n,\n\"Zwart\"\n,\n\"Zweig\"\n,\n\"Zwick\"\n,\n\"Zwiebel\"\n,\n\"Zysk\"\n]\n\t\t</script>\n\t\t<style>\n\t\t\thtml, body {\n\t\t\t\tfont-size: 24pt;\n\t\t\t}\n\t\t</style>\n\t</body>\n</html>"
  },
  {
    "path": "test/tmp/indexedDB.html",
    "content": "<h1>RindexedDB</h1>\n\n<script src=\"../../gun.js\"></script>\n<script src=\"../../lib/radix.js\"></script>\n<script src=\"../../lib/radisk.js\"></script>\n<script src=\"../../lib/store.js\"></script>\n<script src=\"../../lib/rindexed.js\"></script>\n\n<script>\nlocalStorage.clear();\n\nvar opt = {};\n\nopt.store = RindexedDB(opt);\n\nvar gun = Gun(opt);\n</script>\n"
  },
  {
    "path": "test/tmp/mitra/client_to_server.js",
    "content": "process.env.GUN_ENV = \"false\";\nvar Gun=require('gun')\nvar g = new Gun({peers: ['http://localhost:4246/gun'],localStorage: false});\ng.get(\"FOOxx\").get(\"BARxx\").once(data=>console.log(\"RCVD: (SHOULD NOT BE UNDEFINED!)\", data));\n\nconsole.log('now run ```var g = new Gun({peers: [\"http://localhost:4246/gun\"],localStorage: false}); g.get(\"FOOxx\").get(\"BARxx\").once(data=>console.log(\"RCVD:\", data))```');"
  },
  {
    "path": "test/tmp/mitra/gun_https2.js",
    "content": "//var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8080;\n\nconst port = 4246;\n\nconst https = require('https');\nconst http = require('http');\nconst fs = require('fs');\nprocess.env.GUN_ENV = \"false\";\nconst Gun = require('gun');\nconst path = require('path');\n\nconst usehttps = false;\n\nconst options =\n    usehttps ?  {\n        key: fs.readFileSync('/etc/letsencrypt/live/dweb.me/privkey.pem'),\n        cert: fs.readFileSync('/etc/letsencrypt/live/dweb.me/fullchain.pem'),\n    }  : {};\nvar h = usehttps ? https : http\n//var server = h.createServer(options, (req, res) => {\nvar server = h.createServer((req, res) => {\n\tif(Gun.serve(req, res)){ return } // filters gun requests!\n    res.writeHead(200);\n    res.end('go away - nothing for browsers here\\n');\n\n\t/*\n\tfs.createReadStream(path.join(__dirname, req.url))\n    .on('error',function(){ // static files!\n        res.writeHead(200, {'Content-Type': 'text/html'});\n        res.end(fs.readFileSync(path.join(__dirname, 'index.html'))); // or default to index\n        })\n    .pipe(res); // stream\n    */\n});\n\n\n//TODO-GUN put this into a separate require\nfunction hijack(cb) {\n    /* Intercept outgoing message and replace result with\n        result from cb({soul, key, msg, original})\n     */\n\n    Gun.on('opt', function (root) {\n        console.log(\"GUN: Hikacking loading trap\");\n        if (root.once) {\n            return\n        }\n        root.on('out', function (msg) {\n            console.log(\"GUN: Hikacking starting outgoing message=\", msg);\n            let to = this.to;\n            // TODO-GUN - this wont work when running locally in a script ONLY when running in server\n            if(msg['@'] && !msg.put) {\n                console.log(\"GUN: Hikacking outgoing message\", msg);\n                setTimeout(function(){  // TODO-GUN its unclear why this timeout is here, other than for testing\n                    let tmp = root.dup.s[msg['@']];\n                    let original = tmp && tmp.it && tmp.it.get;\n                    console.log(\"GUN: Hikacking outgoing message original=\", original);\n                    if (original) {\n                        let soul = original['#'];\n                        let key = original['.'];\n                        console.log(\"GUN.hijack: soul=\",soul,\"key=\", key);\n                        let res;\n                        try {\n                            //TODO - this res now has to be async\n                            res = cb({soul, key, msg, original});   // Note response can be undefined if error\n                        } catch(err) {\n                            console.warn(\"Gun.hijack callback error\",err);\n                            res = undefined;\n                        }\n                        msg.put = {\n                        [soul]: {\n                                _: {\n                                    '#': soul,\n                                    '>': {[key]: Gun.state()}\n                                },\n                                [key]: res    // Note undefined should (hopefully) be a valid response\n                        }    };\n                        console.log(\"GUN.hijack updated msg =\", msg);\n                        // NOTE: this doesn't necessarily save it back to\n                        // this peers GUN data, (I (Mitra) thinks that may depend on other processes and order of Gun.on)\n                    }\n                    to.next(msg);\n                }, 100);    //Just for testing and note that its async\n            } else {\n                to.next(msg); // pass to next middleware\n            }\n        });\n        this.to.next(root); // This is next for the Gun.on('opt'), not for the root.on('out')\n    });\n}\nhijack(function({soul=undefined, key=undefined, msg=undefined, original=undefined}={}) {\n    console.log(\"GUN: hijack testing\", soul, key, msg, original);\n    return (\"GUN: This is a test result\");\n});\n\nvar gun = new Gun({\n    web: server\n});\n\n\nserver.listen(port);\n\nconsole.log(usehttps ? \"HTTPS\" : \"HTTP\", 'Server started on port ' + port + ' with /gun');\n"
  },
  {
    "path": "test/tmp/radisk.html",
    "content": "<h1>Radisk</h1>\n\n<script src=\"../../examples/jquery.js\"></script>\n<script src=\"../../gun.js\"></script>\n<script src=\"../../lib/radix.js\"></script>\n<script src=\"../../lib/radisk.js\"></script>\n<script src=\"../../lib/store.js\"></script>\n\n<button onclick=\"var i = 0; window.TO = setInterval(function(){ gun.get(Gun.text.random(3)).put({a: ++i}) }, 0);\">start</button>\n<button onclick=\"clearTimeout(window.TO);\">end</button>\n<br/><br/>\n<button onclick=\"gun.get('a').put({b: Gun.text.random(900)});setTimeout(function(){gun.get('x').put({y: Gun.text.random(900)});},1000);\">write</button>\n<button id='read' onclick=\"console.debug.i=1;gun.get('a').once(d => console.log(1, d));gun.get('x').once(d => console.log(2, d));\">read</button>\n\n<script>\n//localStorage.clear();\n\nfunction Store(opt){\n  opt = opt || {};\n  opt.file = String(opt.file || 'radata');\n  var storage = window.storage = localStorage;//{};\n  var store = function Store(){}, u;\n  store.put = function(file, data, cb){\n    //console.log(\"put\", file, data);\n    setTimeout(function(){\n      storage[file] = data;\n      cb(null, 1);\n    }, 25);\n  };\n  store.get = function(file, cb){\n    //console.log(\"get\", file);\n    setTimeout(function(){\n      var tmp = storage[file] || u;\n      cb(null, tmp);\n    }, 10);\n  };\n  store.list = function(cb, match){\n    //console.log('list');\n    setTimeout(function(){\n      Gun.obj.map(Object.keys(storage), cb) || cb();\n    }, 5);\n  };\n  return store;\n}\n\nvar gun = Gun({localStorage: false, store: Store(), chunk: 1024, batch: 100});\n\n//setTimeout(function(){ $('#read').trigger('click') });\n</script>"
  },
  {
    "path": "test/tmp/say.html",
    "content": "<script src=\"../examples/jquery.js\"></script>\n<script src=\"../gun.js\"></script>\n<script src=\"../lib/cryptomodules.js\"></script>\n<script src=\"../sea.js\"></script>\n<script>\n;(function(){\n\tlocalStorage.clear();sessionStorage.clear();\n\t\n\tvar gun = window.gun = Gun();\n\tvar user = gun.user();\n\n\tgun.on('secure', function(at){\n\t\t/* enforce some rules about shared app level data */\n\t\tif(!at.put || !at.put.users){ return }\n\t\tvar no;\n\t\tGun.node.is(at.put.users, function(val, key){\n\t\t\tGun.SEA.read(val, false, function(val){\n\t\t\t\tif('alias/'+key === Gun.val.link.is(val)){ return }\n\t\t\t\tno = true;\n\t\t\t})\n\t\t\tif(no){ return no }\n\t\t});\n\t\tif(no){ return }\n\t\tthis.to.next(at);\n\t});\n\n\tuser.create('alice', 'unsafepassword', login);\n\n\tfunction login(ack){\n\t\tconsole.log(\"login...\");\n\t\twindow.pub = ack.pub;\n\t\tgun.get('users').get('alice').put(gun.get('alias/alice'));\n\t\tuser.auth('alice', 'unsafepassword', sub);\n\t}\n\n\tfunction sub(){\n\t\tconsole.log(\"subscribe...\");\n\t\tgun.get('users').map().map()\n\t\t\t.get('who').get('said').map().on(function(msg){\n\t\t\t\tif(!check[msg.num]){ console.log(msg.num); return } check[msg.num] = false;\n\t\t\t\tconsole.log(\"!!!!!!!\", msg.num ,\"!!!!!!!\");\n\t\t\t\t$(\"<div>\").css({border: '1px solid black'}).text(msg.what).appendTo('body');\n\t\t});\n\t\t//window.user = gun.get('pub/'+window.pub);\n\t\twrite();\n\t}\n\n\tfunction write(data){\n\t\tconsole.log(\"write...\");\n\t\tvar said = window.said = user.get('who').get('said');\n\t\twindow.ID = 'alice';\n\n\t\tfunction run(i){\n\t\t\tsaid.set({\n\t\t\t\twhat: i + \" Hello world! ~ \" + pub.slice(0,3),\n\t\t\t\tnum: i,\n\t\t\t\twho: pub,\n\t\t\t\tid: ID,\n\t\t\t});\n\t\t}\n\n\t\twindow.check = {};\n\t\tvar i = 0, m = 9, to = setInterval(function frame(){\n\t\t\tif(m <= i){\n\t\t\t\tclearTimeout(to);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ti++;\n\t\t\tcheck[i] = true;\n\t\t\trun(i);\n\t\t}, 1);\n\t}\n\n}());\n</script>"
  },
  {
    "path": "test/tmp/seanode.js",
    "content": "var Gun = require('../../gun.js');\nrequire('../../sea.js');\n\nvar pub = \"tgEJ8TTeTN8Xi0D3oMVbZGyVVFDGT4AUoqyrUguAguU.9-yZfWtPSZ_4ILnttWy-KWvwUUyO2-dB1DHRYud-CDE\";\n\nvar sig = decodeURIComponent(\"SEA%7B%22m%22%3A%22%5C%22hello%5C%22%22%2C%22s%22%3A%22%C2%90%C3%B1%C3%93sy%5Cu0011%C3%87%C2%A5%C2%97%C3%93%5Cu0011%C3%A1JV%C2%AA%C3%94C%C3%A3%C3%85%C2%80a%5Cu0006%C2%B6%C2%A7%C3%BE%C2%9F%C2%92%5Cu000eS%C2%90%C3%A8%C3%B1kH%7D%C2%9A%5Cb%C3%B0g%C2%B9%7F%C2%B2%C3%9F%C3%A0j%C3%9Bk%5C%22%3E%C2%B6%C2%8F%5Cu001b%C3%81%C2%8B%C2%97%C3%92%C2%AA%C3%A5%C2%B6%5D%C3%85%C2%9A%3BA%22%7D\");\n\nconsole.log(sig);\n\n;(async function(){\n\tvar test = await Gun.SEA.verify(sig, pub);\n\tconsole.log(\"???\", test);\n}());"
  },
  {
    "path": "test/tmp/space.html",
    "content": "<h1>Search</h1>\n\n<form id=\"ask\">\n  <input id=\"search\" placeholder=\"search...\" autocomplete=\"off\">\n</form>\n\n<div id=\"answer\"></div>\n<ul></ul>\n\n<small>Note: No data is indexed by default, you need to add some!</small>\n\n<script src=\"../../examples/jquery.js\"></script>\n<script src=\"../../gun.js\"></script>\n<script src=\"../../sea.js\"></script>\n<script src=\"../../lib/space.js\"></script>\n\n<script>\nvar gun = Gun();\nvar ask = {};\n\n$('#search').on('keyup', function(e){\n\task.now = (this.value||'').toLowerCase().replace(/[\\W_]+/g,\"\");\n  if(ask.last === ask.now){ return }\n  ask.last = ask.now;\n  clearTimeout(ask.to);\n  ask.to = setTimeout(search, 20);\n});\n\nfunction search(){\n  var key = ask.now;\n  gun.get('Q').space(key, function(ack){\n    if(!ack || key !== ask.now){ return }\n    UI(ack)\n  });\n}\n\nfunction UI(ack){\n  $('#answer').text(ack.data || '');\n  var $ul = $('ul').empty(), tree = ack.tree;\n  Gun.obj.map(tree, function(v,k){\n    $('<li>').text(k +' - ' + v).appendTo($ul);\n  });\n};\n\nfunction load(DATA){\n  Gun.obj.map(DATA, function(v,k){\n    gun.get('Q').space(k, v); \n  });\n}\n</script>"
  },
  {
    "path": "test/tmp/time.html",
    "content": "<h1>Infinite Stream of Tweets/Chats:</h1>\n\n<ul></ul>\n<div id=\"latest\">while in scroll, latest tweet should show here</div>\nScroll:\n<button id=\"up\">UP</button>\n<button id=\"down\">DOWN</button>\n\n<script src=\"../../examples/jquery.js\"></script>\n<script src=\"../../gun.js\"></script>\n<script src=\"../../lib/time.js\"></script>\n\n<script>$(function(){\n\nvar gun = Gun();\nwindow.app = {};\n\napp.newsfeed = gun.get('some').get('news').get('feed'); // this would be a timegraph\n\napp.modifier = app.newsfeed.time();\n\nvar low = -5, top = 0;\napp.modifier.range(low, top);\n\napp.modifier.on(function(range){\n  $('ul').empty(); // bad in theory, but proves out this type of \"range\" object.\n  range.forEach(UI);\n});\n\n$('#up').on('click', function(){\n  alert('not working...');\n  app.modifier.range(--low, --top);\n});\n$('#down').on('click', function(){\n  alert('not working...');\n  app.modifier.range(++low, ++top);\n});\n\nfunction UI(say, id){\n  var li = $('#' + id).get(0) || $('<li>').attr('id', id).appendTo('ul');\n  $(li).text(say);\n};\n\n})</script>\n\n<script>\n/* FAKE CODE TO GENERATE FAKE TESTS */\n/* SHOULD BE REPLACED WITH YOUR OWN */\n/* BUT USING THE SAM TYPE OF TEST!! */\n/* THIS IS BAD CODE!!!!!! */\n/* IT MEMORY LEAKS INFINITELY */\n/* JUST FAKING IT TILL API MAKES IT! */\n/* ACTUAL CODE SHOULD USE GUN NOT INFINITE */\n/* GROWING LOCAL CACHE, GUN ALREADY CACHES */\nvar i = 0, tweet = \"this tweet says \", bad = {leak: []};\nsetInterval(function(){\n  app.newsfeed.set(tweet + (++i));\n}, 1000);\nGun.chain.time = function(){\n  var chain = this.map(function(item){\n    bad.leak.push(item); // bad bad bad bad\n    return bad.leak.slice(0 - bad.num); // should traverse GUN not slice a memory leak\n  });\n  return chain;\n}\nGun.chain.range = function(low, top){\n  bad.low = low;\n  bad.top = top;\n  bad.num = top - low;\n  return this;\n}\n</script>"
  },
  {
    "path": "test/tmp/tmp.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../examples/style.css\">\n</head>\n<body>\n<style>\n\t@import url('https://fonts.googleapis.com/css?family=Oxygen');\n\thtml, body {\n\t\tfont-family: \"Oxygen\", sans-serif;\n\t}\n</style>\n<script src=\"../../examples/jquery.js\"></script>\n<script src=\"../../gun.js\"></script>\n<script src=\"../../sea.js\"></script>\n<script>\nvar db = Gun({faith: true});\n\nsetTimeout(function(){\n\t//return;\n\t//console.log(db.get(window.SOUL)._.put);\n\t//return;\n\tdb.get(window.SOUL).once(function(data){\n\t\tconsole.log('oye!', data);\n\t})\n}, 1000);\n\nfunction test(result, dedupId){ setTimeout(function(){\n\tif (result) {\n\t\tvar foo = function(){}; foo.faith = false;\n\t  db.on('in', {\n\t    '@': dedupId,\n\t    from: 'local',\n\t    put: { [Gun.node.soul(result)]: result },\n\t    err: null,\n\t    _: foo\n\t  })\n\t}\n},100) }\ntest(window.foo = {\"_\":{\"#\": window.SOUL = \"nab/things/1d0f60a50f65b95dd91036836904c3bcbe916300/data~JG43ynRxqjy1-AemyMUoz14UqKM6cnh7zSPy_EAPgts.RCZ5dY7iRaIW_B7cDBlBsDNKwn2QCtbbA1uQ6iL8ENw.\",\">\":{\"title\":1557772735675,\"body\":1557772735675,\"topic\":1557772735675,\"url\":1557772735675,\"author\":1557772735675,\"authorId\":1557772735675,\"timestamp\":1557772735675,\"kind\":1557772735675}},\n\t\"title\":\"{\\\":\\\":\\\"'I can't breathe': Officer faces CCRB trial in Eric Garner death\\\",\\\"~\\\":\\\"6mbgWoNB/zYMpttniBxEE8myvfm9aDKNLflSL1PiURknSZDMAGPG9LxZo0xcsfC24ZTDpmz/Z2PTkk3TpH8jjQ==\\\"}\",\n\t\"body\":\"{\\\":\\\":\\\"\\\",\\\"~\\\":\\\"ivq/8T4ILsGTo7ME5GlcCNeU2uh4RAcLAn+k2J0+3dm+0nFs/uxN6jg5zBxPD3Qf+qs853haH1uM0032k2pKdg==\\\"}\",\"topic\":\"{\\\":\\\":\\\"politics\\\",\\\"~\\\":\\\"X1Z/Wn3qIdaw6vfE22BlgKhXpIYQCavyYNAw9FkxQQanikQSjCmzqrKlDgpvBOYXob9RRXgruGOaWdLqkEvz5A==\\\"}\",\n\t\"url\":\"{\\\":\\\":\\\"https://www.aljazeera.com/news/2019/05/breathe-officer-faces-ccrb-trial-eric-garner-death-190513163733279.html\\\",\\\"~\\\":\\\"g2pdJuGuwCgFyqEJX1Co/sUyG4h8t8lsFa5ON0MC8R7Y3zqKauNhFzcwVpP/QyM1lYr1duoZ7YE5PurDKRVuXw==\\\"}\",\n\t\"author\":\"{\\\":\\\":\\\"go1dfish\\\",\\\"~\\\":\\\"ovwCbuQeYp5rRABi9bTNKcEeeFXEiozWG28aRCl+MjOMNeqOxDEKIsnsgYgJmmSXvNhe/MpuL3376nL0vTN6qA==\\\"}\",\n\t\"authorId\":\"{\\\":\\\":\\\"JG43ynRxqjy1-AemyMUoz14UqKM6cnh7zSPy_EAPgts.RCZ5dY7iRaIW_B7cDBlBsDNKwn2QCtbbA1uQ6iL8ENw\\\",\\\"~\\\":\\\"ekhiqU7UP1M8nHxBFv8QItNBIstP6zuQBtutk6sqMBNaN/2U9BAjb7Vjsogj23kphEMHeCSgO7AqaOE3cOZiyg==\\\"}\",\n\t\"timestamp\":\"{\\\":\\\":1557772735666,\\\"~\\\":\\\"Z2AiDehqJKrbRlXXUllkwWjOEn5//HnjjTMdgNz2j8K/Bw5XPK1g0huVQsfWdKOKfr9XU7Y5sY2N526V13O4XA==\\\"}\",\"kind\":\"{\\\":\\\":\\\"submission\\\",\\\"~\\\":\\\"KwjYOjPnpZH85VVOHZAxLm2Ntd/0p3o74sLEGtTf7grBCKb0pzDo7yERjWIaTEiQJ2IFEtu43V/vzhZMTvuvUQ==\\\"}\"})\n//db.get(window.SOUL);\n</script>\n</body>\n</html>"
  },
  {
    "path": "test/trace.html",
    "content": "<html>\n<head>\n<title>Gun Msg Trace</title>\n<style>\nhtml, body {\n  width: 100%;\n  height: 100%;\n  margin: 0 0;\n  font-family: monospace;\n  padding: 10px 15px;\n  color: white;\n}\nbody {\n  background: rgba(0,0,0,0.7);\n}\n#trace {\n}\n#editor {\n  width: 90%;\n  height: 90%;\n  background: gray;\n}\n\n#diagram {\n/*   width: 100%; */\n/*   height: 100%; */\n  margin: 0 auto;\n/*   background: #d2d2d2; */\n/*   position: absolute; */\n  top:0;\n  left:0;\n}\n/*#diagram svg {\n  width: 100%;\n  height: 100%;\n}*/\n#diagram svg text {\n  fill: #79ce7f;\n  f-ill: black;\n  f-ill: red;\n}\n#diagram svg text:hover {\n  fill: #20ff3b;\n  cursor: pointer;\n}\n#diagram svg .note rect, #diagram svg .note path {\n    fill: #666666;\n}\n#diagram svg .title rect,\n#diagram svg .title path,\n#diagram svg .actor rect,\n#diagram svg .actor path {\n    fill: #ffffff;\n    position: fixed;\n    top: 1em;\n}\n#diagram svg .actor {\n  opacity: 0;\n}\n#diagram svg .actor text {\n    fill: #000000;\n}\n#diagram svg .actor line {\n    fill: #000000;\n    stroke-width: 5px;\n}\n#diagram svg line {\n  stroke: rgba(0,0,0,0.5);\n/*   stroke-width: 5px; */\n}\n.method {\n  font-size: 140%;\n  display: block;\n  background: black;\n  color: white;\n  padding: 0.3em;\n  top: 7em;\n}\n</style>\n</head>\n<body>\n<div id=\"trace\">\n  <h1>Gun Msg Trace</h1>\n  <h2></h2>\n  <div id=\"diagram\"></div>\n</div>\n<script src=\"../gun.js\"></script>\n<script src=\"../sea.js\"></script>\n<script src=\"./trace.js\"></script>\n\n<script src=\"../examples/jquery.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/gh/bramp/js-sequence-diagrams/test/webfont-mock.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/snapsvg@0.5.1/dist/snap.svg.min.js\"></script>\n<script src=\"https://pagecdn.io/lib/underscore/1.11.0/underscore.min.js\"></script>\n<script src=\"https://cdn.jsdelivr.net/gh/bramp/js-sequence-diagrams/dist/sequence-diagram-min.js\"></script>\n<script>\n;(function(){\n  // OVERLOAD GUN FUNCTIONS THAT WE WANT TO TRACE:\n  \n  /// GUN protocolo\n  var _get = Gun.on._get; Gun.on._get = function(a,b,c,d,e){ Trace.log('GET', a); _get.call(this, a,b,c,d,e) } /// PROTOCOL\n  var _put = Gun.on.put; Gun.on.put = function(a,b,c,d,e){ Trace.log('PUT', a); _put.call(this, a,b,c,d,e) } /// PROTOCOL\n  \n  /// GUN chain\n//   var get = Gun.chain.get; Gun.chain.get = function(a,b,c,d,e){ Trace.log('.get', a); return get.call(this, a,b,c,d,e) } /// chain\n//   var put = Gun.chain.put; Gun.chain.put = function(a,b,c,d,e){ Trace.log('.put', a); return put.call(this, a,b,c,d,e) } /// chain\n//   var map = Gun.chain.map; Gun.chain.map = function(a,b,c,d,e){ Trace.log('.map', a); return map.call(this, a,b,c,d,e) } /// chain\n//   var once = Gun.chain.once; Gun.chain.once = function(a,b,c,d,e){ Trace.log('.once', a); return once.call(this, a,b,c,d,e) } /// chain\n//   var on = Gun.chain.on; Gun.chain.on = function(a,b,c,d,e){ Trace.log('.on', a); return on.call(this, a,b,c,d,e) } /// chain\n\n  /// GUN events\n  var input = Gun.on.in; Gun.on.in = function(a,b,c,d,e){ Trace.log('in', a); input.call(this, a,b,c,d,e) } /// EVENT\n\n  var output = Gun.on.out; Gun.on.out = function(a,b,c,d,e){ Trace.log('out', a); output.call(this, a,b,c,d,e) } /// EVENT\n\n//   var only = console.only; console.only = function(a,b,c,d,e,f,g){ Trace.log('ONLY'); return only.apply(console,arguments) }\n//   var start = +new Date;\n//   setTimeout(function log(){\n//     if((+new Date - start) > 100){ return }\n//     setTimeout(log, 0);\n//     Trace.log(\"ASYNC\");\n//   },0);\n}());\n\n;(function(){ // PASTE YOUR UNIT TEST INTO HERE TO TRACE IT!\n// if (typeof localStorage!=='undefined') { localStorage.clear(); }\n// var goff = Gun();\n// Gun.statedisk = function(o,s,cb){ goff.get(s).put(o, cb, {turn: function(fn){fn()}}); };\n\nvar gun = Gun();\nvar bob = {age: 29, name: \"Bob!\"};\nvar cat = {name: \"Fluffy\", species: \"kitty\"};\nvar user = {bob: bob};\nbob.pet = cat;\ncat.slave = bob;\nTrace.log('START');\n// Gun.statedisk(user, 'nodecircle', function(){\nconsole.only.i=1;console.log(\"=============\", gun);\n\n// gun.get('nodecircle').put(user, function(ack) { Trace.log('ACK', ack); });\n// gun.get('nodecircle').on(function(ack) { Trace.log('END', ack); });\ngun.get('nodecircle').once(function(ack) { Trace.log('END', ack); });\n//       gun.get('nodecircle').get('a').get('b').get('c').on(function(v,k){\n//       gun.get('nodecircle').get('bob').on(function(v,k){\n//       gun.get('nodecircle').get('bob').get('pet').get('slave').once(function(v,k){\n// });\n}());\n\n// Gun.on('trace.end', function(msg){\nsetTimeout(function(){\n  console.log('_____TOTAL LOGS: ',Trace.traces.length, new Date());\n  var id, code = Trace.traces.join('\\n');\n  $('h2:first').text(`Total of steps: ${Trace.traces.length}`);\n  $('title:first').text(`(${Trace.traces.length}) steps | Gun Msg Trace`);\n  var diagram = Diagram.parse(code);\n  diagram.drawSVG(id||'diagram', {theme: 'simple'});\n  setTimeout(function(){\n    $('.actor').each(function(){\n      var pos = $(this).offset();\n      $(\"<span class='method'>\").text($(this).text()).css({position: 'fixed', left: pos.left}).appendTo('body');\n    });\n  });\n}, 2000);\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "test/trace.js",
    "content": "// @rogowski CAME UP WITH THIS BRILLIANT GENIUS ABSOLUTELY AMAZING AWESOME IDEA!!!!\n\n/// This is a simple tool to generate logs in a Sequence Diagram compatible format.\n\nvar Trace = function() {}\nTrace.traces=[];\nTrace.log = function(evname, msg) {\n  //if(!(console.only.i)){ return }\n//   clearTimeout(Trace.log.to);\n//   Trace.log.to = setTimeout(function(){\n//     Trace.on('trace.end', {code: Trace.traces.join('\\n')});\n//   }, 1000);\n  if (!msg) {\n    //console.log('WARN, empty message: ',msg);\n//         msg=evname;\n//         evname = 'GUN';\n  }\n  if (!Trace.loglastev) {\n    Trace.loglastev=evname||'GET';\n    return;\n  };\n//       msg.lastev = Trace.loglastev;\n  Trace.log.i = Trace.log.i ? ++Trace.log.i : 1;\n  //console.log(`*(${Trace.log.i}) ${Trace.loglastev}->:%s, msg:`, evname, msg);\n\n  var __ = (!msg||!msg['#'] ? '' : ('#'+msg['#']).slice(0,4)+'');\n  var dam = (!msg||!msg.dam ? '' : ('dam:'+msg.dam));\n  var at = (!msg||!msg['@'] ? '' : ('@'+msg['@']).slice(0,4)+'');\n  var lS = (!msg||!msg.lS ? '' : ('lS:'+msg.lS));\n  var id = (!msg||!msg.id ? '' : ('id:'+msg.id));\n  var ram = (!msg||!msg.ram ? '' : ('ram:'+msg.ram));\n  var get = (!msg||!msg.get ? '' : ('get:'+Trace.clean(msg.get)).slice(0,15)+'');\n  var put = !(typeof msg === 'object' && ('put' in msg)) ? '' : ('put:'+Trace.clean(msg&&msg.put?msg.put:'')).slice(0,30)+'...';\n  \n//   Trace.loglastevdt Trace.loglastev;\n//   Trace.loglastevdt = +new Date();\n\n  var tm = +new Date();\n  Trace.loglastevdt = +new Date();\n\n//       if (dam && Trace.loglastev==='UNIVERSE') { evname='GET'; }\n  var keys = Array.isArray(msg) ? keys.sort().join(',')\n    : typeof msg==='object' ? Object.keys(msg).sort().join(',')\n    : 'this';\n\n  if (dam) {\n    if (msg['#']) {\n      evname='GUN';\n    } else {\n      Trace.loglastev='GUN';\n    }\n    Trace.traces.push(`${Trace.loglastev}->${evname}: (${Trace.log.i})  {${keys}} ${get} ${put} ${__} ${dam} ${ram} ${id} ${at} ${lS}`);\n  } else {\n    //Trace.traces.push(`${Trace.loglastev}->${evname}: (${Trace.log.i})  {${keys.slice(0,15)}} ${get} ${put} ${__} ${dam} ${ram} ${id} ${at} ${lS}`);\n//     Trace.traces.push(Trace.loglastev+'->'+evname+': '+(Trace.log.i+') '+(console.only.i||''))+' '+__+' '+at);\n      Trace.traces.push(Trace.loglastev+'->'+evname+': '+ Trace.log.i+') '+__+' '+at);\n//     Trace.traces.push(`${Trace.loglastev}->${evname}: (${Trace.log.i}) {${!keys?'this':keys}}`);\n  }\n\n  Trace.loglastev   = evname;\n  Trace.loglastevdt = tm;\n};\nTrace.clean = function(txt) { return JSON.stringify(typeof txt==='undefined' ? 'undef' : txt||null).replace(/\"|\\{|\\}+/g,'').slice(0,20).trim(); };\n"
  },
  {
    "path": "test/wire.txt",
    "content": "10,000 writes of 500 bytes second\n\nIf somebody writes data, it gets piped straight to a cold cache stream.\n\nAfter 15 seconds or 100MB we batch the cold cache stream.\n\nThen spawn a process to convert the last cold cache stream into a cold cache state. Ack level 1.\n\nThe cold cache state is an O(1) radix format, where 1 is the length of the key, that can return an individual value. Ack level 2.\n\nThe cold cache also is serializable into a radix file format that can be stream replicated.\n\nBased on the updates, the radix is chunked into 100MB, where any 100MB section that is different than before gets stream written to cold storage at the same or different interval. Ack level 3.\n\nIf somebody reads data, in a new process we first reverse scan the current stream batch to warm cache it if it exists.\n\nWe then read the radix and merge it with the warm cache response and reply immediately if data exists.\n\nFinally we check to see if we've read from cold storage and if we have not (or if we haven't in a while, like 15 seconds multiplied by 100) we read stream from cold storage and (optionally immediately reply on matches) and then run the same steps to convert this into the cold cache state.\n\nFor cost optimizations, you might want to provide the developer with a deterministic key generator helper that mashes primary key (immutable) indices together into a radix hierarchy.\n\nWe theoretically should be able to delete the LRU 100MB radix chunks if we run out of space.\n\n-------------------------------------- STREAM >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n%'1024'#'\"marknadal/says/1234567890/asdf\"'.'\"who\"'='#\"marknadal\"'.'\"when\"'='1234567890'.'\"what\"'='\"Hello world!\"'>'1234567890'#'\"marknadal\"'.'\"last\"'='#\"marknadal/says/1234567890/asdf\"'.'\"says\"'='#\"marknadal/says\"'>'1234567890'#'\"marknadal/says\"'.'\"marknadal/says/1234567890/asdf\"'='#\"marknadal/says/1234567890/asdf\"'>'1234567890'\n\n%'1024'#'\"ambernadal/says/1234567890/asdf\"'.'\"who\"'='#\"ambernadal\"'.'\"when\"'='1234567890'.'\"what\"'='\"Hello world!\"'>'1234567890'#'\"ambernadal\"'.'\"last\"'='#\"ambernadal/says/1234567890/asdf\"'.'\"says\"'='#\"ambernadal/says\"'>'1234567890'#'\"ambernadal/says\"'.'\"ambernadal/says/1234567890/asdf\"'='#\"ambernadal/says/1234567890/asdf\"'>'1234567890'\n\n%'1024'#'\"jessegibson/says/1234567890/asdf\"'.'\"who\"'='#\"jessegibson\"'.'\"when\"'='1234567890'.'\"what\"'='\"Hello world!\"'>'1234567890'#'\"jessegibson\"'.'\"last\"'='#\"jessegibson/says/1234567890/asdf\"'.'\"says\"'='#\"jessegibson/says\"'>'1234567890'#'\"jessegibson/says\"'.'\"jessegibson/says/1234567890/asdf\"'='#\"jessegibson/says/1234567890/asdf\"'>'1234567890'\n\n%'1024'#'\"marknadal/says/1234567891/fdsa\"'.'\"who\"'='#\"marknadal\"'.'\"when\"'='1234567891'.'\"what\"'='\"Hello universe!\"'>'1234567891'#'\"marknadal\"'.'\"last\"'='#\"marknadal/says/1234567891/fdsa\"'.'\"says\"'='#\"marknadal/says\"'>'1234567891'#'\"marknadal/says\"'.'\"marknadal/says/1234567891/fdsa\"'='#\"marknadal/says/1234567891/fdsa\"'>'1234567891'\n\n--------------------------------------- STATE >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n=@\n\t'#'\n\t\t'ambernadal'\n\t\t\t=@\n\t\t\t\t'.'\n\t\t\t\t\t'last' = '#\"ambernadal/says/1234567890/asdf\"'>'1234567890'\n\t\t\t\t\t'says' = '#\"ambernadal/says\"'>'1234567890'\n\t\t\t'/says'\n\t\t\t\t=@\n\t\t\t\t\t'.ambernadal/says/1234567890/asdf' = '#\"ambernadal/says/1234567890/asdf\"'>'1234567890'\n\t\t\t\t'/1234567890/asdf'\n\t\t\t\t\t=@\n\t\t\t\t\t\t'.wh'\n\t\t\t\t\t\t\t'at' = '\"Hello world!\"'>'1234567890'\n\t\t\t\t\t\t\t'en' = '1234567890'>'1234567890'\n\t\t\t\t\t\t\t'o' = '#\"ambernadal\"'>'1234567890'\n\t\t'jessegibson'\n\t\t\t=@\n\t\t\t\t'.'\n\t\t\t\t\t'last' = '#\"jessegibson/says/1234567890/asdf\"'>'1234567890'\n\t\t\t\t\t'says' = '#\"jessegibson/says\"'>'1234567890'\n\t\t\t'/says'\n\t\t\t\t=@\n\t\t\t\t\t'.jessegibson/says/1234567890/asdf' = '#\"jessegibson/says/1234567890/asdf\"'>'1234567890'\n\t\t\t\t'/1234567890/asdf'\n\t\t\t\t\t=@\n\t\t\t\t\t\t'.wh'\n\t\t\t\t\t\t\t'at' = '\"Hello world!\"'>'1234567890'\n\t\t\t\t\t\t\t'en' = '1234567890'>'1234567890'\n\t\t\t\t\t\t\t'o' = '#\"jessegibson\"'>'1234567890'\n\t\t'marknadal'\n\t\t\t=@\n\t\t\t\t'.'\n\t\t\t\t\t'last' = '#\"marknadal/says/1234567891/fdsa\"'>'1234567891'\n\t\t\t\t\t'says' = '#\"marknadal/says\"'>'1234567891'\n\t\t\t'/says'\n\t\t\t\t=@\n\t\t\t\t\t'.marknadal/says/123456789'\n\t\t\t\t\t\t'0/asdf' = '#\"marknadal/says/1234567890/asdf\"'>'1234567890'\n\t\t\t\t\t\t'1/fads' = '#\"marknadal/says/1234567891/fads\"'>'1234567891'\n\t\t\t\t'/123456789'\n\t\t\t\t\t'0/asdf'\n\t\t\t\t\t\t=@\n\t\t\t\t\t\t\t'.wh'\n\t\t\t\t\t\t\t\t'at' = '\"Hello world!\"'>'1234567890'\n\t\t\t\t\t\t\t\t'en' = '1234567890'>'1234567890'\n\t\t\t\t\t\t\t\t'o' = '#\"marknadal\"'>'1234567890'\n\t\t\t\t\t'1/fads'\n\t\t\t\t\t\t=@\n\t\t\t\t\t\t\t'.wh'\n\t\t\t\t\t\t\t\t'at' = '\"Hello universe!\"'>'1234567891'\n\t\t\t\t\t\t\t\t'en' = '1234567891'>'1234567891'\n\t\t\t\t\t\t\t\t'o' = '#\"marknadal\"'>'1234567891'"
  },
  {
    "path": "tsconfig.json",
    "content": "{\r\n  \"compilerOptions\": {\r\n    \"emitDeclarationOnly\": true,\r\n    \"declaration\": true,\r\n  },\r\n  \"include\": [\r\n    // only compile the type definitions by default.\r\n    // That is, ignore the files in 'examples/**'\r\n    \"**/*.d.ts\"\r\n  ],\r\n  \"exclude\": [\r\n    // Among the type definitions, don't try to compile\r\n    // the test file which implements bad types.\r\n    // It implements bad types for testing purposes.\r\n    \"**/*.test-d.ts\"\r\n  ]\r\n}\r\n"
  },
  {
    "path": "types/gun/GunCallbackGet.d.ts",
    "content": "import { GunDataNode, GunSchema, GunSoul } from '.';\nimport { GunSoul2Soul } from '../utils';\n\ntype GunMessageGet<\n  N extends GunSchema,\n  K extends (keyof N & string) | GunSoul2Soul<GunSoul<N>>,\n  V = K extends keyof N & string ? N[K] : N\n> = {\n  /** key */\n  get: K;\n  /** value */\n  put: GunDataNode<V extends GunSchema ? V : N>;\n};\n\nexport type GunCallbackGet<\n  N extends GunSchema,\n  K extends (keyof N & string) | GunSoul2Soul<GunSoul<N>>\n> = (ack: GunMessageGet<N, K>) => void;\n"
  },
  {
    "path": "types/gun/GunCallbackMap.d.ts",
    "content": "import { GunDataNode, GunSchema } from '.';\n\nexport type GunCallbackMap<\n  V extends N[K],\n  K extends keyof N & string,\n  N extends GunSchema\n> = (data: GunDataNode<V extends GunSchema ? V : never>, key: K) => any;\n"
  },
  {
    "path": "types/gun/GunCallbackOn.d.ts",
    "content": "import { GunDataNode, GunHookMessagePut, IGunOnEvent, GunSchema } from '.';\n\nexport type GunCallbackOn<V extends GunSchema, K extends string> = (\n  data: GunDataNode<V>,\n  key: K,\n  message: GunHookMessagePut,\n  event: IGunOnEvent\n) => void;\n"
  },
  {
    "path": "types/gun/GunCallbackOnce.d.ts",
    "content": "import { GunDataNode, GunSchema } from '.';\n\nexport type GunCallbackOnce<V extends GunSchema, K extends string> = (\n  data: GunDataNode<V>,\n  key: K\n) => void;\n"
  },
  {
    "path": "types/gun/GunCallbackPut.d.ts",
    "content": "export type GunMessagePut =\n  | {\n      /** if there was an error during save */\n      err: string;\n    }\n  | {\n      /** if there was a success message (none is required though) */\n      ok: { '': 1 };\n    };\n\nexport type GunCallbackPut = (ack: GunMessagePut) => void;\n"
  },
  {
    "path": "types/gun/GunDataNode.d.ts",
    "content": "import { GunSchema, GunSoul, IGunMeta } from '.';\n\nexport type GunDataNode<T extends GunSchema> = T extends GunSchema & object\n  ? {\n      [K in keyof T]: Exclude<\n        T[K],\n        string | number | boolean | null | undefined\n      > extends never\n        ? T[K]\n        :\n            | GunSoul<\n                Exclude<T[K], string | number | boolean | null | undefined>\n              >\n            | Exclude<T[K], object>;\n    } & IGunMeta<T>\n  : T;\n"
  },
  {
    "path": "types/gun/GunHookCallbackBye.d.ts",
    "content": "import { IGunHookContext, GunPeer } from '.';\n\nexport type GunHookCallbackBye = (\n  this: IGunHookContext<GunPeer>,\n  peer: GunPeer\n) => void;\n"
  },
  {
    "path": "types/gun/GunHookCallbackCreate.d.ts",
    "content": "import { IGunHookContext, _GunRoot } from '.';\n\nexport type GunHookCallbackCreate = (\n  this: IGunHookContext<_GunRoot>,\n  root: _GunRoot\n) => void;\n"
  },
  {
    "path": "types/gun/GunHookCallbackGet.d.ts",
    "content": "import { pany, IGunHookContext, GunNodeGet, _GunRoot } from '.';\n\ntype GunHookMessageGet<MessageExtension extends pany> = {\n  $: { _: _GunRoot };\n  '#': string;\n  get: GunNodeGet;\n} & Partial<MessageExtension>;\n\nexport type GunHookCallackGet<MessageExtension extends pany> = (\n  this: IGunHookContext<GunHookMessageGet<MessageExtension>>,\n  message: GunHookMessageGet<MessageExtension>\n) => void;\n"
  },
  {
    "path": "types/gun/GunHookCallbackHi.d.ts",
    "content": "import { IGunHookContext, GunPeer } from '.';\n\nexport type GunHookCallbackHi = (\n  this: IGunHookContext<GunPeer>,\n  peer: GunPeer\n) => void;\n"
  },
  {
    "path": "types/gun/GunHookCallbackIn.d.ts",
    "content": "import { pany, IGunHookContext, GunDataNode, GunNodeGet, _GunRoot } from '.';\n\nexport type GunHookMessageIn<\n  MessageExtension extends pany,\n  MetaExtension extends pany\n> = {\n  $: { _: _GunRoot };\n  '#': string;\n  get?: GunNodeGet;\n  put?: { [nodePath: string]: GunDataNode<pany> & { _: MetaExtension } };\n} & Partial<MessageExtension>;\n\nexport type GunHookCallbackIn<\n  MessageExtension extends pany,\n  MetaExtension extends pany\n> = (\n  this: IGunHookContext<GunHookMessageIn<MessageExtension, MetaExtension>>,\n  message: GunHookMessageIn<MessageExtension, MetaExtension>\n) => void;\n"
  },
  {
    "path": "types/gun/GunHookCallbackOpt.d.ts",
    "content": "import { IGunHookContext, _GunRoot } from '.';\n\nexport type GunHookCallbackOpt = (this: IGunHookContext<_GunRoot>, root: _GunRoot) => void;\n"
  },
  {
    "path": "types/gun/GunHookCallbackOut.d.ts",
    "content": "import { IGunHookContext, pany, GunDataNode, GunNodeGet, _GunRoot } from '.';\n\nexport type GunHookMessageOut<\n  MessageExtension extends pany,\n  MetaExtension extends pany\n> = {\n  $: { _: _GunRoot };\n  '#': string;\n  get?: GunNodeGet;\n  put?: { [nodePath: string]: GunDataNode<pany> & { _: MetaExtension } };\n} & Partial<MessageExtension>;\n\nexport type GunHookCallbackOut<\n  MessageExtension extends pany,\n  MetaExtension extends pany\n> = (\n  this: IGunHookContext<GunHookMessageOut<MessageExtension, MetaExtension>>,\n  message: GunHookMessageOut<MessageExtension, MetaExtension>\n) => void;\n"
  },
  {
    "path": "types/gun/GunHookCallbackPut.d.ts",
    "content": "import { GunNodePut, IGunHookContext, _GunRoot } from '.';\n\ntype GunHookMessagePut = {\n  $: { _: _GunRoot };\n  '#'?: string;\n  put: GunNodePut;\n};\n\nexport type GunHookCallbackPut = (\n  this: IGunHookContext<GunHookMessagePut>,\n  message: GunHookMessagePut\n) => void;\n"
  },
  {
    "path": "types/gun/GunNodeGet.d.ts",
    "content": "export type GunNodeGet = {\n  /** Node path */\n  '#': string;\n  /** Leaf name */\n  '.': string;\n};\n"
  },
  {
    "path": "types/gun/GunNodePut.d.ts",
    "content": "import { GunNodeGet, GunValueSimple } from '.';\n\nexport type GunNodePut = GunNodeGet & {\n  /** Leaf value */\n  ':': GunValueSimple;\n  /** Leaf timestamp */\n  '>': number;\n};\n"
  },
  {
    "path": "types/gun/GunOptions.d.ts",
    "content": "export type GunOptions =\n  | Partial<{\n      /** Undocumented but mentioned. Write data to a JSON. */\n      file: string;\n\n      /** Undocumented but mentioned. Create a websocket server */\n      web: any;\n\n      /** Undocumented but mentioned. Amazon S3 */\n      s3: {\n        key: string;\n        secret: string;\n        bucket: string;\n        region?: string;\n        fakes3?: any;\n      };\n\n      /** the URLs are properties, and the value is an empty object. */\n      peers: string[] | Record<string, {}>;\n\n      /** default: true, creates and persists local (nodejs) data using Radisk. */\n      radisk: boolean;\n\n      /** default: true, persists local (browser) data to localStorage. */\n      localStorage: boolean;\n\n      /** uuid allows you to override the default 24 random alphanumeric soul generator with your own function. */\n      uuid(): string;\n\n      /**\n       * allows you to pass options to a 3rd party module. Their project README will likely list the exposed options\n       * @see https://github.com/amark/gun/wiki/Modules\n       */\n      [key: string]: any;\n    }>\n  | string\n  | string[];\n"
  },
  {
    "path": "types/gun/GunOptionsOn.d.ts",
    "content": "export type GunOptionsOn = Partial<\n  | {\n      change: boolean;\n    }\n  | boolean\n>;\n"
  },
  {
    "path": "types/gun/GunOptionsOnce.d.ts",
    "content": "export type GunOptionsOnce = Partial<{\n  /**\n   * controls the asynchronous timing\n   */\n  wait: number;\n}>;\n"
  },
  {
    "path": "types/gun/GunOptionsPut.d.ts",
    "content": "export type GunOptionsPut = Partial<{\n  opt: {\n    /** certificate that gives other people write permission */ cert: string;\n  };\n}>;\n"
  },
  {
    "path": "types/gun/GunPeer.d.ts",
    "content": "export type GunPeer = {\n  id: string;\n  url: string;\n  queue: string[];\n  wire: null | WebSocket | RTCDataChannel;\n};\n"
  },
  {
    "path": "types/gun/GunSchema.d.ts",
    "content": "import { GunValueSimple, IGunChain, IGunInstanceRoot } from '.';\n\ninterface IGunSchema {\n  [key: string]:\n    | Exclude<\n        IGunSchema,\n        IGunChain<any, any, any, any> | IGunInstanceRoot<any, any>\n      >\n    | GunValueSimple;\n}\n\nexport type GunSchema =\n  | Exclude<\n      IGunSchema,\n      IGunChain<any, any, any, any> | IGunInstanceRoot<any, any>\n    >\n  | GunValueSimple;\n"
  },
  {
    "path": "types/gun/GunSoul.d.ts",
    "content": "import { GunSchema } from '.';\nexport type GunSoul<_N extends GunSchema, Soul extends string = string> = {\n  '#': Soul;\n};\n"
  },
  {
    "path": "types/gun/GunValueSimple.d.ts",
    "content": "export type GunValueSimple = string | number | boolean | null;\n"
  },
  {
    "path": "types/gun/IGun.d.ts",
    "content": "import {\n  GunOptions,\n  IGunInstance,\n  _GunRoot,\n  GunHookCallbackCreate,\n  GunHookCallbackOpt,\n  GunSchema,\n  IGunChain,\n} from '.';\n\nexport interface IGun {\n  <TNode extends Record<string, GunSchema> = any>(options?: GunOptions): IGunInstance<TNode>;\n  new <TNode extends Record<string, GunSchema> = any>(options?: GunOptions): IGunInstance<TNode>;\n\n  /**\n   * Returns GUN state timestamp\n   */\n  state(): number;\n\n  chain: IGunChain<any> & IGunInstance<any>;\n\n  /**\n   * Listener for a GUN instance creation\n   */\n  on(\n    event: 'create',\n    callback: GunHookCallbackCreate\n  ): void;\n\n  /**\n   * Listener for a GUN options update\n   */\n  on(\n    event: 'opt',\n    callback: GunHookCallbackOpt\n  ): void;\n}\n"
  },
  {
    "path": "types/gun/IGunChain.d.ts",
    "content": "import {\n  _GunRoot,\n  GunCallbackPut,\n  GunOptionsPut,\n  LEXQuery,\n  GunCallbackOn,\n  GunOptionsOn,\n  GunCallbackOnce,\n  GunOptionsOnce,\n  GunSchema,\n  GunDataNode,\n  GunCallbackGet,\n  IGunInstanceRoot,\n  GunSoul,\n  GunCallbackMap,\n} from '.';\nimport { IGunChain2TNode } from '../utils';\n\nexport interface IGunChain<\n  TNode extends GunSchema,\n  TChainParent extends\n    | IGunChain<any, any, any, any>\n    | IGunInstanceRoot<any, any> = any,\n  TGunInstance extends IGunInstanceRoot<any, any> = any,\n  TKey extends string = any\n> {\n  _: _GunRoot;\n\n  /**\n   * Save data into gun, syncing it with your connected peers\n   *\n   * @param value the data to save\n   * @param callback an optional callback, invoked on each acknowledgment\n   * @param options `put` options\n   */\n  put<\n    V extends\n      | (TNode extends object ? Partial<TNode> : TNode)\n      | GunSoul<TNode>\n      | IGunChain<TNode, any, any, any>\n      | IGunChain<NonNullable<TNode>, any, any, any>\n  >(\n    value: V,\n    callback?: GunCallbackPut,\n    options?: GunOptionsPut\n  ): IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n\n  /**\n   * Where to read data from\n   *\n   * @param key The key is the ID or property name of the data that you saved from\n   *  earlier (or that will be saved later)\n   * @param callback The callback is a listener for read errors, not found, and updates.\n   *  It may be called multiple times for a single request, since gun uses a reactive\n   *  streaming architecture. Generally, you'll find `.not`, `.on`, and `.once` as more\n   *  convenient for every day use\n   */\n  get<V extends N[K], K extends keyof N & string, N extends TNode>(\n    key: K,\n    callback?: GunCallbackGet<N, K>\n  ): V extends GunSchema\n    ? IGunChain<\n        V,\n        IGunChain<N, TChainParent, TGunInstance, TKey>,\n        TGunInstance,\n        K\n      >\n    : never;\n\n  /**\n   * Where to read data from\n   *\n   * @param query LEX query\n   * @param callback The callback is a listener for read errors, not found, and updates.\n   *  It may be called multiple times for a single request, since gun uses a reactive\n   *  streaming architecture. Generally, you'll find `.not`, `.on`, and `.once` as more\n   *  convenient for every day use\n   */\n  get<\n    V extends N[K],\n    K extends keyof TNode & string = keyof TNode & string,\n    N extends TNode = TNode\n  >(\n    query: LEXQuery<K>,\n    callback?: GunCallbackGet<N, TKey>\n  ): Record<K, V> extends GunSchema\n    ? IGunChain<Record<K, V>, TChainParent, TGunInstance, TKey>\n    : never;\n\n  /**\n   * Add a unique item to an unordered list. Works like a mathematical set, where each\n   *  item in the list is unique. If the item is added twice, it will be merged. This\n   *  means only objects, for now, are supported\n   *\n   * @param value the data to save\n   * @param callback the callback is invoked exactly the same as `.put`, since `.set` is\n   *  just a convenience wrapper around `.put`\n   */\n  set<\n    V extends Partial<N> | GunSoul<N> | IGunChain<N, any, any, any>,\n    K extends keyof TNode & string,\n    N extends TNode[K] & Record<string, GunSchema>\n  >(\n    value: V,\n    callback?: GunCallbackPut\n  ): V extends GunSchema\n    ? IGunChain<\n        N,\n        IGunChain<TNode, TChainParent, TGunInstance, TKey>,\n        TGunInstance,\n        K\n      >\n    : IGunChain<\n        IGunChain2TNode<V>,\n        IGunChain<TNode, TChainParent, TGunInstance, TKey>,\n        TGunInstance,\n        K\n      >;\n\n  /**\n   * Move up to the parent context on the chain. Every time a new chain is created, a\n   *  reference to the old context is kept to go back to\n   *\n   * @param amount The number of times you want to go back up the chain. `-1` will take you\n   *  to the root. `Infinity` is not yet supported in TypeScript\n   */\n  back<GI extends TGunInstance>(amount: -1): GI;\n  back<CP extends TChainParent>(): CP;\n  back<N extends GunSchema>(): IGunChain<N, any, TGunInstance, string>;\n  back<N extends GunSchema>(\n    amount: number\n  ): IGunChain<N, any, TGunInstance, string>;\n\n  /**\n   * Subscribe to updates and changes on a node or property in realtime\n   *\n   * @param callback Once initially and whenever the property or node you're focused on\n   *  changes, this callback is immediately fired with the data as it is at that point in\n   *  time. Once initially and whenever the property or node you're focused on changes,\n   *  this callback is immediately fired with the data as it is at that point in time\n   * @param options currently, the only option is to filter out old data, and just be\n   *  given the changes. If you're listening to a node with 100 fields, and just one\n   *  changes, you'll instead be passed a node with a single property representing that\n   *  change rather than the full node every time\n   */\n  on<V extends TNode>(\n    callback?: GunCallbackOn<V, TKey>,\n    options?: GunOptionsOn\n  ): IGunChain<V, TChainParent, TGunInstance, TKey>;\n\n  /**\n   * Removes all listeners\n   */\n  off(): IGunChain<TNode, TChainParent, TGunInstance, TKey>;\n\n  /**\n   * Get the current data without subscribing to updates. Or undefined if it cannot be\n   *  found\n   *\n   * `.once` is synchronous and immediate (at extremely high performance) if the data has\n   *  already been loaded.\n   *\n   * `.once` is asynchronous and on a debounce timeout while data is still being loaded\n   *  - so it may be called completely out of order compared to other functions. This is\n   *  intended because gun streams partials of data, so once avoids firing immediately\n   *  because it may not represent the \"complete\" data set yet. You can control this\n   *  timeout with the wait option\n   *\n   * `.once` fires again if you update that node from within it\n   *\n   * @param callback The data is the value for that chain at that given point in time.\n   *  And the key is the last property name or ID of the node\n   * @param options `once` options\n   */\n  once<V extends TNode>(\n    callback?: GunCallbackOnce<V, TKey>,\n    options?: GunOptionsOnce\n  ): IGunChain<V, TChainParent, TGunInstance, TKey>;\n\n  /**\n   * Iterates over each property and item on a node, passing it down the chain, behaving\n   *  like a forEach on your data. It also subscribes to every item as well and listens\n   *  for newly inserted items. It accepts one argument:\n   * - a `callback` function that transforms the data as it passes through. If the data is\n   *  transformed to undefined it gets filtered out of the chain\n   * - the `callback` gets two arguments (value, key) and will be called once for each\n   *  key value pair in the objects that are returned from map\n   *\n   * If your data is cyclic and has a lot of self-references, you may receive multiple\n   *  callbacks with the same result. For example: \"Alice is both the president of the\n   *  company, the wife of Bob, and the friend to the cat.\" This would return 3 times:\n   * ```\n   *  key: president value: alice,\n   *  key: wife value: alice,\n   *  key: friend value: alice\n   * ```\n   *\n   * Here's a summary of .map() behavior depending on where it is on the chain:\n   * - `users.map().on(cb)` subscribes to changes on every user and to users as they are\n   *  added.\n   * - `users.map().once(cb)` gets each user once, including ones that are added over\n   *  time.\n   * - `users.once().map().on(cb)` gets the user list once, but subscribes to changes on\n   *  each of those users (not added ones).\n   * - `users.once().map().once(cb)` gets the user list once, gets each of those users\n   *  only once (not added ones).\n   */\n  map<V extends N[K], K extends keyof N & string, N extends TNode>(\n    callback?: GunCallbackMap<V, K, N>\n  ): V extends GunSchema\n    ? IGunChain<\n        V,\n        IGunChain<TNode, TChainParent, TGunInstance, TKey>,\n        TGunInstance,\n        K\n      >\n    : never;\n}\n"
  },
  {
    "path": "types/gun/IGunHookContext.d.ts",
    "content": "export interface IGunHookContext<T> {\n  off: () => void;\n  to: {\n    next: (subject: T) => void;\n  };\n}\n"
  },
  {
    "path": "types/gun/IGunInstance.d.ts",
    "content": "import { IGunInstanceRoot, GunSchema } from '.';\n\nexport interface IGunInstance<TNode extends Record<string, GunSchema> = any>\n  extends IGunInstanceRoot<TNode, IGunInstance<TNode>> {}\n"
  },
  {
    "path": "types/gun/IGunInstanceHookHandler.d.ts",
    "content": "import {\n  GunHookCallbackCreate,\n  GunHookCallbackPut,\n  pany,\n  GunHookCallackGet,\n  GunHookCallbackOut,\n  GunHookCallbackIn,\n  GunHookCallbackBye,\n  IGunHookContext,\n} from '.';\n\nexport interface IGunInstanceHookHandler {\n  /**\n   * Listener for the GUN instance creation\n   */\n  on(event: 'create', callback: GunHookCallbackCreate): void;\n\n  /**\n   * Listener for the GUN `put` event\n   */\n  on(event: 'put', callback: GunHookCallbackPut): void;\n\n  /**\n   * Listener for the GUN `get` event\n   *\n   * @template MessageExtension extension properties for message\n   */\n  on<MessageExtension extends pany = pany>(\n    event: 'get',\n    callback: GunHookCallackGet<MessageExtension>\n  ): void;\n\n  /**\n   * Listener for the GUN `out` event\n   *\n   * > NEVER PASS ARROW FUNCTIONS AS A CALLBACK OR YOU LOSE `this` CONTEXT!\n   *\n   * > NEVER FORGET TO CALL `this.to.next(message);` IF YOU WANT YOUR MESSAGE TO PASS\n   *\n   * @template MessageExtension extension properties for message\n   * @template MetaExtension extension properties for meta data\n   */\n  on<MessageExtension extends pany = pany, MetaExtension extends pany = pany>(\n    event: 'out',\n    callback: GunHookCallbackOut<MessageExtension, MetaExtension>\n  ): void;\n\n  /**\n   * Listener for the GUN `in` event\n   *\n   * @template MessageExtension extension properties for message\n   * @template MetaExtension extension properties for meta data\n   */\n  on<MessageExtension extends pany = pany, MetaExtension extends pany = pany>(\n    event: 'in',\n    callback: GunHookCallbackIn<MessageExtension, MetaExtension>\n  ): void;\n\n  /**\n   * Listener for new peers\n   */\n  on(\n    event: 'hi',\n    callback: (this: IGunHookContext<any>, peer: any) => void\n  ): void;\n\n  /**\n   * Listener for leaving peers\n   */\n  on(event: 'bye', callback: GunHookCallbackBye): void;\n}\n"
  },
  {
    "path": "types/gun/IGunInstanceRoot.d.ts",
    "content": "import {\n  _GunRoot,\n  GunCallbackPut,\n  GunOptionsPut,\n  IGunChain,\n  LEXQuery,\n  GunOptions,\n  IGunInstanceHookHandler,\n  GunSchema,\n  GunCallbackGet,\n  GunSoul,\n} from '.';\nimport { GunSoul2Soul, GunSoul2TNode } from '../utils';\n\nexport interface IGunInstanceRoot<\n  TNode extends Record<string, GunSchema>,\n  TGunInstance extends IGunInstanceRoot<TNode, any>\n> extends IGunInstanceHookHandler {\n  _: _GunRoot;\n\n  /**\n   * Save data into gun, syncing it with your connected peers\n   *\n   * @param value the data to save\n   * @param callback an optional callback, invoked on each acknowledgment\n   * @param options `put` options\n   * @param options.cert certificate that gives other people write permission\n   */\n  put<V extends Partial<TNode> & Record<string, GunSchema>>(\n    value: V,\n    callback?: GunCallbackPut,\n    options?: GunOptionsPut\n  ): TGunInstance;\n\n  /**\n   * Where to read data from\n   *\n   * @param soul The soul of an object that you saved from earlier\n   * @param callback The callback is a listener for read errors, not found, and updates.\n   *  It may be called multiple times for a single request, since gun uses a reactive\n   *  streaming architecture. Generally, you'll find `.not`, `.on`, and `.once` as more\n   *  convenient for every day use\n   */\n  get<\n    V extends GunSoul2TNode<S>,\n    S extends GunSoul<GunSchema>,\n    N extends TNode\n  >(\n    soul: S,\n    callback?: GunCallbackGet<N, GunSoul2Soul<S>>\n  ): IGunChain<V, TGunInstance, TGunInstance, GunSoul2Soul<S>>;\n\n  /**\n   * Where to read data from\n   *\n   * @param key The key is the ID or property name of the data that you saved from\n   *  earlier (or that will be saved later)\n   * @param callback The callback is a listener for read errors, not found, and updates.\n   *  It may be called multiple times for a single request, since gun uses a reactive\n   *  streaming architecture. Generally, you'll find `.not`, `.on`, and `.once` as more\n   *  convenient for every day use\n   */\n  get<\n    V extends N[K],\n    K extends keyof N & string = keyof TNode & string,\n    N extends TNode = TNode\n  >(\n    key: K,\n    callback?: GunCallbackGet<N, K>\n  ): IGunChain<V, TGunInstance, TGunInstance, K>;\n\n  /**\n   * Where to read data from\n   *\n   * @param query LEX query\n   * @param callback The callback is a listener for read errors, not found, and updates.\n   *  It may be called multiple times for a single request, since gun uses a reactive\n   *  streaming architecture. Generally, you'll find `.not`, `.on`, and `.once` as more\n   *  convenient for every day use\n   */\n  get<V extends N[K], K extends keyof N & string, N extends TNode = TNode>(\n    query: LEXQuery<K>,\n    callback?: GunCallbackGet<N, K>\n  ): IGunChain<V, TGunInstance, TGunInstance, K>;\n\n  /**\n   * Change the configuration of the gun database instance\n   *\n   * @param options The options argument is the same object you pass to the constructor.\n   *  The options's properties replace those in the instance's configuration but\n   *  `options.peers` are added to peers known to the gun instance\n   */\n  opt(options: GunOptions): void;\n}\n"
  },
  {
    "path": "types/gun/IGunMeta.d.ts",
    "content": "export interface IGunMeta<T extends object> {\n  _: {\n    '#': string;\n    '>': {\n      [key in keyof T]: number;\n    };\n  };\n}\n"
  },
  {
    "path": "types/gun/IGunOnEvent.d.ts",
    "content": "export interface IGunOnEvent {\n  off(): void;\n}\n"
  },
  {
    "path": "types/gun/LEX.d.ts",
    "content": "export type LEX<T extends string = string> = {\n  /** exact match */\n  '='?: T;\n  /** prefix match */\n  '*'?: string;\n  /** gte match */\n  '>'?: string;\n  /** lte match */\n  '<'?: string;\n  /** 1 for reverse */\n  '-'?: number;\n};\n"
  },
  {
    "path": "types/gun/LEXQuery.d.ts",
    "content": "import { LEX } from '.';\n\nexport type LEXQuery<T extends string = string> = { '.': LEX<T>; ':'?: number };\n"
  },
  {
    "path": "types/gun/_GunRoot.d.ts",
    "content": "import { GunOptions, IGunInstanceHookHandler } from '.';\n\nexport interface _GunRoot extends IGunInstanceHookHandler {\n  $: { _: _GunRoot };\n\n  /**\n   * Current GUN options\n   */\n  opt: GunOptions;\n}\n"
  },
  {
    "path": "types/gun/index.d.ts",
    "content": "export * from './_GunRoot';\nexport * from './GunCallbackGet';\nexport * from './GunCallbackMap';\nexport * from './GunCallbackOn';\nexport * from './GunCallbackOnce';\nexport * from './GunCallbackPut';\nexport * from './GunDataNode';\nexport * from './GunHookCallbackBye';\nexport * from './GunHookCallbackCreate';\nexport * from './GunHookCallbackGet';\nexport * from './GunHookCallbackHi';\nexport * from './GunHookCallbackIn';\nexport * from './GunHookCallbackOpt';\nexport * from './GunHookCallbackOut';\nexport * from './GunHookCallbackPut';\nexport * from './GunNodeGet';\nexport * from './GunNodePut';\nexport * from './GunOptions';\nexport * from './GunOptionsOn';\nexport * from './GunOptionsOnce';\nexport * from './GunOptionsPut';\nexport * from './GunPeer';\nexport * from './GunSoul';\nexport * from './GunValueSimple';\nexport * from './IGun';\nexport * from './IGunChain';\nexport * from './IGunHookContext';\nexport * from './IGunInstance';\nexport * from './IGunInstanceHookHandler';\nexport * from './IGunInstanceRoot';\nexport * from './IGunMeta';\nexport * from './IGunOnEvent';\nexport * from './GunSchema';\nexport * from './LEX';\nexport * from './LEXQuery';\nexport * from './pany';\n"
  },
  {
    "path": "types/gun/pany.d.ts",
    "content": "export type pany = Partial<any>;\n"
  },
  {
    "path": "types/index.d.ts",
    "content": "export * from './gun';\nexport * from './sea';\n"
  },
  {
    "path": "types/sea/GunCallbackUserAuth.d.ts",
    "content": "import { GunUser, ISEAPair } from '..';\n\nexport type GunCallbackUserAuth = (\n  ack:\n    | {\n        ack: 2;\n        /** ~publicKeyOfUser */\n        soul: string;\n        /** ~publicKeyOfUser */\n        get: string;\n        put: GunUser;\n        sea: ISEAPair;\n      }\n    | { err: string }\n) => void;\n"
  },
  {
    "path": "types/sea/GunCallbackUserCreate.d.ts",
    "content": "export type GunCallbackUserCreate = (\n  ack: { ok: 0; pub: string } | { err: string }\n) => void;\n"
  },
  {
    "path": "types/sea/GunHookCallbackAuth.d.ts",
    "content": "import { GunHookMessagePut, GunUser, IGunOnEvent } from '..';\n\nexport type GunHookCallbackAuth = (\n  user: GunUser,\n  message: GunHookMessagePut,\n  event: IGunOnEvent\n) => void;\n"
  },
  {
    "path": "types/sea/GunUser.d.ts",
    "content": "export type GunUser = {\n  /** Username or Alias which can be used to find a user */\n  alias: string;\n  // auth: string;\n  /** public key for encryption */\n  epub: string;\n  /** public key */\n  pub: string;\n};\n"
  },
  {
    "path": "types/sea/IGun.d.ts",
    "content": "import { ISEA } from '.';\n\nimport {} from '../gun/IGun';\ndeclare module '../gun/IGun' {\n  export interface IGun {\n    SEA: ISEA;\n  }\n}\n"
  },
  {
    "path": "types/sea/IGunInstance.d.ts",
    "content": "import { IGunInstanceRoot, GunSchema, IGunUserInstance } from '..';\n\nimport {} from '../gun/IGunInstance';\ndeclare module '../gun/IGunInstance' {\n  export interface IGunInstance<TNode> {\n    user<\n      UNode extends Record<string, GunSchema> = any,\n      UNodeInstance extends IGunUserInstance<\n        UNode,\n        UNodeInstance,\n        TNode,\n        IGunInstanceRoot<TNode, IGunInstance<TNode>>\n      > = any\n    >(): IGunUserInstance<UNode, UNodeInstance, TNode, IGunInstanceRoot<TNode, IGunInstance<TNode>>>;\n    user<\n      UNode extends Record<string, GunSchema> = any,\n      UNodeInstance extends IGunUserInstance<\n        UNode,\n        UNodeInstance,\n        TNode,\n        IGunInstanceRoot<TNode, IGunInstance<TNode>>\n      > = any\n    >(\n      publicKey: string\n    ): IGunUserInstance<UNode, UNodeInstance, TNode, IGunInstanceRoot<TNode, IGunInstance<TNode>>>;\n  }\n}\n"
  },
  {
    "path": "types/sea/IGunInstanceHookHandler.d.ts",
    "content": "import { GunHookCallbackAuth } from '..';\n\nimport {} from '../gun/IGunInstanceHookHandler';\ndeclare module '../gun/IGunInstanceHookHandler' {\n  export interface IGunInstanceHookHandler {\n    /** Called upon successful user authentication */\n    on(event: 'auth', callback: GunHookCallbackAuth): void;\n  }\n}\n"
  },
  {
    "path": "types/sea/IGunInstanceRoot.d.ts",
    "content": "import { GunSchema, IGunUserInstance } from '..';\n\nimport {} from '../gun/IGunInstanceRoot';\ndeclare module '../gun/IGunInstanceRoot' {\n  export interface IGunInstanceRoot<TNode, TGunInstance> {\n    user<\n      UNode extends Record<string, GunSchema> = any,\n      UNodeInstance extends IGunUserInstance<\n        UNode,\n        UNodeInstance,\n        TNode,\n        TGunInstance\n      > = any\n    >(): IGunUserInstance<UNode, UNodeInstance, TNode, TGunInstance>;\n    user<\n      UNode extends Record<string, GunSchema> = any,\n      UNodeInstance extends IGunUserInstance<\n        UNode,\n        UNodeInstance,\n        TNode,\n        TGunInstance\n      > = any\n    >(\n      publicKey: string\n    ): IGunUserInstance<UNode, UNodeInstance, TNode, TGunInstance>;\n  }\n}\n"
  },
  {
    "path": "types/sea/IGunUserInstance.d.ts",
    "content": "import {\n  GunCallbackUserAuth,\n  GunCallbackUserCreate,\n  OptionsUserAuth,\n  ISEAPair,\n  OptionsUserRecall,\n  IGunInstanceRoot,\n  GunSchema,\n} from '..';\nimport { IGunInstanceRoot2TGunInstance } from '../utils';\n\nexport interface IGunUserInstance<\n  UNode extends Record<string, GunSchema> = any,\n  UNodeInstance extends IGunUserInstance<\n    UNode,\n    UNodeInstance,\n    TNode,\n    TNodeInstanceRoot\n  > = any,\n  TNode extends Record<string, GunSchema> = any,\n  TNodeInstanceRoot extends IGunInstanceRoot<TNode, any> = any\n> extends IGunInstanceRoot<UNode, UNodeInstance> {\n  /** Creates a new user and calls callback upon completion\n   * @param alias Username or Alias which can be used to find a user\n   * @param password Passphrase that will be extended with PBKDF2\n   *  to make it a secure way to login\n   * @param callback that is to be called upon creation of the user\n   */\n  create(\n    alias: string,\n    password: string,\n    callback: GunCallbackUserCreate\n  ): UNodeInstance;\n\n  /** Authenticates a user, previously created via User.create\n   * @param pair Object containing the key pair of the user\n   * @param callback that is to be called upon authentication of the user\n   * @param options Options for authentication\n   */\n  auth(\n    pair: ISEAPair,\n    callback?: GunCallbackUserAuth,\n    options?: OptionsUserAuth\n  ): UNodeInstance;\n  /** Authenticates a user, previously created via User.create\n   * @param alias Username or Alias which can be used to find a user\n   * @param password Passphrase for the user\n   * @param callback that is to be called upon authentication of the user\n   * @param options Options for authentication\n   */\n  auth(\n    alias: string,\n    password: string,\n    callback?: GunCallbackUserAuth,\n    options?: OptionsUserAuth\n  ): UNodeInstance;\n\n  /** To check if you are currently logged in */\n  is?: {\n    alias: string | ISEAPair;\n    /** public key for encryption */\n    epub: string;\n    /** public key */\n    pub: string;\n  };\n\n  /** Log out currently authenticated user\n   * @returns A reference to the gun root chain\n   */\n  leave(): IGunInstanceRoot2TGunInstance<TNodeInstanceRoot>;\n\n  /**\n   * Saves a users credentials in sessionStorage of the browser.\n   * As long as the tab of your app is not closed the user stays\n   * logged in, even through page refreshes and reloads */\n  recall(\n    options: OptionsUserRecall,\n    callback?: GunCallbackUserAuth\n  ): UNodeInstance;\n}\n"
  },
  {
    "path": "types/sea/IPolicy.d.ts",
    "content": "import { LEX } from '..';\n\nexport interface IPolicy extends LEX {\n  /** Path */\n  '#'?: LEX;\n  /** Key */\n  '.'?: LEX;\n  /**\n   * Either Path string or Key string must\n   * contain Certificate's Pub string\n   */\n  '+'?: '*';\n}\n"
  },
  {
    "path": "types/sea/ISEA.d.ts",
    "content": "import { ISEAPair, Policy } from '.';\n\n/**\n * Security, Encryption, and Authorization system used with GUN\n */\nexport interface ISEA {\n  /** Last known error */\n  err?: string;\n\n  /**\n   * This gives you a Proof of Work (POW) / Hashing of Data\n   *\n   * @param data The data to be hashed, work to be performed on\n   * @param pair (salt) You can pass pair of keys to use as salt.\n   *  Salt will prevent others to pre-compute the work, so using\n   *  your public key is not a good idea. If it is not specified, it\n   *  will be random, which ruins your chance of ever being able to\n   *  re-derive the work deterministically\n   * @param callback function to executed upon execution of proof\n   * @param options default: `{ name: 'PBKDF2', encode: 'base64' }`\n   * @returns a promise with a string - hash of data if successful,\n   *  otherwise - undefined\n   */\n  work(\n    data: any,\n    pair?: ISEAPair | null,\n    callback?: ((data: string | undefined) => void) | null,\n    options?: {\n      name?: 'SHA-256' | 'PBKDF2';\n      encode?: 'base64' | 'utf8' | 'hex';\n      salt?: any;\n      hash?: string;\n      length?: number;\n    }\n  ): Promise<string | undefined>;\n\n  /**\n   * This generates a cryptographically secure public/private key pair - be careful not to leak the private keys!\n   * Note: API subject to change we may change the parameters to accept data and work, in addition to generation.\n   * You will need this for most of SEA's API, see those method's examples.\n   * The default cryptographic primitives for the asymmetric keys are ECDSA for signing and ECDH for encryption.\n   */\n  pair(callback?: (data: ISEAPair) => void): Promise<ISEAPair>;\n\n  /**\n   * Adds a signature to a message, for data that you want to\n   *  prevent attackers tampering with. The default\n   *  cryptographic primitive signs a SHA256 fingerprint of the\n   *  data\n   *\n   * @param data the content that you want to prove is authorized\n   * @param pair SEA pair\n   */\n  sign(data: any, pair: { priv: string; pub: string }): Promise<string>;\n\n  /**\n   * Do you want to allow others to write to parts of your own\n   *  organization's graph without sharing your keypair with\n   *  them? Then this feature is for you! With SEA.certify, you\n   *  can create a cryptographically signed Certificate that\n   *  gives other people write permission. A Certificate\n   *  describes WHO has the right to write to your graph, WHERE\n   *  they can write, and (pending security review) until WHEN.\n   *  The Certificate should not be encrypted because it must be\n   *  plain text so that it is interpretable by any and every\n   *  peer and machine in the network, so every peer enforces\n   *  the same security rules, whether it is a browser, phone,\n   *  IoT device, or relay\n   *\n   * @see https://gun.eco/docs/SEA.certify\n   *\n   * @param who Who the certificate is for. These are the people you allow to\n   *  write to your own graph\n   * @param policy The rules of the Certificate\n   * @param authority Certificate Authority or Certificate Issuer.\n   *  This is your priv, or your key pair\n   * @param callback A callback function that runs after a\n   *  Certificate is created\n   */\n  certify(\n    who: '*' | string | string[] | { pub: string } | { pub: string }[],\n    policy: Policy,\n    authority: { priv: string; pub: string },\n    callback?: () => void,\n    options?: {\n      /**\n       * A timestamp (ie. `Date.now() + 10000` or `Gun.state() + 10000`)\n       * to set the Certificate to expire in the future\n       *\n       * If `options.expiry` IS NOT SET, the Certificate is valid PERMANENTLY, and this is\n       *  dangerous!\n       */\n      expiry: number;\n    }\n  ): Promise<string>;\n\n  /**\n   * Gets the data if and only if the message can be verified\n   *  as coming from the person you expect\n   *\n   * @param message what comes from `.sign`\n   * @param pair from `.pair` or its public key text (`pair.pub`)\n   * @returns the data if and only if the message can be\n   *  verified as coming from the person you expect\n   */\n  verify<T extends unknown = any>(\n    message: string,\n    pair: string | { pub: string } | string\n  ): Promise<T>;\n\n  /**\n   * Takes some data that you want to keep secret and encrypts\n   *  it so nobody else can read it\n   *\n   * @param data the content that you want to encrypt\n   * @param pair from `.pair` to use as a cypher to encrypt with\n   */\n  encrypt(data: any, pair: { epriv: string }): Promise<string>;\n\n  /**\n   * Takes some data that you want to keep secret and encrypts\n   *  it so nobody else can read it\n   *\n   * @param data the content that you want to encrypt\n   * @param passphrase the passphrase you want to use as a cypher to encrypt with\n   */\n  encrypt(data: any, passphrase: string): Promise<string>;\n\n  /**\n   * Read the secret data, if and only if you are allowed to\n   *\n   * @param message what comes from `.encrypt`\n   * @param pair from `.pair` to decypher the message\n   */\n  decrypt<T extends unknown = any>(\n    message: string,\n    pair: { epriv: string }\n  ): Promise<T>;\n\n  /**\n   * Read the secret data, if and only if you are allowed to\n   *\n   * @param message what comes from `.encrypt`\n   * @param passphrase the passphrase to decypher the message\n   */\n  decrypt<T extends unknown = any>(\n    message: string,\n    passphrase: string\n  ): Promise<T>;\n\n  /**\n   * Derive shared secret from other's pub and my epub/epriv\n   *\n   * @param key other's public encryption key\n   * @param pair encryption key pair from `.pair`\n   * @param callback A callback function that runs after a secret is created\n   */\n  secret(\n    key: string | { epub: string },\n    pair: { epriv: string; epub: string },\n    callback?: (secret: string | undefined) => void\n  ): Promise<string | undefined>;\n}\n"
  },
  {
    "path": "types/sea/ISEAPair.d.ts",
    "content": "export interface ISEAPair {\n  /** private key for encryption */\n  epriv: string;\n  /** public key for encryption */\n  epub: string;\n  /** private key */\n  priv: string;\n  /** public key */\n  pub: string;\n}\n"
  },
  {
    "path": "types/sea/OptionsUserAuth.d.ts",
    "content": "export type OptionsUserAuth = { change: string };\n"
  },
  {
    "path": "types/sea/OptionsUserRecall.d.ts",
    "content": "export type OptionsUserRecall = { sessionStorage: boolean };\n"
  },
  {
    "path": "types/sea/Policy.d.ts",
    "content": "import { IPolicy } from '.';\n\nexport type Policy = string | IPolicy | (string | IPolicy)[];\n"
  },
  {
    "path": "types/sea/index.d.ts",
    "content": "export * from './GunCallbackUserAuth';\nexport * from './GunCallbackUserCreate';\nexport * from './GunHookCallbackAuth';\nexport * from './GunUser';\nexport * from './IGun';\nexport * from './IGunInstance';\nexport * from './IGunInstanceHookHandler';\nexport * from './IGunUserInstance';\nexport * from './IPolicy';\nexport * from './ISEA';\nexport * from './ISEAPair';\nexport * from './OptionsUserAuth';\nexport * from './OptionsUserRecall';\nexport * from './Policy';\n"
  },
  {
    "path": "types/test/gun-back.test-d.ts",
    "content": "import Gun from '../..';\n\nnew Gun<{ a: { b: number; c: number } }>()\n  .get('a')\n  .get('b')\n  .back()\n  .get('c')\n  .once((c) => c.toFixed(2));\n\nnew Gun()\n  .get<{ b: number; c: number }>('a')\n  .get('b')\n  .back()\n  .get('c')\n  .once((c) => c.toFixed(2));\n\nnew Gun()\n  .get('a')\n  .back<{ a: number; b: number }>()\n  .get('b')\n  .once((b) => b.toFixed(2));\n\nnew Gun()\n  .get('a')\n  .get('b')\n  .back<{ a: number; c: number }>(-2)\n  .get('c')\n  .once((c) => c.toFixed(2));\n"
  },
  {
    "path": "types/test/gun-get.test-d.ts",
    "content": "import Gun from '../..';\n\nnew Gun<{ a: { b: number; c: number } }>().get('a').get('b');\n\nnew Gun().get<{ b: number; c: number }>('a').get('b');\n"
  },
  {
    "path": "types/test/gun-instance.test-d.ts",
    "content": "import Gun from '../..';\n\nnew Gun();\nnew Gun(['http://server1.com/gun', 'http://server2.com/gun']);\nnew Gun({\n  s3: {\n    key: '',\n    secret: '',\n    bucket: '',\n  },\n  file: 'file/path.json',\n  uuid() {\n    return 'xxxxxx';\n  },\n});\n"
  },
  {
    "path": "types/test/gun-map.test-d.ts",
    "content": "import Gun from '../..';\n\nnew Gun<{ users: Record<string, { name: string }> }>()\n  .get('users')\n  .on()\n  .map((user) => (user.name === 'Mark' ? user : undefined));\n\nnew Gun()\n  .get<Record<string, { name: string }>>('users')\n  .map((user) => (user.name === 'Mark' ? user : undefined))\n  .once((user) => console.log(user.name));\n"
  },
  {
    "path": "types/test/gun-on.test-d.ts",
    "content": "import Gun from '../..';\n\ntype TOnlinable = { online: boolean };\n\nconst gun = new Gun<{\n  users: Record<string, TOnlinable>;\n  foo: TOnlinable;\n  home: { lights: TOnlinable };\n}>();\n\nvar listenerHandler = (_value, _key, _msg, _ev) => {};\n\n// add listener to foo\ngun.get('foo').on(listenerHandler, true);\n\n// remove listener to foo\ngun.get('foo').off();\n\ngun\n  .get('users')\n  .get('username')\n  .on(function (user) {\n    // update in real-time\n    if (user.online) {\n    } else {\n    }\n  });\n\ngun.get('home').get('lights').on(listenerHandler, true);\n\nnew Gun()\n  .get('home')\n  .get('lights')\n  .on<TOnlinable>(function (user) {\n    // update in real-time\n    if (user.online) {\n    } else {\n    }\n  });\n"
  },
  {
    "path": "types/test/gun-once.test-d.ts",
    "content": "import Gun from '../..';\n\nconst gun = new Gun<{\n  peer: { userID: { profile: {} } };\n  IoT: { temperature: number };\n  something: string;\n}>();\n\nlet view: any;\n\ngun\n  .get('peer')\n  .get('userID')\n  .get('profile')\n  .once(function (profile) {\n    // render it, but only once. No updates.\n    view.show.user(profile);\n  });\n\ngun\n  .get('IoT')\n  .get('temperature')\n  .once(function (number) {\n    view.show.temp(number);\n  });\n\ngun.get('something').once(function (_data, _key) {\n  gun.put({ something: 'something' });\n  gun.get('something').put('something');\n});\n\nnew Gun().get('something').once<string>(function (data, _key) {\n  gun.put({ something: data });\n  gun.get('something').put(data);\n});\n"
  },
  {
    "path": "types/test/gun-opt.test-d.ts",
    "content": "import Gun from '../..';\n\nnew Gun().opt({\n  uuid: function () {\n    return Math.floor(Math.random() * 4294967296).toString();\n  },\n});\n"
  },
  {
    "path": "types/test/gun-put.test-d.ts",
    "content": "//import { expectError } from 'tsd';\n\nimport Gun from '../..';\n\n//Documentation should work\n\ntype User = { name: string };\n\nconst gun = new Gun<{ user: User; user2: User }>();\ngun.get('user').put({ name: '' });\ngun.get('user').get('name').put(gun.get('user').get('name'));\ngun.get('user2').put(gun.get('user'));\n"
  },
  {
    "path": "types/test/gun-set.test-d.ts",
    "content": "import Gun from '../..';\n\ntype User = { name: string };\n\nconst gun = new Gun<{ users: Record<string, User>; alice: User }>();\nconst user = gun.get('alice').put({ name: 'Alice' });\ngun.get('users').set({ name: 'Bob' });\ngun.get('users').set(user).get('name').put('Sally');\n"
  },
  {
    "path": "types/test/gun-user-auth.test-d.ts",
    "content": "import Gun from '../..';\n\n//Documentation should work\n\nconst gun = new Gun();\ngun.on('auth', (_data) => {});\n\ngun.user().auth('a', 'b');\nasync () => gun.user().auth(await Gun.SEA.pair());\n"
  },
  {
    "path": "types/test/gun-user-leave.test-d.ts",
    "content": "import Gun from '../..';\n\n//Documentation should work\n\nconst gun = new Gun();\n\ngun.user().leave();\n"
  },
  {
    "path": "types/test/gun-user-recall.test-d.ts",
    "content": "import Gun from '../..';\n\nconst gun = new Gun();\ngun.user().recall({ sessionStorage: true });\n"
  },
  {
    "path": "types/test/gun-user.test-d.ts",
    "content": "import Gun from '../..';\n\nvar gun = new Gun();\ngun.user('publicKey');\n"
  },
  {
    "path": "types/test/sea-certify.test-d.ts",
    "content": "import Gun from '../..';\n\n/*Documentation example*/\nasync function certify() {\n  const SEA = Gun.SEA;\n  const gun = new Gun();\n  const user = gun.user();\n  const Alice = await SEA.pair();\n  const AliceHusband = await SEA.pair();\n  const Bob = await SEA.pair();\n  const Dave = await SEA.pair();\n\n  // Alice wants to allow Bob and Dave to use write to her \"inbox\" and \"stories\" UNTIL TOMORROW\n  // On Alice's side:\n  const certificate = await SEA.certify(\n    [Bob.pub, Dave.pub],\n    [{ '*': 'inbox', '+': '*' }, { '*': 'stories' }],\n    Alice,\n    null,\n    { expiry: Gun.state() + 60 * 60 * 24 * 1000 }\n  );\n\n  // Now on Bob/Dave's side, they can write to Alice's graph using gun.put:\n  gun\n    .get('~' + Alice.pub)\n    .get('inbox')\n    .put({ ['deeper' + Bob.pub]: 'hello world' }, null, {\n      opt: { cert: certificate },\n    }); // {opt: {cert: certificate}} is how you use Certificate in gun.put\n}\n"
  },
  {
    "path": "types/test/sea.test-d.ts",
    "content": "import Gun from '../..';\n\nconst SEA = Gun.SEA;\n(async () => {\n  const pair = await SEA.pair();\n  let enc = await SEA.encrypt('hello self', pair);\n  const data = await SEA.sign(enc, pair);\n  console.log(data);\n  const msg = await SEA.verify(data, pair.pub);\n  const dec = await SEA.decrypt(msg, pair);\n  const proof = await SEA.work(dec, pair);\n  const check = await SEA.work('hello self', pair);\n  console.log(dec);\n  console.log(proof === check);\n  // now let's share private data with someone:\n  const alice = await SEA.pair();\n  const bob = await SEA.pair();\n  enc = await SEA.encrypt('shared data', await SEA.secret(bob.epub, alice));\n  await SEA.decrypt(enc, await SEA.secret(alice.epub, bob));\n  // `.secret` is Elliptic-curve Diffie–Hellman\n  // Bob allows Alice to write to part of his graph, he creates a certificate for Alice\n  const certificate = await SEA.certify(alice.pub, ['^AliceOnly.*'], bob);\n  // Alice logs in\n  const gun = Gun();\n  gun.user().auth(alice);\n  // and uses the certificate\n  gun\n    .get('~' + bob.pub)\n    .get('AliceOnly')\n    .put({ 'do-not-tell-anyone': enc }, null, { opt: { cert: certificate } });\n  gun\n    .get('~' + bob.pub)\n    .get('AliceOnly')\n    .get('do-not-tell-anyone')\n    .once(console.log); // return 'enc'\n})();\n"
  },
  {
    "path": "types/utils.d.ts",
    "content": "import { GunSoul, IGunChain, IGunInstanceRoot } from '.';\n\nexport type GunSoul2TNode<T> = T extends GunSoul<infer TNode, infer _Soul>\n  ? TNode\n  : never;\n\nexport type GunSoul2Soul<T> = T extends GunSoul<infer _TNode, infer Soul>\n  ? Soul\n  : never;\n\nexport type IGunChain2TNode<T> = T extends IGunChain<\n  infer TNode,\n  infer _TChainParent,\n  infer _TNodeRoot,\n  infer _TKey\n>\n  ? TNode\n  : never;\n\nexport type IGunInstanceRoot2TGunInstance<T> = T extends IGunInstanceRoot<\n  infer _TNode,\n  infer TGunInstance\n>\n  ? TGunInstance\n  : never;\n"
  }
]