Prechádzať zdrojové kódy

Merge branch 'master' into module-charts

Matt 6 rokov pred
rodič
commit
5bb8eb22ec
100 zmenil súbory, kde vykonal 24162 pridanie a 32500 odobranie
  1. 0 12
      .babelrc
  2. 14 0
      .editorconfig
  3. 1 1
      .eslintignore
  4. 26 11
      .eslintrc.json
  5. 1 12
      .github/ISSUE_TEMPLATE.md
  6. 5 0
      .gitignore
  7. 14 3
      .travis.yml
  8. 194 0
      CHANGELOG.md
  9. 46 0
      CODE_OF_CONDUCT.md
  10. 229 173
      Gruntfile.js
  11. 47 29
      README.md
  12. 24 0
      babel.config.js
  13. BIN
      docs/favicon.ico
  14. 1 1
      docs/jsdoc.conf.json
  15. 34 0
      nightwatch.json
  16. 13999 0
      package-lock.json
  17. 104 52
      package.json
  18. 0 126
      src/core/Chef.js
  19. 198 0
      src/core/Chef.mjs
  20. 235 0
      src/core/ChefWorker.js
  21. 0 206
      src/core/Dish.js
  22. 434 0
      src/core/Dish.mjs
  23. 0 213
      src/core/FlowControl.js
  24. 0 92
      src/core/Ingredient.js
  25. 123 0
      src/core/Ingredient.mjs
  26. 0 163
      src/core/Operation.js
  27. 318 0
      src/core/Operation.mjs
  28. 0 220
      src/core/Recipe.js
  29. 342 0
      src/core/Recipe.mjs
  30. 0 218
      src/core/Utils.js
  31. 180 0
      src/core/Utils.mjs
  32. 162 70
      src/core/config/Categories.json
  33. 0 3604
      src/core/config/OperationConfig.js
  34. 150 0
      src/core/config/scripts/generateConfig.mjs
  35. 60 0
      src/core/config/scripts/generateOpsIndex.mjs
  36. 230 0
      src/core/config/scripts/newOperation.mjs
  37. 26 0
      src/core/errors/DishError.mjs
  38. 26 0
      src/core/errors/OperationError.mjs
  39. 139 0
      src/core/lib/Arithmetic.mjs
  40. 48 0
      src/core/lib/BCD.mjs
  41. 22 0
      src/core/lib/Base58.mjs
  42. 142 0
      src/core/lib/Base64.mjs
  43. 45 0
      src/core/lib/Base85.mjs
  44. 70 0
      src/core/lib/Binary.mjs
  45. 124 0
      src/core/lib/BitwiseOp.mjs
  46. 15 0
      src/core/lib/Braille.mjs
  47. 204 0
      src/core/lib/CanvasComponents.mjs
  48. 58 0
      src/core/lib/ChrEnc.mjs
  49. 82 0
      src/core/lib/Ciphers.mjs
  50. 29 0
      src/core/lib/Code.mjs
  51. 655 0
      src/core/lib/ConvertCoordinates.mjs
  52. 313 0
      src/core/lib/DateTime.mjs
  53. 37 0
      src/core/lib/Decimal.mjs
  54. 74 0
      src/core/lib/Delim.mjs
  55. 59 0
      src/core/lib/Extract.mjs
  56. 20 0
      src/core/lib/FlowControl.mjs
  57. 28 0
      src/core/lib/Hash.mjs
  58. 109 0
      src/core/lib/Hex.mjs
  59. 676 0
      src/core/lib/IP.mjs
  60. 230 0
      src/core/lib/LoremIpsum.mjs
  61. 1283 0
      src/core/lib/Magic.mjs
  62. 117 0
      src/core/lib/PGP.mjs
  63. 72 0
      src/core/lib/PublicKey.mjs
  64. 103 0
      src/core/lib/Rotate.mjs
  65. 78 0
      src/core/lib/TLVParser.mjs
  66. 19 0
      src/core/lib/Zlib.mjs
  67. 0 186
      src/core/lib/canvascomponents.js
  68. 0 25821
      src/core/lib/uas_parser.js
  69. 63 0
      src/core/operations/A1Z26CipherDecode.mjs
  70. 61 0
      src/core/operations/A1Z26CipherEncode.mjs
  71. 77 0
      src/core/operations/ADD.mjs
  72. 109 0
      src/core/operations/AESDecrypt.mjs
  73. 107 0
      src/core/operations/AESEncrypt.mjs
  74. 77 0
      src/core/operations/AND.mjs
  75. 46 0
      src/core/operations/AddLineNumbers.mjs
  76. 53 0
      src/core/operations/Adler32Checksum.mjs
  77. 106 0
      src/core/operations/AffineCipherDecode.mjs
  78. 78 0
      src/core/operations/AffineCipherEncode.mjs
  79. 184 0
      src/core/operations/AnalyseHash.mjs
  80. 67 0
      src/core/operations/AtbashCipher.mjs
  81. 49 0
      src/core/operations/BSONDeserialise.mjs
  82. 49 0
      src/core/operations/BSONSerialise.mjs
  83. 0 66
      src/core/operations/Base.js
  84. 0 137
      src/core/operations/Base58.js
  85. 0 347
      src/core/operations/Base64.js
  86. 55 0
      src/core/operations/Bcrypt.mjs
  87. 56 0
      src/core/operations/BcryptCompare.mjs
  88. 49 0
      src/core/operations/BcryptParse.mjs
  89. 125 0
      src/core/operations/BifidCipherDecode.mjs
  90. 130 0
      src/core/operations/BifidCipherEncode.mjs
  91. 76 0
      src/core/operations/BitShiftLeft.mjs
  92. 83 0
      src/core/operations/BitShiftRight.mjs
  93. 0 310
      src/core/operations/BitwiseOp.js
  94. 101 0
      src/core/operations/BlowfishDecrypt.mjs
  95. 102 0
      src/core/operations/BlowfishEncrypt.mjs
  96. 0 427
      src/core/operations/ByteRepr.js
  97. 56 0
      src/core/operations/Bzip2Decompress.mjs
  98. 41 0
      src/core/operations/CRC16Checksum.mjs
  99. 41 0
      src/core/operations/CRC32Checksum.mjs
  100. 47 0
      src/core/operations/CSSBeautify.mjs

+ 0 - 12
.babelrc

@@ -1,12 +0,0 @@
-{
-    "presets": [
-        ["env", {
-            "targets": {
-                "chrome": 40,
-                "firefox": 35,
-                "edge": 14
-            },
-            "modules": false
-        }]
-    ]
-}

+ 14 - 0
.editorconfig

@@ -0,0 +1,14 @@
+# top-most EditorConfig file
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 4
+
+[{package.json,.travis.yml,nightwatch.json}]
+indent_style = space
+indent_size = 2

+ 1 - 1
.eslintignore

@@ -1 +1 @@
-src/core/lib/**
+src/core/vendor/**

+ 26 - 11
.eslintrc.json

@@ -1,10 +1,12 @@
 {
+    "parser": "babel-eslint",
     "parserOptions": {
-        "ecmaVersion": 8,
+        "ecmaVersion": 9,
         "ecmaFeatures": {
             "impliedStrict": true
         },
-        "sourceType": "module"
+        "sourceType": "module",
+        "allowImportExportEverywhere": true
     },
     "env": {
         "browser": true,
@@ -28,18 +30,13 @@
         // modify rules from base configurations
         "no-unused-vars": ["error", {
             "args": "none",
-            "vars": "local",
-            // Allow vars that start with a capital letter to be unused.
-            // This is mainly for exported module names which are useful to indicate
-            // the name of the module and may be used to refer to itself in future.
-            "varsIgnorePattern": "^[A-Z]"
+            "vars": "all"
         }],
         "no-empty": ["error", {
             "allowEmptyCatch": true
         }],
 
         // disable rules from base configurations
-        "no-console": "off",
         "no-control-regex": "off",
 
         // stylistic conventions
@@ -52,7 +49,11 @@
         "no-trailing-spaces": "warn",
         "eol-last": "error",
         "func-call-spacing": "error",
+        "key-spacing": ["warn", {
+            "mode": "minimum"
+        }],
         "indent": ["error", 4, {
+            "ignoreComments": true,
             "ArrayExpression": "first",
             "SwitchCase": 1
         }],
@@ -85,14 +86,28 @@
         "no-whitespace-before-property": "error",
         "operator-linebreak": ["error", "after"],
         "space-in-parens": "error",
-        "no-var": "error"
+        "no-var": "error",
+        "prefer-const": "error"
     },
+    "overrides": [
+        {
+            "files": "tests/**/*",
+            "rules": {
+                "no-unused-expressions": "off",
+                "no-console": "off"
+            }
+        }
+    ],
     "globals": {
         "$": false,
         "jQuery": false,
-        "moment": false,
+        "log": false,
 
         "COMPILE_TIME": false,
-        "COMPILE_MSG": false
+        "COMPILE_MSG": false,
+        "PKG_VERSION": false,
+        "ENVIRONMENT_IS_WORKER": false,
+        "ENVIRONMENT_IS_NODE": false,
+        "ENVIRONMENT_IS_WEB": false
     }
 }

+ 1 - 12
.github/ISSUE_TEMPLATE.md

@@ -5,21 +5,10 @@
 <!-- Misc: -->
 
 ### Summary
-<!-- If you're describing a bug, tell us what's wrong -->
-<!-- If you're suggesting a change/improvement, tell us what it is and how it should work -->
+
 
 ### Example
 <!-- If describing a bug, tell us what happens instead of the expected behavior -->
 <!-- Include a link that triggers the bug if possible -->
 <!-- If you are requesting a new operation, include example input and output -->
 
-### Possible solutions
-<!-- Not obligatory, but suggest a fix/reason for the bug, or ideas for how to -->
-<!-- implement the addition or change, including links to relevant resources -->
-
-### Environment
-<!-- Include any relevant details about the environment you experienced the bug in -->
-<!-- This information is displayed in the About/Support pane -->
-* CyberChef compile time: 
-* User-Agent: 
-* [Link to reproduce]()

+ 5 - 0
.gitignore

@@ -6,3 +6,8 @@ docs/*
 !docs/*.conf.json
 !docs/*.ico
 .vscode
+src/core/config/modules/*
+src/core/config/OperationConfig.json
+src/core/operations/index.mjs
+tests/browser/output/*
+

+ 14 - 3
.travis.yml

@@ -1,16 +1,21 @@
 language: node_js
 node_js:
   - node
+addons:
+  chrome: stable
 install: npm install
 before_script:
   - npm install -g grunt
+  - export NODE_OPTIONS=--max_old_space_size=2048
 script:
   - grunt lint
   - grunt test
   - grunt docs
   - grunt node
   - grunt prod --msg="$COMPILE_MSG"
+  - xvfb-run --server-args="-screen 0 1200x800x24" grunt testui
 before_deploy:
+  - grunt exec:sitemap
   - grunt copy:ghPages
 deploy:
   - provider: pages
@@ -22,7 +27,7 @@ deploy:
       repo: gchq/CyberChef
       branch: master
   - provider: releases
-    skip_cleaup: true
+    skip_cleanup: true
     api_key:
       secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
     file:
@@ -35,8 +40,14 @@ deploy:
     skip_cleanup: true
     email: "n1474335@gmail.com"
     api_key:
-      secure: "Z3FK6bm4RfQEIRXZ1lBNzQkVIoHpivThr9U+XBHmsBgIfdrK/XUnzs/slugo+NIz8nPiGmMx4gxyJonBCLHDGb1ysky2aEWTl26c0teaF4DeQEjWC1ZaGzv8MV1/GkUamnr1qouXjyUhyEAp33rd8ccN9Rq3QNYB/qLDcA9/FCme7JCW6sCd4zWO0LGEYMJEMc2FzAUkqhqsI05hegGhSDgKXRn5PmLARek4yHD+Hx7pstaTeQIy0WoGJjdzoB3iJIMmo/hWZGzZafktUOh223c5qzx4zMpDRNmMngBUw6R94nKd4KvplYRgB87Y3L/aiVU4CF+axwLmK8RPaC1wbJnlHf06zxHPdiFmsY/zKPpNel+nOnxzRrF5l2KMU4TU6gug3s9Jnzp9T5UMfhp0jW3YkxHGeuOPOeE1i0lTUWUGWrPHLQquAhLfkr2zxaU4ETk/y85hq9W4LAy0ENEDVXX2jP7FnI4Z1fdpmljpmVNJR+outPg6t+Coqgvil7v7XpMtDm8lKQanVYuxwmkb/ncOWFRWuM2j5zIEg3CHnFDcJ9bYrfKRg0b0tb/2BWD14pQnV76goVwzJQYVzdPc8TKIYJw2BZ1Nh9c0iruQVebe/6l1FX9fDCkz8VMmltni61/LxZrf8y0NT1YaU1raeNY2dH5UWvEa9p72FPMI6Eg="
+      secure: "UnDQL3Kh+GK2toL0TK3FObO0ujVssU3Eg4BBuYdjwLB81GhiGE5/DTh7THdZPOpbLo6wQeOwfZDuMeKC1OU+0Uf4NsdYFu1aq6xMO20qBQ4qUfgsyiK4Qgywj9gk0p1+OFZdGAZ/j1CNRAaF71XQIY6iV84c+SO4WoizXYrNT0Jh4sr2DA4/97G2xmJtPi0qOzYrJ09R56ZUozmqeik5G0pMRIuJRbpjS/7bZXV+N7WV0ombZc9RkUaetbabEVOLQ+Xx5YAIVq+VuEeMe9VBSnxY/FfCLmy1wJsjGzpLCyBI9nbrG4nw8Wgc2m8NfK9rcpIvBTGner9r2j60NVDkZ8kLZPrqXhq6AZMwa+oz6K5UQCqRo2RRQzSGwXxg67HY5Tcq+oNmjd+DqpPg4LZ3eGlluyP5XfG+hpSr9Ya4d8q8SrUWLxkoLHI6ZKMtoKFbTCSSQPiluW5hsZxjz3yDkkjsJw64M/EM8UyJrgaXqDklQu+7rBGKLfsK6os7RDiqjBWpQ7gwpo8HvY0O8yqEAabPz+QGkanpjcCOZCXFbSkzWxYy37RMAPu88iINVZVlZE4l+WJenCpZY95ueyy0mG9cyMSzVRPyX6A+/n4H6VMFPFjpGDLTD588ACEjY1lmHfS/eXwXJcgqPPD2gW0XdRdUheU/ssqlfCfGWQMTDXs="
     on:
       tags: true
       branch: master
-
+notifications:
+    webhooks:
+        urls:
+            - https://webhooks.gitter.im/e/83c143a6822e218d5b34
+        on_success: change
+        on_failure: always
+        on_start: never

+ 194 - 0
CHANGELOG.md

@@ -0,0 +1,194 @@
+# Changelog
+All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master).
+
+
+### [8.24.0] - 2019-02-08
+- 'DNS over HTTPS' operation added [@h345983745] | [#489]
+
+### [8.23.1] - 2019-01-18
+- 'Convert co-ordinate format' operation added [@j433866] | [#476]
+
+### [8.23.0] - 2019-01-18
+- 'YARA Rules' operation added [@artemisbot] | [#468]
+
+### [8.22.0] - 2019-01-10
+- 'Subsection' operation added [@j433866] | [#467]
+
+### [8.21.0] - 2019-01-10
+- 'To Case Insensitive Regex' and 'From Case Insensitive Regex' operations added [@masq] | [#461]
+
+### [8.20.0] - 2019-01-09
+- 'Generate Lorem Ipsum' operation added [@klaxon1] | [#455]
+
+### [8.19.0] - 2018-12-30
+- UI test suite added to confirm that the app loads correctly in a reasonable time and that various operations from each module can be run [@n1474335] | [#458]
+
+### [8.18.0] - 2018-12-26
+- 'Split Colour Channels' operation added [@artemisbot] | [#449]
+
+### [8.17.0] - 2018-12-25
+- 'Generate QR Code' and 'Parse QR Code' operations added [@j433866] | [#448]
+
+### [8.16.0] - 2018-12-19
+- 'Play Media' operation added [@anthony-arnold] | [#446]
+
+### [8.15.0] - 2018-12-18
+- 'Text Encoding Brute Force' operation added [@Cynser] | [#439]
+
+### [8.14.0] - 2018-12-18
+- 'To Base62' and 'From Base62' operations added [@tcode2k16] | [#443]
+
+### [8.13.0] - 2018-12-15
+- 'A1Z26 Cipher Encode' and 'A1Z26 Cipher Decode' operations added [@jarmovanlenthe] | [#441]
+
+### [8.12.0] - 2018-11-21
+- 'Citrix CTX1 Encode' and 'Citrix CTX1 Decode' operations added [@bwhitn] | [#428]
+
+### [8.11.0] - 2018-11-13
+- 'CSV to JSON' and 'JSON to CSV' operations added [@n1474335] | [#277]
+
+### [8.10.0] - 2018-11-07
+- 'Remove Diacritics' operation added [@klaxon1] | [#387]
+
+### [8.9.0] - 2018-11-07
+- 'Defang URL' operation added [@arnydo] | [#394]
+
+### [8.8.0] - 2018-10-10
+- 'Parse TLV' operation added [@GCHQ77703] | [#351]
+
+### [8.7.0] - 2018-08-31
+- 'JWT Sign', 'JWT Verify' and 'JWT Decode' operations added [@GCHQ77703] | [#348]
+
+### [8.6.0] - 2018-08-29
+- 'To Geohash' and 'From Geohash' operations added [@GCHQ77703] | [#344]
+
+### [8.5.0] - 2018-08-23
+- 'To Braille' and 'From Braille' operations added [@n1474335] | [#255]
+
+### [8.4.0] - 2018-08-23
+- 'To Base85' and 'From Base85' operations added [@PenguinGeorge] | [#340]
+
+### [8.3.0] - 2018-08-21
+- 'To MessagePack' and 'From MessagePack' operations added [@artemisbot] | [#338]
+
+### [8.2.0] - 2018-08-21
+- Information links added to most operations, accessible in the description popover [@PenguinGeorge] | [#298]
+
+### [8.1.0] - 2018-08-19
+- 'Dechunk HTTP response' operation added [@sevzero] | [#311]
+
+## [8.0.0] - 2018-08-05
+- Codebase rewritten using [ES modules](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/) and [classes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) [@n1474335] [@d98762625] [@artemisbot] [@picapi] | [#284]
+- Operation architecture restructured to make adding new operations a lot simpler [@n1474335] | [#284]
+- A script has been added to aid in the creation of new operations by running `npm run newop` [@n1474335] | [#284]
+- 'Magic' operation added - [automated detection of encoded data](https://github.com/gchq/CyberChef/wiki/Automatic-detection-of-encoded-data-using-CyberChef-Magic) [@n1474335] | [#239]
+- UI updated to use [Bootstrap Material Design](https://fezvrasta.github.io/bootstrap-material-design/) [@n1474335] | [#248]
+- `JSON`, `File` and `List<File>` Dish types added [@n1474335] | [#284]
+- `OperationError` type added for better handling of errors thrown by operations [@d98762625] | [#296]
+- A `present()` method has been added, allowing operations to pass machine-friendly data to subsequent operations whilst presenting human-friendly data to the user [@n1474335] | [#284]
+- Set operations added [@d98762625] | [#281]
+- 'To Table' operation added [@JustAnotherMark] | [#294]
+- 'Haversine distance' operation added [@Dachande663] | [#325]
+- Started keeping a changelog [@n1474335]
+
+## [7.0.0] - 2017-12-28
+- Added support for loading, processing and downloading files up to 500MB [@n1474335] | [#224]
+
+## [6.0.0] - 2017-09-19
+- Threading support added. All recipe processing moved into a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) to increase performance and to allow long-running operations to be cancelled [@n1474335] | [#173]
+- Module system created so that operations relying on large libraries can be downloaded separately as required, reducing the initial loading time for the app [@n1474335] | [#173]
+
+## [5.0.0] - 2017-03-30
+-  Webpack build process configured with Babel transpilation and ES6 imports and exports [@n1474335] | [#95]
+
+## [4.0.0] - 2016-11-28
+-  Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
+
+
+
+[8.24.0]: https://github.com/gchq/CyberChef/releases/tag/v8.24.0
+[8.23.1]: https://github.com/gchq/CyberChef/releases/tag/v8.23.1
+[8.23.0]: https://github.com/gchq/CyberChef/releases/tag/v8.23.0
+[8.22.0]: https://github.com/gchq/CyberChef/releases/tag/v8.22.0
+[8.21.0]: https://github.com/gchq/CyberChef/releases/tag/v8.21.0
+[8.20.0]: https://github.com/gchq/CyberChef/releases/tag/v8.20.0
+[8.19.0]: https://github.com/gchq/CyberChef/releases/tag/v8.19.0
+[8.18.0]: https://github.com/gchq/CyberChef/releases/tag/v8.18.0
+[8.17.0]: https://github.com/gchq/CyberChef/releases/tag/v8.17.0
+[8.16.0]: https://github.com/gchq/CyberChef/releases/tag/v8.16.0
+[8.15.0]: https://github.com/gchq/CyberChef/releases/tag/v8.15.0
+[8.14.0]: https://github.com/gchq/CyberChef/releases/tag/v8.14.0
+[8.13.0]: https://github.com/gchq/CyberChef/releases/tag/v8.13.0
+[8.12.0]: https://github.com/gchq/CyberChef/releases/tag/v8.12.0
+[8.11.0]: https://github.com/gchq/CyberChef/releases/tag/v8.11.0
+[8.10.0]: https://github.com/gchq/CyberChef/releases/tag/v8.10.0
+[8.9.0]: https://github.com/gchq/CyberChef/releases/tag/v8.9.0
+[8.8.0]: https://github.com/gchq/CyberChef/releases/tag/v8.8.0
+[8.7.0]: https://github.com/gchq/CyberChef/releases/tag/v8.7.0
+[8.6.0]: https://github.com/gchq/CyberChef/releases/tag/v8.6.0
+[8.5.0]: https://github.com/gchq/CyberChef/releases/tag/v8.5.0
+[8.4.0]: https://github.com/gchq/CyberChef/releases/tag/v8.4.0
+[8.3.0]: https://github.com/gchq/CyberChef/releases/tag/v8.3.0
+[8.2.0]: https://github.com/gchq/CyberChef/releases/tag/v8.2.0
+[8.1.0]: https://github.com/gchq/CyberChef/releases/tag/v8.1.0
+[8.0.0]: https://github.com/gchq/CyberChef/releases/tag/v8.0.0
+[7.0.0]: https://github.com/gchq/CyberChef/releases/tag/v7.0.0
+[6.0.0]: https://github.com/gchq/CyberChef/releases/tag/v6.0.0
+[5.0.0]: https://github.com/gchq/CyberChef/releases/tag/v5.0.0
+[4.0.0]: https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306
+
+[@n1474335]: https://github.com/n1474335
+[@d98762625]: https://github.com/d98762625
+[@j433866]: https://github.com/j433866
+[@GCHQ77703]: https://github.com/GCHQ77703
+[@h345983745]: https://github.com/h345983745
+[@artemisbot]: https://github.com/artemisbot
+[@picapi]: https://github.com/picapi
+[@Dachande663]: https://github.com/Dachande663
+[@JustAnotherMark]: https://github.com/JustAnotherMark
+[@sevzero]: https://github.com/sevzero
+[@PenguinGeorge]: https://github.com/PenguinGeorge
+[@arnydo]: https://github.com/arnydo
+[@klaxon1]: https://github.com/klaxon1
+[@bwhitn]: https://github.com/bwhitn
+[@jarmovanlenthe]: https://github.com/jarmovanlenthe
+[@tcode2k16]: https://github.com/tcode2k16
+[@Cynser]: https://github.com/Cynser
+[@anthony-arnold]: https://github.com/anthony-arnold
+[@masq]: https://github.com/masq
+
+[#95]: https://github.com/gchq/CyberChef/pull/299
+[#173]: https://github.com/gchq/CyberChef/pull/173
+[#224]: https://github.com/gchq/CyberChef/pull/224
+[#239]: https://github.com/gchq/CyberChef/pull/239
+[#248]: https://github.com/gchq/CyberChef/pull/248
+[#255]: https://github.com/gchq/CyberChef/issues/255
+[#277]: https://github.com/gchq/CyberChef/issues/277
+[#281]: https://github.com/gchq/CyberChef/pull/281
+[#284]: https://github.com/gchq/CyberChef/pull/284
+[#294]: https://github.com/gchq/CyberChef/pull/294
+[#296]: https://github.com/gchq/CyberChef/pull/296
+[#298]: https://github.com/gchq/CyberChef/pull/298
+[#311]: https://github.com/gchq/CyberChef/pull/311
+[#325]: https://github.com/gchq/CyberChef/pull/325
+[#338]: https://github.com/gchq/CyberChef/pull/338
+[#340]: https://github.com/gchq/CyberChef/pull/340
+[#344]: https://github.com/gchq/CyberChef/pull/344
+[#348]: https://github.com/gchq/CyberChef/pull/348
+[#351]: https://github.com/gchq/CyberChef/pull/351
+[#387]: https://github.com/gchq/CyberChef/pull/387
+[#394]: https://github.com/gchq/CyberChef/pull/394
+[#428]: https://github.com/gchq/CyberChef/pull/428
+[#439]: https://github.com/gchq/CyberChef/pull/439
+[#441]: https://github.com/gchq/CyberChef/pull/441
+[#443]: https://github.com/gchq/CyberChef/pull/443
+[#446]: https://github.com/gchq/CyberChef/pull/446
+[#448]: https://github.com/gchq/CyberChef/pull/448
+[#449]: https://github.com/gchq/CyberChef/pull/449
+[#455]: https://github.com/gchq/CyberChef/pull/455
+[#458]: https://github.com/gchq/CyberChef/pull/458
+[#461]: https://github.com/gchq/CyberChef/pull/461
+[#467]: https://github.com/gchq/CyberChef/pull/467
+[#468]: https://github.com/gchq/CyberChef/pull/468
+[#476]: https://github.com/gchq/CyberChef/pull/476
+[#489]: https://github.com/gchq/CyberChef/pull/489

+ 46 - 0
CODE_OF_CONDUCT.md

@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at oss@gchq.gov.uk. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/

+ 229 - 173
Gruntfile.js

@@ -1,7 +1,20 @@
+"use strict";
+
 const webpack = require("webpack");
-const ExtractTextPlugin = require("extract-text-webpack-plugin");
 const HtmlWebpackPlugin = require("html-webpack-plugin");
+const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
+const NodeExternals = require("webpack-node-externals");
 const Inliner = require("web-resource-inliner");
+const glob = require("glob");
+const path = require("path");
+
+/**
+ * Grunt configuration for building the app in various formats.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
 
 module.exports = function (grunt) {
     grunt.file.defaultEncoding = "utf8";
@@ -10,15 +23,19 @@ module.exports = function (grunt) {
     // Tasks
     grunt.registerTask("dev",
         "A persistent task which creates a development build whenever source files are modified.",
-        ["clean:dev", "webpack:webDev"]);
+        ["clean:dev", "clean:config", "exec:generateConfig", "concurrent:dev"]);
 
     grunt.registerTask("node",
         "Compiles CyberChef into a single NodeJS module.",
-        ["clean:node", "webpack:node", "chmod:build"]);
+        ["clean:node", "clean:config", "exec:generateConfig", "webpack:node", "chmod:build"]);
 
     grunt.registerTask("test",
-        "A task which runs all the tests in test/tests.",
-        ["clean:test", "webpack:tests", "execute:test"]);
+        "A task which runs all the operation tests in the tests directory.",
+        ["exec:generateConfig", "exec:opTests"]);
+
+    grunt.registerTask("testui",
+        "A task which runs all the UI tests in the tests directory. The prod task must already have been run.",
+        ["connect:prod", "exec:browserTests"]);
 
     grunt.registerTask("docs",
         "Compiles documentation in the /docs directory.",
@@ -26,7 +43,7 @@ module.exports = function (grunt) {
 
     grunt.registerTask("prod",
         "Creates a production-ready build. Use the --msg flag to add a compile message.",
-        ["eslint", "clean:prod", "webpack:webProd", "inline", "chmod"]);
+        ["eslint", "clean:prod", "clean:config", "exec:generateConfig", "webpack:web", "inline", "chmod"]);
 
     grunt.registerTask("default",
         "Lints the code base",
@@ -34,8 +51,10 @@ module.exports = function (grunt) {
 
     grunt.registerTask("inline",
         "Compiles a production build of CyberChef into a single, portable web page.",
-        runInliner);
+        ["exec:generateConfig", "webpack:webInline", "runInliner", "clean:inlineScripts"]);
 
+
+    grunt.registerTask("runInliner", runInliner);
     grunt.registerTask("doc", "docs");
     grunt.registerTask("tests", "test");
     grunt.registerTask("lint", "eslint");
@@ -47,35 +66,33 @@ module.exports = function (grunt) {
     grunt.loadNpmTasks("grunt-jsdoc");
     grunt.loadNpmTasks("grunt-contrib-clean");
     grunt.loadNpmTasks("grunt-contrib-copy");
+    grunt.loadNpmTasks("grunt-contrib-watch");
     grunt.loadNpmTasks("grunt-chmod");
     grunt.loadNpmTasks("grunt-exec");
-    grunt.loadNpmTasks("grunt-execute");
     grunt.loadNpmTasks("grunt-accessibility");
+    grunt.loadNpmTasks("grunt-concurrent");
+    grunt.loadNpmTasks("grunt-contrib-connect");
 
 
     // Project configuration
     const compileTime = grunt.template.today("UTC:dd/mm/yyyy HH:MM:ss") + " UTC",
-        banner = "/**\n" +
-            "* CyberChef - The Cyber Swiss Army Knife\n" +
-            "*\n" +
-            "* @copyright Crown Copyright 2016\n" +
-            "* @license Apache-2.0\n" +
-            "*\n" +
-            "*   Copyright 2016 Crown Copyright\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" +
-            "*/\n",
-        pkg = grunt.file.readJSON("package.json");
+        pkg = grunt.file.readJSON("package.json"),
+        webpackConfig = require("./webpack.config.js"),
+        BUILD_CONSTANTS = {
+            COMPILE_TIME: JSON.stringify(compileTime),
+            COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || ""),
+            PKG_VERSION: JSON.stringify(pkg.version),
+            ENVIRONMENT_IS_WORKER: function() {
+                return typeof importScripts === "function";
+            },
+            ENVIRONMENT_IS_NODE: function() {
+                return typeof process === "object" && typeof require === "function";
+            },
+            ENVIRONMENT_IS_WEB: function() {
+                return typeof window === "object";
+            }
+        },
+        moduleEntryPoints = listEntryModules();
 
     /**
      * Compiles a production build of CyberChef into a single, portable web page.
@@ -104,23 +121,39 @@ module.exports = function (grunt) {
         });
     }
 
+    /**
+     * Generates an entry list for all the modules.
+     */
+    function listEntryModules() {
+        const entryModules = {};
+
+        glob.sync("./src/core/config/modules/*.mjs").forEach(file => {
+            const basename = path.basename(file);
+            if (basename !== "Default.mjs" && basename !== "OpModules.mjs")
+                entryModules[basename.split(".mjs")[0]] = path.resolve(file);
+        });
+
+        return entryModules;
+    }
+
     grunt.initConfig({
         clean: {
             dev: ["build/dev/*"],
             prod: ["build/prod/*"],
-            test: ["build/test/*"],
             node: ["build/node/*"],
-            docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico"],
+            config: ["src/core/config/OperationConfig.json", "src/core/config/modules/*", "src/code/operations/index.mjs"],
+            docs: ["docs/*", "!docs/*.conf.json", "!docs/*.ico", "!docs/*.png"],
+            inlineScripts: ["build/prod/scripts.js"],
         },
         eslint: {
             options: {
                 configFile: "./.eslintrc.json"
             },
-            configs: ["Gruntfile.js"],
-            core: ["src/core/**/*.js", "!src/core/lib/**/*"],
-            web: ["src/web/**/*.js"],
-            node: ["src/node/**/*.js"],
-            tests: ["test/**/*.js"],
+            configs: ["*.{js,mjs}"],
+            core: ["src/core/**/*.{js,mjs}", "!src/core/vendor/**/*", "!src/core/operations/legacy/**/*"],
+            web: ["src/web/**/*.{js,mjs}"],
+            node: ["src/node/**/*.{js,mjs}"],
+            tests: ["tests/**/*.{js,mjs}"],
         },
         jsdoc: {
             options: {
@@ -133,7 +166,8 @@ module.exports = function (grunt) {
             all: {
                 src: [
                     "src/**/*.js",
-                    "!src/core/lib/**/*",
+                    "src/**/*.mjs",
+                    "!src/core/vendor/**/*"
                 ],
             }
         },
@@ -150,103 +184,49 @@ module.exports = function (grunt) {
             }
         },
         webpack: {
-            options: {
-                plugins: [
-                    new webpack.ProvidePlugin({
-                        $: "jquery",
-                        jQuery: "jquery",
-                        moment: "moment-timezone"
-                    }),
-                    new webpack.BannerPlugin({
-                        banner: banner,
-                        raw: true,
-                        entryOnly: true
-                    }),
-                    new webpack.DefinePlugin({
-                        COMPILE_TIME: JSON.stringify(compileTime),
-                        COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || "")
-                    }),
-                    new ExtractTextPlugin("styles.css"),
-                ],
-                resolve: {
-                    alias: {
-                        jquery: "jquery/src/jquery"
-                    }
-                },
-                module: {
-                    rules: [
-                        {
-                            test: /\.js$/,
-                            exclude: /node_modules/,
-                            loader: "babel-loader?compact=false"
-                        },
-                        {
-                            test: /\.css$/,
-                            use: ExtractTextPlugin.extract({
-                                use: [
-                                    { loader: "css-loader?minimize" },
-                                    { loader: "postcss-loader" },
-                                ]
-                            })
-                        },
-                        {
-                            test: /\.less$/,
-                            use: ExtractTextPlugin.extract({
-                                use: [
-                                    { loader: "css-loader?minimize" },
-                                    { loader: "postcss-loader" },
-                                    { loader: "less-loader" }
-                                ]
-                            })
-                        },
-                        {
-                            test: /\.(ico|eot|ttf|woff|woff2)$/,
-                            loader: "url-loader",
-                            options: {
-                                limit: 10000
-                            }
-                        },
-                        { // First party images are saved as files to be cached
-                            test: /\.(png|jpg|gif|svg)$/,
-                            exclude: /node_modules/,
-                            loader: "file-loader",
-                            options: {
-                                name: "images/[name].[ext]"
-                            }
-                        },
-                        { // Third party images are inlined
-                            test: /\.(png|jpg|gif|svg)$/,
-                            exclude: /web\/static/,
-                            loader: "url-loader",
-                            options: {
-                                limit: 10000
+            options: webpackConfig,
+            web: () => {
+                return {
+                    mode: "production",
+                    target: "web",
+                    entry: Object.assign({
+                        main: "./src/web/index.js",
+                        sitemap: "./src/web/static/sitemap.js"
+                    }, moduleEntryPoints),
+                    output: {
+                        path: __dirname + "/build/prod",
+                        globalObject: "this"
+                    },
+                    resolve: {
+                        alias: {
+                            "./config/modules/OpModules": "./config/modules/Default"
+                        }
+                    },
+                    plugins: [
+                        new webpack.DefinePlugin(BUILD_CONSTANTS),
+                        new HtmlWebpackPlugin({
+                            filename: "index.html",
+                            template: "./src/web/html/index.html",
+                            chunks: ["main"],
+                            compileTime: compileTime,
+                            version: pkg.version,
+                            minify: {
+                                removeComments: true,
+                                collapseWhitespace: true,
+                                minifyJS: true,
+                                minifyCSS: true
                             }
-                        },
+                        }),
+                        new BundleAnalyzerPlugin({
+                            analyzerMode: "static",
+                            reportFilename: "BundleAnalyzerReport.html",
+                            openAnalyzer: false
+                        }),
                     ]
-                },
-                stats: {
-                    children: false,
-                    warningsFilter: /source-map/
-                }
+                };
             },
-            webDev: {
-                target: "web",
-                entry: "./src/web/index.js",
-                output: {
-                    filename: "scripts.js",
-                    path: __dirname + "/build/dev"
-                },
-                plugins: [
-                    new HtmlWebpackPlugin({
-                        filename: "index.html",
-                        template: "./src/web/html/index.html",
-                        compileTime: compileTime,
-                        version: pkg.version,
-                    })
-                ],
-                watch: true
-            },
-            webProd: {
+            webInline: {
+                mode: "production",
                 target: "web",
                 entry: "./src/web/index.js",
                 output: {
@@ -254,32 +234,14 @@ module.exports = function (grunt) {
                     path: __dirname + "/build/prod"
                 },
                 plugins: [
-                    new webpack.optimize.UglifyJsPlugin({
-                        compress: {
-                            "screw_ie8": true,
-                            "dead_code": true,
-                            "unused": true,
-                            "warnings": false
-                        },
-                        comments: false,
-                    }),
-                    new HtmlWebpackPlugin({ // Main version
-                        filename: "index.html",
-                        template: "./src/web/html/index.html",
-                        compileTime: compileTime,
-                        version: pkg.version,
-                        minify: {
-                            removeComments: true,
-                            collapseWhitespace: true,
-                            minifyJS: true,
-                            minifyCSS: true
-                        }
-                    }),
-                    new HtmlWebpackPlugin({ // Inline version
+                    new webpack.DefinePlugin(Object.assign({}, BUILD_CONSTANTS, {
+                        INLINE: "true"
+                    })),
+                    new HtmlWebpackPlugin({
                         filename: "cyberchef.htm",
                         template: "./src/web/html/index.html",
                         compileTime: compileTime,
-                        version: pkg.version,
+                        version: pkg.version + "s",
                         inline: true,
                         minify: {
                             removeComments: true,
@@ -290,37 +252,104 @@ module.exports = function (grunt) {
                     }),
                 ]
             },
-            tests: {
-                target: "node",
-                entry: "./test/index.js",
-                output: {
-                    filename: "index.js",
-                    path: __dirname + "/build/test"
-                }
-            },
             node: {
+                mode: "production",
                 target: "node",
-                entry: "./src/node/index.js",
+                entry: "./src/node/index.mjs",
+                externals: [NodeExternals()],
                 output: {
                     filename: "CyberChef.js",
                     path: __dirname + "/build/node",
                     library: "CyberChef",
                     libraryTarget: "commonjs2"
+                },
+                plugins: [
+                    new webpack.DefinePlugin(BUILD_CONSTANTS)
+                ]
+            }
+        },
+        "webpack-dev-server": {
+            options: {
+                webpack: webpackConfig,
+                host: "0.0.0.0",
+                disableHostCheck: true,
+                overlay: true,
+                inline: false,
+                clientLogLevel: "error",
+                stats: {
+                    children: false,
+                    chunks: false,
+                    modules: false,
+                    entrypoints: false,
+                    warningsFilter: [
+                        /source-map/,
+                        /dependency is an expression/,
+                        /export 'default'/
+                    ],
+                }
+            },
+            start: {
+                webpack: {
+                    mode: "development",
+                    target: "web",
+                    entry: Object.assign({
+                        main: "./src/web/index.js"
+                    }, moduleEntryPoints),
+                    resolve: {
+                        alias: {
+                            "./config/modules/OpModules": "./config/modules/Default"
+                        }
+                    },
+                    output: {
+                        globalObject: "this",
+                    },
+                    plugins: [
+                        new webpack.DefinePlugin(BUILD_CONSTANTS),
+                        new HtmlWebpackPlugin({
+                            filename: "index.html",
+                            template: "./src/web/html/index.html",
+                            chunks: ["main"],
+                            compileTime: compileTime,
+                            version: pkg.version,
+                        })
+                    ]
+                }
+            }
+        },
+        connect: {
+            prod: {
+                options: {
+                    port: 8000,
+                    base: "build/prod/"
                 }
             }
         },
         copy: {
             ghPages: {
                 options: {
-                    process: function (content) {
+                    process: function (content, srcpath) {
                         // Add Google Analytics code to index.html
-                        content = content.replace("</body></html>",
-                            grunt.file.read("src/web/static/ga.html") + "</body></html>");
-                        return grunt.template.process(content);
-                    }
+                        if (srcpath.indexOf("index.html") >= 0) {
+                            content = content.replace("</body></html>",
+                                grunt.file.read("src/web/static/ga.html") + "</body></html>");
+                            return grunt.template.process(content, srcpath);
+                        } else {
+                            return content;
+                        }
+                    },
+                    noProcess: ["**", "!**/*.html"]
                 },
-                src: "build/prod/index.html",
-                dest: "build/prod/index.html"
+                files: [
+                    {
+                        src: "build/prod/index.html",
+                        dest: "build/prod/index.html"
+                    },
+                    {
+                        expand: true,
+                        src: "docs/**",
+                        dest: "build/prod/"
+                    },
+                ]
             }
         },
         chmod: {
@@ -337,6 +366,18 @@ module.exports = function (grunt) {
                 src: ["docs/**/*", "docs/"]
             }
         },
+        watch: {
+            config: {
+                files: ["src/core/operations/**/*", "!src/core/operations/index.mjs"],
+                tasks: ["exec:generateConfig"]
+            }
+        },
+        concurrent: {
+            dev: ["watch:config", "webpack-dev-server:start"],
+            options: {
+                logConcurrentOutput: true
+            }
+        },
         exec: {
             repoSize: {
                 command: [
@@ -348,9 +389,24 @@ module.exports = function (grunt) {
             cleanGit: {
                 command: "git gc --prune=now --aggressive"
             },
-        },
-        execute: {
-            test: "build/test/index.js"
+            sitemap: {
+                command: "node build/prod/sitemap.js > build/prod/sitemap.xml"
+            },
+            generateConfig: {
+                command: [
+                    "echo '\n--- Regenerating config files. ---'",
+                    "echo [] > src/core/config/OperationConfig.json",
+                    "node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
+                    "node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
+                    "echo '--- Config scripts finished. ---\n'"
+                ].join(";")
+            },
+            opTests: {
+                command: "node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs"
+            },
+            browserTests: {
+                command: "./node_modules/.bin/nightwatch --env prod,inline"
+            }
         },
     });
 };

+ 47 - 29
README.md

@@ -1,14 +1,18 @@
 # CyberChef
 
 [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef)
-[![npm](https://badge.fury.io/js/cyberchef.svg)](https://www.npmjs.com/package/cyberchef)
-![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=brightgreen)
+[![dependencies Status](https://david-dm.org/gchq/CyberChef/status.svg)](https://david-dm.org/gchq/CyberChef)
+[![npm](https://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/cyberchef)
+![](https://reposs.herokuapp.com/?path=gchq/CyberChef&color=blue)
+[![](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/gchq/CyberChef/blob/master/LICENSE)
+[![Gitter](https://badges.gitter.im/gchq/CyberChef.svg)](https://gitter.im/gchq/CyberChef?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
 
 #### *The Cyber Swiss Army Knife*
 
-CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser. These operations include creating hexdumps, simple encoding like XOR or Base64, more complex encryption like AES, DES and Blowfish, data compression and decompression, calculating hashes and checksums, IPv6 and X.509 parsing, and much more.
+CyberChef is a simple, intuitive web app for carrying out all manner of "cyber" operations within a web browser. These operations include simple encoding like XOR or Base64, more complex encryption like AES, DES and Blowfish, creating binary and hexdumps, compression and decompression of data, calculating hashes and checksums, IPv6 and X.509 parsing, changing character encodings, and much more.
 
-The tool is designed to enable both technical and non-technical analysts to manipulate data in complex ways without having to deal with complex tools or algorithms. It was conceived, designed, built and incrementally improved by an analyst in their 10% innovation time over several years. Every effort has been made to structure the code in a readable and extendable format, however it should be noted that the analyst is not a professional developer and the code has not been peer-reviewed for compliance with a formal specification.
+The tool is designed to enable both technical and non-technical analysts to manipulate data in complex ways without having to deal with complex tools or algorithms. It was conceived, designed, built and incrementally improved by an analyst in their 10% innovation time over several years.
 
 ## Live demo
 
@@ -23,10 +27,10 @@ Cryptographic operations in CyberChef should not be relied upon to provide secur
 
 There are four main areas in CyberChef:
 
- 1. The **input** box in the top right, where you can paste, type or drag the data you want to operate on.
- 2. The **output** box in the bottom right, where the outcome of the specified processing will be displayed.
+ 1. The **input** box in the top right, where you can paste, type or drag the text or file you want to operate on.
+ 2. The **output** box in the bottom right, where the outcome of your processing will be displayed.
  3. The **operations** list on the far left, where you can find all the operations that CyberChef is capable of in categorised lists, or by searching.
- 4. The **recipe** area in the middle, where you drag the operations that you want to use and specify arguments and options.
+ 4. The **recipe** area in the middle, where you can drag the operations that you want to use and specify arguments and options.
 
 You can use as many operations as you like in simple or complex ways. Some examples are as follows:
 
@@ -34,48 +38,58 @@ You can use as many operations as you like in simple or complex ways. Some examp
  - [Convert a date and time to a different time zone][3]
  - [Parse a Teredo IPv6 address][4]
  - [Convert data from a hexdump, then decompress][5]
- - [Display multiple timestamps as full dates][6]
- - [Carry out different operations on data of different types][7]
+ - [Decrypt and disassemble shellcode][6]
+ - [Display multiple timestamps as full dates][7]
+ - [Carry out different operations on data of different types][8]
+ - [Use parts of the input as arguments to operations][9]
+ - [Perform AES decryption, extracting the IV from the beginning of the cipher stream][10]
+ - [Automagically detect several layers of nested encoding][12]
 
 
 ## Features
 
  - Drag and drop
      - Operations can be dragged in and out of the recipe list, or reorganised.
-     - Files can be dragged over the input box to load them directly.
+     - Files up to 500MB can be dragged over the input box to load them directly into the browser.
  - Auto Bake
-     - Whenever you modify the input or the recipe, CyberChef will automatically “bake” for you and produce the output immediately.
+     - Whenever you modify the input or the recipe, CyberChef will automatically "bake" for you and produce the output immediately.
      - This can be turned off and operated manually if it is affecting performance (if the input is very large, for instance).
-     - If any bake takes longer than 200 milliseconds, auto bake will be switched off automatically to prevent further performance issues.
+ - Automated encoding detection
+     - CyberChef uses [a number of techniques](https://github.com/gchq/CyberChef/wiki/Automatic-detection-of-encoded-data-using-CyberChef-Magic) to attempt to automatically detect which encodings your data is under. If it finds a suitable operation which can make sense of your data, it displays the 'magic' icon in the Output field which you can click to decode your data.
  - Breakpoints
      - You can set breakpoints on any operation in your recipe to pause execution before running it.
      - You can also step through the recipe one operation at a time to see what the data looks like at each stage.
  - Save and load recipes
-     - If you come up with an awesome recipe that you know you’ll want to use again, just click save and add it to your local storage. It'll be waiting for you next time you visit CyberChef.
-     - You can also copy a URL which includes your recipe and input which can be shared with others.
+     - If you come up with an awesome recipe that you know you’ll want to use again, just click "Save recipe" and add it to your local storage. It'll be waiting for you next time you visit CyberChef.
+     - You can also copy the URL, which includes your recipe and input, to easily share it with others.
  - Search
      - If you know the name of the operation you want or a word associated with it, start typing it into the search field and any matching operations will immediately be shown.
  - Highlighting
-     - When you highlight text in the input or output, the offset and length values will be displayed and, if possible, the corresponding data will be highlighted in the output or input respectively (example: [highlight the word 'question' in the input to see where it appears in the output][8]).
+     - When you highlight text in the input or output, the offset and length values will be displayed and, if possible, the corresponding data will be highlighted in the output or input respectively (example: [highlight the word 'question' in the input to see where it appears in the output][11]).
  - Save to file and load from file
-     - You can save the output to a file at any time or load a file by dragging and dropping it into the input field (note that files larger than about 500kb may cause your browser to hang or even crash due to the way that browsers handle large amounts of textual data).
+     - You can save the output to a file at any time or load a file by dragging and dropping it into the input field. Files up to around 500MB are supported (depending on your browser), however some operations may take a very long time to run over this much data.
  - CyberChef is entirely client-side
-     - It should be noted that none of your input or recipe configuration is ever sent to the CyberChef web server - all processing is carried out within your browser, on your own computer.
-     - Due to this feature, CyberChef can be compiled into a single HTML file. You can download this file and drop it into a virtual machine, share it with other people, or use it independently on your desktop.
+     - It should be noted that none of your recipe configuration or input (either text or files) is ever sent to the CyberChef web server - all processing is carried out within your browser, on your own computer.
+     - Due to this feature, CyberChef can be compiled into a single HTML file. You can download this file and drop it into a virtual machine, share it with other people, or use it independently on your local machine.
 
 
 ## Browser support
 
-CyberChef is built to support Google Chrome 40+, Mozilla Firefox 35+ and Microsoft Edge 14+.
+CyberChef is built to support
+
+ - Google Chrome 40+
+ - Mozilla Firefox 35+
+ - Microsoft Edge 14+
 
 
 ## Contributing
 
-An installation walkthrough, how-to guides for adding new operations, descriptions of the repository structure, available data types and coding conventions can all be found in the project [wiki pages](https://github.com/gchq/CyberChef/wiki).
+Contributing a new operation to CyberChef is super easy! There is a quickstart script which will walk you through the process. If you can write basic JavaScript, you can write a CyberChef operation.
+
+An installation walkthrough, how-to guides for adding new operations and themes, descriptions of the repository structure, available data types and coding conventions can all be found in the project [wiki pages](https://github.com/gchq/CyberChef/wiki).
 
- - Sign the [GCHQ Contributor Licence Agreement](https://github.com/gchq/Gaffer/wiki/GCHQ-OSS-Contributor-License-Agreement-V1.0)
  - Push your changes to your fork.
- - Submit a pull request.
+ - Submit a pull request. If you are doing this for the first time, you will be prompted to sign the [GCHQ Contributor Licence Agreement](https://cla-assistant.io/gchq/CyberChef) via the CLA assistant on the pull request. This will also ask whether you are happy for GCHQ to contact you about a token of thanks for your contribution, or about job opportunities at GCHQ.
 
 
 ## Licencing
@@ -84,10 +98,14 @@ CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/lice
 
 
   [1]: https://gchq.github.io/CyberChef
-  [2]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22From%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%2Ctrue%5D%7D%5D&input=VTI4Z2JHOXVaeUJoYm1RZ2RHaGhibXR6SUdadmNpQmhiR3dnZEdobElHWnBjMmd1
-  [3]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Translate%20DateTime%20Format%22%2C%22args%22%3A%5B%22Standard%20date%20and%20time%22%2C%22DD%2FMM%2FYYYY%20HH%3Amm%3Ass%22%2C%22UTC%22%2C%22dddd%20Do%20MMMM%20YYYY%20HH%3Amm%3Ass%20Z%20z%22%2C%22Australia%2FQueensland%22%5D%7D%5D&input=MTUvMDYvMjAxNSAyMDo0NTowMA
-  [4]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Parse%20IPv6%20address%22%2C%22args%22%3A%5B%5D%7D%5D&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy
-  [5]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22From%20Hexdump%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22Gunzip%22%2C%22args%22%3A%5B%5D%7D%5D&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu%2Fy7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb%2F3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw
-  [6]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22From%20UNIX%20Timestamp%22%2C%22args%22%3A%5B%22Seconds%20(s)%22%5D%7D%5D&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA
-  [7]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22Fork%22%2C%22args%22%3A%5B%22%5C%5Cn%22%2C%22%5C%5Cn%22%5D%7D%2C%7B%22op%22%3A%22Conditional%20Jump%22%2C%22args%22%3A%5B%221%22%2C%222%22%2C%2210%22%5D%7D%2C%7B%22op%22%3A%22To%20Hex%22%2C%22args%22%3A%5B%22Space%22%5D%7D%2C%7B%22op%22%3A%22Return%22%2C%22args%22%3A%5B%5D%7D%2C%7B%22op%22%3A%22To%20Base64%22%2C%22args%22%3A%5B%22A-Za-z0-9%2B%2F%3D%22%5D%7D%5D&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
-  [8]: https://gchq.github.io/CyberChef/?recipe=%5B%7B%22op%22%3A%22XOR%22%2C%22args%22%3A%5B%7B%22option%22%3A%22Hex%22%2C%22string%22%3A%223a%22%7D%2Cfalse%2Cfalse%5D%7D%2C%7B%22op%22%3A%22To%20Hexdump%22%2C%22args%22%3A%5B%2216%22%2Cfalse%2Cfalse%5D%7D%5D&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4
+  [2]: https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true)&input=VTI4Z2JHOXVaeUJoYm1RZ2RHaGhibXR6SUdadmNpQmhiR3dnZEdobElHWnBjMmd1
+  [3]: https://gchq.github.io/CyberChef/#recipe=Translate_DateTime_Format('Standard%20date%20and%20time','DD/MM/YYYY%20HH:mm:ss','UTC','dddd%20Do%20MMMM%20YYYY%20HH:mm:ss%20Z%20z','Australia/Queensland')&input=MTUvMDYvMjAxNSAyMDo0NTowMA
+  [4]: https://gchq.github.io/CyberChef/#recipe=Parse_IPv6_address()&input=MjAwMTowMDAwOjQxMzY6ZTM3ODo4MDAwOjYzYmY6M2ZmZjpmZGQy
+  [5]: https://gchq.github.io/CyberChef/#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw
+  [6]: https://gchq.github.io/CyberChef/#recipe=RC4(%7B'option':'UTF8','string':'secret'%7D,'Hex','Hex')Disassemble_x86('64','Full%20x86%20architecture',16,0,true,true)&input=MjFkZGQyNTQwMTYwZWU2NWZlMDc3NzEwM2YyYTM5ZmJlNWJjYjZhYTBhYWJkNDE0ZjkwYzZjYWY1MzEyNzU0YWY3NzRiNzZiM2JiY2QxOTNjYjNkZGZkYmM1YTI2NTMzYTY4NmI1OWI4ZmVkNGQzODBkNDc0NDIwMWFlYzIwNDA1MDcxMzhlMmZlMmIzOTUwNDQ2ZGIzMWQyYmM2MjliZTRkM2YyZWIwMDQzYzI5M2Q3YTVkMjk2MmMwMGZlNmRhMzAwNzJkOGM1YTZiNGZlN2Q4NTlhMDQwZWVhZjI5OTczMzYzMDJmNWEwZWMxOQ
+  [7]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA
+  [8]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',false,'base64',10)To_Hex('Space')Return()Label('base64')To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
+  [9]: https://gchq.github.io/CyberChef/#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ
+  [10]: https://gchq.github.io/CyberChef/#recipe=Register('(.%7B32%7D)',true,false)Drop_bytes(0,32,false)AES_Decrypt(%7B'option':'Hex','string':'1748e7179bd56570d51fa4ba287cc3e5'%7D,%7B'option':'Hex','string':'$R0'%7D,'CTR','Hex','Raw',%7B'option':'Hex','string':''%7D)&input=NTFlMjAxZDQ2MzY5OGVmNWY3MTdmNzFmNWI0NzEyYWYyMGJlNjc0YjNiZmY1M2QzODU0NjM5NmVlNjFkYWFjNDkwOGUzMTljYTNmY2Y3MDg5YmZiNmIzOGVhOTllNzgxZDI2ZTU3N2JhOWRkNmYzMTFhMzk0MjBiODk3OGU5MzAxNGIwNDJkNDQ3MjZjYWVkZjU0MzZlYWY2NTI0MjljMGRmOTRiNTIxNjc2YzdjMmNlODEyMDk3YzI3NzI3M2M3YzcyY2Q4OWFlYzhkOWZiNGEyNzU4NmNjZjZhYTBhZWUyMjRjMzRiYTNiZmRmN2FlYjFkZGQ0Nzc2MjJiOTFlNzJjOWU3MDlhYjYwZjhkYWY3MzFlYzBjYzg1Y2UwZjc0NmZmMTU1NGE1YTNlYzI5MWNhNDBmOWU2MjlhODcyNTkyZDk4OGZkZDgzNDUzNGFiYTc5YzFhZDE2NzY3NjlhN2MwMTBiZjA0NzM5ZWNkYjY1ZDk1MzAyMzcxZDYyOWQ5ZTM3ZTdiNGEzNjFkYTQ2OGYxZWQ1MzU4OTIyZDJlYTc1MmRkMTFjMzY2ZjMwMTdiMTRhYTAxMWQyYWYwM2M0NGY5NTU3OTA5OGExNWUzY2Y5YjQ0ODZmOGZmZTljMjM5ZjM0ZGU3MTUxZjZjYTY1MDBmZTRiODUwYzNmMWMwMmU4MDFjYWYzYTI0NDY0NjE0ZTQyODAxNjE1YjhmZmFhMDdhYzgyNTE0OTNmZmRhN2RlNWRkZjMzNjg4ODBjMmI5NWIwMzBmNDFmOGYxNTA2NmFkZDA3MWE2NmNmNjBlNWY0NmYzYTIzMGQzOTdiNjUyOTYzYTIxYTUzZg
+  [11]: https://gchq.github.io/CyberChef/#recipe=XOR(%7B'option':'Hex','string':'3a'%7D,'Standard',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4
+  [12]: https://gchq.github.io/CyberChef/#recipe=Magic(3,false,false)&input=V1VhZ3dzaWFlNm1QOGdOdENDTFVGcENwQ0IyNlJtQkRvREQ4UGFjZEFtekF6QlZqa0syUXN0RlhhS2hwQzZpVVM3UkhxWHJKdEZpc29SU2dvSjR3aGptMWFybTg2NHFhTnE0UmNmVW1MSHJjc0FhWmM1VFhDWWlmTmRnUzgzZ0RlZWpHWDQ2Z2FpTXl1QlY2RXNrSHQxc2NnSjg4eDJ0TlNvdFFEd2JHWTFtbUNvYjJBUkdGdkNLWU5xaU45aXBNcTFaVTFtZ2tkYk51R2NiNzZhUnRZV2hDR1VjOGc5M1VKdWRoYjhodHNoZVpud1RwZ3FoeDgzU1ZKU1pYTVhVakpUMnptcEM3dVhXdHVtcW9rYmRTaTg4WXRrV0RBYzFUb291aDJvSDRENGRkbU5LSldVRHBNd21uZ1VtSzE0eHdtb21jY1BRRTloTTE3MkFQblNxd3hkS1ExNzJSa2NBc3lzbm1qNWdHdFJtVk5OaDJzMzU5d3I2bVMyUVJQ

+ 24 - 0
babel.config.js

@@ -0,0 +1,24 @@
+module.exports = function(api) {
+    api.cache.forever();
+
+    return {
+        "presets": [
+            ["@babel/preset-env", {
+                "targets": {
+                    "chrome": 40,
+                    "firefox": 35,
+                    "edge": 14,
+                    "node": "6.5"
+                },
+                "modules": false,
+                "useBuiltIns": "entry"
+            }]
+        ],
+        "plugins": [
+            "babel-plugin-syntax-dynamic-import",
+            ["babel-plugin-transform-builtin-extend", {
+                "globals": ["Error"]
+            }]
+        ]
+    };
+};

BIN
docs/favicon.ico


+ 1 - 1
docs/jsdoc.conf.json

@@ -19,7 +19,7 @@
         "outputSourcePath": true,
         "dateFormat": "ddd MMM Do YYYY",
         "sort": false,
-        "logoFile": "../build/prod/images/cyberchef-32x32.png",
+        "logoFile": "cyberchef-32x32.png",
         "cleverLinks": false,
         "monospaceLinks": false,
         "protocol": "html://",

+ 34 - 0
nightwatch.json

@@ -0,0 +1,34 @@
+{
+  "src_folders": ["tests/browser"],
+  "output_folder": "tests/browser/output",
+
+  "test_settings": {
+
+    "default": {
+      "launch_url": "http://localhost:8080",
+      "webdriver": {
+        "start_process": true,
+        "server_path": "./node_modules/.bin/chromedriver",
+        "port": 9515,
+        "log_path": false
+      },
+      "desiredCapabilities": {
+        "browserName": "chrome"
+      }
+    },
+
+    "dev": {
+      "launch_url": "http://localhost:8080"
+    },
+
+    "prod": {
+      "launch_url": "http://localhost:8000/index.html"
+    },
+
+    "inline": {
+      "launch_url": "http://localhost:8000/cyberchef.htm"
+    }
+
+  }
+}
+

+ 13999 - 0
package-lock.json

@@ -0,0 +1,13999 @@
+{
+  "name": "cyberchef",
+  "version": "8.24.2",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@babel/code-frame": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
+      "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.0.0"
+      }
+    },
+    "@babel/core": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.2.2.tgz",
+      "integrity": "sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/generator": "^7.2.2",
+        "@babel/helpers": "^7.2.0",
+        "@babel/parser": "^7.2.2",
+        "@babel/template": "^7.2.2",
+        "@babel/traverse": "^7.2.2",
+        "@babel/types": "^7.2.2",
+        "convert-source-map": "^1.1.0",
+        "debug": "^4.1.0",
+        "json5": "^2.1.0",
+        "lodash": "^4.17.10",
+        "resolve": "^1.3.2",
+        "semver": "^5.4.1",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/generator": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz",
+      "integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.2.2",
+        "jsesc": "^2.5.1",
+        "lodash": "^4.17.10",
+        "source-map": "^0.5.0",
+        "trim-right": "^1.0.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz",
+      "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz",
+      "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-explode-assignable-expression": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-call-delegate": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz",
+      "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.0.0",
+        "@babel/traverse": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-define-map": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz",
+      "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.1.0",
+        "@babel/types": "^7.0.0",
+        "lodash": "^4.17.10"
+      }
+    },
+    "@babel/helper-explode-assignable-expression": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz",
+      "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==",
+      "dev": true,
+      "requires": {
+        "@babel/traverse": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
+      "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.0.0",
+        "@babel/template": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
+      "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz",
+      "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-member-expression-to-functions": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz",
+      "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz",
+      "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz",
+      "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/helper-simple-access": "^7.1.0",
+        "@babel/helper-split-export-declaration": "^7.0.0",
+        "@babel/template": "^7.2.2",
+        "@babel/types": "^7.2.2",
+        "lodash": "^4.17.10"
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz",
+      "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-plugin-utils": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz",
+      "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==",
+      "dev": true
+    },
+    "@babel/helper-regex": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz",
+      "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.10"
+      }
+    },
+    "@babel/helper-remap-async-to-generator": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz",
+      "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.0.0",
+        "@babel/helper-wrap-function": "^7.1.0",
+        "@babel/template": "^7.1.0",
+        "@babel/traverse": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz",
+      "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-member-expression-to-functions": "^7.0.0",
+        "@babel/helper-optimise-call-expression": "^7.0.0",
+        "@babel/traverse": "^7.2.3",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz",
+      "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
+      "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "@babel/helper-wrap-function": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz",
+      "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.1.0",
+        "@babel/template": "^7.1.0",
+        "@babel/traverse": "^7.1.0",
+        "@babel/types": "^7.2.0"
+      }
+    },
+    "@babel/helpers": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.2.0.tgz",
+      "integrity": "sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "^7.1.2",
+        "@babel/traverse": "^7.1.5",
+        "@babel/types": "^7.2.0"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
+      "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.0",
+        "esutils": "^2.0.2",
+        "js-tokens": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "js-tokens": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "@babel/parser": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.3.tgz",
+      "integrity": "sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==",
+      "dev": true
+    },
+    "@babel/plugin-proposal-async-generator-functions": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz",
+      "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-remap-async-to-generator": "^7.1.0",
+        "@babel/plugin-syntax-async-generators": "^7.2.0"
+      }
+    },
+    "@babel/plugin-proposal-json-strings": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz",
+      "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-syntax-json-strings": "^7.2.0"
+      }
+    },
+    "@babel/plugin-proposal-object-rest-spread": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz",
+      "integrity": "sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-syntax-object-rest-spread": "^7.2.0"
+      }
+    },
+    "@babel/plugin-proposal-optional-catch-binding": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz",
+      "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.2.0"
+      }
+    },
+    "@babel/plugin-proposal-unicode-property-regex": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz",
+      "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-regex": "^7.0.0",
+        "regexpu-core": "^4.2.0"
+      }
+    },
+    "@babel/plugin-syntax-async-generators": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz",
+      "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-syntax-json-strings": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz",
+      "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-syntax-object-rest-spread": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz",
+      "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-catch-binding": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz",
+      "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-arrow-functions": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz",
+      "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-async-to-generator": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz",
+      "integrity": "sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-remap-async-to-generator": "^7.1.0"
+      }
+    },
+    "@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz",
+      "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-block-scoping": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz",
+      "integrity": "sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "lodash": "^4.17.10"
+      }
+    },
+    "@babel/plugin-transform-classes": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz",
+      "integrity": "sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.0.0",
+        "@babel/helper-define-map": "^7.1.0",
+        "@babel/helper-function-name": "^7.1.0",
+        "@babel/helper-optimise-call-expression": "^7.0.0",
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-replace-supers": "^7.1.0",
+        "@babel/helper-split-export-declaration": "^7.0.0",
+        "globals": "^11.1.0"
+      },
+      "dependencies": {
+        "globals": {
+          "version": "11.9.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz",
+          "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/plugin-transform-computed-properties": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz",
+      "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-destructuring": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz",
+      "integrity": "sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-dotall-regex": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz",
+      "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-regex": "^7.0.0",
+        "regexpu-core": "^4.1.3"
+      }
+    },
+    "@babel/plugin-transform-duplicate-keys": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz",
+      "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz",
+      "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0",
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-for-of": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz",
+      "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-function-name": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz",
+      "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "^7.1.0",
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-literals": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz",
+      "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-modules-amd": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz",
+      "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.1.0",
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-modules-commonjs": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz",
+      "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.1.0",
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-simple-access": "^7.1.0"
+      }
+    },
+    "@babel/plugin-transform-modules-systemjs": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz",
+      "integrity": "sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.0.0",
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-modules-umd": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz",
+      "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "^7.1.0",
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-new-target": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz",
+      "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-object-super": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz",
+      "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-replace-supers": "^7.1.0"
+      }
+    },
+    "@babel/plugin-transform-parameters": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz",
+      "integrity": "sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-call-delegate": "^7.1.0",
+        "@babel/helper-get-function-arity": "^7.0.0",
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-regenerator": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz",
+      "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "^0.13.3"
+      }
+    },
+    "@babel/plugin-transform-shorthand-properties": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz",
+      "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-spread": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz",
+      "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-sticky-regex": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz",
+      "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-regex": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-template-literals": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz",
+      "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.0.0",
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-typeof-symbol": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz",
+      "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
+    "@babel/plugin-transform-unicode-regex": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz",
+      "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-regex": "^7.0.0",
+        "regexpu-core": "^4.1.3"
+      }
+    },
+    "@babel/polyfill": {
+      "version": "7.2.5",
+      "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.2.5.tgz",
+      "integrity": "sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug==",
+      "requires": {
+        "core-js": "^2.5.7",
+        "regenerator-runtime": "^0.12.0"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.12.1",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
+          "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
+        }
+      }
+    },
+    "@babel/preset-env": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.2.3.tgz",
+      "integrity": "sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/plugin-proposal-async-generator-functions": "^7.2.0",
+        "@babel/plugin-proposal-json-strings": "^7.2.0",
+        "@babel/plugin-proposal-object-rest-spread": "^7.2.0",
+        "@babel/plugin-proposal-optional-catch-binding": "^7.2.0",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.2.0",
+        "@babel/plugin-syntax-async-generators": "^7.2.0",
+        "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.2.0",
+        "@babel/plugin-transform-arrow-functions": "^7.2.0",
+        "@babel/plugin-transform-async-to-generator": "^7.2.0",
+        "@babel/plugin-transform-block-scoped-functions": "^7.2.0",
+        "@babel/plugin-transform-block-scoping": "^7.2.0",
+        "@babel/plugin-transform-classes": "^7.2.0",
+        "@babel/plugin-transform-computed-properties": "^7.2.0",
+        "@babel/plugin-transform-destructuring": "^7.2.0",
+        "@babel/plugin-transform-dotall-regex": "^7.2.0",
+        "@babel/plugin-transform-duplicate-keys": "^7.2.0",
+        "@babel/plugin-transform-exponentiation-operator": "^7.2.0",
+        "@babel/plugin-transform-for-of": "^7.2.0",
+        "@babel/plugin-transform-function-name": "^7.2.0",
+        "@babel/plugin-transform-literals": "^7.2.0",
+        "@babel/plugin-transform-modules-amd": "^7.2.0",
+        "@babel/plugin-transform-modules-commonjs": "^7.2.0",
+        "@babel/plugin-transform-modules-systemjs": "^7.2.0",
+        "@babel/plugin-transform-modules-umd": "^7.2.0",
+        "@babel/plugin-transform-new-target": "^7.0.0",
+        "@babel/plugin-transform-object-super": "^7.2.0",
+        "@babel/plugin-transform-parameters": "^7.2.0",
+        "@babel/plugin-transform-regenerator": "^7.0.0",
+        "@babel/plugin-transform-shorthand-properties": "^7.2.0",
+        "@babel/plugin-transform-spread": "^7.2.0",
+        "@babel/plugin-transform-sticky-regex": "^7.2.0",
+        "@babel/plugin-transform-template-literals": "^7.2.0",
+        "@babel/plugin-transform-typeof-symbol": "^7.2.0",
+        "@babel/plugin-transform-unicode-regex": "^7.2.0",
+        "browserslist": "^4.3.4",
+        "invariant": "^2.2.2",
+        "js-levenshtein": "^1.1.3",
+        "semver": "^5.3.0"
+      }
+    },
+    "@babel/runtime-corejs2": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.3.1.tgz",
+      "integrity": "sha512-YpO13776h3e6Wy8dl2J8T9Qwlvopr+b4trCEhHE+yek6yIqV8sx6g3KozdHMbXeBpjosbPi+Ii5Z7X9oXFHUKA==",
+      "requires": {
+        "core-js": "^2.5.7",
+        "regenerator-runtime": "^0.12.0"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.12.1",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
+          "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
+        }
+      }
+    },
+    "@babel/template": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz",
+      "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/parser": "^7.2.2",
+        "@babel/types": "^7.2.2"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz",
+      "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/generator": "^7.2.2",
+        "@babel/helper-function-name": "^7.1.0",
+        "@babel/helper-split-export-declaration": "^7.0.0",
+        "@babel/parser": "^7.2.3",
+        "@babel/types": "^7.2.2",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0",
+        "lodash": "^4.17.10"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "globals": {
+          "version": "11.9.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz",
+          "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/types": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz",
+      "integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.10",
+        "to-fast-properties": "^2.0.0"
+      },
+      "dependencies": {
+        "to-fast-properties": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+          "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+          "dev": true
+        }
+      }
+    },
+    "@jimp/bmp": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.6.0.tgz",
+      "integrity": "sha512-zZOcVT1zK/1QL5a7qirkzPPgDKB1ianER7pBdpR2J71vx/g8MnrPbL3h/jEVPxjdci2Hph/VWhc/oLBtTbqO8w==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "bmp-js": "^0.1.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/core": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.6.0.tgz",
+      "integrity": "sha512-ngAkyCLtX7buc2QyFy0ql/j4R2wGYQVsVhW2G3Y0GVAAklRIFIUYpyNKrqs228xA8f2O6XStbDStFlYkt7uNeg==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "any-base": "^1.1.0",
+        "buffer": "^5.2.0",
+        "core-js": "^2.5.7",
+        "exif-parser": "^0.1.12",
+        "file-type": "^9.0.0",
+        "load-bmfont": "^1.3.1",
+        "mkdirp": "0.5.1",
+        "phin": "^2.9.1",
+        "pixelmatch": "^4.0.2",
+        "tinycolor2": "^1.4.1"
+      },
+      "dependencies": {
+        "buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+          "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+          "requires": {
+            "base64-js": "^1.0.2",
+            "ieee754": "^1.1.4"
+          }
+        }
+      }
+    },
+    "@jimp/custom": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.6.0.tgz",
+      "integrity": "sha512-+YZIWhf03Rfbi+VPbHomKInu3tcntF/aij/JrIJd1QZq13f8m3mRNxakXupiL18KH0C8BPNDk8RiwFX+HaOw3A==",
+      "requires": {
+        "@jimp/core": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/gif": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.6.0.tgz",
+      "integrity": "sha512-aWQ02P0ymTN1eh0BVsY+84wMdb/QeiVpCNQZl9y50cRnpuMM8TTmF/ZdCEBDiTRFcwXzHsqBXcLwEcYp3X2lTw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7",
+        "omggif": "^1.0.9"
+      }
+    },
+    "@jimp/jpeg": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.6.0.tgz",
+      "integrity": "sha512-quYb+lM4h57jQvr2q9dEIkc0laTljws4dunIdFhJRfa5UlNL5mHInk8h5MxyALo0mZdT07TAcxiDHw5QXZ28JQ==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7",
+        "jpeg-js": "^0.3.4"
+      }
+    },
+    "@jimp/plugin-blit": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.6.0.tgz",
+      "integrity": "sha512-LjiCa+8OT2fgmvBpZt0ogurg/eu5kB8ZFWDRwHPcf8i+058sZC20dar/qrjVd5Knssq4ynjb5oAHsGuJq16Rqw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-blur": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.6.0.tgz",
+      "integrity": "sha512-/vjGcEiHda6OLTCYqXPFkfSTbL+RatZoGcp1vewcWqChUccn9QVINTlxB7nEI/3Nb/i7KdhOPNEQh1k6q6QXsw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-color": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.6.0.tgz",
+      "integrity": "sha512-mvDeAwN8ZpDkOaABMJ0w9zUzo9OOtu1qvvPkSirXDTMiXt1nsbfz8BoeoD7nU2MFhQj5MiGjH65UDnsH5ZzYuw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7",
+        "tinycolor2": "^1.4.1"
+      }
+    },
+    "@jimp/plugin-contain": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.6.0.tgz",
+      "integrity": "sha512-gPHnoQkDztMbvnTVo01BaMoM/hhDJdeJ7FRToD4p4Qvdor4V0I6NXtjOeUPXfD94miTgh/UTyJDqeG4GZzi4sA==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-cover": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.6.0.tgz",
+      "integrity": "sha512-iv9lA2v3qv+x3eaTThtyzFg+hO8/pSnM8NBymC5OlpSJnR54aWi7BVFXLJAF27T4EZyXko432PVul2IdY3BEPw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-crop": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.6.0.tgz",
+      "integrity": "sha512-YftdmFZ2YnZDYyBulkStCt2MZbKKfbjytkE+6i3Djk2b/Rfryg5xjgzVnAumCRQJhVPukexrnc2V7KKbEgx7mQ==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-displace": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.6.0.tgz",
+      "integrity": "sha512-kkva5Fy3r7J7QmiqYQ5c9NeUKKkN7+KSfCGsZ6tkRHK4REMIXhQO/OnJN8XG6RReV29O6QykdyeTXDiHUDiROw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-dither": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.6.0.tgz",
+      "integrity": "sha512-ILSG7bl3SOqmcIa9C4nBvs0h0E0ObnMbeKWUZiNuz6i0OAlbxryiIfU4j0UVQD5XqT9ksC5mviVNrvOMw4SZLw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-flip": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.6.0.tgz",
+      "integrity": "sha512-MXGGwABjERvfqVadEzJuVAmbsEQfjxXD0O/mMBegU1Qh7/JmnKAVplQCnojsMPxUdao/FKZjQqOnB/j4LLJtOQ==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-gaussian": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.0.tgz",
+      "integrity": "sha512-RUsBCyj6Ukxgn/TU8v6c6WRbSFqKM0iknLVqDkKIuiOyJB7ougv66fqomh/i/h3ihIkEnf50BuO0c3ovrczfvw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-invert": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.6.0.tgz",
+      "integrity": "sha512-zTCqK8el6eqcNKAxw0y57gHBFgxygI5iM8dQDPyqsvVWO71i8XII7ubnJhEvPPN7vhIKlOSnS9XXglezvJoX4Q==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-mask": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.6.0.tgz",
+      "integrity": "sha512-zkZVqAA7lxWhkn5EbPjBQ6tPluYIGfLMSX4kD1gksj+MVJJnVAd459AVuEXCvkUvv4wG5AlH8m6ve5NZj9vvxw==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-normalize": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.6.0.tgz",
+      "integrity": "sha512-7bNGT+S0rw9gvmxpkNsA19JSqBZYFrAn9QhEmoN4HIimdKtJaoLJh/GnxrPuOBLuv1IPJntoTOOWvOmfrQ6/ww==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-print": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.6.0.tgz",
+      "integrity": "sha512-kXNHYo7bGQiMZkUqhCvm6OomjJtZnLGs7cgXp9qsCfPcDBLLW+X3oxnoLaePQMlpQt6hX/lzFnNaWKv/KB1jlA==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7",
+        "load-bmfont": "^1.4.0"
+      }
+    },
+    "@jimp/plugin-resize": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.6.0.tgz",
+      "integrity": "sha512-m0AA/mPkJG++RuftBFDUMRenqgIN/uSh88Kqs33VURYaabApni4ML3QslE1TCJtl2Lnu1eosxYlbzODjHx49eg==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-rotate": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.6.0.tgz",
+      "integrity": "sha512-1QGlIisyxs2HNLuynq/ETc4h7E6At3yR+IYAhG9U4KONG4RqlIy0giyDhnfEZaiqOE+O7f+0Z7zN6GoSHmQjzg==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugin-scale": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.6.0.tgz",
+      "integrity": "sha512-le/ttYwYioNPRoMlMaoJMCTv+m8d1v0peo/3J8E6Rf9ok7Bw3agkvjL9ILnsmr8jXj1YLrBSPKRs5nJ6ziM/qA==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "@jimp/plugins": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.6.0.tgz",
+      "integrity": "sha512-9+znfBJM1B31kvw+IcQFnAuDntQhwca/SONFnKOSZ8BNiQdiuTNbXHFxOo3tvdv1ngtB+LkkiTgK+QoF358b8g==",
+      "requires": {
+        "@jimp/plugin-blit": "^0.6.0",
+        "@jimp/plugin-blur": "^0.6.0",
+        "@jimp/plugin-color": "^0.6.0",
+        "@jimp/plugin-contain": "^0.6.0",
+        "@jimp/plugin-cover": "^0.6.0",
+        "@jimp/plugin-crop": "^0.6.0",
+        "@jimp/plugin-displace": "^0.6.0",
+        "@jimp/plugin-dither": "^0.6.0",
+        "@jimp/plugin-flip": "^0.6.0",
+        "@jimp/plugin-gaussian": "^0.6.0",
+        "@jimp/plugin-invert": "^0.6.0",
+        "@jimp/plugin-mask": "^0.6.0",
+        "@jimp/plugin-normalize": "^0.6.0",
+        "@jimp/plugin-print": "^0.6.0",
+        "@jimp/plugin-resize": "^0.6.0",
+        "@jimp/plugin-rotate": "^0.6.0",
+        "@jimp/plugin-scale": "^0.6.0",
+        "core-js": "^2.5.7",
+        "timm": "^1.6.1"
+      }
+    },
+    "@jimp/png": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.6.0.tgz",
+      "integrity": "sha512-DBtMyQyrJxuKI7/1dVqLek+rCMM8U6BSOTHgo05wU7lhJKTB6fn2tbYfsnHQKzd9ld1M2qKuC+O1GTVdB2yl6w==",
+      "requires": {
+        "@jimp/utils": "^0.6.0",
+        "core-js": "^2.5.7",
+        "pngjs": "^3.3.3"
+      }
+    },
+    "@jimp/tiff": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.6.0.tgz",
+      "integrity": "sha512-PV95CquEsolFziq0zZrAEJIzZSKwMK89TvkOXTPDi/xesgdXGC2rtG1IZFpC9L4UX5hi/M5GaeJa49xULX6Nqw==",
+      "requires": {
+        "core-js": "^2.5.7",
+        "utif": "^2.0.1"
+      }
+    },
+    "@jimp/types": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.6.0.tgz",
+      "integrity": "sha512-j4tm82huEWpLrwave/2NYnMTY6us/6K9Js6Vd/CHoM/ki8M71tMXEVzc8tly92wtnEzQ9+FEk0Ue6pYo68m/5A==",
+      "requires": {
+        "@jimp/bmp": "^0.6.0",
+        "@jimp/gif": "^0.6.0",
+        "@jimp/jpeg": "^0.6.0",
+        "@jimp/png": "^0.6.0",
+        "@jimp/tiff": "^0.6.0",
+        "core-js": "^2.5.7",
+        "timm": "^1.6.1"
+      }
+    },
+    "@jimp/utils": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.6.0.tgz",
+      "integrity": "sha512-z5iYEfqc45vlYweROneNkjv32en6jS7lPL/eMLIvaEcQAHaoza20Dw8fUoJ0Ht9S92kR74xeTunAZq+gK2w67Q==",
+      "requires": {
+        "core-js": "^2.5.7"
+      }
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz",
+      "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.7.11",
+        "@webassemblyjs/helper-wasm-bytecode": "1.7.11",
+        "@webassemblyjs/wast-parser": "1.7.11"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz",
+      "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz",
+      "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz",
+      "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz",
+      "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.7.11"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz",
+      "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz",
+      "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz",
+      "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz",
+      "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/helper-buffer": "1.7.11",
+        "@webassemblyjs/helper-wasm-bytecode": "1.7.11",
+        "@webassemblyjs/wasm-gen": "1.7.11"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz",
+      "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz",
+      "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.1"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz",
+      "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz",
+      "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/helper-buffer": "1.7.11",
+        "@webassemblyjs/helper-wasm-bytecode": "1.7.11",
+        "@webassemblyjs/helper-wasm-section": "1.7.11",
+        "@webassemblyjs/wasm-gen": "1.7.11",
+        "@webassemblyjs/wasm-opt": "1.7.11",
+        "@webassemblyjs/wasm-parser": "1.7.11",
+        "@webassemblyjs/wast-printer": "1.7.11"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz",
+      "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/helper-wasm-bytecode": "1.7.11",
+        "@webassemblyjs/ieee754": "1.7.11",
+        "@webassemblyjs/leb128": "1.7.11",
+        "@webassemblyjs/utf8": "1.7.11"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz",
+      "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/helper-buffer": "1.7.11",
+        "@webassemblyjs/wasm-gen": "1.7.11",
+        "@webassemblyjs/wasm-parser": "1.7.11"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz",
+      "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/helper-api-error": "1.7.11",
+        "@webassemblyjs/helper-wasm-bytecode": "1.7.11",
+        "@webassemblyjs/ieee754": "1.7.11",
+        "@webassemblyjs/leb128": "1.7.11",
+        "@webassemblyjs/utf8": "1.7.11"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz",
+      "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/floating-point-hex-parser": "1.7.11",
+        "@webassemblyjs/helper-api-error": "1.7.11",
+        "@webassemblyjs/helper-code-frame": "1.7.11",
+        "@webassemblyjs/helper-fsm": "1.7.11",
+        "@xtuc/long": "4.2.1"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz",
+      "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/wast-parser": "1.7.11",
+        "@xtuc/long": "4.2.1"
+      }
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz",
+      "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==",
+      "dev": true
+    },
+    "JSONSelect": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
+      "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
+    },
+    "abab": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz",
+      "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==",
+      "dev": true
+    },
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+      "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+      "dev": true,
+      "requires": {
+        "mime-types": "~2.1.18",
+        "negotiator": "0.6.1"
+      }
+    },
+    "access-sniff": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/access-sniff/-/access-sniff-3.2.0.tgz",
+      "integrity": "sha512-HLvH8e5g312urx6ZRo+nxSHjhVHEcuUxbpjFaFQ1LZOtN19L0CSb5ppwxtxy0QZ05zYAcWmXH6lVurdb+mGuUw==",
+      "dev": true,
+      "requires": {
+        "axios": "^0.18.0",
+        "bluebird": "^3.5.1",
+        "chalk": "^2.3.1",
+        "commander": "^2.14.1",
+        "glob": "^7.1.2",
+        "html_codesniffer": "^2.1.1",
+        "jsdom": "^11.6.2",
+        "mkdirp": "^0.5.1",
+        "phantomjs-prebuilt": "^2.1.16",
+        "rc": "^1.2.5",
+        "underscore": "^1.8.3",
+        "unixify": "^1.0.0",
+        "validator": "^9.4.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "underscore": {
+          "version": "1.9.1",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
+          "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==",
+          "dev": true
+        }
+      }
+    },
+    "acorn": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz",
+      "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==",
+      "dev": true
+    },
+    "acorn-dynamic-import": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz",
+      "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==",
+      "dev": true,
+      "requires": {
+        "acorn": "^5.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.7.3",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+          "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+          "dev": true
+        }
+      }
+    },
+    "acorn-globals": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz",
+      "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==",
+      "dev": true,
+      "requires": {
+        "acorn": "^6.0.1",
+        "acorn-walk": "^6.0.1"
+      }
+    },
+    "acorn-jsx": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
+      "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
+      "dev": true
+    },
+    "acorn-walk": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
+      "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
+      "dev": true
+    },
+    "agent-base": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
+      "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
+      "dev": true,
+      "requires": {
+        "es6-promisify": "^5.0.0"
+      },
+      "dependencies": {
+        "es6-promisify": {
+          "version": "5.0.0",
+          "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+          "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+          "dev": true,
+          "requires": {
+            "es6-promise": "^4.0.3"
+          }
+        }
+      }
+    },
+    "ajv": {
+      "version": "6.5.5",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz",
+      "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^2.0.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-errors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.0.tgz",
+      "integrity": "sha1-7PAh+hCP0X37Xms4Py3SM+Mf/Fk=",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+      "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
+      "dev": true
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+    },
+    "ansi-colors": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+      "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+      "dev": true
+    },
+    "ansi-escapes": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+      "dev": true
+    },
+    "ansi-html": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+    },
+    "any-base": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
+      "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
+    },
+    "anymatch": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+      "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+      "dev": true,
+      "requires": {
+        "micromatch": "^3.1.4",
+        "normalize-path": "^2.1.1"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
+    "are-we-there-yet": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+      "dev": true,
+      "requires": {
+        "delegates": "^1.0.0",
+        "readable-stream": "^2.0.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-differ": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
+      "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
+      "dev": true
+    },
+    "array-equal": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+      "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "dev": true
+    },
+    "array-flatten": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+      "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "^1.0.1"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "arrive": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/arrive/-/arrive-2.4.1.tgz",
+      "integrity": "sha1-VkyH8gvAm4DeeBEk2UMWlQBLgCA="
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "assert": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+      "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+      "dev": true,
+      "requires": {
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "ast-types": {
+      "version": "0.11.7",
+      "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.7.tgz",
+      "integrity": "sha512-2mP3TwtkY/aTv5X3ZsMpNAbOnyoC/aMJwJSoaELPkHId0nSQgFcnU4dRW3isxiz7+zBexk0ym3WNVjMiQBnJSw==",
+      "dev": true
+    },
+    "astral-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+      "dev": true
+    },
+    "async": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+      "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.10"
+      }
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "async-foreach": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+      "dev": true
+    },
+    "async-limiter": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "9.4.3",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.3.tgz",
+      "integrity": "sha512-/XSnzDepRkAU//xLcXA/lUWxpsBuw0WiriAHOqnxkuCtzLhaz+fL4it4gp20BQ8n5SyLzK/FOc7A0+u/rti2FQ==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.3.6",
+        "caniuse-lite": "^1.0.30000921",
+        "normalize-range": "^0.1.2",
+        "num2fraction": "^1.2.2",
+        "postcss": "^7.0.6",
+        "postcss-value-parser": "^3.3.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "postcss": {
+          "version": "7.0.7",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
+          "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.1",
+            "source-map": "^0.6.1",
+            "supports-color": "^5.5.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+      "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.18.0",
+      "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
+      "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
+      "dev": true,
+      "requires": {
+        "follow-redirects": "^1.3.0",
+        "is-buffer": "^1.1.5"
+      }
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "requires": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      }
+    },
+    "babel-eslint": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.1.tgz",
+      "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/parser": "^7.0.0",
+        "@babel/traverse": "^7.0.0",
+        "@babel/types": "^7.0.0",
+        "eslint-scope": "3.7.1",
+        "eslint-visitor-keys": "^1.0.0"
+      },
+      "dependencies": {
+        "eslint-scope": {
+          "version": "3.7.1",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+          "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+          "dev": true,
+          "requires": {
+            "esrecurse": "^4.1.0",
+            "estraverse": "^4.1.1"
+          }
+        }
+      }
+    },
+    "babel-loader": {
+      "version": "8.0.4",
+      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.4.tgz",
+      "integrity": "sha512-fhBhNkUToJcW9nV46v8w87AJOwAJDz84c1CL57n3Stj73FANM/b9TbCUK4YhdOwEyZ+OxhYpdeZDNzSI29Firw==",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "^1.0.0",
+        "loader-utils": "^1.0.2",
+        "mkdirp": "^0.5.1",
+        "util.promisify": "^1.0.0"
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "requires": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "babel-plugin-syntax-dynamic-import": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
+      "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
+      "dev": true
+    },
+    "babel-plugin-transform-builtin-extend": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-builtin-extend/-/babel-plugin-transform-builtin-extend-1.1.2.tgz",
+      "integrity": "sha1-Xpb+z1i4+h7XTvytiEdbKvPJEW4=",
+      "requires": {
+        "babel-runtime": "^6.2.0",
+        "babel-template": "^6.3.0"
+      }
+    },
+    "babel-polyfill": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+      "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "core-js": "^2.5.0",
+        "regenerator-runtime": "^0.10.5"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.10.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+          "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg="
+        }
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "requires": {
+        "babel-code-frame": "^6.26.0",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "debug": "^2.6.8",
+        "globals": "^9.18.0",
+        "invariant": "^2.2.2",
+        "lodash": "^4.17.4"
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.4",
+        "to-fast-properties": "^1.0.3"
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base64-js": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+      "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
+    },
+    "basic-auth": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+      "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.2"
+      }
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      },
+      "dependencies": {
+        "tweetnacl": {
+          "version": "0.14.5",
+          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+          "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+          "dev": true
+        }
+      }
+    },
+    "bcryptjs": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+      "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
+    },
+    "bfj": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.1.tgz",
+      "integrity": "sha512-+GUNvzHR4nRyGybQc2WpNJL4MJazMuvf92ueIyA0bIkPRwhhQu3IfZQ2PSoVPpCBJfmoSdOxu5rnotfFLlvYRQ==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.1",
+        "check-types": "^7.3.0",
+        "hoopy": "^0.1.2",
+        "tryer": "^1.0.0"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true
+    },
+    "bignumber.js": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.0.2.tgz",
+      "integrity": "sha512-EiuvFrnbv0jFixEQ9f58jo7X0qI2lNGIr/MxntmVzQc5JUweDSh8y8hbTCAomFtqwUPIOWcLXP0VEOSZTG7FFw=="
+    },
+    "binary-extensions": {
+      "version": "1.12.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz",
+      "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==",
+      "dev": true
+    },
+    "block-stream": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.0"
+      }
+    },
+    "bluebird": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
+      "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==",
+      "dev": true
+    },
+    "bmp-js": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
+      "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
+    },
+    "bn": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/bn/-/bn-1.0.1.tgz",
+      "integrity": "sha1-oVOCXmsessLbdyYUmwR6B84KO7M="
+    },
+    "bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "body": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz",
+      "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=",
+      "dev": true,
+      "requires": {
+        "continuable-cache": "^0.3.1",
+        "error": "^7.0.0",
+        "raw-body": "~1.1.0",
+        "safe-json-parse": "~1.0.1"
+      }
+    },
+    "body-parser": {
+      "version": "1.18.3",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
+      "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
+      "dev": true,
+      "requires": {
+        "bytes": "3.0.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "~1.6.3",
+        "iconv-lite": "0.4.23",
+        "on-finished": "~2.3.0",
+        "qs": "6.5.2",
+        "raw-body": "2.3.3",
+        "type-is": "~1.6.16"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+          "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+          "dev": true
+        },
+        "iconv-lite": {
+          "version": "0.4.23",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+          "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+          "dev": true,
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        },
+        "raw-body": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
+          "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
+          "dev": true,
+          "requires": {
+            "bytes": "3.0.0",
+            "http-errors": "1.6.3",
+            "iconv-lite": "0.4.23",
+            "unpipe": "1.0.0"
+          }
+        }
+      }
+    },
+    "bonjour": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+      "dev": true,
+      "requires": {
+        "array-flatten": "^2.1.0",
+        "deep-equal": "^1.0.1",
+        "dns-equal": "^1.0.0",
+        "dns-txt": "^2.0.2",
+        "multicast-dns": "^6.0.1",
+        "multicast-dns-service-types": "^1.1.0"
+      }
+    },
+    "boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
+    },
+    "bootstrap": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.2.1.tgz",
+      "integrity": "sha512-tt/7vIv3Gm2mnd/WeDx36nfGGHleil0Wg8IeB7eMrVkY0fZ5iTaBisSh8oNANc2IBsCc6vCgCNTIM/IEN0+50Q==",
+      "dev": true
+    },
+    "bootstrap-colorpicker": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmjs.org/bootstrap-colorpicker/-/bootstrap-colorpicker-2.5.3.tgz",
+      "integrity": "sha512-xdllX8LSMvKULs3b8JrgRXTvyvjkSMHHHVuHjjN5FNMqr6kRe5NPiMHFmeAFjlgDF73MspikudLuEwR28LbzLw==",
+      "requires": {
+        "jquery": ">=1.10"
+      }
+    },
+    "bootstrap-material-design": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/bootstrap-material-design/-/bootstrap-material-design-4.1.1.tgz",
+      "integrity": "sha1-h0M9sL9k1qCvsPX6qoYGE0ydJtI="
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-process-hrtime": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
+      "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==",
+      "dev": true
+    },
+    "browser-stdout": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+      "dev": true,
+      "optional": true
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "browserify-sign": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+      "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.1",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.2",
+        "elliptic": "^6.0.0",
+        "inherits": "^2.0.1",
+        "parse-asn1": "^5.0.0"
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "browserslist": {
+      "version": "4.3.6",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.3.6.tgz",
+      "integrity": "sha512-kMGKs4BTzRWviZ8yru18xBpx+CyHG9eqgRbj9XbE3IMgtczf4aiA0Y1YCpVdvUieKGZ03kolSPXqTcscBCb9qw==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30000921",
+        "electron-to-chromium": "^1.3.92",
+        "node-releases": "^1.1.1"
+      }
+    },
+    "bson": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/bson/-/bson-4.0.1.tgz",
+      "integrity": "sha512-Q+E5edAc2DnSb77xcBJga0iJDyZlhkKRhWxKdPJcT3UK6nC6BtmMJGpkt+99bGht3HIhXHu7mxi5FLBgQAj5MA==",
+      "requires": {
+        "buffer": "^5.1.0",
+        "long": "^4.0.0"
+      },
+      "dependencies": {
+        "buffer": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+          "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+          "requires": {
+            "base64-js": "^1.0.2",
+            "ieee754": "^1.1.4"
+          }
+        }
+      }
+    },
+    "buffer": {
+      "version": "4.9.1",
+      "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+      "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        }
+      }
+    },
+    "buffer-equal": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
+      "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs="
+    },
+    "buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "buffer-indexof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+      "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
+      "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=",
+      "dev": true
+    },
+    "bzip-deflate": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/bzip-deflate/-/bzip-deflate-1.0.0.tgz",
+      "integrity": "sha1-sC2wB+83vrzCk4Skssb08PTHlsk="
+    },
+    "cacache": {
+      "version": "11.3.2",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz",
+      "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.3",
+        "chownr": "^1.1.1",
+        "figgy-pudding": "^3.5.1",
+        "glob": "^7.1.3",
+        "graceful-fs": "^4.1.15",
+        "lru-cache": "^5.1.1",
+        "mississippi": "^3.0.0",
+        "mkdirp": "^0.5.1",
+        "move-concurrently": "^1.0.1",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^2.6.2",
+        "ssri": "^6.0.1",
+        "unique-filename": "^1.1.1",
+        "y18n": "^4.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+          "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+          "dev": true,
+          "requires": {
+            "yallist": "^3.0.2"
+          }
+        },
+        "y18n": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+          "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+          "dev": true
+        },
+        "yallist": {
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
+          "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
+          "dev": true
+        }
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      }
+    },
+    "callsites": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz",
+      "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==",
+      "dev": true
+    },
+    "camel-case": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
+      "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
+      "dev": true,
+      "requires": {
+        "no-case": "^2.2.0",
+        "upper-case": "^1.1.1"
+      }
+    },
+    "camelcase": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "^2.0.0",
+        "map-obj": "^1.0.0"
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30000925",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000925.tgz",
+      "integrity": "sha512-zcYupoUxtW46rOikuDF7vfL9N1Qe9ZuUBTz3n3q8fFsoJIs/h9UN6Vg/0QpjsmvImXw9mVc3g+ZBfqvUz/iALA==",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "catharsis": {
+      "version": "0.8.9",
+      "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.9.tgz",
+      "integrity": "sha1-mMyJDKZS3S7w5ws3klMQ/56Q/Is=",
+      "dev": true,
+      "requires": {
+        "underscore-contrib": "~0.3.0"
+      }
+    },
+    "chai-nightwatch": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/chai-nightwatch/-/chai-nightwatch-0.2.1.tgz",
+      "integrity": "sha512-2lprSMi72sHq2ZGyPTYUDQNsd2O4z81SicascbI4bkU54Xzk5Ofunn2CbrExADGC7jBH2D8r66X/aSEl+/agXQ==",
+      "dev": true,
+      "requires": {
+        "assertion-error": "1.0.0",
+        "deep-eql": "0.1.3"
+      },
+      "dependencies": {
+        "assertion-error": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz",
+          "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=",
+          "dev": true
+        }
+      }
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "requires": {
+        "ansi-styles": "^2.2.1",
+        "escape-string-regexp": "^1.0.2",
+        "has-ansi": "^2.0.0",
+        "strip-ansi": "^3.0.0",
+        "supports-color": "^2.0.0"
+      }
+    },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+      "dev": true
+    },
+    "check-types": {
+      "version": "7.4.0",
+      "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz",
+      "integrity": "sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==",
+      "dev": true
+    },
+    "chi-squared": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/chi-squared/-/chi-squared-1.1.0.tgz",
+      "integrity": "sha1-iShlz/qOCnIPkhv8nGNcGawqNG0=",
+      "requires": {
+        "gamma": "^1.0.0"
+      }
+    },
+    "chokidar": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
+      "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
+      "dev": true,
+      "requires": {
+        "anymatch": "^2.0.0",
+        "async-each": "^1.0.0",
+        "braces": "^2.3.0",
+        "fsevents": "^1.2.2",
+        "glob-parent": "^3.1.0",
+        "inherits": "^2.0.1",
+        "is-binary-path": "^1.0.0",
+        "is-glob": "^4.0.0",
+        "lodash.debounce": "^4.0.8",
+        "normalize-path": "^2.1.1",
+        "path-is-absolute": "^1.0.0",
+        "readdirp": "^2.0.0",
+        "upath": "^1.0.5"
+      }
+    },
+    "chownr": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
+      "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz",
+      "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "chromedriver": {
+      "version": "2.45.0",
+      "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.45.0.tgz",
+      "integrity": "sha512-Qwmcr+2mU3INeR6mVsQ8gO00vZpL8ZeTJLclX44C0dcs88jrSDgckPqbG+qkVX+m2L/aOPnF0lYgPdOiOiLt5w==",
+      "dev": true,
+      "requires": {
+        "del": "^3.0.0",
+        "extract-zip": "^1.6.7",
+        "mkdirp": "^0.5.1",
+        "request": "^2.88.0",
+        "tcp-port-used": "^1.0.1"
+      }
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "circular-json": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+      "dev": true
+    },
+    "cjson": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/cjson/-/cjson-0.2.1.tgz",
+      "integrity": "sha1-c82KrWXZ4VBfmvF0TTt5wVJ2gqU="
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "clean-css": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
+      "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
+      "dev": true,
+      "requires": {
+        "source-map": "~0.6.0"
+      }
+    },
+    "cli": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+      "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+      "dev": true,
+      "requires": {
+        "exit": "0.1.2",
+        "glob": "^7.1.1"
+      }
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "^2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "cliui": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+      "dev": true,
+      "requires": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wrap-ansi": "^2.0.0"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        }
+      }
+    },
+    "clone-deep": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
+      "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==",
+      "dev": true,
+      "requires": {
+        "for-own": "^1.0.0",
+        "is-plain-object": "^2.0.4",
+        "kind-of": "^6.0.0",
+        "shallow-clone": "^1.0.0"
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "coffeescript": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
+      "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=",
+      "dev": true
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "colors": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
+      "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
+      "dev": true
+    },
+    "combined-stream": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+      "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.17.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+      "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+      "dev": true
+    },
+    "compressible": {
+      "version": "2.0.15",
+      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz",
+      "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==",
+      "dev": true,
+      "requires": {
+        "mime-db": ">= 1.36.0 < 2"
+      }
+    },
+    "compression": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz",
+      "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.5",
+        "bytes": "3.0.0",
+        "compressible": "~2.0.14",
+        "debug": "2.6.9",
+        "on-headers": "~1.0.1",
+        "safe-buffer": "5.1.2",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+          "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+          "dev": true
+        }
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "connect": {
+      "version": "3.6.6",
+      "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+      "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "finalhandler": "1.1.0",
+        "parseurl": "~1.3.2",
+        "utils-merge": "1.0.1"
+      },
+      "dependencies": {
+        "finalhandler": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+          "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "encodeurl": "~1.0.1",
+            "escape-html": "~1.0.3",
+            "on-finished": "~2.3.0",
+            "parseurl": "~1.3.2",
+            "statuses": "~1.3.1",
+            "unpipe": "~1.0.0"
+          }
+        },
+        "statuses": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+          "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+          "dev": true
+        }
+      }
+    },
+    "connect-history-api-fallback": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
+      "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=",
+      "dev": true
+    },
+    "connect-livereload": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz",
+      "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==",
+      "dev": true
+    },
+    "console-browserify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+      "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+      "dev": true,
+      "requires": {
+        "date-now": "^0.1.4"
+      }
+    },
+    "console-control-strings": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+      "dev": true
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "content-disposition": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+      "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
+      "dev": true
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true
+    },
+    "continuable-cache": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
+      "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+      "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "cookie": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+      "dev": true
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "fs-write-stream-atomic": "^1.0.8",
+        "iferr": "^0.1.5",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.0"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-js": {
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
+      "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cosmiconfig": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz",
+      "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==",
+      "dev": true,
+      "requires": {
+        "is-directory": "^0.3.1",
+        "js-yaml": "^3.9.0",
+        "parse-json": "^4.0.0",
+        "require-from-string": "^2.0.1"
+      },
+      "dependencies": {
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        }
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+      "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.0.0"
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.7",
+      "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "requires": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      }
+    },
+    "crypto-api": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/crypto-api/-/crypto-api-0.8.3.tgz",
+      "integrity": "sha512-ZhUQvYTn5DpW2aS8F/OezedZPniCNcJhpP4Njrsuyt+9Y9400ht5Wue7w3D/dZWgekF+W7fz4bYUKf6u/waiGQ=="
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
+    "crypto-js": {
+      "version": "3.1.9-1",
+      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz",
+      "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg="
+    },
+    "css-loader": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.0.tgz",
+      "integrity": "sha512-MoOu+CStsGrSt5K2OeZ89q3Snf+IkxRfAIt9aAKg4piioTrhtP1iEFPu+OVn3Ohz24FO6L+rw9UJxBILiSBw5Q==",
+      "dev": true,
+      "requires": {
+        "icss-utils": "^4.0.0",
+        "loader-utils": "^1.2.1",
+        "lodash": "^4.17.11",
+        "postcss": "^7.0.6",
+        "postcss-modules-extract-imports": "^2.0.0",
+        "postcss-modules-local-by-default": "^2.0.3",
+        "postcss-modules-scope": "^2.0.0",
+        "postcss-modules-values": "^2.0.0",
+        "postcss-value-parser": "^3.3.0",
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "json5": {
+          "version": "1.0.1",
+          "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.0"
+          }
+        },
+        "loader-utils": {
+          "version": "1.2.3",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
+          "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^2.0.0",
+            "json5": "^1.0.1"
+          }
+        },
+        "postcss": {
+          "version": "7.0.7",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
+          "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.1",
+            "source-map": "^0.6.1",
+            "supports-color": "^5.5.0"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "css-select": {
+      "version": "1.2.0",
+      "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+      "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+      "dev": true,
+      "requires": {
+        "boolbase": "~1.0.0",
+        "css-what": "2.1",
+        "domutils": "1.5.1",
+        "nth-check": "~1.0.1"
+      }
+    },
+    "css-selector-tokenizer": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz",
+      "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==",
+      "dev": true,
+      "requires": {
+        "cssesc": "^0.1.0",
+        "fastparse": "^1.1.1",
+        "regexpu-core": "^1.0.0"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        },
+        "regexpu-core": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+          "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
+          "dev": true,
+          "requires": {
+            "regenerate": "^1.2.1",
+            "regjsgen": "^0.2.0",
+            "regjsparser": "^0.1.4"
+          }
+        },
+        "regjsgen": {
+          "version": "0.2.0",
+          "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+          "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+          "dev": true
+        },
+        "regjsparser": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+          "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+          "dev": true,
+          "requires": {
+            "jsesc": "~0.5.0"
+          }
+        }
+      }
+    },
+    "css-what": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz",
+      "integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==",
+      "dev": true
+    },
+    "cssesc": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
+      "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
+      "dev": true
+    },
+    "cssom": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz",
+      "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==",
+      "dev": true
+    },
+    "cssstyle": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz",
+      "integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==",
+      "dev": true,
+      "requires": {
+        "cssom": "0.3.x"
+      }
+    },
+    "ctph.js": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/ctph.js/-/ctph.js-0.0.5.tgz",
+      "integrity": "sha1-F+xd3R2+aPFRvj1EbPGNRhuV8uc="
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "dev": true,
+      "requires": {
+        "array-find-index": "^1.0.1"
+      }
+    },
+    "cycle": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
+      "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=",
+      "dev": true
+    },
+    "cyclist": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
+      "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "data-uri-to-buffer": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz",
+      "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==",
+      "dev": true
+    },
+    "data-urls": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+      "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "whatwg-mimetype": "^2.2.0",
+        "whatwg-url": "^7.0.0"
+      },
+      "dependencies": {
+        "whatwg-url": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz",
+          "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
+          "dev": true,
+          "requires": {
+            "lodash.sortby": "^4.7.0",
+            "tr46": "^1.0.1",
+            "webidl-conversions": "^4.0.2"
+          }
+        }
+      }
+    },
+    "datauri": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/datauri/-/datauri-1.1.0.tgz",
+      "integrity": "sha512-0q+cTTKx7q8eDteZRIQLTFJuiIsVing17UbWTPssY4JLSMaYsk/VKpNulBDo9NSgQWcvlPrkEHW8kUO67T/7mQ==",
+      "dev": true,
+      "requires": {
+        "image-size": "^0.6.2",
+        "mimer": "^0.3.2",
+        "semver": "^5.5.0"
+      }
+    },
+    "date-now": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+      "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+      "dev": true
+    },
+    "dateformat": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+      "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^4.0.1",
+        "meow": "^3.3.0"
+      }
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-eql": {
+      "version": "0.1.3",
+      "resolved": "http://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
+      "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
+      "dev": true,
+      "requires": {
+        "type-detect": "0.1.1"
+      }
+    },
+    "deep-equal": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
+    },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "dev": true
+    },
+    "deep-for-each": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/deep-for-each/-/deep-for-each-2.0.3.tgz",
+      "integrity": "sha512-Y9mu+rplGcNZ7veer+5rqcdI9w3aPb7/WyE/nYnsuPevaE2z5YuC2u7/Gz/hIKsa0zo8sE8gKoBimSNsO/sr+A==",
+      "dev": true,
+      "requires": {
+        "lodash.isplainobject": "^4.0.6"
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
+    },
+    "default-gateway": {
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-2.7.2.tgz",
+      "integrity": "sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==",
+      "dev": true,
+      "requires": {
+        "execa": "^0.10.0",
+        "ip-regex": "^2.1.0"
+      }
+    },
+    "define-properties": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+      "dev": true,
+      "requires": {
+        "object-keys": "^1.0.12"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "degenerator": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz",
+      "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=",
+      "dev": true,
+      "requires": {
+        "ast-types": "0.x.x",
+        "escodegen": "1.x.x",
+        "esprima": "3.x.x"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+          "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
+          "dev": true
+        }
+      }
+    },
+    "del": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
+      "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
+      "dev": true,
+      "requires": {
+        "globby": "^6.1.0",
+        "is-path-cwd": "^1.0.0",
+        "is-path-in-cwd": "^1.0.0",
+        "p-map": "^1.1.1",
+        "pify": "^3.0.0",
+        "rimraf": "^2.2.8"
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "delegates": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "des.js": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+      "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "detect-node": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+      "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+      "dev": true
+    },
+    "diff": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
+    },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      }
+    },
+    "dns-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+      "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+      "dev": true
+    },
+    "dns-packet": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+      "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+      "dev": true,
+      "requires": {
+        "ip": "^1.1.0",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "dns-txt": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+      "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+      "dev": true,
+      "requires": {
+        "buffer-indexof": "^1.0.0"
+      }
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
+    "dom-converter": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+      "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+      "dev": true,
+      "requires": {
+        "utila": "~0.4"
+      }
+    },
+    "dom-serializer": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+      "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "~1.1.1",
+        "entities": "~1.1.1"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "1.1.3",
+          "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+          "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+          "dev": true
+        },
+        "entities": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+          "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+          "dev": true
+        }
+      }
+    },
+    "dom-walk": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
+      "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "domelementtype": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.2.1.tgz",
+      "integrity": "sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA==",
+      "dev": true
+    },
+    "domexception": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+      "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+      "dev": true,
+      "requires": {
+        "webidl-conversions": "^4.0.2"
+      }
+    },
+    "domhandler": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+      "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1"
+      }
+    },
+    "domutils": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+      "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "0",
+        "domelementtype": "1"
+      }
+    },
+    "duplexer": {
+      "version": "0.1.1",
+      "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+      "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz",
+      "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "ebnf-parser": {
+      "version": "0.1.10",
+      "resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz",
+      "integrity": "sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE="
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      },
+      "dependencies": {
+        "jsbn": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+          "dev": true
+        }
+      }
+    },
+    "ecdsa-sig-formatter": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz",
+      "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "ejs": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz",
+      "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==",
+      "dev": true
+    },
+    "electron-to-chromium": {
+      "version": "1.3.96",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.96.tgz",
+      "integrity": "sha512-ZUXBUyGLeoJxp4Nt6G/GjBRLnyz8IKQGexZ2ndWaoegThgMGFO1tdDYID5gBV32/1S83osjJHyfzvanE/8HY4Q==",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
+      "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "emojis-list": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+      "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz",
+      "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "memory-fs": "^0.4.0",
+        "tapable": "^1.0.0"
+      }
+    },
+    "entities": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+      "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+      "dev": true
+    },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
+    "error": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz",
+      "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=",
+      "dev": true,
+      "requires": {
+        "string-template": "~0.2.1",
+        "xtend": "~4.0.0"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.12.0",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
+      "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
+      "dev": true,
+      "requires": {
+        "es-to-primitive": "^1.1.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.1",
+        "is-callable": "^1.1.3",
+        "is-regex": "^1.0.4"
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
+      "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
+      "dev": true,
+      "requires": {
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
+      }
+    },
+    "es6-object-assign": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
+      "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
+    },
+    "es6-polyfills": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/es6-polyfills/-/es6-polyfills-2.0.0.tgz",
+      "integrity": "sha1-fzWP04jYyIjQDPyaHuqJ+XFoOTE=",
+      "requires": {
+        "es6-object-assign": "^1.0.3",
+        "es6-promise-polyfill": "^1.2.0"
+      }
+    },
+    "es6-promise": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz",
+      "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
+      "dev": true
+    },
+    "es6-promise-polyfill": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz",
+      "integrity": "sha1-84kl8jyz4+jObNqP93T867sJDN4="
+    },
+    "es6-promisify": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.0.1.tgz",
+      "integrity": "sha512-J3ZkwbEnnO+fGAKrjVpeUAnZshAdfZvbhQpqfIH9kSAspReRC4nJnu8ewm55b4y9ElyeuhCTzJD0XiH8Tsbhlw=="
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+    },
+    "escodegen": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz",
+      "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==",
+      "requires": {
+        "esprima": "^3.1.3",
+        "estraverse": "^4.2.0",
+        "esutils": "^2.0.2",
+        "optionator": "^0.8.1",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+          "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
+        }
+      }
+    },
+    "escope": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escope/-/escope-1.0.3.tgz",
+      "integrity": "sha1-dZ3OhJbEJI/sLQyq9BCLzz8af10=",
+      "requires": {
+        "estraverse": "^2.0.0"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-2.0.0.tgz",
+          "integrity": "sha1-WuRpYyQ2ACBmdMyySgnhZnT83KE="
+        }
+      }
+    },
+    "eslint": {
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.12.1.tgz",
+      "integrity": "sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "ajv": "^6.5.3",
+        "chalk": "^2.1.0",
+        "cross-spawn": "^6.0.5",
+        "debug": "^4.0.1",
+        "doctrine": "^2.1.0",
+        "eslint-scope": "^4.0.0",
+        "eslint-utils": "^1.3.1",
+        "eslint-visitor-keys": "^1.0.0",
+        "espree": "^5.0.0",
+        "esquery": "^1.0.1",
+        "esutils": "^2.0.2",
+        "file-entry-cache": "^2.0.0",
+        "functional-red-black-tree": "^1.0.1",
+        "glob": "^7.1.2",
+        "globals": "^11.7.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
+        "imurmurhash": "^0.1.4",
+        "inquirer": "^6.1.0",
+        "js-yaml": "^3.12.0",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.3.0",
+        "lodash": "^4.17.5",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.8.2",
+        "path-is-inside": "^1.0.2",
+        "pluralize": "^7.0.0",
+        "progress": "^2.0.0",
+        "regexpp": "^2.0.1",
+        "semver": "^5.5.1",
+        "strip-ansi": "^4.0.0",
+        "strip-json-comments": "^2.0.1",
+        "table": "^5.0.2",
+        "text-table": "^0.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "globals": {
+          "version": "11.10.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz",
+          "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "progress": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+          "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "eslint-scope": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
+      "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "eslint-utils": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
+      "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
+      "dev": true
+    },
+    "eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "dev": true
+    },
+    "esmangle": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esmangle/-/esmangle-1.0.1.tgz",
+      "integrity": "sha1-2bs3uPjq+/Tm1O1reqKVarvTxMI=",
+      "requires": {
+        "escodegen": "~1.3.2",
+        "escope": "~1.0.1",
+        "esprima": "~1.1.1",
+        "esshorten": "~1.1.0",
+        "estraverse": "~1.5.0",
+        "esutils": "~ 1.0.0",
+        "optionator": "~0.3.0",
+        "source-map": "~0.1.33"
+      },
+      "dependencies": {
+        "escodegen": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.3.3.tgz",
+          "integrity": "sha1-8CQBb1qI4Eb9EgBQVek5gC5sXyM=",
+          "requires": {
+            "esprima": "~1.1.1",
+            "estraverse": "~1.5.0",
+            "esutils": "~1.0.0",
+            "source-map": "~0.1.33"
+          }
+        },
+        "esprima": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.1.1.tgz",
+          "integrity": "sha1-W28VR/TRAuZw4UDFCb5ncdautUk="
+        },
+        "estraverse": {
+          "version": "1.5.1",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.5.1.tgz",
+          "integrity": "sha1-hno+jlip+EYYr7bC3bzZFrfLr3E="
+        },
+        "esutils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.0.0.tgz",
+          "integrity": "sha1-gVHTWOIMisx/t0XnRywAJf5JZXA="
+        },
+        "fast-levenshtein": {
+          "version": "1.0.7",
+          "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz",
+          "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk="
+        },
+        "levn": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz",
+          "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=",
+          "requires": {
+            "prelude-ls": "~1.1.0",
+            "type-check": "~0.3.1"
+          }
+        },
+        "optionator": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.3.0.tgz",
+          "integrity": "sha1-lxWotfXnWGz/BsgkngOc1zZNP1Q=",
+          "requires": {
+            "deep-is": "~0.1.2",
+            "fast-levenshtein": "~1.0.0",
+            "levn": "~0.2.4",
+            "prelude-ls": "~1.1.0",
+            "type-check": "~0.3.1",
+            "wordwrap": "~0.0.2"
+          }
+        },
+        "source-map": {
+          "version": "0.1.43",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+          "requires": {
+            "amdefine": ">=0.0.4"
+          }
+        },
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
+        }
+      }
+    },
+    "espree": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz",
+      "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==",
+      "dev": true,
+      "requires": {
+        "acorn": "^6.0.2",
+        "acorn-jsx": "^5.0.0",
+        "eslint-visitor-keys": "^1.0.0"
+      }
+    },
+    "esprima": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
+    },
+    "esquery": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.0.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
+    "esshorten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/esshorten/-/esshorten-1.1.1.tgz",
+      "integrity": "sha1-F0+Wt8wmfkaHLYFOfbfCkL3/Yak=",
+      "requires": {
+        "escope": "~1.0.1",
+        "estraverse": "~4.1.1",
+        "esutils": "~2.0.2"
+      },
+      "dependencies": {
+        "estraverse": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz",
+          "integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI="
+        }
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true
+    },
+    "eventemitter2": {
+      "version": "0.4.14",
+      "resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+      "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
+      "dev": true
+    },
+    "eventemitter3": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
+      "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
+      "dev": true
+    },
+    "events": {
+      "version": "1.1.1",
+      "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz",
+      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
+      "dev": true
+    },
+    "eventsource": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
+      "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
+      "dev": true,
+      "requires": {
+        "original": "^1.0.0"
+      }
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "execa": {
+      "version": "0.10.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
+      "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^3.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      }
+    },
+    "exif-parser": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
+      "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI="
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "exports-loader": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.7.0.tgz",
+      "integrity": "sha512-RKwCrO4A6IiKm0pG3c9V46JxIHcDplwwGJn6+JJ1RcVnh/WSGJa0xkmk5cRVtgOPzCAtTMGj2F7nluh9L0vpSA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "source-map": "0.5.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.0.tgz",
+          "integrity": "sha1-D+llA6yGpa213mP05BKuSHLNvoY=",
+          "dev": true
+        }
+      }
+    },
+    "express": {
+      "version": "4.16.4",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
+      "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.5",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.18.3",
+        "content-disposition": "0.5.2",
+        "content-type": "~1.0.4",
+        "cookie": "0.3.1",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.1.1",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.2",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.4",
+        "qs": "6.5.2",
+        "range-parser": "~1.2.0",
+        "safe-buffer": "5.1.2",
+        "send": "0.16.2",
+        "serve-static": "1.13.2",
+        "setprototypeof": "1.1.0",
+        "statuses": "~1.4.0",
+        "type-is": "~1.6.16",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "array-flatten": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+          "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+          "dev": true
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
+      "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
+      "dev": true,
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "requires": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "extract-zip": {
+      "version": "1.6.7",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+      "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.2",
+        "debug": "2.6.9",
+        "mkdirp": "0.5.1",
+        "yauzl": "2.4.1"
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "eyes": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
+      "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+      "dev": true
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
+    },
+    "fastparse": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
+      "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
+      "dev": true
+    },
+    "faye-websocket": {
+      "version": "0.10.0",
+      "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
+      "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
+      "dev": true,
+      "requires": {
+        "websocket-driver": ">=0.5.1"
+      }
+    },
+    "fd-slicer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+      "dev": true,
+      "requires": {
+        "pend": "~1.2.0"
+      }
+    },
+    "figgy-pudding": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
+      "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==",
+      "dev": true
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "^1.2.1",
+        "object-assign": "^4.0.1"
+      }
+    },
+    "file-loader": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz",
+      "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.0.2",
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "file-saver": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.0.tgz",
+      "integrity": "sha512-cYM1ic5DAkg25pHKgi5f10ziAM7RJU37gaH1XQlyNDrtUnzhC/dfoV9zf2OmF0RMKi42jG5B0JWBnPQqyj/G6g=="
+    },
+    "file-sync-cmp": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz",
+      "integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=",
+      "dev": true
+    },
+    "file-type": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz",
+      "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw=="
+    },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true
+    },
+    "filesize": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz",
+      "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.1",
+      "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+      "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.2",
+        "statuses": "~1.4.0",
+        "unpipe": "~1.0.0"
+      }
+    },
+    "find-cache-dir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
+      "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^1.0.0",
+        "pkg-dir": "^2.0.0"
+      }
+    },
+    "find-up": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "dev": true,
+      "requires": {
+        "locate-path": "^2.0.0"
+      }
+    },
+    "findup-sync": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+      "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
+      "dev": true,
+      "requires": {
+        "glob": "~5.0.0"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "5.0.15",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+          "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+          "dev": true,
+          "requires": {
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "2 || 3",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        }
+      }
+    },
+    "flat-cache": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
+      "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
+      "dev": true,
+      "requires": {
+        "circular-json": "^0.3.1",
+        "graceful-fs": "^4.1.2",
+        "rimraf": "~2.6.2",
+        "write": "^0.2.1"
+      }
+    },
+    "flush-write-stream": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
+      "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.4"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "follow-redirects": {
+      "version": "1.5.9",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz",
+      "integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==",
+      "dev": true,
+      "requires": {
+        "debug": "=3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "requires": {
+        "is-callable": "^1.1.3"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+      "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.1"
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "fs-extra": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+      "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^2.1.0",
+        "klaw": "^1.0.0"
+      }
+    },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "iferr": "^0.1.5",
+        "imurmurhash": "^0.1.4",
+        "readable-stream": "1 || 2"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
+      "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "^2.9.2",
+        "node-pre-gyp": "^0.10.0"
+      },
+      "dependencies": {
+        "abbrev": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "aproba": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "are-we-there-yet": {
+          "version": "1.1.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "delegates": "^1.0.0",
+            "readable-stream": "^2.0.6"
+          }
+        },
+        "balanced-match": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "chownr": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "concat-map": {
+          "version": "0.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "console-control-strings": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "core-util-is": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "detect-libc": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "fs-minipass": {
+          "version": "1.2.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aproba": "^1.0.3",
+            "console-control-strings": "^1.0.0",
+            "has-unicode": "^2.0.0",
+            "object-assign": "^4.1.0",
+            "signal-exit": "^3.0.0",
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1",
+            "wide-align": "^1.1.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "iconv-lite": {
+          "version": "0.4.21",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safer-buffer": "^2.1.0"
+          }
+        },
+        "ignore-walk": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minimatch": "^3.0.4"
+          }
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "once": "^1.3.0",
+            "wrappy": "1"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "ini": {
+          "version": "1.3.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": true,
+          "dev": true
+        },
+        "minipass": {
+          "version": "2.2.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safe-buffer": "^5.1.1",
+            "yallist": "^3.0.0"
+          }
+        },
+        "minizlib": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "needle": {
+          "version": "2.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "^2.1.2",
+            "iconv-lite": "^0.4.4",
+            "sax": "^1.2.4"
+          }
+        },
+        "node-pre-gyp": {
+          "version": "0.10.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "detect-libc": "^1.0.2",
+            "mkdirp": "^0.5.1",
+            "needle": "^2.2.0",
+            "nopt": "^4.0.1",
+            "npm-packlist": "^1.1.6",
+            "npmlog": "^4.0.2",
+            "rc": "^1.1.7",
+            "rimraf": "^2.6.1",
+            "semver": "^5.3.0",
+            "tar": "^4"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "abbrev": "1",
+            "osenv": "^0.1.4"
+          }
+        },
+        "npm-bundled": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "npm-packlist": {
+          "version": "1.1.10",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ignore-walk": "^3.0.1",
+            "npm-bundled": "^1.0.1"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "~1.1.2",
+            "console-control-strings": "~1.1.0",
+            "gauge": "~2.7.3",
+            "set-blocking": "~2.0.0"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "once": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "wrappy": "1"
+          }
+        },
+        "os-homedir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "os-tmpdir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "osenv": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "os-homedir": "^1.0.0",
+            "os-tmpdir": "^1.0.0"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "rc": {
+          "version": "1.2.7",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "deep-extend": "^0.5.1",
+            "ini": "~1.3.0",
+            "minimist": "^1.2.0",
+            "strip-json-comments": "~2.0.1"
+          },
+          "dependencies": {
+            "minimist": {
+              "version": "1.2.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "glob": "^7.0.5"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "safer-buffer": {
+          "version": "2.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "sax": {
+          "version": "1.2.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "semver": {
+          "version": "5.5.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "tar": {
+          "version": "4.4.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chownr": "^1.0.1",
+            "fs-minipass": "^1.2.5",
+            "minipass": "^2.2.4",
+            "minizlib": "^1.1.0",
+            "mkdirp": "^0.5.0",
+            "safe-buffer": "^5.1.1",
+            "yallist": "^3.0.2"
+          }
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "wide-align": {
+          "version": "1.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "string-width": "^1.0.2"
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "yallist": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true
+        }
+      }
+    },
+    "fstream": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+      "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "inherits": "~2.0.0",
+        "mkdirp": ">=0.5 0",
+        "rimraf": "2"
+      }
+    },
+    "ftp": {
+      "version": "0.3.10",
+      "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",
+      "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "1.1.x",
+        "xregexp": "2.0.0"
+      },
+      "dependencies": {
+        "xregexp": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
+          "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=",
+          "dev": true
+        }
+      }
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "gamma": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/gamma/-/gamma-1.0.0.tgz",
+      "integrity": "sha1-mDwck5/iPZMnAVhXEeHZpDDLdMs="
+    },
+    "gauge": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.0.3",
+        "console-control-strings": "^1.0.0",
+        "has-unicode": "^2.0.0",
+        "object-assign": "^4.1.0",
+        "signal-exit": "^3.0.0",
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wide-align": "^1.1.0"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        }
+      }
+    },
+    "gaze": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+      "dev": true,
+      "requires": {
+        "globule": "^1.0.0"
+      }
+    },
+    "geodesy": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/geodesy/-/geodesy-1.1.3.tgz",
+      "integrity": "sha512-H/0XSd1KjKZGZ2YGZcOYzRyY/foYAawwTEumNSo+YUwf+u5d4CfvBRg2i2Qimrx9yUEjWR8hLvMnhghuVFN0Zg=="
+    },
+    "get-caller-file": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+      "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "3.0.0",
+      "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true
+    },
+    "get-uri": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz",
+      "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==",
+      "dev": true,
+      "requires": {
+        "data-uri-to-buffer": "1",
+        "debug": "2",
+        "extend": "3",
+        "file-uri-to-path": "1",
+        "ftp": "~0.3.10",
+        "readable-stream": "2"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getobject": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
+      "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+      "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+      "dev": true,
+      "requires": {
+        "is-glob": "^3.1.0",
+        "path-dirname": "^1.0.0"
+      },
+      "dependencies": {
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.0"
+          }
+        }
+      }
+    },
+    "global": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+      "requires": {
+        "min-document": "^2.19.0",
+        "process": "~0.5.1"
+      },
+      "dependencies": {
+        "process": {
+          "version": "0.5.2",
+          "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+          "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
+        }
+      }
+    },
+    "globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
+    },
+    "globby": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+      "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+      "dev": true,
+      "requires": {
+        "array-union": "^1.0.1",
+        "glob": "^7.0.3",
+        "object-assign": "^4.0.1",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "globule": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
+      "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
+      "dev": true,
+      "requires": {
+        "glob": "~7.1.1",
+        "lodash": "~4.17.10",
+        "minimatch": "~3.0.2"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.15",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+      "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+      "dev": true
+    },
+    "growl": {
+      "version": "1.10.5",
+      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+      "dev": true,
+      "optional": true
+    },
+    "grunt": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.3.tgz",
+      "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==",
+      "dev": true,
+      "requires": {
+        "coffeescript": "~1.10.0",
+        "dateformat": "~1.0.12",
+        "eventemitter2": "~0.4.13",
+        "exit": "~0.1.1",
+        "findup-sync": "~0.3.0",
+        "glob": "~7.0.0",
+        "grunt-cli": "~1.2.0",
+        "grunt-known-options": "~1.1.0",
+        "grunt-legacy-log": "~2.0.0",
+        "grunt-legacy-util": "~1.1.1",
+        "iconv-lite": "~0.4.13",
+        "js-yaml": "~3.5.2",
+        "minimatch": "~3.0.2",
+        "mkdirp": "~0.5.1",
+        "nopt": "~3.0.6",
+        "path-is-absolute": "~1.0.0",
+        "rimraf": "~2.6.2"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "2.7.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+          "dev": true
+        },
+        "glob": {
+          "version": "7.0.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
+          "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.2",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "grunt-cli": {
+          "version": "1.2.0",
+          "resolved": "http://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
+          "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
+          "dev": true,
+          "requires": {
+            "findup-sync": "~0.3.0",
+            "grunt-known-options": "~1.1.0",
+            "nopt": "~3.0.6",
+            "resolve": "~1.1.0"
+          }
+        },
+        "js-yaml": {
+          "version": "3.5.5",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz",
+          "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=",
+          "dev": true,
+          "requires": {
+            "argparse": "^1.0.2",
+            "esprima": "^2.6.0"
+          }
+        },
+        "resolve": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+          "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-accessibility": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-accessibility/-/grunt-accessibility-6.0.0.tgz",
+      "integrity": "sha512-5Y7MMYzpzMICkspvmUOU+YC/VE5eiB5TV8k9u43ZFrzLIoYDulKce8KX0fyi2EXYEDKlUEyaVI/W4rLDqqy3/Q==",
+      "dev": true,
+      "requires": {
+        "access-sniff": "^3.2.0"
+      }
+    },
+    "grunt-chmod": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/grunt-chmod/-/grunt-chmod-1.1.1.tgz",
+      "integrity": "sha1-0YZcWoTn7Zrv5Qn/v1KQ+XoleEA=",
+      "dev": true,
+      "requires": {
+        "shelljs": "^0.5.3"
+      },
+      "dependencies": {
+        "shelljs": {
+          "version": "0.5.3",
+          "resolved": "http://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz",
+          "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-concurrent": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/grunt-concurrent/-/grunt-concurrent-2.3.1.tgz",
+      "integrity": "sha1-Hj2zjM71o9oRleYdYx/n4yE0TSM=",
+      "dev": true,
+      "requires": {
+        "arrify": "^1.0.1",
+        "async": "^1.2.1",
+        "indent-string": "^2.0.0",
+        "pad-stream": "^1.0.0"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-contrib-clean": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-2.0.0.tgz",
+      "integrity": "sha512-g5ZD3ORk6gMa5ugZosLDQl3dZO7cI3R14U75hTM+dVLVxdMNJCPVmwf9OUt4v4eWgpKKWWoVK9DZc1amJp4nQw==",
+      "dev": true,
+      "requires": {
+        "async": "^2.6.1",
+        "rimraf": "^2.6.2"
+      }
+    },
+    "grunt-contrib-connect": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-2.0.0.tgz",
+      "integrity": "sha512-JVjM9UDP84WbT2S7swkyuwPuxFtT+zry/RUBuP3IT8LZPEQjtzzMwiM+qimswNKQ9plh5WhcFWaaqz2ruB9/DA==",
+      "dev": true,
+      "requires": {
+        "async": "^2.6.1",
+        "connect": "^3.6.6",
+        "connect-livereload": "^0.6.0",
+        "morgan": "^1.9.0",
+        "node-http2": "^4.0.1",
+        "opn": "^5.3.0",
+        "portscanner": "^2.2.0",
+        "serve-index": "^1.9.1",
+        "serve-static": "^1.13.2"
+      }
+    },
+    "grunt-contrib-copy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz",
+      "integrity": "sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.1",
+        "file-sync-cmp": "^0.1.0"
+      }
+    },
+    "grunt-contrib-jshint": {
+      "version": "1.1.0",
+      "resolved": "http://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-1.1.0.tgz",
+      "integrity": "sha1-Np2QmyWTxA6L55lAshNAhQx5Oaw=",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.1",
+        "hooker": "^0.2.3",
+        "jshint": "~2.9.4"
+      }
+    },
+    "grunt-contrib-watch": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz",
+      "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==",
+      "dev": true,
+      "requires": {
+        "async": "^2.6.0",
+        "gaze": "^1.1.0",
+        "lodash": "^4.17.10",
+        "tiny-lr": "^1.1.1"
+      }
+    },
+    "grunt-eslint": {
+      "version": "21.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-21.0.0.tgz",
+      "integrity": "sha512-HJocD9P35lpCvy6pPPCTgzBavzckrT1nt7lpqV55Vy8E6LQJv4RortXoH1jJTYhO5DYY7RPATv7Uc4383PUYqQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.1.0",
+        "eslint": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "grunt-exec": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-3.0.0.tgz",
+      "integrity": "sha512-cgAlreXf3muSYS5LzW0Cc4xHK03BjFOYk0MqCQ/MZ3k1Xz2GU7D+IAJg4UKicxpO+XdONJdx/NJ6kpy2wI+uHg==",
+      "dev": true
+    },
+    "grunt-jsdoc": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.3.0.tgz",
+      "integrity": "sha512-gC66TCRXeQMj3HIyqVSBJm8zdUz43e5vaG/PLO/627A1edbJnzxhJV7nF0KqLwMM0RDNu1istC6fvfnYqFKi3w==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^6.0.5",
+        "jsdoc": "~3.5.5",
+        "marked": "^0.5.0"
+      }
+    },
+    "grunt-known-options": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz",
+      "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==",
+      "dev": true
+    },
+    "grunt-legacy-log": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz",
+      "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==",
+      "dev": true,
+      "requires": {
+        "colors": "~1.1.2",
+        "grunt-legacy-log-utils": "~2.0.0",
+        "hooker": "~0.2.3",
+        "lodash": "~4.17.5"
+      },
+      "dependencies": {
+        "colors": {
+          "version": "1.1.2",
+          "resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+          "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-legacy-log-utils": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz",
+      "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==",
+      "dev": true,
+      "requires": {
+        "chalk": "~2.4.1",
+        "lodash": "~4.17.10"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "grunt-legacy-util": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz",
+      "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==",
+      "dev": true,
+      "requires": {
+        "async": "~1.5.2",
+        "exit": "~0.1.1",
+        "getobject": "~0.1.0",
+        "hooker": "~0.2.3",
+        "lodash": "~4.17.10",
+        "underscore.string": "~3.3.4",
+        "which": "~1.3.0"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-webpack": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/grunt-webpack/-/grunt-webpack-3.1.3.tgz",
+      "integrity": "sha512-SaZ8K8lG4iTxs7ClZxOWCf3kxqS2y+Eel8SbaEGgBKwhAp6e45beIu+vhBZRLX3vonKML2kjemKsQ21REaqNFQ==",
+      "dev": true,
+      "requires": {
+        "deep-for-each": "^2.0.2",
+        "lodash": "^4.7.0"
+      }
+    },
+    "gzip-size": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz",
+      "integrity": "sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==",
+      "dev": true,
+      "requires": {
+        "duplexer": "^0.1.1",
+        "pify": "^3.0.0"
+      }
+    },
+    "handle-thing": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz",
+      "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==",
+      "dev": true
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.5.5",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dev": true,
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+      "dev": true
+    },
+    "has-unicode": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+      "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "hasha": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+      "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+      "dev": true,
+      "requires": {
+        "is-stream": "^1.0.1",
+        "pinkie-promise": "^2.0.0"
+      }
+    },
+    "he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+      "dev": true
+    },
+    "highlight.js": {
+      "version": "9.13.1",
+      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.13.1.tgz",
+      "integrity": "sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A=="
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "hooker": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+      "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+      "dev": true
+    },
+    "hoopy": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
+      "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==",
+      "dev": true
+    },
+    "hosted-git-info": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+      "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+      "dev": true
+    },
+    "hpack.js": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+      "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "obuf": "^1.0.0",
+        "readable-stream": "^2.0.1",
+        "wbuf": "^1.1.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "html-encoding-sniffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+      "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+      "dev": true,
+      "requires": {
+        "whatwg-encoding": "^1.0.1"
+      }
+    },
+    "html-entities": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
+      "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
+      "dev": true
+    },
+    "html-minifier": {
+      "version": "3.5.21",
+      "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz",
+      "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==",
+      "dev": true,
+      "requires": {
+        "camel-case": "3.0.x",
+        "clean-css": "4.2.x",
+        "commander": "2.17.x",
+        "he": "1.2.x",
+        "param-case": "2.1.x",
+        "relateurl": "0.2.x",
+        "uglify-js": "3.4.x"
+      }
+    },
+    "html-webpack-plugin": {
+      "version": "3.2.0",
+      "resolved": "http://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
+      "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
+      "dev": true,
+      "requires": {
+        "html-minifier": "^3.2.3",
+        "loader-utils": "^0.2.16",
+        "lodash": "^4.17.3",
+        "pretty-error": "^2.0.2",
+        "tapable": "^1.0.0",
+        "toposort": "^1.0.0",
+        "util.promisify": "1.0.0"
+      },
+      "dependencies": {
+        "json5": {
+          "version": "0.5.1",
+          "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+          "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+          "dev": true
+        },
+        "loader-utils": {
+          "version": "0.2.17",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
+          "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
+          "dev": true,
+          "requires": {
+            "big.js": "^3.1.3",
+            "emojis-list": "^2.0.0",
+            "json5": "^0.5.0",
+            "object-assign": "^4.0.1"
+          },
+          "dependencies": {
+            "big.js": {
+              "version": "3.2.0",
+              "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+              "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "html_codesniffer": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/html_codesniffer/-/html_codesniffer-2.2.0.tgz",
+      "integrity": "sha512-xG6E3g2V/huu/WwRcrX3AFRmAUFkU7PWlgF/QFLtuRitI+NxvJcYTFthb24rB7/mhKE3khSIxB11A8IQTJ2N9w==",
+      "dev": true,
+      "requires": {
+        "grunt": "^1.0.0",
+        "grunt-contrib-copy": "^1.0.0",
+        "grunt-contrib-jshint": "^1.0.0",
+        "grunt-contrib-watch": "^1.0.0",
+        "load-grunt-tasks": "^3.5.2"
+      }
+    },
+    "htmlparser2": {
+      "version": "3.8.3",
+      "resolved": "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+      "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1",
+        "domhandler": "2.3",
+        "domutils": "1.5",
+        "entities": "1.0",
+        "readable-stream": "1.1"
+      }
+    },
+    "http-deceiver": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+      "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+      "dev": true
+    },
+    "http-errors": {
+      "version": "1.6.3",
+      "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+      "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+      "dev": true,
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.0",
+        "statuses": ">= 1.4.0 < 2"
+      }
+    },
+    "http-parser-js": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz",
+      "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==",
+      "dev": true
+    },
+    "http-proxy": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
+      "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "^3.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "http-proxy-agent": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
+      "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
+      "dev": true,
+      "requires": {
+        "agent-base": "4",
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "http-proxy-middleware": {
+      "version": "0.18.0",
+      "resolved": "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
+      "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==",
+      "dev": true,
+      "requires": {
+        "http-proxy": "^1.16.2",
+        "is-glob": "^4.0.0",
+        "lodash": "^4.17.5",
+        "micromatch": "^3.1.9"
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "https-proxy-agent": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+      "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+      "dev": true,
+      "requires": {
+        "agent-base": "^4.1.0",
+        "debug": "^3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "i": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
+      "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=",
+      "dev": true
+    },
+    "iced-error": {
+      "version": "0.0.13",
+      "resolved": "https://registry.npmjs.org/iced-error/-/iced-error-0.0.13.tgz",
+      "integrity": "sha512-yEEaG8QfyyRL0SsbNNDw3rVgTyqwHFMCuV6jDvD43f/2shmdaFXkqvFLGhDlsYNSolzYHwVLM/CrXt9GygYopA=="
+    },
+    "iced-lock": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/iced-lock/-/iced-lock-1.1.0.tgz",
+      "integrity": "sha1-YRbvHKs6zW5rEIk7snumIv0/3nI=",
+      "requires": {
+        "iced-runtime": "^1.0.0"
+      }
+    },
+    "iced-runtime": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/iced-runtime/-/iced-runtime-1.0.3.tgz",
+      "integrity": "sha1-LU9PuZmreqVDCxk8d6f85BGDGc4="
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
+    "icss-replace-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
+      "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
+      "dev": true
+    },
+    "icss-utils": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.0.0.tgz",
+      "integrity": "sha512-bA/xGiwWM17qjllIs9X/y0EjsB7e0AV08F3OL8UPsoNkNRibIuu8f1eKTnQ8QO1DteKKTxTUAn+IEWUToIwGOA==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.5"
+      }
+    },
+    "ieee754": {
+      "version": "1.1.12",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
+      "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA=="
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "dev": true
+    },
+    "image-size": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz",
+      "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==",
+      "dev": true
+    },
+    "import-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+      "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+      "dev": true,
+      "requires": {
+        "import-from": "^2.1.0"
+      }
+    },
+    "import-fresh": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz",
+      "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==",
+      "dev": true,
+      "requires": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      }
+    },
+    "import-from": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+      "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+          "dev": true
+        }
+      }
+    },
+    "import-local": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+      "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^3.0.0",
+        "resolve-cwd": "^2.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
+          "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
+          "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+          "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0"
+          }
+        }
+      }
+    },
+    "imports-loader": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.8.0.tgz",
+      "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.0.2",
+        "source-map": "^0.6.1"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "in-publish": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
+      "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
+      "dev": true
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "dev": true,
+      "requires": {
+        "repeating": "^2.0.0"
+      }
+    },
+    "indexof": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "ink-docstrap": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/ink-docstrap/-/ink-docstrap-1.3.2.tgz",
+      "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==",
+      "dev": true,
+      "requires": {
+        "moment": "^2.14.1",
+        "sanitize-html": "^1.13.0"
+      }
+    },
+    "inquirer": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz",
+      "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^3.2.0",
+        "chalk": "^2.4.2",
+        "cli-cursor": "^2.1.0",
+        "cli-width": "^2.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^2.0.0",
+        "lodash": "^4.17.11",
+        "mute-stream": "0.0.7",
+        "run-async": "^2.2.0",
+        "rxjs": "^6.4.0",
+        "string-width": "^2.1.0",
+        "strip-ansi": "^5.0.0",
+        "through": "^2.3.6"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz",
+          "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz",
+          "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "internal-ip": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-3.0.1.tgz",
+      "integrity": "sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q==",
+      "dev": true,
+      "requires": {
+        "default-gateway": "^2.6.0",
+        "ipaddr.js": "^1.5.2"
+      }
+    },
+    "invariant": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+      "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+      "requires": {
+        "loose-envify": "^1.0.0"
+      }
+    },
+    "invert-kv": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+      "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+      "dev": true
+    },
+    "ip": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+      "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+      "dev": true
+    },
+    "ip-regex": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+      "dev": true
+    },
+    "ipaddr.js": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
+      "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^1.0.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "^1.0.0"
+      }
+    },
+    "is-callable": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+      "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+      "dev": true
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-directory": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+      "dev": true
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "^1.0.0"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true
+    },
+    "is-function": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
+      "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
+    },
+    "is-glob": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+      "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-number-like": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz",
+      "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==",
+      "dev": true,
+      "requires": {
+        "lodash.isfinite": "^3.3.2"
+      }
+    },
+    "is-path-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+      "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+      "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "^1.0.0"
+      }
+    },
+    "is-path-inside": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+      "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "^1.0.1"
+      }
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-regex": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+      "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+      "dev": true,
+      "requires": {
+        "has": "^1.0.1"
+      }
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true
+    },
+    "is-symbol": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
+      "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
+      "dev": true,
+      "requires": {
+        "has-symbols": "^1.0.0"
+      }
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-url": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
+      "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
+      "dev": true
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "is-wsl": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+      "dev": true
+    },
+    "is2": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.1.tgz",
+      "integrity": "sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==",
+      "dev": true,
+      "requires": {
+        "deep-is": "^0.1.3",
+        "ip-regex": "^2.1.0",
+        "is-url": "^1.2.2"
+      }
+    },
+    "isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "jimp": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.6.0.tgz",
+      "integrity": "sha512-RYpN+AAlTEMf8Bnkhq2eeTNyr70rDK/2UUfUqzBJmwmZwdR6fxRJvgbCGWT1BDVRxaAqo+4CWm8ePBxOIsr4jg==",
+      "requires": {
+        "@babel/polyfill": "^7.0.0",
+        "@jimp/custom": "^0.6.0",
+        "@jimp/plugins": "^0.6.0",
+        "@jimp/types": "^0.6.0",
+        "core-js": "^2.5.7"
+      }
+    },
+    "jison": {
+      "version": "0.4.13",
+      "resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz",
+      "integrity": "sha1-kEFwfWIkE2f1iDRTK58ZwsNvrHg=",
+      "requires": {
+        "JSONSelect": "0.4.0",
+        "cjson": "~0.2.1",
+        "ebnf-parser": "~0.1.9",
+        "escodegen": "0.0.21",
+        "esprima": "1.0.x",
+        "jison-lex": "0.2.x",
+        "lex-parser": "~0.1.3",
+        "nomnom": "1.5.2"
+      },
+      "dependencies": {
+        "escodegen": {
+          "version": "0.0.21",
+          "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.21.tgz",
+          "integrity": "sha1-U9ZSz6EDA4gnlFilJmxf/HCcY8M=",
+          "requires": {
+            "esprima": "~1.0.2",
+            "estraverse": "~0.0.4",
+            "source-map": ">= 0.1.2"
+          }
+        },
+        "esprima": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
+          "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
+        },
+        "estraverse": {
+          "version": "0.0.4",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-0.0.4.tgz",
+          "integrity": "sha1-AaCTLf7ldGhKWYr1pnw7+bZCjbI="
+        }
+      }
+    },
+    "jison-lex": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.2.1.tgz",
+      "integrity": "sha1-rEuBXozOUTLrErXfz+jXB7iETf4=",
+      "requires": {
+        "lex-parser": "0.1.x",
+        "nomnom": "1.5.2"
+      }
+    },
+    "jpeg-js": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.4.tgz",
+      "integrity": "sha512-6IzjQxvnlT8UlklNmDXIJMWxijULjqGrzgqc0OG7YadZdvm7KPQ1j0ehmQQHckgEWOfgpptzcnWgESovxudpTA=="
+    },
+    "jquery": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
+      "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="
+    },
+    "js-base64": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz",
+      "integrity": "sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==",
+      "dev": true
+    },
+    "js-crc": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/js-crc/-/js-crc-0.2.0.tgz",
+      "integrity": "sha1-9yxcdhgXa/91zIEqHO2949jraDk="
+    },
+    "js-levenshtein": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.4.tgz",
+      "integrity": "sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow==",
+      "dev": true
+    },
+    "js-sha3": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+      "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
+    },
+    "js-yaml": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
+      "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
+      "dev": true,
+      "requires": {
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      }
+    },
+    "js2xmlparser": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz",
+      "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=",
+      "dev": true,
+      "requires": {
+        "xmlcreate": "^1.0.1"
+      }
+    },
+    "jsdoc": {
+      "version": "3.5.5",
+      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz",
+      "integrity": "sha512-6PxB65TAU4WO0Wzyr/4/YhlGovXl0EVYfpKbpSroSj0qBxT4/xod/l40Opkm38dRHRdQgdeY836M0uVnJQG7kg==",
+      "dev": true,
+      "requires": {
+        "babylon": "7.0.0-beta.19",
+        "bluebird": "~3.5.0",
+        "catharsis": "~0.8.9",
+        "escape-string-regexp": "~1.0.5",
+        "js2xmlparser": "~3.0.0",
+        "klaw": "~2.0.0",
+        "marked": "~0.3.6",
+        "mkdirp": "~0.5.1",
+        "requizzle": "~0.2.1",
+        "strip-json-comments": "~2.0.1",
+        "taffydb": "2.6.2",
+        "underscore": "~1.8.3"
+      },
+      "dependencies": {
+        "babylon": {
+          "version": "7.0.0-beta.19",
+          "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz",
+          "integrity": "sha512-Vg0C9s/REX6/WIXN37UKpv5ZhRi6A4pjHlpkE34+8/a6c2W1Q692n3hmc+SZG5lKRnaExLUbxtJ1SVT+KaCQ/A==",
+          "dev": true
+        },
+        "klaw": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz",
+          "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.9"
+          }
+        },
+        "marked": {
+          "version": "0.3.19",
+          "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
+          "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
+          "dev": true
+        },
+        "underscore": {
+          "version": "1.8.3",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+          "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
+          "dev": true
+        }
+      }
+    },
+    "jsdoc-babel": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.5.0.tgz",
+      "integrity": "sha512-PYfTbc3LNTeR8TpZs2M94NLDWqARq0r9gx3SvuziJfmJS7/AeMKvtj0xjzOX0R/4MOVA7/FqQQK7d6U0iEoztQ==",
+      "dev": true,
+      "requires": {
+        "jsdoc-regex": "^1.0.1",
+        "lodash": "^4.17.10"
+      }
+    },
+    "jsdoc-regex": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz",
+      "integrity": "sha1-hCRCjVtWOtjFx/vsB5uaiwnI3Po=",
+      "dev": true
+    },
+    "jsdom": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
+      "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
+      "dev": true,
+      "requires": {
+        "abab": "^2.0.0",
+        "acorn": "^5.5.3",
+        "acorn-globals": "^4.1.0",
+        "array-equal": "^1.0.0",
+        "cssom": ">= 0.3.2 < 0.4.0",
+        "cssstyle": "^1.0.0",
+        "data-urls": "^1.0.0",
+        "domexception": "^1.0.1",
+        "escodegen": "^1.9.1",
+        "html-encoding-sniffer": "^1.0.2",
+        "left-pad": "^1.3.0",
+        "nwsapi": "^2.0.7",
+        "parse5": "4.0.0",
+        "pn": "^1.1.0",
+        "request": "^2.87.0",
+        "request-promise-native": "^1.0.5",
+        "sax": "^1.2.4",
+        "symbol-tree": "^3.2.2",
+        "tough-cookie": "^2.3.4",
+        "w3c-hr-time": "^1.0.1",
+        "webidl-conversions": "^4.0.2",
+        "whatwg-encoding": "^1.0.3",
+        "whatwg-mimetype": "^2.1.0",
+        "whatwg-url": "^6.4.1",
+        "ws": "^5.2.0",
+        "xml-name-validator": "^3.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.7.3",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+          "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+          "dev": true
+        }
+      }
+    },
+    "jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+    },
+    "jshint": {
+      "version": "2.9.6",
+      "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.6.tgz",
+      "integrity": "sha512-KO9SIAKTlJQOM4lE64GQUtGBRpTOuvbrRrSZw3AhUxMNG266nX9hK2cKA4SBhXOj0irJGyNyGSLT62HGOVDEOA==",
+      "dev": true,
+      "requires": {
+        "cli": "~1.0.0",
+        "console-browserify": "1.1.x",
+        "exit": "0.1.x",
+        "htmlparser2": "3.8.x",
+        "lodash": "~4.17.10",
+        "minimatch": "~3.0.2",
+        "phantom": "~4.0.1",
+        "phantomjs-prebuilt": "~2.1.7",
+        "shelljs": "0.3.x",
+        "strip-json-comments": "1.0.x",
+        "unicode-5.2.0": "^0.7.5"
+      },
+      "dependencies": {
+        "strip-json-comments": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+          "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+          "dev": true
+        }
+      }
+    },
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "json3": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
+      "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
+      "dev": true
+    },
+    "json5": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz",
+      "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.0"
+      }
+    },
+    "jsonfile": {
+      "version": "2.4.0",
+      "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "jsonpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.0.tgz",
+      "integrity": "sha1-Rc2dTE0NaCXZC9fkD4PxGCsT3Qc=",
+      "requires": {
+        "esprima": "1.2.2",
+        "jison": "0.4.13",
+        "static-eval": "2.0.0",
+        "underscore": "1.7.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "1.2.2",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz",
+          "integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs="
+        }
+      }
+    },
+    "jsonwebtoken": {
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz",
+      "integrity": "sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg==",
+      "requires": {
+        "jws": "^3.1.5",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1"
+      },
+      "dependencies": {
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+        }
+      }
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "jsqr": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.1.1.tgz",
+      "integrity": "sha512-FVoMU2ncTyjaOqN/vwvDnZ7jaAVvFzM3LK3vG3jvQZFWJQlAwJ1XTCOgAEKo+4Rkd6ydMXTTvqGV/4w5VunmTw=="
+    },
+    "jsrsasign": {
+      "version": "8.0.12",
+      "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.12.tgz",
+      "integrity": "sha1-Iqu5ZW00owuVMENnIINeicLlwxY="
+    },
+    "jwa": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz",
+      "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==",
+      "requires": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.10",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "jws": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz",
+      "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==",
+      "requires": {
+        "jwa": "^1.1.5",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "kbpgp": {
+      "version": "2.0.82",
+      "resolved": "https://registry.npmjs.org/kbpgp/-/kbpgp-2.0.82.tgz",
+      "integrity": "sha512-CBcV786ZMOP9FOnpg3ZJC3a++TJb47HPVVkCPpmgSuVS9Cnss+m9j1u/IY9HXzEjys7DTebaoMAzqB05FWPZfg==",
+      "requires": {
+        "bn": "^1.0.0",
+        "bzip-deflate": "^1.0.0",
+        "deep-equal": ">=0.2.1",
+        "iced-error": ">=0.0.10",
+        "iced-lock": "^1.0.2",
+        "iced-runtime": "^1.0.3",
+        "keybase-ecurve": "^1.0.0",
+        "keybase-nacl": "^1.0.0",
+        "minimist": "^1.2.0",
+        "pgp-utils": ">=0.0.34",
+        "purepack": ">=1.0.4",
+        "triplesec": ">=3.0.27",
+        "tweetnacl": "^0.13.1"
+      }
+    },
+    "kew": {
+      "version": "0.7.0",
+      "resolved": "http://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+      "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+      "dev": true
+    },
+    "keybase-ecurve": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/keybase-ecurve/-/keybase-ecurve-1.0.0.tgz",
+      "integrity": "sha1-xrxyrdpGA/0xhP7n6ZaU7Y/WmtI=",
+      "requires": {
+        "bn": "^1.0.0"
+      }
+    },
+    "keybase-nacl": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/keybase-nacl/-/keybase-nacl-1.0.10.tgz",
+      "integrity": "sha1-OGWDHpSBUWSI33y9mJRn6VDYeos=",
+      "requires": {
+        "iced-runtime": "^1.0.2",
+        "tweetnacl": "^0.13.1",
+        "uint64be": "^1.0.1"
+      }
+    },
+    "killable": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
+      "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
+      "dev": true
+    },
+    "kind-of": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+      "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+      "dev": true
+    },
+    "klaw": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.9"
+      }
+    },
+    "lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "dev": true,
+      "requires": {
+        "invert-kv": "^1.0.0"
+      }
+    },
+    "left-pad": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
+      "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
+      "dev": true
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "requires": {
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2"
+      }
+    },
+    "lex-parser": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz",
+      "integrity": "sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA="
+    },
+    "libyara-wasm": {
+      "version": "0.0.11",
+      "resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-0.0.11.tgz",
+      "integrity": "sha512-rglapPFo0IHPNksWYQXI8oqftXYj5mOGOf4BXtbSySVRX71pro4BehNjJ5qEpjYx+roGvNkcAD9zCsitA08sxw=="
+    },
+    "livereload-js": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
+      "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==",
+      "dev": true
+    },
+    "load-bmfont": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz",
+      "integrity": "sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==",
+      "requires": {
+        "buffer-equal": "0.0.1",
+        "mime": "^1.3.4",
+        "parse-bmfont-ascii": "^1.0.3",
+        "parse-bmfont-binary": "^1.0.5",
+        "parse-bmfont-xml": "^1.1.4",
+        "phin": "^2.9.1",
+        "xhr": "^2.0.1",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "mime": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+          "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+        }
+      }
+    },
+    "load-grunt-tasks": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz",
+      "integrity": "sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg=",
+      "dev": true,
+      "requires": {
+        "arrify": "^1.0.0",
+        "multimatch": "^2.0.0",
+        "pkg-up": "^1.0.0",
+        "resolve-pkg": "^0.1.0"
+      }
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "parse-json": "^2.2.0",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0",
+        "strip-bom": "^2.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "loader-runner": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz",
+      "integrity": "sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+      "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+      "dev": true,
+      "requires": {
+        "big.js": "^3.1.3",
+        "emojis-list": "^2.0.0",
+        "json5": "^0.5.0"
+      },
+      "dependencies": {
+        "big.js": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+          "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+          "dev": true
+        },
+        "json5": {
+          "version": "0.5.1",
+          "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+          "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+          "dev": true
+        }
+      }
+    },
+    "locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "dev": true,
+      "requires": {
+        "p-locate": "^2.0.0",
+        "path-exists": "^3.0.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.11",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
+    },
+    "lodash._arraycopy": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz",
+      "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=",
+      "dev": true
+    },
+    "lodash._arrayeach": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz",
+      "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754=",
+      "dev": true
+    },
+    "lodash._baseassign": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
+      "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
+      "dev": true,
+      "requires": {
+        "lodash._basecopy": "^3.0.0",
+        "lodash.keys": "^3.0.0"
+      }
+    },
+    "lodash._baseclone": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz",
+      "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=",
+      "dev": true,
+      "requires": {
+        "lodash._arraycopy": "^3.0.0",
+        "lodash._arrayeach": "^3.0.0",
+        "lodash._baseassign": "^3.0.0",
+        "lodash._basefor": "^3.0.0",
+        "lodash.isarray": "^3.0.0",
+        "lodash.keys": "^3.0.0"
+      }
+    },
+    "lodash._basecopy": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
+      "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
+      "dev": true
+    },
+    "lodash._basefor": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz",
+      "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=",
+      "dev": true
+    },
+    "lodash._bindcallback": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
+      "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=",
+      "dev": true
+    },
+    "lodash._getnative": {
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+      "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
+      "dev": true
+    },
+    "lodash._isiterateecall": {
+      "version": "3.0.9",
+      "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
+      "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
+      "dev": true
+    },
+    "lodash.assign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+      "dev": true
+    },
+    "lodash.clone": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-3.0.3.tgz",
+      "integrity": "sha1-hGiMc9MrWpDKJWFpY/GJJSqZcEM=",
+      "dev": true,
+      "requires": {
+        "lodash._baseclone": "^3.0.0",
+        "lodash._bindcallback": "^3.0.0",
+        "lodash._isiterateecall": "^3.0.0"
+      }
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+      "dev": true
+    },
+    "lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+      "dev": true
+    },
+    "lodash.defaultsdeep": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz",
+      "integrity": "sha1-vsECT4WxvZbL6kBbI8FK1kQ6b4E=",
+      "dev": true
+    },
+    "lodash.escaperegexp": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
+      "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=",
+      "dev": true
+    },
+    "lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
+    },
+    "lodash.isarguments": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
+      "dev": true
+    },
+    "lodash.isarray": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+      "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
+      "dev": true
+    },
+    "lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
+    },
+    "lodash.isfinite": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
+      "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=",
+      "dev": true
+    },
+    "lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
+    },
+    "lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
+    },
+    "lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
+    },
+    "lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
+    },
+    "lodash.keys": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+      "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+      "dev": true,
+      "requires": {
+        "lodash._getnative": "^3.0.0",
+        "lodash.isarguments": "^3.0.0",
+        "lodash.isarray": "^3.0.0"
+      }
+    },
+    "lodash.merge": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz",
+      "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==",
+      "dev": true
+    },
+    "lodash.mergewith": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
+      "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==",
+      "dev": true
+    },
+    "lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
+    },
+    "lodash.sortby": {
+      "version": "4.7.0",
+      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+      "dev": true
+    },
+    "lodash.tail": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
+      "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
+      "dev": true
+    },
+    "lodash.unescape": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
+      "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
+      "dev": true
+    },
+    "loglevel": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz",
+      "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po="
+    },
+    "loglevel-message-prefix": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/loglevel-message-prefix/-/loglevel-message-prefix-3.0.0.tgz",
+      "integrity": "sha1-ER/bltlPlh2PyLiqv7ZrBqw+dq0=",
+      "requires": {
+        "es6-polyfills": "^2.0.0",
+        "loglevel": "^1.4.0"
+      }
+    },
+    "long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
+    "loose-envify": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+      "requires": {
+        "js-tokens": "^3.0.0 || ^4.0.0"
+      }
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "dev": true,
+      "requires": {
+        "currently-unhandled": "^0.4.1",
+        "signal-exit": "^3.0.0"
+      }
+    },
+    "lower-case": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
+      "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
+      "dev": true
+    },
+    "lru-cache": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+      "dev": true,
+      "requires": {
+        "pseudomap": "^1.0.2",
+        "yallist": "^2.1.2"
+      }
+    },
+    "make-dir": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+      "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+      "dev": true,
+      "requires": {
+        "pify": "^3.0.0"
+      }
+    },
+    "map-age-cleaner": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+      "dev": true,
+      "requires": {
+        "p-defer": "^1.0.0"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "marked": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-0.5.1.tgz",
+      "integrity": "sha512-iUkBZegCZou4AdwbKTwSW/lNDcz5OuRSl3qdcl31Ia0B2QPG0Jn+tKblh/9/eP9/6+4h27vpoh8wel/vQOV0vw==",
+      "dev": true
+    },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "mem": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz",
+      "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==",
+      "dev": true,
+      "requires": {
+        "map-age-cleaner": "^0.1.1",
+        "mimic-fn": "^1.0.0",
+        "p-is-promise": "^1.1.0"
+      }
+    },
+    "memory-fs": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+      "dev": true,
+      "requires": {
+        "errno": "^0.1.3",
+        "readable-stream": "^2.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "dev": true,
+      "requires": {
+        "camelcase-keys": "^2.0.0",
+        "decamelize": "^1.1.2",
+        "loud-rejection": "^1.0.0",
+        "map-obj": "^1.0.1",
+        "minimist": "^1.1.3",
+        "normalize-package-data": "^2.3.4",
+        "object-assign": "^4.0.1",
+        "read-pkg-up": "^1.0.1",
+        "redent": "^1.0.0",
+        "trim-newlines": "^1.0.0"
+      }
+    },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
+    "methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true
+    },
+    "micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "braces": "^2.3.1",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "extglob": "^2.0.4",
+        "fragment-cache": "^0.2.1",
+        "kind-of": "^6.0.2",
+        "nanomatch": "^1.2.9",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.2"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      }
+    },
+    "mime": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+      "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.37.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+      "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.21",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+      "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+      "dev": true,
+      "requires": {
+        "mime-db": "~1.37.0"
+      }
+    },
+    "mimer": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.3.2.tgz",
+      "integrity": "sha512-N6NcgDQAevhP/02DQ/epK6daLy4NKrIHyTlJcO6qBiYn98q+Y4a/knNsAATCe1xLS2F0nEmJp+QYli2s8vKwyQ==",
+      "dev": true
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+      "dev": true
+    },
+    "min-document": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+      "requires": {
+        "dom-walk": "^0.1.0"
+      }
+    },
+    "mini-css-extract-plugin": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
+      "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "schema-utils": "^1.0.0",
+        "webpack-sources": "^1.1.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "1.2.0",
+      "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+    },
+    "mississippi": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+      "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+      "dev": true,
+      "requires": {
+        "concat-stream": "^1.5.0",
+        "duplexify": "^3.4.2",
+        "end-of-stream": "^1.1.0",
+        "flush-write-stream": "^1.0.0",
+        "from2": "^2.1.0",
+        "parallel-transform": "^1.1.0",
+        "pump": "^3.0.0",
+        "pumpify": "^1.3.3",
+        "stream-each": "^1.1.0",
+        "through2": "^2.0.0"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+          "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        }
+      }
+    },
+    "mixin-deep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "mixin-object": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
+      "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
+      "dev": true,
+      "requires": {
+        "for-in": "^0.1.3",
+        "is-extendable": "^0.1.1"
+      },
+      "dependencies": {
+        "for-in": {
+          "version": "0.1.8",
+          "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
+          "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
+          "dev": true
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "requires": {
+        "minimist": "0.0.8"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "0.0.8",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+        }
+      }
+    },
+    "mkpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz",
+      "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=",
+      "dev": true
+    },
+    "mocha": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
+      "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "browser-stdout": "1.3.1",
+        "commander": "2.15.1",
+        "debug": "3.1.0",
+        "diff": "3.5.0",
+        "escape-string-regexp": "1.0.5",
+        "glob": "7.1.2",
+        "growl": "1.10.5",
+        "he": "1.1.1",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "supports-color": "5.4.0"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.15.1",
+          "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+          "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+          "dev": true,
+          "optional": true
+        },
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "he": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+          "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+          "dev": true,
+          "optional": true
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "moment": {
+      "version": "2.23.0",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz",
+      "integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA=="
+    },
+    "moment-timezone": {
+      "version": "0.5.23",
+      "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.23.tgz",
+      "integrity": "sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==",
+      "requires": {
+        "moment": ">= 2.9.0"
+      }
+    },
+    "more-entropy": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/more-entropy/-/more-entropy-0.0.7.tgz",
+      "integrity": "sha1-Z7/G96hvJvvDeqyD/UbYjGHRCbU=",
+      "requires": {
+        "iced-runtime": ">=0.0.1"
+      }
+    },
+    "morgan": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
+      "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
+      "dev": true,
+      "requires": {
+        "basic-auth": "~2.0.0",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "on-headers": "~1.0.1"
+      }
+    },
+    "move-concurrently": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+      "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "copy-concurrently": "^1.0.0",
+        "fs-write-stream-atomic": "^1.0.8",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.3"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+    },
+    "multicast-dns": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+      "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+      "dev": true,
+      "requires": {
+        "dns-packet": "^1.3.1",
+        "thunky": "^1.0.2"
+      }
+    },
+    "multicast-dns-service-types": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+      "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
+      "dev": true
+    },
+    "multimatch": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
+      "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=",
+      "dev": true,
+      "requires": {
+        "array-differ": "^1.0.0",
+        "array-union": "^1.0.1",
+        "arrify": "^1.0.0",
+        "minimatch": "^3.0.0"
+      }
+    },
+    "mute-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
+      "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==",
+      "dev": true
+    },
+    "nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      }
+    },
+    "natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "ncp": {
+      "version": "1.0.1",
+      "resolved": "http://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz",
+      "integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=",
+      "dev": true
+    },
+    "negotiator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+      "dev": true
+    },
+    "neo-async": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz",
+      "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==",
+      "dev": true
+    },
+    "netmask": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz",
+      "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=",
+      "dev": true
+    },
+    "ngeohash": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/ngeohash/-/ngeohash-0.6.3.tgz",
+      "integrity": "sha512-kltF0cOxgx1AbmVzKxYZaoB0aj7mOxZeHaerEtQV0YaqnkXNq26WWqMmJ6lTqShYxVRWZ/mwvvTrNeOwdslWiw=="
+    },
+    "nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "nightwatch": {
+      "version": "1.0.18",
+      "resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-1.0.18.tgz",
+      "integrity": "sha512-BKosRh/QqpCCMxjnfP+gb8KMQV0y//TNdYDjB0RrU1pXgx2Xjyp46bK8tQWRFfqaxWDj5EKYFIPgvxFBXodIOA==",
+      "dev": true,
+      "requires": {
+        "assertion-error": "^1.1.0",
+        "chai-nightwatch": "0.2.1",
+        "ejs": "^2.5.9",
+        "lodash.clone": "^3.0.3",
+        "lodash.defaultsdeep": "^4.6.0",
+        "lodash.merge": "^4.6.1",
+        "minimatch": "3.0.3",
+        "mkpath": "1.0.0",
+        "mocha": "^5.1.1",
+        "optimist": "^0.6.1",
+        "proxy-agent": "^3.0.0"
+      },
+      "dependencies": {
+        "minimatch": {
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+          "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.0.0"
+          }
+        }
+      }
+    },
+    "no-case": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
+      "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
+      "dev": true,
+      "requires": {
+        "lower-case": "^1.1.1"
+      }
+    },
+    "node-forge": {
+      "version": "0.7.6",
+      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz",
+      "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw=="
+    },
+    "node-gyp": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
+      "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
+      "dev": true,
+      "requires": {
+        "fstream": "^1.0.0",
+        "glob": "^7.0.3",
+        "graceful-fs": "^4.1.2",
+        "mkdirp": "^0.5.0",
+        "nopt": "2 || 3",
+        "npmlog": "0 || 1 || 2 || 3 || 4",
+        "osenv": "0",
+        "request": "^2.87.0",
+        "rimraf": "2",
+        "semver": "~5.3.0",
+        "tar": "^2.0.0",
+        "which": "1"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.3.0",
+          "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+          "dev": true
+        }
+      }
+    },
+    "node-http2": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/node-http2/-/node-http2-4.0.1.tgz",
+      "integrity": "sha1-Fk/1O13SLITwrxQrh3xerraAmVk=",
+      "dev": true,
+      "requires": {
+        "assert": "1.4.1",
+        "events": "1.1.1",
+        "https-browserify": "0.0.1",
+        "setimmediate": "^1.0.5",
+        "stream-browserify": "2.0.1",
+        "timers-browserify": "2.0.2",
+        "url": "^0.11.0",
+        "websocket-stream": "^5.0.1"
+      },
+      "dependencies": {
+        "https-browserify": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
+          "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=",
+          "dev": true
+        },
+        "timers-browserify": {
+          "version": "2.0.2",
+          "resolved": "http://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz",
+          "integrity": "sha1-q0iDz1l9zVCvIRNJoA+8pWrIa4Y=",
+          "dev": true,
+          "requires": {
+            "setimmediate": "^1.0.4"
+          }
+        }
+      }
+    },
+    "node-libs-browser": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
+      "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
+      "dev": true,
+      "requires": {
+        "assert": "^1.1.1",
+        "browserify-zlib": "^0.2.0",
+        "buffer": "^4.3.0",
+        "console-browserify": "^1.1.0",
+        "constants-browserify": "^1.0.0",
+        "crypto-browserify": "^3.11.0",
+        "domain-browser": "^1.1.1",
+        "events": "^1.0.0",
+        "https-browserify": "^1.0.0",
+        "os-browserify": "^0.3.0",
+        "path-browserify": "0.0.0",
+        "process": "^0.11.10",
+        "punycode": "^1.2.4",
+        "querystring-es3": "^0.2.0",
+        "readable-stream": "^2.3.3",
+        "stream-browserify": "^2.0.1",
+        "stream-http": "^2.7.2",
+        "string_decoder": "^1.0.0",
+        "timers-browserify": "^2.0.4",
+        "tty-browserify": "0.0.0",
+        "url": "^0.11.0",
+        "util": "^0.10.3",
+        "vm-browserify": "0.0.4"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          },
+          "dependencies": {
+            "string_decoder": {
+              "version": "1.1.1",
+              "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+              "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+              "dev": true,
+              "requires": {
+                "safe-buffer": "~5.1.0"
+              }
+            }
+          }
+        },
+        "string_decoder": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
+          "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "node-md6": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/node-md6/-/node-md6-0.1.0.tgz",
+      "integrity": "sha1-9WH0WyszY1K4KXbFHMoRR9U5N/U="
+    },
+    "node-releases": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.3.tgz",
+      "integrity": "sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ==",
+      "dev": true,
+      "requires": {
+        "semver": "^5.3.0"
+      }
+    },
+    "node-sass": {
+      "version": "4.11.0",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.11.0.tgz",
+      "integrity": "sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA==",
+      "dev": true,
+      "requires": {
+        "async-foreach": "^0.1.3",
+        "chalk": "^1.1.1",
+        "cross-spawn": "^3.0.0",
+        "gaze": "^1.0.0",
+        "get-stdin": "^4.0.1",
+        "glob": "^7.0.3",
+        "in-publish": "^2.0.0",
+        "lodash.assign": "^4.2.0",
+        "lodash.clonedeep": "^4.3.2",
+        "lodash.mergewith": "^4.6.0",
+        "meow": "^3.7.0",
+        "mkdirp": "^0.5.1",
+        "nan": "^2.10.0",
+        "node-gyp": "^3.8.0",
+        "npmlog": "^4.0.0",
+        "request": "^2.88.0",
+        "sass-graph": "^2.2.4",
+        "stdout-stream": "^1.4.0",
+        "true-case-path": "^1.0.2"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+          "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^4.0.1",
+            "which": "^1.2.9"
+          }
+        }
+      }
+    },
+    "nomnom": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz",
+      "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=",
+      "requires": {
+        "colors": "0.5.x",
+        "underscore": "1.1.x"
+      },
+      "dependencies": {
+        "colors": {
+          "version": "0.5.1",
+          "resolved": "http://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
+          "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
+        },
+        "underscore": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz",
+          "integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA="
+        }
+      }
+    },
+    "nopt": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+      "dev": true,
+      "requires": {
+        "abbrev": "1"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "^2.1.4",
+        "is-builtin-module": "^1.0.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "normalize-path": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "dev": true,
+      "requires": {
+        "remove-trailing-separator": "^1.0.1"
+      }
+    },
+    "normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+      "dev": true
+    },
+    "notepack.io": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/notepack.io/-/notepack.io-2.2.0.tgz",
+      "integrity": "sha512-9b5w3t5VSH6ZPosoYnyDONnUTF8o0UkBw7JLA6eBlYJWyGT1Q3vQa8Hmuj1/X6RYvHjjygBDgw6fJhe0JEojfw=="
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "^2.0.0"
+      }
+    },
+    "npmlog": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+      "dev": true,
+      "requires": {
+        "are-we-there-yet": "~1.1.2",
+        "console-control-strings": "~1.1.0",
+        "gauge": "~2.7.3",
+        "set-blocking": "~2.0.0"
+      }
+    },
+    "nth-check": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+      "dev": true,
+      "requires": {
+        "boolbase": "~1.0.0"
+      }
+    },
+    "num2fraction": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+      "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+      "dev": true
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+      "dev": true
+    },
+    "nwmatcher": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
+      "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ=="
+    },
+    "nwsapi": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.9.tgz",
+      "integrity": "sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==",
+      "dev": true
+    },
+    "oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "object-keys": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
+      "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
+      "dev": true
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.getownpropertydescriptors": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
+      "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.2",
+        "es-abstract": "^1.5.1"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "obuf": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+      "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+      "dev": true
+    },
+    "omggif": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.9.tgz",
+      "integrity": "sha1-3LcCTazVDFK00wPwSALJHAV8dl8="
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "on-headers": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+      "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=",
+      "dev": true
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "^1.0.0"
+      }
+    },
+    "opener": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz",
+      "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==",
+      "dev": true
+    },
+    "opn": {
+      "version": "5.4.0",
+      "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz",
+      "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==",
+      "dev": true,
+      "requires": {
+        "is-wsl": "^1.1.0"
+      }
+    },
+    "optimist": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+      "dev": true,
+      "requires": {
+        "minimist": "~0.0.1",
+        "wordwrap": "~0.0.2"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "0.0.10",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+          "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+          "dev": true
+        },
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+          "dev": true
+        }
+      }
+    },
+    "optionator": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "requires": {
+        "deep-is": "~0.1.3",
+        "fast-levenshtein": "~2.0.4",
+        "levn": "~0.3.0",
+        "prelude-ls": "~1.1.2",
+        "type-check": "~0.3.2",
+        "wordwrap": "~1.0.0"
+      }
+    },
+    "original": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
+      "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
+      "dev": true,
+      "requires": {
+        "url-parse": "^1.4.3"
+      }
+    },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+      "dev": true
+    },
+    "os-locale": {
+      "version": "1.4.0",
+      "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+      "dev": true,
+      "requires": {
+        "lcid": "^1.0.0"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "osenv": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+      "dev": true,
+      "requires": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.0"
+      }
+    },
+    "otp": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/otp/-/otp-0.1.3.tgz",
+      "integrity": "sha1-wle/JdL5Anr3esUiabPBQmjSvWs=",
+      "requires": {
+        "thirty-two": "^0.0.2"
+      }
+    },
+    "p-defer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
+      "dev": true
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
+    "p-is-promise": {
+      "version": "1.1.0",
+      "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+      "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
+      "dev": true
+    },
+    "p-limit": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+      "dev": true,
+      "requires": {
+        "p-try": "^1.0.0"
+      }
+    },
+    "p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "dev": true,
+      "requires": {
+        "p-limit": "^1.1.0"
+      }
+    },
+    "p-map": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
+      "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
+      "dev": true
+    },
+    "p-try": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+      "dev": true
+    },
+    "pac-proxy-agent": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-3.0.0.tgz",
+      "integrity": "sha512-AOUX9jES/EkQX2zRz0AW7lSx9jD//hQS8wFXBvcnd/J2Py9KaMJMqV/LPqJssj1tgGufotb2mmopGPR15ODv1Q==",
+      "dev": true,
+      "requires": {
+        "agent-base": "^4.2.0",
+        "debug": "^3.1.0",
+        "get-uri": "^2.0.0",
+        "http-proxy-agent": "^2.1.0",
+        "https-proxy-agent": "^2.2.1",
+        "pac-resolver": "^3.0.0",
+        "raw-body": "^2.2.0",
+        "socks-proxy-agent": "^4.0.1"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+          "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+          "dev": true
+        },
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "iconv-lite": {
+          "version": "0.4.23",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+          "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+          "dev": true,
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "raw-body": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
+          "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
+          "dev": true,
+          "requires": {
+            "bytes": "3.0.0",
+            "http-errors": "1.6.3",
+            "iconv-lite": "0.4.23",
+            "unpipe": "1.0.0"
+          }
+        }
+      }
+    },
+    "pac-resolver": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz",
+      "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==",
+      "dev": true,
+      "requires": {
+        "co": "^4.6.0",
+        "degenerator": "^1.0.4",
+        "ip": "^1.1.5",
+        "netmask": "^1.0.6",
+        "thunkify": "^2.1.2"
+      }
+    },
+    "pad-stream": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pad-stream/-/pad-stream-1.2.0.tgz",
+      "integrity": "sha1-Yx3Mn3mBC3BZZeid7eps/w/B38k=",
+      "dev": true,
+      "requires": {
+        "meow": "^3.0.0",
+        "pumpify": "^1.3.3",
+        "repeating": "^2.0.0",
+        "split2": "^1.0.0",
+        "through2": "^2.0.0"
+      }
+    },
+    "pako": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+      "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
+    },
+    "parallel-transform": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
+      "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
+      "dev": true,
+      "requires": {
+        "cyclist": "~0.2.2",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.1.5"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "param-case": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
+      "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
+      "dev": true,
+      "requires": {
+        "no-case": "^2.2.0"
+      }
+    },
+    "parent-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz",
+      "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.1",
+      "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+      "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
+      "dev": true,
+      "requires": {
+        "asn1.js": "^4.0.0",
+        "browserify-aes": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3"
+      }
+    },
+    "parse-bmfont-ascii": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
+      "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU="
+    },
+    "parse-bmfont-binary": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz",
+      "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY="
+    },
+    "parse-bmfont-xml": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz",
+      "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==",
+      "requires": {
+        "xml-parse-from-string": "^1.0.0",
+        "xml2js": "^0.4.5"
+      }
+    },
+    "parse-headers": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz",
+      "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=",
+      "requires": {
+        "for-each": "^0.3.2",
+        "trim": "0.0.1"
+      }
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "requires": {
+        "error-ex": "^1.2.0"
+      }
+    },
+    "parse5": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+      "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
+      "dev": true
+    },
+    "parseurl": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+      "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "dev": true
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+      "dev": true
+    },
+    "path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true
+    },
+    "path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "pbkdf2": {
+      "version": "3.0.17",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+      "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+      "dev": true,
+      "requires": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "dev": true
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "pgp-utils": {
+      "version": "0.0.34",
+      "resolved": "https://registry.npmjs.org/pgp-utils/-/pgp-utils-0.0.34.tgz",
+      "integrity": "sha1-2E9J98GTteC5QV9cxcKmle15DCM=",
+      "requires": {
+        "iced-error": ">=0.0.8",
+        "iced-runtime": ">=0.0.1"
+      }
+    },
+    "phantom": {
+      "version": "4.0.12",
+      "resolved": "https://registry.npmjs.org/phantom/-/phantom-4.0.12.tgz",
+      "integrity": "sha512-Tz82XhtPmwCk1FFPmecy7yRGZG2btpzY2KI9fcoPT7zT9det0CcMyfBFPp1S8DqzsnQnm8ZYEfdy528mwVtksA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "phantomjs-prebuilt": "^2.1.16",
+        "split": "^1.0.1",
+        "winston": "^2.4.0"
+      }
+    },
+    "phantomjs-prebuilt": {
+      "version": "2.1.16",
+      "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
+      "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
+      "dev": true,
+      "requires": {
+        "es6-promise": "^4.0.3",
+        "extract-zip": "^1.6.5",
+        "fs-extra": "^1.0.0",
+        "hasha": "^2.2.0",
+        "kew": "^0.7.0",
+        "progress": "^1.1.8",
+        "request": "^2.81.0",
+        "request-progress": "^2.0.1",
+        "which": "^1.2.10"
+      }
+    },
+    "phin": {
+      "version": "2.9.3",
+      "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz",
+      "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA=="
+    },
+    "pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "^2.0.0"
+      }
+    },
+    "pixelmatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz",
+      "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=",
+      "requires": {
+        "pngjs": "^3.0.0"
+      }
+    },
+    "pkg-dir": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+      "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+      "dev": true,
+      "requires": {
+        "find-up": "^2.1.0"
+      }
+    },
+    "pkg-up": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz",
+      "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=",
+      "dev": true,
+      "requires": {
+        "find-up": "^1.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+          "dev": true,
+          "requires": {
+            "path-exists": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "^2.0.0"
+          }
+        }
+      }
+    },
+    "pkginfo": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz",
+      "integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=",
+      "dev": true
+    },
+    "pluralize": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+      "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+      "dev": true
+    },
+    "pn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+      "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+      "dev": true
+    },
+    "pngjs": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.3.tgz",
+      "integrity": "sha512-1n3Z4p3IOxArEs1VRXnZ/RXdfEniAUS9jb68g58FIXMNkPJeZd+Qh4Uq7/e0LVxAQGos1eIUrqrt4FpjdnEd+Q=="
+    },
+    "popper.js": {
+      "version": "1.14.6",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz",
+      "integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA=="
+    },
+    "portfinder": {
+      "version": "1.0.20",
+      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz",
+      "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==",
+      "dev": true,
+      "requires": {
+        "async": "^1.5.2",
+        "debug": "^2.2.0",
+        "mkdirp": "0.5.x"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "portscanner": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz",
+      "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==",
+      "dev": true,
+      "requires": {
+        "async": "^2.6.0",
+        "is-number-like": "^1.0.3"
+      }
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "postcss": {
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.5.tgz",
+      "integrity": "sha512-HBNpviAUFCKvEh7NZhw1e8MBPivRszIiUnhrJ+sBFVSYSqubrzwX3KG51mYgcRHX8j/cAgZJedONZcm5jTBdgQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.1",
+        "source-map": "^0.6.1",
+        "supports-color": "^5.5.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-css-variables": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/postcss-css-variables/-/postcss-css-variables-0.11.0.tgz",
+      "integrity": "sha512-pjqWnJSy8zoentAhRIph/DiOX0EZmT/dpmVbpdSrCSdkdqstl2ViBlAfIIuHvHI+baTV8Gd+WzsVFjDZqVn4dg==",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.3",
+        "extend": "^3.0.1",
+        "postcss": "^6.0.8"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "postcss": {
+          "version": "6.0.23",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+          "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.1",
+            "source-map": "^0.6.1",
+            "supports-color": "^5.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-import": {
+      "version": "12.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz",
+      "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.1",
+        "postcss-value-parser": "^3.2.3",
+        "read-cache": "^1.0.0",
+        "resolve": "^1.1.7"
+      }
+    },
+    "postcss-load-config": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz",
+      "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^4.0.0",
+        "import-cwd": "^2.0.0"
+      }
+    },
+    "postcss-loader": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
+      "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "postcss": "^7.0.0",
+        "postcss-load-config": "^2.0.0",
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "postcss-modules-extract-imports": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
+      "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.5"
+      }
+    },
+    "postcss-modules-local-by-default": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.3.tgz",
+      "integrity": "sha512-jv4CQ8IQ0+TkaAIP7H4kgu/jQbrjte8xU61SYJAIOby+o3H0MGWX6eN1WXUKHccK6/EEjcAERjyIP8MXzAWAbQ==",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "^0.7.0",
+        "postcss": "^7.0.6",
+        "postcss-value-parser": "^3.3.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "postcss": {
+          "version": "7.0.7",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
+          "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.1",
+            "source-map": "^0.6.1",
+            "supports-color": "^5.5.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-modules-scope": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.0.1.tgz",
+      "integrity": "sha512-7+6k9c3/AuZ5c596LJx9n923A/j3nF3ormewYBF1RrIQvjvjXe1xE8V8A1KFyFwXbvnshT6FBZFX0k/F1igneg==",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "^0.7.0",
+        "postcss": "^7.0.6"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "postcss": {
+          "version": "7.0.7",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
+          "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.1",
+            "source-map": "^0.6.1",
+            "supports-color": "^5.5.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-modules-values": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz",
+      "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==",
+      "dev": true,
+      "requires": {
+        "icss-replace-symbols": "^1.1.0",
+        "postcss": "^7.0.6"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "postcss": {
+          "version": "7.0.7",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
+          "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.1",
+            "source-map": "^0.6.1",
+            "supports-color": "^5.5.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-value-parser": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+      "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+      "dev": true
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
+    },
+    "pretty-error": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
+      "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=",
+      "dev": true,
+      "requires": {
+        "renderkid": "^2.0.1",
+        "utila": "~0.4"
+      }
+    },
+    "private": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+      "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+      "dev": true
+    },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+      "dev": true
+    },
+    "progress": {
+      "version": "1.1.8",
+      "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74="
+    },
+    "promise-inflight": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+      "dev": true
+    },
+    "prompt": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/prompt/-/prompt-1.0.0.tgz",
+      "integrity": "sha1-jlcSPDlquYiJf7Mn/Trtw+c15P4=",
+      "dev": true,
+      "requires": {
+        "colors": "^1.1.2",
+        "pkginfo": "0.x.x",
+        "read": "1.0.x",
+        "revalidator": "0.1.x",
+        "utile": "0.3.x",
+        "winston": "2.1.x"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.0.0",
+          "resolved": "http://registry.npmjs.org/async/-/async-1.0.0.tgz",
+          "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=",
+          "dev": true
+        },
+        "winston": {
+          "version": "2.1.1",
+          "resolved": "http://registry.npmjs.org/winston/-/winston-2.1.1.tgz",
+          "integrity": "sha1-PJNJ0ZYgf9G9/51LxD73JRDjoS4=",
+          "dev": true,
+          "requires": {
+            "async": "~1.0.0",
+            "colors": "1.0.x",
+            "cycle": "1.0.x",
+            "eyes": "0.1.x",
+            "isstream": "0.1.x",
+            "pkginfo": "0.3.x",
+            "stack-trace": "0.0.x"
+          },
+          "dependencies": {
+            "colors": {
+              "version": "1.0.3",
+              "resolved": "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+              "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
+              "dev": true
+            },
+            "pkginfo": {
+              "version": "0.3.1",
+              "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz",
+              "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "proxy-addr": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
+      "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
+      "dev": true,
+      "requires": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.8.0"
+      }
+    },
+    "proxy-agent": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.0.3.tgz",
+      "integrity": "sha512-PXVVVuH9tiQuxQltFJVSnXWuDtNr+8aNBP6XVDDCDiUuDN8eRCm+ii4/mFWmXWEA0w8jjJSlePa4LXlM4jIzNA==",
+      "dev": true,
+      "requires": {
+        "agent-base": "^4.2.0",
+        "debug": "^3.1.0",
+        "http-proxy-agent": "^2.1.0",
+        "https-proxy-agent": "^2.2.1",
+        "lru-cache": "^4.1.2",
+        "pac-proxy-agent": "^3.0.0",
+        "proxy-from-env": "^1.0.0",
+        "socks-proxy-agent": "^4.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "proxy-from-env": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+      "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
+      "dev": true
+    },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "psl": {
+      "version": "1.1.29",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
+      "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "pump": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+      "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "pumpify": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+      "dev": true,
+      "requires": {
+        "duplexify": "^3.6.0",
+        "inherits": "^2.0.3",
+        "pump": "^2.0.0"
+      }
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true
+    },
+    "purepack": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/purepack/-/purepack-1.0.4.tgz",
+      "integrity": "sha1-CGKC/ZOShfWGZLqam7oxzbFlzNI="
+    },
+    "qr-image": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/qr-image/-/qr-image-3.2.0.tgz",
+      "integrity": "sha1-n6gpW+rlDEoUnPn5CaHbRkqGcug="
+    },
+    "qs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+      "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+      "dev": true
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "querystringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz",
+      "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==",
+      "dev": true
+    },
+    "randombytes": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+      "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "range-parser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+      "dev": true
+    },
+    "raw-body": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
+      "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=",
+      "dev": true,
+      "requires": {
+        "bytes": "1",
+        "string_decoder": "0.10"
+      }
+    },
+    "rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+      "dev": true,
+      "requires": {
+        "deep-extend": "^0.6.0",
+        "ini": "~1.3.0",
+        "minimist": "^1.2.0",
+        "strip-json-comments": "~2.0.1"
+      }
+    },
+    "read": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+      "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
+      "dev": true,
+      "requires": {
+        "mute-stream": "~0.0.4"
+      }
+    },
+    "read-cache": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+      "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+      "dev": true,
+      "requires": {
+        "pify": "^2.3.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "requires": {
+        "load-json-file": "^1.0.0",
+        "normalize-package-data": "^2.3.2",
+        "path-type": "^1.0.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+      "dev": true,
+      "requires": {
+        "find-up": "^1.0.0",
+        "read-pkg": "^1.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+          "dev": true,
+          "requires": {
+            "path-exists": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "^2.0.0"
+          }
+        }
+      }
+    },
+    "readable-stream": {
+      "version": "1.1.14",
+      "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "0.0.1",
+        "string_decoder": "~0.10.x"
+      }
+    },
+    "readdirp": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+      "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "micromatch": "^3.1.10",
+        "readable-stream": "^2.0.2"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "dev": true,
+      "requires": {
+        "indent-string": "^2.1.0",
+        "strip-indent": "^1.0.1"
+      }
+    },
+    "regenerate": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
+      "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
+      "dev": true
+    },
+    "regenerate-unicode-properties": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz",
+      "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.4.0"
+      }
+    },
+    "regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+    },
+    "regenerator-transform": {
+      "version": "0.13.3",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.13.3.tgz",
+      "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==",
+      "dev": true,
+      "requires": {
+        "private": "^0.1.6"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "regexpp": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+      "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+      "dev": true
+    },
+    "regexpu-core": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.4.0.tgz",
+      "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.4.0",
+        "regenerate-unicode-properties": "^7.0.0",
+        "regjsgen": "^0.5.0",
+        "regjsparser": "^0.6.0",
+        "unicode-match-property-ecmascript": "^1.0.4",
+        "unicode-match-property-value-ecmascript": "^1.0.2"
+      }
+    },
+    "regjsgen": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz",
+      "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==",
+      "dev": true
+    },
+    "regjsparser": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz",
+      "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==",
+      "dev": true,
+      "requires": {
+        "jsesc": "~0.5.0"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        }
+      }
+    },
+    "relateurl": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+      "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
+      "dev": true
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "renderkid": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.2.tgz",
+      "integrity": "sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg==",
+      "dev": true,
+      "requires": {
+        "css-select": "^1.1.0",
+        "dom-converter": "~0.2",
+        "htmlparser2": "~3.3.0",
+        "strip-ansi": "^3.0.0",
+        "utila": "^0.4.0"
+      },
+      "dependencies": {
+        "domhandler": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz",
+          "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1"
+          }
+        },
+        "domutils": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz",
+          "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1"
+          }
+        },
+        "htmlparser2": {
+          "version": "3.3.0",
+          "resolved": "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
+          "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1",
+            "domhandler": "2.1",
+            "domutils": "1.1",
+            "readable-stream": "1.0"
+          }
+        },
+        "readable-stream": {
+          "version": "1.0.34",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.1",
+            "isarray": "0.0.1",
+            "string_decoder": "~0.10.x"
+          }
+        }
+      }
+    },
+    "repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "requires": {
+        "is-finite": "^1.0.0"
+      }
+    },
+    "request": {
+      "version": "2.88.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+      "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.0",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.4.3",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "request-progress": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+      "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+      "dev": true,
+      "requires": {
+        "throttleit": "^1.0.0"
+      }
+    },
+    "request-promise-core": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
+      "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.13.1"
+      }
+    },
+    "request-promise-native": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
+      "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
+      "dev": true,
+      "requires": {
+        "request-promise-core": "1.1.1",
+        "stealthy-require": "^1.1.0",
+        "tough-cookie": ">=2.3.3"
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true
+    },
+    "require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+      "dev": true
+    },
+    "requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+      "dev": true
+    },
+    "requizzle": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.1.tgz",
+      "integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=",
+      "dev": true,
+      "requires": {
+        "underscore": "~1.6.0"
+      },
+      "dependencies": {
+        "underscore": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+          "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=",
+          "dev": true
+        }
+      }
+    },
+    "resolve": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+      "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+      "dev": true,
+      "requires": {
+        "path-parse": "^1.0.5"
+      }
+    },
+    "resolve-cwd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+      "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+          "dev": true
+        }
+      }
+    },
+    "resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true
+    },
+    "resolve-pkg": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-0.1.0.tgz",
+      "integrity": "sha1-AsyZNBDik2livZcWahsHfalyVTE=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^2.0.0"
+      },
+      "dependencies": {
+        "resolve-from": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
+          "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=",
+          "dev": true
+        }
+      }
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "^2.0.0",
+        "signal-exit": "^3.0.2"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "revalidator": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz",
+      "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+      "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.0.5"
+      }
+    },
+    "ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "^2.1.0"
+      }
+    },
+    "run-queue": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+      "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1"
+      }
+    },
+    "rxjs": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+      "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "safe-json-parse": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
+      "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=",
+      "dev": true
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "~0.1.10"
+      }
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "sanitize-html": {
+      "version": "1.19.1",
+      "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.19.1.tgz",
+      "integrity": "sha512-zNYr6FvBn4bZukr9x2uny6od/9YdjCLwF+FqxivqI0YOt/m9GIxfX+tWhm52tBAPUXiTTb4bJTGVagRz5b06bw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.3.0",
+        "htmlparser2": "^3.9.0",
+        "lodash.clonedeep": "^4.5.0",
+        "lodash.escaperegexp": "^4.1.2",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.mergewith": "^4.6.0",
+        "postcss": "^6.0.14",
+        "srcset": "^1.0.0",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "domelementtype": {
+          "version": "1.3.0",
+          "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+          "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+          "dev": true
+        },
+        "entities": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+          "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+          "dev": true
+        },
+        "htmlparser2": {
+          "version": "3.10.0",
+          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
+          "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
+          "dev": true,
+          "requires": {
+            "domelementtype": "^1.3.0",
+            "domhandler": "^2.3.0",
+            "domutils": "^1.5.1",
+            "entities": "^1.1.1",
+            "inherits": "^2.0.1",
+            "readable-stream": "^3.0.6"
+          }
+        },
+        "postcss": {
+          "version": "6.0.23",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+          "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.4.1",
+            "source-map": "^0.6.1",
+            "supports-color": "^5.4.0"
+          }
+        },
+        "readable-stream": {
+          "version": "3.0.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz",
+          "integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "sass-graph": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
+      "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+      "dev": true,
+      "requires": {
+        "glob": "^7.0.0",
+        "lodash": "^4.0.0",
+        "scss-tokenizer": "^0.2.3",
+        "yargs": "^7.0.0"
+      }
+    },
+    "sass-loader": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz",
+      "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==",
+      "dev": true,
+      "requires": {
+        "clone-deep": "^2.0.1",
+        "loader-utils": "^1.0.1",
+        "lodash.tail": "^4.1.1",
+        "neo-async": "^2.5.0",
+        "pify": "^3.0.0",
+        "semver": "^5.5.0"
+      }
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+    },
+    "schema-utils": {
+      "version": "0.4.7",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
+      "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.1.0",
+        "ajv-keywords": "^3.1.0"
+      }
+    },
+    "scryptsy": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.0.0.tgz",
+      "integrity": "sha1-Jiw28CMc+nZU4jY/o5TNLexm83g="
+    },
+    "scss-tokenizer": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+      "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+      "dev": true,
+      "requires": {
+        "js-base64": "^2.1.8",
+        "source-map": "^0.4.2"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.4.4",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+          "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+          "dev": true,
+          "requires": {
+            "amdefine": ">=0.0.4"
+          }
+        }
+      }
+    },
+    "select-hose": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+      "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
+      "dev": true
+    },
+    "selfsigned": {
+      "version": "1.10.4",
+      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz",
+      "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==",
+      "dev": true,
+      "requires": {
+        "node-forge": "0.7.5"
+      },
+      "dependencies": {
+        "node-forge": {
+          "version": "0.7.5",
+          "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
+          "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==",
+          "dev": true
+        }
+      }
+    },
+    "semver": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+      "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
+      "dev": true
+    },
+    "send": {
+      "version": "0.16.2",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+      "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.6.2",
+        "mime": "1.4.1",
+        "ms": "2.0.0",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.0",
+        "statuses": "~1.4.0"
+      },
+      "dependencies": {
+        "mime": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+          "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+          "dev": true
+        }
+      }
+    },
+    "serialize-javascript": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz",
+      "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==",
+      "dev": true
+    },
+    "serve-index": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+      "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.4",
+        "batch": "0.6.1",
+        "debug": "2.6.9",
+        "escape-html": "~1.0.3",
+        "http-errors": "~1.6.2",
+        "mime-types": "~2.1.17",
+        "parseurl": "~1.3.2"
+      }
+    },
+    "serve-static": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+      "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+      "dev": true,
+      "requires": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.2",
+        "send": "0.16.2"
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "setprototypeof": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "shallow-clone": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz",
+      "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==",
+      "dev": true,
+      "requires": {
+        "is-extendable": "^0.1.1",
+        "kind-of": "^5.0.0",
+        "mixin-object": "^2.0.1"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "shelljs": {
+      "version": "0.3.0",
+      "resolved": "http://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+      "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "sitemap": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-2.1.0.tgz",
+      "integrity": "sha512-AkfA7RDVCITQo+j5CpXsMJlZ/8ENO2NtgMHYIh+YMvex2Hao/oe3MQgNa03p0aWY6srCfUA1Q02OgiWCAiuccA==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.10",
+        "url-join": "^4.0.0",
+        "xmlbuilder": "^10.0.0"
+      }
+    },
+    "slice-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+      "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^3.2.0",
+        "astral-regex": "^1.0.0",
+        "is-fullwidth-code-point": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        }
+      }
+    },
+    "smart-buffer": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz",
+      "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==",
+      "dev": true
+    },
+    "snackbarjs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/snackbarjs/-/snackbarjs-1.1.0.tgz",
+      "integrity": "sha1-pont9ExxEEdzvPIhxGk3ZosLvNY="
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.2.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "sockjs": {
+      "version": "0.3.19",
+      "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
+      "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
+      "dev": true,
+      "requires": {
+        "faye-websocket": "^0.10.0",
+        "uuid": "^3.0.1"
+      }
+    },
+    "sockjs-client": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz",
+      "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==",
+      "dev": true,
+      "requires": {
+        "debug": "^3.2.5",
+        "eventsource": "^1.0.7",
+        "faye-websocket": "~0.11.1",
+        "inherits": "^2.0.3",
+        "json3": "^3.3.2",
+        "url-parse": "^1.4.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "faye-websocket": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
+          "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
+          "dev": true,
+          "requires": {
+            "websocket-driver": ">=0.5.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "socks": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.2.tgz",
+      "integrity": "sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q==",
+      "dev": true,
+      "requires": {
+        "ip": "^1.1.5",
+        "smart-buffer": "^4.0.1"
+      }
+    },
+    "socks-proxy-agent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz",
+      "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==",
+      "dev": true,
+      "requires": {
+        "agent-base": "~4.2.0",
+        "socks": "~2.2.0"
+      }
+    },
+    "sortablejs": {
+      "version": "1.8.0-rc1",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.8.0-rc1.tgz",
+      "integrity": "sha512-umyNbQVDwRgc0SZvUB+FRUIUqACnu5vCCmK0zv/xWA3eDSOh+IZsg3GHdWvEOcUBwnykqyk760+YPgVa8HfxFg=="
+    },
+    "source-list-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+    },
+    "source-map-resolve": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.1",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.5.9",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz",
+      "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz",
+      "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+      "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
+      "dev": true
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+      "dev": true,
+      "requires": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz",
+      "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==",
+      "dev": true
+    },
+    "spdy": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz",
+      "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "handle-thing": "^2.0.0",
+        "http-deceiver": "^1.2.7",
+        "select-hose": "^2.0.0",
+        "spdy-transport": "^3.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "spdy-transport": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+      "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "detect-node": "^2.0.4",
+        "hpack.js": "^2.1.6",
+        "obuf": "^1.1.2",
+        "readable-stream": "^3.0.6",
+        "wbuf": "^1.7.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
+          "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
+          "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "split": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+      "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "through": "2"
+      }
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.0"
+      }
+    },
+    "split.js": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.5.10.tgz",
+      "integrity": "sha512-/J52X5c4ZypVwu4WAhD8E1T9uXQtNokvG6mIBHauzyA1aKH6bmETVSv3RPjBXEz6Gcc4mIThgmjGQL39LD16jQ=="
+    },
+    "split2": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/split2/-/split2-1.1.1.tgz",
+      "integrity": "sha1-Fi2bGIZfAqsvKtlYVSLbm1TEgfk=",
+      "dev": true,
+      "requires": {
+        "through2": "~2.0.0"
+      }
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "srcset": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz",
+      "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "^1.0.2",
+        "number-is-nan": "^1.0.0"
+      }
+    },
+    "ssdeep.js": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/ssdeep.js/-/ssdeep.js-0.0.2.tgz",
+      "integrity": "sha1-mItJTQ3JwxkAX9rJZj1jOO/tHyI="
+    },
+    "sshpk": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz",
+      "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==",
+      "dev": true,
+      "requires": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "dependencies": {
+        "jsbn": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+          "dev": true
+        },
+        "tweetnacl": {
+          "version": "0.14.5",
+          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+          "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+          "dev": true
+        }
+      }
+    },
+    "ssri": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+      "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+      "dev": true,
+      "requires": {
+        "figgy-pudding": "^3.5.1"
+      }
+    },
+    "stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
+      "dev": true
+    },
+    "static-eval": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.0.tgz",
+      "integrity": "sha512-6flshd3F1Gwm+Ksxq463LtFd1liC77N/PX1FVVc3OzL3hAmo2fwHFbuArkcfi7s9rTNsLEhcRmXGFZhlgy40uw==",
+      "requires": {
+        "escodegen": "^1.8.1"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "statuses": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+      "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+      "dev": true
+    },
+    "stdout-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+      "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true
+    },
+    "stream-browserify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+      "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.1",
+        "readable-stream": "^2.0.2"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "stream-each": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+      "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "stream-http": {
+      "version": "2.8.3",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+      "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "^3.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.6",
+        "to-arraybuffer": "^1.0.0",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "stream-shift": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+      "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+      "dev": true
+    },
+    "string-template": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
+      "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=",
+      "dev": true
+    },
+    "string-width": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        }
+      }
+    },
+    "string_decoder": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+      "dev": true
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "requires": {
+        "is-utf8": "^0.2.0"
+      }
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "style-loader": {
+      "version": "0.23.1",
+      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz",
+      "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+    },
+    "symbol-tree": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
+      "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=",
+      "dev": true
+    },
+    "table": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/table/-/table-5.2.2.tgz",
+      "integrity": "sha512-f8mJmuu9beQEDkKHLzOv4VxVYlU68NpdzjbGPl69i4Hx0sTopJuNxuzJd17iV2h24dAfa93u794OnDA5jqXvfQ==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.6.1",
+        "lodash": "^4.17.11",
+        "slice-ansi": "^2.0.0",
+        "string-width": "^2.1.1"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz",
+          "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "^2.0.1",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.4.1",
+            "uri-js": "^4.2.2"
+          }
+        }
+      }
+    },
+    "taffydb": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+      "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+      "dev": true
+    },
+    "tapable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.0.tgz",
+      "integrity": "sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA==",
+      "dev": true
+    },
+    "tar": {
+      "version": "2.2.1",
+      "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+      "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+      "dev": true,
+      "requires": {
+        "block-stream": "*",
+        "fstream": "^1.0.2",
+        "inherits": "2"
+      }
+    },
+    "tcp-port-used": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.1.tgz",
+      "integrity": "sha512-rwi5xJeU6utXoEIiMvVBMc9eJ2/ofzB+7nLOdnZuFTmNCLqRiQh2sMG9MqCxHU/69VC/Fwp5dV9306Qd54ll1Q==",
+      "dev": true,
+      "requires": {
+        "debug": "4.1.0",
+        "is2": "2.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
+          "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "terser": {
+      "version": "3.14.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-3.14.0.tgz",
+      "integrity": "sha512-KQC1QNKbC/K1ZUjLIWsezW7wkTJuB4v9ptQQUNOzAPVHuVf2LrwEcB0I9t2HTEYUwAFVGiiS6wc+P4ClLDc5FQ==",
+      "dev": true,
+      "requires": {
+        "commander": "~2.17.1",
+        "source-map": "~0.6.1",
+        "source-map-support": "~0.5.6"
+      }
+    },
+    "terser-webpack-plugin": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz",
+      "integrity": "sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw==",
+      "dev": true,
+      "requires": {
+        "cacache": "^11.0.2",
+        "find-cache-dir": "^2.0.0",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^1.4.0",
+        "source-map": "^0.6.1",
+        "terser": "^3.8.1",
+        "webpack-sources": "^1.1.0",
+        "worker-farm": "^1.5.2"
+      },
+      "dependencies": {
+        "find-cache-dir": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz",
+          "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^1.0.0",
+            "pkg-dir": "^3.0.0"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
+          "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
+          "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+          "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "thirty-two": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/thirty-two/-/thirty-two-0.0.2.tgz",
+      "integrity": "sha1-QlPinYywWPBIAmfFaYwOSSflS2o="
+    },
+    "throttleit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+      "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "thunkify": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz",
+      "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=",
+      "dev": true
+    },
+    "thunky": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz",
+      "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==",
+      "dev": true
+    },
+    "timers-browserify": {
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
+      "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
+      "dev": true,
+      "requires": {
+        "setimmediate": "^1.0.4"
+      }
+    },
+    "timm": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/timm/-/timm-1.6.1.tgz",
+      "integrity": "sha512-hqDTYi/bWuDxL2i6T3v6nrvkAQ/1Bc060GSkVEQZp02zTSTB4CHSKsOkliequCftQaNRcjRqUZmpGWs5FfhrNg=="
+    },
+    "tiny-lr": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz",
+      "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==",
+      "dev": true,
+      "requires": {
+        "body": "^5.1.0",
+        "debug": "^3.1.0",
+        "faye-websocket": "~0.10.0",
+        "livereload-js": "^2.3.0",
+        "object-assign": "^4.1.0",
+        "qs": "^6.4.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "tinycolor2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
+      "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "requires": {
+        "os-tmpdir": "~1.0.2"
+      }
+    },
+    "to-arraybuffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+      "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+      "dev": true
+    },
+    "to-fast-properties": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+      "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      }
+    },
+    "toposort": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
+      "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
+      "dev": true
+    },
+    "tough-cookie": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+      "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+      "dev": true,
+      "requires": {
+        "psl": "^1.1.24",
+        "punycode": "^1.4.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
+      }
+    },
+    "tr46": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+      "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "trim": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+      "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0="
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+      "dev": true
+    },
+    "trim-right": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+      "dev": true
+    },
+    "triplesec": {
+      "version": "3.0.27",
+      "resolved": "https://registry.npmjs.org/triplesec/-/triplesec-3.0.27.tgz",
+      "integrity": "sha512-FDhkxa3JYnPOerOd+8k+SBmm7cb7KkyX+xXwNFV3XV6dsQgHuRvjtbnzWfPJ2kimeR8ErjZfPd/6r7RH6epHDw==",
+      "requires": {
+        "iced-error": ">=0.0.9",
+        "iced-lock": "^1.0.1",
+        "iced-runtime": "^1.0.2",
+        "more-entropy": ">=0.0.7",
+        "progress": "~1.1.2",
+        "uglify-js": "^3.1.9"
+      }
+    },
+    "true-case-path": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
+      "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.2"
+      }
+    },
+    "tryer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",
+      "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==",
+      "dev": true
+    },
+    "tslib": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+      "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+      "dev": true
+    },
+    "tty-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+      "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.13.3",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz",
+      "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y="
+    },
+    "type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "requires": {
+        "prelude-ls": "~1.1.2"
+      }
+    },
+    "type-detect": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
+      "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=",
+      "dev": true
+    },
+    "type-is": {
+      "version": "1.6.16",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+      "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+      "dev": true,
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.18"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "ua-parser-js": {
+      "version": "0.7.19",
+      "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz",
+      "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ=="
+    },
+    "uglify-js": {
+      "version": "3.4.9",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
+      "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
+      "requires": {
+        "commander": "~2.17.1",
+        "source-map": "~0.6.1"
+      }
+    },
+    "uint64be": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz",
+      "integrity": "sha1-H3FUIC8qG4rzU4cd2mUb80zpPpU="
+    },
+    "ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true
+    },
+    "underscore": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
+      "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk="
+    },
+    "underscore-contrib": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/underscore-contrib/-/underscore-contrib-0.3.0.tgz",
+      "integrity": "sha1-ZltmwkeD+PorGMn4y7Dix9SMJsc=",
+      "dev": true,
+      "requires": {
+        "underscore": "1.6.0"
+      },
+      "dependencies": {
+        "underscore": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+          "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=",
+          "dev": true
+        }
+      }
+    },
+    "underscore.string": {
+      "version": "3.3.5",
+      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
+      "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "^1.0.3",
+        "util-deprecate": "^1.0.2"
+      }
+    },
+    "unicode-5.2.0": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/unicode-5.2.0/-/unicode-5.2.0-0.7.5.tgz",
+      "integrity": "sha512-KVGLW1Bri30x00yv4HNM8kBxoqFXr0Sbo55735nvrlsx4PYBZol3UtoWgO492fSwmsetzPEZzy73rbU8OGXJcA==",
+      "dev": true
+    },
+    "unicode-canonical-property-names-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+      "dev": true
+    },
+    "unicode-match-property-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+      "dev": true,
+      "requires": {
+        "unicode-canonical-property-names-ecmascript": "^1.0.4",
+        "unicode-property-aliases-ecmascript": "^1.0.4"
+      }
+    },
+    "unicode-match-property-value-ecmascript": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz",
+      "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==",
+      "dev": true
+    },
+    "unicode-property-aliases-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==",
+      "dev": true
+    },
+    "union-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^0.4.3"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "set-value": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "^2.0.1",
+            "is-extendable": "^0.1.1",
+            "is-plain-object": "^2.0.1",
+            "to-object-path": "^0.3.0"
+          }
+        }
+      }
+    },
+    "unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "dev": true,
+      "requires": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz",
+      "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
+    "unixify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz",
+      "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=",
+      "dev": true,
+      "requires": {
+        "normalize-path": "^2.1.1"
+      }
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "^2.0.3",
+            "has-values": "^0.1.4",
+            "isobject": "^2.0.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        }
+      }
+    },
+    "upath": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
+      "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
+      "dev": true
+    },
+    "upper-case": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+      "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
+      "dev": true
+    },
+    "uri-js": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
+        }
+      }
+    },
+    "url-join": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz",
+      "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=",
+      "dev": true
+    },
+    "url-loader": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz",
+      "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "mime": "^2.0.3",
+        "schema-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        }
+      }
+    },
+    "url-parse": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz",
+      "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==",
+      "dev": true,
+      "requires": {
+        "querystringify": "^2.0.0",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true
+    },
+    "utf8": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ=="
+    },
+    "utif": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz",
+      "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==",
+      "requires": {
+        "pako": "^1.0.5"
+      }
+    },
+    "util": {
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+      "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "util.promisify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+      "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.2",
+        "object.getownpropertydescriptors": "^2.0.3"
+      }
+    },
+    "utila": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+      "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
+      "dev": true
+    },
+    "utile": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/utile/-/utile-0.3.0.tgz",
+      "integrity": "sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo=",
+      "dev": true,
+      "requires": {
+        "async": "~0.9.0",
+        "deep-equal": "~0.2.1",
+        "i": "0.3.x",
+        "mkdirp": "0.x.x",
+        "ncp": "1.0.x",
+        "rimraf": "2.x.x"
+      },
+      "dependencies": {
+        "async": {
+          "version": "0.9.2",
+          "resolved": "http://registry.npmjs.org/async/-/async-0.9.2.tgz",
+          "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
+          "dev": true
+        },
+        "deep-equal": {
+          "version": "0.2.2",
+          "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz",
+          "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=",
+          "dev": true
+        }
+      }
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true
+    },
+    "uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true
+    },
+    "valid-data-url": {
+      "version": "0.1.6",
+      "resolved": "http://registry.npmjs.org/valid-data-url/-/valid-data-url-0.1.6.tgz",
+      "integrity": "sha512-FXg2qXMzfAhZc0y2HzELNfUeiOjPr+52hU1DNBWiJJ2luXD+dD1R9NA48Ug5aj0ibbxroeGDc/RJv6ThiGgkDw==",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "validator": {
+      "version": "9.4.1",
+      "resolved": "http://registry.npmjs.org/validator/-/validator-9.4.1.tgz",
+      "integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==",
+      "dev": true
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "vkbeautify": {
+      "version": "0.99.3",
+      "resolved": "https://registry.npmjs.org/vkbeautify/-/vkbeautify-0.99.3.tgz",
+      "integrity": "sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q=="
+    },
+    "vm-browserify": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+      "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+      "dev": true,
+      "requires": {
+        "indexof": "0.0.1"
+      }
+    },
+    "w3c-hr-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
+      "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
+      "dev": true,
+      "requires": {
+        "browser-process-hrtime": "^0.1.2"
+      }
+    },
+    "watchpack": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
+      "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^2.0.2",
+        "graceful-fs": "^4.1.2",
+        "neo-async": "^2.5.0"
+      }
+    },
+    "wbuf": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+      "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+      "dev": true,
+      "requires": {
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "web-resource-inliner": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.2.1.tgz",
+      "integrity": "sha512-fOWnBQHVX8zHvEbECDTxtYL0FXIIZZ5H3LWoez8mGopYJK7inEru1kVMDzM1lVdeJBNEqUnNP5FBGxvzuMcwwQ==",
+      "dev": true,
+      "requires": {
+        "async": "^2.1.2",
+        "chalk": "^1.1.3",
+        "datauri": "^1.0.4",
+        "htmlparser2": "^3.9.2",
+        "lodash.unescape": "^4.0.1",
+        "request": "^2.78.0",
+        "valid-data-url": "^0.1.4",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "1.3.0",
+          "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+          "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+          "dev": true
+        },
+        "entities": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+          "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+          "dev": true
+        },
+        "htmlparser2": {
+          "version": "3.10.0",
+          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
+          "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
+          "dev": true,
+          "requires": {
+            "domelementtype": "^1.3.0",
+            "domhandler": "^2.3.0",
+            "domutils": "^1.5.1",
+            "entities": "^1.1.1",
+            "inherits": "^2.0.1",
+            "readable-stream": "^3.0.6"
+          }
+        },
+        "readable-stream": {
+          "version": "3.0.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz",
+          "integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        }
+      }
+    },
+    "webidl-conversions": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+      "dev": true
+    },
+    "webpack": {
+      "version": "4.28.3",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.3.tgz",
+      "integrity": "sha512-vLZN9k5I7Nr/XB1IDG9GbZB4yQd1sPuvufMFgJkx0b31fi2LD97KQIjwjxE7xytdruAYfu5S0FLBLjdxmwGJCg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.7.11",
+        "@webassemblyjs/helper-module-context": "1.7.11",
+        "@webassemblyjs/wasm-edit": "1.7.11",
+        "@webassemblyjs/wasm-parser": "1.7.11",
+        "acorn": "^5.6.2",
+        "acorn-dynamic-import": "^3.0.0",
+        "ajv": "^6.1.0",
+        "ajv-keywords": "^3.1.0",
+        "chrome-trace-event": "^1.0.0",
+        "enhanced-resolve": "^4.1.0",
+        "eslint-scope": "^4.0.0",
+        "json-parse-better-errors": "^1.0.2",
+        "loader-runner": "^2.3.0",
+        "loader-utils": "^1.1.0",
+        "memory-fs": "~0.4.1",
+        "micromatch": "^3.1.8",
+        "mkdirp": "~0.5.0",
+        "neo-async": "^2.5.0",
+        "node-libs-browser": "^2.0.0",
+        "schema-utils": "^0.4.4",
+        "tapable": "^1.1.0",
+        "terser-webpack-plugin": "^1.1.0",
+        "watchpack": "^1.5.0",
+        "webpack-sources": "^1.3.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.7.3",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+          "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-bundle-analyzer": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.3.tgz",
+      "integrity": "sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw==",
+      "dev": true,
+      "requires": {
+        "acorn": "^5.7.3",
+        "bfj": "^6.1.1",
+        "chalk": "^2.4.1",
+        "commander": "^2.18.0",
+        "ejs": "^2.6.1",
+        "express": "^4.16.3",
+        "filesize": "^3.6.1",
+        "gzip-size": "^5.0.0",
+        "lodash": "^4.17.10",
+        "mkdirp": "^0.5.1",
+        "opener": "^1.5.1",
+        "ws": "^6.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.7.3",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+          "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "commander": {
+          "version": "2.19.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
+          "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "ws": {
+          "version": "6.1.2",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz",
+          "integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==",
+          "dev": true,
+          "requires": {
+            "async-limiter": "~1.0.0"
+          }
+        }
+      }
+    },
+    "webpack-dev-middleware": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz",
+      "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==",
+      "dev": true,
+      "requires": {
+        "memory-fs": "~0.4.1",
+        "mime": "^2.3.1",
+        "range-parser": "^1.0.3",
+        "webpack-log": "^2.0.0"
+      }
+    },
+    "webpack-dev-server": {
+      "version": "3.1.14",
+      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz",
+      "integrity": "sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==",
+      "dev": true,
+      "requires": {
+        "ansi-html": "0.0.7",
+        "bonjour": "^3.5.0",
+        "chokidar": "^2.0.0",
+        "compression": "^1.5.2",
+        "connect-history-api-fallback": "^1.3.0",
+        "debug": "^3.1.0",
+        "del": "^3.0.0",
+        "express": "^4.16.2",
+        "html-entities": "^1.2.0",
+        "http-proxy-middleware": "~0.18.0",
+        "import-local": "^2.0.0",
+        "internal-ip": "^3.0.1",
+        "ip": "^1.1.5",
+        "killable": "^1.0.0",
+        "loglevel": "^1.4.1",
+        "opn": "^5.1.0",
+        "portfinder": "^1.0.9",
+        "schema-utils": "^1.0.0",
+        "selfsigned": "^1.9.1",
+        "semver": "^5.6.0",
+        "serve-index": "^1.7.2",
+        "sockjs": "0.3.19",
+        "sockjs-client": "1.3.0",
+        "spdy": "^4.0.0",
+        "strip-ansi": "^3.0.0",
+        "supports-color": "^5.1.0",
+        "url": "^0.11.0",
+        "webpack-dev-middleware": "3.4.0",
+        "webpack-log": "^2.0.0",
+        "yargs": "12.0.2"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "camelcase": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+          "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+          "dev": true
+        },
+        "cliui": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+          "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^2.1.1",
+            "strip-ansi": "^4.0.0",
+            "wrap-ansi": "^2.0.0"
+          },
+          "dependencies": {
+            "strip-ansi": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^3.0.0"
+              }
+            }
+          }
+        },
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "decamelize": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz",
+          "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==",
+          "dev": true,
+          "requires": {
+            "xregexp": "4.0.0"
+          }
+        },
+        "execa": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+          "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^6.0.0",
+            "get-stream": "^4.0.0",
+            "is-stream": "^1.1.0",
+            "npm-run-path": "^2.0.0",
+            "p-finally": "^1.0.0",
+            "signal-exit": "^3.0.0",
+            "strip-eof": "^1.0.0"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+          "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "invert-kv": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+          "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+          "dev": true
+        },
+        "lcid": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+          "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+          "dev": true,
+          "requires": {
+            "invert-kv": "^2.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "os-locale": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+          "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+          "dev": true,
+          "requires": {
+            "execa": "^1.0.0",
+            "lcid": "^2.0.0",
+            "mem": "^4.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
+          "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
+          "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+          "dev": true
+        },
+        "pump": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+          "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        },
+        "schema-utils": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+          "dev": true,
+          "requires": {
+            "ajv": "^6.1.0",
+            "ajv-errors": "^1.0.0",
+            "ajv-keywords": "^3.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "which-module": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+          "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+          "dev": true
+        },
+        "xregexp": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz",
+          "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==",
+          "dev": true
+        },
+        "yargs": {
+          "version": "12.0.2",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz",
+          "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==",
+          "dev": true,
+          "requires": {
+            "cliui": "^4.0.0",
+            "decamelize": "^2.0.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^1.0.1",
+            "os-locale": "^3.0.0",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^1.0.1",
+            "set-blocking": "^2.0.0",
+            "string-width": "^2.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^3.2.1 || ^4.0.0",
+            "yargs-parser": "^10.1.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "10.1.0",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+          "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^4.1.0"
+          }
+        }
+      }
+    },
+    "webpack-log": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+      "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+      "dev": true,
+      "requires": {
+        "ansi-colors": "^3.0.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "webpack-node-externals": {
+      "version": "1.7.2",
+      "resolved": "http://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz",
+      "integrity": "sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg==",
+      "dev": true
+    },
+    "webpack-sources": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz",
+      "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "^2.0.0",
+        "source-map": "~0.6.1"
+      }
+    },
+    "websocket-driver": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
+      "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
+      "dev": true,
+      "requires": {
+        "http-parser-js": ">=0.4.0",
+        "websocket-extensions": ">=0.1.1"
+      }
+    },
+    "websocket-extensions": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+      "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+      "dev": true
+    },
+    "websocket-stream": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.1.2.tgz",
+      "integrity": "sha512-lchLOk435iDWs0jNuL+hiU14i3ERSrMA0IKSiJh7z6X/i4XNsutBZrtqu2CPOZuA4G/zabiqVAos0vW+S7GEVw==",
+      "dev": true,
+      "requires": {
+        "duplexify": "^3.5.1",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.3",
+        "safe-buffer": "^5.1.1",
+        "ws": "^3.2.0",
+        "xtend": "^4.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        },
+        "ws": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+          "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+          "dev": true,
+          "requires": {
+            "async-limiter": "~1.0.0",
+            "safe-buffer": "~5.1.0",
+            "ultron": "~1.1.0"
+          }
+        }
+      }
+    },
+    "whatwg-encoding": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+      "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+      "dev": true,
+      "requires": {
+        "iconv-lite": "0.4.24"
+      }
+    },
+    "whatwg-mimetype": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.2.0.tgz",
+      "integrity": "sha512-5YSO1nMd5D1hY3WzAQV3PzZL83W3YeyR1yW9PcH26Weh1t+Vzh9B6XkDh7aXm83HBZ4nSMvkjvN2H2ySWIvBgw==",
+      "dev": true
+    },
+    "whatwg-url": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+      "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+      "dev": true,
+      "requires": {
+        "lodash.sortby": "^4.7.0",
+        "tr46": "^1.0.1",
+        "webidl-conversions": "^4.0.2"
+      }
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "requires": {
+        "isexe": "^2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+      "dev": true
+    },
+    "wide-align": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+      "dev": true,
+      "requires": {
+        "string-width": "^1.0.2 || 2"
+      }
+    },
+    "winston": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.4.tgz",
+      "integrity": "sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "async": "~1.0.0",
+        "colors": "1.0.x",
+        "cycle": "1.0.x",
+        "eyes": "0.1.x",
+        "isstream": "0.1.x",
+        "stack-trace": "0.0.x"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.0.0",
+          "resolved": "http://registry.npmjs.org/async/-/async-1.0.0.tgz",
+          "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=",
+          "dev": true,
+          "optional": true
+        },
+        "colors": {
+          "version": "1.0.3",
+          "resolved": "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+          "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
+    },
+    "worker-farm": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
+      "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==",
+      "dev": true,
+      "requires": {
+        "errno": "~0.1.7"
+      }
+    },
+    "worker-loader": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz",
+      "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.0.0",
+        "schema-utils": "^0.4.0"
+      }
+    },
+    "wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "dev": true,
+      "requires": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        }
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "write": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "dev": true,
+      "requires": {
+        "mkdirp": "^0.5.1"
+      }
+    },
+    "ws": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "dev": true,
+      "requires": {
+        "async-limiter": "~1.0.0"
+      }
+    },
+    "xhr": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
+      "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
+      "requires": {
+        "global": "~4.3.0",
+        "is-function": "^1.0.1",
+        "parse-headers": "^2.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "xml-name-validator": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+      "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+      "dev": true
+    },
+    "xml-parse-from-string": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
+      "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig="
+    },
+    "xml2js": {
+      "version": "0.4.19",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+      "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+      "requires": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~9.0.1"
+      },
+      "dependencies": {
+        "xmlbuilder": {
+          "version": "9.0.7",
+          "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+          "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+        }
+      }
+    },
+    "xmlbuilder": {
+      "version": "10.1.1",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz",
+      "integrity": "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==",
+      "dev": true
+    },
+    "xmlcreate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz",
+      "integrity": "sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8=",
+      "dev": true
+    },
+    "xmldom": {
+      "version": "0.1.27",
+      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
+      "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk="
+    },
+    "xpath": {
+      "version": "0.0.27",
+      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
+      "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ=="
+    },
+    "xregexp": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.2.4.tgz",
+      "integrity": "sha512-sO0bYdYeJAJBcJA8g7MJJX7UrOZIfJPd8U2SC7B2Dd/J24U0aQNoGp33shCaBSWeb0rD5rh6VBUIXOkGal1TZA==",
+      "requires": {
+        "@babel/runtime-corejs2": "^7.2.0"
+      }
+    },
+    "xtend": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+    },
+    "y18n": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+      "dev": true
+    },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+      "dev": true
+    },
+    "yargs": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+      "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+      "dev": true,
+      "requires": {
+        "camelcase": "^3.0.0",
+        "cliui": "^3.2.0",
+        "decamelize": "^1.1.1",
+        "get-caller-file": "^1.0.1",
+        "os-locale": "^1.4.0",
+        "read-pkg-up": "^1.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^1.0.1",
+        "set-blocking": "^2.0.0",
+        "string-width": "^1.0.2",
+        "which-module": "^1.0.0",
+        "y18n": "^3.2.1",
+        "yargs-parser": "^5.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+      "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+      "dev": true,
+      "requires": {
+        "camelcase": "^3.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "dev": true
+        }
+      }
+    },
+    "yauzl": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+      "dev": true,
+      "requires": {
+        "fd-slicer": "~1.0.1"
+      }
+    },
+    "zlibjs": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
+      "integrity": "sha1-UBl+2yihxCymWcyLTmqd3W1ERVQ="
+    }
+  }
+}

+ 104 - 52
package.json

@@ -1,6 +1,6 @@
 {
   "name": "cyberchef",
-  "version": "5.7.2",
+  "version": "8.24.2",
   "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
   "author": "n1474335 <n1474335@gmail.com>",
   "homepage": "https://gchq.github.io/CyberChef",
@@ -30,69 +30,121 @@
   "main": "build/node/CyberChef.js",
   "bugs": "https://github.com/gchq/CyberChef/issues",
   "devDependencies": {
-    "babel-core": "^6.24.0",
-    "babel-loader": "^6.4.0",
-    "babel-polyfill": "^6.23.0",
-    "babel-preset-env": "^1.2.2",
-    "css-loader": "^0.27.3",
-    "exports-loader": "^0.6.4",
-    "extract-text-webpack-plugin": "^2.1.0",
-    "file-loader": "^0.10.1",
-    "grunt": ">=0.4.5",
-    "grunt-accessibility": "~5.0.0",
+    "@babel/core": "^7.2.2",
+    "@babel/preset-env": "^7.2.3",
+    "autoprefixer": "^9.4.3",
+    "babel-eslint": "^10.0.1",
+    "babel-loader": "^8.0.4",
+    "babel-plugin-syntax-dynamic-import": "^6.18.0",
+    "bootstrap": "^4.2.1",
+    "chromedriver": "^2.45.0",
+    "colors": "^1.3.3",
+    "css-loader": "^2.1.0",
+    "eslint": "^5.12.1",
+    "exports-loader": "^0.7.0",
+    "file-loader": "^3.0.1",
+    "grunt": "^1.0.3",
+    "grunt-accessibility": "~6.0.0",
     "grunt-chmod": "~1.1.1",
-    "grunt-contrib-clean": "~1.0.0",
+    "grunt-concurrent": "^2.3.1",
+    "grunt-contrib-clean": "~2.0.0",
+    "grunt-contrib-connect": "^2.0.0",
     "grunt-contrib-copy": "~1.0.0",
-    "grunt-eslint": "^19.0.0",
-    "grunt-exec": "~1.0.1",
-    "grunt-execute": "^0.2.2",
-    "grunt-jsdoc": "^2.1.0",
-    "grunt-webpack": "^2.0.1",
-    "html-webpack-plugin": "^2.28.0",
-    "imports-loader": "^0.7.1",
-    "ink-docstrap": "^1.1.4",
-    "jsdoc-babel": "^0.3.0",
-    "less": "^2.7.2",
-    "less-loader": "^4.0.3",
-    "postcss-css-variables": "^0.7.0",
-    "postcss-import": "^10.0.0",
-    "postcss-loader": "^2.0.5",
-    "style-loader": "^0.15.0",
-    "url-loader": "^0.5.8",
-    "web-resource-inliner": "^4.1.0",
-    "webpack": "^2.2.1"
+    "grunt-contrib-watch": "^1.1.0",
+    "grunt-eslint": "^21.0.0",
+    "grunt-exec": "~3.0.0",
+    "grunt-jsdoc": "^2.3.0",
+    "grunt-webpack": "^3.1.3",
+    "html-webpack-plugin": "^3.2.0",
+    "imports-loader": "^0.8.0",
+    "ink-docstrap": "^1.3.2",
+    "jsdoc-babel": "^0.5.0",
+    "mini-css-extract-plugin": "^0.5.0",
+    "nightwatch": "^1.0.18",
+    "node-sass": "^4.11.0",
+    "postcss-css-variables": "^0.11.0",
+    "postcss-import": "^12.0.1",
+    "postcss-loader": "^3.0.0",
+    "prompt": "^1.0.0",
+    "sass-loader": "^7.1.0",
+    "sitemap": "^2.1.0",
+    "style-loader": "^0.23.1",
+    "url-loader": "^1.1.2",
+    "web-resource-inliner": "^4.2.1",
+    "webpack": "^4.28.3",
+    "webpack-bundle-analyzer": "^3.0.3",
+    "webpack-dev-server": "^3.1.14",
+    "webpack-node-externals": "^1.7.2",
+    "worker-loader": "^2.0.0"
   },
   "dependencies": {
-    "bootstrap": "^3.3.7",
-    "bootstrap-colorpicker": "^2.5.1",
-    "bootstrap-switch": "^3.3.4",
-    "crypto-api": "^0.6.2",
+    "arrive": "^2.4.1",
+    "babel-plugin-transform-builtin-extend": "1.1.2",
+    "babel-polyfill": "^6.26.0",
+    "bcryptjs": "^2.4.3",
+    "bignumber.js": "^8.0.2",
+    "bootstrap-colorpicker": "^2.5.3",
+    "bootstrap-material-design": "^4.1.1",
+    "bson": "^4.0.1",
+    "chi-squared": "^1.1.0",
+    "crypto-api": "^0.8.3",
     "crypto-js": "^3.1.9-1",
     "d3": "^4.9.1",
     "d3-hexbin": "^0.2.2",
-    "diff": "^3.2.0",
-    "escodegen": "^1.8.1",
+    "ctph.js": "0.0.5",
+    "diff": "^3.5.0",
+    "es6-promisify": "^6.0.1",
+    "escodegen": "^1.11.0",
     "esmangle": "^1.0.1",
-    "esprima": "^3.1.3",
-    "exif-parser": "^0.1.9",
-    "google-code-prettify": "^1.0.5",
-    "jquery": "^3.1.1",
-    "jsbn": "^1.1.0",
-    "jsrsasign": "7.1.3",
-    "lodash": "^4.17.4",
-    "moment": "^2.17.1",
-    "moment-timezone": "^0.5.11",
-    "sladex-blowfish": "^0.8.1",
-    "sortablejs": "^1.5.1",
-    "split.js": "^1.2.0",
-    "vkbeautify": "^0.99.1",
+    "esprima": "^4.0.1",
+    "exif-parser": "^0.1.12",
+    "file-saver": "^2.0.0",
+    "geodesy": "^1.1.3",
+    "highlight.js": "^9.13.1",
+    "jimp": "^0.6.0",
+    "jquery": "^3.3.1",
+    "js-crc": "^0.2.0",
+    "js-sha3": "^0.8.0",
+    "jsesc": "^2.5.2",
+    "jsonpath": "^1.0.0",
+    "jsonwebtoken": "^8.4.0",
+    "jsqr": "^1.1.1",
+    "jsrsasign": "8.0.12",
+    "kbpgp": "^2.0.82",
+    "libyara-wasm": "0.0.11",
+    "lodash": "^4.17.11",
+    "loglevel": "^1.6.1",
+    "loglevel-message-prefix": "^3.0.0",
+    "moment": "^2.23.0",
+    "moment-timezone": "^0.5.23",
+    "ngeohash": "^0.6.3",
+    "node-forge": "^0.7.6",
+    "node-md6": "^0.1.0",
+    "notepack.io": "^2.2.0",
+    "nwmatcher": "^1.4.4",
+    "otp": "^0.1.3",
+    "popper.js": "^1.14.6",
+    "qr-image": "^3.2.0",
+    "scryptsy": "^2.0.0",
+    "snackbarjs": "^1.1.0",
+    "sortablejs": "^1.8.0-rc1",
+    "split.js": "^1.5.10",
+    "ssdeep.js": "0.0.2",
+    "ua-parser-js": "^0.7.19",
+    "utf8": "^3.0.0",
+    "vkbeautify": "^0.99.3",
     "xmldom": "^0.1.27",
-    "xpath": "0.0.24",
-    "zlibjs": "^0.2.0"
+    "xpath": "0.0.27",
+    "xregexp": "^4.2.4",
+    "zlibjs": "^0.3.1"
   },
   "scripts": {
+    "start": "grunt dev",
     "build": "grunt prod",
     "test": "grunt test",
-    "docs": "grunt docs"
+    "testui": "grunt testui",
+    "docs": "grunt docs",
+    "lint": "grunt lint",
+    "newop": "node --experimental-modules src/core/config/scripts/newOperation.mjs"
   }
 }

+ 0 - 126
src/core/Chef.js

@@ -1,126 +0,0 @@
-import Dish from "./Dish.js";
-import Recipe from "./Recipe.js";
-
-
-/**
- * The main controller for CyberChef.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @class
- */
-const Chef = function() {
-    this.dish = new Dish();
-};
-
-
-/**
- * Runs the recipe over the input.
- *
- * @param {string} inputText - The input data as a string
- * @param {Object[]} recipeConfig - The recipe configuration object
- * @param {Object} options - The options object storing various user choices
- * @param {boolean} options.attempHighlight - Whether or not to attempt highlighting
- * @param {number} progress - The position in the recipe to start from
- * @param {number} [step] - Whether to only execute one operation in the recipe
- *
- * @returns {Object} response
- * @returns {string} response.result - The output of the recipe
- * @returns {string} response.type - The data type of the result
- * @returns {number} response.progress - The position that we have got to in the recipe
- * @returns {number} response.options - The app options object (which may have been changed)
- * @returns {number} response.duration - The number of ms it took to execute the recipe
- * @returns {number} response.error - The error object thrown by a failed operation (false if no error)
-*/
-Chef.prototype.bake = async function(inputText, recipeConfig, options, progress, step) {
-    let startTime  = new Date().getTime(),
-        recipe     = new Recipe(recipeConfig),
-        containsFc = recipe.containsFlowControl(),
-        error      = false;
-
-    // Reset attemptHighlight flag
-    if (options.hasOwnProperty("attemptHighlight")) {
-        options.attemptHighlight = true;
-    }
-
-    if (containsFc) options.attemptHighlight = false;
-
-    // Clean up progress
-    if (progress >= recipeConfig.length) {
-        progress = 0;
-    }
-
-    if (step) {
-        // Unset breakpoint on this step
-        recipe.setBreakpoint(progress, false);
-        // Set breakpoint on next step
-        recipe.setBreakpoint(progress + 1, true);
-    }
-
-    // If stepping with flow control, we have to start from the beginning
-    // but still want to skip all previous breakpoints
-    if (progress > 0 && containsFc) {
-        recipe.removeBreaksUpTo(progress);
-        progress = 0;
-    }
-
-    // If starting from scratch, load data
-    if (progress === 0) {
-        this.dish.set(inputText, Dish.STRING);
-    }
-
-    try {
-        progress = await recipe.execute(this.dish, progress);
-    } catch (err) {
-        // Return the error in the result so that everything else gets correctly updated
-        // rather than throwing it here and losing state info.
-        error = err;
-        progress = err.progress;
-    }
-
-    return {
-        result: this.dish.type === Dish.HTML ?
-            this.dish.get(Dish.HTML) :
-            this.dish.get(Dish.STRING),
-        type: Dish.enumLookup(this.dish.type),
-        progress: progress,
-        options: options,
-        duration: new Date().getTime() - startTime,
-        error: error
-    };
-};
-
-
-/**
- * When a browser tab is unfocused and the browser has to run lots of dynamic content in other tabs,
- * it swaps out the memory for that tab. If the CyberChef tab has been unfocused for more than a
- * minute, we run a silent bake which will force the browser to load and cache all the relevant
- * JavaScript code needed to do a real bake.
- *
- * This will stop baking taking a long time when the CyberChef browser tab has been unfocused for a
- * long time and the browser has swapped out all its memory.
- *
- * The output will not be modified (hence "silent" bake).
- *
- * This will only actually execute the recipe if auto-bake is enabled, otherwise it will just load
- * the recipe, ingredients and dish.
- *
- * @param {Object[]} recipeConfig - The recipe configuration object
- * @returns {number} The time it took to run the silent bake in milliseconds.
-*/
-Chef.prototype.silentBake = function(recipeConfig) {
-    let startTime = new Date().getTime(),
-        recipe    = new Recipe(recipeConfig),
-        dish      = new Dish("", Dish.STRING);
-
-    try {
-        recipe.execute(dish);
-    } catch (err) {
-        // Suppress all errors
-    }
-    return new Date().getTime() - startTime;
-};
-
-export default Chef;

+ 198 - 0
src/core/Chef.mjs

@@ -0,0 +1,198 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Dish from "./Dish";
+import Recipe from "./Recipe";
+import log from "loglevel";
+
+/**
+ * The main controller for CyberChef.
+ */
+class Chef {
+
+    /**
+     * Chef constructor
+     */
+    constructor() {
+        this.dish = new Dish();
+    }
+
+
+    /**
+     * Runs the recipe over the input.
+     *
+     * @param {string|ArrayBuffer} input - The input data as a string or ArrayBuffer
+     * @param {Object[]} recipeConfig - The recipe configuration object
+     * @param {Object} options - The options object storing various user choices
+     * @param {boolean} options.attempHighlight - Whether or not to attempt highlighting
+     * @param {number} progress - The position in the recipe to start from
+     * @param {number} [step] - Whether to only execute one operation in the recipe
+     *
+     * @returns {Object} response
+     * @returns {string} response.result - The output of the recipe
+     * @returns {string} response.type - The data type of the result
+     * @returns {number} response.progress - The position that we have got to in the recipe
+     * @returns {number} response.duration - The number of ms it took to execute the recipe
+     * @returns {number} response.error - The error object thrown by a failed operation (false if no error)
+    */
+    async bake(input, recipeConfig, options, progress, step) {
+        log.debug("Chef baking");
+        const startTime = new Date().getTime(),
+            recipe      = new Recipe(recipeConfig),
+            containsFc  = recipe.containsFlowControl(),
+            notUTF8     = options && options.hasOwnProperty("treatAsUtf8") && !options.treatAsUtf8;
+        let error = false;
+
+        if (containsFc && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
+
+        // Clean up progress
+        if (progress >= recipeConfig.length) {
+            progress = 0;
+        }
+
+        if (step) {
+            // Unset breakpoint on this step
+            recipe.setBreakpoint(progress, false);
+            // Set breakpoint on next step
+            recipe.setBreakpoint(progress + 1, true);
+        }
+
+        // If the previously run operation presented a different value to its
+        // normal output, we need to recalculate it.
+        if (recipe.lastOpPresented(progress)) {
+            progress = 0;
+        }
+
+        // If stepping with flow control, we have to start from the beginning
+        // but still want to skip all previous breakpoints
+        if (progress > 0 && containsFc) {
+            recipe.removeBreaksUpTo(progress);
+            progress = 0;
+        }
+
+        // If starting from scratch, load data
+        if (progress === 0) {
+            const type = input instanceof ArrayBuffer ? Dish.ARRAY_BUFFER : Dish.STRING;
+            this.dish.set(input, type);
+        }
+
+        try {
+            progress = await recipe.execute(this.dish, progress);
+        } catch (err) {
+            log.error(err);
+            error = {
+                displayStr: err.displayStr,
+            };
+            progress = err.progress;
+        }
+
+        // Depending on the size of the output, we may send it back as a string or an ArrayBuffer.
+        // This can prevent unnecessary casting as an ArrayBuffer can be easily downloaded as a file.
+        // The threshold is specified in KiB.
+        const threshold = (options.ioDisplayThreshold || 1024) * 1024;
+        const returnType = this.dish.size > threshold ? Dish.ARRAY_BUFFER : Dish.STRING;
+
+        // Create a raw version of the dish, unpresented
+        const rawDish = this.dish.clone();
+
+        // Present the raw result
+        await recipe.present(this.dish);
+
+        return {
+            dish: rawDish,
+            result: this.dish.type === Dish.HTML ?
+                await this.dish.get(Dish.HTML, notUTF8) :
+                await this.dish.get(returnType, notUTF8),
+            type: Dish.enumLookup(this.dish.type),
+            progress: progress,
+            duration: new Date().getTime() - startTime,
+            error: error
+        };
+    }
+
+
+    /**
+     * When a browser tab is unfocused and the browser has to run lots of dynamic content in other tabs,
+     * it swaps out the memory for that tab. If the CyberChef tab has been unfocused for more than a
+     * minute, we run a silent bake which will force the browser to load and cache all the relevant
+     * JavaScript code needed to do a real bake.
+     *
+     * This will stop baking taking a long time when the CyberChef browser tab has been unfocused for a
+     * long time and the browser has swapped out all its memory.
+     *
+     * The output will not be modified (hence "silent" bake).
+     *
+     * This will only actually execute the recipe if auto-bake is enabled, otherwise it will just load
+     * the recipe, ingredients and dish.
+     *
+     * @param {Object[]} recipeConfig - The recipe configuration object
+     * @returns {number} The time it took to run the silent bake in milliseconds.
+    */
+    silentBake(recipeConfig) {
+        log.debug("Running silent bake");
+
+        const startTime = new Date().getTime(),
+            recipe = new Recipe(recipeConfig),
+            dish = new Dish();
+
+        try {
+            recipe.execute(dish);
+        } catch (err) {
+            // Suppress all errors
+        }
+        return new Date().getTime() - startTime;
+    }
+
+
+    /**
+     * Calculates highlight offsets if possible.
+     *
+     * @param {Object[]} recipeConfig
+     * @param {string} direction
+     * @param {Object} pos - The position object for the highlight.
+     * @param {number} pos.start - The start offset.
+     * @param {number} pos.end - The end offset.
+     * @returns {Object}
+     */
+    async calculateHighlights(recipeConfig, direction, pos) {
+        const recipe = new Recipe(recipeConfig);
+        const highlights = await recipe.generateHighlightList();
+
+        if (!highlights) return false;
+
+        for (let i = 0; i < highlights.length; i++) {
+            // Remove multiple highlights before processing again
+            pos = [pos[0]];
+
+            const func = direction === "forward" ? highlights[i].f : highlights[i].b;
+
+            if (typeof func == "function") {
+                pos = func(pos, highlights[i].args);
+            }
+        }
+
+        return {
+            pos: pos,
+            direction: direction
+        };
+    }
+
+
+    /**
+     * Translates the dish to a specified type and returns it.
+     *
+     * @param {Dish} dish
+     * @param {string} type
+     * @returns {Dish}
+     */
+    async getDishAs(dish, type) {
+        const newDish = new Dish(dish);
+        return await newDish.get(type);
+    }
+
+}
+
+export default Chef;

+ 235 - 0
src/core/ChefWorker.js

@@ -0,0 +1,235 @@
+/**
+ * Web Worker to handle communications between the front-end and the core.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+
+import "babel-polyfill";
+import Chef from "./Chef";
+import OperationConfig from "./config/OperationConfig.json";
+import OpModules from "./config/modules/OpModules";
+
+// Add ">" to the start of all log messages in the Chef Worker
+import loglevelMessagePrefix from "loglevel-message-prefix";
+
+loglevelMessagePrefix(log, {
+    prefixes: [],
+    staticPrefixes: [">"],
+    prefixFormat: "%p"
+});
+
+
+// Set up Chef instance
+self.chef = new Chef();
+
+self.OpModules = OpModules;
+self.OperationConfig = OperationConfig;
+
+// Tell the app that the worker has loaded and is ready to operate
+self.postMessage({
+    action: "workerLoaded",
+    data: {}
+});
+
+/**
+ * Respond to message from parent thread.
+ *
+ * Messages should have the following format:
+ * {
+ *     action: "bake" | "silentBake",
+ *     data: {
+ *         input: {string},
+ *         recipeConfig: {[Object]},
+ *         options: {Object},
+ *         progress: {number},
+ *         step: {boolean}
+ *     } | undefined
+ * }
+ */
+self.addEventListener("message", function(e) {
+    // Handle message
+    const r = e.data;
+    log.debug("ChefWorker receiving command '" + r.action + "'");
+
+    switch (r.action) {
+        case "bake":
+            bake(r.data);
+            break;
+        case "silentBake":
+            silentBake(r.data);
+            break;
+        case "getDishAs":
+            getDishAs(r.data);
+            break;
+        case "docURL":
+            // Used to set the URL of the current document so that scripts can be
+            // imported into an inline worker.
+            self.docURL = r.data;
+            break;
+        case "highlight":
+            calculateHighlights(
+                r.data.recipeConfig,
+                r.data.direction,
+                r.data.pos
+            );
+            break;
+        case "setLogLevel":
+            log.setLevel(r.data, false);
+            break;
+        default:
+            break;
+    }
+});
+
+
+/**
+ * Baking handler
+ *
+ * @param {Object} data
+ */
+async function bake(data) {
+    // Ensure the relevant modules are loaded
+    self.loadRequiredModules(data.recipeConfig);
+
+    try {
+        const response = await self.chef.bake(
+            data.input,          // The user's input
+            data.recipeConfig,   // The configuration of the recipe
+            data.options,        // Options set by the user
+            data.progress,       // The current position in the recipe
+            data.step            // Whether or not to take one step or execute the whole recipe
+        );
+
+        self.postMessage({
+            action: "bakeComplete",
+            data: Object.assign(response, {
+                id: data.id
+            })
+        });
+    } catch (err) {
+        self.postMessage({
+            action: "bakeError",
+            data: Object.assign(err, {
+                id: data.id
+            })
+        });
+    }
+}
+
+
+/**
+ * Silent baking handler
+ */
+function silentBake(data) {
+    const duration = self.chef.silentBake(data.recipeConfig);
+
+    self.postMessage({
+        action: "silentBakeComplete",
+        data: duration
+    });
+}
+
+
+/**
+ * Translates the dish to a given type.
+ */
+async function getDishAs(data) {
+    const value = await self.chef.getDishAs(data.dish, data.type);
+
+    self.postMessage({
+        action: "dishReturned",
+        data: {
+            value: value,
+            id: data.id
+        }
+    });
+}
+
+
+/**
+ * Calculates highlight offsets if possible.
+ *
+ * @param {Object[]} recipeConfig
+ * @param {string} direction
+ * @param {Object} pos - The position object for the highlight.
+ * @param {number} pos.start - The start offset.
+ * @param {number} pos.end - The end offset.
+ */
+async function calculateHighlights(recipeConfig, direction, pos) {
+    pos = await self.chef.calculateHighlights(recipeConfig, direction, pos);
+
+    self.postMessage({
+        action: "highlightsCalculated",
+        data: pos
+    });
+}
+
+
+/**
+ * Checks that all required modules are loaded and loads them if not.
+ *
+ * @param {Object} recipeConfig
+ */
+self.loadRequiredModules = function(recipeConfig) {
+    recipeConfig.forEach(op => {
+        const module = self.OperationConfig[op.op].module;
+
+        if (!OpModules.hasOwnProperty(module)) {
+            log.info(`Loading ${module} module`);
+            self.sendStatusMessage(`Loading ${module} module`);
+            self.importScripts(`${self.docURL}/${module}.js`);
+            self.sendStatusMessage("");
+        }
+    });
+};
+
+
+/**
+ * Send status update to the app.
+ *
+ * @param {string} msg
+ */
+self.sendStatusMessage = function(msg) {
+    self.postMessage({
+        action: "statusMessage",
+        data: msg
+    });
+};
+
+
+/**
+ * Send an option value update to the app.
+ *
+ * @param {string} option
+ * @param {*} value
+ */
+self.setOption = function(option, value) {
+    self.postMessage({
+        action: "optionUpdate",
+        data: {
+            option: option,
+            value: value
+        }
+    });
+};
+
+
+/**
+ * Send register values back to the app.
+ *
+ * @param {number} opIndex
+ * @param {number} numPrevRegisters
+ * @param {string[]} registers
+ */
+self.setRegisters = function(opIndex, numPrevRegisters, registers) {
+    self.postMessage({
+        action: "setRegisters",
+        data: {
+            opIndex: opIndex,
+            numPrevRegisters: numPrevRegisters,
+            registers: registers
+        }
+    });
+};

+ 0 - 206
src/core/Dish.js

@@ -1,206 +0,0 @@
-import Utils from "./Utils.js";
-
-/**
- * The data being operated on by each operation.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @class
- * @param {byteArray|string|number} value - The value of the input data.
- * @param {number} type - The data type of value, see Dish enums.
- */
-const Dish = function(value, type) {
-    this.value = value || typeof value == "string" ? value : null;
-    this.type  = type || Dish.BYTE_ARRAY;
-};
-
-
-/**
- * Dish data type enum for byte arrays.
- * @readonly
- * @enum
- */
-Dish.BYTE_ARRAY = 0;
-/**
- * Dish data type enum for strings.
- * @readonly
- * @enum
- */
-Dish.STRING = 1;
-/**
- * Dish data type enum for numbers.
- * @readonly
- * @enum
- */
-Dish.NUMBER = 2;
-/**
- * Dish data type enum for HTML.
- * @readonly
- * @enum
- */
-Dish.HTML = 3;
-
-
-/**
- * Returns the data type enum for the given type string.
- *
- * @static
- * @param {string} typeStr - The name of the data type.
- * @returns {number} The data type enum value.
- */
-Dish.typeEnum = function(typeStr) {
-    switch (typeStr) {
-        case "byteArray":
-        case "Byte array":
-            return Dish.BYTE_ARRAY;
-        case "string":
-        case "String":
-            return Dish.STRING;
-        case "number":
-        case "Number":
-            return Dish.NUMBER;
-        case "html":
-        case "HTML":
-            return Dish.HTML;
-        default:
-            throw "Invalid data type string. No matching enum.";
-    }
-};
-
-
-/**
- * Returns the data type string for the given type enum.
- *
- * @static
- * @param {string} typeEnum - The enum value of the data type.
- * @returns {number} The data type as a string.
- */
-Dish.enumLookup = function(typeEnum) {
-    switch (typeEnum) {
-        case Dish.BYTE_ARRAY:
-            return "byteArray";
-        case Dish.STRING:
-            return "string";
-        case Dish.NUMBER:
-            return "number";
-        case Dish.HTML:
-            return "html";
-        default:
-            throw "Invalid data type enum. No matching type.";
-    }
-};
-
-
-/**
- * Sets the data value and type and then validates them.
- *
- * @param {byteArray|string|number} value - The value of the input data.
- * @param {number} type - The data type of value, see Dish enums.
- */
-Dish.prototype.set = function(value, type) {
-    this.value = value;
-    this.type  = type;
-
-    if (!this.valid()) {
-        const sample = Utils.truncate(JSON.stringify(this.value), 13);
-        throw "Data is not a valid " + Dish.enumLookup(type) + ": " + sample;
-    }
-};
-
-
-/**
- * Returns the value of the data in the type format specified.
- *
- * @param {number} type - The data type of value, see Dish enums.
- * @returns {byteArray|string|number} The value of the output data.
- */
-Dish.prototype.get = function(type) {
-    if (this.type !== type) {
-        this.translate(type);
-    }
-    return this.value;
-};
-
-
-/**
- * Translates the data to the given type format.
- *
- * @param {number} toType - The data type of value, see Dish enums.
- */
-Dish.prototype.translate = function(toType) {
-    // Convert data to intermediate byteArray type
-    switch (this.type) {
-        case Dish.STRING:
-            this.value = this.value ? Utils.strToByteArray(this.value) : [];
-            this.type = Dish.BYTE_ARRAY;
-            break;
-        case Dish.NUMBER:
-            this.value = typeof this.value == "number" ? Utils.strToByteArray(this.value.toString()) : [];
-            this.type = Dish.BYTE_ARRAY;
-            break;
-        case Dish.HTML:
-            this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
-            this.type = Dish.BYTE_ARRAY;
-            break;
-        default:
-            break;
-    }
-
-    // Convert from byteArray to toType
-    switch (toType) {
-        case Dish.STRING:
-        case Dish.HTML:
-            this.value = this.value ? Utils.byteArrayToUtf8(this.value) : "";
-            this.type = Dish.STRING;
-            break;
-        case Dish.NUMBER:
-            this.value = this.value ? parseFloat(Utils.byteArrayToUtf8(this.value)) : 0;
-            this.type = Dish.NUMBER;
-            break;
-        default:
-            break;
-    }
-};
-
-
-/**
- * Validates that the value is the type that has been specified.
- * May have to disable parts of BYTE_ARRAY validation if it effects performance.
- *
- * @returns {boolean} Whether the data is valid or not.
-*/
-Dish.prototype.valid = function() {
-    switch (this.type) {
-        case Dish.BYTE_ARRAY:
-            if (!(this.value instanceof Array)) {
-                return false;
-            }
-
-            // Check that every value is a number between 0 - 255
-            for (let i = 0; i < this.value.length; i++) {
-                if (typeof this.value[i] != "number" ||
-                    this.value[i] < 0 ||
-                    this.value[i] > 255) {
-                    return false;
-                }
-            }
-            return true;
-        case Dish.STRING:
-        case Dish.HTML:
-            if (typeof this.value == "string") {
-                return true;
-            }
-            return false;
-        case Dish.NUMBER:
-            if (typeof this.value == "number") {
-                return true;
-            }
-            return false;
-        default:
-            return false;
-    }
-};
-
-export default Dish;

+ 434 - 0
src/core/Dish.mjs

@@ -0,0 +1,434 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Utils from "./Utils";
+import DishError from "./errors/DishError";
+import BigNumber from "bignumber.js";
+import log from "loglevel";
+
+/**
+ * The data being operated on by each operation.
+ */
+class Dish {
+
+    /**
+     * Dish constructor
+     *
+     * @param {Dish} [dish=null] - A dish to clone
+     */
+    constructor(dish=null) {
+        this.value = [];
+        this.type = Dish.BYTE_ARRAY;
+
+        if (dish &&
+            dish.hasOwnProperty("value") &&
+            dish.hasOwnProperty("type")) {
+            this.set(dish.value, dish.type);
+        }
+    }
+
+
+    /**
+     * Returns the data type enum for the given type string.
+     *
+     * @param {string} typeStr - The name of the data type.
+     * @returns {number} The data type enum value.
+     */
+    static typeEnum(typeStr) {
+        switch (typeStr.toLowerCase()) {
+            case "bytearray":
+            case "byte array":
+                return Dish.BYTE_ARRAY;
+            case "string":
+                return Dish.STRING;
+            case "number":
+                return Dish.NUMBER;
+            case "html":
+                return Dish.HTML;
+            case "arraybuffer":
+            case "array buffer":
+                return Dish.ARRAY_BUFFER;
+            case "bignumber":
+            case "big number":
+                return Dish.BIG_NUMBER;
+            case "json":
+                return Dish.JSON;
+            case "file":
+                return Dish.FILE;
+            case "list<file>":
+                return Dish.LIST_FILE;
+            default:
+                throw new DishError("Invalid data type string. No matching enum.");
+        }
+    }
+
+
+    /**
+     * Returns the data type string for the given type enum.
+     *
+     * @param {number} typeEnum - The enum value of the data type.
+     * @returns {string} The data type as a string.
+     */
+    static enumLookup(typeEnum) {
+        switch (typeEnum) {
+            case Dish.BYTE_ARRAY:
+                return "byteArray";
+            case Dish.STRING:
+                return "string";
+            case Dish.NUMBER:
+                return "number";
+            case Dish.HTML:
+                return "html";
+            case Dish.ARRAY_BUFFER:
+                return "ArrayBuffer";
+            case Dish.BIG_NUMBER:
+                return "BigNumber";
+            case Dish.JSON:
+                return "JSON";
+            case Dish.FILE:
+                return "File";
+            case Dish.LIST_FILE:
+                return "List<File>";
+            default:
+                throw new DishError("Invalid data type enum. No matching type.");
+        }
+    }
+
+
+    /**
+     * Sets the data value and type and then validates them.
+     *
+     * @param {*} value
+     *     - The value of the input data.
+     * @param {number} type
+     *     - The data type of value, see Dish enums.
+     */
+    set(value, type) {
+        if (typeof type === "string") {
+            type = Dish.typeEnum(type);
+        }
+
+        log.debug("Dish type: " + Dish.enumLookup(type));
+        this.value = value;
+        this.type = type;
+
+        if (!this.valid()) {
+            const sample = Utils.truncate(JSON.stringify(this.value), 13);
+            throw new DishError(`Data is not a valid ${Dish.enumLookup(type)}: ${sample}`);
+        }
+    }
+
+
+    /**
+     * Returns the value of the data in the type format specified.
+     *
+     * @param {number} type - The data type of value, see Dish enums.
+     * @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
+     * @returns {*} - The value of the output data.
+     */
+    async get(type, notUTF8=false) {
+        if (typeof type === "string") {
+            type = Dish.typeEnum(type);
+        }
+        if (this.type !== type) {
+            await this._translate(type, notUTF8);
+        }
+        return this.value;
+    }
+
+
+    /**
+     * Translates the data to the given type format.
+     *
+     * @param {number} toType - The data type of value, see Dish enums.
+     * @param {boolean} [notUTF8=false] - Do not treat strings as UTF8.
+     */
+    async _translate(toType, notUTF8=false) {
+        log.debug(`Translating Dish from ${Dish.enumLookup(this.type)} to ${Dish.enumLookup(toType)}`);
+        const byteArrayToStr = notUTF8 ? Utils.byteArrayToChars : Utils.byteArrayToUtf8;
+
+        // Convert data to intermediate byteArray type
+        try {
+            switch (this.type) {
+                case Dish.STRING:
+                    this.value = this.value ? Utils.strToByteArray(this.value) : [];
+                    break;
+                case Dish.NUMBER:
+                    this.value = typeof this.value === "number" ? Utils.strToByteArray(this.value.toString()) : [];
+                    break;
+                case Dish.HTML:
+                    this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
+                    break;
+                case Dish.ARRAY_BUFFER:
+                    // Array.from() would be nicer here, but it's slightly slower
+                    this.value = Array.prototype.slice.call(new Uint8Array(this.value));
+                    break;
+                case Dish.BIG_NUMBER:
+                    this.value = BigNumber.isBigNumber(this.value) ? Utils.strToByteArray(this.value.toFixed()) : [];
+                    break;
+                case Dish.JSON:
+                    this.value = this.value ? Utils.strToByteArray(JSON.stringify(this.value, null, 4)) : [];
+                    break;
+                case Dish.FILE:
+                    this.value = await Utils.readFile(this.value);
+                    this.value = Array.prototype.slice.call(this.value);
+                    break;
+                case Dish.LIST_FILE:
+                    this.value = await Promise.all(this.value.map(async f => Utils.readFile(f)));
+                    this.value = this.value.map(b => Array.prototype.slice.call(b));
+                    this.value = [].concat.apply([], this.value);
+                    break;
+                default:
+                    break;
+            }
+        } catch (err) {
+            throw new DishError(`Error translating from ${Dish.enumLookup(this.type)} to byteArray: ${err}`);
+        }
+
+        this.type = Dish.BYTE_ARRAY;
+
+        // Convert from byteArray to toType
+        try {
+            switch (toType) {
+                case Dish.STRING:
+                case Dish.HTML:
+                    this.value = this.value ? byteArrayToStr(this.value) : "";
+                    this.type = Dish.STRING;
+                    break;
+                case Dish.NUMBER:
+                    this.value = this.value ? parseFloat(byteArrayToStr(this.value)) : 0;
+                    this.type = Dish.NUMBER;
+                    break;
+                case Dish.ARRAY_BUFFER:
+                    this.value = new Uint8Array(this.value).buffer;
+                    this.type = Dish.ARRAY_BUFFER;
+                    break;
+                case Dish.BIG_NUMBER:
+                    try {
+                        this.value = new BigNumber(byteArrayToStr(this.value));
+                    } catch (err) {
+                        this.value = new BigNumber(NaN);
+                    }
+                    this.type = Dish.BIG_NUMBER;
+                    break;
+                case Dish.JSON:
+                    this.value = JSON.parse(byteArrayToStr(this.value));
+                    this.type = Dish.JSON;
+                    break;
+                case Dish.FILE:
+                    this.value = new File(this.value, "unknown");
+                    break;
+                case Dish.LIST_FILE:
+                    this.value = [new File(this.value, "unknown")];
+                    this.type = Dish.LIST_FILE;
+                    break;
+                default:
+                    break;
+            }
+        } catch (err) {
+            throw new DishError(`Error translating from byteArray to ${Dish.enumLookup(toType)}: ${err}`);
+        }
+    }
+
+
+    /**
+     * Validates that the value is the type that has been specified.
+     * May have to disable parts of BYTE_ARRAY validation if it effects performance.
+     *
+     * @returns {boolean} Whether the data is valid or not.
+    */
+    valid() {
+        switch (this.type) {
+            case Dish.BYTE_ARRAY:
+                if (!(this.value instanceof Array)) {
+                    return false;
+                }
+
+                // Check that every value is a number between 0 - 255
+                for (let i = 0; i < this.value.length; i++) {
+                    if (typeof this.value[i] !== "number" ||
+                        this.value[i] < 0 ||
+                        this.value[i] > 255) {
+                        return false;
+                    }
+                }
+                return true;
+            case Dish.STRING:
+            case Dish.HTML:
+                return typeof this.value === "string";
+            case Dish.NUMBER:
+                return typeof this.value === "number";
+            case Dish.ARRAY_BUFFER:
+                return this.value instanceof ArrayBuffer;
+            case Dish.BIG_NUMBER:
+                return BigNumber.isBigNumber(this.value);
+            case Dish.JSON:
+                // All values can be serialised in some manner, so we return true in all cases
+                return true;
+            case Dish.FILE:
+                return this.value instanceof File;
+            case Dish.LIST_FILE:
+                return this.value instanceof Array &&
+                    this.value.reduce((acc, curr) => acc && curr instanceof File, true);
+            default:
+                return false;
+        }
+    }
+
+
+    /**
+     * Determines how much space the Dish takes up.
+     * Numbers in JavaScript are 64-bit floating point, however for the purposes of the Dish,
+     * we measure how many bytes are taken up when the number is written as a string.
+     *
+     * @returns {number}
+    */
+    get size() {
+        switch (this.type) {
+            case Dish.BYTE_ARRAY:
+            case Dish.STRING:
+            case Dish.HTML:
+                return this.value.length;
+            case Dish.NUMBER:
+            case Dish.BIG_NUMBER:
+                return this.value.toString().length;
+            case Dish.ARRAY_BUFFER:
+                return this.value.byteLength;
+            case Dish.JSON:
+                return JSON.stringify(this.value).length;
+            case Dish.FILE:
+                return this.value.size;
+            case Dish.LIST_FILE:
+                return this.value.reduce((acc, curr) => acc + curr.size, 0);
+            default:
+                return -1;
+        }
+    }
+
+
+    /**
+     * Returns a deep clone of the current Dish.
+     *
+     * @returns {Dish}
+     */
+    clone() {
+        const newDish = new Dish();
+
+        switch (this.type) {
+            case Dish.STRING:
+            case Dish.HTML:
+            case Dish.NUMBER:
+            case Dish.BIG_NUMBER:
+                // These data types are immutable so it is acceptable to copy them by reference
+                newDish.set(
+                    this.value,
+                    this.type
+                );
+                break;
+            case Dish.BYTE_ARRAY:
+            case Dish.JSON:
+                // These data types are mutable so they need to be copied by value
+                newDish.set(
+                    JSON.parse(JSON.stringify(this.value)),
+                    this.type
+                );
+                break;
+            case Dish.ARRAY_BUFFER:
+                // Slicing an ArrayBuffer returns a new ArrayBuffer with a copy its contents
+                newDish.set(
+                    this.value.slice(0),
+                    this.type
+                );
+                break;
+            case Dish.FILE:
+                // A new file can be created by copying over all the values from the original
+                newDish.set(
+                    new File([this.value], this.value.name, {
+                        "type": this.value.type,
+                        "lastModified": this.value.lastModified
+                    }),
+                    this.type
+                );
+                break;
+            case Dish.LIST_FILE:
+                newDish.set(
+                    this.value.map(f =>
+                        new File([f], f.name, {
+                            "type": f.type,
+                            "lastModified": f.lastModified
+                        })
+                    ),
+                    this.type
+                );
+                break;
+            default:
+                throw new DishError("Cannot clone Dish, unknown type");
+        }
+
+        return newDish;
+    }
+
+}
+
+
+/**
+ * Dish data type enum for byte arrays.
+ * @readonly
+ * @enum
+ */
+Dish.BYTE_ARRAY = 0;
+/**
+ * Dish data type enum for strings.
+ * @readonly
+ * @enum
+ */
+Dish.STRING = 1;
+/**
+ * Dish data type enum for numbers.
+ * @readonly
+ * @enum
+ */
+Dish.NUMBER = 2;
+/**
+ * Dish data type enum for HTML.
+ * @readonly
+ * @enum
+ */
+Dish.HTML = 3;
+/**
+ * Dish data type enum for ArrayBuffers.
+ * @readonly
+ * @enum
+ */
+Dish.ARRAY_BUFFER = 4;
+/**
+ * Dish data type enum for BigNumbers.
+ * @readonly
+ * @enum
+ */
+Dish.BIG_NUMBER = 5;
+/**
+ * Dish data type enum for JSON.
+ * @readonly
+ * @enum
+ */
+Dish.JSON = 6;
+/**
+ * Dish data type enum for lists of files.
+ * @readonly
+ * @enum
+ */
+Dish.FILE = 7;
+/**
+* Dish data type enum for lists of files.
+* @readonly
+* @enum
+*/
+Dish.LIST_FILE = 8;
+
+
+export default Dish;

+ 0 - 213
src/core/FlowControl.js

@@ -1,213 +0,0 @@
-import Recipe from "./Recipe.js";
-import Dish from "./Dish.js";
-
-
-/**
- * Flow Control operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @namespace
- */
-const FlowControl = {
-
-    /**
-     * @constant
-     * @default
-     */
-    FORK_DELIM: "\\n",
-    /**
-     * @constant
-     * @default
-     */
-    MERGE_DELIM: "\\n",
-    /**
-     * @constant
-     * @default
-     */
-    FORK_IGNORE_ERRORS: false,
-
-    /**
-     * Fork operation.
-     *
-     * @param {Object} state - The current state of the recipe.
-     * @param {number} state.progress - The current position in the recipe.
-     * @param {Dish} state.dish - The Dish being operated on.
-     * @param {Operation[]} state.opList - The list of operations in the recipe.
-     * @returns {Object} The updated state of the recipe.
-     */
-    runFork: async function(state) {
-        let opList       = state.opList,
-            inputType    = opList[state.progress].inputType,
-            outputType   = opList[state.progress].outputType,
-            input        = state.dish.get(inputType),
-            ings         = opList[state.progress].getIngValues(),
-            splitDelim   = ings[0],
-            mergeDelim   = ings[1],
-            ignoreErrors = ings[2],
-            subOpList    = [],
-            inputs       = [],
-            i;
-
-        if (input)
-            inputs = input.split(splitDelim);
-
-        // Create subOpList for each tranche to operate on
-        // (all remaining operations unless we encounter a Merge)
-        for (i = state.progress + 1; i < opList.length; i++) {
-            if (opList[i].name === "Merge" && !opList[i].isDisabled()) {
-                break;
-            } else {
-                subOpList.push(opList[i]);
-            }
-        }
-
-        let recipe = new Recipe(),
-            output = "",
-            progress = 0;
-
-        recipe.addOperations(subOpList);
-
-        // Run recipe over each tranche
-        for (i = 0; i < inputs.length; i++) {
-            const dish = new Dish(inputs[i], inputType);
-            try {
-                progress = await recipe.execute(dish, 0);
-            } catch (err) {
-                if (!ignoreErrors) {
-                    throw err;
-                }
-                progress = err.progress + 1;
-            }
-            output += dish.get(outputType) + mergeDelim;
-        }
-
-        state.dish.set(output, outputType);
-        state.progress += progress;
-        return state;
-    },
-
-
-    /**
-     * Merge operation.
-     *
-     * @param {Object} state - The current state of the recipe.
-     * @param {number} state.progress - The current position in the recipe.
-     * @param {Dish} state.dish - The Dish being operated on.
-     * @param {Operation[]} state.opList - The list of operations in the recipe.
-     * @returns {Object} The updated state of the recipe.
-     */
-    runMerge: function(state) {
-        // No need to actually do anything here. The fork operation will
-        // merge when it sees this operation.
-        return state;
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    JUMP_NUM: 0,
-    /**
-     * @constant
-     * @default
-     */
-    MAX_JUMPS: 10,
-
-    /**
-     * Jump operation.
-     *
-     * @param {Object} state - The current state of the recipe.
-     * @param {number} state.progress - The current position in the recipe.
-     * @param {Dish} state.dish - The Dish being operated on.
-     * @param {Operation[]} state.opList - The list of operations in the recipe.
-     * @param {number} state.numJumps - The number of jumps taken so far.
-     * @returns {Object} The updated state of the recipe.
-     */
-    runJump: function(state) {
-        let ings     = state.opList[state.progress].getIngValues(),
-            jumpNum  = ings[0],
-            maxJumps = ings[1];
-
-        if (jumpNum < 0) {
-            jumpNum--;
-        }
-
-        if (state.numJumps >= maxJumps) {
-            return state;
-        }
-
-        state.progress += jumpNum;
-        state.numJumps++;
-        return state;
-    },
-
-
-    /**
-     * Conditional Jump operation.
-     *
-     * @param {Object} state - The current state of the recipe.
-     * @param {number} state.progress - The current position in the recipe.
-     * @param {Dish} state.dish - The Dish being operated on.
-     * @param {Operation[]} state.opList - The list of operations in the recipe.
-     * @param {number} state.numJumps - The number of jumps taken so far.
-     * @returns {Object} The updated state of the recipe.
-     */
-    runCondJump: function(state) {
-        let ings     = state.opList[state.progress].getIngValues(),
-            dish     = state.dish,
-            regexStr = ings[0],
-            jumpNum  = ings[1],
-            maxJumps = ings[2];
-
-        if (jumpNum < 0) {
-            jumpNum--;
-        }
-
-        if (state.numJumps >= maxJumps) {
-            return state;
-        }
-
-        if (regexStr !== "" && dish.get(Dish.STRING).search(regexStr) > -1) {
-            state.progress += jumpNum;
-            state.numJumps++;
-        }
-
-        return state;
-    },
-
-
-    /**
-     * Return operation.
-     *
-     * @param {Object} state - The current state of the recipe.
-     * @param {number} state.progress - The current position in the recipe.
-     * @param {Dish} state.dish - The Dish being operated on.
-     * @param {Operation[]} state.opList - The list of operations in the recipe.
-     * @returns {Object} The updated state of the recipe.
-     */
-    runReturn: function(state) {
-        state.progress = state.opList.length;
-        return state;
-    },
-
-
-    /**
-     * Comment operation.
-     *
-     * @param {Object} state - The current state of the recipe.
-     * @param {number} state.progress - The current position in the recipe.
-     * @param {Dish} state.dish - The Dish being operated on.
-     * @param {Operation[]} state.opList - The list of operations in the recipe.
-     * @returns {Object} The updated state of the recipe.
-     */
-    runComment: function(state) {
-        return state;
-    },
-
-};
-
-export default FlowControl;

+ 0 - 92
src/core/Ingredient.js

@@ -1,92 +0,0 @@
-import Utils from "./Utils.js";
-
-
-/**
- * The arguments to operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @class
- * @param {Object} ingredientConfig
- */
-const Ingredient = function(ingredientConfig) {
-    this.name  = "";
-    this.type  = "";
-    this.value = null;
-
-    if (ingredientConfig) {
-        this._parseConfig(ingredientConfig);
-    }
-};
-
-
-/**
- * Reads and parses the given config.
- *
- * @private
- * @param {Object} ingredientConfig
- */
-Ingredient.prototype._parseConfig = function(ingredientConfig) {
-    this.name = ingredientConfig.name;
-    this.type = ingredientConfig.type;
-};
-
-
-/**
- * Returns the value of the Ingredient as it should be displayed in a recipe config.
- *
- * @returns {*}
- */
-Ingredient.prototype.getConfig = function() {
-    return this.value;
-};
-
-
-/**
- * Sets the value of the Ingredient.
- *
- * @param {*} value
- */
-Ingredient.prototype.setValue = function(value) {
-    this.value = Ingredient.prepare(value, this.type);
-};
-
-
-/**
- * Most values will be strings when they are entered. This function converts them to the correct
- * type.
- *
- * @static
- * @param {*} data
- * @param {string} type - The name of the data type.
-*/
-Ingredient.prepare = function(data, type) {
-    let number;
-
-    switch (type) {
-        case "binaryString":
-        case "binaryShortString":
-        case "editableOption":
-            return Utils.parseEscapedChars(data);
-        case "byteArray":
-            if (typeof data == "string") {
-                data = data.replace(/\s+/g, "");
-                return Utils.hexToByteArray(data);
-            } else {
-                return data;
-            }
-        case "number":
-            number = parseFloat(data);
-            if (isNaN(number)) {
-                const sample = Utils.truncate(data.toString(), 10);
-                throw "Invalid ingredient value. Not a number: " + sample;
-            }
-            return number;
-        default:
-            return data;
-    }
-};
-
-export default Ingredient;

+ 123 - 0
src/core/Ingredient.mjs

@@ -0,0 +1,123 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Utils from "./Utils";
+import {fromHex} from "./lib/Hex";
+
+/**
+ * The arguments to operations.
+ */
+class Ingredient {
+
+    /**
+     * Ingredient constructor
+     *
+     * @param {Object} ingredientConfig
+     */
+    constructor(ingredientConfig) {
+        this.name  = "";
+        this.type  = "";
+        this._value = null;
+        this.disabled = false;
+        this.hint = "";
+        this.rows = 0;
+        this.toggleValues = [];
+        this.target = null;
+        this.defaultIndex = 0;
+
+        if (ingredientConfig) {
+            this._parseConfig(ingredientConfig);
+        }
+    }
+
+
+    /**
+     * Reads and parses the given config.
+     *
+     * @private
+     * @param {Object} ingredientConfig
+     */
+    _parseConfig(ingredientConfig) {
+        this.name = ingredientConfig.name;
+        this.type = ingredientConfig.type;
+        this.defaultValue = ingredientConfig.value;
+        this.disabled = !!ingredientConfig.disabled;
+        this.hint = ingredientConfig.hint || false;
+        this.rows = ingredientConfig.rows || false;
+        this.toggleValues = ingredientConfig.toggleValues;
+        this.target = typeof ingredientConfig.target !== "undefined" ? ingredientConfig.target : null;
+        this.defaultIndex = typeof ingredientConfig.defaultIndex !== "undefined" ? ingredientConfig.defaultIndex : 0;
+    }
+
+
+    /**
+     * Returns the value of the Ingredient as it should be displayed in a recipe config.
+     *
+     * @returns {*}
+     */
+    get config() {
+        return this._value;
+    }
+
+
+    /**
+     * Sets the value of the Ingredient.
+     *
+     * @param {*} value
+     */
+    set value(value) {
+        this._value = Ingredient.prepare(value, this.type);
+    }
+
+
+    /**
+     * Gets the value of the Ingredient.
+     *
+     * @returns {*}
+     */
+    get value() {
+        return this._value;
+    }
+
+
+    /**
+     * Most values will be strings when they are entered. This function converts them to the correct
+     * type.
+     *
+     * @param {*} data
+     * @param {string} type - The name of the data type.
+    */
+    static prepare(data, type) {
+        let number;
+
+        switch (type) {
+            case "binaryString":
+            case "binaryShortString":
+            case "editableOption":
+            case "editableOptionShort":
+                return Utils.parseEscapedChars(data);
+            case "byteArray":
+                if (typeof data == "string") {
+                    data = data.replace(/\s+/g, "");
+                    return fromHex(data);
+                } else {
+                    return data;
+                }
+            case "number":
+                number = parseFloat(data);
+                if (isNaN(number)) {
+                    const sample = Utils.truncate(data.toString(), 10);
+                    throw "Invalid ingredient value. Not a number: " + sample;
+                }
+                return number;
+            default:
+                return data;
+        }
+    }
+
+}
+
+export default Ingredient;

+ 0 - 163
src/core/Operation.js

@@ -1,163 +0,0 @@
-import Dish from "./Dish.js";
-import Ingredient from "./Ingredient.js";
-
-
-/**
- * The Operation specified by the user to be run.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @class
- * @param {string} operationName
- * @param {Object} operationConfig
- */
-const Operation = function(operationName, operationConfig) {
-    this.name             = operationName;
-    this.description      = "";
-    this.inputType        = -1;
-    this.outputType       = -1;
-    this.run              = null;
-    this.highlight        = null;
-    this.highlightReverse = null;
-    this.breakpoint       = false;
-    this.disabled         = false;
-    this.ingList          = [];
-
-    if (operationConfig) {
-        this._parseConfig(operationConfig);
-    }
-};
-
-
-/**
- * Reads and parses the given config.
- *
- * @private
- * @param {Object} operationConfig
- */
-Operation.prototype._parseConfig = function(operationConfig) {
-    this.description      = operationConfig.description;
-    this.inputType        = Dish.typeEnum(operationConfig.inputType);
-    this.outputType       = Dish.typeEnum(operationConfig.outputType);
-    this.run              = operationConfig.run;
-    this.highlight        = operationConfig.highlight;
-    this.highlightReverse = operationConfig.highlightReverse;
-    this.flowControl      = operationConfig.flowControl;
-
-    for (let a = 0; a < operationConfig.args.length; a++) {
-        const ingredientConfig = operationConfig.args[a];
-        const ingredient = new Ingredient(ingredientConfig);
-        this.addIngredient(ingredient);
-    }
-};
-
-
-/**
- * Returns the value of the Operation as it should be displayed in a recipe config.
- *
- * @returns {Object}
- */
-Operation.prototype.getConfig = function() {
-    const ingredientConfig = [];
-
-    for (let o = 0; o < this.ingList.length; o++) {
-        ingredientConfig.push(this.ingList[o].getConfig());
-    }
-
-    const operationConfig = {
-        "op": this.name,
-        "args": ingredientConfig
-    };
-
-    return operationConfig;
-};
-
-
-/**
- * Adds a new Ingredient to this Operation.
- *
- * @param {Ingredient} ingredient
- */
-Operation.prototype.addIngredient = function(ingredient) {
-    this.ingList.push(ingredient);
-};
-
-
-/**
- * Set the Ingredient values for this Operation.
- *
- * @param {Object[]} ingValues
- */
-Operation.prototype.setIngValues = function(ingValues) {
-    for (let i = 0; i < ingValues.length; i++) {
-        this.ingList[i].setValue(ingValues[i]);
-    }
-};
-
-
-/**
- * Get the Ingredient values for this Operation.
- *
- * @returns {Object[]}
- */
-Operation.prototype.getIngValues = function() {
-    const ingValues = [];
-    for (let i = 0; i < this.ingList.length; i++) {
-        ingValues.push(this.ingList[i].value);
-    }
-    return ingValues;
-};
-
-
-/**
- * Set whether this Operation has a breakpoint.
- *
- * @param {boolean} value
- */
-Operation.prototype.setBreakpoint = function(value) {
-    this.breakpoint = !!value;
-};
-
-
-/**
- * Returns true if this Operation has a breakpoint set.
- *
- * @returns {boolean}
- */
-Operation.prototype.isBreakpoint = function() {
-    return this.breakpoint;
-};
-
-
-/**
- * Set whether this Operation is disabled.
- *
- * @param {boolean} value
- */
-Operation.prototype.setDisabled = function(value) {
-    this.disabled = !!value;
-};
-
-
-/**
- * Returns true if this Operation is disabled.
- *
- * @returns {boolean}
- */
-Operation.prototype.isDisabled = function() {
-    return this.disabled;
-};
-
-
-/**
- * Returns true if this Operation is a flow control.
- *
- * @returns {boolean}
- */
-Operation.prototype.isFlowControl = function() {
-    return this.flowControl;
-};
-
-export default Operation;

+ 318 - 0
src/core/Operation.mjs

@@ -0,0 +1,318 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Dish from "./Dish";
+import Ingredient from "./Ingredient";
+
+/**
+ * The Operation specified by the user to be run.
+ */
+class Operation {
+
+    /**
+     * Operation constructor
+     */
+    constructor() {
+        // Private fields
+        this._inputType       = -1;
+        this._outputType      = -1;
+        this._presentType     = -1;
+        this._breakpoint      = false;
+        this._disabled        = false;
+        this._flowControl     = false;
+        this._manualBake      = false;
+        this._ingList         = [];
+
+        // Public fields
+        this.name             = "";
+        this.module           = "";
+        this.description      = "";
+        this.infoURL          = null;
+    }
+
+
+    /**
+     * Interface for operation runner
+     *
+     * @param {*} input
+     * @param {Object[]} args
+     * @returns {*}
+     */
+    run(input, args) {
+        return input;
+    }
+
+
+    /**
+     * Interface for forward highlighter
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return false;
+    }
+
+
+    /**
+     * Interface for reverse highlighter
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return false;
+    }
+
+
+    /**
+     * Method to be called when displaying the result of an operation in a human-readable
+     * format. This allows operations to return usable data from their run() method and
+     * only format them when this method is called.
+     *
+     * The default action is to return the data unchanged, but child classes can override
+     * this behaviour.
+     *
+     * @param {*} data - The result of the run() function
+     * @param {Object[]} args - The operation's arguments
+     * @returns {*} - A human-readable version of the data
+     */
+    present(data, args) {
+        return data;
+    }
+
+
+    /**
+     * Sets the input type as a Dish enum.
+     *
+     * @param {string} typeStr
+     */
+    set inputType(typeStr) {
+        this._inputType = Dish.typeEnum(typeStr);
+    }
+
+
+    /**
+     * Gets the input type as a readable string.
+     *
+     * @returns {string}
+     */
+    get inputType() {
+        return Dish.enumLookup(this._inputType);
+    }
+
+
+    /**
+     * Sets the output type as a Dish enum.
+     *
+     * @param {string} typeStr
+     */
+    set outputType(typeStr) {
+        this._outputType = Dish.typeEnum(typeStr);
+        if (this._presentType < 0) this._presentType = this._outputType;
+    }
+
+
+    /**
+     * Gets the output type as a readable string.
+     *
+     * @returns {string}
+     */
+    get outputType() {
+        return Dish.enumLookup(this._outputType);
+    }
+
+
+    /**
+     * Sets the presentation type as a Dish enum.
+     *
+     * @param {string} typeStr
+     */
+    set presentType(typeStr) {
+        this._presentType = Dish.typeEnum(typeStr);
+    }
+
+
+    /**
+     * Gets the presentation type as a readable string.
+     *
+     * @returns {string}
+     */
+    get presentType() {
+        return Dish.enumLookup(this._presentType);
+    }
+
+
+    /**
+     * Sets the args for the current operation.
+     *
+     * @param {Object[]} conf
+     */
+    set args(conf) {
+        conf.forEach(arg => {
+            const ingredient = new Ingredient(arg);
+            this.addIngredient(ingredient);
+        });
+    }
+
+
+    /**
+     * Gets the args for the current operation.
+     *
+     * @param {Object[]} conf
+     */
+    get args() {
+        return this._ingList.map(ing => {
+            const conf = {
+                name: ing.name,
+                type: ing.type,
+                value: ing.defaultValue
+            };
+
+            if (ing.toggleValues) conf.toggleValues = ing.toggleValues;
+            if (ing.hint) conf.hint = ing.hint;
+            if (ing.rows) conf.rows = ing.rows;
+            if (ing.disabled) conf.disabled = ing.disabled;
+            if (ing.target) conf.target = ing.target;
+            if (ing.defaultIndex) conf.defaultIndex = ing.defaultIndex;
+            return conf;
+        });
+    }
+
+
+    /**
+     * Returns the value of the Operation as it should be displayed in a recipe config.
+     *
+     * @returns {Object}
+     */
+    get config() {
+        return {
+            "op": this.name,
+            "args": this._ingList.map(ing => ing.config)
+        };
+    }
+
+
+    /**
+     * Adds a new Ingredient to this Operation.
+     *
+     * @param {Ingredient} ingredient
+     */
+    addIngredient(ingredient) {
+        this._ingList.push(ingredient);
+    }
+
+
+    /**
+     * Set the Ingredient values for this Operation.
+     *
+     * @param {Object[]} ingValues
+     */
+    set ingValues(ingValues) {
+        ingValues.forEach((val, i) => {
+            this._ingList[i].value = val;
+        });
+    }
+
+
+    /**
+     * Get the Ingredient values for this Operation.
+     *
+     * @returns {Object[]}
+     */
+    get ingValues() {
+        return this._ingList.map(ing => ing.value);
+    }
+
+
+    /**
+     * Set whether this Operation has a breakpoint.
+     *
+     * @param {boolean} value
+     */
+    set breakpoint(value) {
+        this._breakpoint = !!value;
+    }
+
+
+    /**
+     * Returns true if this Operation has a breakpoint set.
+     *
+     * @returns {boolean}
+     */
+    get breakpoint() {
+        return this._breakpoint;
+    }
+
+
+    /**
+     * Set whether this Operation is disabled.
+     *
+     * @param {boolean} value
+     */
+    set disabled(value) {
+        this._disabled = !!value;
+    }
+
+
+    /**
+     * Returns true if this Operation is disabled.
+     *
+     * @returns {boolean}
+     */
+    get disabled() {
+        return this._disabled;
+    }
+
+
+    /**
+     * Returns true if this Operation is a flow control.
+     *
+     * @returns {boolean}
+     */
+    get flowControl() {
+        return this._flowControl;
+    }
+
+
+    /**
+     * Set whether this Operation is a flowcontrol op.
+     *
+     * @param {boolean} value
+     */
+    set flowControl(value) {
+        this._flowControl = !!value;
+    }
+
+
+    /**
+     * Returns true if this Operation should not trigger AutoBake.
+     *
+     * @returns {boolean}
+     */
+    get manualBake() {
+        return this._manualBake;
+    }
+
+
+    /**
+     * Set whether this Operation should trigger AutoBake.
+     *
+     * @param {boolean} value
+     */
+    set manualBake(value) {
+        this._manualBake = !!value;
+    }
+
+}
+
+export default Operation;

+ 0 - 220
src/core/Recipe.js

@@ -1,220 +0,0 @@
-import Operation from "./Operation.js";
-import OperationConfig from "./config/OperationConfig.js";
-
-
-/**
- * The Recipe controls a list of Operations and the Dish they operate on.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @class
- * @param {Object} recipeConfig
- */
-const Recipe = function(recipeConfig) {
-    this.opList = [];
-
-    if (recipeConfig) {
-        this._parseConfig(recipeConfig);
-    }
-};
-
-
-/**
- * Reads and parses the given config.
- *
- * @private
- * @param {Object} recipeConfig
- */
-Recipe.prototype._parseConfig = function(recipeConfig) {
-    for (let c = 0; c < recipeConfig.length; c++) {
-        const operationName = recipeConfig[c].op;
-        const operationConfig = OperationConfig[operationName];
-        const operation = new Operation(operationName, operationConfig);
-        operation.setIngValues(recipeConfig[c].args);
-        operation.setBreakpoint(recipeConfig[c].breakpoint);
-        operation.setDisabled(recipeConfig[c].disabled);
-        this.addOperation(operation);
-    }
-};
-
-
-/**
- * Returns the value of the Recipe as it should be displayed in a recipe config.
- *
- * @returns {*}
- */
-Recipe.prototype.getConfig = function() {
-    const recipeConfig = [];
-
-    for (let o = 0; o < this.opList.length; o++) {
-        recipeConfig.push(this.opList[o].getConfig());
-    }
-
-    return recipeConfig;
-};
-
-
-/**
- * Adds a new Operation to this Recipe.
- *
- * @param {Operation} operation
- */
-Recipe.prototype.addOperation = function(operation) {
-    this.opList.push(operation);
-};
-
-
-/**
- * Adds a list of Operations to this Recipe.
- *
- * @param {Operation[]} operations
- */
-Recipe.prototype.addOperations = function(operations) {
-    this.opList = this.opList.concat(operations);
-};
-
-
-/**
- * Set a breakpoint on a specified Operation.
- *
- * @param {number} position - The index of the Operation
- * @param {boolean} value
- */
-Recipe.prototype.setBreakpoint = function(position, value) {
-    try {
-        this.opList[position].setBreakpoint(value);
-    } catch (err) {
-        // Ignore index error
-    }
-};
-
-
-/**
- * Remove breakpoints on all Operations in the Recipe up to the specified position. Used by Flow
- * Control Fork operation.
- *
- * @param {number} pos
- */
-Recipe.prototype.removeBreaksUpTo = function(pos) {
-    for (let i = 0; i < pos; i++) {
-        this.opList[i].setBreakpoint(false);
-    }
-};
-
-
-/**
- * Returns true if there is an Flow Control Operation in this Recipe.
- *
- * @returns {boolean}
- */
-Recipe.prototype.containsFlowControl = function() {
-    for (let i = 0; i < this.opList.length; i++) {
-        if (this.opList[i].isFlowControl()) return true;
-    }
-    return false;
-};
-
-
-/**
- * Returns the index of the last Operation index that will be executed, taking into account disabled
- * Operations and breakpoints.
- *
- * @param {number} [startIndex=0] - The index to start searching from
- * @returns (number}
- */
-Recipe.prototype.lastOpIndex = function(startIndex) {
-    let i = startIndex + 1 || 0,
-        op;
-
-    for (; i < this.opList.length; i++) {
-        op = this.opList[i];
-        if (op.isDisabled()) return i-1;
-        if (op.isBreakpoint()) return i-1;
-    }
-
-    return i-1;
-};
-
-
-/**
- * Executes each operation in the recipe over the given Dish.
- *
- * @param {Dish} dish
- * @param {number} [startFrom=0] - The index of the Operation to start executing from
- * @returns {number} - The final progress through the recipe
- */
-Recipe.prototype.execute = async function(dish, startFrom) {
-    startFrom = startFrom || 0;
-    let op, input, output, numJumps = 0;
-
-    for (let i = startFrom; i < this.opList.length; i++) {
-        op = this.opList[i];
-        if (op.isDisabled()) {
-            continue;
-        }
-        if (op.isBreakpoint()) {
-            return i;
-        }
-
-        try {
-            input = dish.get(op.inputType);
-
-            if (op.isFlowControl()) {
-                // Package up the current state
-                let state = {
-                    "progress" : i,
-                    "dish"     : dish,
-                    "opList"  : this.opList,
-                    "numJumps" : numJumps
-                };
-
-                state = await op.run(state);
-                i = state.progress;
-                numJumps = state.numJumps;
-            } else {
-                output = await op.run(input, op.getIngValues());
-                dish.set(output, op.outputType);
-            }
-        } catch (err) {
-            const e = typeof err == "string" ? { message: err } : err;
-
-            e.progress = i;
-            if (e.fileName) {
-                e.displayStr = op.name + " - " + e.name + " in " +
-                    e.fileName + " on line " + e.lineNumber +
-                    ".<br><br>Message: " + (e.displayStr || e.message);
-            } else {
-                e.displayStr = op.name + " - " + (e.displayStr || e.message);
-            }
-
-            throw e;
-        }
-    }
-
-    return this.opList.length;
-};
-
-
-/**
- * Returns the recipe configuration in string format.
- *
- * @returns {string}
- */
-Recipe.prototype.toString = function() {
-    return JSON.stringify(this.getConfig());
-};
-
-
-/**
- * Creates a Recipe from a given configuration string.
- *
- * @param {string} recipeStr
- */
-Recipe.prototype.fromString = function(recipeStr) {
-    const recipeConfig = JSON.parse(recipeStr);
-    this._parseConfig(recipeConfig);
-};
-
-export default Recipe;

+ 342 - 0
src/core/Recipe.mjs

@@ -0,0 +1,342 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import OperationConfig from "./config/OperationConfig.json";
+import OperationError from "./errors/OperationError";
+import Operation from "./Operation";
+import DishError from "./errors/DishError";
+import log from "loglevel";
+
+// Cache container for modules
+let modules = null;
+
+/**
+ * The Recipe controls a list of Operations and the Dish they operate on.
+ */
+class Recipe  {
+
+    /**
+     * Recipe constructor
+     *
+     * @param {Object} recipeConfig
+     */
+    constructor(recipeConfig) {
+        this.opList = [];
+
+        if (recipeConfig) {
+            this._parseConfig(recipeConfig);
+        }
+    }
+
+
+    /**
+     * Reads and parses the given config.
+     *
+     * @private
+     * @param {Object} recipeConfig
+     */
+    _parseConfig(recipeConfig) {
+        recipeConfig.forEach(c => {
+            this.opList.push({
+                name: c.op,
+                module: OperationConfig[c.op].module,
+                ingValues: c.args,
+                breakpoint: c.breakpoint,
+                disabled: c.disabled,
+            });
+        });
+    }
+
+
+    /**
+     * Populate elements of opList with operation instances.
+     * Dynamic import here removes top-level cyclic dependency issue.
+     *
+     * @private
+     */
+    async _hydrateOpList() {
+        if (!modules) {
+            // Using Webpack Magic Comments to force the dynamic import to be included in the main chunk
+            // https://webpack.js.org/api/module-methods/
+            modules = await import(/* webpackMode: "eager" */ "./config/modules/OpModules");
+            modules = modules.default;
+        }
+
+        this.opList = this.opList.map(o => {
+            if (o instanceof Operation) {
+                return o;
+            } else {
+                const op = new modules[o.module][o.name]();
+                op.ingValues = o.ingValues;
+                op.breakpoint = o.breakpoint;
+                op.disabled = o.disabled;
+                return op;
+            }
+        });
+    }
+
+
+    /**
+     * Returns the value of the Recipe as it should be displayed in a recipe config.
+     *
+     * @returns {Object[]}
+     */
+    get config() {
+        return this.opList.map(op => ({
+            op: op.name,
+            args: op.ingValues,
+        }));
+    }
+
+
+    /**
+     * Adds a new Operation to this Recipe.
+     *
+     * @param {Operation} operation
+     */
+    addOperation(operation) {
+        this.opList.push(operation);
+    }
+
+
+    /**
+     * Adds a list of Operations to this Recipe.
+     *
+     * @param {Operation[]} operations
+     */
+    addOperations(operations) {
+        operations.forEach(o => {
+            if (o instanceof Operation) {
+                this.opList.push(o);
+            } else {
+                this.opList.push({
+                    name: o.name,
+                    module: o.module,
+                    ingValues: o.args,
+                    breakpoint: o.breakpoint,
+                    disabled: o.disabled,
+                });
+            }
+        });
+    }
+
+
+    /**
+     * Set a breakpoint on a specified Operation.
+     *
+     * @param {number} position - The index of the Operation
+     * @param {boolean} value
+     */
+    setBreakpoint(position, value) {
+        try {
+            this.opList[position].breakpoint = value;
+        } catch (err) {
+            // Ignore index error
+        }
+    }
+
+
+    /**
+     * Remove breakpoints on all Operations in the Recipe up to the specified position. Used by Flow
+     * Control Fork operation.
+     *
+     * @param {number} pos
+     */
+    removeBreaksUpTo(pos) {
+        for (let i = 0; i < pos; i++) {
+            this.opList[i].breakpoint = false;
+        }
+    }
+
+
+    /**
+     * Returns true if there is a Flow Control Operation in this Recipe.
+     *
+     * @returns {boolean}
+     */
+    containsFlowControl() {
+        return this.opList.reduce((acc, curr) => {
+            return acc || curr.flowControl;
+        }, false);
+    }
+
+
+    /**
+     * Executes each operation in the recipe over the given Dish.
+     *
+     * @param {Dish} dish
+     * @param {number} [startFrom=0]
+     *     - The index of the Operation to start executing from
+     * @param {number} [forkState={}]
+     *     - If this is a forked recipe, the state of the recipe up to this point
+     * @returns {number}
+     *     - The final progress through the recipe
+     */
+    async execute(dish, startFrom=0, forkState={}) {
+        let op, input, output,
+            numJumps = 0,
+            numRegisters = forkState.numRegisters || 0;
+
+        if (startFrom === 0) this.lastRunOp = null;
+
+        await this._hydrateOpList();
+
+        log.debug(`[*] Executing recipe of ${this.opList.length} operations, starting at ${startFrom}`);
+
+        for (let i = startFrom; i < this.opList.length; i++) {
+            op = this.opList[i];
+            log.debug(`[${i}] ${op.name} ${JSON.stringify(op.ingValues)}`);
+            if (op.disabled) {
+                log.debug("Operation is disabled, skipping");
+                continue;
+            }
+            if (op.breakpoint) {
+                log.debug("Pausing at breakpoint");
+                return i;
+            }
+
+            try {
+                input = await dish.get(op.inputType);
+                log.debug("Executing operation");
+
+                if (op.flowControl) {
+                    // Package up the current state
+                    let state = {
+                        "progress":     i,
+                        "dish":         dish,
+                        "opList":       this.opList,
+                        "numJumps":     numJumps,
+                        "numRegisters": numRegisters,
+                        "forkOffset":   forkState.forkOffset || 0
+                    };
+
+                    state = await op.run(state);
+                    i = state.progress;
+                    numJumps = state.numJumps;
+                    numRegisters = state.numRegisters;
+                } else {
+                    output = await op.run(input, op.ingValues);
+                    dish.set(output, op.outputType);
+                }
+                this.lastRunOp = op;
+            } catch (err) {
+                // Return expected errors as output
+                if (err instanceof OperationError ||
+                    (err.type && err.type === "OperationError")) {
+                    // Cannot rely on `err instanceof OperationError` here as extending
+                    // native types is not fully supported yet.
+                    dish.set(err.message, "string");
+                    return i;
+                } else if (err instanceof DishError ||
+                    (err.type && err.type === "DishError")) {
+                    dish.set(err.message, "string");
+                    return i;
+                } else {
+                    const e = typeof err == "string" ? { message: err } : err;
+
+                    e.progress = i;
+                    if (e.fileName) {
+                        e.displayStr = `${op.name} - ${e.name} in ${e.fileName} on line ` +
+                            `${e.lineNumber}.<br><br>Message: ${e.displayStr || e.message}`;
+                    } else {
+                        e.displayStr = `${op.name} - ${e.displayStr || e.message}`;
+                    }
+
+                    throw e;
+                }
+            }
+        }
+
+        log.debug("Recipe complete");
+        return this.opList.length;
+    }
+
+
+    /**
+     * Present the results of the final operation.
+     *
+     * @param {Dish} dish
+     */
+    async present(dish) {
+        if (!this.lastRunOp) return;
+
+        const output = await this.lastRunOp.present(
+            await dish.get(this.lastRunOp.outputType),
+            this.lastRunOp.ingValues
+        );
+        dish.set(output, this.lastRunOp.presentType);
+    }
+
+
+    /**
+     * Returns the recipe configuration in string format.
+     *
+     * @returns {string}
+     */
+    toString() {
+        return JSON.stringify(this.config);
+    }
+
+
+    /**
+     * Creates a Recipe from a given configuration string.
+     *
+     * @param {string} recipeStr
+     */
+    fromString(recipeStr) {
+        const recipeConfig = JSON.parse(recipeStr);
+        this._parseConfig(recipeConfig);
+    }
+
+
+    /**
+     * Generates a list of all the highlight functions assigned to operations in the recipe, if the
+     * entire recipe supports highlighting.
+     *
+     * @returns {Object[]} highlights
+     * @returns {function} highlights[].f
+     * @returns {function} highlights[].b
+     * @returns {Object[]} highlights[].args
+     */
+    async generateHighlightList() {
+        await this._hydrateOpList();
+        const highlights = [];
+
+        for (let i = 0; i < this.opList.length; i++) {
+            const op = this.opList[i];
+            if (op.disabled) continue;
+
+            // If any breakpoints are set, do not attempt to highlight
+            if (op.breakpoint) return false;
+
+            // If any of the operations do not support highlighting, fail immediately.
+            if (op.highlight === false || op.highlight === undefined) return false;
+
+            highlights.push({
+                f: op.highlight,
+                b: op.highlightReverse,
+                args: op.ingValues
+            });
+        }
+
+        return highlights;
+    }
+
+
+    /**
+     * Determines whether the previous operation has a different presentation type to its normal output.
+     *
+     * @param {number} progress
+     * @returns {boolean}
+     */
+    lastOpPresented(progress) {
+        if (progress < 1) return false;
+        return this.opList[progress-1].presentType !== this.opList[progress-1].outputType;
+    }
+
+}
+
+export default Recipe;

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 218
src/core/Utils.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 180 - 0
src/core/Utils.mjs


+ 162 - 70
src/core/config/Categories.js → src/core/config/Categories.json

@@ -1,30 +1,11 @@
-/**
- * Type definition for a CatConf.
- *
- * @typedef {Object} CatConf
- * @property {string} name - The display name for the category
- * @property {string[]} ops - A list of the operations to be included in this category
- */
-
-
-/**
- * Categories of operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @constant
- * @type {CatConf[]}
- */
-const Categories = [
+[
     {
-        name: "Favourites",
-        ops: []
+        "name": "Favourites",
+        "ops": []
     },
     {
-        name: "Data format",
-        ops: [
+        "name": "Data format",
+        "ops": [
             "To Hexdump",
             "From Hexdump",
             "To Hex",
@@ -44,12 +25,19 @@ const Categories = [
             "From Base32",
             "To Base58",
             "From Base58",
+            "To Base62",
+            "From Base62",
+            "To Base85",
+            "From Base85",
             "To Base",
             "From Base",
+            "To BCD",
+            "From BCD",
             "To HTML Entity",
             "From HTML Entity",
             "URL Encode",
             "URL Decode",
+            "Escape Unicode Characters",
             "Unescape Unicode Characters",
             "To Quoted Printable",
             "From Quoted Printable",
@@ -63,12 +51,20 @@ const Categories = [
             "Change IP format",
             "Encode text",
             "Decode text",
+            "Text Encoding Brute Force",
             "Swap endianness",
+            "To MessagePack",
+            "From MessagePack",
+            "To Braille",
+            "From Braille",
+            "Parse TLV",
+            "CSV to JSON",
+            "JSON to CSV"
         ]
     },
     {
-        name: "Encryption / Encoding",
-        ops: [
+        "name": "Encryption / Encoding",
+        "ops": [
             "AES Encrypt",
             "AES Decrypt",
             "Blowfish Encrypt",
@@ -77,8 +73,8 @@ const Categories = [
             "DES Decrypt",
             "Triple DES Encrypt",
             "Triple DES Decrypt",
-            "Rabbit Encrypt",
-            "Rabbit Decrypt",
+            "RC2 Encrypt",
+            "RC2 Decrypt",
             "RC4",
             "RC4 Drop",
             "ROT13",
@@ -89,28 +85,51 @@ const Categories = [
             "Vigenère Decode",
             "To Morse Code",
             "From Morse Code",
+            "Bifid Cipher Encode",
+            "Bifid Cipher Decode",
             "Affine Cipher Encode",
             "Affine Cipher Decode",
+            "A1Z26 Cipher Encode",
+            "A1Z26 Cipher Decode",
             "Atbash Cipher",
             "Substitute",
             "Derive PBKDF2 key",
             "Derive EVP key",
+            "Bcrypt",
+            "Scrypt",
+            "JWT Sign",
+            "JWT Verify",
+            "JWT Decode",
+            "Citrix CTX1 Encode",
+            "Citrix CTX1 Decode",
+            "Pseudo-Random Number Generator"
         ]
     },
     {
-        name: "Public Key",
-        ops: [
+        "name": "Public Key",
+        "ops": [
             "Parse X.509 certificate",
             "Parse ASN.1 hex string",
             "PEM to Hex",
             "Hex to PEM",
             "Hex to Object Identifier",
             "Object Identifier to Hex",
+            "Generate PGP Key Pair",
+            "PGP Encrypt",
+            "PGP Decrypt",
+            "PGP Encrypt and Sign",
+            "PGP Decrypt and Verify"
         ]
     },
     {
-        name: "Logical operations",
-        ops: [
+        "name": "Arithmetic / Logic",
+        "ops": [
+            "Set Union",
+            "Set Intersection",
+            "Set Difference",
+            "Symmetric Difference",
+            "Cartesian Product",
+            "Power Set",
             "XOR",
             "XOR Brute Force",
             "OR",
@@ -118,15 +137,27 @@ const Categories = [
             "AND",
             "ADD",
             "SUB",
+            "Sum",
+            "Subtract",
+            "Multiply",
+            "Divide",
+            "Mean",
+            "Median",
+            "Standard Deviation",
+            "Bit shift left",
+            "Bit shift right",
             "Rotate left",
             "Rotate right",
-            "ROT13",
+            "ROT13"
         ]
     },
     {
-        name: "Networking",
-        ops: [
+        "name": "Networking",
+        "ops": [
+            "HTTP request",
+            "DNS over HTTPS",
             "Strip HTTP headers",
+            "Dechunk HTTP response",
             "Parse User Agent",
             "Parse IP range",
             "Parse IPv6 address",
@@ -139,26 +170,31 @@ const Categories = [
             "Group IP addresses",
             "Encode NetBIOS Name",
             "Decode NetBIOS Name",
+            "Defang URL"
         ]
     },
     {
-        name: "Language",
-        ops: [
+        "name": "Language",
+        "ops": [
             "Encode text",
             "Decode text",
-            "Unescape Unicode Characters",
+            "Remove Diacritics",
+            "Unescape Unicode Characters"
         ]
     },
     {
-        name: "Utils",
-        ops: [
+        "name": "Utils",
+        "ops": [
             "Diff",
             "Remove whitespace",
             "Remove null bytes",
             "To Upper case",
             "To Lower case",
+			"To Case Insensitive Regex",
+			"From Case Insensitive Regex",
             "Add line numbers",
             "Remove line numbers",
+            "To Table",
             "Reverse",
             "Sort",
             "Unique",
@@ -168,36 +204,44 @@ const Categories = [
             "Tail",
             "Count occurrences",
             "Expand alphabet range",
-            "Parse escaped string",
             "Drop bytes",
             "Take bytes",
             "Pad lines",
             "Find / Replace",
             "Regular expression",
             "Offset checker",
+            "Hamming Distance",
             "Convert distance",
             "Convert area",
             "Convert mass",
             "Convert speed",
             "Convert data units",
+            "Convert co-ordinate format",
             "Parse UNIX file permissions",
             "Swap endianness",
             "Parse colour code",
+            "Escape string",
+            "Unescape string",
+            "Pseudo-Random Number Generator",
+            "Sleep"
         ]
     },
     {
-        name: "Date / Time",
-        ops: [
+        "name": "Date / Time",
+        "ops": [
             "Parse DateTime",
             "Translate DateTime Format",
             "From UNIX Timestamp",
             "To UNIX Timestamp",
+            "Windows Filetime to UNIX Timestamp",
+            "UNIX Timestamp to Windows Filetime",
             "Extract dates",
+            "Sleep"
         ]
     },
     {
-        name: "Extractors",
-        ops: [
+        "name": "Extractors",
+        "ops": [
             "Strings",
             "Extract IP addresses",
             "Extract email addresses",
@@ -208,13 +252,14 @@ const Categories = [
             "Extract dates",
             "Regular expression",
             "XPath expression",
+            "JPath expression",
             "CSS selector",
-            "Extract EXIF",
+            "Extract EXIF"
         ]
     },
     {
-        name: "Compression",
-        ops: [
+        "name": "Compression",
+        "ops": [
             "Raw Deflate",
             "Raw Inflate",
             "Zlib Deflate",
@@ -225,38 +270,50 @@ const Categories = [
             "Unzip",
             "Bzip2 Decompress",
             "Tar",
-            "Untar",
+            "Untar"
         ]
     },
     {
-        name: "Hashing",
-        ops: [
+        "name": "Hashing",
+        "ops": [
             "Analyse hash",
             "Generate all hashes",
             "MD2",
             "MD4",
             "MD5",
+            "MD6",
             "SHA0",
             "SHA1",
-            "SHA224",
-            "SHA256",
-            "SHA384",
-            "SHA512",
+            "SHA2",
             "SHA3",
-            "RIPEMD-160",
+            "Keccak",
+            "Shake",
+            "RIPEMD",
+            "HAS-160",
+            "Whirlpool",
+            "Snefru",
+            "SSDEEP",
+            "CTPH",
+            "Compare SSDEEP hashes",
+            "Compare CTPH hashes",
             "HMAC",
+            "Bcrypt",
+            "Bcrypt compare",
+            "Bcrypt parse",
+            "Scrypt",
             "Fletcher-8 Checksum",
             "Fletcher-16 Checksum",
             "Fletcher-32 Checksum",
             "Fletcher-64 Checksum",
             "Adler-32 Checksum",
+            "CRC-16 Checksum",
             "CRC-32 Checksum",
-            "TCP/IP Checksum",
+            "TCP/IP Checksum"
         ]
     },
     {
-        name: "Code tidy",
-        ops: [
+        "name": "Code tidy",
+        "ops": [
             "Syntax highlighter",
             "Generic Code Beautify",
             "JavaScript Parser",
@@ -271,37 +328,72 @@ const Categories = [
             "CSS Beautify",
             "CSS Minify",
             "XPath expression",
+            "JPath expression",
             "CSS selector",
+            "PHP Deserialize",
+            "Microsoft Script Decoder",
             "Strip HTML tags",
             "Diff",
             "To Snake case",
             "To Camel case",
             "To Kebab case",
+            "BSON serialise",
+            "BSON deserialise",
+            "To MessagePack",
+            "From MessagePack"
         ]
     },
     {
-        name: "Other",
-        ops: [
-            "Entropy",
-            "Frequency distribution",
+        "name": "Forensics",
+        "ops": [
             "Detect File Type",
             "Scan for Embedded Files",
-            "Generate UUID",
+            "Remove EXIF",
+            "Extract EXIF"
+        ]
+    },
+    {
+        "name": "Multimedia",
+        "ops": [
             "Render Image",
+            "Play Media",
+            "Remove EXIF",
+            "Extract EXIF",
+            "Split Colour Channels"
+        ]
+    },
+    {
+        "name": "Other",
+        "ops": [
+            "Entropy",
+            "Frequency distribution",
+            "Chi Square",
+            "Disassemble x86",
+            "Pseudo-Random Number Generator",
+            "Generate UUID",
+            "Generate TOTP",
+            "Generate HOTP",
+            "Generate QR Code",
+            "Parse QR Code",
+            "Haversine distance",
+            "Generate Lorem Ipsum",
             "Numberwang",
+            "XKCD Random Number"
         ]
     },
     {
-        name: "Flow control",
-        ops: [
+        "name": "Flow control",
+        "ops": [
+            "Magic",
             "Fork",
+            "Subsection",
             "Merge",
+            "Register",
+            "Label",
             "Jump",
             "Conditional Jump",
             "Return",
             "Comment"
         ]
-    },
-];
-
-export default Categories;
+    }
+]

+ 0 - 3604
src/core/config/OperationConfig.js

@@ -1,3604 +0,0 @@
-import FlowControl from "../FlowControl.js";
-import Base from "../operations/Base.js";
-import Base58 from "../operations/Base58.js";
-import Base64 from "../operations/Base64.js";
-import BitwiseOp from "../operations/BitwiseOp.js";
-import ByteRepr from "../operations/ByteRepr.js";
-import CharEnc from "../operations/CharEnc.js";
-import Charts from "../operations/Charts.js";
-import Checksum from "../operations/Checksum.js";
-import Cipher from "../operations/Cipher.js";
-import Code from "../operations/Code.js";
-import Compress from "../operations/Compress.js";
-import Convert from "../operations/Convert.js";
-import DateTime from "../operations/DateTime.js";
-import Endian from "../operations/Endian.js";
-import Entropy from "../operations/Entropy.js";
-import Extract from "../operations/Extract.js";
-import FileType from "../operations/FileType.js";
-import Image from "../operations/Image.js";
-import Hash from "../operations/Hash.js";
-import Hexdump from "../operations/Hexdump.js";
-import HTML from "../operations/HTML.js";
-import HTTP from "../operations/HTTP.js";
-import IP from "../operations/IP.js";
-import JS from "../operations/JS.js";
-import MAC from "../operations/MAC.js";
-import MorseCode from "../operations/MorseCode.js";
-import NetBIOS from "../operations/NetBIOS.js";
-import Numberwang from "../operations/Numberwang.js";
-import OS from "../operations/OS.js";
-import PublicKey from "../operations/PublicKey.js";
-import Punycode from "../operations/Punycode.js";
-import QuotedPrintable from "../operations/QuotedPrintable.js";
-import Rotate from "../operations/Rotate.js";
-import SeqUtils from "../operations/SeqUtils.js";
-import StrUtils from "../operations/StrUtils.js";
-import Tidy from "../operations/Tidy.js";
-import Unicode from "../operations/Unicode.js";
-import URL_ from "../operations/URL.js";
-import UUID from "../operations/UUID.js";
-
-
-/**
- * Type definition for an OpConf.
- *
- * @typedef {Object} OpConf
- * @property {html} description - A description of the operation with optional HTML tags
- * @property {Function} run - The function which can be called the run the operation
- * @property {string} inputType
- * @property {string} outputType
- * @property {Function|boolean} [highlight] - A function to calculate the highlight offset, or true
- *   if the offset does not change
- * @property {Function|boolean} [highlightReverse] - A function to calculate the highlight offset
- *   in reverse, or true if the offset does not change
- * @property {boolean} [flowControl] - True if the operation is for Flow Control
- * @property {ArgConf[]} [args] - A list of configuration objects for the arguments
- */
-
-
-/**
- * Type definition for an ArgConf.
- *
- * @typedef {Object} ArgConf
- * @property {string} name - The display name of the argument
- * @property {string} type - The data type of the argument
- * @property {*} value
- * @property {number[]} [disableArgs] - A list of the indices of the operation's arguments which
- *   should be toggled on or off when this argument is changed
- * @property {boolean} [disabled] - Whether or not this argument starts off disabled
- */
-
-
-/**
- * Operation configuration objects.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @constant
- * @type {Object.<string, OpConf>}
- */
-const OperationConfig = {
-    "Fork": {
-        description: "Split the input data up based on the specified delimiter and run all subsequent operations on each branch separately.<br><br>For example, to decode multiple Base64 strings, enter them all on separate lines then add the 'Fork' and 'From Base64' operations to the recipe. Each string will be decoded separately.",
-        run: FlowControl.runFork,
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "Split delimiter",
-                type: "binaryShortString",
-                value: FlowControl.FORK_DELIM
-            },
-            {
-                name: "Merge delimiter",
-                type: "binaryShortString",
-                value: FlowControl.MERGE_DELIM
-            },
-            {
-                name: "Ignore errors",
-                type: "boolean",
-                value: FlowControl.FORK_IGNORE_ERRORS
-            }
-        ]
-    },
-    "Merge": {
-        description: "Consolidate all branches back into a single trunk. The opposite of Fork.",
-        run: FlowControl.runMerge,
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: []
-    },
-    "Jump": {
-        description: "Jump forwards or backwards over the specified number of operations.",
-        run: FlowControl.runJump,
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "Number of operations to jump over",
-                type: "number",
-                value: FlowControl.JUMP_NUM
-            },
-            {
-                name: "Maximum jumps (if jumping backwards)",
-                type: "number",
-                value: FlowControl.MAX_JUMPS
-            }
-        ]
-    },
-    "Conditional Jump": {
-        description: "Conditionally jump forwards or backwards over the specified number of operations based on whether the data matches the specified regular expression.",
-        run: FlowControl.runCondJump,
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "Match (regex)",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Number of operations to jump over if match found",
-                type: "number",
-                value: FlowControl.JUMP_NUM
-            },
-            {
-                name: "Maximum jumps (if jumping backwards)",
-                type: "number",
-                value: FlowControl.MAX_JUMPS
-            }
-        ]
-    },
-    "Return": {
-        description: "End execution of operations at this point in the recipe.",
-        run: FlowControl.runReturn,
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: []
-    },
-    "Comment": {
-        description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.",
-        run: FlowControl.runComment,
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "",
-                type: "text",
-                value: ""
-            }
-        ]
-    },
-    "From Base64": {
-        description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation decodes data from an ASCII Base64 string back into its raw format.<br><br>e.g. <code>aGVsbG8=</code> becomes <code>hello</code>",
-        run: Base64.runFrom,
-        highlight: Base64.highlightFrom,
-        highlightReverse: Base64.highlightTo,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base64.ALPHABET_OPTIONS
-            },
-            {
-                name: "Remove non&#8209;alphabet chars",
-                type: "boolean",
-                value: Base64.REMOVE_NON_ALPH_CHARS
-            }
-        ]
-    },
-    "To Base64": {
-        description: "Base64 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers.<br><br>This operation encodes data in an ASCII Base64 string.<br><br>e.g. <code>hello</code> becomes <code>aGVsbG8=</code>",
-        run: Base64.runTo,
-        highlight: Base64.highlightTo,
-        highlightReverse: Base64.highlightFrom,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base64.ALPHABET_OPTIONS
-            },
-        ]
-    },
-    "From Base58": {
-        description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.<br><br>This operation decodes data from an ASCII string (with an alphabet of your choosing, presets included) back into its raw form.<br><br>e.g. <code>StV1DL6CwTryKyV</code> becomes <code>hello world</code><br><br>Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).",
-        run: Base58.runFrom,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base58.ALPHABET_OPTIONS
-            },
-            {
-                name: "Remove non&#8209;alphabet chars",
-                type: "boolean",
-                value: Base58.REMOVE_NON_ALPH_CHARS
-            }
-        ]
-    },
-    "To Base58": {
-        description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.<br><br>This operation encodes data in an ASCII string (with an alphabet of your choosing, presets included).<br><br>e.g. <code>hello world</code> becomes <code>StV1DL6CwTryKyV</code><br><br>Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).",
-        run: Base58.runTo,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base58.ALPHABET_OPTIONS
-            },
-        ]
-    },
-    "From Base32": {
-        description: "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.",
-        run: Base64.runFrom32,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Alphabet",
-                type: "binaryString",
-                value: Base64.BASE32_ALPHABET
-            },
-            {
-                name: "Remove non&#8209;alphabet chars",
-                type: "boolean",
-                value: Base64.REMOVE_NON_ALPH_CHARS
-            }
-        ]
-    },
-    "To Base32": {
-        description: "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.",
-        run: Base64.runTo32,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Alphabet",
-                type: "binaryString",
-                value: Base64.BASE32_ALPHABET
-            }
-        ]
-    },
-    "Show Base64 offsets": {
-        description: "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.",
-        run: Base64.runOffsets,
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-            {
-                name: "Alphabet",
-                type: "binaryString",
-                value: Base64.ALPHABET
-            },
-            {
-                name: "Show variable chars and padding",
-                type: "boolean",
-                value: Base64.OFFSETS_SHOW_VARIABLE
-            }
-        ]
-    },
-    "XOR": {
-        description: "XOR the input with the given key.<br>e.g. <code>fe023da5</code><br><br><strong>Options</strong><br><u>Null preserving:</u> If the current byte is 0x00 or the same as the key, skip it.<br><br><u>Scheme:</u><ul><li>Standard - key is unchanged after each round</li><li>Input differential - key is set to the value of the previous unprocessed byte</li><li>Output differential - key is set to the value of the previous processed byte</li></ul>",
-        run: BitwiseOp.runXor,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            },
-            {
-                name: "Scheme",
-                type: "option",
-                value: BitwiseOp.XOR_SCHEME
-            },
-            {
-                name: "Null preserving",
-                type: "boolean",
-                value: BitwiseOp.XOR_PRESERVE_NULLS
-            }
-        ]
-    },
-    "XOR Brute Force": {
-        description: "Enumerate all possible XOR solutions. Current maximum key length is 2 due to browser performance.<br><br>Optionally enter a regex string that you expect to find in the plaintext to filter results (crib).",
-        run: BitwiseOp.runXorBrute,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Key length",
-                type: "option",
-                value: BitwiseOp.XOR_BRUTE_KEY_LENGTH
-            },
-            {
-                name: "Length of sample",
-                type: "number",
-                value: BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH
-            },
-            {
-                name: "Offset of sample",
-                type: "number",
-                value: BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET
-            },
-            {
-                name: "Null preserving",
-                type: "boolean",
-                value: BitwiseOp.XOR_PRESERVE_NULLS
-            },
-            {
-                name: "Differential",
-                type: "boolean",
-                value: BitwiseOp.XOR_DIFFERENTIAL
-            },
-            {
-                name: "Crib (known plaintext string)",
-                type: "binaryString",
-                value: ""
-            },
-            {
-                name: "Print key",
-                type: "boolean",
-                value: BitwiseOp.XOR_BRUTE_PRINT_KEY
-            },
-            {
-                name: "Output as hex",
-                type: "boolean",
-                value: BitwiseOp.XOR_BRUTE_OUTPUT_HEX
-            }
-        ]
-    },
-    "NOT": {
-        description: "Returns the inverse of each byte.",
-        run: BitwiseOp.runNot,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: []
-    },
-    "AND": {
-        description: "AND the input with the given key.<br>e.g. <code>fe023da5</code>",
-        run: BitwiseOp.runAnd,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "OR": {
-        description: "OR the input with the given key.<br>e.g. <code>fe023da5</code>",
-        run: BitwiseOp.runOr,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "ADD": {
-        description: "ADD the input with the given key (e.g. <code>fe023da5</code>), MOD 255",
-        run: BitwiseOp.runAdd,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "SUB": {
-        description: "SUB the input with the given key (e.g. <code>fe023da5</code>), MOD 255",
-        run: BitwiseOp.runSub,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "From Hex": {
-        description: "Converts a hexadecimal byte string back into its raw value.<br><br>e.g. <code>ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
-        run: ByteRepr.runFromHex,
-        highlight: ByteRepr.highlightFrom,
-        highlightReverse: ByteRepr.highlightTo,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.HEX_DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Hex": {
-        description: "Converts the input string to hexadecimal bytes separated by the specified delimiter.<br><br>e.g. The UTF-8 encoded string <code>Γειά σου</code> becomes <code>ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a</code>",
-        run: ByteRepr.runToHex,
-        highlight: ByteRepr.highlightTo,
-        highlightReverse: ByteRepr.highlightFrom,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.HEX_DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Octal": {
-        description: "Converts an octal byte string back into its raw value.<br><br>e.g. <code>316 223 316 265 316 271 316 254 40 317 203 316 277 317 205</code> becomes the UTF-8 encoded string <code>Γειά σου</code>",
-        run: ByteRepr.runFromOct,
-        highlight: false,
-        highlightReverse: false,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Octal": {
-        description: "Converts the input string to octal bytes separated by the specified delimiter.<br><br>e.g. The UTF-8 encoded string <code>Γειά σου</code> becomes <code>316 223 316 265 316 271 316 254 40 317 203 316 277 317 205</code>",
-        run: ByteRepr.runToOct,
-        highlight: false,
-        highlightReverse: false,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Charcode": {
-        description: "Converts unicode character codes back into text.<br><br>e.g. <code>0393 03b5 03b9 03ac 20 03c3 03bf 03c5</code> becomes <code>Γειά σου</code>",
-        run: ByteRepr.runFromCharcode,
-        highlight: ByteRepr.highlightFrom,
-        highlightReverse: ByteRepr.highlightTo,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            },
-            {
-                name: "Base",
-                type: "number",
-                value: ByteRepr.CHARCODE_BASE
-            }
-        ]
-    },
-    "To Charcode": {
-        description: "Converts text to its unicode character code equivalent.<br><br>e.g. <code>Γειά σου</code> becomes <code>0393 03b5 03b9 03ac 20 03c3 03bf 03c5</code>",
-        run: ByteRepr.runToCharcode,
-        highlight: ByteRepr.highlightTo,
-        highlightReverse: ByteRepr.highlightFrom,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            },
-            {
-                name: "Base",
-                type: "number",
-                value: ByteRepr.CHARCODE_BASE
-            }
-        ]
-    },
-    "From Binary": {
-        description: "Converts a binary string back into its raw form.<br><br>e.g. <code>01001000 01101001</code> becomes <code>Hi</code>",
-        run: ByteRepr.runFromBinary,
-        highlight: ByteRepr.highlightFromBinary,
-        highlightReverse: ByteRepr.highlightToBinary,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.BIN_DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Binary": {
-        description: "Displays the input data as a binary string.<br><br>e.g. <code>Hi</code> becomes <code>01001000 01101001</code>",
-        run: ByteRepr.runToBinary,
-        highlight: ByteRepr.highlightToBinary,
-        highlightReverse: ByteRepr.highlightFromBinary,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.BIN_DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Decimal": {
-        description: "Converts the data from an ordinal integer array back into its raw form.<br><br>e.g. <code>72 101 108 108 111</code> becomes <code>Hello</code>",
-        run: ByteRepr.runFromDecimal,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Decimal": {
-        description: "Converts the input data to an ordinal integer array.<br><br>e.g. <code>Hello</code> becomes <code>72 101 108 108 111</code>",
-        run: ByteRepr.runToDecimal,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Hexdump": {
-        description: "Attempts to convert a hexdump back into raw data. This operation supports many different hexdump variations, but probably not all. Make sure you verify that the data it gives you is correct before continuing analysis.",
-        run: Hexdump.runFrom,
-        highlight: Hexdump.highlightFrom,
-        highlightReverse: Hexdump.highlightTo,
-        inputType: "string",
-        outputType: "byteArray",
-        args: []
-    },
-    "To Hexdump": {
-        description: "Creates a hexdump of the input data, displaying both the hexademinal values of each byte and an ASCII representation alongside.",
-        run: Hexdump.runTo,
-        highlight: Hexdump.highlightTo,
-        highlightReverse: Hexdump.highlightFrom,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Width",
-                type: "number",
-                value: Hexdump.WIDTH
-            },
-            {
-                name: "Upper case hex",
-                type: "boolean",
-                value: Hexdump.UPPER_CASE
-            },
-            {
-                name: "Include final length",
-                type: "boolean",
-                value: Hexdump.INCLUDE_FINAL_LENGTH
-            }
-        ]
-    },
-    "From Base": {
-        description: "Converts a number to decimal from a given numerical base.",
-        run: Base.runFrom,
-        inputType: "string",
-        outputType: "number",
-        args: [
-            {
-                name: "Radix",
-                type: "number",
-                value: Base.DEFAULT_RADIX
-            }
-        ]
-    },
-    "To Base": {
-        description: "Converts a decimal number to a given numerical base.",
-        run: Base.runTo,
-        inputType: "number",
-        outputType: "string",
-        args: [
-            {
-                name: "Radix",
-                type: "number",
-                value: Base.DEFAULT_RADIX
-            }
-        ]
-    },
-    "From HTML Entity": {
-        description: "Converts HTML entities back to characters<br><br>e.g. <code>&amp;<span>amp;</span></code> becomes <code>&amp;</code>", // <span> tags required to stop the browser just printing &
-        run: HTML.runFromEntity,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "To HTML Entity": {
-        description: "Converts characters to HTML entities<br><br>e.g. <code>&amp;</code> becomes <code>&amp;<span>amp;</span></code>", // <span> tags required to stop the browser just printing &
-        run: HTML.runToEntity,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Convert all characters",
-                type: "boolean",
-                value: HTML.CONVERT_ALL
-            },
-            {
-                name: "Convert to",
-                type: "option",
-                value: HTML.CONVERT_OPTIONS
-            }
-        ]
-    },
-    "Strip HTML tags": {
-        description: "Removes all HTML tags from the input.",
-        run: HTML.runStripTags,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Remove indentation",
-                type: "boolean",
-                value: HTML.REMOVE_INDENTATION
-            },
-            {
-                name: "Remove excess line breaks",
-                type: "boolean",
-                value: HTML.REMOVE_LINE_BREAKS
-            }
-        ]
-    },
-    "URL Decode": {
-        description: "Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
-        run: URL_.runFrom,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "URL Encode": {
-        description: "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.<br><br>e.g. <code>=</code> becomes <code>%3d</code>",
-        run: URL_.runTo,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Encode all special chars",
-                type: "boolean",
-                value: URL_.ENCODE_ALL
-            }
-        ]
-    },
-    "Parse URI": {
-        description: "Pretty prints complicated Uniform Resource Identifier (URI) strings for ease of reading. Particularly useful for Uniform Resource Locators (URLs) with a lot of arguments.",
-        run: URL_.runParse,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Unescape Unicode Characters": {
-        description: "Converts unicode-escaped character notation back into raw characters.<br><br>Supports the prefixes:<ul><li><code>\\u</code></li><li><code>%u</code></li><li><code>U+</code></li></ul>e.g. <code>\\u03c3\\u03bf\\u03c5</code> becomes <code>σου</code>",
-        run: Unicode.runUnescape,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Prefix",
-                type: "option",
-                value: Unicode.PREFIXES
-            }
-        ]
-    },
-    "From Quoted Printable": {
-        description: "Converts QP-encoded text back to standard text.",
-        run: QuotedPrintable.runFrom,
-        inputType: "string",
-        outputType: "byteArray",
-        args: []
-    },
-    "To Quoted Printable": {
-        description: "Quoted-Printable, or QP encoding, is an encoding using printable ASCII characters (alphanumeric and the equals sign '=') to transmit 8-bit data over a 7-bit data path or, generally, over a medium which is not 8-bit clean. It is defined as a MIME content transfer encoding for use in e-mail.<br><br>QP works by using the equals sign '=' as an escape character. It also limits line length to 76, as some software has limits on line length.",
-        run: QuotedPrintable.runTo,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "From Punycode": {
-        description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.<br><br>e.g. <code>mnchen-3ya</code> decodes to <code>münchen</code>",
-        run: Punycode.runToUnicode,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Internationalised domain name",
-                type: "boolean",
-                value: Punycode.IDN
-            }
-        ]
-    },
-    "To Punycode": {
-        description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.<br><br>e.g. <code>münchen</code> encodes to <code>mnchen-3ya</code>",
-        run: Punycode.runToAscii,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Internationalised domain name",
-                type: "boolean",
-                value: Punycode.IDN
-            }
-        ]
-    },
-    "From Hex Content": {
-        description: "Translates hexadecimal bytes in text back to raw bytes.<br><br>e.g. <code>foo|3d|bar</code> becomes <code>foo=bar</code>.",
-        run: ByteRepr.runFromHexContent,
-        inputType: "string",
-        outputType: "byteArray",
-        args: []
-    },
-    "To Hex Content": {
-        description: "Converts special characters in a string to hexadecimal.<br><br>e.g. <code>foo=bar</code> becomes <code>foo|3d|bar</code>.",
-        run: ByteRepr.runToHexContent,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Convert",
-                type: "option",
-                value: ByteRepr.HEX_CONTENT_CONVERT_WHICH
-            },
-            {
-                name: "Print spaces between bytes",
-                type: "boolean",
-                value: ByteRepr.HEX_CONTENT_SPACES_BETWEEN_BYTES
-            },
-        ]
-    },
-    "Change IP format": {
-        description: "Convert an IP address from one format to another, e.g. <code>172.20.23.54</code> to <code>ac141736</code>",
-        run: IP.runChangeIpFormat,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Input format",
-                type: "option",
-                value: IP.IP_FORMAT_LIST
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: IP.IP_FORMAT_LIST
-            }
-        ]
-    },
-    "Parse IP range": {
-        description: "Given a CIDR range (e.g. <code>10.0.0.0/24</code>) or a hyphenated range (e.g. <code>10.0.0.0 - 10.0.1.0</code>), this operation provides network information and enumerates all IP addresses in the range.<br><br>IPv6 is supported but will not be enumerated.",
-        run: IP.runParseIpRange,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Include network info",
-                type: "boolean",
-                value: IP.INCLUDE_NETWORK_INFO
-            },
-            {
-                name: "Enumerate IP addresses",
-                type: "boolean",
-                value: IP.ENUMERATE_ADDRESSES
-            },
-            {
-                name: "Allow large queries",
-                type: "boolean",
-                value: IP.ALLOW_LARGE_LIST
-            }
-        ]
-    },
-    "Group IP addresses": {
-        description: "Groups a list of IP addresses into subnets. Supports both IPv4 and IPv6 addresses.",
-        run: IP.runGroupIps,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: IP.DELIM_OPTIONS
-            },
-            {
-                name: "Subnet (CIDR)",
-                type: "number",
-                value: IP.GROUP_CIDR
-            },
-            {
-                name: "Only show the subnets",
-                type: "boolean",
-                value: IP.GROUP_ONLY_SUBNET
-            }
-        ]
-    },
-    "Parse IPv6 address": {
-        description: "Displays the longhand and shorthand versions of a valid IPv6 address.<br><br>Recognises all reserved ranges and parses encapsulated or tunnelled addresses including Teredo and 6to4.",
-        run: IP.runParseIPv6,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse IPv4 header": {
-        description: "Given an IPv4 header, this operations parses and displays each field in an easily readable format.",
-        run: IP.runParseIPv4Header,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Input format",
-                type: "option",
-                value: IP.IP_HEADER_FORMAT
-            }
-        ]
-    },
-    "Encode text": {
-        description: [
-            "Encodes text into the chosen character encoding.",
-            "<br><br>",
-            "Supported charsets are:",
-            "<ul>",
-            Object.keys(CharEnc.IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
-            "</ul>",
-        ].join("\n"),
-        run: CharEnc.runEncode,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Encoding",
-                type: "option",
-                value: Object.keys(CharEnc.IO_FORMAT),
-            },
-        ]
-    },
-    "Decode text": {
-        description: [
-            "Decodes text from the chosen character encoding.",
-            "<br><br>",
-            "Supported charsets are:",
-            "<ul>",
-            Object.keys(CharEnc.IO_FORMAT).map(e => `<li>${e}</li>`).join("\n"),
-            "</ul>",
-        ].join("\n"),
-        run: CharEnc.runDecode,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Encoding",
-                type: "option",
-                value: Object.keys(CharEnc.IO_FORMAT),
-            },
-        ]
-    },
-    "AES Decrypt": {
-        description: "To successfully decrypt AES, you need either:<ul><li>The passphrase</li><li>Or the key and IV</li></ul>The IV should be the first 16 bytes of encrypted material.",
-        run: Cipher.runAesDec,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT2
-            },
-        ]
-    },
-    "AES Encrypt": {
-        description: "Input: Either enter a passphrase (which will be used to derive a key using the OpenSSL KDF) or both the key and IV.<br><br>Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br>AES-128, AES-192, and AES-256 are supported.  The variant will be chosen based on the size of the key passed in.  If a passphrase is used, a 256-bit key will be generated.",
-        run: Cipher.runAesEnc,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Output result",
-                type: "option",
-                value: Cipher.RESULT_TYPE
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-        ]
-    },
-    "DES Decrypt": {
-        description: "To successfully decrypt DES, you need either:<ul><li>The passphrase</li><li>Or the key and IV</li></ul>The IV should be the first 8 bytes of encrypted material.",
-        run: Cipher.runDesDec,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT2
-            },
-        ]
-    },
-    "DES Encrypt": {
-        description: "Input: Either enter a passphrase (which will be used to derive a key using the OpenSSL KDF) or both the key and IV.<br><br>DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.",
-        run: Cipher.runDesEnc,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Output result",
-                type: "option",
-                value: Cipher.RESULT_TYPE
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-        ]
-    },
-    "Triple DES Decrypt": {
-        description: "To successfully decrypt Triple DES, you need either:<ul><li>The passphrase</li><li>Or the key and IV</li></ul>The IV should be the first 8 bytes of encrypted material.",
-        run: Cipher.runTripleDesDec,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT2
-            },
-        ]
-    },
-    "Triple DES Encrypt": {
-        description: "Input: Either enter a passphrase (which will be used to derive a key using the OpenSSL KDF) or both the key and IV.<br><br>Triple DES applies DES three times to each block to increase key size.",
-        run: Cipher.runTripleDesEnc,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Output result",
-                type: "option",
-                value: Cipher.RESULT_TYPE
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-        ]
-    },
-    "Blowfish Decrypt": {
-        description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.",
-        run: Cipher.runBlowfishDec,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.BLOWFISH_MODES
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT3
-            },
-        ]
-    },
-    "Blowfish Encrypt": {
-        description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.",
-        run: Cipher.runBlowfishEnc,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.BLOWFISH_MODES
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT3
-            },
-        ]
-    },
-    "Rabbit Decrypt": {
-        description: "To successfully decrypt Rabbit, you need either:<ul><li>The passphrase</li><li>Or the key and IV (This is currently broken. You need the key and salt at the moment.)</li></ul>The IV should be the first 8 bytes of encrypted material.",
-        run: Cipher.runRabbitDec,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT2
-            },
-        ]
-    },
-    "Rabbit Encrypt": {
-        description: "Input: Either enter a passphrase (which will be used to derive a key using the OpenSSL KDF) or both the key and IV.<br><br>Rabbit is a high-performance stream cipher and a finalist in the eSTREAM Portfolio.  It is one of the four designs selected after a 3 1/2 year process where 22 designs were evaluated.",
-        run: Cipher.runRabbitEnc,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase/Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "IV",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-
-            },
-            {
-                name: "Salt",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT1
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: Cipher.MODES
-            },
-            {
-                name: "Padding",
-                type: "option",
-                value: Cipher.PADDING
-            },
-            {
-                name: "Output result",
-                type: "option",
-                value: Cipher.RESULT_TYPE
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT1
-            },
-        ]
-    },
-    "RC4": {
-        description: "RC4 is a widely-used stream cipher. It is used in popular protocols such as SSL and WEP. Although remarkable for its simplicity and speed, the algorithm's history doesn't inspire confidence in its security.",
-        run: Cipher.runRc4,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT4
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT4
-            },
-        ]
-    },
-    "RC4 Drop": {
-        description: "It was discovered that the first few bytes of the RC4 keystream are strongly non-random and leak information about the key. We can defend against this attack by discarding the initial portion of the keystream. This modified algorithm is traditionally called RC4-drop.",
-        run: Cipher.runRc4drop,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Passphrase",
-                type: "toggleString",
-                value: "",
-                toggleValues: Cipher.IO_FORMAT2
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT4
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT4
-            },
-            {
-                name: "Number of bytes to drop",
-                type: "number",
-                value: Cipher.RC4DROP_BYTES
-            },
-        ]
-    },
-    "Derive PBKDF2 key": {
-        description: "PBKDF2 is a password-based key derivation function. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.<br><br>A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.<br><br>Enter your passphrase as the input and then set the relevant options to generate a key.",
-        run: Cipher.runPbkdf2,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key size",
-                type: "number",
-                value: Cipher.KDF_KEY_SIZE
-            },
-            {
-                name: "Iterations",
-                type: "number",
-                value: Cipher.KDF_ITERATIONS
-            },
-            {
-                name: "Hashing function",
-                type: "option",
-                value: Cipher.HASHERS
-            },
-            {
-                name: "Salt (hex)",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT2
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT3
-            },
-        ]
-    },
-    "Derive EVP key": {
-        description: "EVP is a password-based key derivation function used extensively in OpenSSL. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.<br><br>A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.<br><br>Enter your passphrase as the input and then set the relevant options to generate a key.",
-        run: Cipher.runEvpkdf,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key size",
-                type: "number",
-                value: Cipher.KDF_KEY_SIZE
-            },
-            {
-                name: "Iterations",
-                type: "number",
-                value: Cipher.KDF_ITERATIONS
-            },
-            {
-                name: "Hashing function",
-                type: "option",
-                value: Cipher.HASHERS
-            },
-            {
-                name: "Salt (hex)",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Cipher.IO_FORMAT2
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Cipher.IO_FORMAT3
-            },
-        ]
-    },
-    "Vigenère Encode": {
-        description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.",
-        run: Cipher.runVigenereEnc,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key",
-                type: "string",
-                value: ""
-            }
-        ]
-    },
-    "Vigenère Decode": {
-        description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.",
-        run: Cipher.runVigenereDec,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key",
-                type: "string",
-                value: ""
-            }
-        ]
-    },
-    "Affine Cipher Encode": {
-        description: "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, <code>(ax + b) % 26</code>, and converted back to a letter.",
-        run: Cipher.runAffineEnc,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "a",
-                type: "number",
-                value: Cipher.AFFINE_A
-            },
-            {
-                name: "b",
-                type: "number",
-                value: Cipher.AFFINE_B
-            }
-        ]
-    },
-    "Affine Cipher Decode": {
-        description: "The Affine cipher is a type of monoalphabetic substitution cipher. To decrypt, each letter in an alphabet is mapped to its numeric equivalent, decrypted by a mathematical function, and converted back to a letter.",
-        run: Cipher.runAffineDec,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "a",
-                type: "number",
-                value: Cipher.AFFINE_A
-            },
-            {
-                name: "b",
-                type: "number",
-                value: Cipher.AFFINE_B
-            }
-        ]
-    },
-    "Atbash Cipher": {
-        description: "Atbash is a mono-alphabetic substitution cipher originally used to encode the Hebrew alphabet. It has been modified here for use with the Latin alphabet.",
-        run: Cipher.runAtbash,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Rotate right": {
-        description: "Rotates each byte to the right by the number of bits specified. Currently only supports 8-bit values.",
-        run: Rotate.runRotr,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Number of bits",
-                type: "number",
-                value: Rotate.ROTATE_AMOUNT
-            },
-            {
-                name: "Rotate as a whole",
-                type: "boolean",
-                value: Rotate.ROTATE_WHOLE
-            }
-        ]
-    },
-    "Rotate left": {
-        description: "Rotates each byte to the left by the number of bits specified. Currently only supports 8-bit values.",
-        run: Rotate.runRotl,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Number of bits",
-                type: "number",
-                value: Rotate.ROTATE_AMOUNT
-            },
-            {
-                name: "Rotate as a whole",
-                type: "boolean",
-                value: Rotate.ROTATE_WHOLE
-            }
-        ]
-    },
-    "ROT13": {
-        description: "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).",
-        run: Rotate.runRot13,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Rotate lower case chars",
-                type: "boolean",
-                value: Rotate.ROT13_LOWERCASE
-            },
-            {
-                name: "Rotate upper case chars",
-                type: "boolean",
-                value: Rotate.ROT13_UPPERCASE
-            },
-            {
-                name: "Amount",
-                type: "number",
-                value: Rotate.ROT13_AMOUNT
-            },
-        ]
-    },
-    "ROT47": {
-        description: "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.",
-        run: Rotate.runRot47,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Amount",
-                type: "number",
-                value: Rotate.ROT47_AMOUNT
-            },
-        ]
-    },
-    "Strip HTTP headers": {
-        description: "Removes HTTP headers from a request or response by looking for the first instance of a double newline.",
-        run: HTTP.runStripHeaders,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse User Agent": {
-        description: "Attempts to identify and categorise information contained in a user-agent string.",
-        run: HTTP.runParseUserAgent,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Format MAC addresses": {
-        description: "Displays given MAC addresses in multiple different formats.<br><br>Expects addresses in a list separated by newlines, spaces or commas.<br><br>WARNING: There are no validity checks.",
-        run: MAC.runFormat,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Output case",
-                type: "option",
-                value: MAC.OUTPUT_CASE
-            },
-            {
-                name: "No delimiter",
-                type: "boolean",
-                value: MAC.NO_DELIM
-            },
-            {
-                name: "Dash delimiter",
-                type: "boolean",
-                value: MAC.DASH_DELIM
-            },
-            {
-                name: "Colon delimiter",
-                type: "boolean",
-                value: MAC.COLON_DELIM
-            },
-            {
-                name: "Cisco style",
-                type: "boolean",
-                value: MAC.CISCO_STYLE
-            }
-        ]
-    },
-    "Encode NetBIOS Name": {
-        description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.<br><br>There are two levels of encoding. The first level maps a NetBIOS name into a domain system name.  The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.<br><br>This operation carries out the first level of encoding. See RFC 1001 for full details.",
-        run: NetBIOS.runEncodeName,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Offset",
-                type: "number",
-                value: NetBIOS.OFFSET
-            }
-        ]
-    },
-    "Decode NetBIOS Name": {
-        description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.<br><br>There are two levels of encoding. The first level maps a NetBIOS name into a domain system name.  The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.<br><br>This operation decodes the first level of encoding. See RFC 1001 for full details.",
-        run: NetBIOS.runDecodeName,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Offset",
-                type: "number",
-                value: NetBIOS.OFFSET
-            }
-        ]
-    },
-    "Offset checker": {
-        description: "Compares multiple inputs (separated by the specified delimiter) and highlights matching characters which appear at the same position in all samples.",
-        run: StrUtils.runOffsetChecker,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Sample delimiter",
-                type: "binaryString",
-                value: StrUtils.OFF_CHK_SAMPLE_DELIMITER
-            }
-        ]
-    },
-    "Remove whitespace": {
-        description: "Optionally removes all spaces, carriage returns, line feeds, tabs and form feeds from the input data.<br><br>This operation also supports the removal of full stops which are sometimes used to represent non-printable bytes in ASCII output.",
-        run: Tidy.runRemoveWhitespace,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Spaces",
-                type: "boolean",
-                value: Tidy.REMOVE_SPACES
-            },
-            {
-                name: "Carriage returns (\\r)",
-                type: "boolean",
-                value: Tidy.REMOVE_CARIAGE_RETURNS
-            },
-            {
-                name: "Line feeds (\\n)",
-                type: "boolean",
-                value: Tidy.REMOVE_LINE_FEEDS
-            },
-            {
-                name: "Tabs",
-                type: "boolean",
-                value: Tidy.REMOVE_TABS
-            },
-            {
-                name: "Form feeds (\\f)",
-                type: "boolean",
-                value: Tidy.REMOVE_FORM_FEEDS
-            },
-            {
-                name: "Full stops",
-                type: "boolean",
-                value: Tidy.REMOVE_FULL_STOPS
-            }
-        ]
-    },
-    "Remove null bytes": {
-        description: "Removes all null bytes (<code>0x00</code>) from the input.",
-        run: Tidy.runRemoveNulls,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: []
-    },
-    "Drop bytes": {
-        description: "Cuts the specified number of bytes out of the data.",
-        run: Tidy.runDropBytes,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Start",
-                type: "number",
-                value: Tidy.DROP_START
-            },
-            {
-                name: "Length",
-                type: "number",
-                value: Tidy.DROP_LENGTH
-            },
-            {
-                name: "Apply to each line",
-                type: "boolean",
-                value: Tidy.APPLY_TO_EACH_LINE
-            }
-        ]
-    },
-    "Take bytes": {
-        description: "Takes a slice of the specified number of bytes from the data.",
-        run: Tidy.runTakeBytes,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Start",
-                type: "number",
-                value: Tidy.TAKE_START
-            },
-            {
-                name: "Length",
-                type: "number",
-                value: Tidy.TAKE_LENGTH
-            },
-            {
-                name: "Apply to each line",
-                type: "boolean",
-                value: Tidy.APPLY_TO_EACH_LINE
-            }
-        ]
-    },
-    "Pad lines": {
-        description: "Add the specified number of the specified character to the beginning or end of each line",
-        run: Tidy.runPad,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Position",
-                type: "option",
-                value: Tidy.PAD_POSITION
-            },
-            {
-                name: "Length",
-                type: "number",
-                value: Tidy.PAD_LENGTH
-            },
-            {
-                name: "Character",
-                type: "binaryShortString",
-                value: Tidy.PAD_CHAR
-            }
-        ]
-    },
-    "Reverse": {
-        description: "Reverses the input string.",
-        run: SeqUtils.runReverse,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "By",
-                type: "option",
-                value: SeqUtils.REVERSE_BY
-            }
-        ]
-    },
-    "Sort": {
-        description: "Alphabetically sorts strings separated by the specified delimiter.<br><br>The IP address option supports IPv4 only.",
-        run: SeqUtils.runSort,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: SeqUtils.DELIMITER_OPTIONS
-            },
-            {
-                name: "Reverse",
-                type: "boolean",
-                value: SeqUtils.SORT_REVERSE
-            },
-            {
-                name: "Order",
-                type: "option",
-                value: SeqUtils.SORT_ORDER
-            }
-        ]
-    },
-    "Unique": {
-        description: "Removes duplicate strings from the input.",
-        run: SeqUtils.runUnique,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: SeqUtils.DELIMITER_OPTIONS
-            }
-        ]
-    },
-    "Count occurrences": {
-        description: "Counts the number of times the provided string occurs in the input.",
-        run: SeqUtils.runCount,
-        inputType: "string",
-        outputType: "number",
-        args: [
-            {
-                name: "Search string",
-                type: "toggleString",
-                value: "",
-                toggleValues: SeqUtils.SEARCH_TYPE
-            }
-        ]
-    },
-    "Add line numbers": {
-        description: "Adds line numbers to the output.",
-        run: SeqUtils.runAddLineNumbers,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Remove line numbers": {
-        description: "Removes line numbers from the output if they can be trivially detected.",
-        run: SeqUtils.runRemoveLineNumbers,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Find / Replace": {
-        description: "Replaces all occurrences of the first string with the second.<br><br>The three match options are only relevant to regex search strings.",
-        run: StrUtils.runFindReplace,
-        manualBake: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Find",
-                type: "toggleString",
-                value: "",
-                toggleValues: StrUtils.SEARCH_TYPE
-            },
-            {
-                name: "Replace",
-                type: "binaryString",
-                value: ""
-            },
-            {
-                name: "Global match",
-                type: "boolean",
-                value: StrUtils.FIND_REPLACE_GLOBAL,
-            },
-            {
-                name: "Case insensitive",
-                type: "boolean",
-                value: StrUtils.FIND_REPLACE_CASE,
-            },
-            {
-                name: "Multiline matching",
-                type: "boolean",
-                value: StrUtils.FIND_REPLACE_MULTILINE,
-            },
-
-        ]
-    },
-    "To Upper case": {
-        description: "Converts the input string to upper case, optionally limiting scope to only the first character in each word, sentence or paragraph.",
-        run: StrUtils.runUpper,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Scope",
-                type: "option",
-                value: StrUtils.CASE_SCOPE
-            }
-        ]
-    },
-    "To Lower case": {
-        description: "Converts every character in the input to lower case.",
-        run: StrUtils.runLower,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Split": {
-        description: "Splits a string into sections around a given delimiter.",
-        run: StrUtils.runSplit,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Split delimiter",
-                type: "binaryShortString",
-                value: StrUtils.SPLIT_DELIM
-            },
-            {
-                name: "Join delimiter",
-                type: "option",
-                value: StrUtils.DELIMITER_OPTIONS
-            }
-        ]
-    },
-    "Filter": {
-        description: "Splits up the input using the specified delimiter and then filters each branch based on a regular expression.",
-        run: StrUtils.runFilter,
-        manualBake: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: StrUtils.DELIMITER_OPTIONS
-            },
-            {
-                name: "Regex",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Invert condition",
-                type: "boolean",
-                value: SeqUtils.SORT_REVERSE
-            },
-        ]
-    },
-    "Strings": {
-        description: "Extracts all strings from the input.",
-        run: Extract.runStrings,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Minimum length",
-                type: "number",
-                value: Extract.MIN_STRING_LEN
-            },
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract IP addresses": {
-        description: "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>710.65.0.456</code>, this will match <code>10.65.0.45</code> so always check the original input!",
-        run: Extract.runIp,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "IPv4",
-                type: "boolean",
-                value: Extract.INCLUDE_IPV4
-            },
-            {
-                name: "IPv6",
-                type: "boolean",
-                value: Extract.INCLUDE_IPV6
-            },
-            {
-                name: "Remove local IPv4 addresses",
-                type: "boolean",
-                value: Extract.REMOVE_LOCAL
-            },
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract email addresses": {
-        description: "Extracts all email addresses from the input.",
-        run: Extract.runEmail,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract MAC addresses": {
-        description: "Extracts all Media Access Control (MAC) addresses from the input.",
-        run: Extract.runMac,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract URLs": {
-        description: "Extracts Uniform Resource Locators (URLs) from the input. The protocol (http, ftp etc.) is required otherwise there will be far too many false positives.",
-        run: Extract.runUrls,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract domains": {
-        description: "Extracts domain names with common Top-Level Domains (TLDs).<br>Note that this will not include paths. Use <strong>Extract URLs</strong> to find entire URLs.",
-        run: Extract.runDomains,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract file paths": {
-        description: "Extracts anything that looks like a Windows or UNIX file path.<br><br>Note that if UNIX is selected, there will likely be a lot of false positives.",
-        run: Extract.runFilePaths,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Windows",
-                type: "boolean",
-                value: Extract.INCLUDE_WIN_PATH
-            },
-            {
-                name: "UNIX",
-                type: "boolean",
-                value: Extract.INCLUDE_UNIX_PATH
-            },
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract dates": {
-        description: "Extracts dates in the following formats<ul><li><code>yyyy-mm-dd</code></li><li><code>dd/mm/yyyy</code></li><li><code>mm/dd/yyyy</code></li></ul>Dividers can be any of /, -, . or space",
-        run: Extract.runDates,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Regular expression": {
-        description: "Define your own regular expression (regex) to search the input data with, optionally choosing from a list of pre-defined patterns.",
-        run: StrUtils.runRegex,
-        manualBake: true,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Built in regexes",
-                type: "populateOption",
-                value: StrUtils.REGEX_PRE_POPULATE,
-                target: 1,
-            },
-            {
-                name: "Regex",
-                type: "text",
-                value: ""
-            },
-            {
-                name: "Case insensitive",
-                type: "boolean",
-                value: StrUtils.REGEX_CASE_INSENSITIVE
-            },
-            {
-                name: "Multiline matching",
-                type: "boolean",
-                value: StrUtils.REGEX_MULTILINE_MATCHING
-            },
-            {
-                name: "Display total",
-                type: "boolean",
-                value: StrUtils.DISPLAY_TOTAL
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: StrUtils.OUTPUT_FORMAT
-            },
-        ]
-    },
-    "XPath expression": {
-        description: "Extract information from an XML document with an XPath query",
-        run: Code.runXpath,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "XPath",
-                type: "string",
-                value: Code.XPATH_INITIAL
-            },
-            {
-                name: "Result delimiter",
-                type: "binaryShortString",
-                value: Code.XPATH_DELIMITER
-            }
-        ]
-    },
-    "CSS selector": {
-        description: "Extract information from an HTML document with a CSS selector",
-        run: Code.runCSSQuery,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "CSS selector",
-                type: "string",
-                value: Code.CSS_SELECTOR_INITIAL
-            },
-            {
-                name: "Delimiter",
-                type: "binaryShortString",
-                value: Code.CSS_QUERY_DELIMITER
-            },
-        ]
-    },
-    "From UNIX Timestamp": {
-        description: "Converts a UNIX timestamp to a datetime string.<br><br>e.g. <code>978346800</code> becomes <code>Mon 1 January 2001 11:00:00 UTC</code>",
-        run: DateTime.runFromUnixTimestamp,
-        inputType: "number",
-        outputType: "string",
-        args: [
-            {
-                name: "Units",
-                type: "option",
-                value: DateTime.UNITS
-            }
-        ]
-    },
-    "To UNIX Timestamp": {
-        description: "Parses a datetime string in UTC and returns the corresponding UNIX timestamp.<br><br>e.g. <code>Mon 1 January 2001 11:00:00</code> becomes <code>978346800</code>",
-        run: DateTime.runToUnixTimestamp,
-        inputType: "string",
-        outputType: "number",
-        args: [
-            {
-                name: "Units",
-                type: "option",
-                value: DateTime.UNITS
-            },
-            {
-                name: "Treat as UTC",
-                type: "boolean",
-                value: DateTime.TREAT_AS_UTC
-            }
-        ]
-    },
-    "Translate DateTime Format": {
-        description: "Parses a datetime string in one format and re-writes it in another.<br><br>Run with no input to see the relevant format string examples.",
-        run: DateTime.runTranslateFormat,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Built in formats",
-                type: "populateOption",
-                value: DateTime.DATETIME_FORMATS,
-                target: 1
-            },
-            {
-                name: "Input format string",
-                type: "binaryString",
-                value: DateTime.INPUT_FORMAT_STRING
-            },
-            {
-                name: "Input timezone",
-                type: "option",
-                value: DateTime.TIMEZONES
-            },
-            {
-                name: "Output format string",
-                type: "binaryString",
-                value: DateTime.OUTPUT_FORMAT_STRING
-            },
-            {
-                name: "Output timezone",
-                type: "option",
-                value: DateTime.TIMEZONES
-            }
-        ]
-    },
-    "Parse DateTime": {
-        description: "Parses a DateTime string in your specified format and displays it in whichever timezone you choose with the following information:<ul><li>Date</li><li>Time</li><li>Period (AM/PM)</li><li>Timezone</li><li>UTC offset</li><li>Daylight Saving Time</li><li>Leap year</li><li>Days in this month</li><li>Day of year</li><li>Week number</li><li>Quarter</li></ul>Run with no input to see format string examples if required.",
-        run: DateTime.runParse,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Built in formats",
-                type: "populateOption",
-                value: DateTime.DATETIME_FORMATS,
-                target: 1
-            },
-            {
-                name: "Input format string",
-                type: "binaryString",
-                value: DateTime.INPUT_FORMAT_STRING
-            },
-            {
-                name: "Input timezone",
-                type: "option",
-                value: DateTime.TIMEZONES
-            },
-        ]
-    },
-    "Convert distance": {
-        description: "Converts a unit of distance to another format.",
-        run: Convert.runDistance,
-        inputType: "number",
-        outputType: "number",
-        args: [
-            {
-                name: "Input units",
-                type: "option",
-                value: Convert.DISTANCE_UNITS
-            },
-            {
-                name: "Output units",
-                type: "option",
-                value: Convert.DISTANCE_UNITS
-            }
-        ]
-    },
-    "Convert area": {
-        description: "Converts a unit of area to another format.",
-        run: Convert.runArea,
-        inputType: "number",
-        outputType: "number",
-        args: [
-            {
-                name: "Input units",
-                type: "option",
-                value: Convert.AREA_UNITS
-            },
-            {
-                name: "Output units",
-                type: "option",
-                value: Convert.AREA_UNITS
-            }
-        ]
-    },
-    "Convert mass": {
-        description: "Converts a unit of mass to another format.",
-        run: Convert.runMass,
-        inputType: "number",
-        outputType: "number",
-        args: [
-            {
-                name: "Input units",
-                type: "option",
-                value: Convert.MASS_UNITS
-            },
-            {
-                name: "Output units",
-                type: "option",
-                value: Convert.MASS_UNITS
-            }
-        ]
-    },
-    "Convert speed": {
-        description: "Converts a unit of speed to another format.",
-        run: Convert.runSpeed,
-        inputType: "number",
-        outputType: "number",
-        args: [
-            {
-                name: "Input units",
-                type: "option",
-                value: Convert.SPEED_UNITS
-            },
-            {
-                name: "Output units",
-                type: "option",
-                value: Convert.SPEED_UNITS
-            }
-        ]
-    },
-    "Convert data units": {
-        description: "Converts a unit of data to another format.",
-        run: Convert.runDataSize,
-        inputType: "number",
-        outputType: "number",
-        args: [
-            {
-                name: "Input units",
-                type: "option",
-                value: Convert.DATA_UNITS
-            },
-            {
-                name: "Output units",
-                type: "option",
-                value: Convert.DATA_UNITS
-            }
-        ]
-    },
-    "Raw Deflate": {
-        description: "Compresses data using the deflate algorithm with no headers.",
-        run: Compress.runRawDeflate,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Compression type",
-                type: "option",
-                value: Compress.COMPRESSION_TYPE
-            }
-        ]
-    },
-    "Raw Inflate": {
-        description: "Decompresses data which has been compressed using the deflate algorithm with no headers.",
-        run: Compress.runRawInflate,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Start index",
-                type: "number",
-                value: Compress.INFLATE_INDEX
-            },
-            {
-                name: "Initial output buffer size",
-                type: "number",
-                value: Compress.INFLATE_BUFFER_SIZE
-            },
-            {
-                name: "Buffer expansion type",
-                type: "option",
-                value: Compress.INFLATE_BUFFER_TYPE
-            },
-            {
-                name: "Resize buffer after decompression",
-                type: "boolean",
-                value: Compress.INFLATE_RESIZE
-            },
-            {
-                name: "Verify result",
-                type: "boolean",
-                value: Compress.INFLATE_VERIFY
-            }
-        ]
-    },
-    "Zlib Deflate": {
-        description: "Compresses data using the deflate algorithm adding zlib headers.",
-        run: Compress.runZlibDeflate,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Compression type",
-                type: "option",
-                value: Compress.COMPRESSION_TYPE
-            }
-        ]
-    },
-    "Zlib Inflate": {
-        description: "Decompresses data which has been compressed using the deflate algorithm with zlib headers.",
-        run: Compress.runZlibInflate,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Start index",
-                type: "number",
-                value: Compress.INFLATE_INDEX
-            },
-            {
-                name: "Initial output buffer size",
-                type: "number",
-                value: Compress.INFLATE_BUFFER_SIZE
-            },
-            {
-                name: "Buffer expansion type",
-                type: "option",
-                value: Compress.INFLATE_BUFFER_TYPE
-            },
-            {
-                name: "Resize buffer after decompression",
-                type: "boolean",
-                value: Compress.INFLATE_RESIZE
-            },
-            {
-                name: "Verify result",
-                type: "boolean",
-                value: Compress.INFLATE_VERIFY
-            }
-        ]
-    },
-    "Gzip": {
-        description: "Compresses data using the deflate algorithm with gzip headers.",
-        run: Compress.runGzip,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Compression type",
-                type: "option",
-                value: Compress.COMPRESSION_TYPE
-            },
-            {
-                name: "Filename (optional)",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Comment (optional)",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Include file checksum",
-                type: "boolean",
-                value: Compress.GZIP_CHECKSUM
-            }
-        ]
-    },
-    "Gunzip": {
-        description: "Decompresses data which has been compressed using the deflate algorithm with gzip headers.",
-        run: Compress.runGunzip,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: []
-    },
-    "Zip": {
-        description: "Compresses data using the PKZIP algorithm with the given filename.<br><br>No support for multiple files at this time.",
-        run: Compress.runPkzip,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Filename",
-                type: "string",
-                value: Compress.PKZIP_FILENAME
-            },
-            {
-                name: "Comment",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Password",
-                type: "binaryString",
-                value: ""
-            },
-            {
-                name: "Compression method",
-                type: "option",
-                value: Compress.COMPRESSION_METHOD
-            },
-            {
-                name: "Operating system",
-                type: "option",
-                value: Compress.OS
-            },
-            {
-                name: "Compression type",
-                type: "option",
-                value: Compress.COMPRESSION_TYPE
-            }
-        ]
-    },
-    "Unzip": {
-        description: "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.",
-        run: Compress.runPkunzip,
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-            {
-                name: "Password",
-                type: "binaryString",
-                value: ""
-            },
-            {
-                name: "Verify result",
-                type: "boolean",
-                value: Compress.PKUNZIP_VERIFY
-            }
-        ]
-    },
-    "Bzip2 Decompress": {
-        description: "Decompresses data using the Bzip2 algorithm.",
-        run: Compress.runBzip2Decompress,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Generic Code Beautify": {
-        description: "Attempts to pretty print C-style languages such as C, C++, C#, Java, PHP, JavaScript etc.<br><br>This will not do a perfect job, and the resulting code may not work any more. This operation is designed purely to make obfuscated or minified code more easy to read and understand.<br><br>Things which will not work properly:<ul><li>For loop formatting</li><li>Do-While loop formatting</li><li>Switch/Case indentation</li><li>Certain bit shift operators</li></ul>",
-        run: Code.runGenericBeautify,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "JavaScript Parser": {
-        description: "Returns an Abstract Syntax Tree for valid JavaScript code.",
-        run: JS.runParse,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Location info",
-                type: "boolean",
-                value: JS.PARSE_LOC
-            },
-            {
-                name: "Range info",
-                type: "boolean",
-                value: JS.PARSE_RANGE
-            },
-            {
-                name: "Include tokens array",
-                type: "boolean",
-                value: JS.PARSE_TOKENS
-            },
-            {
-                name: "Include comments array",
-                type: "boolean",
-                value: JS.PARSE_COMMENT
-            },
-            {
-                name: "Report errors and try to continue",
-                type: "boolean",
-                value: JS.PARSE_TOLERANT
-            },
-        ]
-    },
-    "JavaScript Beautify": {
-        description: "Parses and pretty prints valid JavaScript code. Also works with JavaScript Object Notation (JSON).",
-        run: JS.runBeautify,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: JS.BEAUTIFY_INDENT
-            },
-            {
-                name: "Quotes",
-                type: "option",
-                value: JS.BEAUTIFY_QUOTES
-            },
-            {
-                name: "Semicolons before closing braces",
-                type: "boolean",
-                value: JS.BEAUTIFY_SEMICOLONS
-            },
-            {
-                name: "Include comments",
-                type: "boolean",
-                value: JS.BEAUTIFY_COMMENT
-            },
-        ]
-    },
-    "JavaScript Minify": {
-        description: "Compresses JavaScript code.",
-        run: JS.runMinify,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "XML Beautify": {
-        description: "Indents and prettifies eXtensible Markup Language (XML) code.",
-        run: Code.runXmlBeautify,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "JSON Beautify": {
-        description: "Indents and prettifies JavaScript Object Notation (JSON) code.",
-        run: Code.runJsonBeautify,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "CSS Beautify": {
-        description: "Indents and prettifies Cascading Style Sheets (CSS) code.",
-        run: Code.runCssBeautify,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "SQL Beautify": {
-        description: "Indents and prettifies Structured Query Language (SQL) code.",
-        run: Code.runSqlBeautify,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "XML Minify": {
-        description: "Compresses eXtensible Markup Language (XML) code.",
-        run: Code.runXmlMinify,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Preserve comments",
-                type: "boolean",
-                value: Code.PRESERVE_COMMENTS
-            }
-        ]
-    },
-    "JSON Minify": {
-        description: "Compresses JavaScript Object Notation (JSON) code.",
-        run: Code.runJsonMinify,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "CSS Minify": {
-        description: "Compresses Cascading Style Sheets (CSS) code.",
-        run: Code.runCssMinify,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Preserve comments",
-                type: "boolean",
-                value: Code.PRESERVE_COMMENTS
-            }
-        ]
-    },
-    "SQL Minify": {
-        description: "Compresses Structured Query Language (SQL) code.",
-        run: Code.runSqlMinify,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Analyse hash": {
-        description: "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.",
-        run: Hash.runAnalyse,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "MD2": {
-        description: "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.<br><br>Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA.",
-        run: Hash.runMD2,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "MD4": {
-        description: "The MD4 (Message-Digest 4) algorithm is a cryptographic hash function developed by Ronald Rivest in 1990. The digest length is 128 bits. The algorithm has influenced later designs, such as the MD5, SHA-1 and RIPEMD algorithms.<br><br>The security of MD4 has been severely compromised.",
-        run: Hash.runMD4,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "MD5": {
-        description: "MD5 (Message-Digest 5) is a widely used hash function. It has been used in a variety of security applications and is also commonly used to check the integrity of files.<br><br>However, MD5 is not collision resistant and it isn't suitable for applications like SSL/TLS certificates or digital signatures that rely on this property.",
-        run: Hash.runMD5,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA0": {
-        description: "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1.",
-        run: Hash.runSHA0,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA1": {
-        description: "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.<br><br>However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved.",
-        run: Hash.runSHA1,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA224": {
-        description: "SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.",
-        run: Hash.runSHA224,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA256": {
-        description: "SHA-256 is one of the four variants in the SHA-2 set. It isn't as widely used as SHA-1, though it provides much better security.",
-        run: Hash.runSHA256,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA384": {
-        description: "SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.",
-        run: Hash.runSHA384,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA512": {
-        description: "SHA-512 is largely identical to SHA-256 but operates on 64-bit words rather than 32.",
-        run: Hash.runSHA512,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA3": {
-        description: "This is an implementation of Keccak[c=2d]. SHA3 functions based on different implementations of Keccak will give different results.",
-        run: Hash.runSHA3,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Output length",
-                type: "option",
-                value: Hash.SHA3_LENGTH
-            }
-        ]
-    },
-    "RIPEMD-160": {
-        description: "RIPEMD (RACE Integrity Primitives Evaluation Message Digest) is a family of cryptographic hash functions developed in Leuven, Belgium, by Hans Dobbertin, Antoon Bosselaers and Bart Preneel at the COSIC research group at the Katholieke Universiteit Leuven, and first published in 1996.<br><br>RIPEMD was based upon the design principles used in MD4, and is similar in performance to the more popular SHA-1.<br><br>RIPEMD-160 is an improved, 160-bit version of the original RIPEMD, and the most common version in the family.",
-        run: Hash.runRIPEMD160,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "HMAC": {
-        description: "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.",
-        run: Hash.runHMAC,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Password",
-                type: "binaryString",
-                value: ""
-            },
-            {
-                name: "Hashing function",
-                type: "option",
-                value: Hash.HMAC_FUNCTIONS
-            },
-        ]
-    },
-    "Fletcher-8 Checksum": {
-        description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.<br><br>The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.",
-        run: Checksum.runFletcher8,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Fletcher-16 Checksum": {
-        description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.<br><br>The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.",
-        run: Checksum.runFletcher16,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Fletcher-32 Checksum": {
-        description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.<br><br>The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.",
-        run: Checksum.runFletcher32,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Fletcher-64 Checksum": {
-        description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.<br><br>The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.",
-        run: Checksum.runFletcher64,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Adler-32 Checksum": {
-        description: "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).<br><br>Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.",
-        run: Checksum.runAdler32,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "CRC-32 Checksum": {
-        description: "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.<br><br>The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975.",
-        run: Checksum.runCRC32,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Generate all hashes": {
-        description: "Generates all available hashes and checksums for the input.",
-        run: Hash.runAll,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Entropy": {
-        description: "Calculates the Shannon entropy of the input data which gives an idea of its randomness. 8 is the maximum.",
-        run: Entropy.runEntropy,
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-            {
-                name: "Chunk size",
-                type: "number",
-                value: Entropy.CHUNK_SIZE
-            }
-        ]
-    },
-    "Frequency distribution": {
-        description: "Displays the distribution of bytes in the data as a graph.",
-        run: Entropy.runFreqDistrib,
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-            {
-                name: "Show 0%'s",
-                type: "boolean",
-                value: Entropy.FREQ_ZEROS
-            }
-        ]
-    },
-    "Numberwang": {
-        description: "Based on the popular gameshow by Mitchell and Webb.",
-        run: Numberwang.run,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse X.509 certificate": {
-        description: "X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). It is commonly involved with SSL/TLS security.<br><br>This operation displays the contents of a certificate in a human readable format, similar to the openssl command line tool.",
-        run: PublicKey.runParseX509,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Input format",
-                type: "option",
-                value: PublicKey.X509_INPUT_FORMAT
-            }
-        ]
-    },
-    "PEM to Hex": {
-        description: "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.",
-        run: PublicKey.runPemToHex,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Hex to PEM": {
-        description: "Converts a hexadecimal DER (Distinguished Encoding Rules) string into PEM (Privacy Enhanced Mail) format.",
-        run: PublicKey.runHexToPem,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Header string",
-                type: "string",
-                value: PublicKey.PEM_HEADER_STRING
-            }
-        ]
-    },
-    "Hex to Object Identifier": {
-        description: "Converts a hexadecimal string into an object identifier (OID).",
-        run: PublicKey.runHexToObjectIdentifier,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Object Identifier to Hex": {
-        description: "Converts an object identifier (OID) into a hexadecimal string.",
-        run: PublicKey.runObjectIdentifierToHex,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse ASN.1 hex string": {
-        description: "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.<br><br>This operation parses arbitrary ASN.1 data and presents the resulting tree.",
-        run: PublicKey.runParseAsn1HexString,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Starting index",
-                type: "number",
-                value: 0
-            },
-            {
-                name: "Truncate octet strings longer than",
-                type: "number",
-                value: PublicKey.ASN1_TRUNCATE_LENGTH
-            }
-        ]
-    },
-    "Detect File Type": {
-        description: "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.<br><br>Currently supports the following file types: 7z, amr, avi, bmp, bz2, class, cr2, crx, dex, dmg, doc, elf, eot, epub, exe, flac, flv, gif, gz, ico, iso, jpg, jxr, m4a, m4v, mid, mkv, mov, mp3, mp4, mpg, ogg, otf, pdf, png, ppt, ps, psd, rar, rtf, sqlite, swf, tar, tar.z, tif, ttf, utf8, vmdk, wav, webm, webp, wmv, woff, woff2, xls, xz, zip.",
-        run: FileType.runDetect,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Scan for Embedded Files": {
-        description: "Scans the data for potential embedded files by looking for magic bytes at all offsets. This operation is prone to false positives.<br><br>WARNING: Files over about 100KB in size will take a VERY long time to process.",
-        run: FileType.runScanForEmbeddedFiles,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Ignore common byte sequences",
-                type: "boolean",
-                value: FileType.IGNORE_COMMON_BYTE_SEQUENCES
-            }
-        ]
-    },
-    "Expand alphabet range": {
-        description: "Expand an alphabet range string into a list of the characters in that range.<br><br>e.g. <code>a-z</code> becomes <code>abcdefghijklmnopqrstuvwxyz</code>.",
-        run: SeqUtils.runExpandAlphRange,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "binaryString",
-                value: ""
-            }
-        ]
-    },
-    "Diff": {
-        description: "Compares two inputs (separated by the specified delimiter) and highlights the differences between them.",
-        run: StrUtils.runDiff,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Sample delimiter",
-                type: "binaryString",
-                value: StrUtils.DIFF_SAMPLE_DELIMITER
-            },
-            {
-                name: "Diff by",
-                type: "option",
-                value: StrUtils.DIFF_BY
-            },
-            {
-                name: "Show added",
-                type: "boolean",
-                value: true
-            },
-            {
-                name: "Show removed",
-                type: "boolean",
-                value: true
-            },
-            {
-                name: "Ignore whitespace (relevant for word and line)",
-                type: "boolean",
-                value: false
-            }
-        ]
-    },
-    "Parse UNIX file permissions": {
-        description: "Given a UNIX/Linux file permission string in octal or textual format, this operation explains which permissions are granted to which user groups.<br><br>Input should be in either octal (e.g. <code>755</code>) or textual (e.g. <code>drwxr-xr-x</code>) format.",
-        run: OS.runParseUnixPerms,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Swap endianness": {
-        description: "Switches the data from big-endian to little-endian or vice-versa. Data can be read in as hexadecimal or raw bytes. It will be returned in the same format as it is entered.",
-        run: Endian.runSwapEndianness,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Data format",
-                type: "option",
-                value: Endian.DATA_FORMAT
-            },
-            {
-                name: "Word length (bytes)",
-                type: "number",
-                value: Endian.WORD_LENGTH
-            },
-            {
-                name: "Pad incomplete words",
-                type: "boolean",
-                value: Endian.PAD_INCOMPLETE_WORDS
-            }
-        ]
-    },
-    "Syntax highlighter": {
-        description: "Adds syntax highlighting to a range of source code languages. Note that this will not indent the code. Use one of the 'Beautify' operations for that.",
-        run: Code.runSyntaxHighlight,
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Language/File extension",
-                type: "option",
-                value: Code.LANGUAGES
-            },
-            {
-                name: "Display line numbers",
-                type: "boolean",
-                value: Code.LINE_NUMS
-            }
-        ]
-    },
-    "Parse escaped string": {
-        description: "Replaces escaped characters with the bytes they represent.<br><br>e.g.<code>Hello\\nWorld</code> becomes <code>Hello<br>World</code>",
-        run: StrUtils.runParseEscapedString,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "TCP/IP Checksum": {
-        description: "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes.",
-        run: Checksum.runTCPIP,
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Parse colour code": {
-        description: "Converts a colour code in a standard format to other standard formats and displays the colour itself.<br><br><strong>Example inputs</strong><ul><li><code>#d9edf7</code></li><li><code>rgba(217,237,247,1)</code></li><li><code>hsla(200,65%,91%,1)</code></li><li><code>cmyk(0.12, 0.04, 0.00, 0.03)</code></li></ul>",
-        run: HTML.runParseColourCode,
-        inputType: "string",
-        outputType: "html",
-        args: []
-    },
-    "Generate UUID": {
-        description: "Generates an RFC 4122 version 4 compliant Universally Unique Identifier (UUID), also known as a Globally Unique Identifier (GUID).<br><br>A version 4 UUID relies on random numbers, in this case generated using <code>window.crypto</code> if available and falling back to <code>Math.random</code> if not.",
-        run: UUID.runGenerateV4,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Substitute": {
-        description: "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.<br><br>Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.<br><br>Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either <code>\\n</code> or <code>\\x0a</code>.<br><br>Byte ranges can be specified using a hyphen. For example, the sequence <code>0123456789</code> can be written as <code>0-9</code>.",
-        run: Cipher.runSubstitute,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Plaintext",
-                type: "binaryString",
-                value: Cipher.SUBS_PLAINTEXT
-            },
-            {
-                name: "Ciphertext",
-                type: "binaryString",
-                value: Cipher.SUBS_CIPHERTEXT
-            }
-        ]
-    },
-    "To Morse Code": {
-        description: "Translates alphanumeric characters into International Morse Code.<br><br>Ignores non-Morse characters.<br><br>e.g. <code>SOS</code> becomes <code>... --- ...</code>",
-        run: MorseCode.runTo,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Format options",
-                type: "option",
-                value: MorseCode.FORMAT_OPTIONS
-            },
-            {
-                name: "Letter delimiter",
-                type: "option",
-                value: MorseCode.LETTER_DELIM_OPTIONS
-            },
-            {
-                name: "Word delimiter",
-                type: "option",
-                value: MorseCode.WORD_DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Morse Code": {
-        description: "Translates Morse Code into (upper case) alphanumeric characters.",
-        run: MorseCode.runFrom,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Letter delimiter",
-                type: "option",
-                value: MorseCode.LETTER_DELIM_OPTIONS
-            },
-            {
-                name: "Word delimiter",
-                type: "option",
-                value: MorseCode.WORD_DELIM_OPTIONS
-            }
-        ]
-    },
-    "Tar": {
-        description: "Packs the input into a tarball.<br><br>No support for multiple files at this time.",
-        run: Compress.runTar,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Filename",
-                type: "string",
-                value: Compress.TAR_FILENAME
-            }
-        ]
-    },
-    "Untar": {
-        description: "Unpacks a tarball and displays it per file.",
-        run: Compress.runUntar,
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-        ]
-    },
-    "Head": {
-        description: [
-            "Like the UNIX head utility.",
-            "<br>",
-            "Gets the first n lines.",
-            "<br>",
-            "You can select all but the last n lines by entering a negative value for n.",
-            "<br>",
-            "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.",
-        ].join("\n"),
-        run: StrUtils.runHead,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: StrUtils.DELIMITER_OPTIONS
-            },
-            {
-                name: "Number",
-                type: "number",
-                value: 10,
-            },
-        ]
-    },
-    "Tail": {
-        description: [
-            "Like the UNIX tail utility.",
-            "<br>",
-            "Gets the last n lines.",
-            "<br>",
-            "Optionally you can select all lines after line n by entering a negative value for n.",
-            "<br>",
-            "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.",
-        ].join("\n"),
-        run: StrUtils.runTail,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: StrUtils.DELIMITER_OPTIONS
-            },
-            {
-                name: "Number",
-                type: "number",
-                value: 10,
-            },
-        ]
-    },
-    "To Snake case": {
-        description: [
-            "Converts the input string to snake case.",
-            "<br><br>",
-            "Snake case is all lower case with underscores as word boundaries.",
-            "<br><br>",
-            "e.g. this_is_snake_case",
-            "<br><br>",
-            "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.",
-        ].join("\n"),
-        run: Code.runToSnakeCase,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Attempt to be context aware",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "To Camel case": {
-        description: [
-            "Converts the input string to camel case.",
-            "<br><br>",
-            "Camel case is all lower case except letters after word boundaries which are uppercase.",
-            "<br><br>",
-            "e.g. thisIsCamelCase",
-            "<br><br>",
-            "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.",
-        ].join("\n"),
-        run: Code.runToCamelCase,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Attempt to be context aware",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "To Kebab case": {
-        description: [
-            "Converts the input string to kebab case.",
-            "<br><br>",
-            "Kebab case is all lower case with dashes as word boundaries.",
-            "<br><br>",
-            "e.g. this-is-kebab-case",
-            "<br><br>",
-            "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.",
-        ].join("\n"),
-        run: Code.runToKebabCase,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Attempt to be context aware",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "Extract EXIF": {
-        description: [
-            "Extracts EXIF data from an image.",
-            "<br><br>",
-            "EXIF data is metadata embedded in images (JPEG, JPG, TIFF) and audio files.",
-            "<br><br>",
-            "EXIF data from photos usually contains information about the image file itself as well as the device used to create it.",
-        ].join("\n"),
-        run: Image.runEXIF,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [],
-    },
-    "Render Image": {
-        description: "Displays the input as an image. Supports the following formats:<br><br><ul><li>jpg/jpeg</li><li>png</li><li>gif</li><li>webp</li><li>bmp</li><li>ico</li></ul>",
-        run: Image.runRenderImage,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Input format",
-                type: "option",
-                value: Image.INPUT_FORMAT
-            }
-        ]
-    },
-    "Hex Density chart": {
-        description: [].join("\n"),
-        run: Charts.runHexDensityChart,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Record delimiter",
-                type: "option",
-                value: Charts.RECORD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "Field delimiter",
-                type: "option",
-                value: Charts.FIELD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "Pack radius",
-                type: "number",
-                value: 25,
-            },
-            {
-                name: "Draw radius",
-                type: "number",
-                value: 15,
-            },
-            {
-                name: "Use column headers as labels",
-                type: "boolean",
-                value: true,
-            },
-            {
-                name: "X label",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Y label",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Draw hexagon edges",
-                type: "boolean",
-                value: false,
-            },
-            {
-                name: "Min colour value",
-                type: "string",
-                value: Charts.COLOURS.min,
-            },
-            {
-                name: "Max colour value",
-                type: "string",
-                value: Charts.COLOURS.max,
-            },
-            {
-                name: "Draw empty hexagons within data boundaries",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "Heatmap chart": {
-        description: [].join("\n"),
-        run: Charts.runHeatmapChart,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Record delimiter",
-                type: "option",
-                value: Charts.RECORD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "Field delimiter",
-                type: "option",
-                value: Charts.FIELD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "Number of vertical bins",
-                type: "number",
-                value: 25,
-            },
-            {
-                name: "Number of horizontal bins",
-                type: "number",
-                value: 25,
-            },
-            {
-                name: "Use column headers as labels",
-                type: "boolean",
-                value: true,
-            },
-            {
-                name: "X label",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Y label",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Draw bin edges",
-                type: "boolean",
-                value: false,
-            },
-            {
-                name: "Min colour value",
-                type: "string",
-                value: Charts.COLOURS.min,
-            },
-            {
-                name: "Max colour value",
-                type: "string",
-                value: Charts.COLOURS.max,
-            },
-        ]
-    },
-    "Scatter chart": {
-        description: [].join("\n"),
-        run: Charts.runScatterChart,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Record delimiter",
-                type: "option",
-                value: Charts.RECORD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "Field delimiter",
-                type: "option",
-                value: Charts.FIELD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "Use column headers as labels",
-                type: "boolean",
-                value: true,
-            },
-            {
-                name: "X label",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Y label",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Colour",
-                type: "string",
-                value: Charts.COLOURS.max,
-            },
-            {
-                name: "Point radius",
-                type: "number",
-                value: 10,
-            },
-            {
-                name: "Use colour from third column",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "Series chart": {
-        description: [].join("\n"),
-        run: Charts.runSeriesChart,
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Record delimiter",
-                type: "option",
-                value: Charts.RECORD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "Field delimiter",
-                type: "option",
-                value: Charts.FIELD_DELIMITER_OPTIONS,
-            },
-            {
-                name: "X label",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Point radius",
-                type: "number",
-                value: 1,
-            },
-            {
-                name: "Series colours",
-                type: "string",
-                value: "mediumseagreen, dodgerblue, tomato",
-            },
-        ]
-    },
-    "HTML to Text": {
-        description: [].join("\n"),
-        run: HTML.runHTMLToText,
-        inputType: "html",
-        outputType: "string",
-        args: [
-        ]
-    }
-};
-
-export default OperationConfig;

+ 150 - 0
src/core/config/scripts/generateConfig.mjs

@@ -0,0 +1,150 @@
+/**
+ * This script automatically generates OperationConfig.json, containing metadata
+ * for each operation in the src/core/operations directory.
+ * It also generates modules in the src/core/config/modules directory to separate
+ * out operations into logical collections.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/*eslint no-console: ["off"] */
+
+import path from "path";
+import fs  from "fs";
+import process from "process";
+import * as Ops from "../../operations/index";
+
+const dir = path.join(process.cwd() + "/src/core/config/");
+if (!fs.existsSync(dir)) {
+    console.log("\nCWD: " + process.cwd());
+    console.log("Error: generateConfig.mjs should be run from the project root");
+    console.log("Example> node --experimental-modules src/core/config/scripts/generateConfig.mjs");
+    process.exit(1);
+}
+
+
+const operationConfig = {},
+    modules = {};
+
+/**
+ * Generate operation config and module lists.
+ */
+for (const opObj in Ops) {
+    const op = new Ops[opObj]();
+
+    operationConfig[op.name] = {
+        module:      op.module,
+        description: op.description,
+        infoURL:     op.infoURL,
+        inputType:   op.inputType,
+        outputType:  op.presentType,
+        flowControl: op.flowControl,
+        manualBake:  op.manualBake,
+        args:        op.args
+    };
+
+    if (op.hasOwnProperty("patterns")) {
+        operationConfig[op.name].patterns = op.patterns;
+    }
+
+    if (!modules.hasOwnProperty(op.module))
+        modules[op.module] = {};
+    modules[op.module][op.name] = opObj;
+}
+
+
+/**
+ * Write OperationConfig.
+ */
+fs.writeFileSync(
+    path.join(dir, "OperationConfig.json"),
+    JSON.stringify(operationConfig, null, 4)
+);
+console.log("Written OperationConfig.json");
+
+
+/**
+ * Write modules.
+ */
+if (!fs.existsSync(path.join(dir, "modules/"))) {
+    fs.mkdirSync(path.join(dir, "modules/"));
+}
+
+for (const module in modules) {
+    let code = `/**
+* THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/scripts/generateConfig.mjs
+*
+* @author n1474335 [n1474335@gmail.com]
+* @copyright Crown Copyright ${new Date().getUTCFullYear()}
+* @license Apache-2.0
+*/
+`;
+
+    for (const opName in modules[module]) {
+        const objName = modules[module][opName];
+        code += `import ${objName} from "../../operations/${objName}";\n`;
+    }
+
+    code += `
+const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.${module} = {
+`;
+    for (const opName in modules[module]) {
+        const objName = modules[module][opName];
+        code += `    "${opName}": ${objName},\n`;
+    }
+
+    code += `};
+
+export default OpModules;
+`;
+    fs.writeFileSync(
+        path.join(dir, `modules/${module}.mjs`),
+        code
+    );
+    console.log(`Written ${module} module`);
+}
+
+
+/**
+ * Write OpModules wrapper.
+ */
+let opModulesCode = `/**
+* THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/scripts/generateConfig.mjs
+*
+* Imports all modules for builds which do not load modules separately.
+*
+* @author n1474335 [n1474335@gmail.com]
+* @copyright Crown Copyright ${new Date().getUTCFullYear()}
+* @license Apache-2.0
+*/
+`;
+
+for (const module in modules) {
+    opModulesCode += `import ${module}Module from "./${module}";\n`;
+}
+
+opModulesCode += `
+const OpModules = {};
+
+Object.assign(
+    OpModules,
+`;
+
+for (const module in modules) {
+    opModulesCode += `    ${module}Module,\n`;
+}
+
+opModulesCode += `);
+
+export default OpModules;
+`;
+
+fs.writeFileSync(
+    path.join(dir, "modules/OpModules.mjs"),
+    opModulesCode
+);
+console.log("Written OpModules.mjs");

+ 60 - 0
src/core/config/scripts/generateOpsIndex.mjs

@@ -0,0 +1,60 @@
+/**
+ * This script automatically generates src/core/operations/index.mjs, containing
+ * imports for all operations in src/core/operations.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/*eslint no-console: ["off"] */
+
+import path from "path";
+import fs  from "fs";
+import process from "process";
+
+const dir = path.join(process.cwd() + "/src/core/config/");
+if (!fs.existsSync(dir)) {
+    console.log("\nCWD: " + process.cwd());
+    console.log("Error: generateOpsIndex.mjs should be run from the project root");
+    console.log("Example> node --experimental-modules src/core/config/scripts/generateOpsIndex.mjs");
+    process.exit(1);
+}
+
+// Find all operation files
+const opObjs = [];
+fs.readdirSync(path.join(dir, "../operations")).forEach(file => {
+    if (!file.endsWith(".mjs") || file === "index.mjs") return;
+    opObjs.push(file.split(".mjs")[0]);
+});
+
+// Construct index file
+let code = `/**
+* THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/scripts/generateOpsIndex.mjs
+*
+* @author n1474335 [n1474335@gmail.com]
+* @copyright Crown Copyright ${new Date().getUTCFullYear()}
+* @license Apache-2.0
+*/
+`;
+
+opObjs.forEach(obj => {
+    code += `import ${obj} from "./${obj}";\n`;
+});
+
+code += `
+export {
+`;
+
+opObjs.forEach(obj => {
+    code += `    ${obj},\n`;
+});
+
+code += "};\n";
+
+// Write file
+fs.writeFileSync(
+    path.join(dir, "../operations/index.mjs"),
+    code
+);
+console.log("Written operation index.");

+ 230 - 0
src/core/config/scripts/newOperation.mjs

@@ -0,0 +1,230 @@
+/**
+ * Interactive script for generating a new operation template.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/*eslint no-console: ["off"] */
+
+import prompt from "prompt";
+import colors from "colors";
+import process from "process";
+import fs from "fs";
+import path from "path";
+import EscapeString from "../../operations/EscapeString";
+
+
+const dir = path.join(process.cwd() + "/src/core/operations/");
+if (!fs.existsSync(dir)) {
+    console.log("\nCWD: " + process.cwd());
+    console.log("Error: newOperation.mjs should be run from the project root");
+    console.log("Example> node --experimental-modules src/core/config/scripts/newOperation.mjs");
+    process.exit(1);
+}
+
+const ioTypes = ["string", "byteArray", "number", "html", "ArrayBuffer", "BigNumber", "JSON", "File", "List<File>"];
+
+const schema = {
+    properties: {
+        opName: {
+            description: "The operation name should be short but descriptive.",
+            example: "URL Decode",
+            prompt: "Operation name",
+            type: "string",
+            pattern: /^[\w\s-/().]+$/,
+            required: true,
+            message: "Operation names should consist of letters, numbers or the following symbols: _-/()."
+        },
+        module: {
+            description: `Modules are used to group operations that rely on large libraries. Any operation that is not in the Default module will be loaded in dynamically when it is first called. All operations in the same module will also be loaded at this time. This system prevents the CyberChef web app from getting too bloated and taking a long time to load initially.
+If your operation does not rely on a library, just leave this blank and it will be added to the Default module. If it relies on the same library as other operations, enter the name of the module those operations are in. If it relies on a new large library, enter a new module name (capitalise the first letter).`,
+            example: "Crypto",
+            prompt: "Module",
+            type: "string",
+            pattern: /^[A-Z][A-Za-z\d]+$/,
+            message: "Module names should start with a capital letter and not contain any spaces or symbols.",
+            default: "Default"
+        },
+        description: {
+            description: "The description should explain what the operation is and how it works. It can describe how the arguments should be entered and give examples of expected input and output. HTML markup is supported. Use <code> tags for examples. The description is scanned during searches, so include terms that are likely to be searched for when someone is looking for your operation.",
+            example: "Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
+            prompt: "Description",
+            type: "string"
+        },
+        infoURL: {
+            description: "An optional URL for an external site can be added to give more information about the operation. Wikipedia links are often suitable. If linking to Wikipedia, use an international link (e.g. https://wikipedia.org/...) rather than a localised link (e.g. https://en.wikipedia.org/...).",
+            example: "https://wikipedia.org/wiki/Percent-encoding",
+            prompt: "Information URL",
+            type: "string",
+        },
+        inputType: {
+            description: `The input type defines how the input data will be presented to your operation. Check the project wiki for a full description of each type. The options are: ${ioTypes.join(", ")}.`,
+            example: "string",
+            prompt: "Input type",
+            type: "string",
+            pattern: new RegExp(`^(${ioTypes.join("|")})$`),
+            required: true,
+            message: `The input type should be one of: ${ioTypes.join(", ")}.`
+        },
+        outputType: {
+            description: `The output type tells CyberChef what sort of data you are returning from your operation. Check the project wiki for a full description of each type. The options are: ${ioTypes.join(", ")}.`,
+            example: "string",
+            prompt: "Output type",
+            type: "string",
+            pattern: new RegExp(`^(${ioTypes.join("|")})$`),
+            required: true,
+            message: `The output type should be one of: ${ioTypes.join(", ")}.`
+        },
+        highlight: {
+            description: "If your operation does not change the length of the input in any way, we can enable highlighting. If it does change the length in a predictable way, we may still be able to enable highlighting and calculate the correct offsets. If this is not possible, we will disable highlighting for this operation.",
+            example: "true/false",
+            prompt: "Enable highlighting",
+            type: "boolean",
+            default: "false",
+            message: "Enter true or false to specify if highlighting should be enabled."
+        },
+        authorName: {
+            description: "Your name or username will be added to the @author tag for this operation.",
+            example: "n1474335",
+            prompt: "Username",
+            type: "string"
+        },
+        authorEmail: {
+            description: "Your email address will also be added to the @author tag for this operation.",
+            example: "n1474335@gmail.com",
+            prompt: "Email",
+            type: "string"
+        }
+    }
+};
+
+// Build schema
+for (const prop in schema.properties) {
+    const p = schema.properties[prop];
+    p.description = "\n" + colors.white(p.description) + colors.cyan("\nExample: " + p.example) + "\n" + colors.green(p.prompt);
+}
+
+console.log("\n\nThis script will generate a new operation template based on the information you provide. These values can be changed manually later.".yellow);
+
+prompt.message = "";
+prompt.delimiter = ":".green;
+
+prompt.start();
+
+prompt.get(schema, (err, result) => {
+    if (err) {
+        console.log("\nExiting build script.");
+        process.exit(0);
+    }
+
+    const moduleName = result.opName.replace(/\w\S*/g, txt => {
+        return txt.charAt(0).toUpperCase() + txt.substr(1);
+    }).replace(/[\s-()/./]/g, "");
+
+
+    const template = `/**
+ * @author ${result.authorName} [${result.authorEmail}]
+ * @copyright Crown Copyright ${(new Date()).getFullYear()}
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
+
+/**
+ * ${result.opName} operation
+ */
+class ${moduleName} extends Operation {
+
+    /**
+     * ${moduleName} constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "${result.opName}";
+        this.module = "${result.module}";
+        this.description = "${(new EscapeString).run(result.description, ["Special chars", "Double"])}";
+        this.infoURL = "${result.infoURL}";
+        this.inputType = "${result.inputType}";
+        this.outputType = "${result.outputType}";
+        this.args = [
+            /* Example arguments. See the project wiki for full details.
+            {
+                name: "First arg",
+                type: "string",
+                value: "Don't Panic"
+            },
+            {
+                name: "Second arg",
+                type: "number",
+                value: 42
+            }
+            */
+        ];
+    }
+
+    /**
+     * @param {${result.inputType}} input
+     * @param {Object[]} args
+     * @returns {${result.outputType}}
+     */
+    run(input, args) {
+        // const [firstArg, secondArg] = args;
+
+        throw new OperationError("Test");
+    }
+${result.highlight ? `
+    /**
+     * Highlight ${result.opName}
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight ${result.opName} in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+` : ""}
+}
+
+export default ${moduleName};
+`;
+
+    //console.log(template);
+
+    const filename = path.join(dir, `./${moduleName}.mjs`);
+    if (fs.existsSync(filename)) {
+        console.log(`${filename} already exists. It has NOT been overwritten.`.red);
+        console.log("Choose a different operation name to avoid conflicts.");
+        process.exit(0);
+    }
+    fs.writeFileSync(filename, template);
+
+    console.log(`\nOperation template written to ${colors.green(filename)}`);
+    console.log(`\nNext steps:
+1. Add your operation to ${colors.green("src/core/config/Categories.json")}
+2. Write your operation code.
+3. Write tests in ${colors.green("tests/operations/tests/")}
+4. Run ${colors.cyan("npm run lint")} and ${colors.cyan("npm run test")}
+5. Submit a Pull Request to get your operation added to the official CyberChef repository.`);
+
+});
+

+ 26 - 0
src/core/errors/DishError.mjs

@@ -0,0 +1,26 @@
+/**
+ * Custom error type for handling Dish type errors.
+ * i.e. where the Dish cannot be successfully translated between types
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+class DishError extends Error {
+    /**
+     * Standard error constructor. Adds no new behaviour.
+     *
+     * @param args - Standard error args
+     */
+    constructor(...args) {
+        super(...args);
+
+        this.type = "DishError";
+
+        if (Error.captureStackTrace) {
+            Error.captureStackTrace(this, DishError);
+        }
+    }
+}
+
+export default DishError;

+ 26 - 0
src/core/errors/OperationError.mjs

@@ -0,0 +1,26 @@
+/**
+ * Custom error type for handling operation input errors.
+ * i.e. where the operation can handle the error and print a message to the screen.
+ *
+ * @author d98762625 [d98762625@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+class OperationError extends Error {
+    /**
+     * Standard error constructor. Adds no new behaviour.
+     *
+     * @param args - Standard error args
+     */
+    constructor(...args) {
+        super(...args);
+
+        this.type = "OperationError";
+
+        if (Error.captureStackTrace) {
+            Error.captureStackTrace(this, OperationError);
+        }
+    }
+}
+
+export default OperationError;

+ 139 - 0
src/core/lib/Arithmetic.mjs

@@ -0,0 +1,139 @@
+/**
+ * @author bwhitn [brian.m.whitney@outlook.com]
+ * @author d98762625 [d98762625@gmailcom]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+import BigNumber from "bignumber.js";
+
+
+/**
+ * Converts a string array to a number array.
+ *
+ * @param {string[]} input
+ * @param {string} delim
+ * @returns {BigNumber[]}
+ */
+export function createNumArray(input, delim) {
+    delim = Utils.charRep(delim || "Space");
+    const splitNumbers = input.split(delim);
+    const numbers = [];
+    let num;
+
+    splitNumbers.map((number) => {
+        try {
+            num = BigNumber(number.trim());
+            if (!num.isNaN()) {
+                numbers.push(num);
+            }
+        } catch (err) {
+            // This line is not a valid number
+        }
+    });
+    return numbers;
+}
+
+
+/**
+ * Adds an array of numbers and returns the value.
+ *
+ * @param {BigNumber[]} data
+ * @returns {BigNumber}
+ */
+export function sum(data) {
+    if (data.length > 0) {
+        return data.reduce((acc, curr) => acc.plus(curr));
+    }
+}
+
+
+/**
+ * Subtracts an array of numbers and returns the value.
+ *
+ * @param {BigNumber[]} data
+ * @returns {BigNumber}
+ */
+export function sub(data) {
+    if (data.length > 0) {
+        return data.reduce((acc, curr) => acc.minus(curr));
+    }
+}
+
+
+/**
+ * Multiplies an array of numbers and returns the value.
+ *
+ * @param {BigNumber[]} data
+ * @returns {BigNumber}
+ */
+export function multi(data) {
+    if (data.length > 0) {
+        return data.reduce((acc, curr) => acc.times(curr));
+    }
+}
+
+
+/**
+ * Divides an array of numbers and returns the value.
+ *
+ * @param {BigNumber[]} data
+ * @returns {BigNumber}
+ */
+export function div(data) {
+    if (data.length > 0) {
+        return data.reduce((acc, curr) => acc.div(curr));
+    }
+}
+
+
+/**
+ * Computes mean of a number array and returns the value.
+ *
+ * @param {BigNumber[]} data
+ * @returns {BigNumber}
+ */
+export function mean(data) {
+    if (data.length > 0) {
+        return sum(data).div(data.length);
+    }
+}
+
+
+/**
+ * Computes median of a number array and returns the value.
+ *
+ * @param {BigNumber[]} data
+ * @returns {BigNumber}
+ */
+export function median(data) {
+    if ((data.length % 2) === 0 && data.length > 0) {
+        data.sort(function(a, b){
+            return a.minus(b);
+        });
+        const first = data[Math.floor(data.length / 2)];
+        const second = data[Math.floor(data.length / 2) - 1];
+        return mean([first, second]);
+    } else {
+        return data[Math.floor(data.length / 2)];
+    }
+}
+
+
+/**
+ * Computes standard deviation of a number array and returns the value.
+ *
+ * @param {BigNumber[]} data
+ * @returns {BigNumber}
+ */
+export function stdDev(data) {
+    if (data.length > 0) {
+        const avg = mean(data);
+        let devSum = new BigNumber(0);
+        data.map((datum) => {
+            devSum = devSum.plus(datum.minus(avg).pow(2));
+        });
+        return devSum.div(data.length).sqrt();
+    }
+}

+ 48 - 0
src/core/lib/BCD.mjs

@@ -0,0 +1,48 @@
+/**
+ * Binary Code Decimal resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+
+/**
+ * BCD encoding schemes.
+ */
+export const ENCODING_SCHEME = [
+    "8 4 2 1",
+    "7 4 2 1",
+    "4 2 2 1",
+    "2 4 2 1",
+    "8 4 -2 -1",
+    "Excess-3",
+    "IBM 8 4 2 1",
+];
+
+/**
+ * Lookup table for the binary value of each digit representation.
+ *
+ * I wrote a very nice algorithm to generate 8 4 2 1 encoding programatically,
+ * but unfortunately it's much easier (if less elegant) to use lookup tables
+ * when supporting multiple encoding schemes.
+ *
+ * "Practicality beats purity" - PEP 20
+ *
+ * In some schemes it is possible to represent the same value in multiple ways.
+ * For instance, in 4 2 2 1 encoding, 0100 and 0010 both represent 2. Support
+ * has not yet been added for this.
+ */
+export const ENCODING_LOOKUP = {
+    "8 4 2 1":     [0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
+    "7 4 2 1":     [0,  1,  2,  3,  4,  5,  6,  8,  9,  10],
+    "4 2 2 1":     [0,  1,  4,  5,  8,  9,  12, 13, 14, 15],
+    "2 4 2 1":     [0,  1,  2,  3,  4,  11, 12, 13, 14, 15],
+    "8 4 -2 -1":   [0,  7,  6,  5,  4,  11, 10, 9,  8,  15],
+    "Excess-3":    [3,  4,  5,  6,  7,  8,  9,  10, 11, 12],
+    "IBM 8 4 2 1": [10, 1,  2,  3,  4,  5,  6,  7,  8,  9],
+};
+
+/**
+ * BCD formats.
+ */
+export const FORMAT = ["Nibbles", "Bytes", "Raw"];

+ 22 - 0
src/core/lib/Base58.mjs

@@ -0,0 +1,22 @@
+/**
+ * Base58 resources.
+ *
+ * @author tlwr [toby@toby.codes]
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+
+/**
+ * Base58 alphabet options.
+ */
+export const ALPHABET_OPTIONS = [
+    {
+        name: "Bitcoin",
+        value: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
+    },
+    {
+        name: "Ripple",
+        value: "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
+    },
+];

+ 142 - 0
src/core/lib/Base64.mjs

@@ -0,0 +1,142 @@
+/**
+ * Base64 functions.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+
+
+/**
+ * Base64's the input byte array using the given alphabet, returning a string.
+ *
+ * @param {byteArray|Uint8Array|string} data
+ * @param {string} [alphabet="A-Za-z0-9+/="]
+ * @returns {string}
+ *
+ * @example
+ * // returns "SGVsbG8="
+ * toBase64([72, 101, 108, 108, 111]);
+ *
+ * // returns "SGVsbG8="
+ * toBase64("Hello");
+ */
+export function toBase64(data, alphabet="A-Za-z0-9+/=") {
+    if (!data) return "";
+    if (typeof data == "string") {
+        data = Utils.strToByteArray(data);
+    }
+
+    alphabet = Utils.expandAlphRange(alphabet).join("");
+
+    let output = "",
+        chr1, chr2, chr3,
+        enc1, enc2, enc3, enc4,
+        i = 0;
+
+    while (i < data.length) {
+        chr1 = data[i++];
+        chr2 = data[i++];
+        chr3 = data[i++];
+
+        enc1 = chr1 >> 2;
+        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+        enc4 = chr3 & 63;
+
+        if (isNaN(chr2)) {
+            enc3 = enc4 = 64;
+        } else if (isNaN(chr3)) {
+            enc4 = 64;
+        }
+
+        output += alphabet.charAt(enc1) + alphabet.charAt(enc2) +
+            alphabet.charAt(enc3) + alphabet.charAt(enc4);
+    }
+
+    return output;
+}
+
+
+/**
+ * UnBase64's the input string using the given alphabet, returning a byte array.
+ *
+ * @param {byteArray} data
+ * @param {string} [alphabet="A-Za-z0-9+/="]
+ * @param {string} [returnType="string"] - Either "string" or "byteArray"
+ * @param {boolean} [removeNonAlphChars=true]
+ * @returns {byteArray}
+ *
+ * @example
+ * // returns "Hello"
+ * fromBase64("SGVsbG8=");
+ *
+ * // returns [72, 101, 108, 108, 111]
+ * fromBase64("SGVsbG8=", null, "byteArray");
+ */
+export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", removeNonAlphChars=true) {
+    if (!data) {
+        return returnType === "string" ? "" : [];
+    }
+
+    alphabet = alphabet || "A-Za-z0-9+/=";
+    alphabet = Utils.expandAlphRange(alphabet).join("");
+
+    const output = [];
+    let chr1, chr2, chr3,
+        enc1, enc2, enc3, enc4,
+        i = 0;
+
+    if (removeNonAlphChars) {
+        const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
+        data = data.replace(re, "");
+    }
+
+    while (i < data.length) {
+        enc1 = alphabet.indexOf(data.charAt(i++));
+        enc2 = alphabet.indexOf(data.charAt(i++) || "=");
+        enc3 = alphabet.indexOf(data.charAt(i++) || "=");
+        enc4 = alphabet.indexOf(data.charAt(i++) || "=");
+
+        enc2 = enc2 === -1 ? 64 : enc2;
+        enc3 = enc3 === -1 ? 64 : enc3;
+        enc4 = enc4 === -1 ? 64 : enc4;
+
+        chr1 = (enc1 << 2) | (enc2 >> 4);
+        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+        chr3 = ((enc3 & 3) << 6) | enc4;
+
+        output.push(chr1);
+
+        if (enc3 !== 64) {
+            output.push(chr2);
+        }
+        if (enc4 !== 64) {
+            output.push(chr3);
+        }
+    }
+
+    return returnType === "string" ? Utils.byteArrayToUtf8(output) : output;
+}
+
+
+/**
+ * Base64 alphabets.
+ */
+export const ALPHABET_OPTIONS = [
+    {name: "Standard (RFC 4648): A-Za-z0-9+/=", value: "A-Za-z0-9+/="},
+    {name: "URL safe (RFC 4648 \u00A75): A-Za-z0-9-_", value: "A-Za-z0-9-_"},
+    {name: "Filename safe: A-Za-z0-9+-=", value: "A-Za-z0-9+\\-="},
+    {name: "itoa64: ./0-9A-Za-z=", value: "./0-9A-Za-z="},
+    {name: "XML: A-Za-z0-9_.", value: "A-Za-z0-9_."},
+    {name: "y64: A-Za-z0-9._-", value: "A-Za-z0-9._-"},
+    {name: "z64: 0-9a-zA-Z+/=", value: "0-9a-zA-Z+/="},
+    {name: "Radix-64 (RFC 4880): 0-9A-Za-z+/=", value: "0-9A-Za-z+/="},
+    {name: "Uuencoding: [space]-_", value: " -_"},
+    {name: "Xxencoding: +-0-9A-Za-z", value: "+\\-0-9A-Za-z"},
+    {name: "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r", value: "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"},
+    {name: "ROT13: N-ZA-Mn-za-m0-9+/=", value: "N-ZA-Mn-za-m0-9+/="},
+    {name: "UNIX crypt: ./0-9A-Za-z", value: "./0-9A-Za-z"},
+];

+ 45 - 0
src/core/lib/Base85.mjs

@@ -0,0 +1,45 @@
+/**
+ * Base85 resources.
+ *
+ * @author PenguinGeorge [george@penguingeorge.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/**
+ * Base85 alphabet options.
+ */
+export const ALPHABET_OPTIONS = [
+    {
+        name: "Standard",
+        value: "!-u",
+    },
+    {
+        name: "Z85 (ZeroMQ)",
+        value: "0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#",
+    },
+    {
+        name: "IPv6",
+        value: "0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|~}",
+    }
+];
+
+
+/**
+ * Returns the name of the alphabet, when given the alphabet.
+ *
+ * @param {string} alphabet
+ * @returns {string}
+ */
+export function alphabetName(alphabet) {
+    alphabet = alphabet.replace("'", "&apos;");
+    alphabet = alphabet.replace("\"", "&quot;");
+    alphabet = alphabet.replace("\\", "&bsol;");
+    let name;
+
+    ALPHABET_OPTIONS.forEach(function(a) {
+        if (escape(alphabet) === escape(a.value)) name = a.name;
+    });
+
+    return name;
+}

+ 70 - 0
src/core/lib/Binary.mjs

@@ -0,0 +1,70 @@
+/**
+ * Binary functions.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+
+
+/**
+ * Convert a byte array into a binary string.
+ *
+ * @param {Uint8Array|byteArray} data
+ * @param {string} [delim="Space"]
+ * @param {number} [padding=8]
+ * @returns {string}
+ *
+ * @example
+ * // returns "00010000 00100000 00110000"
+ * toBinary([10,20,30]);
+ *
+ * // returns "00010000 00100000 00110000"
+ * toBinary([10,20,30], ":");
+ */
+export function toBinary(data, delim="Space", padding=8) {
+    if (!data) return "";
+
+    delim = Utils.charRep(delim);
+    let output = "";
+
+    for (let i = 0; i < data.length; i++) {
+        output += data[i].toString(2).padStart(padding, "0") + delim;
+    }
+
+    if (delim.length) {
+        return output.slice(0, -delim.length);
+    } else {
+        return output;
+    }
+}
+
+
+/**
+ * Convert a binary string into a byte array.
+ *
+ * @param {string} data
+ * @param {string} [delim]
+ * @param {number} [byteLen=8]
+ * @returns {byteArray}
+ *
+ * @example
+ * // returns [10,20,30]
+ * fromBinary("00010000 00100000 00110000");
+ *
+ * // returns [10,20,30]
+ * fromBinary("00010000:00100000:00110000", "Colon");
+ */
+export function fromBinary(data, delim="Space", byteLen=8) {
+    const delimRegex = Utils.regexRep(delim);
+    data = data.replace(delimRegex, "");
+
+    const output = [];
+    for (let i = 0; i < data.length; i += byteLen) {
+        output.push(parseInt(data.substr(i, byteLen), 2));
+    }
+    return output;
+}
+

+ 124 - 0
src/core/lib/BitwiseOp.mjs

@@ -0,0 +1,124 @@
+/**
+ * Bitwise operation resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/**
+ * Runs bitwise operations across the input data.
+ *
+ * @param {byteArray} input
+ * @param {byteArray} key
+ * @param {function} func - The bitwise calculation to carry out
+ * @param {boolean} nullPreserving
+ * @param {string} scheme
+ * @returns {byteArray}
+ */
+export function bitOp (input, key, func, nullPreserving, scheme) {
+    if (!key || !key.length) key = [0];
+    const result = [];
+    let x = null,
+        k = null,
+        o = null;
+
+    for (let i = 0; i < input.length; i++) {
+        k = key[i % key.length];
+        if (scheme === "Cascade") k = input[i + 1] || 0;
+        o = input[i];
+        x = nullPreserving && (o === 0 || o === k) ? o : func(o, k);
+        result.push(x);
+        if (scheme &&
+            scheme !== "Standard" &&
+            !(nullPreserving && (o === 0 || o === k))) {
+            switch (scheme) {
+                case "Input differential":
+                    key[i % key.length] = x;
+                    break;
+                case "Output differential":
+                    key[i % key.length] = o;
+                    break;
+            }
+        }
+    }
+
+    return result;
+}
+
+/**
+ * XOR bitwise calculation.
+ *
+ * @param {number} operand
+ * @param {number} key
+ * @returns {number}
+ */
+export function xor(operand, key) {
+    return operand ^ key;
+}
+
+
+/**
+ * NOT bitwise calculation.
+ *
+ * @param {number} operand
+ * @returns {number}
+ */
+export function not(operand, _) {
+    return ~operand & 0xff;
+}
+
+
+/**
+ * AND bitwise calculation.
+ *
+ * @param {number} operand
+ * @param {number} key
+ * @returns {number}
+ */
+export function and(operand, key) {
+    return operand & key;
+}
+
+
+/**
+ * OR bitwise calculation.
+ *
+ * @param {number} operand
+ * @param {number} key
+ * @returns {number}
+ */
+export function or(operand, key) {
+    return operand | key;
+}
+
+
+/**
+ * ADD bitwise calculation.
+ *
+ * @param {number} operand
+ * @param {number} key
+ * @returns {number}
+ */
+export function add(operand, key) {
+    return (operand + key) % 256;
+}
+
+
+/**
+ * SUB bitwise calculation.
+ *
+ * @param {number} operand
+ * @param {number} key
+ * @returns {number}
+ */
+export function sub(operand, key) {
+    const result = operand - key;
+    return (result < 0) ? 256 + result : result;
+}
+
+
+/**
+ * Delimiter options for bitwise operations
+ */
+export const BITWISE_OP_DELIMS = ["Hex", "Decimal", "Binary", "Base64", "UTF8", "Latin1"];

+ 15 - 0
src/core/lib/Braille.mjs

@@ -0,0 +1,15 @@
+/**
+ * Braille resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/**
+ * Braille lookup table.
+ */
+export const BRAILLE_LOOKUP = {
+    ascii: " A1B'K2L@CIF/MSP\"E3H9O6R^DJG>NTQ,*5<-U8V.%[$+X!&;:4\\0Z7(_?W]#Y)=",
+    dot6:  "⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿"
+};

+ 204 - 0
src/core/lib/CanvasComponents.mjs

@@ -0,0 +1,204 @@
+/**
+ * Various components for drawing diagrams on an HTML5 canvas.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+/**
+ * Draws a line from one point to another
+ *
+ * @param ctx
+ * @param startX
+ * @param startY
+ * @param endX
+ * @param endY
+ */
+export function drawLine(ctx, startX, startY, endX, endY) {
+    ctx.beginPath();
+    ctx.moveTo(startX, startY);
+    ctx.lineTo(endX, endY);
+    ctx.closePath();
+    ctx.stroke();
+}
+
+/**
+ * Draws a bar chart on the canvas.
+ *
+ * @param canvas
+ * @param scores
+ * @param xAxisLabel
+ * @param yAxisLabel
+ * @param numXLabels
+ * @param numYLabels
+ * @param fontSize
+ */
+export function drawBarChart(canvas, scores, xAxisLabel, yAxisLabel, numXLabels, numYLabels, fontSize) {
+    fontSize = fontSize || 15;
+    if (!numXLabels || numXLabels > Math.round(canvas.width / 50)) {
+        numXLabels = Math.round(canvas.width / 50);
+    }
+    if (!numYLabels || numYLabels > Math.round(canvas.width / 50)) {
+        numYLabels = Math.round(canvas.height / 50);
+    }
+
+    // Graph properties
+    const ctx = canvas.getContext("2d"),
+        leftPadding = canvas.width * 0.08,
+        rightPadding = canvas.width * 0.03,
+        topPadding = canvas.height * 0.08,
+        bottomPadding = canvas.height * 0.2,
+        graphHeight = canvas.height - topPadding - bottomPadding,
+        graphWidth = canvas.width - leftPadding - rightPadding,
+        base = topPadding + graphHeight,
+        ceil = topPadding;
+
+    ctx.font = fontSize + "px Arial";
+
+    // Draw axis
+    ctx.lineWidth = "1.0";
+    ctx.strokeStyle = "#444";
+    drawLine(ctx, leftPadding, base, graphWidth + leftPadding, base); // x
+    drawLine(ctx, leftPadding, base, leftPadding, ceil); // y
+
+    // Bar properties
+    const barPadding = graphWidth * 0.003,
+        barWidth = (graphWidth - (barPadding * scores.length)) / scores.length,
+        max = Math.max.apply(Math, scores);
+    let currX = leftPadding + barPadding;
+
+    // Draw bars
+    ctx.fillStyle = "green";
+    for (let i = 0; i < scores.length; i++) {
+        const h = scores[i] / max * graphHeight;
+        ctx.fillRect(currX, base - h, barWidth, h);
+        currX += barWidth + barPadding;
+    }
+
+    // Mark x axis
+    ctx.fillStyle = "black";
+    ctx.textAlign = "center";
+    currX = leftPadding + barPadding;
+    if (numXLabels >= scores.length) {
+        // Mark every score
+        for (let i = 0; i <= scores.length; i++) {
+            ctx.fillText(i, currX, base + (bottomPadding * 0.3));
+            currX += barWidth + barPadding;
+        }
+    } else {
+        // Mark some scores
+        for (let i = 0; i <= numXLabels; i++) {
+            const val = Math.ceil((scores.length / numXLabels) * i);
+            currX = (graphWidth / numXLabels) * i + leftPadding;
+            ctx.fillText(val, currX, base + (bottomPadding * 0.3));
+        }
+    }
+
+    // Mark y axis
+    ctx.textAlign = "right";
+    let currY;
+    if (numYLabels >= max) {
+        // Mark every increment
+        for (let i = 0; i <= max; i++) {
+            currY = base - (i / max * graphHeight) + fontSize / 3;
+            ctx.fillText(i, leftPadding * 0.8, currY);
+        }
+    } else {
+        // Mark some increments
+        for (let i = 0; i <= numYLabels; i++) {
+            const val = Math.ceil((max / numYLabels) * i);
+            currY = base - (val / max * graphHeight) + fontSize / 3;
+            ctx.fillText(val, leftPadding * 0.8, currY);
+        }
+    }
+
+    // Label x axis
+    if (xAxisLabel) {
+        ctx.textAlign = "center";
+        ctx.fillText(xAxisLabel, graphWidth / 2 + leftPadding, base + bottomPadding * 0.8);
+    }
+
+    // Label y axis
+    if (yAxisLabel) {
+        ctx.save();
+        const x = leftPadding * 0.3,
+            y = graphHeight / 2 + topPadding;
+        ctx.translate(x, y);
+        ctx.rotate(-Math.PI / 2);
+        ctx.textAlign = "center";
+        ctx.fillText(yAxisLabel, 0, 0);
+        ctx.restore();
+    }
+}
+
+/**
+ * Draws a scale bar on the canvas.
+ *
+ * @param canvas
+ * @param score
+ * @param max
+ * @param markings
+ */
+export function drawScaleBar(canvas, score, max, markings) {
+    // Bar properties
+    const ctx = canvas.getContext("2d"),
+        leftPadding = canvas.width * 0.01,
+        rightPadding = canvas.width * 0.01,
+        topPadding = canvas.height * 0.1,
+        bottomPadding = canvas.height * 0.35,
+        barHeight = canvas.height - topPadding - bottomPadding,
+        barWidth = canvas.width - leftPadding - rightPadding;
+
+    // Scale properties
+    const proportion = score / max;
+
+    // Draw bar outline
+    ctx.strokeRect(leftPadding, topPadding, barWidth, barHeight);
+
+    // Shade in up to proportion
+    const grad = ctx.createLinearGradient(leftPadding, 0, barWidth + leftPadding, 0);
+    grad.addColorStop(0, "green");
+    grad.addColorStop(0.5, "gold");
+    grad.addColorStop(1, "red");
+    ctx.fillStyle = grad;
+    ctx.fillRect(leftPadding, topPadding, barWidth * proportion, barHeight);
+
+    // Add markings
+    let x0, y0, x1, y1;
+    ctx.fillStyle = "black";
+    ctx.textAlign = "center";
+    ctx.font = "13px Arial";
+    for (let i = 0; i < markings.length; i++) {
+        // Draw min line down
+        x0 = barWidth / max * markings[i].min + leftPadding;
+        y0 = topPadding + barHeight + (bottomPadding * 0.1);
+        x1 = x0;
+        y1 = topPadding + barHeight + (bottomPadding * 0.3);
+        drawLine(ctx, x0, y0, x1, y1);
+
+        // Draw max line down
+        x0 = barWidth / max * markings[i].max + leftPadding;
+        x1 = x0;
+        drawLine(ctx, x0, y0, x1, y1);
+
+        // Join min and max lines
+        x0 = barWidth / max * markings[i].min + leftPadding;
+        y0 = topPadding + barHeight + (bottomPadding * 0.3);
+        x1 = barWidth / max * markings[i].max + leftPadding;
+        y1 = y0;
+        drawLine(ctx, x0, y0, x1, y1);
+
+        // Add label
+        if (markings[i].max >= max * 0.9) {
+            ctx.textAlign = "right";
+            x0 = x1;
+        } else if (markings[i].max <= max * 0.1) {
+            ctx.textAlign = "left";
+        } else {
+            x0 = x0 + (x1 - x0) / 2;
+        }
+        y0 = topPadding + barHeight + (bottomPadding * 0.8);
+        ctx.fillText(markings[i].label, x0, y0);
+    }
+}

+ 58 - 0
src/core/lib/ChrEnc.mjs

@@ -0,0 +1,58 @@
+/**
+ * Character encoding resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+/**
+ * Character encoding format mappings.
+ */
+export const IO_FORMAT = {
+    "UTF-8 (65001)": 65001,
+    "UTF-7 (65000)": 65000,
+    "UTF16LE (1200)": 1200,
+    "UTF16BE (1201)": 1201,
+    "UTF16 (1201)": 1201,
+    "IBM EBCDIC International (500)": 500,
+    "IBM EBCDIC US-Canada (37)": 37,
+    "Windows-874 Thai (874)": 874,
+    "Japanese Shift-JIS (932)": 932,
+    "Simplified Chinese GBK (936)": 936,
+    "Korean (949)": 949,
+    "Traditional Chinese Big5 (950)": 950,
+    "Windows-1250 Central European (1250)": 1250,
+    "Windows-1251 Cyrillic (1251)": 1251,
+    "Windows-1252 Latin (1252)": 1252,
+    "Windows-1253 Greek (1253)": 1253,
+    "Windows-1254 Turkish (1254)": 1254,
+    "Windows-1255 Hebrew (1255)": 1255,
+    "Windows-1256 Arabic (1256)": 1256,
+    "Windows-1257 Baltic (1257)": 1257,
+    "Windows-1258 Vietnam (1258)": 1258,
+    "US-ASCII (20127)": 20127,
+    "Simplified Chinese GB2312 (20936)": 20936,
+    "KOI8-R Russian Cyrillic (20866)": 20866,
+    "KOI8-U Ukrainian Cyrillic (21866)": 21866,
+    "ISO-8859-1 Latin 1 Western European (28591)": 28591,
+    "ISO-8859-2 Latin 2 Central European (28592)": 28592,
+    "ISO-8859-3 Latin 3 South European (28593)": 28593,
+    "ISO-8859-4 Latin 4 North European (28594)": 28594,
+    "ISO-8859-5 Latin/Cyrillic (28595)": 28595,
+    "ISO-8859-6 Latin/Arabic (28596)": 28596,
+    "ISO-8859-7 Latin/Greek (28597)": 28597,
+    "ISO-8859-8 Latin/Hebrew (28598)": 28598,
+    "ISO-8859-9 Latin 5 Turkish (28599)": 28599,
+    "ISO-8859-10 Latin 6 Nordic (28600)": 28600,
+    "ISO-8859-11 Latin/Thai (28601)": 28601,
+    "ISO-8859-13 Latin 7 Baltic Rim (28603)": 28603,
+    "ISO-8859-14 Latin 8 Celtic (28604)": 28604,
+    "ISO-8859-15 Latin 9 (28605)": 28605,
+    "ISO-8859-16 Latin 10 (28606)": 28606,
+    "ISO-2022 JIS Japanese (50222)": 50222,
+    "EUC Japanese (51932)": 51932,
+    "EUC Korean (51949)": 51949,
+    "Simplified Chinese GB18030 (54936)": 54936,
+};
+

+ 82 - 0
src/core/lib/Ciphers.mjs

@@ -0,0 +1,82 @@
+/**
+ * Cipher functions.
+ *
+ * @author Matt C [matt@artemisbot.uk]
+ * @author n1474335 [n1474335@gmail.com]
+ *
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ *
+ */
+
+import OperationError from "../errors/OperationError";
+import CryptoJS from "crypto-js";
+
+/**
+ * Affine Cipher Encode operation.
+ *
+ * @author Matt C [matt@artemisbot.uk]
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+export function affineEncode(input, args) {
+    const alphabet = "abcdefghijklmnopqrstuvwxyz",
+        a = args[0],
+        b = args[1];
+    let output = "";
+
+    if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) {
+        throw new OperationError("The values of a and b can only be integers.");
+    }
+
+    for (let i = 0; i < input.length; i++) {
+        if (alphabet.indexOf(input[i]) >= 0) {
+            // Uses the affine function ax+b % m = y (where m is length of the alphabet)
+            output += alphabet[((a * alphabet.indexOf(input[i])) + b) % 26];
+        } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
+            // Same as above, accounting for uppercase
+            output += alphabet[((a * alphabet.indexOf(input[i].toLowerCase())) + b) % 26].toUpperCase();
+        } else {
+            // Non-alphabetic characters
+            output += input[i];
+        }
+    }
+    return output;
+}
+
+/**
+ * Generates a polybius square for the given keyword
+ *
+ * @private
+ * @author Matt C [matt@artemisbot.uk]
+ * @param {string} keyword - Must be upper case
+ * @returns {string}
+ */
+export function genPolybiusSquare (keyword) {
+    const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
+        polArray = `${keyword}${alpha}`.split("").unique(),
+        polybius = [];
+
+    for (let i = 0; i < 5; i++) {
+        polybius[i] = polArray.slice(i*5, i*5 + 5);
+    }
+
+    return polybius;
+}
+
+/**
+ * A mapping of string formats to their classes in the CryptoJS library.
+ *
+ * @private
+ * @constant
+ */
+export const format = {
+    "Hex":     CryptoJS.enc.Hex,
+    "Base64":  CryptoJS.enc.Base64,
+    "UTF8":    CryptoJS.enc.Utf8,
+    "UTF16":   CryptoJS.enc.Utf16,
+    "UTF16LE": CryptoJS.enc.Utf16LE,
+    "UTF16BE": CryptoJS.enc.Utf16BE,
+    "Latin1":  CryptoJS.enc.Latin1,
+};

+ 29 - 0
src/core/lib/Code.mjs

@@ -0,0 +1,29 @@
+/**
+ * Code resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/**
+ * This tries to rename variable names in a code snippet according to a function.
+ *
+ * @param {string} input
+ * @param {function} replacer - This function will be fed the token which should be renamed.
+ * @returns {string}
+ */
+export function replaceVariableNames(input, replacer) {
+    const tokenRegex = /\\"|"(?:\\"|[^"])*"|(\b[a-z0-9\-_]+\b)/ig;
+
+    return input.replace(tokenRegex, (...args) => {
+        const match = args[0],
+            quotes = args[1];
+
+        if (!quotes) {
+            return match;
+        } else {
+            return replacer(match);
+        }
+    });
+}

+ 655 - 0
src/core/lib/ConvertCoordinates.mjs

@@ -0,0 +1,655 @@
+/**
+ * Co-ordinate conversion resources.
+ *
+ * @author j433866 [j433866@gmail.com]
+ * @copyright Crown Copyright 2019
+ * @license Apache-2.0
+ */
+
+import geohash from "ngeohash";
+import geodesy from "geodesy";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Co-ordinate formats
+ */
+export const FORMATS = [
+    "Degrees Minutes Seconds",
+    "Degrees Decimal Minutes",
+    "Decimal Degrees",
+    "Geohash",
+    "Military Grid Reference System",
+    "Ordnance Survey National Grid",
+    "Universal Transverse Mercator"
+];
+
+/**
+ * Formats that should be passed to the conversion module as-is
+ */
+const NO_CHANGE = [
+    "Geohash",
+    "Military Grid Reference System",
+    "Ordnance Survey National Grid",
+    "Universal Transverse Mercator",
+];
+
+/**
+ * Convert a given latitude and longitude into a different format.
+ *
+ * @param {string} input - Input string to be converted
+ * @param {string} inFormat - Format of the input coordinates
+ * @param {string} inDelim - The delimiter splitting the lat/long of the input
+ * @param {string} outFormat - Format to convert to
+ * @param {string} outDelim - The delimiter to separate the output with
+ * @param {string} includeDir - Whether or not to include the compass direction in the output
+ * @param {number} precision - Precision of the result
+ * @returns {string} A formatted string of the converted co-ordinates
+ */
+export function convertCoordinates (input, inFormat, inDelim, outFormat, outDelim, includeDir, precision) {
+    let isPair = false,
+        split,
+        latlon,
+        convLat,
+        convLon,
+        conv,
+        hash,
+        utm,
+        mgrs,
+        osng,
+        splitLat,
+        splitLong,
+        lat,
+        lon;
+
+    // Can't have a precision less than 0!
+    if (precision < 0) {
+        precision = 0;
+    }
+
+    if (inDelim === "Auto") {
+        // Try to detect a delimiter in the input.
+        inDelim = findDelim(input);
+        if (inDelim === null) {
+            throw new OperationError("Unable to detect the input delimiter automatically.");
+        }
+    } else if (!inDelim.includes("Direction")) {
+        // Convert the delimiter argument value to the actual character
+        inDelim = realDelim(inDelim);
+    }
+
+    if (inFormat === "Auto") {
+        // Try to detect the format of the input data
+        inFormat = findFormat(input, inDelim);
+        if (inFormat === null) {
+            throw new OperationError("Unable to detect the input format automatically.");
+        }
+    }
+
+    // Convert the output delimiter argument to the real character
+    outDelim = realDelim(outDelim);
+
+    if (!NO_CHANGE.includes(inFormat)) {
+        if (inDelim.includes("Direction")) {
+            // Split on directions
+            split = input.split(/[NnEeSsWw]/g);
+            if (split[0] === "") {
+                // Remove first element if direction preceding
+                split = split.slice(1);
+            }
+        } else {
+            split = input.split(inDelim);
+        }
+        // Replace any co-ordinate symbols with spaces so we can split on them later
+        for (let i = 0; i < split.length; i++) {
+            split[i] = split[i].replace(/[°˝´'"]/g, " ");
+        }
+        if (split.length > 1) {
+            isPair = true;
+        }
+    } else {
+        // Remove any delimiters from the input
+        input = input.replace(inDelim, "");
+        isPair = true;
+    }
+
+    // Conversions from the input format into a geodesy latlon object
+    switch (inFormat) {
+        case "Geohash":
+            hash = geohash.decode(input.replace(/[^A-Za-z0-9]/g, ""));
+            latlon = new geodesy.LatLonEllipsoidal(hash.latitude, hash.longitude);
+            break;
+        case "Military Grid Reference System":
+            utm = geodesy.Mgrs.parse(input.replace(/[^A-Za-z0-9]/g, "")).toUtm();
+            latlon = utm.toLatLonE();
+            break;
+        case "Ordnance Survey National Grid":
+            osng = geodesy.OsGridRef.parse(input.replace(/[^A-Za-z0-9]/g, ""));
+            latlon = geodesy.OsGridRef.osGridToLatLon(osng);
+            break;
+        case "Universal Transverse Mercator":
+            // Geodesy needs a space between the first 2 digits and the next letter
+            if (/^[\d]{2}[A-Za-z]/.test(input)) {
+                input = input.slice(0, 2) + " " + input.slice(2);
+            }
+            utm = geodesy.Utm.parse(input);
+            latlon = utm.toLatLonE();
+            break;
+        case "Degrees Minutes Seconds":
+            if (isPair) {
+                // Split up the lat/long into degrees / minutes / seconds values
+                splitLat = splitInput(split[0]);
+                splitLong = splitInput(split[1]);
+
+                if (splitLat.length >= 3 && splitLong.length >= 3) {
+                    lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2], 10);
+                    lon = convDMSToDD(splitLong[0], splitLong[1], splitLong[2], 10);
+                    latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lon.degrees);
+                } else {
+                    throw new OperationError("Invalid co-ordinate format for Degrees Minutes Seconds");
+                }
+            } else {
+                // Not a pair, so only try to convert one set of co-ordinates
+                splitLat = splitInput(split[0]);
+                if (splitLat.length >= 3) {
+                    lat = convDMSToDD(splitLat[0], splitLat[1], splitLat[2]);
+                    latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lat.degrees);
+                } else {
+                    throw new OperationError("Invalid co-ordinate format for Degrees Minutes Seconds");
+                }
+            }
+            break;
+        case "Degrees Decimal Minutes":
+            if (isPair) {
+                splitLat = splitInput(split[0]);
+                splitLong = splitInput(split[1]);
+                if (splitLat.length !== 2 || splitLong.length !== 2) {
+                    throw new OperationError("Invalid co-ordinate format for Degrees Decimal Minutes.");
+                }
+                // Convert to decimal degrees, and then convert to a geodesy object
+                lat = convDDMToDD(splitLat[0], splitLat[1], 10);
+                lon = convDDMToDD(splitLong[0], splitLong[1], 10);
+                latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lon.degrees);
+            } else {
+                // Not a pair, so only try to convert one set of co-ordinates
+                splitLat = splitInput(input);
+                if (splitLat.length !== 2) {
+                    throw new OperationError("Invalid co-ordinate format for Degrees Decimal Minutes.");
+                }
+                lat = convDDMToDD(splitLat[0], splitLat[1], 10);
+                latlon = new geodesy.LatLonEllipsoidal(lat.degrees, lat.degrees);
+            }
+            break;
+        case "Decimal Degrees":
+            if (isPair) {
+                splitLat =  splitInput(split[0]);
+                splitLong = splitInput(split[1]);
+                if (splitLat.length !== 1 || splitLong.length !== 1) {
+                    throw new OperationError("Invalid co-ordinate format for Decimal Degrees.");
+                }
+                latlon = new geodesy.LatLonEllipsoidal(splitLat[0], splitLong[0]);
+            } else {
+                // Not a pair, so only try to convert one set of co-ordinates
+                splitLat = splitInput(split[0]);
+                if (splitLat.length !== 1) {
+                    throw new OperationError("Invalid co-ordinate format for Decimal Degrees.");
+                }
+                latlon = new geodesy.LatLonEllipsoidal(splitLat[0], splitLat[0]);
+            }
+            break;
+        default:
+            throw new OperationError(`Unknown input format '${inFormat}'`);
+    }
+
+    // Everything is now a geodesy latlon object
+    // These store the latitude and longitude as decimal
+    if (inFormat.includes("Degrees")) {
+        // If the input string contains directions, we need to check if they're S or W.
+        // If either of the directions are, we should make the decimal value negative
+        const dirs = input.toUpperCase().match(/[NESW]/g);
+        if (dirs && dirs.length >= 1) {
+            // Make positive lat/lon values with S/W directions into negative values
+            if (dirs[0] === "S" || dirs[0] === "W" && latlon.lat > 0) {
+                latlon.lat = -latlon.lat;
+            }
+            if (dirs.length >= 2) {
+                if (dirs[1] === "S" || dirs[1] === "W" && latlon.lon > 0) {
+                    latlon.lon = -latlon.lon;
+                }
+            }
+        }
+    }
+
+    // Try to find the compass directions of the lat and long
+    const [latDir, longDir] = findDirs(latlon.lat + "," + latlon.lon, ",");
+
+    // Output conversions for each output format
+    switch (outFormat) {
+        case "Decimal Degrees":
+            // We could use the built in latlon.toString(),
+            // but this makes adjusting the output harder
+            lat = convDDToDD(latlon.lat, precision);
+            lon = convDDToDD(latlon.lon, precision);
+            convLat = lat.string;
+            convLon = lon.string;
+            break;
+        case "Degrees Decimal Minutes":
+            lat = convDDToDDM(latlon.lat, precision);
+            lon = convDDToDDM(latlon.lon, precision);
+            convLat = lat.string;
+            convLon = lon.string;
+            break;
+        case "Degrees Minutes Seconds":
+            lat = convDDToDMS(latlon.lat, precision);
+            lon = convDDToDMS(latlon.lon, precision);
+            convLat = lat.string;
+            convLon = lon.string;
+            break;
+        case "Geohash":
+            convLat = geohash.encode(latlon.lat, latlon.lon, precision);
+            break;
+        case "Military Grid Reference System":
+            utm = latlon.toUtm();
+            mgrs = utm.toMgrs();
+            // MGRS wants a precision that's an even number between 2 and 10
+            if (precision % 2 !== 0) {
+                precision = precision + 1;
+            }
+            if (precision > 10) {
+                precision = 10;
+            }
+            convLat = mgrs.toString(precision);
+            break;
+        case "Ordnance Survey National Grid":
+            osng = geodesy.OsGridRef.latLonToOsGrid(latlon);
+            if (osng.toString() === "") {
+                throw new OperationError("Could not convert co-ordinates to OS National Grid. Are the co-ordinates in range?");
+            }
+            // OSNG wants a precision that's an even number between 2 and 10
+            if (precision % 2 !== 0) {
+                precision = precision + 1;
+            }
+            if (precision > 10) {
+                precision = 10;
+            }
+            convLat = osng.toString(precision);
+            break;
+        case "Universal Transverse Mercator":
+            utm = latlon.toUtm();
+            convLat = utm.toString(precision);
+            break;
+    }
+
+    if (convLat === undefined) {
+        throw new OperationError("Error converting co-ordinates.");
+    }
+
+    if (outFormat.includes("Degrees")) {
+        // Format DD/DDM/DMS for output
+        // If we're outputting a compass direction, remove the negative sign
+        if (latDir === "S" && includeDir !== "None") {
+            convLat = convLat.replace("-", "");
+        }
+        if (longDir === "W" && includeDir !== "None") {
+            convLon = convLon.replace("-", "");
+        }
+
+        let outConv = "";
+        if (includeDir === "Before") {
+            outConv += latDir + " ";
+        }
+
+        outConv += convLat;
+        if (includeDir === "After") {
+            outConv += " " + latDir;
+        }
+        outConv += outDelim;
+        if (isPair) {
+            if (includeDir === "Before") {
+                outConv += longDir + " ";
+            }
+            outConv += convLon;
+            if (includeDir === "After") {
+                outConv += " " + longDir;
+            }
+            outConv += outDelim;
+        }
+        conv = outConv;
+    } else {
+        conv = convLat + outDelim;
+    }
+
+    return conv;
+}
+
+/**
+ * Split up the input using a space or degrees signs, and sanitise the result
+ *
+ * @param {string} input - The input data to be split
+ * @returns {number[]} An array of the different items in the string, stored as floats
+ */
+function splitInput (input){
+    const split = [];
+
+    input.split(/\s+/).forEach(item => {
+        // Remove any character that isn't a digit, decimal point or negative sign
+        item = item.replace(/[^0-9.-]/g, "");
+        if (item.length > 0){
+            // Turn the item into a float
+            split.push(parseFloat(item));
+        }
+    });
+    return split;
+}
+
+/**
+ * Convert Degrees Minutes Seconds to Decimal Degrees
+ *
+ * @param {number} degrees - The degrees of the input co-ordinates
+ * @param {number} minutes - The minutes of the input co-ordinates
+ * @param {number} seconds - The seconds of the input co-ordinates
+ * @param {number} precision - The precision the result should be rounded to
+ * @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
+ */
+function convDMSToDD (degrees, minutes, seconds, precision){
+    const absDegrees = Math.abs(degrees);
+    let conv = absDegrees + (minutes / 60) + (seconds / 3600);
+    let outString = round(conv, precision) + "°";
+    if (isNegativeZero(degrees) || degrees < 0) {
+        conv = -conv;
+        outString = "-" + outString;
+    }
+    return {
+        "degrees": conv,
+        "string": outString
+    };
+}
+
+/**
+ * Convert Decimal Degrees Minutes to Decimal Degrees
+ *
+ * @param {number} degrees - The input degrees to be converted
+ * @param {number} minutes - The input minutes to be converted
+ * @param {number} precision - The precision which the result should be rounded to
+ * @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
+ */
+function convDDMToDD (degrees, minutes, precision) {
+    const absDegrees = Math.abs(degrees);
+    let conv = absDegrees + minutes / 60;
+    let outString = round(conv, precision) + "°";
+    if (isNegativeZero(degrees) || degrees < 0) {
+        conv = -conv;
+        outString = "-" + outString;
+    }
+    return {
+        "degrees": conv,
+        "string": outString
+    };
+}
+
+/**
+ * Convert Decimal Degrees to Decimal Degrees
+ *
+ * Doesn't affect the input, just puts it into an object
+ * @param {number} degrees - The input degrees to be converted
+ * @param {number} precision - The precision which the result should be rounded to
+ * @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
+ */
+function convDDToDD (degrees, precision) {
+    return {
+        "degrees": degrees,
+        "string": round(degrees, precision) + "°"
+    };
+}
+
+/**
+ * Convert Decimal Degrees to Degrees Minutes Seconds
+ *
+ * @param {number} decDegrees - The input data to be converted
+ * @param {number} precision - The precision which the result should be rounded to
+ * @returns {{string: string, degrees: number, minutes: number, seconds: number}} An object containing the raw converted value as separate numbers (.degrees, .minutes, .seconds), and a formatted string version (obj.string)
+ */
+function convDDToDMS (decDegrees, precision) {
+    const absDegrees = Math.abs(decDegrees);
+    let degrees = Math.floor(absDegrees);
+    const minutes = Math.floor(60 * (absDegrees - degrees)),
+        seconds = round(3600 * (absDegrees - degrees) - 60 * minutes, precision);
+    let outString = degrees + "° " + minutes + "' " + seconds + "\"";
+    if (isNegativeZero(decDegrees) || decDegrees < 0) {
+        degrees = -degrees;
+        outString = "-" + outString;
+    }
+    return {
+        "degrees": degrees,
+        "minutes": minutes,
+        "seconds": seconds,
+        "string": outString
+    };
+}
+
+/**
+ * Convert Decimal Degrees to Degrees Decimal Minutes
+ *
+ * @param {number} decDegrees - The input degrees to be converted
+ * @param {number} precision - The precision the input data should be rounded to
+ * @returns {{string: string, degrees: number, minutes: number}} An object containing the raw converted value as separate numbers (.degrees, .minutes), and a formatted string version (obj.string)
+ */
+function convDDToDDM (decDegrees, precision) {
+    const absDegrees = Math.abs(decDegrees);
+    let degrees = Math.floor(absDegrees);
+    const minutes = absDegrees - degrees,
+        decMinutes = round(minutes * 60, precision);
+    let outString = degrees + "° " + decMinutes + "'";
+    if (decDegrees < 0 || isNegativeZero(decDegrees)) {
+        degrees = -degrees;
+        outString = "-" + outString;
+    }
+
+    return {
+        "degrees": degrees,
+        "minutes": decMinutes,
+        "string": outString,
+    };
+}
+
+/**
+ * Finds and returns the compass directions in an input string
+ *
+ * @param {string} input - The input co-ordinates containing the direction
+ * @param {string} delim - The delimiter separating latitide and longitude
+ * @returns {string[]} String array containing the latitude and longitude directions
+ */
+export function findDirs(input, delim) {
+    const upperInput = input.toUpperCase();
+    const dirExp = new RegExp(/[NESW]/g);
+
+    const dirs = upperInput.match(dirExp);
+
+    if (dirs) {
+        // If there's actually compass directions
+        // in the input, use these to work out the direction
+        if (dirs.length <= 2 && dirs.length >= 1) {
+            return dirs.length === 2 ? [dirs[0], dirs[1]] : [dirs[0], ""];
+        }
+    }
+
+    // Nothing was returned, so guess the directions
+    let lat = upperInput,
+        long,
+        latDir = "",
+        longDir = "";
+    if (!delim.includes("Direction")) {
+        if (upperInput.includes(delim)) {
+            const split = upperInput.split(delim);
+            if (split.length >= 1) {
+                if (split[0] !== "") {
+                    lat = split[0];
+                }
+                if (split.length >= 2 && split[1] !== "") {
+                    long = split[1];
+                }
+            }
+        }
+    } else {
+        const split = upperInput.split(dirExp);
+        if (split.length > 1) {
+            lat = split[0] === "" ? split[1] : split[0];
+            if (split.length > 2 && split[2] !== "") {
+                long = split[2];
+            }
+        }
+    }
+
+    if (lat) {
+        lat = parseFloat(lat);
+        latDir = lat < 0 ? "S" : "N";
+    }
+
+    if (long) {
+        long = parseFloat(long);
+        longDir = long < 0 ? "W" : "E";
+    }
+
+    return [latDir, longDir];
+}
+
+/**
+ * Detects the co-ordinate format of the input data
+ *
+ * @param {string} input - The input data whose format we need to detect
+ * @param {string} delim - The delimiter separating the data in input
+ * @returns {string} The input format
+ */
+export function findFormat (input, delim) {
+    let testData;
+    const mgrsPattern = new RegExp(/^[0-9]{2}\s?[C-HJ-NP-X]{1}\s?[A-HJ-NP-Z][A-HJ-NP-V]\s?[0-9\s]+/),
+        osngPattern = new RegExp(/^[A-HJ-Z]{2}\s+[0-9\s]+$/),
+        geohashPattern = new RegExp(/^[0123456789BCDEFGHJKMNPQRSTUVWXYZ]+$/),
+        utmPattern = new RegExp(/^[0-9]{2}\s?[C-HJ-NP-X]\s[0-9.]+\s?[0-9.]+$/),
+        degPattern = new RegExp(/[°'"]/g);
+
+    input = input.trim();
+
+    if (delim !== null && delim.includes("Direction")) {
+        const split = input.split(/[NnEeSsWw]/);
+        if (split.length > 1) {
+            testData = split[0] === "" ? split[1] : split[0];
+        }
+    } else if (delim !== null && delim !== "") {
+        if (input.includes(delim)) {
+            const split = input.split(delim);
+            if (split.length > 1) {
+                testData = split[0] === "" ? split[1] : split[0];
+            }
+        } else {
+            testData = input;
+        }
+    }
+
+    // Test non-degrees formats
+    if (!degPattern.test(input)) {
+        const filteredInput = input.toUpperCase().replace(delim, "");
+
+        if (utmPattern.test(filteredInput)) {
+            return "Universal Transverse Mercator";
+        }
+        if (mgrsPattern.test(filteredInput)) {
+            return "Military Grid Reference System";
+        }
+        if (osngPattern.test(filteredInput)) {
+            return "Ordnance Survey National Grid";
+        }
+        if (geohashPattern.test(filteredInput)) {
+            return "Geohash";
+        }
+    }
+
+    // Test DMS/DDM/DD formats
+    if (testData !== undefined) {
+        const split = splitInput(testData);
+        switch (split.length){
+            case 3:
+                return "Degrees Minutes Seconds";
+            case 2:
+                return "Degrees Decimal Minutes";
+            case 1:
+                return "Decimal Degrees";
+        }
+    }
+    return null;
+}
+
+/**
+ * Automatically find the delimeter type from the given input
+ *
+ * @param {string} input
+ * @returns {string} Delimiter type
+ */
+export function findDelim (input) {
+    input = input.trim();
+    const delims = [",", ";", ":"];
+    const testDir = input.match(/[NnEeSsWw]/g);
+    if (testDir !== null && testDir.length > 0 && testDir.length < 3) {
+        // Possibly contains a direction
+        const splitInput = input.split(/[NnEeSsWw]/);
+        if (splitInput.length <= 3 && splitInput.length > 0) {
+            // If there's 3 splits (one should be empty), then assume we have directions
+            if (splitInput[0] === "") {
+                return "Direction Preceding";
+            } else if (splitInput[splitInput.length - 1] === "") {
+                return "Direction Following";
+            }
+        }
+    }
+
+    // Loop through the standard delimiters, and try to find them in the input
+    for (let i = 0; i < delims.length; i++) {
+        const delim = delims[i];
+        if (input.includes(delim)) {
+            const splitInput = input.split(delim);
+            if (splitInput.length <= 3 && splitInput.length > 0) {
+                // Don't want to try and convert more than 2 co-ordinates
+                return delim;
+            }
+        }
+    }
+    return null;
+}
+
+/**
+ * Gets the real string for a delimiter name.
+ *
+ * @param {string} delim The delimiter to be matched
+ * @returns {string}
+ */
+export function realDelim (delim) {
+    return {
+        "Auto":         "Auto",
+        "Space":        " ",
+        "\\n":          "\n",
+        "Comma":        ",",
+        "Semi-colon":   ";",
+        "Colon":        ":"
+    }[delim];
+}
+
+/**
+ * Returns true if a zero is negative
+ *
+ * @param {number} zero
+ * @returns {boolean}
+ */
+function isNegativeZero(zero) {
+    return zero === 0 && (1/zero < 0);
+}
+
+/**
+ * Rounds a number to a specified number of decimal places
+ *
+ * @param {number} input - The number to be rounded
+ * @param {precision} precision - The number of decimal places the number should be rounded to
+ * @returns {number}
+ */
+function round(input, precision) {
+    precision = Math.pow(10, precision);
+    return Math.round(input * precision) / precision;
+}

+ 313 - 0
src/core/lib/DateTime.mjs

@@ -0,0 +1,313 @@
+/**
+ * DateTime resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+/**
+ * DateTime units.
+ */
+export const UNITS = ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"];
+
+/**
+ * DateTime formats.
+ */
+export const DATETIME_FORMATS = [
+    {
+        name: "Standard date and time",
+        value: "DD/MM/YYYY HH:mm:ss"
+    },
+    {
+        name: "American-style date and time",
+        value: "MM/DD/YYYY HH:mm:ss"
+    },
+    {
+        name: "International date and time",
+        value: "YYYY-MM-DD HH:mm:ss"
+    },
+    {
+        name: "Verbose date and time",
+        value: "dddd Do MMMM YYYY HH:mm:ss Z z"
+    },
+    {
+        name: "UNIX timestamp (seconds)",
+        value: "X"
+    },
+    {
+        name: "UNIX timestamp offset (milliseconds)",
+        value: "x"
+    },
+    {
+        name: "Automatic",
+        value: ""
+    },
+];
+
+/**
+ * MomentJS DateTime formatting examples.
+ */
+export const FORMAT_EXAMPLES = `Format string tokens:
+<table class="table table-striped table-hover table-sm table-bordered" style="font-family: sans-serif">
+  <thead class="thead-dark">
+    <tr>
+      <th>Category</th>
+      <th>Token</th>
+      <th>Output</th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td><b>Month</b></td>
+      <td>M</td>
+      <td>1 2 ... 11 12</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Mo</td>
+      <td>1st 2nd ... 11th 12th</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>MM</td>
+      <td>01 02 ... 11 12</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>MMM</td>
+      <td>Jan Feb ... Nov Dec</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>MMMM</td>
+      <td>January February ... November December</td>
+    </tr>
+    <tr>
+      <td><b>Quarter</b></td>
+      <td>Q</td>
+      <td>1 2 3 4</td>
+    </tr>
+    <tr>
+      <td><b>Day of Month</b></td>
+      <td>D</td>
+      <td>1 2 ... 30 31</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Do</td>
+      <td>1st 2nd ... 30th 31st</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>DD</td>
+      <td>01 02 ... 30 31</td>
+    </tr>
+    <tr>
+      <td><b>Day of Year</b></td>
+      <td>DDD</td>
+      <td>1 2 ... 364 365</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>DDDo</td>
+      <td>1st 2nd ... 364th 365th</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>DDDD</td>
+      <td>001 002 ... 364 365</td>
+    </tr>
+    <tr>
+      <td><b>Day of Week</b></td>
+      <td>d</td>
+      <td>0 1 ... 5 6</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>do</td>
+      <td>0th 1st ... 5th 6th</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>dd</td>
+      <td>Su Mo ... Fr Sa</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ddd</td>
+      <td>Sun Mon ... Fri Sat</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>dddd</td>
+      <td>Sunday Monday ... Friday Saturday</td>
+    </tr>
+    <tr>
+      <td><b>Day of Week (Locale)</b></td>
+      <td>e</td>
+      <td>0 1 ... 5 6</td>
+    </tr>
+    <tr>
+      <td><b>Day of Week (ISO)</b></td>
+      <td>E</td>
+      <td>1 2 ... 6 7</td>
+    </tr>
+    <tr>
+      <td><b>Week of Year</b></td>
+      <td>w</td>
+      <td>1 2 ... 52 53</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>wo</td>
+      <td>1st 2nd ... 52nd 53rd</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ww</td>
+      <td>01 02 ... 52 53</td>
+    </tr>
+    <tr>
+      <td><b>Week of Year (ISO)</b></td>
+      <td>W</td>
+      <td>1 2 ... 52 53</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Wo</td>
+      <td>1st 2nd ... 52nd 53rd</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>WW</td>
+      <td>01 02 ... 52 53</td>
+    </tr>
+    <tr>
+      <td><b>Year</b></td>
+      <td>YY</td>
+      <td>70 71 ... 29 30</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>YYYY</td>
+      <td>1970 1971 ... 2029 2030</td>
+    </tr>
+    <tr>
+      <td><b>Week Year</b></td>
+      <td>gg</td>
+      <td>70 71 ... 29 30</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>gggg</td>
+      <td>1970 1971 ... 2029 2030</td>
+    </tr>
+    <tr>
+      <td><b>Week Year (ISO)</b></td>
+      <td>GG</td>
+      <td>70 71 ... 29 30</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>GGGG</td>
+      <td>1970 1971 ... 2029 2030</td>
+    </tr>
+    <tr>
+      <td><b>AM/PM</b></td>
+      <td>A</td>
+      <td>AM PM</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>a</td>
+      <td>am pm</td>
+    </tr>
+    <tr>
+      <td><b>Hour</b></td>
+      <td>H</td>
+      <td>0 1 ... 22 23</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>HH</td>
+      <td>00 01 ... 22 23</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>h</td>
+      <td>1 2 ... 11 12</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>hh</td>
+      <td>01 02 ... 11 12</td>
+    </tr>
+    <tr>
+      <td><b>Minute</b></td>
+      <td>m</td>
+      <td>0 1 ... 58 59</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>mm</td>
+      <td>00 01 ... 58 59</td>
+    </tr>
+    <tr>
+      <td><b>Second</b></td>
+      <td>s</td>
+      <td>0 1 ... 58 59</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ss</td>
+      <td>00 01 ... 58 59</td>
+    </tr>
+    <tr>
+      <td><b>Fractional Second</b></td>
+      <td>S</td>
+      <td>0 1 ... 8 9</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>SS</td>
+      <td>00 01 ... 98 99</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>SSS</td>
+      <td>000 001 ... 998 999</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>SSSS ... SSSSSSSSS</td>
+      <td>000[0..] 001[0..] ... 998[0..] 999[0..]</td>
+    </tr>
+    <tr>
+      <td><b>Timezone</b></td>
+      <td>z or zz</td>
+      <td>EST CST ... MST PST</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>Z</td>
+      <td>-07:00 -06:00 ... +06:00 +07:00</td>
+    </tr>
+    <tr>
+      <td></td>
+      <td>ZZ</td>
+      <td>-0700 -0600 ... +0600 +0700</td>
+    </tr>
+    <tr>
+      <td><b>Unix Timestamp</b></td>
+      <td>X</td>
+      <td>1360013296</td>
+    </tr>
+    <tr>
+      <td><b>Unix Millisecond Timestamp</b></td>
+      <td>x</td>
+      <td>1360013296123</td>
+    </tr>
+  </tbody>
+</table>`;
+

+ 37 - 0
src/core/lib/Decimal.mjs

@@ -0,0 +1,37 @@
+/**
+ * Decimal functions.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+
+
+/**
+ * Convert a string of decimal values into a byte array.
+ *
+ * @param {string} data
+ * @param {string} [delim]
+ * @returns {byteArray}
+ *
+ * @example
+ * // returns [10,20,30]
+ * fromDecimal("10 20 30");
+ *
+ * // returns [10,20,30]
+ * fromDecimal("10:20:30", "Colon");
+ */
+export function fromDecimal(data, delim="Auto") {
+    delim = Utils.charRep(delim);
+    const output = [];
+    let byteStr = data.split(delim);
+    if (byteStr[byteStr.length-1] === "")
+        byteStr = byteStr.slice(0, byteStr.length-1);
+
+    for (let i = 0; i < byteStr.length; i++) {
+        output[i] = parseInt(byteStr[i], 10);
+    }
+    return output;
+}

+ 74 - 0
src/core/lib/Delim.mjs

@@ -0,0 +1,74 @@
+/**
+ * Various delimiters
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/**
+ * Generic sequence delimiters.
+ */
+export const DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"];
+
+/**
+ * Binary sequence delimiters.
+ */
+export const BIN_DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "None"];
+
+/**
+ * Letter sequence delimiters.
+ */
+export const LETTER_DELIM_OPTIONS = ["Space", "Line feed", "CRLF", "Forward slash", "Backslash", "Comma", "Semi-colon", "Colon"];
+
+/**
+ * Word sequence delimiters.
+ */
+export const WORD_DELIM_OPTIONS = ["Line feed", "CRLF", "Forward slash", "Backslash", "Comma", "Semi-colon", "Colon"];
+
+/**
+ * Input sequence delimiters.
+ */
+export const INPUT_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"];
+
+/**
+ * Armithmetic sequence delimiters
+ */
+export const ARITHMETIC_DELIM_OPTIONS = ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"];
+
+/**
+ * Hash delimiters
+ */
+export const HASH_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma"];
+
+/**
+ * IP delimiters
+ */
+export const IP_DELIM_OPTIONS = ["Line feed", "CRLF", "Space", "Comma", "Semi-colon"];
+
+/**
+ * Split delimiters.
+ */
+export const SPLIT_DELIM_OPTIONS = [
+    {name: "Comma", value: ","},
+    {name: "Space", value: " "},
+    {name: "Line feed", value: "\\n"},
+    {name: "CRLF", value: "\\r\\n"},
+    {name: "Semi-colon", value: ";"},
+    {name: "Colon", value: ":"},
+    {name: "Nothing (separate chars)", value: ""}
+];
+
+/**
+ * Join delimiters.
+ */
+export const JOIN_DELIM_OPTIONS = [
+    {name: "Line feed", value: "\\n"},
+    {name: "CRLF", value: "\\r\\n"},
+    {name: "Space", value: " "},
+    {name: "Comma", value: ","},
+    {name: "Semi-colon", value: ";"},
+    {name: "Colon", value: ":"},
+    {name: "Nothing (join chars)", value: ""}
+];
+

+ 59 - 0
src/core/lib/Extract.mjs

@@ -0,0 +1,59 @@
+/**
+ * Identifier extraction functions
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ */
+
+/**
+ * Runs search operations across the input data using regular expressions.
+ *
+ * @param {string} input
+ * @param {RegExp} searchRegex
+ * @param {RegExp} removeRegex - A regular expression defining results to remove from the
+ *      final list
+ * @param {boolean} includeTotal - Whether or not to include the total number of results
+ * @returns {string}
+ */
+export function search (input, searchRegex, removeRegex, includeTotal) {
+    let output = "",
+        total = 0,
+        match;
+
+    while ((match = searchRegex.exec(input))) {
+        // Moves pointer when an empty string is matched (prevents infinite loop)
+        if (match.index === searchRegex.lastIndex) {
+            searchRegex.lastIndex++;
+        }
+
+        if (removeRegex && removeRegex.test(match[0]))
+            continue;
+        total++;
+        output += match[0] + "\n";
+    }
+
+    if (includeTotal)
+        output = "Total found: " + total + "\n\n" + output;
+
+    return output;
+}
+
+
+/**
+ * URL regular expression
+ */
+const protocol = "[A-Z]+://",
+    hostname = "[-\\w]+(?:\\.\\w[-\\w]*)+",
+    port = ":\\d+",
+    path = "/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*" +
+        "(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*";
+
+export const URL_REGEX = new RegExp(protocol + hostname + "(?:" + port + ")?(?:" + path + ")?", "ig");
+
+
+/**
+ * Domain name regular expression
+ */
+export const DOMAIN_REGEX = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig;

+ 20 - 0
src/core/lib/FlowControl.mjs

@@ -0,0 +1,20 @@
+/**
+ * Flow control functions
+ *
+ * @author d98762625 [d98762625@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/**
+ * Returns the index of a label.
+ *
+ * @param {Object} state - The current state of the recipe.
+ * @param {string} name - The label name to look for.
+ * @returns {number}
+ */
+export function getLabelIndex(name, state) {
+    return state.opList.findIndex((operation) => {
+        return (operation.name === "Label") && (name === operation.ingValues[0]);
+    });
+}

+ 28 - 0
src/core/lib/Hash.mjs

@@ -0,0 +1,28 @@
+/**
+ * Hashing resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ *
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+import CryptoApi from "crypto-api/src/crypto-api";
+
+
+/**
+ * Generic hash function.
+ *
+ * @param {string} name
+ * @param {ArrayBuffer} input
+ * @param {Object} [options={}]
+ * @returns {string}
+ */
+export function runHash(name, input, options={}) {
+    const msg = Utils.arrayBufferToStr(input, false),
+        hasher = CryptoApi.getHasher(name, options);
+    hasher.update(msg);
+    return CryptoApi.encoder.toHex(hasher.finalize());
+}
+

+ 109 - 0
src/core/lib/Hex.mjs

@@ -0,0 +1,109 @@
+/**
+ * Hexadecimal functions.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+
+
+/**
+ * Convert a byte array into a hex string.
+ *
+ * @param {Uint8Array|byteArray} data
+ * @param {string} [delim=" "]
+ * @param {number} [padding=2]
+ * @returns {string}
+ *
+ * @example
+ * // returns "0a 14 1e"
+ * toHex([10,20,30]);
+ *
+ * // returns "0a:14:1e"
+ * toHex([10,20,30], ":");
+ */
+export function toHex(data, delim=" ", padding=2) {
+    if (!data) return "";
+
+    let output = "";
+
+    for (let i = 0; i < data.length; i++) {
+        output += data[i].toString(16).padStart(padding, "0") + delim;
+    }
+
+    // Add \x or 0x to beginning
+    if (delim === "0x") output = "0x" + output;
+    if (delim === "\\x") output = "\\x" + output;
+
+    if (delim.length)
+        return output.slice(0, -delim.length);
+    else
+        return output;
+}
+
+
+/**
+ * Convert a byte array into a hex string as efficiently as possible with no options.
+ *
+ * @param {byteArray} data
+ * @returns {string}
+ *
+ * @example
+ * // returns "0a141e"
+ * toHex([10,20,30]);
+ */
+export function toHexFast(data) {
+    if (!data) return "";
+
+    const output = [];
+
+    for (let i = 0; i < data.length; i++) {
+        output.push((data[i] >>> 4).toString(16));
+        output.push((data[i] & 0x0f).toString(16));
+    }
+
+    return output.join("");
+}
+
+
+/**
+ * Convert a hex string into a byte array.
+ *
+ * @param {string} data
+ * @param {string} [delim]
+ * @param {number} [byteLen=2]
+ * @returns {byteArray}
+ *
+ * @example
+ * // returns [10,20,30]
+ * fromHex("0a 14 1e");
+ *
+ * // returns [10,20,30]
+ * fromHex("0a:14:1e", "Colon");
+ */
+export function fromHex(data, delim="Auto", byteLen=2) {
+    if (delim !== "None") {
+        const delimRegex = delim === "Auto" ? /[^a-f\d]/gi : Utils.regexRep(delim);
+        data = data.replace(delimRegex, "");
+    }
+
+    const output = [];
+    for (let i = 0; i < data.length; i += byteLen) {
+        output.push(parseInt(data.substr(i, byteLen), 16));
+    }
+    return output;
+}
+
+
+/**
+ * To Hexadecimal delimiters.
+ */
+export const TO_HEX_DELIM_OPTIONS = ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"];
+
+
+/**
+ * From Hexadecimal delimiters.
+ */
+export const FROM_HEX_DELIM_OPTIONS = ["Auto"].concat(TO_HEX_DELIM_OPTIONS);

+ 676 - 0
src/core/lib/IP.mjs

@@ -0,0 +1,676 @@
+/**
+ * IP resources.
+ *
+ * @author picapi
+ * @author n1474335 [n1474335@gmail.com]
+ * @author Klaxon [klaxon@veyr.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Utils from "../Utils";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Parses an IPv4 CIDR range (e.g. 192.168.0.0/24) and displays information about it.
+ *
+ * @param {RegExp} cidr
+ * @param {boolean} includeNetworkInfo
+ * @param {boolean} enumerateAddresses
+ * @param {boolean} allowLargeList
+ * @returns {string}
+ */
+export function ipv4CidrRange(cidr, includeNetworkInfo, enumerateAddresses, allowLargeList) {
+    const network = strToIpv4(cidr[1]),
+        cidrRange = parseInt(cidr[2], 10);
+    let output = "";
+
+    if (cidrRange < 0 || cidrRange > 31) {
+        return "IPv4 CIDR must be less than 32";
+    }
+
+    const mask = ~(0xFFFFFFFF >>> cidrRange),
+        ip1 = network & mask,
+        ip2 = ip1 | ~mask;
+
+    if (includeNetworkInfo) {
+        output += "Network: " + ipv4ToStr(network) + "\n";
+        output += "CIDR: " + cidrRange + "\n";
+        output += "Mask: " + ipv4ToStr(mask) + "\n";
+        output += "Range: " + ipv4ToStr(ip1) + " - " + ipv4ToStr(ip2) + "\n";
+        output += "Total addresses in range: " + (((ip2 - ip1) >>> 0) + 1) + "\n\n";
+    }
+
+    if (enumerateAddresses) {
+        if (cidrRange >= 16 || allowLargeList) {
+            output += generateIpv4Range(ip1, ip2).join("\n");
+        } else {
+            output += _LARGE_RANGE_ERROR;
+        }
+    }
+    return output;
+}
+
+/**
+ * Parses an IPv6 CIDR range (e.g. ff00::/48) and displays information about it.
+ *
+ * @param {RegExp} cidr
+ * @param {boolean} includeNetworkInfo
+ * @returns {string}
+ */
+export function ipv6CidrRange(cidr, includeNetworkInfo) {
+    let output = "";
+    const network = strToIpv6(cidr[1]),
+        cidrRange = parseInt(cidr[cidr.length-1], 10);
+
+    if (cidrRange < 0 || cidrRange > 127) {
+        return "IPv6 CIDR must be less than 128";
+    }
+
+    const ip1 = new Array(8),
+        ip2 = new Array(8),
+        total = new Array(128);
+
+    const mask = genIpv6Mask(cidrRange);
+    let totalDiff = "";
+
+
+    for (let i = 0; i < 8; i++) {
+        ip1[i] = network[i] & mask[i];
+        ip2[i] = ip1[i] | (~mask[i] & 0x0000FFFF);
+        totalDiff = (ip2[i] - ip1[i]).toString(2);
+
+        if (totalDiff !== "0") {
+            for (let n = 0; n < totalDiff.length; n++) {
+                total[i*16 + 16-(totalDiff.length-n)] = totalDiff[n];
+            }
+        }
+    }
+
+    if (includeNetworkInfo) {
+        output += "Network: " + ipv6ToStr(network) + "\n";
+        output += "Shorthand: " + ipv6ToStr(network, true) + "\n";
+        output += "CIDR: " + cidrRange + "\n";
+        output += "Mask: " + ipv6ToStr(mask) + "\n";
+        output += "Range: " + ipv6ToStr(ip1) + " - " + ipv6ToStr(ip2) + "\n";
+        output += "Total addresses in range: " + (parseInt(total.join(""), 2) + 1) + "\n\n";
+    }
+
+    return output;
+}
+
+/**
+ * Parses an IPv4 hyphenated range (e.g. 192.168.0.0 - 192.168.0.255) and displays information
+ * about it.
+ *
+ * @param {RegExp} range
+ * @param {boolean} includeNetworkInfo
+ * @param {boolean} enumerateAddresses
+ * @param {boolean} allowLargeList
+ * @returns {string}
+ */
+export function ipv4HyphenatedRange(range, includeNetworkInfo, enumerateAddresses, allowLargeList) {
+    const ip1 = strToIpv4(range[0].split("-")[0].trim()),
+        ip2 = strToIpv4(range[0].split("-")[1].trim());
+
+    let output = "";
+
+    // Calculate mask
+    let diff = ip1 ^ ip2,
+        cidr = 32,
+        mask = 0;
+
+    while (diff !== 0) {
+        diff >>= 1;
+        cidr--;
+        mask = (mask << 1) | 1;
+    }
+
+    mask = ~mask >>> 0;
+    const network = ip1 & mask,
+        subIp1 = network & mask,
+        subIp2 = subIp1 | ~mask;
+
+    if (includeNetworkInfo) {
+        output += `Minimum subnet required to hold this range:
+\tNetwork: ${ipv4ToStr(network)}
+\tCIDR: ${cidr}
+\tMask: ${ipv4ToStr(mask)}
+\tSubnet range: ${ipv4ToStr(subIp1)} - ${ipv4ToStr(subIp2)}
+\tTotal addresses in subnet: ${(((subIp2 - subIp1) >>> 0) + 1)}
+
+Range: ${ipv4ToStr(ip1)} - ${ipv4ToStr(ip2)}
+Total addresses in range: ${(((ip2 - ip1) >>> 0) + 1)}
+
+`;
+    }
+
+    if (enumerateAddresses) {
+        if (((ip2 - ip1) >>> 0) <= 65536 || allowLargeList) {
+            output += generateIpv4Range(ip1, ip2).join("\n");
+        } else {
+            output += _LARGE_RANGE_ERROR;
+        }
+    }
+    return output;
+}
+
+/**
+ * Parses an IPv6 hyphenated range (e.g. ff00:: - ffff::) and displays information about it.
+ *
+ * @param {RegExp} range
+ * @param {boolean} includeNetworkInfo
+ * @returns {string}
+ */
+export function ipv6HyphenatedRange(range, includeNetworkInfo) {
+    const ip1 = strToIpv6(range[0].split("-")[0].trim()),
+        ip2 = strToIpv6(range[0].split("-")[1].trim()),
+        total = new Array(128).fill();
+
+    let output = "",
+        t = "",
+        i;
+
+    for (i = 0; i < 8; i++) {
+        t = (ip2[i] - ip1[i]).toString(2);
+        if (t !== "0") {
+            for (let n = 0; n < t.length; n++) {
+                total[i*16 + 16-(t.length-n)] = t[n];
+            }
+        }
+    }
+
+    if (includeNetworkInfo) {
+        output += "Range: " + ipv6ToStr(ip1) + " - " + ipv6ToStr(ip2) + "\n";
+        output += "Shorthand range: " + ipv6ToStr(ip1, true) + " - " + ipv6ToStr(ip2, true) + "\n";
+        output += "Total addresses in range: " + (parseInt(total.join(""), 2) + 1) + "\n\n";
+    }
+
+    return output;
+}
+
+/**
+ * Parses a list of IPv4 addresses separated by a new line (\n) and displays information
+ * about it.
+ *
+ * @param {RegExp} list
+ * @param {boolean} includeNetworkInfo
+ * @param {boolean} enumerateAddresses
+ * @param {boolean} allowLargeList
+ * @returns {string}
+ */
+export function ipv4ListedRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList) {
+
+    let ipv4List = match[0].split("\n");
+    ipv4List = ipv4List.filter(Boolean);
+
+    const ipv4CidrList = ipv4List.filter(function(a) {
+        return a.includes("/");
+    });
+    for (let i = 0; i < ipv4CidrList.length; i++) {
+        const network = strToIpv4(ipv4CidrList[i].split("/")[0]);
+        const cidrRange = parseInt(ipv4CidrList[i].split("/")[1], 10);
+        if (cidrRange < 0 || cidrRange > 31) {
+            return "IPv4 CIDR must be less than 32";
+        }
+        const mask = ~(0xFFFFFFFF >>> cidrRange),
+            cidrIp1 = network & mask,
+            cidrIp2 = cidrIp1 | ~mask;
+        ipv4List.splice(ipv4List.indexOf(ipv4CidrList[i]), 1);
+        ipv4List.push(ipv4ToStr(cidrIp1), ipv4ToStr(cidrIp2));
+    }
+
+    ipv4List = ipv4List.sort(ipv4Compare);
+    const ip1 = ipv4List[0];
+    const ip2 = ipv4List[ipv4List.length - 1];
+    const range = [ip1 + " - " + ip2];
+    return ipv4HyphenatedRange(range, includeNetworkInfo, enumerateAddresses, allowLargeList);
+}
+
+/**
+ * Parses a list of IPv6 addresses separated by a new line (\n) and displays information
+ * about it.
+ *
+ * @param {RegExp} list
+ * @param {boolean} includeNetworkInfo
+ * @returns {string}
+ */
+export function ipv6ListedRange(match, includeNetworkInfo) {
+
+    let ipv6List = match[0].split("\n");
+    ipv6List = ipv6List.filter(function(str) {
+        return str.trim();
+    });
+    for (let i =0; i < ipv6List.length; i++){
+        ipv6List[i] = ipv6List[i].trim();
+    }
+    const ipv6CidrList = ipv6List.filter(function(a) {
+        return a.includes("/");
+    });
+
+    for (let i = 0; i < ipv6CidrList.length; i++) {
+
+        const network = strToIpv6(ipv6CidrList[i].split("/")[0]);
+        const cidrRange = parseInt(ipv6CidrList[i].split("/")[1], 10);
+
+        if (cidrRange < 0 || cidrRange > 127) {
+            return "IPv6 CIDR must be less than 128";
+        }
+
+        const cidrIp1 = new Array(8),
+            cidrIp2 = new Array(8);
+
+        const mask = genIpv6Mask(cidrRange);
+
+        for (let j = 0; j < 8; j++) {
+            cidrIp1[j] = network[j] & mask[j];
+            cidrIp2[j] = cidrIp1[j] | (~mask[j] & 0x0000FFFF);
+        }
+        ipv6List.splice(ipv6List.indexOf(ipv6CidrList[i]), 1);
+        ipv6List.push(ipv6ToStr(cidrIp1), ipv6ToStr(cidrIp2));
+    }
+    ipv6List = ipv6List.sort(ipv6Compare);
+    const ip1 = ipv6List[0];
+    const ip2 = ipv6List[ipv6List.length - 1];
+    const range = [ip1 + " - " + ip2];
+    return ipv6HyphenatedRange(range, includeNetworkInfo);
+}
+
+/**
+ * Converts an IPv4 address from string format to numerical format.
+ *
+ * @param {string} ipStr
+ * @returns {number}
+ *
+ * @example
+ * // returns 168427520
+ * strToIpv4("10.10.0.0");
+ */
+export function strToIpv4(ipStr) {
+    const blocks = ipStr.split("."),
+        numBlocks = parseBlocks(blocks);
+    let result = 0;
+
+    result += numBlocks[0] << 24;
+    result += numBlocks[1] << 16;
+    result += numBlocks[2] << 8;
+    result += numBlocks[3];
+
+    return result;
+
+    /**
+     * Converts a list of 4 numeric strings in the range 0-255 to a list of numbers.
+     */
+    function parseBlocks(blocks) {
+        if (blocks.length !== 4)
+            throw new OperationError("More than 4 blocks.");
+
+        const numBlocks = [];
+        for (let i = 0; i < 4; i++) {
+            numBlocks[i] = parseInt(blocks[i], 10);
+            if (numBlocks[i] < 0 || numBlocks[i] > 255)
+                throw new OperationError("Block out of range.");
+        }
+        return numBlocks;
+    }
+}
+
+/**
+ * Converts an IPv4 address from numerical format to string format.
+ *
+ * @param {number} ipInt
+ * @returns {string}
+ *
+ * @example
+ * // returns "10.10.0.0"
+ * ipv4ToStr(168427520);
+ */
+export function ipv4ToStr(ipInt) {
+    const blockA = (ipInt >> 24) & 255,
+        blockB = (ipInt >> 16) & 255,
+        blockC = (ipInt >> 8) & 255,
+        blockD = ipInt & 255;
+
+    return blockA + "." + blockB + "." + blockC + "." + blockD;
+}
+
+
+/**
+ * Converts an IPv6 address from string format to numerical array format.
+ *
+ * @param {string} ipStr
+ * @returns {number[]}
+ *
+ * @example
+ * // returns [65280, 0, 0, 0, 0, 0, 4369, 8738]
+ * strToIpv6("ff00::1111:2222");
+ */
+export function strToIpv6(ipStr) {
+    let j = 0;
+    const blocks = ipStr.split(":"),
+        numBlocks = parseBlocks(blocks),
+        ipv6 = new Array(8);
+
+    for (let i = 0; i < 8; i++) {
+        if (isNaN(numBlocks[j])) {
+            ipv6[i] = 0;
+            if (i === (8-numBlocks.slice(j).length)) j++;
+        } else {
+            ipv6[i] = numBlocks[j];
+            j++;
+        }
+    }
+    return ipv6;
+
+    /**
+     * Converts a list of 3-8 numeric hex strings in the range 0-65535 to a list of numbers.
+     */
+    function parseBlocks(blocks) {
+        if (blocks.length < 3 || blocks.length > 8)
+            throw new OperationError("Badly formatted IPv6 address.");
+        const numBlocks = [];
+        for (let i = 0; i < blocks.length; i++) {
+            numBlocks[i] = parseInt(blocks[i], 16);
+            if (numBlocks[i] < 0 || numBlocks[i] > 65535)
+                throw new OperationError("Block out of range.");
+        }
+        return numBlocks;
+    }
+}
+
+/**
+ * Converts an IPv6 address from numerical array format to string format.
+ *
+ * @param {number[]} ipv6
+ * @param {boolean} compact - Whether or not to return the address in shorthand or not
+ * @returns {string}
+ *
+ * @example
+ * // returns "ff00::1111:2222"
+ * ipv6ToStr([65280, 0, 0, 0, 0, 0, 4369, 8738], true);
+ *
+ * // returns "ff00:0000:0000:0000:0000:0000:1111:2222"
+ * ipv6ToStr([65280, 0, 0, 0, 0, 0, 4369, 8738], false);
+ */
+export function ipv6ToStr(ipv6, compact) {
+    let output = "",
+        i = 0;
+
+    if (compact) {
+        let start = -1,
+            end = -1,
+            s = 0,
+            e = -1;
+
+        for (i = 0; i < 8; i++) {
+            if (ipv6[i] === 0 && e === (i-1)) {
+                e = i;
+            } else if (ipv6[i] === 0) {
+                s = i; e = i;
+            }
+            if (e >= 0 && (e-s) > (end - start)) {
+                start = s;
+                end = e;
+            }
+        }
+
+        for (i = 0; i < 8; i++) {
+            if (i !== start) {
+                output += Utils.hex(ipv6[i], 1) + ":";
+            } else {
+                output += ":";
+                i = end;
+                if (end === 7) output += ":";
+            }
+        }
+        if (output[0] === ":")
+            output = ":" + output;
+    } else {
+        for (i = 0; i < 8; i++) {
+            output += Utils.hex(ipv6[i], 4) + ":";
+        }
+    }
+    return output.slice(0, output.length-1);
+}
+
+/**
+ * Generates a list of IPv4 addresses in string format between two given numerical values.
+ *
+ * @param {number} ip
+ * @param {number} endIp
+ * @returns {string[]}
+ *
+ * @example
+ * // returns ["0.0.0.1", "0.0.0.2", "0.0.0.3"]
+ * IP.generateIpv4Range(1, 3);
+ */
+export function generateIpv4Range(ip, endIp) {
+    const range = [];
+    if (endIp >= ip) {
+        for (; ip <= endIp; ip++) {
+            range.push(ipv4ToStr(ip));
+        }
+    } else {
+        range[0] = "Second IP address smaller than first.";
+    }
+    return range;
+}
+
+/**
+ * Generates an IPv6 subnet mask given a CIDR value.
+ *
+ * @param {number} cidr
+ * @returns {number[]}
+ */
+export function genIpv6Mask(cidr) {
+    const mask = new Array(8);
+    let shift;
+
+    for (let i = 0; i < 8; i++) {
+        if (cidr > ((i+1)*16)) {
+            mask[i] = 0x0000FFFF;
+        } else {
+            shift = cidr-(i*16);
+            if (shift < 0) shift = 0;
+            mask[i] = ~((0x0000FFFF >>> shift) | 0xFFFF0000);
+        }
+    }
+
+    return mask;
+}
+
+/**
+ * Comparison operation for sorting of IPv4 addresses.
+ *
+ * @param {string} a
+ * @param {string} b
+ * @returns {number}
+ */
+export function ipv4Compare(a, b) {
+    return strToIpv4(a) - strToIpv4(b);
+}
+
+/**
+ * Comparison operation for sorting of IPv6 addresses.
+ *
+ * @param {string} a
+ * @param {string} b
+ * @returns {number}
+ */
+export function ipv6Compare(a, b) {
+
+    const a_ = strToIpv6(a),
+        b_ = strToIpv6(b);
+
+    for (let i = 0; i < a_.length; i++){
+        if (a_[i] !== b_[i]){
+            return a_[i] - b_[i];
+        }
+    }
+    return 0;
+}
+
+const _LARGE_RANGE_ERROR = "The specified range contains more than 65,536 addresses. Running this query could crash your browser. If you want to run it, select the \"Allow large queries\" option. You are advised to turn off \"Auto Bake\" whilst editing large ranges.";
+
+/**
+ * A regular expression that matches an IPv4 address
+ */
+export const IPV4_REGEX = /^\s*((?:\d{1,3}\.){3}\d{1,3})\s*$/;
+
+/**
+ * A regular expression that matches an IPv6 address
+ */
+export const IPV6_REGEX = /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i;
+
+/**
+ * Lookup table for Internet Protocols.
+ * Taken from https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
+ */
+export const protocolLookup = {
+    0: {keyword: "HOPOPT", protocol: "IPv6 Hop-by-Hop Option"},
+    1: {keyword: "ICMP", protocol: "Internet Control Message"},
+    2: {keyword: "IGMP", protocol: "Internet Group Management"},
+    3: {keyword: "GGP", protocol: "Gateway-to-Gateway"},
+    4: {keyword: "IPv4", protocol: "IPv4 encapsulation"},
+    5: {keyword: "ST", protocol: "Stream"},
+    6: {keyword: "TCP", protocol: "Transmission Control"},
+    7: {keyword: "CBT", protocol: "CBT"},
+    8: {keyword: "EGP", protocol: "Exterior Gateway Protocol"},
+    9: {keyword: "IGP", protocol: "any private interior gateway (used by Cisco for their IGRP)"},
+    10: {keyword: "BBN-RCC-MON", protocol: "BBN RCC Monitoring"},
+    11: {keyword: "NVP-II", protocol: "Network Voice Protocol"},
+    12: {keyword: "PUP", protocol: "PUP"},
+    13: {keyword: "ARGUS (deprecated)", protocol: "ARGUS"},
+    14: {keyword: "EMCON", protocol: "EMCON"},
+    15: {keyword: "XNET", protocol: "Cross Net Debugger"},
+    16: {keyword: "CHAOS", protocol: "Chaos"},
+    17: {keyword: "UDP", protocol: "User Datagram"},
+    18: {keyword: "MUX", protocol: "Multiplexing"},
+    19: {keyword: "DCN-MEAS", protocol: "DCN Measurement Subsystems"},
+    20: {keyword: "HMP", protocol: "Host Monitoring"},
+    21: {keyword: "PRM", protocol: "Packet Radio Measurement"},
+    22: {keyword: "XNS-IDP", protocol: "XEROX NS IDP"},
+    23: {keyword: "TRUNK-1", protocol: "Trunk-1"},
+    24: {keyword: "TRUNK-2", protocol: "Trunk-2"},
+    25: {keyword: "LEAF-1", protocol: "Leaf-1"},
+    26: {keyword: "LEAF-2", protocol: "Leaf-2"},
+    27: {keyword: "RDP", protocol: "Reliable Data Protocol"},
+    28: {keyword: "IRTP", protocol: "Internet Reliable Transaction"},
+    29: {keyword: "ISO-TP4", protocol: "ISO Transport Protocol Class 4"},
+    30: {keyword: "NETBLT", protocol: "Bulk Data Transfer Protocol"},
+    31: {keyword: "MFE-NSP", protocol: "MFE Network Services Protocol"},
+    32: {keyword: "MERIT-INP", protocol: "MERIT Internodal Protocol"},
+    33: {keyword: "DCCP", protocol: "Datagram Congestion Control Protocol"},
+    34: {keyword: "3PC", protocol: "Third Party Connect Protocol"},
+    35: {keyword: "IDPR", protocol: "Inter-Domain Policy Routing Protocol"},
+    36: {keyword: "XTP", protocol: "XTP"},
+    37: {keyword: "DDP", protocol: "Datagram Delivery Protocol"},
+    38: {keyword: "IDPR-CMTP", protocol: "IDPR Control Message Transport Proto"},
+    39: {keyword: "TP++", protocol: "TP++ Transport Protocol"},
+    40: {keyword: "IL", protocol: "IL Transport Protocol"},
+    41: {keyword: "IPv6", protocol: "IPv6 encapsulation"},
+    42: {keyword: "SDRP", protocol: "Source Demand Routing Protocol"},
+    43: {keyword: "IPv6-Route", protocol: "Routing Header for IPv6"},
+    44: {keyword: "IPv6-Frag", protocol: "Fragment Header for IPv6"},
+    45: {keyword: "IDRP", protocol: "Inter-Domain Routing Protocol"},
+    46: {keyword: "RSVP", protocol: "Reservation Protocol"},
+    47: {keyword: "GRE", protocol: "Generic Routing Encapsulation"},
+    48: {keyword: "DSR", protocol: "Dynamic Source Routing Protocol"},
+    49: {keyword: "BNA", protocol: "BNA"},
+    50: {keyword: "ESP", protocol: "Encap Security Payload"},
+    51: {keyword: "AH", protocol: "Authentication Header"},
+    52: {keyword: "I-NLSP", protocol: "Integrated Net Layer Security  TUBA"},
+    53: {keyword: "SWIPE (deprecated)", protocol: "IP with Encryption"},
+    54: {keyword: "NARP", protocol: "NBMA Address Resolution Protocol"},
+    55: {keyword: "MOBILE", protocol: "IP Mobility"},
+    56: {keyword: "TLSP", protocol: "Transport Layer Security Protocol using Kryptonet key management"},
+    57: {keyword: "SKIP", protocol: "SKIP"},
+    58: {keyword: "IPv6-ICMP", protocol: "ICMP for IPv6"},
+    59: {keyword: "IPv6-NoNxt", protocol: "No Next Header for IPv6"},
+    60: {keyword: "IPv6-Opts", protocol: "Destination Options for IPv6"},
+    61: {keyword: "", protocol: "any host internal protocol"},
+    62: {keyword: "CFTP", protocol: "CFTP"},
+    63: {keyword: "", protocol: "any local network"},
+    64: {keyword: "SAT-EXPAK", protocol: "SATNET and Backroom EXPAK"},
+    65: {keyword: "KRYPTOLAN", protocol: "Kryptolan"},
+    66: {keyword: "RVD", protocol: "MIT Remote Virtual Disk Protocol"},
+    67: {keyword: "IPPC", protocol: "Internet Pluribus Packet Core"},
+    68: {keyword: "", protocol: "any distributed file system"},
+    69: {keyword: "SAT-MON", protocol: "SATNET Monitoring"},
+    70: {keyword: "VISA", protocol: "VISA Protocol"},
+    71: {keyword: "IPCV", protocol: "Internet Packet Core Utility"},
+    72: {keyword: "CPNX", protocol: "Computer Protocol Network Executive"},
+    73: {keyword: "CPHB", protocol: "Computer Protocol Heart Beat"},
+    74: {keyword: "WSN", protocol: "Wang Span Network"},
+    75: {keyword: "PVP", protocol: "Packet Video Protocol"},
+    76: {keyword: "BR-SAT-MON", protocol: "Backroom SATNET Monitoring"},
+    77: {keyword: "SUN-ND", protocol: "SUN ND PROTOCOL-Temporary"},
+    78: {keyword: "WB-MON", protocol: "WIDEBAND Monitoring"},
+    79: {keyword: "WB-EXPAK", protocol: "WIDEBAND EXPAK"},
+    80: {keyword: "ISO-IP", protocol: "ISO Internet Protocol"},
+    81: {keyword: "VMTP", protocol: "VMTP"},
+    82: {keyword: "SECURE-VMTP", protocol: "SECURE-VMTP"},
+    83: {keyword: "VINES", protocol: "VINES"},
+    84: {keyword: "TTP", protocol: "Transaction Transport Protocol"},
+    85: {keyword: "NSFNET-IGP", protocol: "NSFNET-IGP"},
+    86: {keyword: "DGP", protocol: "Dissimilar Gateway Protocol"},
+    87: {keyword: "TCF", protocol: "TCF"},
+    88: {keyword: "EIGRP", protocol: "EIGRP"},
+    89: {keyword: "OSPFIGP", protocol: "OSPFIGP"},
+    90: {keyword: "Sprite-RPC", protocol: "Sprite RPC Protocol"},
+    91: {keyword: "LARP", protocol: "Locus Address Resolution Protocol"},
+    92: {keyword: "MTP", protocol: "Multicast Transport Protocol"},
+    93: {keyword: "AX.25", protocol: "AX.25 Frames"},
+    94: {keyword: "IPIP", protocol: "IP-within-IP Encapsulation Protocol"},
+    95: {keyword: "MICP (deprecated)", protocol: "Mobile Internetworking Control Pro."},
+    96: {keyword: "SCC-SP", protocol: "Semaphore Communications Sec. Pro."},
+    97: {keyword: "ETHERIP", protocol: "Ethernet-within-IP Encapsulation"},
+    98: {keyword: "ENCAP", protocol: "Encapsulation Header"},
+    99: {keyword: "", protocol: "any private encryption scheme"},
+    100: {keyword: "GMTP", protocol: "GMTP"},
+    101: {keyword: "IFMP", protocol: "Ipsilon Flow Management Protocol"},
+    102: {keyword: "PNNI", protocol: "PNNI over IP"},
+    103: {keyword: "PIM", protocol: "Protocol Independent Multicast"},
+    104: {keyword: "ARIS", protocol: "ARIS"},
+    105: {keyword: "SCPS", protocol: "SCPS"},
+    106: {keyword: "QNX", protocol: "QNX"},
+    107: {keyword: "A/N", protocol: "Active Networks"},
+    108: {keyword: "IPComp", protocol: "IP Payload Compression Protocol"},
+    109: {keyword: "SNP", protocol: "Sitara Networks Protocol"},
+    110: {keyword: "Compaq-Peer", protocol: "Compaq Peer Protocol"},
+    111: {keyword: "IPX-in-IP", protocol: "IPX in IP"},
+    112: {keyword: "VRRP", protocol: "Virtual Router Redundancy Protocol"},
+    113: {keyword: "PGM", protocol: "PGM Reliable Transport Protocol"},
+    114: {keyword: "", protocol: "any 0-hop protocol"},
+    115: {keyword: "L2TP", protocol: "Layer Two Tunneling Protocol"},
+    116: {keyword: "DDX", protocol: "D-II Data Exchange (DDX)"},
+    117: {keyword: "IATP", protocol: "Interactive Agent Transfer Protocol"},
+    118: {keyword: "STP", protocol: "Schedule Transfer Protocol"},
+    119: {keyword: "SRP", protocol: "SpectraLink Radio Protocol"},
+    120: {keyword: "UTI", protocol: "UTI"},
+    121: {keyword: "SMP", protocol: "Simple Message Protocol"},
+    122: {keyword: "SM (deprecated)", protocol: "Simple Multicast Protocol"},
+    123: {keyword: "PTP", protocol: "Performance Transparency Protocol"},
+    124: {keyword: "ISIS over IPv4", protocol: ""},
+    125: {keyword: "FIRE", protocol: ""},
+    126: {keyword: "CRTP", protocol: "Combat Radio Transport Protocol"},
+    127: {keyword: "CRUDP", protocol: "Combat Radio User Datagram"},
+    128: {keyword: "SSCOPMCE", protocol: ""},
+    129: {keyword: "IPLT", protocol: ""},
+    130: {keyword: "SPS", protocol: "Secure Packet Shield"},
+    131: {keyword: "PIPE", protocol: "Private IP Encapsulation within IP"},
+    132: {keyword: "SCTP", protocol: "Stream Control Transmission Protocol"},
+    133: {keyword: "FC", protocol: "Fibre Channel"},
+    134: {keyword: "RSVP-E2E-IGNORE", protocol: ""},
+    135: {keyword: "Mobility Header", protocol: ""},
+    136: {keyword: "UDPLite", protocol: ""},
+    137: {keyword: "MPLS-in-IP", protocol: ""},
+    138: {keyword: "manet", protocol: "MANET Protocols"},
+    139: {keyword: "HIP", protocol: "Host Identity Protocol"},
+    140: {keyword: "Shim6", protocol: "Shim6 Protocol"},
+    141: {keyword: "WESP", protocol: "Wrapped Encapsulating Security Payload"},
+    142: {keyword: "ROHC", protocol: "Robust Header Compression"},
+    253: {keyword: "", protocol: "Use for experimentation and testing"},
+    254: {keyword: "", protocol: "Use for experimentation and testing"},
+    255: {keyword: "Reserved", protocol: ""}
+};

+ 230 - 0
src/core/lib/LoremIpsum.mjs

@@ -0,0 +1,230 @@
+/**
+ * Lorem Ipsum generator.
+ *
+ * @author Klaxon [klaxon@veyr.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+/**
+ * Generate lorem ipsum paragraphs.
+ *
+ * @param {number} length
+ * @returns {string}
+ */
+export function GenerateParagraphs(length=3) {
+    const paragraphs = [];
+    while (paragraphs.length < length) {
+        const paragraphLength = getRandomLength(PARAGRAPH_LENGTH_MEAN, PARAGRAPH_LENGTH_STD_DEV);
+        const sentences = [];
+        while (sentences.length < paragraphLength) {
+            const sentenceLength = getRandomLength(SENTENCE_LENGTH_MEAN, SENTENCE_LENGTH_STD_DEV);
+            const sentence = getWords(sentenceLength);
+            sentences.push(formatSentence(sentence));
+        }
+        paragraphs.push(formatParagraph(sentences));
+    }
+    paragraphs[paragraphs.length-1] = paragraphs[paragraphs.length-1].slice(0, -2);
+    paragraphs[0] = replaceStart(paragraphs[0]);
+    return paragraphs.join("");
+}
+
+
+/**
+ * Generate lorem ipsum sentences.
+ *
+ * @param {number} length
+ * @returns {string}
+ */
+export function GenerateSentences(length=3) {
+    const sentences = [];
+    while (sentences.length < length) {
+        const sentenceLength = getRandomLength(SENTENCE_LENGTH_MEAN, SENTENCE_LENGTH_STD_DEV);
+        const sentence = getWords(sentenceLength);
+        sentences.push(formatSentence(sentence));
+    }
+    const paragraphs = sentencesToParagraphs(sentences);
+    return paragraphs.join("");
+}
+
+
+/**
+ * Generate lorem ipsum words.
+ *
+ * @param {number} length
+ * @returns {string}
+ */
+export function GenerateWords(length=3) {
+    const words = getWords(length);
+    const sentences = wordsToSentences(words);
+    const paragraphs = sentencesToParagraphs(sentences);
+    return paragraphs.join("");
+}
+
+
+/**
+ * Generate lorem ipsum bytes.
+ *
+ * @param {number} length
+ * @returns {string}
+ */
+export function GenerateBytes(length=3) {
+    const str = GenerateWords(length/3);
+    return str.slice(0, length);
+}
+
+
+/**
+ * Get array of randomly selected words from the lorem ipsum wordList.
+ *
+ * @param {number} length
+ * @returns {string[]}
+ * @private
+ */
+function getWords(length=3) {
+    const words = [];
+    let word;
+    let previousWord;
+    while (words.length < length){
+        do {
+            word = wordList[Math.floor(Math.random() * wordList.length)];
+        } while (previousWord === word);
+        words.push(word);
+        previousWord = word;
+    }
+    return words;
+}
+
+
+/**
+ * Convert an array of words into an array of sentences
+ *
+ * @param {string[]} words
+ * @returns {string[]}
+ * @private
+ */
+function wordsToSentences(words) {
+    const sentences = [];
+    while (words.length > 0) {
+        const sentenceLength = getRandomLength(SENTENCE_LENGTH_MEAN, SENTENCE_LENGTH_STD_DEV);
+        if (sentenceLength <= words.length) {
+            sentences.push(formatSentence(words.splice(0, sentenceLength)));
+        } else {
+            sentences.push(formatSentence(words.splice(0, words.length)));
+        }
+    }
+    return sentences;
+}
+
+
+/**
+ * Convert an array of sentences into an array of paragraphs
+ *
+ * @param {string[]} sentences
+ * @returns {string[]}
+ * @private
+ */
+function sentencesToParagraphs(sentences) {
+    const paragraphs = [];
+    while (sentences.length > 0) {
+        const paragraphLength = getRandomLength(PARAGRAPH_LENGTH_MEAN, PARAGRAPH_LENGTH_STD_DEV);
+        paragraphs.push(formatParagraph(sentences.splice(0, paragraphLength)));
+    }
+    paragraphs[paragraphs.length-1] = paragraphs[paragraphs.length-1].slice(0, -1);
+    paragraphs[0] = replaceStart(paragraphs[0]);
+    return paragraphs;
+}
+
+
+/**
+ * Format an array of words into a sentence.
+ *
+ * @param {string[]} words
+ * @returns {string}
+ * @private
+ */
+function formatSentence(words) {
+    // 0.35 chance of a  comma being added randomly to the sentence.
+    if (Math.random() < PROBABILITY_OF_A_COMMA) {
+        const pos = Math.round(Math.random()*(words.length-1));
+        words[pos] +=",";
+    }
+    let sentence = words.join(" ");
+    sentence = sentence.charAt(0).toUpperCase() + sentence.slice(1);
+    sentence += ".";
+    return sentence;
+}
+
+
+/**
+ * Format an array of sentences into a paragraph.
+ *
+ * @param {string[]} sentences
+ * @returns {string}
+ * @private
+ */
+function formatParagraph(sentences) {
+    let paragraph = sentences.join(" ");
+    paragraph += "\n\n";
+    return paragraph;
+}
+
+
+/**
+ * Get a random number based on a mean and standard deviation.
+ *
+ * @param {number} mean
+ * @param {number} stdDev
+ * @returns {number}
+ * @private
+ */
+function getRandomLength(mean, stdDev) {
+    let length;
+    do {
+        length =  Math.round((Math.random()*2-1)+(Math.random()*2-1)+(Math.random()*2-1)*stdDev+mean);
+    } while (length <= 0);
+    return length;
+}
+
+
+/**
+ * Replace first 5 words with "Lorem ipsum dolor sit amet"
+ *
+ * @param {string[]} str
+ * @returns {string[]}
+ * @private
+ */
+function replaceStart(str) {
+    let words = str.split(" ");
+    if (words.length > 5) {
+        words.splice(0, 5, "Lorem", "ipsum", "dolor", "sit", "amet");
+        return words.join(" ");
+    } else {
+        const lorem = ["Lorem", "ipsum", "dolor", "sit", "amet"];
+        words = lorem.slice(0, words.length);
+        str = words.join(" ");
+        str += ".";
+        return str;
+    }
+}
+
+
+const SENTENCE_LENGTH_MEAN = 15;
+const SENTENCE_LENGTH_STD_DEV = 9;
+const PARAGRAPH_LENGTH_MEAN = 5;
+const PARAGRAPH_LENGTH_STD_DEV = 2;
+const PROBABILITY_OF_A_COMMA = 0.35;
+
+const wordList = [
+    "ad", "adipisicing", "aliqua", "aliquip", "amet", "anim",
+    "aute", "cillum", "commodo", "consectetur", "consequat", "culpa",
+    "cupidatat", "deserunt", "do", "dolor", "dolore", "duis",
+    "ea", "eiusmod", "elit", "enim", "esse", "est",
+    "et", "eu", "ex", "excepteur", "exercitation", "fugiat",
+    "id", "in", "incididunt", "ipsum", "irure", "labore",
+    "laboris", "laborum", "Lorem", "magna", "minim", "mollit",
+    "nisi", "non", "nostrud", "nulla", "occaecat", "officia",
+    "pariatur", "proident", "qui", "quis", "reprehenderit", "sint",
+    "sit", "sunt", "tempor", "ullamco", "ut", "velit",
+    "veniam", "voluptate",
+];

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1283 - 0
src/core/lib/Magic.mjs


+ 117 - 0
src/core/lib/PGP.mjs

@@ -0,0 +1,117 @@
+/**
+ * PGP functions.
+ *
+ * @author tlwr [toby@toby.codes]
+ * @author Matt C [matt@artemisbot.uk]
+ * @author n1474335 [n1474335@gmail.com]
+ *
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ *
+ */
+
+import OperationError from "../errors/OperationError";
+import kbpgp from "kbpgp";
+import * as es6promisify from "es6-promisify";
+const promisify = es6promisify.default ? es6promisify.default.promisify : es6promisify.promisify;
+
+/**
+ * Progress callback
+ */
+export const ASP = kbpgp.ASP({
+    "progress_hook": info => {
+        let msg = "";
+
+        switch (info.what) {
+            case "guess":
+                msg = "Guessing a prime";
+                break;
+            case "fermat":
+                msg = "Factoring prime using Fermat's factorization method";
+                break;
+            case "mr":
+                msg = "Performing Miller-Rabin primality test";
+                break;
+            case "passed_mr":
+                msg = "Passed Miller-Rabin primality test";
+                break;
+            case "failed_mr":
+                msg = "Failed Miller-Rabin primality test";
+                break;
+            case "found":
+                msg = "Prime found";
+                break;
+            default:
+                msg = `Stage: ${info.what}`;
+        }
+
+        if (ENVIRONMENT_IS_WORKER())
+            self.sendStatusMessage(msg);
+    }
+});
+
+/**
+ * Get size of subkey
+ *
+ * @param {number} keySize
+ * @returns {number}
+ */
+export function getSubkeySize(keySize) {
+    return {
+        1024: 1024,
+        2048: 1024,
+        4096: 2048,
+        256:   256,
+        384:   256,
+    }[keySize];
+}
+
+/**
+* Import private key and unlock if necessary
+*
+* @param {string} privateKey
+* @param {string} [passphrase]
+* @returns {Object}
+*/
+export async function importPrivateKey(privateKey, passphrase) {
+    try {
+        const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
+            armored: privateKey,
+            opts: {
+                "no_check_keys": true
+            }
+        });
+        if (key.is_pgp_locked()) {
+            if (passphrase) {
+                await promisify(key.unlock_pgp.bind(key))({
+                    passphrase
+                });
+            } else {
+                throw new OperationError("Did not provide passphrase with locked private key.");
+            }
+        }
+        return key;
+    } catch (err) {
+        throw new OperationError(`Could not import private key: ${err}`);
+    }
+}
+
+/**
+ * Import public key
+ *
+ * @param {string} publicKey
+ * @returns {Object}
+ */
+export async function importPublicKey (publicKey) {
+    try {
+        const key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
+            armored: publicKey,
+            opts: {
+                "no_check_keys": true
+            }
+        });
+        return key;
+    } catch (err) {
+        throw new OperationError(`Could not import public key: ${err}`);
+    }
+}

+ 72 - 0
src/core/lib/PublicKey.mjs

@@ -0,0 +1,72 @@
+/**
+ * Public key resources.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import { toHex, fromHex } from "./Hex";
+
+/**
+ * Formats Distinguished Name (DN) strings.
+ *
+ * @param {string} dnStr
+ * @param {number} indent
+ * @returns {string}
+ */
+export function formatDnStr (dnStr, indent) {
+    const fields = dnStr.substr(1).replace(/([^\\])\//g, "$1$1/").split(/[^\\]\//);
+    let output = "",
+        maxKeyLen = 0,
+        key,
+        value,
+        i,
+        str;
+
+    for (i = 0; i < fields.length; i++) {
+        if (!fields[i].length) continue;
+
+        key = fields[i].split("=")[0];
+
+        maxKeyLen = key.length > maxKeyLen ? key.length : maxKeyLen;
+    }
+
+    for (i = 0; i < fields.length; i++) {
+        if (!fields[i].length) continue;
+
+        key = fields[i].split("=")[0];
+        value = fields[i].split("=")[1];
+        str = key.padEnd(maxKeyLen, " ") + " = " + value + "\n";
+
+        output += str.padStart(indent + str.length, " ");
+    }
+
+    return output.slice(0, -1);
+}
+
+
+/**
+ * Formats byte strings by adding line breaks and delimiters.
+ *
+ * @param {string} byteStr
+ * @param {number} length - Line width
+ * @param {number} indent
+ * @returns {string}
+ */
+export function formatByteStr (byteStr, length, indent) {
+    byteStr = toHex(fromHex(byteStr), ":");
+    length = length * 3;
+    let output = "";
+
+    for (let i = 0; i < byteStr.length; i += length) {
+        const str = byteStr.slice(i, i + length) + "\n";
+        if (i === 0) {
+            output += str;
+        } else {
+            output += str.padStart(indent + str.length, " ");
+        }
+    }
+
+    return output.slice(0, output.length-1);
+}

+ 103 - 0
src/core/lib/Rotate.mjs

@@ -0,0 +1,103 @@
+/**
+ * Bit rotation functions.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ * @todo Support for UTF16
+ */
+
+
+/**
+ * Runs rotation operations across the input data.
+ *
+ * @param {byteArray} data
+ * @param {number} amount
+ * @param {function} algo - The rotation operation to carry out
+ * @returns {byteArray}
+ */
+export function rot(data, amount, algo) {
+    const result = [];
+    for (let i = 0; i < data.length; i++) {
+        let b = data[i];
+        for (let j = 0; j < amount; j++) {
+            b = algo(b);
+        }
+        result.push(b);
+    }
+    return result;
+}
+
+
+/**
+ * Rotate right bitwise op.
+ *
+ * @param {byte} b
+ * @returns {byte}
+ */
+export function rotr(b) {
+    const bit = (b & 1) << 7;
+    return (b >> 1) | bit;
+}
+
+/**
+ * Rotate left bitwise op.
+ *
+ * @param {byte} b
+ * @returns {byte}
+ */
+export function rotl(b) {
+    const bit = (b >> 7) & 1;
+    return ((b << 1) | bit) & 0xFF;
+}
+
+
+/**
+ * Rotates a byte array to the right by a specific amount as a whole, so that bits are wrapped
+ * from the end of the array to the beginning.
+ *
+ * @param {byteArray} data
+ * @param {number} amount
+ * @returns {byteArray}
+ */
+export function rotrCarry(data, amount) {
+    const result = [];
+    let carryBits = 0,
+        newByte;
+
+    amount = amount % 8;
+    for (let i = 0; i < data.length; i++) {
+        const oldByte = data[i] >>> 0;
+        newByte = (oldByte >> amount) | carryBits;
+        carryBits = (oldByte & (Math.pow(2, amount)-1)) << (8-amount);
+        result.push(newByte);
+    }
+    result[0] |= carryBits;
+    return result;
+}
+
+
+/**
+ * Rotates a byte array to the left by a specific amount as a whole, so that bits are wrapped
+ * from the beginning of the array to the end.
+ *
+ * @param {byteArray} data
+ * @param {number} amount
+ * @returns {byteArray}
+ */
+export function rotlCarry(data, amount) {
+    const result = [];
+    let carryBits = 0,
+        newByte;
+
+    amount = amount % 8;
+    for (let i = data.length-1; i >= 0; i--) {
+        const oldByte = data[i];
+        newByte = ((oldByte << amount) | carryBits) & 0xFF;
+        carryBits = (oldByte >> (8-amount)) & (Math.pow(2, amount)-1);
+        result[i] = (newByte);
+    }
+    result[data.length-1] = result[data.length-1] | carryBits;
+    return result;
+}

+ 78 - 0
src/core/lib/TLVParser.mjs

@@ -0,0 +1,78 @@
+/**
+ * Parser for Type-length-value data.
+ *
+ * @author gchq77703 []
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+const defaults = {
+    location: 0,
+    bytesInLength: 1,
+    basicEncodingRules: false
+};
+
+/**
+ * TLVParser library
+ */
+export default class TLVParser {
+
+    /**
+     * TLVParser constructor
+     *
+     * @param {byteArray} input
+     * @param {Object} options
+     */
+    constructor(input, options) {
+        this.input = input;
+        Object.assign(this, defaults, options);
+    }
+
+    /**
+     * @returns {number}
+     */
+    getLength() {
+        if (this.basicEncodingRules) {
+            const bit = this.input[this.location];
+            if (bit & 0x80) {
+                this.bytesInLength = bit & ~0x80;
+            } else {
+                this.location++;
+                return bit & ~0x80;
+            }
+        }
+
+        let length = 0;
+
+        for (let i = 0; i < this.bytesInLength; i++) {
+            length += this.input[this.location] * Math.pow(Math.pow(2, 8), i);
+            this.location++;
+        }
+
+        return length;
+    }
+
+    /**
+     * @param {number} length
+     * @returns {number[]}
+     */
+    getValue(length) {
+        const value = [];
+
+        for (let i = 0; i < length; i++) {
+            if (this.location > this.input.length) return value;
+            value.push(this.input[this.location]);
+            this.location++;
+        }
+
+        return value;
+    }
+
+    /**
+     * @returns {boolean}
+     */
+    atEnd() {
+        return this.input.length <= this.location;
+    }
+}

+ 19 - 0
src/core/lib/Zlib.mjs

@@ -0,0 +1,19 @@
+/**
+ * Zlib exports.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min";
+
+const Zlib = zlibAndGzip.Zlib;
+
+export const COMPRESSION_TYPE = ["Dynamic Huffman Coding", "Fixed Huffman Coding", "None (Store)"];
+export const INFLATE_BUFFER_TYPE = ["Adaptive", "Block"];
+export const ZLIB_COMPRESSION_TYPE_LOOKUP = {
+    "Fixed Huffman Coding":   Zlib.Deflate.CompressionType.FIXED,
+    "Dynamic Huffman Coding": Zlib.Deflate.CompressionType.DYNAMIC,
+    "None (Store)":           Zlib.Deflate.CompressionType.NONE,
+};

+ 0 - 186
src/core/lib/canvascomponents.js

@@ -1,186 +0,0 @@
-"use strict";
-
-/**
- * Various components for drawing diagrams on an HTML5 canvas.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @constant
- * @namespace
- */
-const CanvasComponents = {
-
-    drawLine: function(ctx, startX, startY, endX, endY) {
-        ctx.beginPath();
-        ctx.moveTo(startX, startY);
-        ctx.lineTo(endX, endY);
-        ctx.closePath();
-        ctx.stroke();
-    },
-
-    drawBarChart: function(canvas, scores, xAxisLabel, yAxisLabel, numXLabels, numYLabels, fontSize) {
-        fontSize = fontSize || 15;
-        if (!numXLabels || numXLabels > Math.round(canvas.width / 50)) {
-            numXLabels = Math.round(canvas.width / 50);
-        }
-        if (!numYLabels || numYLabels > Math.round(canvas.width / 50)) {
-            numYLabels = Math.round(canvas.height / 50);
-        }
-
-        // Graph properties
-        var ctx = canvas.getContext("2d"),
-            leftPadding = canvas.width * 0.08,
-            rightPadding = canvas.width * 0.03,
-            topPadding = canvas.height * 0.08,
-            bottomPadding = canvas.height * 0.15,
-            graphHeight = canvas.height - topPadding - bottomPadding,
-            graphWidth = canvas.width - leftPadding - rightPadding,
-            base = topPadding + graphHeight,
-            ceil = topPadding;
-
-        ctx.font = fontSize + "px Arial";
-
-        // Draw axis
-        ctx.lineWidth = "1.0";
-        ctx.strokeStyle = "#444";
-        CanvasComponents.drawLine(ctx, leftPadding, base, graphWidth + leftPadding, base); // x
-        CanvasComponents.drawLine(ctx, leftPadding, base, leftPadding, ceil); // y
-
-        // Bar properties
-        var barPadding = graphWidth * 0.003,
-            barWidth = (graphWidth - (barPadding * scores.length)) / scores.length,
-            currX = leftPadding + barPadding,
-            max = Math.max.apply(Math, scores);
-
-        // Draw bars
-        ctx.fillStyle = "green";
-        for (var i = 0; i < scores.length; i++) {
-            var h = scores[i] / max * graphHeight;
-            ctx.fillRect(currX, base - h, barWidth, h);
-            currX += barWidth + barPadding;
-        }
-
-        // Mark x axis
-        ctx.fillStyle = "black";
-        ctx.textAlign = "center";
-        currX = leftPadding + barPadding;
-        if (numXLabels >= scores.length) {
-            // Mark every score
-            for (i = 0; i <= scores.length; i++) {
-                ctx.fillText(i, currX, base + (bottomPadding * 0.3));
-                currX += barWidth + barPadding;
-            }
-        } else {
-            // Mark some scores
-            for (i = 0; i <= numXLabels; i++) {
-                var val = Math.ceil((scores.length / numXLabels) * i);
-                currX = (graphWidth / numXLabels) * i + leftPadding;
-                ctx.fillText(val, currX, base + (bottomPadding * 0.3));
-            }
-        }
-
-        // Mark y axis
-        ctx.textAlign = "right";
-        var currY;
-        if (numYLabels >= max) {
-            // Mark every increment
-            for (i = 0; i <= max; i++) {
-                currY = base - (i / max * graphHeight) + fontSize / 3;
-                ctx.fillText(i, leftPadding * 0.8, currY);
-            }
-        } else {
-            // Mark some increments
-            for (i = 0; i <= numYLabels; i++) {
-                val = Math.ceil((max / numYLabels) * i);
-                currY = base - (val / max * graphHeight) + fontSize / 3;
-                ctx.fillText(val, leftPadding * 0.8, currY);
-            }
-        }
-
-        // Label x axis
-        if (xAxisLabel) {
-            ctx.textAlign = "center";
-            ctx.fillText(xAxisLabel, graphWidth / 2 + leftPadding, base + bottomPadding * 0.8);
-        }
-
-        // Label y axis
-        if (yAxisLabel) {
-            ctx.save();
-            var x = leftPadding * 0.3,
-                y = graphHeight / 2 + topPadding;
-            ctx.translate(x, y);
-            ctx.rotate(-Math.PI / 2);
-            ctx.textAlign = "center";
-            ctx.fillText(yAxisLabel, 0, 0);
-            ctx.restore();
-        }
-    },
-
-    drawScaleBar: function(canvas, score, max, markings) {
-        // Bar properties
-        var ctx = canvas.getContext("2d"),
-            leftPadding = canvas.width * 0.01,
-            rightPadding = canvas.width * 0.01,
-            topPadding = canvas.height * 0.1,
-            bottomPadding = canvas.height * 0.3,
-            barHeight = canvas.height - topPadding - bottomPadding,
-            barWidth = canvas.width - leftPadding - rightPadding;
-
-        // Scale properties
-        var proportion = score / max;
-
-        // Draw bar outline
-        ctx.strokeRect(leftPadding, topPadding, barWidth, barHeight);
-
-        // Shade in up to proportion
-        var grad = ctx.createLinearGradient(leftPadding, 0, barWidth + leftPadding, 0);
-        grad.addColorStop(0, "green");
-        grad.addColorStop(0.5, "gold");
-        grad.addColorStop(1, "red");
-        ctx.fillStyle = grad;
-        ctx.fillRect(leftPadding, topPadding, barWidth * proportion, barHeight);
-
-        // Add markings
-        var x0, y0, x1, y1;
-        ctx.fillStyle = "black";
-        ctx.textAlign = "center";
-        ctx.font = "13px Arial";
-        for (var i = 0; i < markings.length; i++) {
-            // Draw min line down
-            x0 = barWidth / max * markings[i].min + leftPadding;
-            y0 = topPadding + barHeight + (bottomPadding * 0.1);
-            x1 = x0;
-            y1 = topPadding + barHeight + (bottomPadding * 0.3);
-            CanvasComponents.drawLine(ctx, x0, y0, x1, y1);
-
-            // Draw max line down
-            x0 = barWidth / max * markings[i].max + leftPadding;
-            x1 = x0;
-            CanvasComponents.drawLine(ctx, x0, y0, x1, y1);
-
-            // Join min and max lines
-            x0 = barWidth / max * markings[i].min + leftPadding;
-            y0 = topPadding + barHeight + (bottomPadding * 0.3);
-            x1 = barWidth / max * markings[i].max + leftPadding;
-            y1 = y0;
-            CanvasComponents.drawLine(ctx, x0, y0, x1, y1);
-
-            // Add label
-            if (markings[i].max >= max * 0.9) {
-                ctx.textAlign = "right";
-                x0 = x1;
-            } else if (markings[i].max <= max * 0.1) {
-                ctx.textAlign = "left";
-            } else {
-                x0 = x0 + (x1 - x0) / 2;
-            }
-            y0 = topPadding + barHeight + (bottomPadding * 0.8);
-            ctx.fillText(markings[i].label, x0, y0);
-        }
-    },
-
-};
-
-export default CanvasComponents;

+ 0 - 25821
src/core/lib/uas_parser.js

@@ -1,25821 +0,0 @@
-/** @license
-========================================================================
-  UAS Parser
-  Copyright (c) 2013 Nick Muerdter
-
-  MIT License
-
-  Permission is hereby granted, free of charge, to any person obtaining
-  a copy of this software and associated documentation files (the
-  "Software"), to deal in the Software without restriction, including
-  without limitation the rights to use, copy, modify, merge, publish,
-  distribute, sublicense, and/or sell copies of the Software, and to
-  permit persons to whom the Software is furnished to do so, subject to
-  the following conditions:
-
-  The above copyright notice and this permission notice shall be
-  included in all copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-import Utils from "../Utils.js";
-
-const UAS_parser = {
-	
-	parse: function (userAgent) {
-		var result = {
-			type: 'unknown',
-			uaFamily: 'unknown',
-			uaName: 'unknown',
-			uaUrl: 'unknown',
-			uaCompany: 'unknown',
-			uaCompanyUrl: 'unknown',
-			uaIcon: 'unknown.png',
-			uaInfoUrl: 'unknown',
-			osFamily: 'unknown',
-			osName: 'unknown',
-			osUrl: 'unknown',
-			osCompany: 'unknown',
-			osCompanyUrl: 'unknown',
-			osIcon: 'unknown.png',
-			deviceType: 'unknown',
-			deviceIcon: 'unknown.png',
-			deviceInfoUrl: 'unknown'
-		};
-		for (var i = 0; i < UAS_cache.robots.order.length; i++) {
-			var robotId = UAS_cache.robots.order[i];
-			var robot = UAS_cache.robots[robotId];
-			if (robot.userAgent === userAgent) {
-				result.type = 'Robot';
-				result = Utils.extend(result, robot.metadata);
-				Utils.extend(result, UAS_cache.device['1']);
-				return result;
-			}
-		}
-		var osId;
-		for (i = 0; i < UAS_cache.browserReg.order.length; i++) {
-			var browserRegId = UAS_cache.browserReg.order[i];
-			var browserReg = UAS_cache.browserReg[browserRegId];
-			var matches = userAgent.match(browserReg.regexp);
-			if (matches) {
-				var browser = UAS_cache.browser[browserReg.browserId];
-				if (browser) {
-					result = Utils.extend(result, browser.metadata);
-					var browserType = UAS_cache.browserType[browser.typeId];
-					if (browserType) {
-						result.type = browserType;
-					}
-					result.uaName = browser.metadata.uaFamily;
-					if (matches[1]) {
-						result.uaName += ' ' + matches[1];
-					}
-				}
-				osId = UAS_cache.browserOs[browserReg.browserId];
-				break;
-			}
-		}
-		if (!osId) {
-			for (i = 0; i < UAS_cache.osReg.order.length; i++) {
-				var osRegId = UAS_cache.osReg.order[i];
-				var osReg = UAS_cache.osReg[osRegId];
-				if (osReg.regexp.test(userAgent)) {
-					osId = osReg.osId;
-					break;
-				}
-			}
-		}
-		if (osId) {
-			var os = UAS_cache.os[osId];
-			if (os) {
-				result = Utils.extend(result, os);
-			}
-		}
-		var device;
-		if (result.type === 'Robot') {
-			device = UAS_cache.device['1'];
-		} else {
-			for (i = 0; i < UAS_cache.deviceReg.order.length; i++) {
-				var deviceRegId = UAS_cache.deviceReg.order[i];
-				var deviceReg = UAS_cache.deviceReg[deviceRegId];
-				if (deviceReg.regexp.test(userAgent)) {
-					device = UAS_cache.device[deviceReg.deviceId];
-					break;
-				}
-			}
-		}
-		if (!device) {
-			if ([
-					'Other',
-					'Library',
-					'Validator',
-					'Useragent Anonymizer'
-				].indexOf(result.type) !== -1) {
-				device = UAS_cache.device['1'];
-			} else if ([
-					'Mobile Browser',
-					'Wap Browser'
-				].indexOf(result.type) !== -1) {
-				device = UAS_cache.device['3'];
-			} else {
-				device = UAS_cache.device['2'];
-			}
-		}
-		if (device) {
-			result = Utils.extend(result, device);
-		}
-		return result;
-	}
-};
-
-const UAS_cache = {
-	version: '20131025-01',
-	robots: {
-		'3': {
-			userAgent: 'msnbot/1.0 (+http://search.msn.com/msnbot.htm)',
-			metadata: {
-				uaFamily: 'MSNBot',
-				uaName: 'MSNBot/1.0',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSNBot'
-			}
-		},
-		'4': {
-			userAgent: 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)',
-			metadata: {
-				uaFamily: 'Yahoo!',
-				uaName: 'Yahoo! Slurp',
-				uaUrl: 'http://help.yahoo.com/help/us/ysearch/slurp',
-				uaCompany: 'Yahoo! Inc.',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo!'
-			}
-		},
-		'5': {
-			userAgent: 'Jyxobot/1',
-			metadata: {
-				uaFamily: 'Jyxobot',
-				uaName: 'Jyxobot',
-				uaUrl: '',
-				uaCompany: 'Jyxo s.r.o.',
-				uaCompanyUrl: 'http://jyxo.cz/',
-				uaIcon: 'bot_Jyxobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Jyxobot'
-			}
-		},
-		'9': {
-			userAgent: 'Scooter/3.3',
-			metadata: {
-				uaFamily: 'Scooter',
-				uaName: 'Scooter/3.3',
-				uaUrl: '',
-				uaCompany: 'AltaVista',
-				uaCompanyUrl: 'http://www.altavista.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Scooter'
-			}
-		},
-		'14': {
-			userAgent: 'Baiduspider+(+http://www.baidu.com/search/spider.htm)',
-			metadata: {
-				uaFamily: 'Baiduspider',
-				uaName: 'Baiduspider',
-				uaUrl: 'http://www.baidu.com/search/spider.htm',
-				uaCompany: 'Baidu',
-				uaCompanyUrl: 'http://www.baidu.com/',
-				uaIcon: 'bot_baiduspider.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Baiduspider'
-			}
-		},
-		'20': {
-			userAgent: 'lmspider (lmspider@scansoft.com)',
-			metadata: {
-				uaFamily: 'lmspider',
-				uaName: 'lmspider',
-				uaUrl: 'http://www.nuance.com/',
-				uaCompany: 'Nuance Communications, Inc.',
-				uaCompanyUrl: 'http://www.nuance.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=lmspider'
-			}
-		},
-		'25': {
-			userAgent: 'Googlebot-Image/1.0',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot-Image/1.0',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1061943',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'31': {
-			userAgent: 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot/2.1',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1061943',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'32': {
-			userAgent: 'ConveraMultiMediaCrawler/0.1 (+http://www.authoritativeweb.com/crawl)',
-			metadata: {
-				uaFamily: 'ConveraCrawler',
-				uaName: 'ConveraMultiMediaCrawler/0.1',
-				uaUrl: 'http://www.authoritativeweb.com/crawl',
-				uaCompany: 'Convera Corporation',
-				uaCompanyUrl: 'http://www.authoritativeweb.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ConveraCrawler'
-			}
-		},
-		'37': {
-			userAgent: 'Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)',
-			metadata: {
-				uaFamily: 'Ask Jeeves/Teoma',
-				uaName: 'Ask Jeeves/Teoma - b',
-				uaUrl: 'http://about.ask.com/en/docs/about/webmasters.shtml',
-				uaCompany: 'Ask Jeeves Inc.',
-				uaCompanyUrl: 'http://about.ask.com/en/docs/about/index.shtml',
-				uaIcon: 'bot_AskJeeves.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ask Jeeves/Teoma'
-			}
-		},
-		'38': {
-			userAgent: 'NG/2.0',
-			metadata: {
-				uaFamily: 'NG',
-				uaName: 'NG/2.0',
-				uaUrl: '',
-				uaCompany: 'Exalead',
-				uaCompanyUrl: 'http://exalead.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NG'
-			}
-		},
-		'40': {
-			userAgent: 'TutorGigBot/1.5 ( +http://www.tutorgig.info )',
-			metadata: {
-				uaFamily: 'TutorGigBot',
-				uaName: 'TutorGigBot',
-				uaUrl: 'http://www.tutorgig.com/help.html',
-				uaCompany: 'TutorGig',
-				uaCompanyUrl: 'http://www.tutorgig.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TutorGigBot'
-			}
-		},
-		'43': {
-			userAgent: 'ZACATEK_CZ_BOT (www.zacatek.cz)',
-			metadata: {
-				uaFamily: 'ZACATEK_CZ',
-				uaName: 'ZACATEK_CZ_BOT',
-				uaUrl: 'http://www.zacatek.cz/',
-				uaCompany: 'webprovider - Adam Haken',
-				uaCompanyUrl: 'http://www.webprovider.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZACATEK_CZ'
-			}
-		},
-		'45': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; Girafabot; girafabot at girafa dot com; http://www.girafa.com)',
-			metadata: {
-				uaFamily: 'Girafabot',
-				uaName: 'Girafabot',
-				uaUrl: '',
-				uaCompany: 'Girafa Inc.',
-				uaCompanyUrl: 'http://www.girafa.com/',
-				uaIcon: 'bot_girafabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Girafabot'
-			}
-		},
-		'47': {
-			userAgent: 'FAST MetaWeb Crawler (helpdesk at fastsearch dot com)',
-			metadata: {
-				uaFamily: 'FAST MetaWeb Crawler',
-				uaName: 'FAST MetaWeb Crawler',
-				uaUrl: 'http://www.fast.no/glossary.aspx?m=48&amid=415',
-				uaCompany: 'Fast Search & Transfer',
-				uaCompanyUrl: 'http://www.fastsearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FAST MetaWeb Crawler'
-			}
-		},
-		'56': {
-			userAgent: 'psbot/0.1 (+http://www.picsearch.com/bot.html)',
-			metadata: {
-				uaFamily: 'psbot',
-				uaName: 'psbot/0.1',
-				uaUrl: 'http://www.picsearch.com/bot.html',
-				uaCompany: 'picsearch.com',
-				uaCompanyUrl: 'http://www.picsearch.com/',
-				uaIcon: 'bot_psbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=psbot'
-			}
-		},
-		'76': {
-			userAgent: 'City4you/1.3 Cesky (+http://www.city4you.pl)',
-			metadata: {
-				uaFamily: 'City4you',
-				uaName: 'City4you/1.3 Cesky',
-				uaUrl: '',
-				uaCompany: 'city4you',
-				uaCompanyUrl: 'http://www.city4you.pl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=City4you'
-			}
-		},
-		'80': {
-			userAgent: 'ConveraCrawler/0.9d (+http://www.authoritativeweb.com/crawl)',
-			metadata: {
-				uaFamily: 'ConveraCrawler',
-				uaName: 'ConveraCrawler 0.9d',
-				uaUrl: 'http://www.authoritativeweb.com/crawl',
-				uaCompany: 'Convera Corporation',
-				uaCompanyUrl: 'http://www.authoritativeweb.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ConveraCrawler'
-			}
-		},
-		'81': {
-			userAgent: 'IlTrovatore-Setaccio/1.2 (It search engine; http://www.iltrovatore.it/bot.html; bot@iltrovatore.it)',
-			metadata: {
-				uaFamily: 'IlTrovatore-Setaccio',
-				uaName: 'IlTrovatore-Setaccio/1.2',
-				uaUrl: 'http://www.iltrovatore.it/bot.html',
-				uaCompany: 'Il Trovatore',
-				uaCompanyUrl: 'http://www.iltrovatore.it/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IlTrovatore-Setaccio'
-			}
-		},
-		'82': {
-			userAgent: 'NutchCVS/0.8-dev (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCSV/0.8-dev',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'83': {
-			userAgent: 'ksibot/5.2m (+http://ego.ms.mff.cuni.cz/)',
-			metadata: {
-				uaFamily: 'ksibot',
-				uaName: 'ksibot/5.2m',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ksibot'
-			}
-		},
-		'84': {
-			userAgent: 'NutchCVS/0.06-dev (http://www.nutch.org/docs/en/bot.html; rhwarren+nutch@uwaterloo.ca)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.06-dev at uwaterloo.ca',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'85': {
-			userAgent: 'InfociousBot (+http://corp.infocious.com/tech_crawler.php)',
-			metadata: {
-				uaFamily: 'InfociousBot',
-				uaName: 'InfociousBot b',
-				uaUrl: 'http://corp.infocious.com/tech_craw.php',
-				uaCompany: 'Infocious Inc.',
-				uaCompanyUrl: 'http://corp.infocious.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=InfociousBot'
-			}
-		},
-		'86': {
-			userAgent: 'NutchCVS/0.7 (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.7',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'88': {
-			userAgent: 'SBIder/0.7 (SBIder; http://www.sitesell.com/sbider.html; http://support.sitesell.com/contact-support.html)',
-			metadata: {
-				uaFamily: 'SBIder',
-				uaName: 'SBIder/0.7',
-				uaUrl: 'http://www.sitesell.com/sbider.html',
-				uaCompany: 'SiteSell',
-				uaCompanyUrl: 'http://www.sitesell.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SBIder'
-			}
-		},
-		'89': {
-			userAgent: 'appie 1.1 (www.walhello.com)',
-			metadata: {
-				uaFamily: 'aippie',
-				uaName: 'appie 1.1',
-				uaUrl: 'http://www.walhello.com/aboutgl.html',
-				uaCompany: 'Walhello.com',
-				uaCompanyUrl: 'http://www.walhello.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aippie'
-			}
-		},
-		'90': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler   [bc22]',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden bc22',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'93': {
-			userAgent: 'OmniExplorer_Bot/4.02 (+http://www.omni-explorer.com) WorldIndexer',
-			metadata: {
-				uaFamily: 'OmniExplorer_Bot',
-				uaName: 'OmniExplorer_Bot/4.02',
-				uaUrl: 'http://www.omni-explorer.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OmniExplorer_Bot'
-			}
-		},
-		'96': {
-			userAgent: 'Szukankobot /1.0 (+http://www.szukanko.pl/addurl.php)',
-			metadata: {
-				uaFamily: 'Szukankobot',
-				uaName: 'Szukankobot /1.0',
-				uaUrl: 'http://www.szukanko.pl/',
-				uaCompany: 'szukanko.pl',
-				uaCompanyUrl: 'http://www.szukanko.pl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Szukankobot'
-			}
-		},
-		'100': {
-			userAgent: 'NutchOSU-VLIB/0.7 (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchOSU-VLIB/0.7',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'101': {
-			userAgent: 'snap.com beta crawler v0',
-			metadata: {
-				uaFamily: 'snap.com',
-				uaName: 'snap.com beta crawler v0',
-				uaUrl: '',
-				uaCompany: ' Idealab',
-				uaCompanyUrl: 'http://www.idealab.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=snap.com'
-			}
-		},
-		'109': {
-			userAgent: 'Mozilla/5.0 (compatible; OnetSzukaj/5.0; +http://szukaj.onet.pl)',
-			metadata: {
-				uaFamily: 'OnetSzukaj',
-				uaName: 'OnetSzukaj/5.0',
-				uaUrl: '',
-				uaCompany: 'Onet.pl',
-				uaCompanyUrl: 'http://www.onet.pl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OnetSzukaj'
-			}
-		},
-		'114': {
-			userAgent: 'Metaspinner/0.01 (Metaspinner; http://www.meta-spinner.de/; support@meta-spinner.de/)',
-			metadata: {
-				uaFamily: 'Metaspinner/0.01',
-				uaName: 'Metaspinner/0.01',
-				uaUrl: 'http://www.meta-spinner.de/',
-				uaCompany: 'metaspinnner media GmbH',
-				uaCompanyUrl: 'http://www.metaspinner-media.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Metaspinner/0.01'
-			}
-		},
-		'116': {
-			userAgent: 'OmniExplorer_Bot/4.06 (+http://www.omni-explorer.com) WorldIndexer',
-			metadata: {
-				uaFamily: 'OmniExplorer_Bot',
-				uaName: 'OmniExplorer_Bot/4.06',
-				uaUrl: 'http://www.omni-explorer.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OmniExplorer_Bot'
-			}
-		},
-		'117': {
-			userAgent: 'e-SocietyRobot(http://www.yama.info.waseda.ac.jp/~yamana/es/)',
-			metadata: {
-				uaFamily: 'e-SocietyRobot',
-				uaName: 'e-SocietyRobot',
-				uaUrl: 'http://www.yama.info.waseda.ac.jp/~yamana/es',
-				uaCompany: 'Waseda University Yamana Laboratory',
-				uaCompanyUrl: 'http://www.yama.info.waseda.ac.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=e-SocietyRobot'
-			}
-		},
-		'118': {
-			userAgent: 'Findexa Crawler (http://www.findexa.no/gulesider/article26548.ece)',
-			metadata: {
-				uaFamily: 'Findexa Crawler',
-				uaName: 'Findexa Crawler',
-				uaUrl: 'http://www.findexa.no/gulesider/article26548.ece',
-				uaCompany: 'Findexa AS',
-				uaCompanyUrl: 'http://www.findexa.no/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Findexa Crawler'
-			}
-		},
-		'120': {
-			userAgent: 'InternetArchive/0.8-dev (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'InternetArchive/0.8-dev',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'123': {
-			userAgent: 'SBIder/0.8-dev (SBIder; http://www.sitesell.com/sbider.html; http://support.sitesell.com/contact-support.html)',
-			metadata: {
-				uaFamily: 'SBIder',
-				uaName: 'SBIder/0.8dev',
-				uaUrl: 'http://www.sitesell.com/sbider.html',
-				uaCompany: 'SiteSell',
-				uaCompanyUrl: 'http://www.sitesell.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SBIder'
-			}
-		},
-		'124': {
-			userAgent: 'ichiro/1.0 (ichiro@nttr.co.jp)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/1.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'125': {
-			userAgent: 'miniRank/1.2 (miniRank; http://minirank.com/; MiniRank)',
-			metadata: {
-				uaFamily: 'miniRank',
-				uaName: 'miniRank/1.2',
-				uaUrl: 'http://www.minirank.com/',
-				uaCompany: 'TitaniumLine.com',
-				uaCompanyUrl: 'http://titaniumline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=miniRank'
-			}
-		},
-		'128': {
-			userAgent: 'Amfibibot/0.07 (Amfibi Robot; http://www.amfibi.com; agent@amfibi.com)',
-			metadata: {
-				uaFamily: 'Amfibibot',
-				uaName: 'Amfibibot/0.07',
-				uaUrl: 'http://www.amfibi.com/',
-				uaCompany: 'Barcelona Internet Telecom',
-				uaCompanyUrl: 'http://www.bcntelecom.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Amfibibot'
-			}
-		},
-		'130': {
-			userAgent: 'LinkWalker',
-			metadata: {
-				uaFamily: 'LinkWalker',
-				uaName: 'LinkWalker',
-				uaUrl: '',
-				uaCompany: 'SEVENtwentyfour Inc.',
-				uaCompanyUrl: 'http://www.seventwentyfour.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LinkWalker'
-			}
-		},
-		'131': {
-			userAgent: 'Mozilla/2.0 (compatible; Ask Jeeves/Teoma)',
-			metadata: {
-				uaFamily: 'Ask Jeeves/Teoma',
-				uaName: 'Ask Jeeves/Teoma',
-				uaUrl: 'http://about.ask.com/en/docs/about/webmasters.shtml',
-				uaCompany: 'Ask Jeeves Inc.',
-				uaCompanyUrl: 'http://about.ask.com/en/docs/about/index.shtml',
-				uaIcon: 'bot_AskJeeves.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ask Jeeves/Teoma'
-			}
-		},
-		'132': {
-			userAgent: 'StackRambler/2.0 (MSIE incompatible)',
-			metadata: {
-				uaFamily: 'StackRambler',
-				uaName: 'StackRambler/2.0',
-				uaUrl: 'http://www.rambler.ru/doc/robots.shtml',
-				uaCompany: 'Rambler Media Group',
-				uaCompanyUrl: 'http://ramblermedia.com/',
-				uaIcon: 'bot_stackrambler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=StackRambler'
-			}
-		},
-		'133': {
-			userAgent: 'NutchCVS/0.7.1 (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.7.1',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'135': {
-			userAgent: 'Mozdex/0.7.2-dev (Mozdex; http://www.mozdex.com/bot.html; spider@mozdex.com)',
-			metadata: {
-				uaFamily: 'mozDex',
-				uaName: 'Mozdex/0.7.2-dev',
-				uaUrl: 'http://www.mozdex.com/bot.html',
-				uaCompany: 'Mozdex.com',
-				uaCompanyUrl: 'http://www.mozdex.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=mozDex'
-			}
-		},
-		'137': {
-			userAgent: 'Gaisbot/3.0+(robot@gais.cs.ccu.edu.tw;+http://gais.cs.ccu.edu.tw/robot.php)',
-			metadata: {
-				uaFamily: 'Gaisbot',
-				uaName: 'Gaisbot/3.0',
-				uaUrl: 'http://gais.cs.ccu.edu.tw/robot.php',
-				uaCompany: 'National Chung Cheng University',
-				uaCompanyUrl: 'http://www.ccu.edu.tw/',
-				uaIcon: 'bot_gaisbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Gaisbot'
-			}
-		},
-		'140': {
-			userAgent: 'Mozilla/4.0 compatible ZyBorg/1.0 Dead Link Checker (wn.dlc@looksmart.net; http://www.WISEnutbot.com)',
-			metadata: {
-				uaFamily: 'ZyBorg',
-				uaName: 'ZyBorg/1.0 Dead Link Checker',
-				uaUrl: 'http://www.wisenutbot.com/',
-				uaCompany: 'LookSmart, Ltd.',
-				uaCompanyUrl: 'http://aboutus.looksmart.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZyBorg'
-			}
-		},
-		'141': {
-			userAgent: 'Mozilla/5.0 (compatible; Pogodak.co.yu/3.1)',
-			metadata: {
-				uaFamily: 'Pogodak.co.yu',
-				uaName: 'Pogodak.co.yu/3.1',
-				uaUrl: '',
-				uaCompany: 'Pogodak d.o.o.',
-				uaCompanyUrl: 'http://www.pogodak.co.yu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Pogodak.co.yu'
-			}
-		},
-		'144': {
-			userAgent: 'ichiro/2.0 (ichiro@nttr.co.jp)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/2.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'146': {
-			userAgent: 'boitho.com-dc/0.83 ( http://www.boitho.com/dcbot.html )',
-			metadata: {
-				uaFamily: 'boitho.com-dc',
-				uaName: 'boitho.com-dc/0.83',
-				uaUrl: 'http://www.boitho.com/dcbot.html',
-				uaCompany: 'Boitho',
-				uaCompanyUrl: 'http://www.boitho.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=boitho.com-dc'
-			}
-		},
-		'148': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler   [hc4]',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden hc4',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'151': {
-			userAgent: 'Sensis Web Crawler (search_comments\\at\\sensis\\dot\\com\\dot\\au)',
-			metadata: {
-				uaFamily: 'Sensis Web Crawler',
-				uaName: 'Sensis Web Crawler - b',
-				uaUrl: '',
-				uaCompany: 'Telstra Corporation Ltd.',
-				uaCompanyUrl: 'http://telstra.com/',
-				uaIcon: 'bot_sensiswebcrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sensis Web Crawler'
-			}
-		},
-		'153': {
-			userAgent: 'WebMiner (Web Miner; http://64.124.122.252/feedback.html)',
-			metadata: {
-				uaFamily: 'WebarooBot',
-				uaName: 'WebMiner (Web Miner)',
-				uaUrl: 'http://www.webaroo.com/company/site-owners',
-				uaCompany: 'Webaroo Inc.',
-				uaCompanyUrl: 'http://www.webaroo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebarooBot'
-			}
-		},
-		'155': {
-			userAgent: 'ia_archiver-web.archive.org',
-			metadata: {
-				uaFamily: 'ia_archiver',
-				uaName: 'ia_archiver',
-				uaUrl: 'http://www.alexa.com/site/help/webmasters',
-				uaCompany: 'Alexa Internet, Inc.',
-				uaCompanyUrl: 'http://www.alexa.com/',
-				uaIcon: 'bot_ia_archiver.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ia_archiver'
-			}
-		},
-		'159': {
-			userAgent: 'Mozilla/4.0 compatible ZyBorg/1.0 (wn-14.zyborg@looksmart.net; http://www.WISEnutbot.com)',
-			metadata: {
-				uaFamily: 'ZyBorg',
-				uaName: 'ZyBorg/1.0',
-				uaUrl: 'http://www.wisenutbot.com/',
-				uaCompany: 'LookSmart, Ltd.',
-				uaCompanyUrl: 'http://aboutus.looksmart.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZyBorg'
-			}
-		},
-		'162': {
-			userAgent: 'Accoona-AI-Agent/1.1.1 (crawler at accoona dot com)',
-			metadata: {
-				uaFamily: 'Accoona-AI-Agent',
-				uaName: 'Accoona-AI-Agent/1.1.1',
-				uaUrl: '',
-				uaCompany: 'Accoona Corp.',
-				uaCompanyUrl: 'http://accoona.com/',
-				uaIcon: 'bot_accoona-ai-agent.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Accoona-AI-Agent'
-			}
-		},
-		'164': {
-			userAgent: 'oBot',
-			metadata: {
-				uaFamily: 'oBot',
-				uaName: 'oBot',
-				uaUrl: 'http://filterdb.iss.net/crawler/',
-				uaCompany: 'IBM Germany Research & Development GmbH',
-				uaCompanyUrl: 'http://www.ibm.com/ibm/de/de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=oBot'
-			}
-		},
-		'167': {
-			userAgent: 'Ipselonbot/0.47-beta (Ipselon; http://www.ipselon.com/intl/en/ipselonbot.html; ipselonbot@ipselon.com)',
-			metadata: {
-				uaFamily: 'Ipselonbot',
-				uaName: 'Ipselonbot/0.47-beta',
-				uaUrl: 'http://www.ipselon.com/intl/en/ipselonbot.html',
-				uaCompany: 'Ipselon Networks s.l.',
-				uaCompanyUrl: 'http://www.ipselon.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ipselonbot'
-			}
-		},
-		'168': {
-			userAgent: 'IlTrovatore-Setaccio/1.2 (Italy search engine; http://www.iltrovatore.it/bot.html; bot@iltrovatore.it)',
-			metadata: {
-				uaFamily: 'IlTrovatore-Setaccio',
-				uaName: 'IlTrovatore-Setaccio/1.2 b',
-				uaUrl: 'http://www.iltrovatore.it/bot.html',
-				uaCompany: 'Il Trovatore',
-				uaCompanyUrl: 'http://www.iltrovatore.it/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IlTrovatore-Setaccio'
-			}
-		},
-		'170': {
-			userAgent: 'RufusBot (Rufus Web Miner; http://64.124.122.252/feedback.html)',
-			metadata: {
-				uaFamily: 'WebarooBot',
-				uaName: 'RufusBot (Rufus Web Miner)',
-				uaUrl: 'http://www.webaroo.com/company/site-owners',
-				uaCompany: 'Webaroo Inc.',
-				uaCompanyUrl: 'http://www.webaroo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebarooBot'
-			}
-		},
-		'177': {
-			userAgent: 'NutchCVS/0.7.1 (Nutch; http://www.vvdb.org; voorzitter@vvdb.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.7.1 vvdg.org',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'178': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; obot)',
-			metadata: {
-				uaFamily: 'oBot',
-				uaName: 'oBot - b',
-				uaUrl: 'http://filterdb.iss.net/crawler/',
-				uaCompany: 'IBM Germany Research & Development GmbH',
-				uaCompanyUrl: 'http://www.ibm.com/ibm/de/de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=oBot'
-			}
-		},
-		'184': {
-			userAgent: 'ccubee/3.2',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/3.2',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'190': {
-			userAgent: 'genieBot (wgao@genieknows.com)',
-			metadata: {
-				uaFamily: 'genieBot',
-				uaName: 'genieBot a',
-				uaUrl: 'http://64.5.245.11/faq/faq.html',
-				uaCompany: 'IT Interactive Services Inc.',
-				uaCompanyUrl: 'http://www.genieknows.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=genieBot'
-			}
-		},
-		'192': {
-			userAgent: 'ejupiter.com',
-			metadata: {
-				uaFamily: 'ejupiter.com',
-				uaName: 'ejupiter.com',
-				uaUrl: 'http://robot.ejupiter.com/16/robot_privacy.html',
-				uaCompany: 'eJupiter Inc',
-				uaCompanyUrl: 'http://www.ejupiter.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ejupiter.com'
-			}
-		},
-		'193': {
-			userAgent: 'Mozilla/5.0 (compatible; Yahoo! Slurp China; http://misc.yahoo.com.cn/help.html)',
-			metadata: {
-				uaFamily: 'Yahoo!',
-				uaName: 'Yahoo! Slurp China',
-				uaUrl: 'http://misc.yahoo.com.cn/help.html',
-				uaCompany: 'Yahoo! Inc.',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo!'
-			}
-		},
-		'194': {
-			userAgent: 'thumbshots-de-Bot (Version: 1.02, powered by www.thumbshots.de)',
-			metadata: {
-				uaFamily: 'thumbshots-de-Bot',
-				uaName: 'thumbshots-de-Bot 1.02',
-				uaUrl: 'http://www.thumbshots.de/content-39-seite_auszuschliessen.html',
-				uaCompany: 'Mobile & More Mobilkommunikation GmbH',
-				uaCompanyUrl: 'http://www.mobile-more.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=thumbshots-de-Bot'
-			}
-		},
-		'195': {
-			userAgent: 'Vespa Crawler',
-			metadata: {
-				uaFamily: 'Vespa Crawler',
-				uaName: 'Vespa Crawler',
-				uaUrl: 'http://jobs.yahoo.no/index.html',
-				uaCompany: 'Yahoo!',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Vespa Crawler'
-			}
-		},
-		'197': {
-			userAgent: 'Ipselonbot/1.0-beta (+; http://www.ipselon.com/intl/en/ipselonbot.html)',
-			metadata: {
-				uaFamily: 'Ipselonbot',
-				uaName: 'Ipselonbot/1.0-beta',
-				uaUrl: 'http://www.ipselon.com/intl/en/ipselonbot.html',
-				uaCompany: 'Ipselon Networks s.l.',
-				uaCompanyUrl: 'http://www.ipselon.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ipselonbot'
-			}
-		},
-		'200': {
-			userAgent: 'ccubee/3.3',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/3.3',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'201': {
-			userAgent: 'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.7) NimbleCrawler 1.11 obeys UserAgent NimbleCrawler For problems contact: crawler_at_dataalchemy.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/1.11',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'204': {
-			userAgent: 'SynooBot/0.7.1 (SynooBot; http://www.synoo.de/bot.html; webmaster@synoo.com)',
-			metadata: {
-				uaFamily: 'SynooBot',
-				uaName: 'SynooBot/0.7.1',
-				uaUrl: 'http://www.synoo.de/bot.html',
-				uaCompany: 'Synoo',
-				uaCompanyUrl: 'http://www.synoo.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SynooBot'
-			}
-		},
-		'207': {
-			userAgent: 'ccubee/3.7',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/3.7',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'208': {
-			userAgent: 'Silk/1.0',
-			metadata: {
-				uaFamily: 'silk',
-				uaName: 'silk/1.0 -a',
-				uaUrl: 'http://www.slider.com/silk.html',
-				uaCompany: 'Slider.com',
-				uaCompanyUrl: 'http://www.slider.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=silk'
-			}
-		},
-		'209': {
-			userAgent: 'Mozilla/5.0 (Windows;) NimbleCrawler 1.12 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/1.12',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'214': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler   [bc14]',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden bc14',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'215': {
-			userAgent: 'genieBot ((http://64.5.245.11/faq/faq.html))',
-			metadata: {
-				uaFamily: 'genieBot',
-				uaName: 'genieBot b',
-				uaUrl: 'http://64.5.245.11/faq/faq.html',
-				uaCompany: 'IT Interactive Services Inc.',
-				uaCompanyUrl: 'http://www.genieknows.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=genieBot'
-			}
-		},
-		'217': {
-			userAgent: 'g2Crawler (nobody@airmail.net)',
-			metadata: {
-				uaFamily: 'g2crawler',
-				uaName: 'g2crawler',
-				uaUrl: 'http://g2crawler.blogspot.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=g2crawler'
-			}
-		},
-		'218': {
-			userAgent: 'Mozilla/5.0 (compatible; Theophrastus/2.0; +http://users.cs.cf.ac.uk/N.A.Smith/theophrastus.php)',
-			metadata: {
-				uaFamily: 'Theophrastus',
-				uaName: 'Theophrastus/2.0',
-				uaUrl: 'http://users.cs.cf.ac.uk/N.A.Smith/theophrastus.php',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Theophrastus'
-			}
-		},
-		'219': {
-			userAgent: 'Mozilla/5.0 (compatible; OnetSzukaj/5.0; +http://szukaj.onet.pl',
-			metadata: {
-				uaFamily: 'OnetSzukaj',
-				uaName: 'OnetSzukaj/5.0 b',
-				uaUrl: '',
-				uaCompany: 'Onet.pl',
-				uaCompanyUrl: 'http://www.onet.pl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OnetSzukaj'
-			}
-		},
-		'221': {
-			userAgent: 'Sensis Web Crawler (search_comments\\\\at\\\\sensis\\\\dot\\\\com\\\\dot\\\\au)',
-			metadata: {
-				uaFamily: 'Sensis Web Crawler',
-				uaName: 'Sensis Web Crawler',
-				uaUrl: 'http://www.sensis.com.au/help.do',
-				uaCompany: 'Telstra Corporation Ltd.',
-				uaCompanyUrl: 'http://www.telstra.com/',
-				uaIcon: 'bot_sensiswebcrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sensis Web Crawler'
-			}
-		},
-		'222': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 5.0; Windows 95) VoilaBot BETA 1.2 (http://www.voila.com/)',
-			metadata: {
-				uaFamily: 'VoilaBot',
-				uaName: 'VoilaBot BETA 1.2',
-				uaUrl: 'http://www.voila.com/',
-				uaCompany: 'France Telecom',
-				uaCompanyUrl: 'http://www.francetelecom.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VoilaBot'
-			}
-		},
-		'223': {
-			userAgent: 'ichiro/2.0 (http://help.goo.ne.jp/door/crawler.html)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/2.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'225': {
-			userAgent: 'VORTEX/1.2 (+http://marty.anstey.ca/robots/vortex/)',
-			metadata: {
-				uaFamily: 'VORTEX',
-				uaName: 'VORTEX/1.2',
-				uaUrl: 'http://marty.anstey.ca/projects/robots/vortex/',
-				uaCompany: 'Marty Anstey',
-				uaCompanyUrl: 'http://marty.anstey.ca/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VORTEX'
-			}
-		},
-		'226': {
-			userAgent: 'GOFORITBOT ( http://www.goforit.com/about/ )',
-			metadata: {
-				uaFamily: 'GOFORITBOT',
-				uaName: 'GOFORITBOT',
-				uaUrl: 'http://www.goforit.com/about/',
-				uaCompany: 'GoForIt Entertainment LLC',
-				uaCompanyUrl: 'http://www.goforit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GOFORITBOT'
-			}
-		},
-		'227': {
-			userAgent: 'silk/1.0 (+http://www.slider.com/silk.htm)/3.7',
-			metadata: {
-				uaFamily: 'silk',
-				uaName: 'silk/1.0',
-				uaUrl: 'http://www.slider.com/silk.htm',
-				uaCompany: 'Slider.com',
-				uaCompanyUrl: 'http://www.slider.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=silk'
-			}
-		},
-		'232': {
-			userAgent: 'miniRank/1.5 (miniRank; www.minirank.com; robot)',
-			metadata: {
-				uaFamily: 'miniRank',
-				uaName: 'miniRank/1.5',
-				uaUrl: 'http://www.minirank.com/',
-				uaCompany: 'TitaniumLine.com',
-				uaCompanyUrl: 'http://titaniumline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=miniRank'
-			}
-		},
-		'235': {
-			userAgent: 'SurveyBot/2.3 (Whois Source)',
-			metadata: {
-				uaFamily: 'SurveyBot',
-				uaName: 'SurveyBot/2.3',
-				uaUrl: 'http://www.whois.sc/info/webmasters/surveybot.html',
-				uaCompany: 'Name Intelligence, Inc.',
-				uaCompanyUrl: 'http://www.nameintelligence.com/',
-				uaIcon: 'bot_surveybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SurveyBot'
-			}
-		},
-		'236': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler   [bc5]',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden bc5',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'237': {
-			userAgent: 'btbot/0.4 (+http://www.btbot.com/btbot.html)',
-			metadata: {
-				uaFamily: 'btbot',
-				uaName: 'btbot/0.4',
-				uaUrl: 'http://www.btbot.com/btbot.html',
-				uaCompany: 'btbot.com',
-				uaCompanyUrl: 'http://www.btbot.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=btbot'
-			}
-		},
-		'238': {
-			userAgent: 'WIRE/0.10 (Linux; i686; Bot,Robot,Spider,Crawler)',
-			metadata: {
-				uaFamily: 'WIRE',
-				uaName: 'WIRE/0.10',
-				uaUrl: 'http://www.cwr.cl/projects/WIRE/',
-				uaCompany: 'Universidad de Chile',
-				uaCompanyUrl: 'http://www.dcc.uchile.cl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WIRE'
-			}
-		},
-		'242': {
-			userAgent: 'IRLbot/2.0 (+http://irl.cs.tamu.edu/crawler)',
-			metadata: {
-				uaFamily: 'IRLbot',
-				uaName: 'IRLbot/2.0',
-				uaUrl: 'http://irl.cs.tamu.edu/crawler/',
-				uaCompany: 'Texas A&M University',
-				uaCompanyUrl: 'http://www.tamu.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IRLbot'
-			}
-		},
-		'252': {
-			userAgent: 'MSRBOT',
-			metadata: {
-				uaFamily: 'MSRBOT',
-				uaName: 'MSRBOT',
-				uaUrl: 'http://research.microsoft.com/research/sv/msrbot/',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSRBOT'
-			}
-		},
-		'253': {
-			userAgent: 'PageBitesHyperBot/600 (http://www.pagebites.com/)',
-			metadata: {
-				uaFamily: 'PageBitesHyperBot',
-				uaName: 'PageBitesHyperBot/600',
-				uaUrl: '',
-				uaCompany: 'PageBites Inc.',
-				uaCompanyUrl: 'http://www.pagebites.com/',
-				uaIcon: 'bot_pagebiteshyperbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PageBitesHyperBot'
-			}
-		},
-		'262': {
-			userAgent: 'Shim-Crawler(Mozilla-compatible; http://www.logos.ic.i.u-tokyo.ac.jp/crawler/; crawl@logos.ic.i.u-tokyo.ac.jp)',
-			metadata: {
-				uaFamily: 'Shim-Crawler',
-				uaName: 'Shim-Crawler',
-				uaUrl: 'http://www.logos.ic.i.u-tokyo.ac.jp/crawler/index.en.html',
-				uaCompany: 'Chikayama-Taura Lab, The University of Tokyo',
-				uaCompanyUrl: 'http://www.logos.ic.i.u-tokyo.ac.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Shim-Crawler'
-			}
-		},
-		'263': {
-			userAgent: 'ccubee/4.0',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/4.0',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'266': {
-			userAgent: 'ksibot/7.0d (+http://ego.ms.mff.cuni.cz/)',
-			metadata: {
-				uaFamily: 'ksibot',
-				uaName: 'ksibot/7.0d',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ksibot'
-			}
-		},
-		'267': {
-			userAgent: 'IRLbot/2.0 (compatible; MSIE 6.0; http://irl.cs.tamu.edu/crawler)',
-			metadata: {
-				uaFamily: 'IRLbot',
-				uaName: 'IRLbot/2.0 b',
-				uaUrl: 'http://irl.cs.tamu.edu/crawler/',
-				uaCompany: 'Texas A&M University',
-				uaCompanyUrl: 'http://www.tamu.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IRLbot'
-			}
-		},
-		'278': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler   [fc13]',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden fc13',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'281': {
-			userAgent: 'HooWWWer/2.1.3 (debugging run) (+http://cosco.hiit.fi/search/hoowwwer/ | mailto:crawler-info<at>hiit.fi)',
-			metadata: {
-				uaFamily: 'HooWWWer',
-				uaName: 'HooWWWer/2.1.3',
-				uaUrl: 'http://cosco.hiit.fi/search/hoowwwer/',
-				uaCompany: 'CoSCo',
-				uaCompanyUrl: 'http://cosco.hiit.fi/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HooWWWer'
-			}
-		},
-		'282': {
-			userAgent: 'Mozilla/5.0 (Windows;) NimbleCrawler 1.13 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/1.13',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'285': {
-			userAgent: 'Mozilla/5.0 (compatible; BecomeBot/2.3; MSIE 6.0 compatible; +http://www.become.com/site_owners.html)',
-			metadata: {
-				uaFamily: 'BecomeBot',
-				uaName: 'BecomeBot/2.3',
-				uaUrl: 'http://www.become.com/site_owners.html',
-				uaCompany: 'Become, Inc.',
-				uaCompanyUrl: 'http://www.become.com/',
-				uaIcon: 'bot_becomebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BecomeBot'
-			}
-		},
-		'290': {
-			userAgent: 'Mozilla/5.0 (Windows;) NimbleCrawler 1.14 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/1.14',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'294': {
-			userAgent: 'Mozilla/5.0 (Windows;) NimbleCrawler 1.15 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/1.15',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'295': {
-			userAgent: 'MetaTagRobot/1.6 (http://www.widexl.com/remote/search-engines/metatag-analyzer.html)',
-			metadata: {
-				uaFamily: 'MetaTagRobot',
-				uaName: 'MetaTagRobot/1.6',
-				uaUrl: 'http://www.widexl.com/remote/search-engines/metatag-analyzer.html',
-				uaCompany: 'widexl.com',
-				uaCompanyUrl: 'http://www.widexl.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetaTagRobot'
-			}
-		},
-		'296': {
-			userAgent: 'sproose/0.1-alpha (sproose crawler; http://www.sproose.com/bot.html; crawler@sproose.com)',
-			metadata: {
-				uaFamily: 'sproose',
-				uaName: 'sproose/0.1-alpha',
-				uaUrl: 'http://www.sproose.com/bot.html',
-				uaCompany: 'Sproose, Inc.',
-				uaCompanyUrl: 'http://www.sproose.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sproose'
-			}
-		},
-		'301': {
-			userAgent: 'Search Engine World Robots.txt Validator at http://www.searchengineworld.com/cgi-bin/robotcheck.cgi',
-			metadata: {
-				uaFamily: 'Search Engine World Robots.txt Validator',
-				uaName: 'Search Engine World Robots.txt Validator',
-				uaUrl: 'http://www.searchengineworld.com/cgi-bin/robotcheck.cgi',
-				uaCompany: 'searchengineworld',
-				uaCompanyUrl: 'http://www.searchengineworld.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Search Engine World Robots.txt Validator'
-			}
-		},
-		'303': {
-			userAgent: 'Gaisbot/3.0+(robot06@gais.cs.ccu.edu.tw;+http://gais.cs.ccu.edu.tw/robot.php)',
-			metadata: {
-				uaFamily: 'Gaisbot',
-				uaName: 'Gaisbot/3.0 - 06',
-				uaUrl: 'http://gais.cs.ccu.edu.tw/robot.php',
-				uaCompany: 'National Chung Cheng University',
-				uaCompanyUrl: 'http://www.ccu.edu.tw/',
-				uaIcon: 'bot_gaisbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Gaisbot'
-			}
-		},
-		'306': {
-			userAgent: 'Forschungsportal/0.8-dev (Testinstallation; http://www.forschungsportal.net/; fpcrawler@rrzn.uni-hannover.de)',
-			metadata: {
-				uaFamily: 'Forschungsportal',
-				uaName: 'Forschungsportal/0.8-dev',
-				uaUrl: 'http://www.forschungsportal.net/',
-				uaCompany: 'Bundesministerium f\xfcr Bildung und Forschung',
-				uaCompanyUrl: 'http://www.bmbf.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Forschungsportal'
-			}
-		},
-		'307': {
-			userAgent: 'HooWWWer/2.2.0 (debugging run) (+http://cosco.hiit.fi/search/hoowwwer/ | mailto:crawler-info<at>hiit.fi)',
-			metadata: {
-				uaFamily: 'HooWWWer',
-				uaName: 'HooWWWer/2.2.0',
-				uaUrl: 'http://cosco.hiit.fi/search/hoowwwer/',
-				uaCompany: 'CoSCo',
-				uaCompanyUrl: 'http://cosco.hiit.fi/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HooWWWer'
-			}
-		},
-		'308': {
-			userAgent: 'OmniExplorer_Bot/6.47 (+http://www.omni-explorer.com) WorldIndexer',
-			metadata: {
-				uaFamily: 'OmniExplorer_Bot',
-				uaName: 'OmniExplorer_Bot/6.47',
-				uaUrl: 'http://www.omni-explorer.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OmniExplorer_Bot'
-			}
-		},
-		'310': {
-			userAgent: 'Orbiter (+http://www.dailyorbit.com/bot.htm)',
-			metadata: {
-				uaFamily: 'Orbiter',
-				uaName: 'Orbiter',
-				uaUrl: 'http://www.dailyorbit.com/bot.htm',
-				uaCompany: 'DailyOrbit.com',
-				uaCompanyUrl: 'http://www.dailyorbit.com/',
-				uaIcon: 'bot_orbiter.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Orbiter'
-			}
-		},
-		'312': {
-			userAgent: 'FAST Enterprise Crawler/6.4 (crawler@fast.no)',
-			metadata: {
-				uaFamily: 'FAST Enterprise Crawler',
-				uaName: 'FAST Enterprise Crawler/6.4',
-				uaUrl: 'http://www.fast.no/glossary.aspx?m=48&amid=415',
-				uaCompany: 'Fast Search & Transfer',
-				uaCompanyUrl: 'http://www.fastsearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FAST Enterprise Crawler'
-			}
-		},
-		'317': {
-			userAgent: 'csci_b659/0.13',
-			metadata: {
-				uaFamily: 'csci_b659',
-				uaName: 'csci_b659/0.13',
-				uaUrl: 'http://informatics.indiana.edu/fil/Class/b659/',
-				uaCompany: 'Indiana University',
-				uaCompanyUrl: 'http://www.indiana.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=csci_b659'
-			}
-		},
-		'321': {
-			userAgent: 'NutchCVS/0.06-dev (Nutch; http://www.nutch.org/docs/en/bot.html; nutch-agent@lists.sourceforge.net)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.06-dev',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'323': {
-			userAgent: 'NutchCVS/0.7.1 (Nutch running at UW; http://www.nutch.org/docs/en/bot.html; sycrawl@cs.washington.edu)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.7.1 at washihinton.edu',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'326': {
-			userAgent: 'miniRank/1.6 (Website ranking; www.minirank.com; robot)',
-			metadata: {
-				uaFamily: 'miniRank',
-				uaName: 'miniRank/1.6',
-				uaUrl: 'http://www.minirank.com/',
-				uaCompany: 'TitaniumLine.com',
-				uaCompanyUrl: 'http://titaniumline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=miniRank'
-			}
-		},
-		'327': {
-			userAgent: 'ccubee/3.5',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/3.5',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'328': {
-			userAgent: 'boitho.com-dc/0.79 ( http://www.boitho.com/dcbot.html )',
-			metadata: {
-				uaFamily: 'boitho.com-dc',
-				uaName: 'boitho.com-dc/0.79',
-				uaUrl: 'http://www.boitho.com/dcbot.html',
-				uaCompany: 'Boitho',
-				uaCompanyUrl: 'http://www.boitho.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=boitho.com-dc'
-			}
-		},
-		'329': {
-			userAgent: 'Mozilla/5.0 (compatible; Vermut +http://vermut.aol.com)',
-			metadata: {
-				uaFamily: 'Vermut',
-				uaName: 'Vermut',
-				uaUrl: 'http://vermut.aol.com/',
-				uaCompany: 'America Online, Inc.',
-				uaCompanyUrl: 'http://www.aol.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Vermut'
-			}
-		},
-		'333': {
-			userAgent: 'SynooBot (compatible; Synoobot/0.7.1; http://www.synoo.com/search/bot.html)',
-			metadata: {
-				uaFamily: 'SynooBot',
-				uaName: 'SynooBot/0.7.1 com',
-				uaUrl: ' http://www.synoo.com/search/bot.html',
-				uaCompany: 'Synoo',
-				uaCompanyUrl: 'http://www.synoo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SynooBot'
-			}
-		},
-		'335': {
-			userAgent: 'NuSearch Spider (compatible; MSIE 6.0)',
-			metadata: {
-				uaFamily: 'NuSearch Spider',
-				uaName: 'NuSearch Spider',
-				uaUrl: 'http://www.nusearch.com/',
-				uaCompany: 'nusearch.com',
-				uaCompanyUrl: 'http://www.nusearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NuSearch Spider'
-			}
-		},
-		'337': {
-			userAgent: 'Robo Crawler 6.4.5 (robocrawler@bb.softbank.co.jp)',
-			metadata: {
-				uaFamily: 'Robo Crawler',
-				uaName: 'Robo Crawler 6.4.5',
-				uaUrl: 'http://www.softbank.co.jp/',
-				uaCompany: 'SOFTBANK CORP.',
-				uaCompanyUrl: 'http://www.softbank.co.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Robo Crawler'
-			}
-		},
-		'338': {
-			userAgent: 'NutchCVS/0.7.1 (Nutch running at UW; http://crawlers.cs.washington.edu/; sycrawl@cs.washington.edu)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.7.1 at UW',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'340': {
-			userAgent: 'XML Sitemaps Generator 1.0',
-			metadata: {
-				uaFamily: 'XML Sitemaps Generator',
-				uaName: 'XML Sitemaps Generator 1.0',
-				uaUrl: 'http://www.xml-sitemaps.com/',
-				uaCompany: 'XML-Sitemaps.com',
-				uaCompanyUrl: 'http://www.xml-sitemaps.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=XML Sitemaps Generator'
-			}
-		},
-		'341': {
-			userAgent: 'Mozilla/5.0 (Windows;) NimbleCrawler 2.0.0 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/2.0.0',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'343': {
-			userAgent: 'NutchCVS/0.7.2 (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.7.2',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'345': {
-			userAgent: 'updated/0.1-beta (updated; http://www.updated.com; crawler@updated.com)',
-			metadata: {
-				uaFamily: 'updated',
-				uaName: 'updated/0.1-beta',
-				uaUrl: '',
-				uaCompany: 'Updated.com Inc.',
-				uaCompanyUrl: 'http://www.updated.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=updated'
-			}
-		},
-		'349': {
-			userAgent: 'noyona_0_1',
-			metadata: {
-				uaFamily: 'noyona',
-				uaName: 'noyona_0_1',
-				uaUrl: 'http://www.noyona.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=noyona'
-			}
-		},
-		'350': {
-			userAgent: 'Mozdex/0.7.2 (Mozdex; http://www.mozdex.com/bot.html; spider@mozdex.com)',
-			metadata: {
-				uaFamily: 'mozDex',
-				uaName: 'Mozdex/0.7.2',
-				uaUrl: 'http://www.mozdex.com/bot.html',
-				uaCompany: 'Mozdex.com',
-				uaCompanyUrl: 'http://www.mozdex.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=mozDex'
-			}
-		},
-		'352': {
-			userAgent: 'TeragramCrawler',
-			metadata: {
-				uaFamily: 'TeragramCrawler',
-				uaName: 'TeragramCrawler',
-				uaUrl: '',
-				uaCompany: 'Teragram Corporation',
-				uaCompanyUrl: 'http://www.teragram.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TeragramCrawler'
-			}
-		},
-		'355': {
-			userAgent: 'Openfind data gatherer, Openbot/3.0+(robot-response@openfind.com.tw;+http://www.openfind.com.tw/robot.html)',
-			metadata: {
-				uaFamily: 'Openbot',
-				uaName: 'Openbot/3.0',
-				uaUrl: 'http://www.openfind.com.tw/robot.html',
-				uaCompany: 'Openfind Information Technology INC.',
-				uaCompanyUrl: 'http://www.openfind.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Openbot'
-			}
-		},
-		'360': {
-			userAgent: 'Mozilla/5.0 (compatible; BecomeBot/3.0; MSIE 6.0 compatible; +http://www.become.com/site_owners.html)',
-			metadata: {
-				uaFamily: 'BecomeBot',
-				uaName: 'BecomeBot/3.0',
-				uaUrl: 'http://www.become.com/site_owners.html',
-				uaCompany: 'Become, Inc.',
-				uaCompanyUrl: 'http://www.become.com/',
-				uaIcon: 'bot_becomebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BecomeBot'
-			}
-		},
-		'364': {
-			userAgent: 'wwwster/1.4 (Beta, mailto:gue@cis.uni-muenchen.de)',
-			metadata: {
-				uaFamily: 'wwwster',
-				uaName: 'wwwster/1.4 Beta',
-				uaUrl: '',
-				uaCompany: 'CIS',
-				uaCompanyUrl: 'http://www.cis.uni-muenchen.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=wwwster'
-			}
-		},
-		'366': {
-			userAgent: 'NPBot/3 (NPBot; http://www.nameprotect.com; npbot@nameprotect.com)',
-			metadata: {
-				uaFamily: 'NPBot',
-				uaName: 'NPBot/3',
-				uaUrl: 'http://www.nameprotect.com/botinfo.html',
-				uaCompany: 'NameProtect Inc.',
-				uaCompanyUrl: 'http://www.nameprotect.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NPBot'
-			}
-		},
-		'368': {
-			userAgent: 'NetWhatCrawler/0.06-dev (NetWhatCrawler from NetWhat.com; http://www.netwhat.com; support@netwhat.com)',
-			metadata: {
-				uaFamily: 'NetWhatCrawler',
-				uaName: 'NetWhatCrawler/0.06-dev',
-				uaUrl: '',
-				uaCompany: 'GreenWave Online, Inc.',
-				uaCompanyUrl: 'http://www.sonicrun.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NetWhatCrawler'
-			}
-		},
-		'376': {
-			userAgent: 'virus_detector (virus_harvester@securecomputing.com)',
-			metadata: {
-				uaFamily: 'virus_detector',
-				uaName: 'virus_detector',
-				uaUrl: 'http://www.securecomputing.com/sg2_antivirus.cfm?menu=solutions',
-				uaCompany: 'Secure Computing Corporation.',
-				uaCompanyUrl: 'http://www.securecomputing.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=virus_detector'
-			}
-		},
-		'378': {
-			userAgent: 'IlTrovatore/1.2 (IlTrovatore; http://www.iltrovatore.it/bot.html; bot@iltrovatore.it)',
-			metadata: {
-				uaFamily: 'IlTrovatore',
-				uaName: 'IlTrovatore/1.2',
-				uaUrl: 'http://www.iltrovatore.it/bot.html',
-				uaCompany: 'Il Trovatore',
-				uaCompanyUrl: 'http://www.iltrovatore.it/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IlTrovatore'
-			}
-		},
-		'382': {
-			userAgent: 'NutchCVS/0.8-dev (Nutch running at UW; http://www.nutch.org/docs/en/bot.html; sycrawl@cs.washington.edu)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCSV/0.8-dev at UW',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'391': {
-			userAgent: 'kakle-spider/0.1 (kakle-spider; http://www.kakle.com/bot.html; support@kakle.com)',
-			metadata: {
-				uaFamily: 'Kakle Bot',
-				uaName: 'kakle-spider/0.1',
-				uaUrl: 'http://www.kakle.com/bot.html',
-				uaCompany: 'Kakle Inc.',
-				uaCompanyUrl: 'http://www.kakle.com',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Kakle Bot'
-			}
-		},
-		'392': {
-			userAgent: 'SrevBot/2.0 (SrevBot; http://winsrev.com/bot.html; bot@winsrev.com)',
-			metadata: {
-				uaFamily: 'SrevBot',
-				uaName: 'SrevBot/2.0',
-				uaUrl: 'http://www.winsrev.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SrevBot'
-			}
-		},
-		'393': {
-			userAgent: 'CJB.NET Proxy',
-			metadata: {
-				uaFamily: 'CJB.NET Proxy',
-				uaName: 'CJB.NET Proxy',
-				uaUrl: 'http://proxy.cjb.net/',
-				uaCompany: 'CJB.NET',
-				uaCompanyUrl: 'http://www.cjb.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CJB.NET Proxy'
-			}
-		},
-		'394': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler   [bc6]',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden bc6',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'396': {
-			userAgent: 'Krugle/Krugle,Nutch/0.8+ (Krugle web crawler; http://www.krugle.com/crawler/info.html; webcrawler@krugle.com)',
-			metadata: {
-				uaFamily: 'Krugle',
-				uaName: 'Krugle (Nutch/0.8+)',
-				uaUrl: 'http://corp.krugle.com/crawler/info.html',
-				uaCompany: 'Steve Larsen',
-				uaCompanyUrl: 'http://blog.krugle.com/?page_id=5',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Krugle'
-			}
-		},
-		'398': {
-			userAgent: 'page_verifier (http://www.securecomputing.com/goto/pv)',
-			metadata: {
-				uaFamily: 'page_verifier',
-				uaName: 'page_verifier',
-				uaUrl: 'http://www.securecomputing.com/goto/pv',
-				uaCompany: 'Secure Computing Corporation',
-				uaCompanyUrl: 'http://www.securecomputing.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=page_verifier'
-			}
-		},
-		'401': {
-			userAgent: 'Mozilla/4.0 compatible ZyBorg/1.0 (wn-16.zyborg@looksmart.net; http://www.WISEnutbot.com)',
-			metadata: {
-				uaFamily: 'ZyBorg',
-				uaName: 'ZyBorg/1.0 - b',
-				uaUrl: 'http://www.wisenutbot.com/',
-				uaCompany: 'LookSmart, Ltd.',
-				uaCompanyUrl: 'http://aboutus.looksmart.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZyBorg'
-			}
-		},
-		'405': {
-			userAgent: 'ksibot/8.0a (+http://ego.ms.mff.cuni.cz/)',
-			metadata: {
-				uaFamily: 'ksibot',
-				uaName: 'ksibot/8.0a',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ksibot'
-			}
-		},
-		'406': {
-			userAgent: 'WinkBot/0.06 (Wink.com search engine web crawler; http://www.wink.com/Wink:WinkBot; winkbot@wink.com)',
-			metadata: {
-				uaFamily: 'WinkBot',
-				uaName: 'WinkBot/0.06',
-				uaUrl: 'http://www.wink.com/Wink:WinkBot',
-				uaCompany: 'Wink Technologies, Inc',
-				uaCompanyUrl: 'http://www.wink.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WinkBot'
-			}
-		},
-		'408': {
-			userAgent: 'Snapbot/1.0',
-			metadata: {
-				uaFamily: 'Snapbot',
-				uaName: 'Snapbot/1.0',
-				uaUrl: '',
-				uaCompany: 'Snap',
-				uaCompanyUrl: 'http://www.snap.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Snapbot'
-			}
-		},
-		'410': {
-			userAgent: 'SrevBot/1.2 (SrevBot; http://winsrev.com/bot.html; bot@winsrev.comg)',
-			metadata: {
-				uaFamily: 'SrevBot',
-				uaName: 'SrevBot/1.2',
-				uaUrl: 'http://www.winsrev.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SrevBot'
-			}
-		},
-		'411': {
-			userAgent: 'Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://about.ask.com/en/docs/about/webmasters.shtml)',
-			metadata: {
-				uaFamily: 'Ask Jeeves/Teoma',
-				uaName: 'Ask Jeeves/Teoma - c',
-				uaUrl: 'http://about.ask.com/en/docs/about/webmasters.shtml',
-				uaCompany: 'Ask Jeeves Inc.',
-				uaCompanyUrl: 'http://about.ask.com/en/docs/about/index.shtml',
-				uaIcon: 'bot_AskJeeves.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ask Jeeves/Teoma'
-			}
-		},
-		'412': {
-			userAgent: 'textractor.queuekeeper/0.1 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.queuekeeper/0.1',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'415': {
-			userAgent: 'WIRE/0.11 (Linux; i686; Bot,Robot,Spider,Crawler,aromano@cli.di.unipi.it)',
-			metadata: {
-				uaFamily: 'WIRE',
-				uaName: 'WIRE/0.11',
-				uaUrl: 'http://www.cwr.cl/projects/WIRE/',
-				uaCompany: 'Universidad de Chile',
-				uaCompanyUrl: 'http://www.dcc.uchile.cl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WIRE'
-			}
-		},
-		'416': {
-			userAgent: 'MQbot metaquerier.cs.uiuc.edu/crawler',
-			metadata: {
-				uaFamily: 'MQbot',
-				uaName: 'MQbot',
-				uaUrl: 'http://metaquerier.cs.uiuc.edu/crawler/',
-				uaCompany: 'University of Illinois at Urbana-Champaign',
-				uaCompanyUrl: 'http://www.uiuc.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MQbot'
-			}
-		},
-		'422': {
-			userAgent: 'DataparkSearch/4.40.1 (+http://www.dataparksearch.org/)',
-			metadata: {
-				uaFamily: 'DataparkSearch',
-				uaName: 'DataparkSearch/4.40',
-				uaUrl: 'http://www.dataparksearch.org/',
-				uaCompany: 'DataPark',
-				uaCompanyUrl: 'http://www.datapark.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DataparkSearch'
-			}
-		},
-		'425': {
-			userAgent: 'exactseek.com',
-			metadata: {
-				uaFamily: 'ExactSEEK',
-				uaName: 'ExactSEEK',
-				uaUrl: 'http://www.exactseek.com/',
-				uaCompany: 'Jayde Online, Inc.',
-				uaCompanyUrl: 'http://www.jaydeonlineinc.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ExactSEEK'
-			}
-		},
-		'431': {
-			userAgent: 'Mozilla/5.0 (Windows;) NimbleCrawler 2.0.1 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/2.0.1',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'435': {
-			userAgent: 'sproose/0.1 (sproose bot; http://www.sproose.com/bot.html; crawler@sproose.com)',
-			metadata: {
-				uaFamily: 'sproose',
-				uaName: 'sproose/0.1',
-				uaUrl: 'http://www.sproose.com/bot.html',
-				uaCompany: 'Sproose, Inc.',
-				uaCompanyUrl: 'http://www.sproose.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sproose'
-			}
-		},
-		'437': {
-			userAgent: 'updated/0.1-alpha (updated crawler; http://www.updated.com; crawler@updated.com)',
-			metadata: {
-				uaFamily: 'updated',
-				uaName: 'updated/0.1-alpha',
-				uaUrl: '',
-				uaCompany: 'Updated.com Inc.',
-				uaCompanyUrl: 'http://www.updated.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=updated'
-			}
-		},
-		'439': {
-			userAgent: 'Vagabondo/3.0 (webagent at wise-guys dot nl)',
-			metadata: {
-				uaFamily: 'Vagabondo',
-				uaName: 'Vagabondo/3.0',
-				uaUrl: 'http://webagent.wise-guys.nl/',
-				uaCompany: 'WiseGuys Internet BV',
-				uaCompanyUrl: 'http://www.wise-guys.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Vagabondo'
-			}
-		},
-		'442': {
-			userAgent: 'Mozilla/4.0 (compatible; MyFamilyBot/1.0; http://www.myfamilyinc.com)',
-			metadata: {
-				uaFamily: 'MyFamilyBot',
-				uaName: 'MyFamilyBot/1.0',
-				uaUrl: 'http://www.ancestry.com/learn/bot.aspx',
-				uaCompany: 'MyFamily.com, Inc.',
-				uaCompanyUrl: 'http://www.myfamilyinc.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MyFamilyBot'
-			}
-		},
-		'445': {
-			userAgent: 'textractor.harvester/h7/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h7/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'447': {
-			userAgent: 'textractor.harvester/h3/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h3/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'452': {
-			userAgent: 'WIRE/0.11 (Linux; i686; Robot,Spider,Crawler,aromano@cli.di.unipi.it)',
-			metadata: {
-				uaFamily: 'WIRE',
-				uaName: 'WIRE/0.11 b',
-				uaUrl: 'http://www.cwr.cl/projects/WIRE/',
-				uaCompany: 'Universidad de Chile',
-				uaCompanyUrl: 'http://www.dcc.uchile.cl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WIRE'
-			}
-		},
-		'456': {
-			userAgent: 'boitho.com-dc/0.85 ( http://www.boitho.com/dcbot.html )',
-			metadata: {
-				uaFamily: 'boitho.com-dc',
-				uaName: 'boitho.com-dc/0.85',
-				uaUrl: 'http://www.boitho.com/dcbot.html',
-				uaCompany: 'Boitho',
-				uaCompanyUrl: 'http://www.boitho.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=boitho.com-dc'
-			}
-		},
-		'462': {
-			userAgent: 'schibstedsokbot (compatible; Mozilla/5.0; MSIE 5.0; FAST FreshCrawler 6; +http://www.schibstedsok.no/bot/)',
-			metadata: {
-				uaFamily: 'schibstedsokbot',
-				uaName: 'schibstedsokbot',
-				uaUrl: '',
-				uaCompany: 'Schibsted ASA',
-				uaCompanyUrl: 'http://www.schibsted.no/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=schibstedsokbot'
-			}
-		},
-		'465': {
-			userAgent: 'NG-Search/0.90 (NG-SearchBot; http://www.ng-search.com;  )',
-			metadata: {
-				uaFamily: 'NG-Search',
-				uaName: 'NG-Search/0.90',
-				uaUrl: '',
-				uaCompany: 'NG-Marketing',
-				uaCompanyUrl: 'http://www.ng-search.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NG-Search'
-			}
-		},
-		'469': {
-			userAgent: 'WebRankSpider/1.37 (+http://ulm191.server4you.de/crawler/)',
-			metadata: {
-				uaFamily: 'WebRankSpider',
-				uaName: 'WebRankSpider/1.37',
-				uaUrl: 'http://ulm191.server4you.de/crawler/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebRankSpider'
-			}
-		},
-		'470': {
-			userAgent: 'Szukacz/1.5 (robot; www.szukacz.pl/html/jak_dziala_robot.html; info@szukacz.pl)',
-			metadata: {
-				uaFamily: 'Szukacz',
-				uaName: 'Szukacz/1.5',
-				uaUrl: 'http://www.szukacz.pl/jakdzialarobot.html',
-				uaCompany: '24 Godziny Sp. z o.o.',
-				uaCompanyUrl: 'http://www.szukacz.pl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Szukacz'
-			}
-		},
-		'471': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler   [bc12]',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden bc12',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'479': {
-			userAgent: 'KRetrieve/1.1/dbsearchexpert.com',
-			metadata: {
-				uaFamily: 'KRetrieve',
-				uaName: 'KRetrieve/1.1',
-				uaUrl: 'http://www.dbsearchexpert.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=KRetrieve'
-			}
-		},
-		'480': {
-			userAgent: 'Nusearch Spider (www.nusearch.com)',
-			metadata: {
-				uaFamily: 'NuSearch Spider',
-				uaName: 'NuSearch Spider - b',
-				uaUrl: 'http://www.nusearch.com/',
-				uaCompany: 'nusearch.com',
-				uaCompanyUrl: 'http://www.nusearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NuSearch Spider'
-			}
-		},
-		'481': {
-			userAgent: 'Link Valet Online 1.1',
-			metadata: {
-				uaFamily: 'Link Valet Online',
-				uaName: 'Link Valet Online 1.1',
-				uaUrl: 'http://valet.htmlhelp.com/',
-				uaCompany: 'Web Design Group',
-				uaCompanyUrl: 'http://www.htmlhelp.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Link Valet Online'
-			}
-		},
-		'482': {
-			userAgent: 'asked/Nutch-0.8 (web crawler; http://asked.jp; epicurus at gmail dot com)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'Nutch/0.8 at asked.jp',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'483': {
-			userAgent: 'Link Valet Online 1.2',
-			metadata: {
-				uaFamily: 'Link Valet Online',
-				uaName: 'Link Valet Online 1.2',
-				uaUrl: 'http://valet.htmlhelp.com/',
-				uaCompany: 'Web Design Group',
-				uaCompanyUrl: 'http://www.htmlhelp.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Link Valet Online'
-			}
-		},
-		'484': {
-			userAgent: "HouxouCrawler/Nutch-0.9-dev (houxou.com's nutch-based crawler which serves special interest on-line communities; http://www.houxou.com/crawler; crawler at houxou dot com)",
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'Nutch/0.9-dev at houxou.com',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'485': {
-			userAgent: 'BilgiBetaBot/0.8-dev (bilgi.com (Beta) ; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'Nutch/0.8-dev at bilgi.com',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'488': {
-			userAgent: 'egothor/8.0f (+http://ego.ms.mff.cuni.cz/)',
-			metadata: {
-				uaFamily: 'egothor',
-				uaName: 'egothor/8.0f',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed Univerzity Karlovi',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/cs/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=egothor'
-			}
-		},
-		'489': {
-			userAgent: 'TurnitinBot/2.0 (http://www.turnitin.com/robot/crawlerinfo.html)',
-			metadata: {
-				uaFamily: 'TurnitinBot',
-				uaName: 'TurnitinBot/2.0',
-				uaUrl: 'http://www.turnitin.com/robot/crawlerinfo.html',
-				uaCompany: 'iParadigms, LLC.',
-				uaCompanyUrl: 'http://www.iparadigms.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TurnitinBot'
-			}
-		},
-		'491': {
-			userAgent: "HouxouCrawler/Nutch-0.8 (houxou.com's nutch-based crawler which serves special interest on-line communities; http://www.houxou.com/crawler; crawler at houxou dot com)",
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'Nutch/0.8 at houxou.com',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'493': {
-			userAgent: 'NutchCVS/0.7.1 (Nutch; http://lucene.apache.org/nutch/bot.html; raphael@unterreuth.de)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCVS/0.7.1 at unterreuth.de',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'494': {
-			userAgent: 'www.adressendeutschland.de',
-			metadata: {
-				uaFamily: 'adressendeutschland.de',
-				uaName: 'adressendeutschland.de',
-				uaUrl: 'http://www.adressendeutschland.de/konzept.html',
-				uaCompany: 'http://www.arktosmedia.de/',
-				uaCompanyUrl: 'Arktos MEDIA GmbH',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=adressendeutschland.de'
-			}
-		},
-		'496': {
-			userAgent: 'MetaTagRobot/2.1 (http://www.widexl.com/remote/search-engines/metatag-analyzer.html)',
-			metadata: {
-				uaFamily: 'MetaTagRobot',
-				uaName: 'MetaTagRobot/2.1',
-				uaUrl: 'http://www.widexl.com/remote/search-engines/metatag-analyzer.html',
-				uaCompany: '',
-				uaCompanyUrl: 'http://www.widexl.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetaTagRobot'
-			}
-		},
-		'499': {
-			userAgent: 'Cazoodle/Nutch-0.9-dev (Cazoodle Nutch Crawler; http://www.cazoodle.com; mqbot@cazoodle.com)',
-			metadata: {
-				uaFamily: 'CazoodleBot',
-				uaName: 'CazoodleBot a',
-				uaUrl: 'http://www.cazoodle.com/cazoodlebot.php',
-				uaCompany: 'Cazoodle Inc.',
-				uaCompanyUrl: 'http://www.cazoodle.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CazoodleBot'
-			}
-		},
-		'501': {
-			userAgent: 'Mozilla/3.0 (compatible; ScollSpider; http://www.webwobot.com)',
-			metadata: {
-				uaFamily: 'ScollSpider',
-				uaName: 'ScollSpider',
-				uaUrl: 'http://www.webwobot.com/ScollSpider.php',
-				uaCompany: 'WebWoBot.com',
-				uaCompanyUrl: 'http://www.webwobot.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ScollSpider'
-			}
-		},
-		'512': {
-			userAgent: 'Accoona-AI-Agent/1.1.2 (aicrawler at accoonabot dot com)',
-			metadata: {
-				uaFamily: 'Accoona-AI-Agent',
-				uaName: 'Accoona-AI-Agent/1.1.2',
-				uaUrl: '',
-				uaCompany: 'Accoona Corp.',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_accoona-ai-agent.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Accoona-AI-Agent'
-			}
-		},
-		'515': {
-			userAgent: 'NG-Search/0.9.8 (NG-SearchBot; http://www.ng-search.com)',
-			metadata: {
-				uaFamily: 'NG-Search',
-				uaName: 'NG-Search/0.9.8',
-				uaUrl: '',
-				uaCompany: 'NG-Marketing',
-				uaCompanyUrl: 'http://www.ng-search.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NG-Search'
-			}
-		},
-		'517': {
-			userAgent: 'holmes/3.9 (onet.pl)',
-			metadata: {
-				uaFamily: 'Holmes',
-				uaName: 'holmes/3.9 - onet.pl',
-				uaUrl: 'http://www.ucw.cz/holmes/',
-				uaCompany: 'Martin Mare\u0161 and Robert \u0160palek',
-				uaCompanyUrl: 'http://www.ucw.cz/holmes/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Holmes'
-			}
-		},
-		'520': {
-			userAgent: 'miniRank/2.0 (miniRank; http://minirank.com/; website ranking engine)',
-			metadata: {
-				uaFamily: 'miniRank',
-				uaName: 'miniRank/2.0',
-				uaUrl: 'http://www.minirank.com/',
-				uaCompany: 'TitaniumLine.com',
-				uaCompanyUrl: 'http://titaniumline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=miniRank'
-			}
-		},
-		'523': {
-			userAgent: 'sogou spider',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'sogou spider',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'525': {
-			userAgent: 'Megatext/Nutch-0.8.1 (Beta; http://www.megatext.cz/; microton@microton.cz)',
-			metadata: {
-				uaFamily: 'Megatext',
-				uaName: 'Megatext-0.8.1 beta',
-				uaUrl: '',
-				uaCompany: 'Microton, s.r.o.',
-				uaCompanyUrl: 'http://www.microton.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Megatext'
-			}
-		},
-		'528': {
-			userAgent: 'Mozilla/4.0 (compatible; MyFamilyBot/1.0; http://www.ancestry.com/learn/bot.aspx)',
-			metadata: {
-				uaFamily: 'MyFamilyBot',
-				uaName: 'MyFamilyBot/1.0 b',
-				uaUrl: 'http://www.ancestry.com/learn/bot.aspx',
-				uaCompany: 'MyFamily.com, Inc.',
-				uaCompanyUrl: 'http://www.myfamilyinc.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MyFamilyBot'
-			}
-		},
-		'531': {
-			userAgent: 'Mozilla/4.0 compatible FurlBot/Furl Search 2.0 (FurlBot; http://www.furl.net; wn.furlbot@looksmart.net)',
-			metadata: {
-				uaFamily: 'FurlBot',
-				uaName: 'FurlBot/Furl Search 2.0',
-				uaUrl: '',
-				uaCompany: 'LookSmart, Ltd.',
-				uaCompanyUrl: 'http://search.looksmart.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FurlBot'
-			}
-		},
-		'536': {
-			userAgent: 'Shim-Crawler(Mozilla-compatible; http://www.logos.ic.i.u-tokyo.ac.jp/crawl/; crawl@logos.ic.i.u-tokyo.ac.jp)',
-			metadata: {
-				uaFamily: 'Shim-Crawler',
-				uaName: 'Shim-Crawler - b',
-				uaUrl: 'http://www.logos.ic.i.u-tokyo.ac.jp/crawler/index.en.html',
-				uaCompany: 'Chikayama-Taura Lab, The University of Tokyo',
-				uaCompanyUrl: 'http://www.logos.ic.i.u-tokyo.ac.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Shim-Crawler'
-			}
-		},
-		'538': {
-			userAgent: 'Motoricerca-Robots.txt-Checker/1.0 (http://tool.motoricerca.info/robots-checker.phtml)',
-			metadata: {
-				uaFamily: 'Motoricerca-Robots.txt-Checker',
-				uaName: 'Motoricerca-Robots.txt-Checker/1.0',
-				uaUrl: 'http://tool.motoricerca.info/robots-checker.phtml',
-				uaCompany: 'Motoricerca.info',
-				uaCompanyUrl: 'http://www.motoricerca.info/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Motoricerca-Robots.txt-Checker'
-			}
-		},
-		'539': {
-			userAgent: 'Kongulo v0.1 personal web crawler',
-			metadata: {
-				uaFamily: 'Kongulo',
-				uaName: 'Kongulo v0.1',
-				uaUrl: 'http://goog-kongulo.sourceforge.net/',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Kongulo'
-			}
-		},
-		'540': {
-			userAgent: 'ichiro/2.01 (http://help.goo.ne.jp/door/crawler.html)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/2.01',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'545': {
-			userAgent: 'sproose/1.0beta (sproose bot; http://www.sproose.com/bot.html; crawler@sproose.com)',
-			metadata: {
-				uaFamily: 'Sproose',
-				uaName: 'Sproose/1.0beta',
-				uaUrl: 'http://www.sproose.com/bot.html',
-				uaCompany: 'Sproose, Inc.',
-				uaCompanyUrl: 'http://www.sproose.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sproose'
-			}
-		},
-		'546': {
-			userAgent: 'MSRBOT (http://research.microsoft.com/research/sv/msrbot/)',
-			metadata: {
-				uaFamily: 'MSRBOT',
-				uaName: 'MSRBOT b',
-				uaUrl: 'http://research.microsoft.com/research/sv/msrbot/',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSRBOT'
-			}
-		},
-		'547': {
-			userAgent: 'envolk/1.7 (+http://www.envolk.com/envolkspiderinfo.html)',
-			metadata: {
-				uaFamily: 'envolk',
-				uaName: 'envolk/1.7',
-				uaUrl: 'http://www.envolk.com/envolkspiderinfo.html',
-				uaCompany: 'Envolk',
-				uaCompanyUrl: 'http://www.envolk.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=envolk'
-			}
-		},
-		'548': {
-			userAgent: 'Blaiz-Bee/2.00.5622 (+http://www.blaiz.net)',
-			metadata: {
-				uaFamily: 'Blaiz-Bee',
-				uaName: 'Blaiz-Bee/2.00.5622',
-				uaUrl: 'http://www.rawgrunt.com/index.html',
-				uaCompany: 'Blaiz Enterprises',
-				uaCompanyUrl: 'http://www.blaiz.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Blaiz-Bee'
-			}
-		},
-		'554': {
-			userAgent: 'holmes/3.9 (OnetSzukaj/5.0; +http://szukaj.onet.pl)',
-			metadata: {
-				uaFamily: 'Holmes',
-				uaName: 'holmes/3.9 - onet.pl b',
-				uaUrl: 'http://www.ucw.cz/holmes/',
-				uaCompany: 'Martin Mare\u0161 and Robert \u0160palek',
-				uaCompanyUrl: 'http://www.ucw.cz/holmes/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Holmes'
-			}
-		},
-		'556': {
-			userAgent: 'EDI/1.6.5 (Edacious & Intelligent Web Robot, Daum Communications Corp.)',
-			metadata: {
-				uaFamily: 'EDI',
-				uaName: 'EDI/1.6.5',
-				uaUrl: '',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EDI'
-			}
-		},
-		'560': {
-			userAgent: 'ccubee/9.0',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/9.0',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'562': {
-			userAgent: 'MQBOT/Nutch-0.9-dev (MQBOT Nutch Crawler; http://falcon.cs.uiuc.edu; mqbot@cs.uiuc.edu)',
-			metadata: {
-				uaFamily: 'MQbot',
-				uaName: 'MQBOT/Nutch-0.9-dev',
-				uaUrl: 'http://metaquerier.cs.uiuc.edu/crawler/',
-				uaCompany: 'University of Illinois at Urbana-Champaign',
-				uaCompanyUrl: 'http://www.uiuc.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MQbot'
-			}
-		},
-		'563': {
-			userAgent: 'Mozilla/5.0 (compatible; nextthing.org/1.0; +http://www.nextthing.org/bot)',
-			metadata: {
-				uaFamily: 'nextthing.org',
-				uaName: 'nextthing.org/1.0',
-				uaUrl: 'http://www.nextthing.org/bot/',
-				uaCompany: 'Andrew Wooster',
-				uaCompanyUrl: 'http://www.cs.hmc.edu/~awooster/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=nextthing.org'
-			}
-		},
-		'564': {
-			userAgent: 'crawler43.ejupiter.com',
-			metadata: {
-				uaFamily: 'ejupiter.com',
-				uaName: 'ejupiter.com 43',
-				uaUrl: 'http://robot.ejupiter.com/16/robot_privacy.html',
-				uaCompany: 'eJupiter Inc',
-				uaCompanyUrl: 'http://www.ejupiter.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ejupiter.com'
-			}
-		},
-		'565': {
-			userAgent: 'Szukacz/1.5 (robot; www.szukacz.pl/jakdzialarobot.html; info@szukacz.pl)',
-			metadata: {
-				uaFamily: 'Szukacz',
-				uaName: 'Szukacz/1.5 b',
-				uaUrl: 'http://www.szukacz.pl/jakdzialarobot.html',
-				uaCompany: '24 Godziny Sp. z o.o.',
-				uaCompanyUrl: 'http://www.szukacz.pl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Szukacz'
-			}
-		},
-		'566': {
-			userAgent: 'Mozilla/5.0 (compatible; BecomeBot/3.0; +http://www.become.com/site_owners.html)',
-			metadata: {
-				uaFamily: 'BecomeBot',
-				uaName: 'BecomeBot/3.0 b',
-				uaUrl: 'http://www.become.com/site_owners.html',
-				uaCompany: 'Become, Inc.',
-				uaCompanyUrl: 'http://www.become.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BecomeBot'
-			}
-		},
-		'567': {
-			userAgent: 'Steeler/3.2 (http://www.tkl.iis.u-tokyo.ac.jp/~crawler/)',
-			metadata: {
-				uaFamily: 'Steeler',
-				uaName: 'Steeler/3.2',
-				uaUrl: 'http://www.tkl.iis.u-tokyo.ac.jp/~crawler/',
-				uaCompany: 'Kitsuregawa Laboratory, The University of Tokyo',
-				uaCompanyUrl: 'http://www.tkl.iis.u-tokyo.ac.jp/',
-				uaIcon: 'bot_Steeler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Steeler'
-			}
-		},
-		'569': {
-			userAgent: 'Mozilla/4.0 (compatible; EDI/1.6.6; Edacious & Intelligent Web Robot; Daum Communications Corp., Korea)',
-			metadata: {
-				uaFamily: 'EDI',
-				uaName: 'EDI/1.6.6',
-				uaUrl: '',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EDI'
-			}
-		},
-		'580': {
-			userAgent: 'Blaiz-Bee/2.00.5655 (+http://www.blaiz.net)',
-			metadata: {
-				uaFamily: 'Blaiz-Bee',
-				uaName: 'Blaiz-Bee/2.00.5655',
-				uaUrl: 'http://www.rawgrunt.com/index.html',
-				uaCompany: 'Blaiz Enterprises',
-				uaCompanyUrl: 'http://www.blaiz.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Blaiz-Bee'
-			}
-		},
-		'581': {
-			userAgent: "Zeusbot/0.07 (Ulysseek's web-crawling robot; http://www.zeusbot.com; agent@zeusbot.com)",
-			metadata: {
-				uaFamily: 'Zeusbot',
-				uaName: 'Zeusbot/0.07',
-				uaUrl: 'http://www.zeusbot.com/',
-				uaCompany: 'Ulysseek',
-				uaCompanyUrl: 'http://www.ulysseek.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Zeusbot'
-			}
-		},
-		'587': {
-			userAgent: 'MQBOT/Nutch-0.9-dev (MQBOT Crawler; http://falcon.cs.uiuc.edu; mqbot@cs.uiuc.edu)',
-			metadata: {
-				uaFamily: 'MQbot',
-				uaName: 'MQBOT/Nutch-0.9-dev b',
-				uaUrl: 'http://metaquerier.cs.uiuc.edu/crawler/',
-				uaCompany: 'University of Illinois at Urbana-Champaign',
-				uaCompanyUrl: 'http://www.uiuc.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MQbot'
-			}
-		},
-		'588': {
-			userAgent: 'CazoodleBot/Nutch-0.9-dev (CazoodleBot Crawler; http://www.cazoodle.com; mqbot@cazoodle.com)',
-			metadata: {
-				uaFamily: 'CazoodleBot',
-				uaName: 'CazoodleBot d',
-				uaUrl: 'http://www.cazoodle.com/cazoodlebot.php',
-				uaCompany: 'Cazoodle Inc.',
-				uaCompanyUrl: 'http://www.cazoodle.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CazoodleBot'
-			}
-		},
-		'594': {
-			userAgent: 'ccubee/10.0',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/10.0',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'597': {
-			userAgent: 'Mozilla/5.0 (compatible; egothor/8.0g; +http://ego.ms.mff.cuni.cz/)',
-			metadata: {
-				uaFamily: 'egothor',
-				uaName: 'egothor/8.0g',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed Univerzity Karlovi',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/cs/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=egothor'
-			}
-		},
-		'600': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE is not me; EDI/1.6.6; Edacious & Intelligent Web Robot; Daum Communications Corp., Korea)',
-			metadata: {
-				uaFamily: 'EDI',
-				uaName: 'EDI/1.6.6 b',
-				uaUrl: '',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EDI'
-			}
-		},
-		'602': {
-			userAgent: 'Bigsearch.ca/Nutch-0.9-dev (Bigsearch.ca Internet Spider; http://www.bigsearch.ca/; info@enhancededge.com)',
-			metadata: {
-				uaFamily: 'Bigsearch.ca',
-				uaName: 'Bigsearch.ca/Nutch-0.9-dev',
-				uaUrl: '',
-				uaCompany: 'bigsearch.ca',
-				uaCompanyUrl: 'http://www.bigsearch.ca/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Bigsearch.ca'
-			}
-		},
-		'605': {
-			userAgent: 'Yandex/1.01.001 (compatible; Win16; I)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'Yandex/1.01.001',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'606': {
-			userAgent: 'SBIder/SBIder-0.8.2-dev (http://www.sitesell.com/sbider.html)',
-			metadata: {
-				uaFamily: 'SBIder',
-				uaName: 'SBIder-0.8.2-dev',
-				uaUrl: 'http://www.sitesell.com/sbider.html',
-				uaCompany: 'SiteSell Inc.',
-				uaCompanyUrl: 'http://www.sitesell.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SBIder'
-			}
-		},
-		'608': {
-			userAgent: 'Combine/3 http://combine.it.lth.se/',
-			metadata: {
-				uaFamily: 'Combine',
-				uaName: 'Combine/3',
-				uaUrl: 'http://combine.it.lth.se/',
-				uaCompany: 'Lunds universitet',
-				uaCompanyUrl: 'http://www.lu.se/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Combine'
-			}
-		},
-		'609': {
-			userAgent: 'Megatext/Megatext-0.5 (beta; http://www.megatext.cz/; microton@microton.cz)',
-			metadata: {
-				uaFamily: 'Megatext',
-				uaName: 'Megatext-0.5 beta',
-				uaUrl: '',
-				uaCompany: 'Microton, s.r.o.',
-				uaCompanyUrl: 'http://www.microton.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Megatext'
-			}
-		},
-		'612': {
-			userAgent: 'VMBot/0.7.2 (VMBot; http://www.VerticalMatch.com/; vmbot@tradedot.com)',
-			metadata: {
-				uaFamily: 'VMBot',
-				uaName: 'VMBot/0.7.2',
-				uaUrl: '',
-				uaCompany: 'Vertical Search Engine (China)',
-				uaCompanyUrl: 'http://www.verticalmatch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VMBot'
-			}
-		},
-		'616': {
-			userAgent: 'Mozilla/5.0 (compatible; polixea.de-Robot +http://www.polixea.de)',
-			metadata: {
-				uaFamily: 'polixea.de',
-				uaName: 'polixea.de',
-				uaUrl: '',
-				uaCompany: 'POLIXEA AG',
-				uaCompanyUrl: 'http://www.polixea.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=polixea.de'
-			}
-		},
-		'623': {
-			userAgent: 'HiddenMarket-1.0-beta (www.hiddenmarket.net/crawler.php)',
-			metadata: {
-				uaFamily: 'HiddenMarket',
-				uaName: 'HiddenMarket-1.0-beta',
-				uaUrl: 'http://www.hiddenmarket.net/crawler.php',
-				uaCompany: 'HiddenMarket Group, Inc.',
-				uaCompanyUrl: 'http://www.hiddenmarket.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HiddenMarket'
-			}
-		},
-		'624': {
-			userAgent: 'Mozdex/0.7.1 (Mozdex; http://www.mozdex.com/bot.html; spider@mozdex.com)',
-			metadata: {
-				uaFamily: 'mozDex',
-				uaName: 'Mozdex/0.7.1',
-				uaUrl: 'http://www.mozdex.com/bot.html',
-				uaCompany: 'Mozdex.com',
-				uaCompanyUrl: 'http://www.mozdex.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=mozDex'
-			}
-		},
-		'626': {
-			userAgent: 'www.fi crawler, contact crawler@www.fi',
-			metadata: {
-				uaFamily: 'www.fi crawler',
-				uaName: 'www.fi crawler',
-				uaUrl: '',
-				uaCompany: 'Fonecta',
-				uaCompanyUrl: 'http://www.fonecta.fi/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=www.fi crawler'
-			}
-		},
-		'629': {
-			userAgent: 'Visbot/1.1 (Visvo.com - The Category Search Engine!; http://www.visvo.com/bot.html; bot@visvo.com)',
-			metadata: {
-				uaFamily: 'Visbot',
-				uaName: 'Visbot/1.1',
-				uaUrl: 'http://www.visvo.com/webmasters.html',
-				uaCompany: 'Visvo Inc.',
-				uaCompanyUrl: 'http://www.visvo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Visbot'
-			}
-		},
-		'630': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE is not me; DAUMOA/1.0.0; DAUM Web Robot; Daum Communications Corp., Korea)',
-			metadata: {
-				uaFamily: 'Daumoa',
-				uaName: 'DAUMOA/1.0.0',
-				uaUrl: 'http://tab.search.daum.net/aboutWebSearch_en.html',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Daumoa'
-			}
-		},
-		'631': {
-			userAgent: 'LapozzBot/1.4 (+http://robot.lapozz.hu)',
-			metadata: {
-				uaFamily: 'LapozzBot',
-				uaName: 'LapozzBot/1.4 hu',
-				uaUrl: 'http://robot.lapozz.hu/',
-				uaCompany: 'lapozz.hu',
-				uaCompanyUrl: 'http://www.lapozz.hu/',
-				uaIcon: 'bot_lapozzbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LapozzBot'
-			}
-		},
-		'632': {
-			userAgent: 'LapozzBot/1.4 (+http://robot.lapozz.com)',
-			metadata: {
-				uaFamily: 'LapozzBot',
-				uaName: 'LapozzBot/1.4 com',
-				uaUrl: 'http://robot.lapozz.com/',
-				uaCompany: 'lapozz.hu',
-				uaCompanyUrl: 'http://www.lapozz.hu/',
-				uaIcon: 'bot_lapozzbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LapozzBot'
-			}
-		},
-		'633': {
-			userAgent: 'Krugle/Krugle,Nutch/0.8+ (Krugle web crawler; http://corp.krugle.com/crawler/info.html; webcrawler@krugle.com)',
-			metadata: {
-				uaFamily: 'Krugle',
-				uaName: 'Krugle (Nutch/0.8+) b',
-				uaUrl: 'http://corp.krugle.com/crawler/info.html',
-				uaCompany: 'Steve Larsen',
-				uaCompanyUrl: 'http://blog.krugle.com/?page_id=5',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Krugle'
-			}
-		},
-		'645': {
-			userAgent: 'textractor.harvester/h2/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h2/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'646': {
-			userAgent: 'textractor.harvester/h27/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h27/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'648': {
-			userAgent: 'textractor.harvester/h24/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h24/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'652': {
-			userAgent: 'Mozilla/4.0 (compatible; DepSpid/5.07; +http://about.depspid.net)',
-			metadata: {
-				uaFamily: 'DepSpid',
-				uaName: 'DepSpid/5.07',
-				uaUrl: 'http://about.depspid.net/',
-				uaCompany: 'Bjoern Henke',
-				uaCompanyUrl: 'http://www.bjoernhenke.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DepSpid'
-			}
-		},
-		'653': {
-			userAgent: 'YodaoBot/1.0 (http://www.yodao.com/help/webmaster/spider/; )',
-			metadata: {
-				uaFamily: 'YodaoBot',
-				uaName: 'YodaoBot/1.0',
-				uaUrl: 'http://www.yodao.com/help/webmaster/spider/',
-				uaCompany: 'Yodao',
-				uaCompanyUrl: 'http://www.yodao.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YodaoBot'
-			}
-		},
-		'656': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 4.0; Girafabot; girafabot at girafa dot com; http://www.girafa.com)',
-			metadata: {
-				uaFamily: 'Girafabot',
-				uaName: 'Girafabot b',
-				uaUrl: '',
-				uaCompany: 'Girafa Inc.',
-				uaCompanyUrl: 'http://www.girafa.com/',
-				uaIcon: 'bot_girafabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Girafabot'
-			}
-		},
-		'657': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; Girafabot [girafa.com])',
-			metadata: {
-				uaFamily: 'Girafabot',
-				uaName: 'Girafabot c',
-				uaUrl: '',
-				uaCompany: 'Girafa Inc.',
-				uaCompanyUrl: 'http://www.girafa.com/',
-				uaIcon: 'bot_girafabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Girafabot'
-			}
-		},
-		'658': {
-			userAgent: 'VERASYS 2k Mozilla/4.0 (compatible; en) (compatible; MSIE 6.0; Windows NT 5.2; (+ http://web.verasys.ro); SV1; Unix; .NET CLR 1.1.4322)',
-			metadata: {
-				uaFamily: 'VERASYS 2k',
-				uaName: 'VERASYS 2k',
-				uaUrl: 'http://www.ghita.ro/article/1/verasys_2k.html',
-				uaCompany: 'Serban Ghita',
-				uaCompanyUrl: 'http://www.ghita.ro/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VERASYS 2k'
-			}
-		},
-		'665': {
-			userAgent: 'Blaiz-Bee/2.00.6082 (+http://www.blaiz.net)',
-			metadata: {
-				uaFamily: 'Blaiz-Bee',
-				uaName: 'Blaiz-Bee/2.00.6082',
-				uaUrl: 'http://www.rawgrunt.com/index.html',
-				uaCompany: 'Blaiz Enterprises',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Blaiz-Bee'
-			}
-		},
-		'669': {
-			userAgent: 'holmes/3.10.1 (OnetSzukaj/5.0; +http://szukaj.onet.pl)',
-			metadata: {
-				uaFamily: 'Holmes',
-				uaName: 'holmes/3.10.1 - onet.pl',
-				uaUrl: 'http://www.ucw.cz/holmes/',
-				uaCompany: 'Martin Mare\u0161 and Robert \u0160palek',
-				uaCompanyUrl: 'http://www.ucw.cz/holmes/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Holmes'
-			}
-		},
-		'671': {
-			userAgent: 'http://www.almaden.ibm.com/cs/crawler',
-			metadata: {
-				uaFamily: 'Almaden',
-				uaName: 'Almaden',
-				uaUrl: 'http://www.almaden.ibm.com/cs/crawler/',
-				uaCompany: 'IBM Almaden Research Center',
-				uaCompanyUrl: 'http://www.almaden.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Almaden'
-			}
-		},
-		'676': {
-			userAgent: 'AdsBot-Google (+http://www.google.com/adsbot.html)',
-			metadata: {
-				uaFamily: 'AdsBot-Google',
-				uaName: 'AdsBot-Google',
-				uaUrl: 'http://www.google.com/adsbot.html',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AdsBot-Google'
-			}
-		},
-		'678': {
-			userAgent: 'LinkWalker/2.0',
-			metadata: {
-				uaFamily: 'LinkWalker',
-				uaName: 'LinkWalker/2.0',
-				uaUrl: '',
-				uaCompany: 'SEVENtwentyfour Inc.',
-				uaCompanyUrl: 'http://www.seventwentyfour.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LinkWalker'
-			}
-		},
-		'679': {
-			userAgent: 'Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)',
-			metadata: {
-				uaFamily: 'Exabot',
-				uaName: 'Exabot/3.0',
-				uaUrl: 'http://www.exabot.com/go/robot',
-				uaCompany: 'Exalead S.A.',
-				uaCompanyUrl: 'http://www.exalead.com/',
-				uaIcon: 'bot_Exabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Exabot'
-			}
-		},
-		'688': {
-			userAgent: 'ConveraCrawler/0.9e (+http://www.authoritativeweb.com/crawl)',
-			metadata: {
-				uaFamily: 'ConveraCrawler',
-				uaName: 'ConveraCrawler 0.9e',
-				uaUrl: 'http://www.authoritativeweb.com/crawl',
-				uaCompany: 'Convera Corporation',
-				uaCompanyUrl: 'http://www.authoritativeweb.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ConveraCrawler'
-			}
-		},
-		'689': {
-			userAgent: 'miniRank/3.1 (miniRank; www.minirank.com; website ranking engine)',
-			metadata: {
-				uaFamily: 'miniRank',
-				uaName: 'miniRank/3.1',
-				uaUrl: 'http://www.minirank.com/',
-				uaCompany: 'TitaniumLine.com',
-				uaCompanyUrl: 'http://titaniumline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=miniRank'
-			}
-		},
-		'690': {
-			userAgent: 'Pingdom GIGRIB (http://www.pingdom.com)',
-			metadata: {
-				uaFamily: 'pingdom.com_bot',
-				uaName: 'Pingdom GIGRIB',
-				uaUrl: 'http://uptime.pingdom.com/general/what_is',
-				uaCompany: 'Pingdom',
-				uaCompanyUrl: 'http://www.pingdom.com/',
-				uaIcon: 'bot_pingdomcom_bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=pingdom.com_bot'
-			}
-		},
-		'694': {
-			userAgent: 'Mozilla/5.0 (compatible; Ask Jeeves/Teoma; +http://about.ask.com/en/docs/about/webmasters.shtml)',
-			metadata: {
-				uaFamily: 'Ask Jeeves/Teoma',
-				uaName: 'Ask Jeeves/Teoma',
-				uaUrl: 'http://about.ask.com/en/docs/about/webmasters.shtml',
-				uaCompany: 'Ask Jeeves Inc.',
-				uaCompanyUrl: 'http://about.ask.com/en/docs/about/index.shtml',
-				uaIcon: 'bot_AskJeeves.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ask Jeeves/Teoma'
-			}
-		},
-		'698': {
-			userAgent: 'VMBot/0.9 (VMBot; http://www.verticalmatch.com; vmbot@tradedot.com)',
-			metadata: {
-				uaFamily: 'VMBot',
-				uaName: 'VMBot/0.9',
-				uaUrl: '',
-				uaCompany: 'Vertical Search Engine (China)',
-				uaCompanyUrl: 'http://www.verticalmatch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VMBot'
-			}
-		},
-		'703': {
-			userAgent: 'TurnitinBot/2.1 (http://www.turnitin.com/robot/crawlerinfo.html)',
-			metadata: {
-				uaFamily: 'TurnitinBot',
-				uaName: 'TurnitinBot/2.1',
-				uaUrl: 'http://www.turnitin.com/robot/crawlerinfo.html',
-				uaCompany: 'iParadigms, LLC.',
-				uaCompanyUrl: 'http://www.iparadigms.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TurnitinBot'
-			}
-		},
-		'710': {
-			userAgent: 'heeii/Nutch-0.9-dev (heeii.com; www.heeii.com; nutch at heeii.com)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'heeii/Nutch-0.9-dev at heeii.com',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'712': {
-			userAgent: 'Mozilla/5.0 (compatible; BecomeJPBot/2.3; MSIE 6.0 compatible; +http://www.become.co.jp/site_owners.html)',
-			metadata: {
-				uaFamily: 'BecomeBot',
-				uaName: 'BecomeBot/2.3 b',
-				uaUrl: 'http://www.become.com/site_owners.html',
-				uaCompany: 'Become, Inc.',
-				uaCompanyUrl: 'http://www.become.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BecomeBot'
-			}
-		},
-		'715': {
-			userAgent: 'AdsBot-Google',
-			metadata: {
-				uaFamily: 'AdsBot-Google',
-				uaName: 'AdsBot-Google b',
-				uaUrl: 'http://www.google.com/adsbot.html',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AdsBot-Google'
-			}
-		},
-		'716': {
-			userAgent: "HouxouCrawler/Nutch-0.8.2-dev (houxou.com's nutch-based crawler which serves special interest on-line communities; http://www.houxou.com/crawler; crawler at houxou dot com)",
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'Nutch/0.8.2-dev at houxou.com',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'725': {
-			userAgent: 'DataFountains/Dmoz Downloader (http://ivia.ucr.edu/useragents.shtml)',
-			metadata: {
-				uaFamily: 'DataFountains',
-				uaName: 'DataFountains at Dmoz',
-				uaUrl: 'http://ivia.ucr.edu/useragents.shtml',
-				uaCompany: 'University of California',
-				uaCompanyUrl: 'http://www.universityofcalifornia.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DataFountains'
-			}
-		},
-		'728': {
-			userAgent: 'Mozilla/5.0 (compatible; YodaoBot/1.0; http://www.yodao.com/help/webmaster/spider/; )',
-			metadata: {
-				uaFamily: 'YodaoBot',
-				uaName: 'YodaoBot/1.0',
-				uaUrl: 'http://www.yodao.com/help/webmaster/spider/',
-				uaCompany: 'yodao.com',
-				uaCompanyUrl: 'http://www.yodao.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YodaoBot'
-			}
-		},
-		'729': {
-			userAgent: 'IRLbot/3.0 (compatible; MSIE 6.0; http://irl.cs.tamu.edu/crawler)',
-			metadata: {
-				uaFamily: 'IRLbot',
-				uaName: 'IRLbot/3.0',
-				uaUrl: 'http://irl.cs.tamu.edu/crawler/',
-				uaCompany: 'Texas A&M University',
-				uaCompanyUrl: 'http://www.tamu.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IRLbot'
-			}
-		},
-		'731': {
-			userAgent: 'Mozilla/5.0 (compatible; del.icio.us-thumbnails/1.0; FreeBSD) KHTML/4.3.2 (like Gecko)',
-			metadata: {
-				uaFamily: 'del.icio.us-thumbnails',
-				uaName: 'del.icio.us-thumbnails/1.0',
-				uaUrl: '',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=del.icio.us-thumbnails'
-			}
-		},
-		'741': {
-			userAgent: 'Gallent Search Spider v1.4 Robot 3 (http://www.GallentSearch.com/robot)',
-			metadata: {
-				uaFamily: 'Gallent Search Spider',
-				uaName: 'Gallent Search Spider v1.4 Robot 3',
-				uaUrl: '',
-				uaCompany: 'Gallent Limited',
-				uaCompanyUrl: 'http://www.gallentsearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Gallent Search Spider'
-			}
-		},
-		'742': {
-			userAgent: 'CazoodleBot/0.1 (CazoodleBot Crawler; http://www.cazoodle.com; mqbot@cazoodle.com)',
-			metadata: {
-				uaFamily: 'CazoodleBot',
-				uaName: 'CazoodleBot b',
-				uaUrl: 'http://www.cazoodle.com/cazoodlebot.php',
-				uaCompany: 'Cazoodle Inc.',
-				uaCompanyUrl: 'http://www.cazoodle.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CazoodleBot'
-			}
-		},
-		'747': {
-			userAgent: 'ShopWiki/1.0 ( +http://www.shopwiki.com/wiki/Help:Bot)',
-			metadata: {
-				uaFamily: 'ShopWiki',
-				uaName: 'ShopWiki/1.0',
-				uaUrl: 'http://www.shopwiki.com/wiki/Help:Bot',
-				uaCompany: 'ShopWiki Corp',
-				uaCompanyUrl: 'http://www.shopwiki.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ShopWiki'
-			}
-		},
-		'749': {
-			userAgent: 'Blaiz-Bee/2.00.8315 (BE Internet Search Engine http://www.rawgrunt.com)',
-			metadata: {
-				uaFamily: 'Blaiz-Bee',
-				uaName: 'Blaiz-Bee/2.00.8315',
-				uaUrl: 'http://www.rawgrunt.com/index.html',
-				uaCompany: 'Blaiz Enterprises',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Blaiz-Bee'
-			}
-		},
-		'752': {
-			userAgent: 'del.icio.us-thumbnails/1.0 Mozilla/5.0 (compatible; Konqueror/3.4; FreeBSD) KHTML/3.4.2 (like Gecko)',
-			metadata: {
-				uaFamily: 'del.icio.us-thumbnails',
-				uaName: 'del.icio.us-thumbnails/1.0',
-				uaUrl: '',
-				uaCompany: 'Yahoo!',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=del.icio.us-thumbnails'
-			}
-		},
-		'753': {
-			userAgent: 'Mozilla/5.0 (compatible; Exabot-Images/3.0; +http://www.exabot.com/go/robot)',
-			metadata: {
-				uaFamily: 'Exabot',
-				uaName: 'Exabot-Images/3.0',
-				uaUrl: 'http://www.exabot.com/go/robot',
-				uaCompany: 'Exalead S.A.',
-				uaCompanyUrl: 'http://www.exalead.com/',
-				uaIcon: 'bot_Exabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Exabot'
-			}
-		},
-		'754': {
-			userAgent: 'Snapbot/1.0 (+http://www.snap.com)',
-			metadata: {
-				uaFamily: 'Snapbot',
-				uaName: 'Snapbot/1.0 b',
-				uaUrl: '',
-				uaCompany: 'Snap',
-				uaCompanyUrl: 'http://www.snap.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Snapbot'
-			}
-		},
-		'755': {
-			userAgent: 'DataFountains/DMOZ Feature Vector Corpus Creator (http://ivia.ucr.edu/useragents.shtml)',
-			metadata: {
-				uaFamily: 'DataFountains',
-				uaName: 'DataFountains at Dmoz b',
-				uaUrl: 'http://ivia.ucr.edu/useragents.shtml',
-				uaCompany: 'University of California',
-				uaCompanyUrl: 'http://www.universityofcalifornia.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DataFountains'
-			}
-		},
-		'756': {
-			userAgent: 'HatenaScreenshot/1.0 (checker)',
-			metadata: {
-				uaFamily: 'HatenaScreenshot',
-				uaName: 'HatenaScreenshot/1.0 (checker)',
-				uaUrl: 'http://screenshot.hatena.ne.jp/help',
-				uaCompany: 'hatena',
-				uaCompanyUrl: 'http://www.hatena.ne.jp/company/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HatenaScreenshot'
-			}
-		},
-		'758': {
-			userAgent: 'Webscope/Nutch-0.9-dev (http://www.cs.washington.edu/homes/mjc/agent.html)',
-			metadata: {
-				uaFamily: 'Webscope Crawler',
-				uaName: 'Webscope Crawler',
-				uaUrl: 'http://www.cs.washington.edu/homes/mjc/agent.html',
-				uaCompany: 'University of Washington Computer Science & Engineering',
-				uaCompanyUrl: 'http://www.cs.washington.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Webscope Crawler'
-			}
-		},
-		'760': {
-			userAgent: 'posterus (seek.se) +http://www.seek.se/studio/index.php?id=47&t=details',
-			metadata: {
-				uaFamily: 'posterus',
-				uaName: 'posterus',
-				uaUrl: 'http://www.seek.se/studio/index.php?id=47&t=details',
-				uaCompany: 'Seek.se',
-				uaCompanyUrl: 'http://www.seek.se/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=posterus'
-			}
-		},
-		'761': {
-			userAgent: 'iaskspider/2.0(+http://iask.com/help/help_index.html)',
-			metadata: {
-				uaFamily: 'iaskspider',
-				uaName: 'iaskspider/2.0',
-				uaUrl: 'http://iask.com/help/help_index.html',
-				uaCompany: 'SINA Corporation',
-				uaCompanyUrl: 'http://corp.sina.com.cn/eng/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=iaskspider'
-			}
-		},
-		'764': {
-			userAgent: 'IlseBot/1.1',
-			metadata: {
-				uaFamily: 'IlseBot',
-				uaName: 'IlseBot/1.1',
-				uaUrl: '',
-				uaCompany: 'ilse.nl',
-				uaCompanyUrl: 'http://ilse.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IlseBot'
-			}
-		},
-		'765': {
-			userAgent: 'WebarooBot (Webaroo Bot; http://64.124.122.252/feedback.html)',
-			metadata: {
-				uaFamily: 'WebarooBot',
-				uaName: 'WebarooBot (Webaroo Bot)',
-				uaUrl: 'http://www.webaroo.com/company/site-owners',
-				uaCompany: 'Webaroo Inc.',
-				uaCompanyUrl: 'http://www.webaroo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebarooBot'
-			}
-		},
-		'768': {
-			userAgent: 'sogou web spider http://www.sogou.com/docs/help/webmasters.htm#07',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'sogou spider',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'770': {
-			userAgent: 'sogou web spider(+http://www.sogou.com/docs/help/webmasters.htm#07)',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'sogou spider',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'771': {
-			userAgent: 'NextGenSearchBot 1 (for information visit http://about.zoominfo.com/About/NextGenSearchBot.aspx)',
-			metadata: {
-				uaFamily: 'NextGenSearchBot',
-				uaName: 'NextGenSearchBot 1',
-				uaUrl: 'http://www.zoominfo.com/About/misc/NextGenSearchBot.aspx',
-				uaCompany: 'Zoom Information Inc.',
-				uaCompanyUrl: 'http://www.zoominfo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NextGenSearchBot'
-			}
-		},
-		'773': {
-			userAgent: 'Sogou web spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'Sogou web spider/3.0',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'774': {
-			userAgent: 'Mozilla/5.0 (compatible; LinksManager.com_bot +http://linksmanager.com/linkchecker.html)',
-			metadata: {
-				uaFamily: 'linksmanager_bot',
-				uaName: 'linksmanager_bot',
-				uaUrl: 'http://linksmanager.com/linkchecker.html',
-				uaCompany: 'CreativeNetVentures, Inc.',
-				uaCompanyUrl: 'http://cnvi.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=linksmanager_bot'
-			}
-		},
-		'778': {
-			userAgent: 'LarbinWebCrawler (spider@download11.com)',
-			metadata: {
-				uaFamily: 'LemurWebCrawler',
-				uaName: 'LabrinWebCrawler',
-				uaUrl: 'http://boston.lti.cs.cmu.edu/crawler_12/',
-				uaCompany: 'Language Technologies Institute',
-				uaCompanyUrl: 'http://www.lti.cs.cmu.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LemurWebCrawler'
-			}
-		},
-		'786': {
-			userAgent: 'wectar/Nutch-0.9 (wectar - wectar extracted from the glorious web; http://goosebumps4all.net/wectar)',
-			metadata: {
-				uaFamily: 'wectar',
-				uaName: 'wectar/Nutch-0.9',
-				uaUrl: 'http://wectar.com/',
-				uaCompany: 'Martin Dudek',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=wectar'
-			}
-		},
-		'788': {
-			userAgent: 'WebarooBot (Webaroo Bot; http://www.webaroo.com/rooSiteOwners.html)',
-			metadata: {
-				uaFamily: 'WebarooBot',
-				uaName: 'WebarooBot (Webaroo Bot) b',
-				uaUrl: 'http://www.webaroo.com/company/site-owners',
-				uaCompany: 'Webaroo Inc.',
-				uaCompanyUrl: 'http://www.webaroo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebarooBot'
-			}
-		},
-		'789': {
-			userAgent: 'Bigsearch.ca/Nutch-1.0-dev (Bigsearch.ca Internet Spider; http://www.bigsearch.ca/; info@enhancededge.com)',
-			metadata: {
-				uaFamily: 'Bigsearch.ca',
-				uaName: 'Bigsearch.ca/Nutch-1.0-dev',
-				uaUrl: '',
-				uaCompany: 'bigsearch.ca',
-				uaCompanyUrl: 'http://www.bigsearch.ca/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Bigsearch.ca'
-			}
-		},
-		'791': {
-			userAgent: 'MSRBOT (http://research.microsoft.com/research/sv/msrbot)',
-			metadata: {
-				uaFamily: 'MSRBOT',
-				uaName: 'MSRBOT c',
-				uaUrl: 'http://research.microsoft.com/research/sv/msrbot/',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSRBOT'
-			}
-		},
-		'797': {
-			userAgent: 'Jambot/0.1.1 (Jambot; http://www.jambot.com/blog; crawler@jambot.com)',
-			metadata: {
-				uaFamily: 'Jambot',
-				uaName: 'Jambot/0.1.1',
-				uaUrl: 'http://www.jambot.com/blog/static.php?page=webmaster-robot',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Jambot'
-			}
-		},
-		'798': {
-			userAgent: 'VisBot/2.0 (Visvo.com Crawler; http://www.visvo.com/bot.html; bot@visvo.com)',
-			metadata: {
-				uaFamily: 'Visbot',
-				uaName: 'Visbot/2.0',
-				uaUrl: 'http://www.visvo.com/webmasters.html',
-				uaCompany: 'Visvo Inc.',
-				uaCompanyUrl: 'http://www.visvo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Visbot'
-			}
-		},
-		'804': {
-			userAgent: 'Francis/2.0 (francis@neomo.de http://www.neomo.de/pages/crawler.php)',
-			metadata: {
-				uaFamily: 'Francis',
-				uaName: 'Francis/2.0',
-				uaUrl: 'http://www.neomo.de/pages/crawler.php',
-				uaCompany: 'Neomo GmbH & Co. KG.',
-				uaCompanyUrl: 'http://www.neomo.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Francis'
-			}
-		},
-		'805': {
-			userAgent: 'cinetic_htdig',
-			metadata: {
-				uaFamily: 'ht://Dig',
-				uaName: 'ht://Dig',
-				uaUrl: '',
-				uaCompany: 'The ht://Dig Group',
-				uaCompanyUrl: 'http://htdig.sourceforge.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ht://Dig'
-			}
-		},
-		'807': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE is not me; DAUMOA/1.0.1; DAUM Web Robot; Daum Communications Corp., Korea)',
-			metadata: {
-				uaFamily: 'Daumoa',
-				uaName: 'DAUMOA/1.0.1',
-				uaUrl: 'http://tab.search.daum.net/aboutWebSearch_en.html',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Daumoa'
-			}
-		},
-		'808': {
-			userAgent: 'favorstarbot/1.0 (+http://favorstar.com/bot.html)',
-			metadata: {
-				uaFamily: 'favorstarbot',
-				uaName: 'favorstarbot/1.0',
-				uaUrl: 'http://favorstar.com/bot.html',
-				uaCompany: 'favorstar.com',
-				uaCompanyUrl: 'http://favorstar.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=favorstarbot'
-			}
-		},
-		'809': {
-			userAgent: 'FAST Enterprise Crawler 6 used by FAST (jim.mosher@fastsearch.com)',
-			metadata: {
-				uaFamily: 'FAST Enterprise Crawler',
-				uaName: 'FAST Enterprise Crawler/6',
-				uaUrl: 'http://www.fast.no/glossary.aspx?m=48&amid=415',
-				uaCompany: 'Fast Search & Transfer',
-				uaCompanyUrl: 'http://www.fastsearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FAST Enterprise Crawler'
-			}
-		},
-		'811': {
-			userAgent: 'depspid - the dependency spider',
-			metadata: {
-				uaFamily: 'DepSpid',
-				uaName: 'DepSpid',
-				uaUrl: 'http://about.depspid.net/',
-				uaCompany: 'Bjoern Henke',
-				uaCompanyUrl: 'http://www.bjoernhenke.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DepSpid'
-			}
-		},
-		'812': {
-			userAgent: 'mozilla/4.0 (compatible; changedetection/1.0 (admin@changedetection.com))',
-			metadata: {
-				uaFamily: 'ChangeDetection',
-				uaName: 'changedetection/1.0',
-				uaUrl: '',
-				uaCompany: 'FreeFind.com',
-				uaCompanyUrl: 'http://www.freefind.com/',
-				uaIcon: 'bot_ChangeDetection.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ChangeDetection'
-			}
-		},
-		'813': {
-			userAgent: 'mozilla/4.0 (compatible; myfamilybot/1.0; http://www.ancestry.com/learn/bot.aspx)',
-			metadata: {
-				uaFamily: 'MyFamilyBot',
-				uaName: 'MyFamilyBot/1.0',
-				uaUrl: 'http://www.ancestry.com/learn/bot.aspx',
-				uaCompany: 'The Generations Network, Inc.',
-				uaCompanyUrl: 'http://www.myfamilyinc.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MyFamilyBot'
-			}
-		},
-		'814': {
-			userAgent: 'navissobot/1.7  (+http://navisso.com/)',
-			metadata: {
-				uaFamily: 'navissobot',
-				uaName: 'navissobot/1.7',
-				uaUrl: 'http://navisso.com/topics?c=navissobot',
-				uaCompany: 'Navisso Search',
-				uaCompanyUrl: 'http://navisso.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=navissobot'
-			}
-		},
-		'815': {
-			userAgent: 'Mozilla/5.0 (compatible; SnapPreviewBot; en-US; rv:1.8.0.9) Gecko/20061206 Firefox/1.5.0.9',
-			metadata: {
-				uaFamily: 'SnapBot',
-				uaName: 'SnapPreviewBot',
-				uaUrl: '',
-				uaCompany: 'Snap',
-				uaCompanyUrl: 'http://www.snap.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SnapBot'
-			}
-		},
-		'817': {
-			userAgent: 'Mozilla/5.0 (compatible; BuzzRankingBot/1.0; +http://www.buzzrankingbot.com/)',
-			metadata: {
-				uaFamily: 'BuzzRankingBot',
-				uaName: 'BuzzRankingBot/1.0',
-				uaUrl: 'http://www.buzzrankingbot.com/',
-				uaCompany: 'Matthieu Aubry',
-				uaCompanyUrl: 'http://giik.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BuzzRankingBot'
-			}
-		},
-		'820': {
-			userAgent: 'lmspider/Nutch-0.9-dev (For research purposes.; www.nuance.com)',
-			metadata: {
-				uaFamily: 'lmspider',
-				uaName: 'lmspider b',
-				uaUrl: 'http://www.nuance.com/',
-				uaCompany: 'Nuance Communications, Inc.',
-				uaCompanyUrl: 'http://www.nuance.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=lmspider'
-			}
-		},
-		'824': {
-			userAgent: 'ccubee/3.5',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/3.5',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'825': {
-			userAgent: 'Snapbot/1.0 (Snap Shots, +http://www.snap.com)',
-			metadata: {
-				uaFamily: 'Snapbot',
-				uaName: 'Snapbot/1.0 c',
-				uaUrl: '',
-				uaCompany: 'Snap',
-				uaCompanyUrl: 'http://www.snap.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Snapbot'
-			}
-		},
-		'829': {
-			userAgent: 'Acorn/Nutch-0.9 (Non-Profit Search Engine; acorn.isara.org; acorn at isara dot org)',
-			metadata: {
-				uaFamily: 'Acorn',
-				uaName: 'Acorn/Nutch-0.9',
-				uaUrl: 'http://acorn.isara.org/',
-				uaCompany: 'Isara',
-				uaCompanyUrl: 'http://www.isara.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Acorn'
-			}
-		},
-		'832': {
-			userAgent: 'nestReader/0.2 (discovery; http://echonest.com/reader.shtml; reader at echonest.com)',
-			metadata: {
-				uaFamily: 'nestReader',
-				uaName: 'nestReader/0.2',
-				uaUrl: 'http://echonest.com/reader.shtml',
-				uaCompany: 'The Echo Nest Corporation',
-				uaCompanyUrl: 'http://echonest.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=nestReader'
-			}
-		},
-		'833': {
-			userAgent: 'boitho.com-dc/0.86 ( http://www.boitho.com/dcbot.html )',
-			metadata: {
-				uaFamily: 'boitho.com-dc',
-				uaName: 'boitho.com-dc/0.86',
-				uaUrl: 'http://www.boitho.com/dcbot.html',
-				uaCompany: 'Boitho',
-				uaCompanyUrl: 'http://www.boitho.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=boitho.com-dc'
-			}
-		},
-		'835': {
-			userAgent: 'Snappy/1.1 ( http://www.urltrends.com/ )',
-			metadata: {
-				uaFamily: 'Snappy',
-				uaName: 'Snappy/1.1',
-				uaUrl: 'http://www.urltrends.com/',
-				uaCompany: 'Xerocity Design Group, LLC.',
-				uaCompanyUrl: 'http://www.xerocity.com/',
-				uaIcon: 'bot_snappy.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Snappy'
-			}
-		},
-		'844': {
-			userAgent: 'great-plains-web-spider/gpws (Flatland Industries Web Spider; http://www.flatlandindustries.com/flatlandbot.php; jason@flatlandindustries.com)',
-			metadata: {
-				uaFamily: 'flatlandbot',
-				uaName: 'flatlandbot c',
-				uaUrl: 'http://www.flatlandindustries.com/flatlandbot.php',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=flatlandbot'
-			}
-		},
-		'851': {
-			userAgent: 'Mozilla/5.0 (compatible; FunnelBack; http://cyan.funnelback.com/robot.html)',
-			metadata: {
-				uaFamily: 'FunnelBack',
-				uaName: 'FunnelBack',
-				uaUrl: 'http://cyan.funnelback.com/robot.html',
-				uaCompany: 'Funnelback Pty Ltd',
-				uaCompanyUrl: 'http://www.funnelback.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FunnelBack'
-			}
-		},
-		'856': {
-			userAgent: 'RedBot/redbot-1.0 (Rediff.com Crawler; redbot at rediff dot com)',
-			metadata: {
-				uaFamily: 'RedBot',
-				uaName: 'RedBot1.0',
-				uaUrl: '',
-				uaCompany: 'Rediff.com India Limited.',
-				uaCompanyUrl: 'http://www.rediff.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=RedBot'
-			}
-		},
-		'859': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.12.0 +http://www.accelobot.com)',
-			metadata: {
-				uaFamily: 'Accelobot',
-				uaName: 'Accelobot',
-				uaUrl: 'http://www.accelobot.com/',
-				uaCompany: 'NetBase Solutions, Inc.',
-				uaCompanyUrl: 'http://www.netbase.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Accelobot'
-			}
-		},
-		'861': {
-			userAgent: 'wectar/Nutch-0.9 (nectar extracted form the glorious web; http://goosebumps4all.net/wectar; see website)',
-			metadata: {
-				uaFamily: 'wectar',
-				uaName: 'wectar/Nutch-0.9 b',
-				uaUrl: 'http://wectar.com/',
-				uaCompany: 'Martin Dudek',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=wectar'
-			}
-		},
-		'865': {
-			userAgent: 'MQBOT/Nutch-0.9-dev (MQBOT Nutch Crawler; http://vwbot.cs.uiuc.edu; mqbot@cs.uiuc.edu)',
-			metadata: {
-				uaFamily: 'MQbot',
-				uaName: 'MQBOT/Nutch-0.9-dev c',
-				uaUrl: 'http://metaquerier.cs.uiuc.edu/crawler/',
-				uaCompany: 'University of Illinois at Urbana-Champaign',
-				uaCompanyUrl: 'http://www.uiuc.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MQbot'
-			}
-		},
-		'872': {
-			userAgent: 'Willow Internet Crawler by Twotrees V2.1',
-			metadata: {
-				uaFamily: 'Willow Internet Crawler',
-				uaName: 'Willow Internet Crawler 2.1',
-				uaUrl: '',
-				uaCompany: 'Twotrees Technologies, LLC.',
-				uaCompanyUrl: 'http://www.twotrees.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Willow Internet Crawler'
-			}
-		},
-		'873': {
-			userAgent: 'Netintelligence LiveAssessment - www.netintelligence.com',
-			metadata: {
-				uaFamily: 'Netintelligence LiveAssessment',
-				uaName: 'Netintelligence LiveAssessment',
-				uaUrl: '',
-				uaCompany: 'Netintelligence Limited',
-				uaCompanyUrl: 'http://www.netintelligence.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Netintelligence LiveAssessment'
-			}
-		},
-		'874': {
-			userAgent: 'Mozilla/5.0 (compatible; SkreemRBot +http://skreemr.com)',
-			metadata: {
-				uaFamily: 'SkreemRBot',
-				uaName: 'SkreemRBot',
-				uaUrl: '',
-				uaCompany: 'SkreemR',
-				uaCompanyUrl: 'http://skreemr.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SkreemRBot'
-			}
-		},
-		'876': {
-			userAgent: 'great-plains-web-spider/flatlandbot (Flatland Industries Web Robot; http://www.flatlandindustries.com/flatlandbot.php; jason@flatlandindustries.com)',
-			metadata: {
-				uaFamily: 'flatlandbot',
-				uaName: 'flatlandbot b',
-				uaUrl: 'http://www.flatlandindustries.com/flatlandbot.php',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=flatlandbot'
-			}
-		},
-		'877': {
-			userAgent: 'flatlandbot/flatlandbot (Flatland Industries Web Spider; http://www.flatlandindustries.com/flatlandbot.php; jason@flatlandindustries.com)',
-			metadata: {
-				uaFamily: 'flatlandbot',
-				uaName: 'flatlandbot',
-				uaUrl: 'http://www.flatlandindustries.com/flatlandbot.php',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=flatlandbot'
-			}
-		},
-		'881': {
-			userAgent: 'Larbin (larbin2.6.3@unspecified.mail)',
-			metadata: {
-				uaFamily: 'Larbin',
-				uaName: 'Larbin/2.6.3',
-				uaUrl: '',
-				uaCompany: 'Sebastien Ailleret',
-				uaCompanyUrl: 'http://larbin.sourceforge.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Larbin'
-			}
-		},
-		'882': {
-			userAgent: 'InternetSeer.com',
-			metadata: {
-				uaFamily: 'InternetSeer',
-				uaName: 'InternetSeer (Web Monitor)',
-				uaUrl: '',
-				uaCompany: 'InternetSeer',
-				uaCompanyUrl: 'http://internetseer.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=InternetSeer'
-			}
-		},
-		'886': {
-			userAgent: 'panscient.com',
-			metadata: {
-				uaFamily: 'Panscient web crawler',
-				uaName: 'Panscient web crawler',
-				uaUrl: 'http://panscient.com/faq.html',
-				uaCompany: 'Panscient, Inc.',
-				uaCompanyUrl: 'http://panscient.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Panscient web crawler'
-			}
-		},
-		'888': {
-			userAgent: 'void-bot/0.1 (bot@void.be; http://www.void.be/)',
-			metadata: {
-				uaFamily: 'void-bot',
-				uaName: 'void-bot/0.1',
-				uaUrl: 'http://www.void.be/void-bot.html',
-				uaCompany: 'Void Security',
-				uaCompanyUrl: 'http://www.void.be/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=void-bot'
-			}
-		},
-		'890': {
-			userAgent: 'Mozilla/2.0 (compatible; Ask Jeeves/Teoma; http://about.ask.com/en/docs/about/webmasters.shtml)',
-			metadata: {
-				uaFamily: 'Ask Jeeves/Teoma',
-				uaName: 'Ask Jeeves/Teoma - d',
-				uaUrl: 'http://about.ask.com/en/docs/about/webmasters.shtml',
-				uaCompany: 'Ask Jeeves Inc.',
-				uaCompanyUrl: 'http://about.ask.com/en/docs/about/index.shtml',
-				uaIcon: 'bot_AskJeeves.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ask Jeeves/Teoma'
-			}
-		},
-		'891': {
-			userAgent: 'Mozilla/5.0 (compatible; Yoono; http://www.yoono.com/)',
-			metadata: {
-				uaFamily: 'Yoono Bot',
-				uaName: 'Yoono Bot',
-				uaUrl: 'http://blog.yoono.com/blog/?page_id=40',
-				uaCompany: 'Yoono Team',
-				uaCompanyUrl: 'http://www.yoono.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yoono Bot'
-			}
-		},
-		'892': {
-			userAgent: 'Accelobot',
-			metadata: {
-				uaFamily: 'Accelobot',
-				uaName: 'Accelobot',
-				uaUrl: 'http://www.accelobot.com/',
-				uaCompany: 'Accelovation, Inc.',
-				uaCompanyUrl: 'http://www.accelovation.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Accelobot'
-			}
-		},
-		'902': {
-			userAgent: 'WebAlta Crawler/1.3.33 (http://www.webalta.net/ru/about_webmaster.html) (Windows; U; Windows NT 5.1; ru-RU)',
-			metadata: {
-				uaFamily: 'WebAlta Crawler',
-				uaName: 'WebAlta Crawler/1.3.33',
-				uaUrl: 'http://www.webalta.net/ru/about_webmaster.html',
-				uaCompany: 'Webalta',
-				uaCompanyUrl: 'http://www.webalta.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebAlta Crawler'
-			}
-		},
-		'911': {
-			userAgent: 'Sirketcebot/v.01 (http://www.sirketce.com/bot.html)',
-			metadata: {
-				uaFamily: 'Sirketce/Busiverse',
-				uaName: 'Sirketcebot/v.01',
-				uaUrl: 'http://www.sirketce.com/bot.html',
-				uaCompany: 'BERI.L Teknoloji Ltd.',
-				uaCompanyUrl: 'http://www.berilteknoloji.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sirketce/Busiverse'
-			}
-		},
-		'913': {
-			userAgent: 'ZoomSpider - wrensoft.com [ZSEBOT]',
-			metadata: {
-				uaFamily: 'ZoomSpider (ZSEBOT)',
-				uaName: 'ZoomSpider (ZSEBOT)',
-				uaUrl: 'http://wrensoft.com/zoom/support/useragent.html',
-				uaCompany: 'PassMark Software Pty Ltd.',
-				uaCompanyUrl: 'http://www.passmark.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZoomSpider (ZSEBOT)'
-			}
-		},
-		'914': {
-			userAgent: 'Mozilla/5.0 (compatible; Quantcastbot/1.0; www.quantcast.com)',
-			metadata: {
-				uaFamily: 'Quantcastbot',
-				uaName: 'Quantcastbot/1.0',
-				uaUrl: '',
-				uaCompany: 'Quantcast Corporation',
-				uaCompanyUrl: 'http://www.quantcast.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Quantcastbot'
-			}
-		},
-		'917': {
-			userAgent: 'NutchCVS/Nutch-0.9 (Nutch; http://lucene.apache.org/nutch/bot.html; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'NutchCSV/0.9',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'920': {
-			userAgent: 'Gigabot/3.0 (http://www.gigablast.com/spider.html)',
-			metadata: {
-				uaFamily: 'Gigabot',
-				uaName: 'Gigabot/3.0',
-				uaUrl: 'http://www.gigablast.com/spider.html',
-				uaCompany: 'Gigablast Inc',
-				uaCompanyUrl: 'http://www.gigablast.com/',
-				uaIcon: 'bot_gigabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Gigabot'
-			}
-		},
-		'921': {
-			userAgent: 'Snapbot/1.0 (Site Search Crawler, +http://www.snap.com)',
-			metadata: {
-				uaFamily: 'Snapbot',
-				uaName: 'Snapbot/1.0 d',
-				uaUrl: '',
-				uaCompany: 'Snap',
-				uaCompanyUrl: 'http://www.snap.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Snapbot'
-			}
-		},
-		'922': {
-			userAgent: 'WebAlta Crawler/1.3.34 (http://www.webalta.net/ru/about_webmaster.html) (Windows; U; Windows NT 5.1; ru-RU)',
-			metadata: {
-				uaFamily: 'WebAlta Crawler',
-				uaName: 'WebAlta Crawler/1.3.34',
-				uaUrl: 'http://www.webalta.net/ru/about_webmaster.html',
-				uaCompany: 'Webalta',
-				uaCompanyUrl: 'http://www.webalta.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebAlta Crawler'
-			}
-		},
-		'925': {
-			userAgent: 'great-plains-web-spider/flatlandbot (Flatland Industries Web Spider; http://www.flatlandindustries.com/flatlandbot.php; jason@flatlandindustries.com)',
-			metadata: {
-				uaFamily: 'flatlandbot',
-				uaName: 'flatlandbot d',
-				uaUrl: 'http://www.flatlandindustries.com/flatlandbot.php',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=flatlandbot'
-			}
-		},
-		'927': {
-			userAgent: 'holmes/3.11 (OnetSzukaj/5.0; +http://szukaj.onet.pl)',
-			metadata: {
-				uaFamily: 'Holmes',
-				uaName: 'holmes/3.11 - onet.pl',
-				uaUrl: 'http://www.ucw.cz/holmes/',
-				uaCompany: 'Martin Mare\u0161 and Robert \u0160palek',
-				uaCompanyUrl: 'http://www.ucw.cz/holmes/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Holmes'
-			}
-		},
-		'928': {
-			userAgent: 'CazoodleBot/Nutch-0.9-dev (CazoodleBot Crawler; http://www.cazoodle.com/cazoodlebot; cazoodlebot@cazoodle.com)',
-			metadata: {
-				uaFamily: 'CazoodleBot',
-				uaName: 'CazoodleBot c',
-				uaUrl: 'http://www.cazoodle.com/cazoodlebot.php',
-				uaCompany: 'Cazoodle Inc.',
-				uaCompanyUrl: 'http://www.cazoodle.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CazoodleBot'
-			}
-		},
-		'929': {
-			userAgent: 'VWBOT/Nutch-0.9-dev (VWBOT Nutch Crawler; http://vwbot.cs.uiuc.edu; vwbot@cs.uiuc.edu)',
-			metadata: {
-				uaFamily: 'VWBot',
-				uaName: 'VWBot/Nutch-0.9-dev',
-				uaUrl: 'http://vwbot.cs.uiuc.edu/',
-				uaCompany: 'University of Illinois at Urbana-Champaign',
-				uaCompanyUrl: 'http://www.cs.uiuc.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VWBot'
-			}
-		},
-		'934': {
-			userAgent: 'Spock Crawler (http://www.spock.com/crawler)',
-			metadata: {
-				uaFamily: 'Spock Crawler',
-				uaName: 'Spock Crawler',
-				uaUrl: 'http://www.spock.com/crawler',
-				uaCompany: 'spock.com',
-				uaCompanyUrl: 'http://www.spock.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Spock Crawler'
-			}
-		},
-		'938': {
-			userAgent: 'Mozilla/4.0 (compatible; DepSpid/5.10; +http://about.depspid.net)',
-			metadata: {
-				uaFamily: 'DepSpid',
-				uaName: 'DepSpid/5.10',
-				uaUrl: 'http://about.depspid.net/',
-				uaCompany: 'Bjoern Henke',
-				uaCompanyUrl: 'http://www.bjoernhenke.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DepSpid'
-			}
-		},
-		'959': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;  http://www.changedetection.com/bot.html )',
-			metadata: {
-				uaFamily: 'ChangeDetection',
-				uaName: 'ChangeDetection',
-				uaUrl: 'http://www.changedetection.com/bot.html',
-				uaCompany: 'FreeFind.com',
-				uaCompanyUrl: 'http://www.freefind.com/',
-				uaIcon: 'bot_ChangeDetection.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ChangeDetection'
-			}
-		},
-		'961': {
-			userAgent: 'textractor.harvester/h5/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h5/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'962': {
-			userAgent: 'textractor.harvester/h39/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h39/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'963': {
-			userAgent: 'textractor.harvester/h37/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h37/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'964': {
-			userAgent: 'textractor.harvester/h38/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h38/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'965': {
-			userAgent: 'textractor.harvester/h12/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h12/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'966': {
-			userAgent: 'textractor.harvester/h34/1.0 (+http://ufal.mff.cuni.cz/project/textractor/, textractor@ufal.mff.cuni.cz)',
-			metadata: {
-				uaFamily: 'textractor',
-				uaName: 'textractor.harvester/h34/1.0',
-				uaUrl: 'http://ufal.mff.cuni.cz/project/textractor/',
-				uaCompany: 'Institute of Formal and Applied Linguistics (\xdaFAL)',
-				uaCompanyUrl: 'http://ufal.mff.cuni.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=textractor'
-			}
-		},
-		'967': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE enviable; DAUMOA/1.0.1; DAUM Web Robot; Daum Communications Corp., Korea; +http://ws.daum.net/aboutkr.html)',
-			metadata: {
-				uaFamily: 'Daumoa',
-				uaName: 'DAUMOA/1.0.1 b',
-				uaUrl: 'http://tab.search.daum.net/aboutWebSearch_en.html',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Daumoa'
-			}
-		},
-		'969': {
-			userAgent: 'CazoodleBot/CazoodleBot-0.1 (CazoodleBot Crawler; http://www.cazoodle.com/cazoodlebot; cazoodlebot@cazoodle.com)',
-			metadata: {
-				uaFamily: 'CazoodleBot',
-				uaName: 'CazoodleBot-0.1',
-				uaUrl: 'http://www.cazoodle.com/cazoodlebot.php',
-				uaCompany: 'Cazoodle Inc.',
-				uaCompanyUrl: 'http://www.cazoodle.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CazoodleBot'
-			}
-		},
-		'977': {
-			userAgent: 'multicrawler (+http://sw.deri.org/2006/04/multicrawler/robots.html)',
-			metadata: {
-				uaFamily: 'MultiCrawler',
-				uaName: 'MultiCrawler',
-				uaUrl: 'http://sw.deri.org/2006/04/multicrawler/robots.html',
-				uaCompany: 'Semantic Web Search Engine',
-				uaCompanyUrl: 'http://swse.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MultiCrawler'
-			}
-		},
-		'982': {
-			userAgent: 'Mediapartners-Google',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Mediapartners-Google',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1061943',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'994': {
-			userAgent: 'MnoGoSearch/3.3.2',
-			metadata: {
-				uaFamily: 'MnoGoSearch',
-				uaName: 'MnoGoSearch/3.3.2',
-				uaUrl: 'http://www.mnogosearch.org/products.html',
-				uaCompany: 'Lavtech.Com',
-				uaCompanyUrl: 'http://www.lavtech.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MnoGoSearch'
-			}
-		},
-		'999': {
-			userAgent: 'Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)',
-			metadata: {
-				uaFamily: 'Speedy',
-				uaName: 'Speedy Spider',
-				uaUrl: '',
-				uaCompany: 'Entireweb Sweden AB',
-				uaCompanyUrl: 'http://www.entireweb.com/',
-				uaIcon: 'bot_Speedy.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Speedy'
-			}
-		},
-		'1005': {
-			userAgent: 'FAST Enterprise Crawler 6 used by Virk.dk - udvikling (thomas.bentzen@capgemini.com)',
-			metadata: {
-				uaFamily: 'FAST Enterprise Crawler',
-				uaName: 'FAST Enterprise Crawler 6 at virk.dk',
-				uaUrl: 'http://www.fast.no/glossary.aspx?m=48&amid=415',
-				uaCompany: 'Fast Search & Transfer',
-				uaCompanyUrl: 'http://www.fastsearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FAST Enterprise Crawler'
-			}
-		},
-		'1023': {
-			userAgent: 'ccubee/2008',
-			metadata: {
-				uaFamily: 'ccubee',
-				uaName: 'ccubee/2008',
-				uaUrl: 'http://empyreum.com/technologies/platforms/ccubee/',
-				uaCompany: 'EMPYREUM k. s.',
-				uaCompanyUrl: 'http://empyreum.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ccubee'
-			}
-		},
-		'1024': {
-			userAgent: 'MSRBOT (http://research.microsoft.com/research/sv/msrbot/',
-			metadata: {
-				uaFamily: 'MSRBOT',
-				uaName: 'MSRBOT d',
-				uaUrl: 'http://research.microsoft.com/research/sv/msrbot/',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSRBOT'
-			}
-		},
-		'1027': {
-			userAgent: 'Enterprise_Search/1.00.143;MSSQL (http://www.innerprise.net/es-spider.asp)',
-			metadata: {
-				uaFamily: 'Enterprise_Search',
-				uaName: 'Enterprise_Search/1.00.143',
-				uaUrl: 'http://www.innerprise.net/hosted-bi.asp',
-				uaCompany: 'Innerprise',
-				uaCompanyUrl: 'http://www.innerprise.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Enterprise_Search'
-			}
-		},
-		'1035': {
-			userAgent: 'FyberSpider/1.2 (http://www.fybersearch.com/fyberspider.php)',
-			metadata: {
-				uaFamily: 'FyberSpider',
-				uaName: 'FyberSpider/1.2',
-				uaUrl: 'http://www.fybersearch.com/fyberspider.php',
-				uaCompany: 'FyberSearch',
-				uaCompanyUrl: 'http://www.fybersearch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FyberSpider'
-			}
-		},
-		'1037': {
-			userAgent: 'owsBot/0.1 (Nutch; www.oneworldstreet.com; nutch-agent@lucene.apache.org)',
-			metadata: {
-				uaFamily: 'owsBot',
-				uaName: 'owsBot/0.1',
-				uaUrl: '',
-				uaCompany: 'OneWorldStreet.com',
-				uaCompanyUrl: 'http://www.oneworldstreet.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=owsBot'
-			}
-		},
-		'1040': {
-			userAgent: 'owsBot/0.2 (owsBot; www.oneworldstreet.com; owsBot)',
-			metadata: {
-				uaFamily: 'owsBot',
-				uaName: 'owsBot/0.2',
-				uaUrl: '',
-				uaCompany: 'OneWorldStreet.com',
-				uaCompanyUrl: 'http://www.oneworldstreet.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=owsBot'
-			}
-		},
-		'1042': {
-			userAgent: 'ASAHA Search Engine Turkey V.001 (http://www.asaha.com/)',
-			metadata: {
-				uaFamily: 'ASAHA Search Engine Turkey',
-				uaName: 'ASAHA Search Engine Turkey V.001',
-				uaUrl: 'http://www.asaha.com/beta/',
-				uaCompany: 'asaha.com',
-				uaCompanyUrl: 'http://www.asaha.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ASAHA Search Engine Turkey'
-			}
-		},
-		'1044': {
-			userAgent: 'ICF_Site_Crawler+(see+http://www.infocenter.fi/spiderinfo.html)',
-			metadata: {
-				uaFamily: 'ICF_Site_Crawler',
-				uaName: 'ICF_Site_Crawler',
-				uaUrl: 'http://www.infocenter.fi/spiderinfo.html',
-				uaCompany: 'Info Center Finland Ltd.',
-				uaCompanyUrl: 'http://www.infocenter.fi/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ICF_Site_Crawler'
-			}
-		},
-		'1052': {
-			userAgent: 'Giant/1.0 (Openmaru bot; robot@openmaru.com)',
-			metadata: {
-				uaFamily: 'Giant/1.0',
-				uaName: 'Giant/1.0',
-				uaUrl: '',
-				uaCompany: 'openmaru studio',
-				uaCompanyUrl: 'http://www.openmaru.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Giant/1.0'
-			}
-		},
-		'1061': {
-			userAgent: 'Factbot 1.09',
-			metadata: {
-				uaFamily: 'factbot',
-				uaName: 'Factbot 1.09',
-				uaUrl: 'http://www.factbites.com/webmasters.php',
-				uaCompany: 'Rapid Intelligence Pty Ltd',
-				uaCompanyUrl: 'http://www.rapint.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=factbot'
-			}
-		},
-		'1072': {
-			userAgent: 'Mozilla/5.0 (Windows;) NimbleCrawler 2.0.2 obeys UserAgent NimbleCrawler For problems contact: crawler@healthline.com',
-			metadata: {
-				uaFamily: 'NimbleCrawler',
-				uaName: 'NimbleCrawler/2.0.2',
-				uaUrl: '',
-				uaCompany: 'Healthline Networks, Inc.',
-				uaCompanyUrl: 'http://www.healthline.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NimbleCrawler'
-			}
-		},
-		'1078': {
-			userAgent: 'SygolBot http://www.sygol.com',
-			metadata: {
-				uaFamily: 'SygolBot',
-				uaName: 'SygolBot',
-				uaUrl: 'http://www.sygol.com/SygolBot.asp',
-				uaCompany: 'Giorgio Galeotti',
-				uaCompanyUrl: 'http://www.sygol.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SygolBot'
-			}
-		},
-		'1089': {
-			userAgent: "HouxouCrawler/Nutch-0.9 (houxou.com's nutch-based crawler which serves special interest on-line communities; http://www.houxou.com/crawler; crawler at houxou dot com)",
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'Nutch/0.9 at houxou.com',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'1092': {
-			userAgent: 'Steeler/3.3 (http://www.tkl.iis.u-tokyo.ac.jp/~crawler/)',
-			metadata: {
-				uaFamily: 'Steeler',
-				uaName: 'Steeler/3.3',
-				uaUrl: 'http://www.tkl.iis.u-tokyo.ac.jp/~crawler/',
-				uaCompany: 'Kitsuregawa Laboratory, The University of Tokyo',
-				uaCompanyUrl: 'http://www.tkl.iis.u-tokyo.ac.jp/',
-				uaIcon: 'bot_Steeler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Steeler'
-			}
-		},
-		'1095': {
-			userAgent: 'nrsbot/5.0(loopip.com/robot.html)',
-			metadata: {
-				uaFamily: 'NetResearchServer',
-				uaName: 'nrsbot/5.0',
-				uaUrl: 'http://loopip.com/robot.html',
-				uaCompany: 'LoopIP LLC',
-				uaCompanyUrl: 'http://loopip.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NetResearchServer'
-			}
-		},
-		'1102': {
-			userAgent: 'NextGenSearchBot 1 (for information visit http://www.zoominfo.com/About/misc/NextGenSearchBot.aspx)',
-			metadata: {
-				uaFamily: 'NextGenSearchBot',
-				uaName: 'NextGenSearchBot 1 b',
-				uaUrl: 'http://www.zoominfo.com/About/misc/NextGenSearchBot.aspx',
-				uaCompany: 'Zoom Information Inc.',
-				uaCompanyUrl: 'http://www.zoominfo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NextGenSearchBot'
-			}
-		},
-		'1115': {
-			userAgent: 'Mozilla/5.0 (compatible; egothor/11.0d; +http://ego.ms.mff.cuni.cz/)',
-			metadata: {
-				uaFamily: 'egothor',
-				uaName: 'egothor/11.0d',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed Univerzity Karlovi',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/cs/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=egothor'
-			}
-		},
-		'1133': {
-			userAgent: 'GeonaBot/1.2; http://www.geona.com/',
-			metadata: {
-				uaFamily: 'GeonaBot',
-				uaName: 'GeonaBot/1.2',
-				uaUrl: 'http://www.geona.net/about.htm',
-				uaCompany: 'Gold Vision Communications',
-				uaCompanyUrl: 'http://www.goldvision.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GeonaBot'
-			}
-		},
-		'1137': {
-			userAgent: 'Mozilla/4.0 (compatible; DepSpid/5.24; +http://about.depspid.net)',
-			metadata: {
-				uaFamily: 'DepSpid',
-				uaName: 'DepSpid/5.24',
-				uaUrl: 'http://about.depspid.net/',
-				uaCompany: 'Bjoern Henke',
-				uaCompanyUrl: 'http://www.bjoernhenke.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DepSpid'
-			}
-		},
-		'1150': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE enviable; DAUMOA 2.0; DAUM Web Robot; Daum Communications Corp., Korea; +http://ws.daum.net/aboutkr.html)',
-			metadata: {
-				uaFamily: 'Daumoa',
-				uaName: 'Daumoa/2.0',
-				uaUrl: 'http://tab.search.daum.net/aboutWebSearch_en.html',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Daumoa'
-			}
-		},
-		'1164': {
-			userAgent: 'Mozilla/4.0 (compatible; DepSpid/5.25; +http://about.depspid.net)',
-			metadata: {
-				uaFamily: 'DepSpid',
-				uaName: 'DepSpid/5.25',
-				uaUrl: 'http://about.depspid.net/',
-				uaCompany: 'Bjoern Henke',
-				uaCompanyUrl: 'http://www.bjoernhenke.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DepSpid'
-			}
-		},
-		'1169': {
-			userAgent: 'Mozilla/5.0 (compatible; egothor/11.0d; +https://kocour.ms.mff.cuni.cz/ego/)',
-			metadata: {
-				uaFamily: 'egothor',
-				uaName: 'egothor/11.0d b',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed Univerzity Karlovi',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/cs/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=egothor'
-			}
-		},
-		'1180': {
-			userAgent: 'msnbot/1.1 (+http://search.msn.com/msnbot.htm)',
-			metadata: {
-				uaFamily: 'MSNBot',
-				uaName: 'MSNBot/1.1',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSNBot'
-			}
-		},
-		'1197': {
-			userAgent: 'ichiro/3.0 (http://help.goo.ne.jp/door/crawler.html)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/3.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'1198': {
-			userAgent: 'EnaBot/1.1 (http://www.enaball.com/crawler.html)',
-			metadata: {
-				uaFamily: 'EnaBot',
-				uaName: 'EnaBot/1.1',
-				uaUrl: 'http://www.enaball.com/crawler.html',
-				uaCompany: 'Enaball Inc.',
-				uaCompanyUrl: 'http://www.enaball.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EnaBot'
-			}
-		},
-		'1205': {
-			userAgent: 'EnaBot/1.2 (http://www.enaball.com/crawler.html)',
-			metadata: {
-				uaFamily: 'EnaBot',
-				uaName: 'EnaBot/1.2',
-				uaUrl: 'http://www.enaball.com/crawler.html',
-				uaCompany: 'Enaball Inc.',
-				uaCompanyUrl: 'http://www.enaball.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EnaBot'
-			}
-		},
-		'1210': {
-			userAgent: 'Mahiti.Com/Mahiti Crawler-1.0 (Mahiti.Com; http://mahiti.com ; mahiti.com)',
-			metadata: {
-				uaFamily: 'Mahiti Crawler',
-				uaName: 'Mahiti Crawler-1.0',
-				uaUrl: '',
-				uaCompany: 'Mahiti.Com',
-				uaCompanyUrl: 'http://mahiti.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mahiti Crawler'
-			}
-		},
-		'1213': {
-			userAgent: 'MLBot (www.metadatalabs.com)',
-			metadata: {
-				uaFamily: 'MLBot',
-				uaName: 'MLBot',
-				uaUrl: 'http://www.metadatalabs.com/mlbot/',
-				uaCompany: 'metadata labs',
-				uaCompanyUrl: 'http://www.metadatalabs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MLBot'
-			}
-		},
-		'1214': {
-			userAgent: 'Mozilla/4.0 (compatible; DepSpid/5.26; +http://about.depspid.net)',
-			metadata: {
-				uaFamily: 'DepSpid',
-				uaName: 'DepSpid/5.26',
-				uaUrl: 'http://about.depspid.net/',
-				uaCompany: 'Bjoern Henke',
-				uaCompanyUrl: 'http://www.bjoernhenke.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DepSpid'
-			}
-		},
-		'1220': {
-			userAgent: 'IRLbot/3.0 (compatible; MSIE 6.0; http://irl.cs.tamu.edu/crawler/)',
-			metadata: {
-				uaFamily: 'IRLbot',
-				uaName: 'IRLbot/3.0 b',
-				uaUrl: 'http://irl.cs.tamu.edu/crawler/',
-				uaCompany: 'Texas A&M University',
-				uaCompanyUrl: 'http://www.tamu.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IRLbot'
-			}
-		},
-		'1225': {
-			userAgent: 'DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)',
-			metadata: {
-				uaFamily: 'DuckDuckBot',
-				uaName: 'DuckDuckBot/1.0',
-				uaUrl: 'http://duckduckgo.com/duckduckbot.html',
-				uaCompany: 'Duck Duck Go, Inc.',
-				uaCompanyUrl: 'http://duckduckgo.com/blog/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DuckDuckBot'
-			}
-		},
-		'1238': {
-			userAgent: 'CCBot/1.0 (+http://www.commoncrawl.org/bot.html)',
-			metadata: {
-				uaFamily: 'CCBot',
-				uaName: 'CCBot/1.0',
-				uaUrl: 'http://commoncrawl.org/research/',
-				uaCompany: 'CommonCrawl Foundation',
-				uaCompanyUrl: 'http://www.commoncrawl.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CCBot'
-			}
-		},
-		'1247': {
-			userAgent: 'MnoGoSearch/3.3.6',
-			metadata: {
-				uaFamily: 'MnoGoSearch',
-				uaName: 'MnoGoSearch/3.3.6',
-				uaUrl: 'http://www.mnogosearch.org/products.html',
-				uaCompany: 'Lavtech.Com',
-				uaCompanyUrl: 'http://www.lavtech.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MnoGoSearch'
-			}
-		},
-		'1270': {
-			userAgent: 'Mozilla/5.0 (compatible; Charlotte/1.1; http://www.searchme.com/support/)',
-			metadata: {
-				uaFamily: 'Charlotte',
-				uaName: 'Charlotte/1.1',
-				uaUrl: 'http://www.searchme.com/support/)',
-				uaCompany: 'Searchme, Inc.',
-				uaCompanyUrl: 'http://www.searchme.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Charlotte'
-			}
-		},
-		'1273': {
-			userAgent: 'Acoon-Robot 4.0.0RC2 (http://www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon-Robot 4.0.0RC2',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'1282': {
-			userAgent: 'Acoon-Robot 4.0.1 (http://www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon-Robot 4.0.1',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'1283': {
-			userAgent: 'MLBot (www.metadatalabs.com/mlbot)',
-			metadata: {
-				uaFamily: 'MLBot',
-				uaName: 'MLBot b',
-				uaUrl: 'http://www.metadatalabs.com/mlbot/',
-				uaCompany: 'metadata labs',
-				uaCompanyUrl: 'http://www.metadatalabs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MLBot'
-			}
-		},
-		'1287': {
-			userAgent: 'Acoon-Robot 4.0.2 (http://www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon-Robot 4.0.2',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'1293': {
-			userAgent: 'Touche (+http://www.touche.com.ve)',
-			metadata: {
-				uaFamily: 'Touche',
-				uaName: 'Touche',
-				uaUrl: 'http://www.touche.com.ve/Acerca.jsp',
-				uaCompany: 'Touch\xe9',
-				uaCompanyUrl: 'http://www.touche.com.ve/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Touche'
-			}
-		},
-		'1297': {
-			userAgent: 'Acoon-Robot 4.0.2.17 (http://www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon-Robot 4.0.2.17',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'1323': {
-			userAgent: 'Mozilla/5.0 (compatible; egothor/12.0rc-2; +http://ego.ms.mff.cuni.cz/)',
-			metadata: {
-				uaFamily: 'egothor',
-				uaName: 'egothor/12.0rc-2',
-				uaUrl: 'http://ego.ms.mff.cuni.cz/',
-				uaCompany: 'Katedra softwarov\xe9ho in\u017een\xfdrstv\xed Univerzity Karlovi',
-				uaCompanyUrl: 'http://kocour.ms.mff.cuni.cz/cs/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=egothor'
-			}
-		},
-		'1458': {
-			userAgent: 'Yandex/1.01.001 (compatible; Win16; P)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'Yandex/1.01.001',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'1459': {
-			userAgent: 'Mozilla/5.0 (compatible; DotBot/1.1; http://www.dotnetdotcom.org/, crawler@dotnetdotcom.org)',
-			metadata: {
-				uaFamily: 'DotBot',
-				uaName: 'DotBot/1.1',
-				uaUrl: 'http://www.dotnetdotcom.org/',
-				uaCompany: 'dotnetdotcom.org',
-				uaCompanyUrl: 'http://www.dotnetdotcom.org/#cont',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DotBot'
-			}
-		},
-		'1461': {
-			userAgent: 'ia_archiver (+http://www.alexa.com/site/help/webmasters; crawler@alexa.com)',
-			metadata: {
-				uaFamily: 'ia_archiver',
-				uaName: 'ia_archiver alexa',
-				uaUrl: 'http://www.alexa.com/site/help/webmasters',
-				uaCompany: 'Alexa Internet, Inc.',
-				uaCompanyUrl: 'http://www.alexa.com/',
-				uaIcon: 'bot_ia_archiver.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ia_archiver'
-			}
-		},
-		'1462': {
-			userAgent: 'Mozilla/5.0 (Twiceler-0.9 http://www.cuil.com/twiceler/robot.html)',
-			metadata: {
-				uaFamily: 'Twiceler',
-				uaName: 'Twiceler-0.9',
-				uaUrl: 'http://www.cuil.com/twiceler/robot.html',
-				uaCompany: 'Cuil, Inc. ',
-				uaCompanyUrl: 'http://www.cuil.com/',
-				uaIcon: 'bot_Twiceler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Twiceler'
-			}
-		},
-		'1463': {
-			userAgent: 'Mozilla/5.0 (compatible; Seznam screenshot-generator 2.0; +http://fulltext.sblog.cz/screenshot/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'Seznam screenshot-generator 2.0',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'1464': {
-			userAgent: 'SeznamBot/2.0 (+http://fulltext.sblog.cz/robot/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/2.0',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'1466': {
-			userAgent: 'Mozilla/5.0 (compatible; MSIE or Firefox mutant; not on Windows server; +http://ws.daum.net/aboutWebSearch.html) Daumoa/2.0',
-			metadata: {
-				uaFamily: 'Daumoa',
-				uaName: 'Daumoa/2.0 b',
-				uaUrl: 'http://tab.search.daum.net/aboutWebSearch_en.html',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Daumoa'
-			}
-		},
-		'1468': {
-			userAgent: 'msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)',
-			metadata: {
-				uaFamily: 'MSNBot',
-				uaName: 'msnbot-media/1.1',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSNBot'
-			}
-		},
-		'1469': {
-			userAgent: 'OOZBOT/0.20 ( -- ; http://www.setooz.com/oozbot.html ; agentname at setooz dot_com )',
-			metadata: {
-				uaFamily: 'Setoozbot',
-				uaName: 'OOZBOT/0.20',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot'
-			}
-		},
-		'1470': {
-			userAgent: 'Sogou develop spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'Sogou develop spider/4.0',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'1471': {
-			userAgent: 'Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'Sogou web spider/4.0',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'1472': {
-			userAgent: 'SpokeSpider/1.0 (http://support.spoke.com/webspider/) Mozilla/5.0 (not really)',
-			metadata: {
-				uaFamily: 'SpokeSpider',
-				uaName: 'SpokeSpider/1.0',
-				uaUrl: 'http://support.spoke.com/webspider/',
-				uaCompany: 'Spoke Software ',
-				uaCompanyUrl: 'http://www.spoke.com/company/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SpokeSpider'
-			}
-		},
-		'1474': {
-			userAgent: 'Baiduspider+(+http://www.baidu.jp/spider/)',
-			metadata: {
-				uaFamily: 'Baiduspider',
-				uaName: 'Baiduspider japan',
-				uaUrl: 'http://www.baidu.com/search/spider.htm',
-				uaCompany: 'Baidu',
-				uaCompanyUrl: 'http://www.baidu.com/',
-				uaIcon: 'bot_baiduspider.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Baiduspider'
-			}
-		},
-		'1475': {
-			userAgent: 'linkdexbot/Nutch-1.0-dev (http://www.linkdex.com/; crawl at linkdex dot com)',
-			metadata: {
-				uaFamily: 'linkdexbot',
-				uaName: 'linkdexbot',
-				uaUrl: 'http://www.linkdex.com/about/bots/',
-				uaCompany: 'Linkdex Limited.',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=linkdexbot'
-			}
-		},
-		'1476': {
-			userAgent: 'Yeti/1.0 (NHN Corp.; http://help.naver.com/robots/)',
-			metadata: {
-				uaFamily: 'NaverBot',
-				uaName: 'Yeti/1.0',
-				uaUrl: 'http://help.naver.com/robots/',
-				uaCompany: 'NHN Corporation',
-				uaCompanyUrl: 'http://www.nhncorp.com/',
-				uaIcon: 'bot_NaverBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NaverBot'
-			}
-		},
-		'1478': {
-			userAgent: 'mozilla/5.0 (compatible; webmastercoffee/0.7; +http://webmastercoffee.com/about)',
-			metadata: {
-				uaFamily: 'webmastercoffee',
-				uaName: 'webmastercoffee/0.7',
-				uaUrl: 'http://webmastercoffee.com/about',
-				uaCompany: 'Martin Schwartz',
-				uaCompanyUrl: 'http://webmastercoffee.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=webmastercoffee'
-			}
-		},
-		'1479': {
-			userAgent: 'boitho.com-dc/0.82 ( http://www.boitho.com/dcbot.html )',
-			metadata: {
-				uaFamily: 'boitho.com-dc',
-				uaName: 'boitho.com-dc/0.82',
-				uaUrl: 'http://www.boitho.com/dcbot.html',
-				uaCompany: 'Boitho',
-				uaCompanyUrl: 'http://www.boitho.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=boitho.com-dc'
-			}
-		},
-		'1480': {
-			userAgent: 'Busiversebot/v1.0 (http://www.busiverse.com/bot.php)',
-			metadata: {
-				uaFamily: 'Sirketce/Busiverse',
-				uaName: 'Busiversebot/v1.0',
-				uaUrl: 'http://www.busiverse.com/bot.php',
-				uaCompany: 'BerilTech',
-				uaCompanyUrl: 'http://www.sirketce.com.tr/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sirketce/Busiverse'
-			}
-		},
-		'1481': {
-			userAgent: 'CatchBot/1.0; +http://www.catchbot.com',
-			metadata: {
-				uaFamily: 'CatchBot',
-				uaName: 'CatchBot/1.0',
-				uaUrl: 'http://www.catchbot.com/',
-				uaCompany: 'Reed Business Information Pty Limited',
-				uaCompanyUrl: 'http://www.reedbusiness.com/',
-				uaIcon: 'bot_CatchBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CatchBot'
-			}
-		},
-		'1482': {
-			userAgent: 'CazoodleBot/0.0.2 (http://www.cazoodle.com/contact.php; cbot@cazoodle.com)',
-			metadata: {
-				uaFamily: 'CazoodleBot',
-				uaName: 'CazoodleBot/0.0.2',
-				uaUrl: 'http://www.cazoodle.com/cazoodlebot.php',
-				uaCompany: 'Cazoodle Inc.',
-				uaCompanyUrl: 'http://www.cazoodle.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CazoodleBot'
-			}
-		},
-		'1484': {
-			userAgent: 'kalooga/KaloogaBot (Kalooga; http://www.kalooga.com/info.html?page=crawler; crawler@kalooga.com)',
-			metadata: {
-				uaFamily: 'Kalooga',
-				uaName: 'Kalooga',
-				uaUrl: 'http://www.kalooga.com/info.html?page=crawler',
-				uaCompany: 'Kalooga',
-				uaCompanyUrl: 'http://www.kalooga.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Kalooga'
-			}
-		},
-		'1490': {
-			userAgent: '192.comAgent',
-			metadata: {
-				uaFamily: '192.comAgent',
-				uaName: '192.comAgent',
-				uaUrl: 'http://www.192.com/help/tools-guides/webcrawler/',
-				uaCompany: 'i-CD Publishing (UK) Limited',
-				uaCompanyUrl: 'http://www.icdpublishing.co.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=192.comAgent'
-			}
-		},
-		'1494': {
-			userAgent: 'Mozilla/4.0 (compatible; NaverBot/1.0; http://help.naver.com/customer_webtxt_02.jsp)',
-			metadata: {
-				uaFamily: 'NaverBot',
-				uaName: 'NaverBot/1.0',
-				uaUrl: 'http://help.naver.com/robots/',
-				uaCompany: 'NHN Corporation',
-				uaCompanyUrl: 'http://www.nhncorp.com/',
-				uaIcon: 'bot_NaverBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NaverBot'
-			}
-		},
-		'1495': {
-			userAgent: 'copyright sheriff (+http://www.copyrightsheriff.com/)',
-			metadata: {
-				uaFamily: 'copyright sheriff',
-				uaName: 'copyright sheriff',
-				uaUrl: '',
-				uaCompany: 'CopyrightSheriff .Com',
-				uaCompanyUrl: 'http://www.copyrightsheriff.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=copyright sheriff'
-			}
-		},
-		'1496': {
-			userAgent: 'Mozilla/5.0 (compatible; OsO; http://oso.octopodus.com/abot.html)',
-			metadata: {
-				uaFamily: 'OsObot',
-				uaName: 'OsObot',
-				uaUrl: 'http://oso.octopodus.com/abot.html',
-				uaCompany: 'Denis Chatelain',
-				uaCompanyUrl: 'http://buildingasearchengine.blogspot.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OsObot'
-			}
-		},
-		'1497': {
-			userAgent: 'msnbot/2.0b (+http://search.msn.com/msnbot.htm)',
-			metadata: {
-				uaFamily: 'MSNBot',
-				uaName: 'MSNBot/2.0b',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSNBot'
-			}
-		},
-		'1500': {
-			userAgent: 'Eurobot/1.1 (http://eurobot.ayell.eu)',
-			metadata: {
-				uaFamily: 'Eurobot',
-				uaName: 'Eurobot/1.1',
-				uaUrl: 'http://eurobot.ayell.de/',
-				uaCompany: 'Ayell Euronet',
-				uaCompanyUrl: 'http://www.ayell.eu/',
-				uaIcon: 'bot_eurobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Eurobot'
-			}
-		},
-		'1501': {
-			userAgent: 'Mozilla/5.0 (compatible; woriobot +http://worio.com)',
-			metadata: {
-				uaFamily: 'woriobot',
-				uaName: 'woriobot',
-				uaUrl: '',
-				uaCompany: 'Zite',
-				uaCompanyUrl: 'http://zite.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=woriobot'
-			}
-		},
-		'1502': {
-			userAgent: 'Mail.Ru/1.0',
-			metadata: {
-				uaFamily: 'Mail.Ru bot',
-				uaName: 'Mail.Ru/1.0',
-				uaUrl: 'http://go.mail.ru/help/robots',
-				uaCompany: 'Mail.Ru Group',
-				uaCompanyUrl: 'http://corp.mail.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mail.Ru bot'
-			}
-		},
-		'1504': {
-			userAgent: 'LinguaBot/v0.001-dev (MultiLinual Sarch Engine v0.001; LinguaSeek; admin at linguaseek dot com)',
-			metadata: {
-				uaFamily: 'LinguaBot',
-				uaName: 'LinguaBot/v0.001-dev',
-				uaUrl: '',
-				uaCompany: 'linguaseek.com ',
-				uaCompanyUrl: 'http://linguaseek.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LinguaBot'
-			}
-		},
-		'1505': {
-			userAgent: 'urlfan-bot/1.0; +http://www.urlfan.com/site/bot/350.html',
-			metadata: {
-				uaFamily: 'urlfan-bot',
-				uaName: 'urlfan-bot/1.0',
-				uaUrl: 'http://www.urlfan.com/site/bot/350.html',
-				uaCompany: '://URLFAN',
-				uaCompanyUrl: 'http://www.urlfan.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=urlfan-bot'
-			}
-		},
-		'1507': {
-			userAgent: 'Mozilla/5.0 (compatible; YoudaoBot/1.0; http://www.youdao.com/help/webmaster/spider/; )',
-			metadata: {
-				uaFamily: 'YoudaoBot',
-				uaName: 'YoudaoBot/1.0',
-				uaUrl: 'http://www.youdao.com/help/webmaster/spider/',
-				uaCompany: 'youdao.com',
-				uaCompanyUrl: 'http://www.youdao.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YoudaoBot'
-			}
-		},
-		'1509': {
-			userAgent: 'YowedoBot/Yowedo 1.0 (Search Engine crawler for yowedo.com; http://yowedo.com/en/partners.html; crawler@yowedo.com)',
-			metadata: {
-				uaFamily: 'YowedoBot',
-				uaName: 'YowedoBot/1.0',
-				uaUrl: 'http://yowedo.com/en/partners.html',
-				uaCompany: 'yowedo.com',
-				uaCompanyUrl: 'http://yowedo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YowedoBot'
-			}
-		},
-		'1512': {
-			userAgent: 'Yanga WorldSearch Bot v1.1/beta (http://www.yanga.co.uk/)',
-			metadata: {
-				uaFamily: 'Yanga',
-				uaName: 'Yanga v1.1/beta',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Gigabase Ltd.',
-				uaCompanyUrl: 'http://www.gigabase.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yanga'
-			}
-		},
-		'1516': {
-			userAgent: 'Mozilla/5.0 (compatible; Butterfly/1.0; +http://labs.topsy.com/butterfly.html) Gecko/2009032608 Firefox/3.0.8',
-			metadata: {
-				uaFamily: 'Butterfly',
-				uaName: 'Butterfly/1.0',
-				uaUrl: 'http://labs.topsy.com/butterfly.html',
-				uaCompany: 'Topsy Labs',
-				uaCompanyUrl: 'http://labs.topsy.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Butterfly'
-			}
-		},
-		'1517': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.2.4; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.2.4',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'1519': {
-			userAgent: 'holmes/3.12.4 (http://morfeo.centrum.cz/bot)',
-			metadata: {
-				uaFamily: 'Holmes',
-				uaName: 'holmes/3.12.4 - morfeo',
-				uaUrl: 'http://www.ucw.cz/holmes/',
-				uaCompany: 'Martin Mare\u0161 and Robert \u0160palek',
-				uaCompanyUrl: 'http://www.ucw.cz/holmes/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Holmes'
-			}
-		},
-		'1522': {
-			userAgent: 'OOZBOT/0.20 ( Setooz v\xfdrazn\xfd ako say-th-uuz, znamen\xe1 mosty.  ; http://www.setooz.com/oozbot.html ; agentname at setooz dot_com )',
-			metadata: {
-				uaFamily: 'Setoozbot',
-				uaName: 'OOZBOT/0.20 b',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot'
-			}
-		},
-		'1523': {
-			userAgent: 'facebookexternalhit/1.0 (+http://www.facebook.com/externalhit_uatext.php)',
-			metadata: {
-				uaFamily: 'FacebookExternalHit',
-				uaName: 'FacebookExternalHit/1.0',
-				uaUrl: 'http://www.facebook.com/externalhit_uatext.php',
-				uaCompany: 'Facebook',
-				uaCompanyUrl: 'http://www.facebook.com/',
-				uaIcon: 'bot_facebook.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FacebookExternalHit'
-			}
-		},
-		'1524': {
-			userAgent: 'kalooga/KaloogaBot (Kalooga; http://www.kalooga.com/info.html?page=crawler)',
-			metadata: {
-				uaFamily: 'Kalooga',
-				uaName: 'Kalooga',
-				uaUrl: 'http://www.kalooga.com/info.html?page=crawler',
-				uaCompany: 'Kalooga',
-				uaCompanyUrl: 'http://www.kalooga.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Kalooga'
-			}
-		},
-		'1530': {
-			userAgent: 'Mozilla/5.0 (compatible; DBLBot/1.0; +http://www.dontbuylists.com/)',
-			metadata: {
-				uaFamily: 'DBLBot',
-				uaName: 'DBLBot/1.0',
-				uaUrl: 'http://www.dontbuylists.com/faq.htm',
-				uaCompany: 'Dontbuylists.com',
-				uaCompanyUrl: 'http://www.dontbuylists.com/team.htm',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DBLBot'
-			}
-		},
-		'1533': {
-			userAgent: 'Mozilla/5.0 (compatible; Mp3Bot/0.4; +http://mp3realm.org/mp3bot/)',
-			metadata: {
-				uaFamily: 'Mp3Bot',
-				uaName: 'Mp3Bot/0.4',
-				uaUrl: 'http://mp3realm.org/mp3bot/',
-				uaCompany: 'Mp3Realm.Org',
-				uaCompanyUrl: 'http://mp3realm.org/',
-				uaIcon: 'bot_Mp3Bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mp3Bot'
-			}
-		},
-		'1536': {
-			userAgent: 'http://www.uni-koblenz.de/~flocke/robot-info.txt',
-			metadata: {
-				uaFamily: 'Flocke bot',
-				uaName: 'Flocke bot',
-				uaUrl: 'http://www.uni-koblenz.de/~flocke/robot-info.txt',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Flocke bot'
-			}
-		},
-		'1540': {
-			userAgent: 'JadynAve - http://www.jadynave.com/robot',
-			metadata: {
-				uaFamily: 'JadynAve',
-				uaName: 'JadynAve',
-				uaUrl: '',
-				uaCompany: 'Yesup Ecommerce Solutions Inc',
-				uaCompanyUrl: 'http://www.yesup.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=JadynAve'
-			}
-		},
-		'1542': {
-			userAgent: 'KeywenBot/4.1  http://www.keywen.com/Encyclopedia/Links',
-			metadata: {
-				uaFamily: 'KeywenBot',
-				uaName: 'KeywenBot/4.1',
-				uaUrl: 'http://www.keywen.com/Encyclopedia/Links/',
-				uaCompany: 'Michael Charnine',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=KeywenBot'
-			}
-		},
-		'1546': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.12.1 +http://www.webarchiv.cz)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/1.12.1',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'1548': {
-			userAgent: 'Y!J-BRI/0.0.1 crawler ( http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html )',
-			metadata: {
-				uaFamily: 'Yahoo! JAPAN',
-				uaName: 'Y!J-BRI/0.0.1',
-				uaUrl: 'http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo! JAPAN'
-			}
-		},
-		'1550': {
-			userAgent: 'Mozilla/5.0 (compatible; akula/12.0rc-2; +http://k311.fd.cvut.cz/)',
-			metadata: {
-				uaFamily: 'akula',
-				uaName: 'akula/12.0rc-2',
-				uaUrl: 'http://k311.fd.cvut.cz/',
-				uaCompany: '\u010cVUT Fakulta dopravn\xed',
-				uaCompanyUrl: 'http://www.fd.cvut.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=akula'
-			}
-		},
-		'1555': {
-			userAgent: 'Mozilla/5.0 (compatible; akula/k311; +http://k311.fd.cvut.cz/)',
-			metadata: {
-				uaFamily: 'akula',
-				uaName: 'akula/k311',
-				uaUrl: 'http://k311.fd.cvut.cz/',
-				uaCompany: '\u010cVUT Fakulta dopravn\xed',
-				uaCompanyUrl: 'http://www.fd.cvut.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=akula'
-			}
-		},
-		'1558': {
-			userAgent: 'Y!J-BSC/1.0 (http://help.yahoo.co.jp/help/jp/blog-search/)',
-			metadata: {
-				uaFamily: 'Yahoo! JAPAN',
-				uaName: 'Y!J-BSC/1.0',
-				uaUrl: 'http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo! JAPAN'
-			}
-		},
-		'1562': {
-			userAgent: 'Shelob (shelob@gmx.net)',
-			metadata: {
-				uaFamily: 'Shelob',
-				uaName: 'Shelob',
-				uaUrl: 'http://mattwork.potsdam.edu/projects/wiki/index.php/Shelob',
-				uaCompany: 'M@',
-				uaCompanyUrl: 'http://mattwork.potsdam.edu/projects/wiki/index.php/Category:Me',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Shelob'
-			}
-		},
-		'1563': {
-			userAgent: 'DoCoMo/2.0 N902iS(c100;TB;W24H12)(compatible; moba-crawler; http://crawler.dena.jp/)',
-			metadata: {
-				uaFamily: 'moba-crawler',
-				uaName: 'moba-crawler',
-				uaUrl: 'http://crawler.dena.jp/',
-				uaCompany: 'DeNA Co.,Ltd.',
-				uaCompanyUrl: 'http://dena.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=moba-crawler'
-			}
-		},
-		'1564': {
-			userAgent: 'Mozilla/5.0 (compatible; Yahoo! Slurp/3.0; http://help.yahoo.com/help/us/ysearch/slurp)',
-			metadata: {
-				uaFamily: 'Yahoo!',
-				uaName: 'Yahoo! Slurp/3.0',
-				uaUrl: 'http://help.yahoo.com/help/us/ysearch/slurp',
-				uaCompany: 'Yahoo! Inc.',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo!'
-			}
-		},
-		'1565': {
-			userAgent: 'Mozilla/5.0 (compatible; ScoutJet; +http://www.scoutjet.com/)',
-			metadata: {
-				uaFamily: 'ScoutJet',
-				uaName: 'ScoutJet old',
-				uaUrl: 'http://www.scoutjet.com/',
-				uaCompany: 'blekko, inc.',
-				uaCompanyUrl: 'http://blekko.com/',
-				uaIcon: 'bot_ScoutJet.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ScoutJet'
-			}
-		},
-		'1567': {
-			userAgent: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1) VoilaBot BETA 1.2 (support.voilabot@orange-ftgroup.com)',
-			metadata: {
-				uaFamily: 'VoilaBot',
-				uaName: 'VoilaBot BETA 1.2',
-				uaUrl: '',
-				uaCompany: 'France Telecom',
-				uaCompanyUrl: 'http://www.francetelecom.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VoilaBot'
-			}
-		},
-		'1568': {
-			userAgent: 'DealGates Bot/1.1 by Luc Michalski (http://spider.dealgates.com/bot.html)',
-			metadata: {
-				uaFamily: 'DealGates Bot',
-				uaName: 'DealGates Bot/1.1',
-				uaUrl: 'http://www.dealgates.net/bot.html',
-				uaCompany: 'Luc Michalski',
-				uaCompanyUrl: 'http://www.dealgates.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DealGates Bot'
-			}
-		},
-		'1573': {
-			userAgent: 'GingerCrawler/1.0 (Language Assistant for Dyslexics; www.gingersoftware.com/crawler_agent.htm; support at ginger software dot com)',
-			metadata: {
-				uaFamily: 'GingerCrawler',
-				uaName: 'GingerCrawler/1.0',
-				uaUrl: 'http://www.gingersoftware.com/crawler_agent.htm',
-				uaCompany: 'Ginger Software',
-				uaCompanyUrl: 'http://www.gingersoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GingerCrawler'
-			}
-		},
-		'1582': {
-			userAgent: 'flatlandbot/baypup (Flatland Industries Web Spider; http://www.flatlandindustries.com/flatlandbot; jason@flatlandindustries.com)',
-			metadata: {
-				uaFamily: 'Flatland Industries Web Spider',
-				uaName: 'flatlandbot/baypup',
-				uaUrl: 'http://www.flatlandindustries.com/flatlandbot',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Flatland Industries Web Spider'
-			}
-		},
-		'1583': {
-			userAgent: 'holmes/3.11 (http://morfeo.centrum.cz/bot)',
-			metadata: {
-				uaFamily: 'Holmes',
-				uaName: 'holmes/3.11',
-				uaUrl: 'http://www.ucw.cz/holmes/',
-				uaCompany: 'Martin Mare\u0161 and Robert \u0160palek',
-				uaCompanyUrl: 'http://www.ucw.cz/holmes/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Holmes'
-			}
-		},
-		'1586': {
-			userAgent: 'voyager/2.0 (http://www.kosmix.com/crawler.html)',
-			metadata: {
-				uaFamily: 'voyager',
-				uaName: 'voyager/2.0',
-				uaUrl: 'http://www.kosmix.com/corp/crawler.html',
-				uaCompany: 'Kosmix Corporation',
-				uaCompanyUrl: 'http://www.kosmix.com/html/about.html',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=voyager'
-			}
-		},
-		'1595': {
-			userAgent: 'FeedCatBot/3.0 (+http://www.feedcat.net/)',
-			metadata: {
-				uaFamily: 'FeedCatBot',
-				uaName: 'FeedCatBot/3.0',
-				uaUrl: 'http://www.feedcat.net/',
-				uaCompany: 'FEEDCAT.NET',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FeedCatBot'
-			}
-		},
-		'1599': {
-			userAgent: 'JyxobotRSS/0.06',
-			metadata: {
-				uaFamily: 'Jyxobot',
-				uaName: 'JyxobotRSS/0.06',
-				uaUrl: '',
-				uaCompany: 'Jyxo s.r.o.',
-				uaCompanyUrl: 'http://jyxo.cz/',
-				uaIcon: 'bot_Jyxobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Jyxobot'
-			}
-		},
-		'1600': {
-			userAgent: 'SniffRSS/0.5beta (+http://www.blogator.com/)',
-			metadata: {
-				uaFamily: 'SniffRSS',
-				uaName: 'SniffRSS/0.5beta',
-				uaUrl: '',
-				uaCompany: 'blogator.com',
-				uaCompanyUrl: 'http://www.blogator.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SniffRSS'
-			}
-		},
-		'1601': {
-			userAgent: 'RSSMicro.com RSS/Atom Feed Robot',
-			metadata: {
-				uaFamily: 'RSSMicro.com RSS/Atom Feed Robot',
-				uaName: 'RSSMicro.com RSS/Atom Feed Robot',
-				uaUrl: '',
-				uaCompany: 'RSSMicro.com',
-				uaCompanyUrl: 'http://rssmicro.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=RSSMicro.com RSS/Atom Feed Robot'
-			}
-		},
-		'1602': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.2.1; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.2.1',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'1604': {
-			userAgent: 'yacybot (i386 Linux 2.6.28-11-generic; java 1.6.0_13; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'1619': {
-			userAgent: 'voyager/1.0 (+http://www.kosmix.com/html/crawler.html)',
-			metadata: {
-				uaFamily: 'voyager',
-				uaName: 'voyager/1.0',
-				uaUrl: 'http://www.kosmix.com/corp/crawler.html',
-				uaCompany: 'Kosmix Corporation',
-				uaCompanyUrl: 'http://www.kosmix.com/html/about.html',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=voyager'
-			}
-		},
-		'1633': {
-			userAgent: 'Mozilla/5.0 (compatible; 80bot/0.71; http://www.80legs.com/spider.html;) Gecko/2008032620',
-			metadata: {
-				uaFamily: '80legs',
-				uaName: '80legs/0.71',
-				uaUrl: 'http://www.80legs.com/webcrawler.html',
-				uaCompany: 'Computational Crawling, LP ',
-				uaCompanyUrl: 'http://compucrawl.com/',
-				uaIcon: 'bot_80legs.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=80legs'
-			}
-		},
-		'1637': {
-			userAgent: 'BlogPulseLive (support@blogpulse.com)',
-			metadata: {
-				uaFamily: 'BlogPulse',
-				uaName: 'BlogPulseLive',
-				uaUrl: 'http://www.blogpulse.com/',
-				uaCompany: 'Nielsen Company',
-				uaCompanyUrl: 'http://www.nielsen-online.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BlogPulse'
-			}
-		},
-		'1645': {
-			userAgent: 'yacybot (amd64 Linux 2.6.24-23-generic; java 1.6.0_07; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'1650': {
-			userAgent: 'Mozilla/5.0 (compatible; DKIMRepBot/1.0; +http://www.dkim-reputation.org)',
-			metadata: {
-				uaFamily: 'DKIMRepBot',
-				uaName: 'DKIMRepBot/1.0',
-				uaUrl: 'http://www.dkim-reputation.org/',
-				uaCompany: 'DKIM',
-				uaCompanyUrl: 'http://www.dkim.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DKIMRepBot'
-			}
-		},
-		'1653': {
-			userAgent: 'yacybot (i386 Linux 2.6.28-gentoo-r5; java 1.5.0_18; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'1658': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.14.3 +http://archive.org)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/1.14.3',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'1662': {
-			userAgent: 'UptimeDog Robot (www.uptimedog.com)',
-			metadata: {
-				uaFamily: 'UptimeDog',
-				uaName: 'UptimeDog',
-				uaUrl: 'http://www.uptimedog.com/',
-				uaCompany: 'San Pedro Software Inc.',
-				uaCompanyUrl: 'http://mosw.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=UptimeDog'
-			}
-		},
-		'1663': {
-			userAgent: 'Mozilla/4.0 (compatible; Fooooo_Web_Video_Crawl http://fooooo.com/bot.html)',
-			metadata: {
-				uaFamily: 'Fooooo_Web_Video_Crawl',
-				uaName: 'Fooooo_Web_Video_Crawl',
-				uaUrl: 'http://fooooo.com/bot.html',
-				uaCompany: 'Bank of innvation Inc.',
-				uaCompanyUrl: 'http://en.boi.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Fooooo_Web_Video_Crawl'
-			}
-		},
-		'1676': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.2.5; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.2.5',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'1681': {
-			userAgent: 'Orgbybot/OrgbyBot v1.2 (Spidering the net for Orgby; http://www.orgby.com/  ; Orgby.com Search Engine)',
-			metadata: {
-				uaFamily: 'OrgbyBot',
-				uaName: 'OrgbyBot/1.2',
-				uaUrl: 'http://orgby.com/bot/',
-				uaCompany: 'Orgby.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OrgbyBot'
-			}
-		},
-		'1685': {
-			userAgent: 'OpenAcoon v4.1.0 (www.openacoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'OpenAcoon v4.1.0',
-				uaUrl: 'http://www.openacoon.de/',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'1690': {
-			userAgent: 'YandexSomething/1.0',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexSomething/1.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'1703': {
-			userAgent: 'OOZBOT/0.20 ( http://www.setooz.com/oozbot.html ; agentname at setooz dot_com )',
-			metadata: {
-				uaFamily: 'Setoozbot ',
-				uaName: 'OOZBOT/0.20 c',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot '
-			}
-		},
-		'1704': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/2.0.2 +http://seekda.com)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/2.0.2',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'1705': {
-			userAgent: 'adidxbot/1.1 (+http://search.msn.com/msnbot.htm)',
-			metadata: {
-				uaFamily: 'adidxbot',
-				uaName: 'adidxbot/1.1',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: '\tMicrosoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=adidxbot'
-			}
-		},
-		'1711': {
-			userAgent: 'Robozilla/1.0',
-			metadata: {
-				uaFamily: 'Robozilla',
-				uaName: 'Robozilla/1.0',
-				uaUrl: 'http://www.dmoz.org/guidelines/robozilla.html',
-				uaCompany: 'DMOZ',
-				uaCompanyUrl: 'http://www.dmoz.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Robozilla'
-			}
-		},
-		'1712': {
-			userAgent: 'yacybot (x86 Windows Vista 6.1; java 1.6.0_13; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'1717': {
-			userAgent: 'Mozilla/5.0 (compatible; Falconsbot; +http://iws.seu.edu.cn/services/falcons/contact_us.jsp)',
-			metadata: {
-				uaFamily: 'Falconsbot',
-				uaName: 'Falconsbot',
-				uaUrl: 'http://ws.nju.edu.cn/falcons/contact_us.jsp',
-				uaCompany: 'Institute of Web Science',
-				uaCompanyUrl: 'http://iws.seu.edu.cn/page/english/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Falconsbot'
-			}
-		},
-		'1726': {
-			userAgent: 'Bloggsi/1.0 (http://bloggsi.com/)',
-			metadata: {
-				uaFamily: 'Bloggsi',
-				uaName: 'Bloggsi/1.0',
-				uaUrl: 'http://bloggsi.com/',
-				uaCompany: 'Stefan Fischerl\xe4nder',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Bloggsi'
-			}
-		},
-		'1727': {
-			userAgent: 'Technoratibot/7.0',
-			metadata: {
-				uaFamily: 'Technoratibot',
-				uaName: 'Technoratibot/7.0',
-				uaUrl: '',
-				uaCompany: 'Technorati Inc.',
-				uaCompanyUrl: 'http://www.technorati.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Technoratibot'
-			}
-		},
-		'1728': {
-			userAgent: 'Technoratibot/8.0',
-			metadata: {
-				uaFamily: 'Technoratibot',
-				uaName: 'Technoratibot/8.0',
-				uaUrl: '',
-				uaCompany: 'Technorati Inc.',
-				uaCompanyUrl: 'http://www.technorati.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Technoratibot'
-			}
-		},
-		'1731': {
-			userAgent: 'Mozilla/5.0 (compatible; DNS-Digger-Explorer/1.0; +http://www.dnsdigger.com)',
-			metadata: {
-				uaFamily: 'DNS-Digger-Explorer',
-				uaName: 'DNS-Digger-Explorer/1.0',
-				uaUrl: '',
-				uaCompany: 'DNSDigger',
-				uaCompanyUrl: 'http://www.dnsdigger.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DNS-Digger-Explorer'
-			}
-		},
-		'1733': {
-			userAgent: 'Nokia6680/1.0 (4.04.07) SymbianOS/8.0 Series60/2.6 Profile/MIDP-2.0 Configuration/CLDC-1.1 (botmobi find.mobi/bot.html find@mtld.mobi)',
-			metadata: {
-				uaFamily: 'botmobi',
-				uaName: 'botmobi',
-				uaUrl: 'http://find.mobi/bot.html',
-				uaCompany: 'mTLD, Ltd.',
-				uaCompanyUrl: 'http://mtld.mobi/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=botmobi'
-			}
-		},
-		'1735': {
-			userAgent: 'Mozilla/5.0 (compatible; AboutUsBot/0.9; +http://www.aboutus.org/AboutUsBot)',
-			metadata: {
-				uaFamily: 'AboutUsBot',
-				uaName: 'AboutUsBot/0.9',
-				uaUrl: 'http://www.aboutus.org/AboutUs:Bot',
-				uaCompany: 'AboutUs, Inc.',
-				uaCompanyUrl: 'http://www.aboutus.org/AboutUs.org',
-				uaIcon: 'bot_AboutUsBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AboutUsBot'
-			}
-		},
-		'1738': {
-			userAgent: 'ICC-Crawler(Mozilla-compatible; ; http://kc.nict.go.jp/project1/crawl.html)',
-			metadata: {
-				uaFamily: 'ICC-Crawler',
-				uaName: 'ICC-Crawler',
-				uaUrl: 'http://kc.nict.go.jp/project1/crawl.html',
-				uaCompany: 'NICT',
-				uaCompanyUrl: 'http://nict.go.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ICC-Crawler'
-			}
-		},
-		'1751': {
-			userAgent: 'WebImages 0.3 ( http://herbert.groot.jebbink.nl/?app=WebImages )',
-			metadata: {
-				uaFamily: 'WebImages',
-				uaName: 'WebImages 0.3',
-				uaUrl: '',
-				uaCompany: 'Herbert Groot Jebbink',
-				uaCompanyUrl: 'http://herbert.groot.jebbink.nl/ ',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebImages'
-			}
-		},
-		'1752': {
-			userAgent: 'Browsershots',
-			metadata: {
-				uaFamily: 'Browsershots',
-				uaName: 'Browsershots',
-				uaUrl: 'http://browsershots.org/faq',
-				uaCompany: 'Browsershots.org',
-				uaCompanyUrl: 'http://browsershots.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Browsershots'
-			}
-		},
-		'1753': {
-			userAgent: 'BotOnParade, http://www.bots-on-para.de/bot.html',
-			metadata: {
-				uaFamily: 'BotOnParade',
-				uaName: 'BotOnParade',
-				uaUrl: 'http://www.bots-on-para.de/bot.html',
-				uaCompany: 'Angus Internetmarketing',
-				uaCompanyUrl: 'http://www.angus.co.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BotOnParade'
-			}
-		},
-		'1754': {
-			userAgent: 'BlogPulse (ISSpider-3.0)',
-			metadata: {
-				uaFamily: 'BlogPulse',
-				uaName: 'BlogPulse',
-				uaUrl: 'http://www.blogpulse.com/',
-				uaCompany: 'Nielsen Company',
-				uaCompanyUrl: 'http://www.nielsen-online.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BlogPulse'
-			}
-		},
-		'1759': {
-			userAgent: 'Twiceler-0.9 http://www.cuill.com/twiceler/robot.html',
-			metadata: {
-				uaFamily: 'Twiceler',
-				uaName: 'Twiceler-0.9 b',
-				uaUrl: 'http://www.cuil.com/twiceler/robot.html',
-				uaCompany: 'Cuil, Inc.',
-				uaCompanyUrl: 'http://www.cuil.com/',
-				uaIcon: 'bot_Twiceler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Twiceler'
-			}
-		},
-		'1763': {
-			userAgent: 'TwengaBot/1.1 (+http://www.twenga.com/bot.html)',
-			metadata: {
-				uaFamily: 'TwengaBot',
-				uaName: 'TwengaBot/1.1',
-				uaUrl: 'http://www.twenga.com/bot.html',
-				uaCompany: 'Twenga SA',
-				uaCompanyUrl: 'http://www.twenga.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TwengaBot'
-			}
-		},
-		'1765': {
-			userAgent: 'ICC-Crawler/2.0 (Mozilla-compatible; ; http://kc.nict.go.jp/project1/crawl.html)',
-			metadata: {
-				uaFamily: 'ICC-Crawler',
-				uaName: 'ICC-Crawler/2.0',
-				uaUrl: 'http://kc.nict.go.jp/project1/crawl.html',
-				uaCompany: 'NICT',
-				uaCompanyUrl: 'http://nict.go.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ICC-Crawler'
-			}
-		},
-		'1766': {
-			userAgent: 'Mozilla/4.0 (compatible;  Vagabondo/4.0Beta; webcrawler at wise-guys dot nl; http://webagent.wise-guys.nl/; http://www.wise-guys.nl/)',
-			metadata: {
-				uaFamily: 'Vagabondo',
-				uaName: 'Vagabondo/4.0Beta',
-				uaUrl: 'http://webagent.wise-guys.nl/',
-				uaCompany: 'WiseGuys Internet BV',
-				uaCompanyUrl: 'http://www.wise-guys.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Vagabondo'
-			}
-		},
-		'1770': {
-			userAgent: 'baypup/1.1 (Baypup; http://www.baypup.com/; jason@baypup.com)',
-			metadata: {
-				uaFamily: 'baypup',
-				uaName: 'baypup/1.1',
-				uaUrl: '',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot_Baypup.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=baypup'
-			}
-		},
-		'1771': {
-			userAgent: 'mozilla/5.0 (compatible; discobot/1.1; +http://discoveryengine.com/discobot.html)',
-			metadata: {
-				uaFamily: 'discoverybot',
-				uaName: 'discobot/1.1',
-				uaUrl: 'http://discoveryengine.com/discoverybot.html',
-				uaCompany: 'discoveryengine.com. ',
-				uaCompanyUrl: 'http://www.discoveryengine.com/',
-				uaIcon: 'bot_discobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=discoverybot'
-			}
-		},
-		'1772': {
-			userAgent: 'Mozilla/5.0 (compatible; Tagoobot/3.0; +http://www.tagoo.ru)',
-			metadata: {
-				uaFamily: 'Tagoobot',
-				uaName: 'Tagoobot/3.0',
-				uaUrl: '',
-				uaCompany: 'Tagoo',
-				uaCompanyUrl: 'http://www.tagoo.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Tagoobot'
-			}
-		},
-		'1773': {
-			userAgent: '50.nu/0.01 ( +http://50.nu/bot.html )',
-			metadata: {
-				uaFamily: '50.nu',
-				uaName: '50.nu/0.01',
-				uaUrl: 'http://50.nu/bot.html',
-				uaCompany: 'Innovate it',
-				uaCompanyUrl: 'http://innovateit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=50.nu'
-			}
-		},
-		'1776': {
-			userAgent: 'yacybot (i386 Linux 2.6.28-13-generic; java 1.6.0_13; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'1779': {
-			userAgent: 'Mozilla/5.0 (compatible; Scarlett/ 1.0; +http://www.ellerdale.com/crawler.html)',
-			metadata: {
-				uaFamily: 'Scarlett',
-				uaName: 'Scarlett/ 1.0',
-				uaUrl: 'http://www.ellerdale.com/crawler.html',
-				uaCompany: 'Ellerdale Project',
-				uaCompanyUrl: 'http://www.ellerdale.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Scarlett'
-			}
-		},
-		'1780': {
-			userAgent: 'LexxeBot/1.0 (lexxebot@lexxe.com)',
-			metadata: {
-				uaFamily: 'LexxeBot',
-				uaName: 'LexxeBot/1.0',
-				uaUrl: 'http://lexxe.com/about/webmasters.cfm',
-				uaCompany: 'Lexxe Pty Ltd',
-				uaCompanyUrl: 'http://lexxe.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LexxeBot'
-			}
-		},
-		'1784': {
-			userAgent: 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1; aggregator:Spinn3r (Spinn3r 3.1); http://spinn3r.com/robot) Gecko/20021130',
-			metadata: {
-				uaFamily: 'Spinn3r',
-				uaName: 'Spinn3r 3.1',
-				uaUrl: 'http://spinn3r.com/robot',
-				uaCompany: 'Tailrank Inc',
-				uaCompanyUrl: 'http://tailrank.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Spinn3r'
-			}
-		},
-		'1793': {
-			userAgent: 'Mozilla/5.0 (Yahoo-MMCrawler/4.0; mailto:vertical-crawl-support@yahoo-inc.com)',
-			metadata: {
-				uaFamily: 'Yahoo!',
-				uaName: 'Yahoo-MMCrawler/4.0',
-				uaUrl: 'http://help.yahoo.com/',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo!'
-			}
-		},
-		'1798': {
-			userAgent: 'LinkAider (http://linkaider.com/crawler/)',
-			metadata: {
-				uaFamily: 'LinkAider',
-				uaName: 'LinkAider',
-				uaUrl: 'http://linkaider.com/crawler/',
-				uaCompany: 'Ivinco',
-				uaCompanyUrl: 'http://linkaider.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LinkAider'
-			}
-		},
-		'1805': {
-			userAgent: 'WinWebBot/1.0; (Balaena Ltd, UK); http://www.balaena.com/winwebbot.html; winwebbot@balaena.com;)',
-			metadata: {
-				uaFamily: 'WinWebBot',
-				uaName: 'WinWebBot/1.0',
-				uaUrl: 'http://www.balaena.com/winwebbot.html',
-				uaCompany: 'Balaena Ltd',
-				uaCompanyUrl: 'http://www.balaena.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WinWebBot'
-			}
-		},
-		'1815': {
-			userAgent: 'R6_FeedFetcher(www.radian6.com/crawler)',
-			metadata: {
-				uaFamily: 'R6 bot',
-				uaName: 'R6_FeedFetcher',
-				uaUrl: 'http://www.radian6.com/crawler/',
-				uaCompany: 'Radian6 Technologies Inc',
-				uaCompanyUrl: 'http://www.radian6.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=R6 bot'
-			}
-		},
-		'1816': {
-			userAgent: 'http://domino.research.ibm.com/comm/research_projects.nsf/pages/sai-crawler.callingcard.html',
-			metadata: {
-				uaFamily: 'SAI Crawler',
-				uaName: 'SAI Crawler',
-				uaUrl: 'http://domino.research.ibm.com/comm/research_projects.nsf/pages/sai-crawler.callingcard.html',
-				uaCompany: 'IBM',
-				uaCompanyUrl: 'http://www.ibm.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SAI Crawler'
-			}
-		},
-		'1818': {
-			userAgent: 'Mozilla/5.0 (compatible;YodaoBot-Image/1.0;http://www.youdao.com/help/webmaster/spider/;)',
-			metadata: {
-				uaFamily: 'YodaoBot',
-				uaName: 'YodaoBot-Image/1.0',
-				uaUrl: 'http://www.youdao.com/help/webmaster/spider/',
-				uaCompany: 'youdao',
-				uaCompanyUrl: 'http://www.youdao.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YodaoBot'
-			}
-		},
-		'1838': {
-			userAgent: 'Mozilla/5.0 (compatible; Topicbot/12.0rc-2; +http://topicbot.awardspace.us/)',
-			metadata: {
-				uaFamily: 'Topicbot',
-				uaName: 'Topicbot/12.0rc-2',
-				uaUrl: 'http://topicbot.awardspace.us/',
-				uaCompany: 'Research Group TopicBot',
-				uaCompanyUrl: 'http://topicbot.awardspace.us/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Topicbot'
-			}
-		},
-		'1849': {
-			userAgent: 'http://www.amagit.com/',
-			metadata: {
-				uaFamily: 'Amagit.COM',
-				uaName: 'Amagit.COM',
-				uaUrl: '',
-				uaCompany: 'Joshua Schwarz',
-				uaCompanyUrl: 'http://contacts.joshuaschwarz.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Amagit.COM'
-			}
-		},
-		'1853': {
-			userAgent: 'Sosospider+(+http://help.soso.com/webspider.htm)',
-			metadata: {
-				uaFamily: 'Sosospider',
-				uaName: 'Sosospider',
-				uaUrl: 'http://help.soso.com/webspider.htm',
-				uaCompany: 'Tencent, Inc.',
-				uaCompanyUrl: 'http://www.tencent.com/',
-				uaIcon: 'bot_soso.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sosospider'
-			}
-		},
-		'1856': {
-			userAgent: 'findlinks/1.1.5-beta7 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.4-beta7',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'1859': {
-			userAgent: 'Mozilla/5.0 (compatible; JadynAveBot; +http://www.jadynave.com/robot)',
-			metadata: {
-				uaFamily: 'JadynAveBot',
-				uaName: 'JadynAveBot',
-				uaUrl: 'http://www.jadynave.com/robot',
-				uaCompany: 'Yesup Ecommerce Solutions Inc.',
-				uaCompanyUrl: 'http://www.yesup.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=JadynAveBot'
-			}
-		},
-		'1866': {
-			userAgent: 'smart.apnoti.com Robot/v1.34 (http://smart.apnoti.com/en/aboutApnotiWebCrawler.html)',
-			metadata: {
-				uaFamily: 'smart.apnoti.com Robot',
-				uaName: 'smart.apnoti.com Robot/v1.34',
-				uaUrl: 'http://smart.apnoti.com/en/aboutApnotiWebCrawler.html',
-				uaCompany: 'apnoti.com GmbH',
-				uaCompanyUrl: 'http://www.apnoti.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=smart.apnoti.com Robot'
-			}
-		},
-		'1867': {
-			userAgent: 'MnoGoSearch/3.3.9',
-			metadata: {
-				uaFamily: 'MnoGoSearch',
-				uaName: 'MnoGoSearch/3.3.9',
-				uaUrl: 'http://www.mnogosearch.org/products.html',
-				uaCompany: 'Lavtech.Com',
-				uaCompanyUrl: 'http://www.lavtech.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MnoGoSearch'
-			}
-		},
-		'1869': {
-			userAgent: 'Yandex/1.01.001 (compatible; Win16; H)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'Yandex/1.01.001',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'1870': {
-			userAgent: 'FollowSite Bot ( http://www.followsite.com/bot.html )',
-			metadata: {
-				uaFamily: 'FollowSite Bot',
-				uaName: 'FollowSite Bot',
-				uaUrl: 'http://www.followsite.com/bot.html',
-				uaCompany: 'ASX Networks ApS',
-				uaCompanyUrl: 'http://asxnetworks.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FollowSite Bot'
-			}
-		},
-		'1871': {
-			userAgent: 'Mozilla/5.0 (compatible; 008/0.83; http://www.80legs.com/spider.html;) Gecko/2008032620',
-			metadata: {
-				uaFamily: '80legs',
-				uaName: '80legs/0.83',
-				uaUrl: 'http://www.80legs.com/webcrawler.html',
-				uaCompany: 'Computational Crawling, LP',
-				uaCompanyUrl: 'http://compucrawl.com/',
-				uaIcon: 'bot_80legs.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=80legs'
-			}
-		},
-		'1872': {
-			userAgent: 'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.20) Gecko/20090429 HeartRails_Capture/0.6 (+http://capture.heartrails.com/) BonEcho/2.0.0.20',
-			metadata: {
-				uaFamily: 'HeartRails_Capture',
-				uaName: 'HeartRails_Capture/0.6',
-				uaUrl: 'http://capture.heartrails.com/help/question',
-				uaCompany: 'HeartRails Inc.',
-				uaCompanyUrl: 'http://www.heartrails.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HeartRails_Capture'
-			}
-		},
-		'1885': {
-			userAgent: 'Speedy Spider (Entireweb; Beta/1.2; http://www.entireweb.com/about/search_tech/speedyspider/)',
-			metadata: {
-				uaFamily: 'Speedy',
-				uaName: 'Speedy Spider Beta/1.2',
-				uaUrl: '',
-				uaCompany: 'Entireweb Sweden AB',
-				uaCompanyUrl: 'http://www.entireweb.com/',
-				uaIcon: 'bot_Speedy.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Speedy'
-			}
-		},
-		'1887': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.14.2 +http://rjpower.org)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/1.14.2',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'1894': {
-			userAgent: 'yacybot (amd64 Windows 7 6.1; java 1.6.0_14; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'1895': {
-			userAgent: 'Mozilla/5.0 (compatible; Plukkie/1.1; http://www.botje.com/plukkie.htm)',
-			metadata: {
-				uaFamily: 'Plukkie',
-				uaName: 'Plukkie/1.1',
-				uaUrl: 'http://www.botje.com/plukkie.htm',
-				uaCompany: 'botje.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Plukkie'
-			}
-		},
-		'1906': {
-			userAgent: 'SanszBot/1.7(http://www.sansz.org/sanszbot, spider@sansz.org) (spider@sansz.org)',
-			metadata: {
-				uaFamily: 'SanszBot',
-				uaName: 'SanszBot/1.7',
-				uaUrl: 'http://www.sansz.org/sanszbot',
-				uaCompany: 'Peres Levente (Sansz Foundation)',
-				uaCompanyUrl: 'http://www.sansz.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SanszBot'
-			}
-		},
-		'1908': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.2.3; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.2.3',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'1909': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.3.0; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.3.0',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'1932': {
-			userAgent: 'Mozilla/5.0 (compatible; GurujiBot/1.0; +http://www.guruji.com/en/WebmasterFAQ.html)',
-			metadata: {
-				uaFamily: 'GurujiBot',
-				uaName: 'GurujiBot/1.0',
-				uaUrl: 'http://www.guruji.com/en/WebmasterFAQ.html',
-				uaCompany: 'Guruji.com Software Private Limited',
-				uaCompanyUrl: 'http://www.guruji.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GurujiBot'
-			}
-		},
-		'1936': {
-			userAgent: 'Sogou-Test-Spider/4.0 (compatible; MSIE 5.5; Windows 98)',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'Sogou-Test-Spider/4.0',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'1938': {
-			userAgent: 'Mozilla/5.0 (compatible;+ParchBot/1.0;++http://www.parchmenthill.com/search.htm)',
-			metadata: {
-				uaFamily: 'ParchBot',
-				uaName: 'ParchBot/1.0',
-				uaUrl: 'http://www.parchmenthill.com/search.htm',
-				uaCompany: 'Parchment Hill',
-				uaCompanyUrl: 'http://www.parchmenthill.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ParchBot'
-			}
-		},
-		'1941': {
-			userAgent: 'AboutUsBot',
-			metadata: {
-				uaFamily: 'AboutUsBot',
-				uaName: 'AboutUsBot',
-				uaUrl: 'http://www.aboutus.org/AboutUs:Bot',
-				uaCompany: 'AboutUs, Inc. ',
-				uaCompanyUrl: 'http://www.aboutus.org/AboutUs.org',
-				uaIcon: 'bot_AboutUsBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AboutUsBot'
-			}
-		},
-		'1943': {
-			userAgent: 'Yandex/1.01.001 (compatible; Win16; m)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'Yandex/1.01.001',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'1950': {
-			userAgent: 'Mozilla/5.0 (compatible; SecretSerachEngineLabs.com-SBSearch/0.9; http://www.secretsearchenginelabs.com/secret-web-crawler.php)',
-			metadata: {
-				uaFamily: 'SBSearch',
-				uaName: 'SBSearch/0.9',
-				uaUrl: 'http://www.secretsearchenginelabs.com/secret-web-crawler.php',
-				uaCompany: 'SecretSearchEngineLabs.com',
-				uaCompanyUrl: 'http://www.secretsearchenginelabs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SBSearch'
-			}
-		},
-		'1957': {
-			userAgent: 'yacybot (i386 Linux 2.6.23; java 1.6.0_06; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'1971': {
-			userAgent: 'taptubot *** please read http://www.taptu.com/corp/taptubot ***',
-			metadata: {
-				uaFamily: 'taptubot',
-				uaName: 'taptubot',
-				uaUrl: 'http://www.taptu.com/corp/taptubot',
-				uaCompany: 'Taptu Limited',
-				uaCompanyUrl: 'http://www.taptu.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=taptubot'
-			}
-		},
-		'1982': {
-			userAgent: 'Qseero v1.0.0',
-			metadata: {
-				uaFamily: 'Qseero',
-				uaName: 'Qseero 1.0.0',
-				uaUrl: '',
-				uaCompany: 'Qseero, Inc.',
-				uaCompanyUrl: 'http://q0.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Qseero'
-			}
-		},
-		'1992': {
-			userAgent: 'SeznamBot/2.0 (+http://fulltext.seznam.cz/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/2.0',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'1994': {
-			userAgent: 'Mozilla/5.0 (compatible; Exabot/3.0 (BiggerBetter); +http://www.exabot.com/go/robot)',
-			metadata: {
-				uaFamily: 'Exabot',
-				uaName: 'Exabot/3.0/BiggerBetter',
-				uaUrl: 'http://www.exabot.com/go/robot',
-				uaCompany: 'Exalead S.A.',
-				uaCompanyUrl: 'http://www.exalead.com/',
-				uaIcon: 'bot_Exabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Exabot'
-			}
-		},
-		'2003': {
-			userAgent: 'TinEye/1.0; +http://www.tineye.com/',
-			metadata: {
-				uaFamily: 'TinEye',
-				uaName: 'TinEye/1.0',
-				uaUrl: 'http://tineye.com/crawler.html ',
-				uaCompany: 'Id\xe9e Inc.',
-				uaCompanyUrl: 'http://ideeinc.com/',
-				uaIcon: 'bot_TinEye.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TinEye'
-			}
-		},
-		'2004': {
-			userAgent: 'Thumbnail.CZ robot 1.1 (http://thumbnail.cz/why-no-robots-txt.html)',
-			metadata: {
-				uaFamily: 'Thumbnail.CZ robot',
-				uaName: 'Thumbnail.CZ robot 1.1',
-				uaUrl: 'http://thumbnail.cz/why-no-robots-txt.html',
-				uaCompany: 'Miroslav Such\xfd',
-				uaCompanyUrl: 'http://miroslav.suchy.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Thumbnail.CZ robot'
-			}
-		},
-		'2016': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.12.1b +http://netarkivet.dk/website/info.html)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/1.12.1b',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'2017': {
-			userAgent: 'yacybot (amd64 Linux 2.6.18-164.el5; java 1.6.0; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'2021': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.14.3 +http://www.webarchiv.cz)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/1.14.3',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'2022': {
-			userAgent: 'bitlybot',
-			metadata: {
-				uaFamily: 'bitlybot',
-				uaName: 'bitlybot',
-				uaUrl: 'http://code.google.com/p/bitly-bot/',
-				uaCompany: 'Rahul Garg',
-				uaCompanyUrl: 'http://www.google.com/profiles/mr.rahulgarg',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bitlybot'
-			}
-		},
-		'2024': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.3.1; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.3.1',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'2026': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/2.0.2 +http://aihit.com)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/2.0.2',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'2028': {
-			userAgent: 'Mozilla/5.0 (compatible; Najdi.si/3.1)',
-			metadata: {
-				uaFamily: 'Najdi.si',
-				uaName: 'Najdi.si/3.1',
-				uaUrl: 'http://www.najdi.si/help/aboutsearch.html#q5',
-				uaCompany: 'Najdi.si d.o.o.',
-				uaCompanyUrl: 'http://www.najdi.si/',
-				uaIcon: 'bot_najdi.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Najdi.si'
-			}
-		},
-		'2050': {
-			userAgent: 'BabalooSpider/1.3 (BabalooSpider; http://www.babaloo.si; spider@babaloo.si)',
-			metadata: {
-				uaFamily: 'BabalooSpider',
-				uaName: 'BabalooSpider/1.3',
-				uaUrl: '',
-				uaCompany: 'Babaloo d.o.o.',
-				uaCompanyUrl: 'http://www.babaloo.si/',
-				uaIcon: 'bot_BabalooSpider.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BabalooSpider'
-			}
-		},
-		'2057': {
-			userAgent: 'http://arachnode.net 1.2',
-			metadata: {
-				uaFamily: 'arachnode.net',
-				uaName: 'arachnode.net/1.2',
-				uaUrl: 'http://arachnode.codeplex.com/',
-				uaCompany: 'arachnode.net, llc',
-				uaCompanyUrl: 'http://arachnode.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=arachnode.net'
-			}
-		},
-		'2063': {
-			userAgent: 'BDFetch',
-			metadata: {
-				uaFamily: 'BDFetch',
-				uaName: 'BDFetch',
-				uaUrl: '',
-				uaCompany: 'BDProtect Inc.',
-				uaCompanyUrl: 'http://www.brandprotect.com/',
-				uaIcon: 'bot_BDFetch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BDFetch'
-			}
-		},
-		'2071': {
-			userAgent: 'yacybot (i386 Linux 2.6.24-23-generic; java 1.6.0_16; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'2073': {
-			userAgent: 'Mozilla/5.0 (compatible; Plukkie/1.2; http://www.botje.com/plukkie.htm)',
-			metadata: {
-				uaFamily: 'Plukkie',
-				uaName: 'Plukkie/1.2',
-				uaUrl: 'http://www.botje.com/plukkie.htm',
-				uaCompany: 'botje.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Plukkie'
-			}
-		},
-		'2078': {
-			userAgent: 'Ronzoobot/1.2 (http://www.ronzoo.com/about.php)',
-			metadata: {
-				uaFamily: 'Ronzoobot',
-				uaName: 'Ronzoobot/1.2',
-				uaUrl: 'http://www.ronzoo.com/about/',
-				uaCompany: 'Ronzoo',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_Ronzoobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ronzoobot'
-			}
-		},
-		'2079': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/3.0.0-SNAPSHOT-20091120.021634 +http://crawler.archive.org)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/3.0.0',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'2081': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.14.3.r6601 +http://www.buddybuzz.net/yptrino)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/1.14.3.r6601',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'2087': {
-			userAgent: 'Zscho.de Crawler/Nutch-1.0-Zscho.de-semantic_patch (Zscho.de Crawler, collecting for machine learning; http://zscho.de/)',
-			metadata: {
-				uaFamily: 'Nutch',
-				uaName: 'Nutch/1.0 at zscho.de',
-				uaUrl: 'http://www.nutch.org/docs/en/bot.html',
-				uaCompany: 'lucene',
-				uaCompanyUrl: 'http://lucene.apache.org/',
-				uaIcon: 'bot_Nutch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nutch'
-			}
-		},
-		'2088': {
-			userAgent: 'yacybot (i386 Linux 2.6.23; java 1.6.0_17; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'2091': {
-			userAgent: 'yacybot (amd64 Linux 2.6.26-2-openvz-amd64; java 1.6.0_12; UTC/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'2098': {
-			userAgent: 'Surphace Scout&v4.0 - scout at surphace dot com',
-			metadata: {
-				uaFamily: 'Surphace Scout',
-				uaName: 'Surphace Scout/4.0',
-				uaUrl: '',
-				uaCompany: 'Surphace (AOL news)',
-				uaCompanyUrl: 'http://www.surphace.com/',
-				uaIcon: 'bot_Surphace_Scout.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Surphace Scout'
-			}
-		},
-		'2099': {
-			userAgent: 'Mozilla/5.0 (compatible; Steeler/3.5; http://www.tkl.iis.u-tokyo.ac.jp/~crawler/)',
-			metadata: {
-				uaFamily: 'Steeler',
-				uaName: 'Steeler/3.5',
-				uaUrl: 'http://www.tkl.iis.u-tokyo.ac.jp/~crawler/',
-				uaCompany: 'Kitsuregawa Laboratory, The University of Tokyo',
-				uaCompanyUrl: 'http://www.tkl.iis.u-tokyo.ac.jp/',
-				uaIcon: 'bot_Steeler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Steeler'
-			}
-		},
-		'2102': {
-			userAgent: 'Mozilla/5.0 (compatible; aiHitBot-DM/2.0.2 +http://www.aihit.com)',
-			metadata: {
-				uaFamily: 'aiHitBot',
-				uaName: 'aiHitBot-DM/2.0.2',
-				uaUrl: '',
-				uaCompany: 'aiHit Ltd.',
-				uaCompanyUrl: 'http://aihit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aiHitBot'
-			}
-		},
-		'2110': {
-			userAgent: 'amibot - http://www.amidalla.de - tech@amidalla.com libwww-perl/5.831',
-			metadata: {
-				uaFamily: 'amibot',
-				uaName: 'amibot',
-				uaUrl: 'http://www.amidalla.de/info.htm',
-				uaCompany: 'amidalla.de',
-				uaCompanyUrl: 'http://www.amidalla.de/',
-				uaIcon: 'bot_amibot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=amibot'
-			}
-		},
-		'2120': {
-			userAgent: 'Mozilla/5.0 (compatible; Mp3Bot/0.7; +http://mp3realm.org/mp3bot/)',
-			metadata: {
-				uaFamily: 'Mp3Bot',
-				uaName: 'Mp3Bot/0.7',
-				uaUrl: 'http://mp3realm.org/mp3bot/',
-				uaCompany: 'Mp3Realm.Org',
-				uaCompanyUrl: 'http://mp3realm.org/',
-				uaIcon: 'bot_Mp3Bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mp3Bot'
-			}
-		},
-		'2125': {
-			userAgent: 'baypup/colbert (Baypup; http://sf.baypup.com/webmasters; jason@baypup.com)',
-			metadata: {
-				uaFamily: 'baypup',
-				uaName: 'baypup/colbert',
-				uaUrl: 'http://www.baypup.com/webmasters',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot_Baypup.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=baypup'
-			}
-		},
-		'2132': {
-			userAgent: 'gonzo1[P] +http://www.suchen.de/faq.html',
-			metadata: {
-				uaFamily: 'gonzo',
-				uaName: 'gonzo1',
-				uaUrl: 'http://www.suchen.de/faq.html',
-				uaCompany: 'SEARCHTEQ',
-				uaCompanyUrl: 'http://www.searchteq.de/',
-				uaIcon: 'bot_gonzo.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=gonzo'
-			}
-		},
-		'2133': {
-			userAgent: 'gonzo2[P] +http://www.suchen.de/faq.html',
-			metadata: {
-				uaFamily: 'gonzo',
-				uaName: 'gonzo2',
-				uaUrl: 'http://www.suchen.de/faq.html',
-				uaCompany: 'SEARCHTEQ',
-				uaCompanyUrl: 'http://www.searchteq.de/',
-				uaIcon: 'bot_gonzo.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=gonzo'
-			}
-		},
-		'2135': {
-			userAgent: 'Mozilla/5.0 (compatible; ptd-crawler; +http://bixolabs.com/crawler/ptd/; crawler@bixolabs.com)',
-			metadata: {
-				uaFamily: 'bixocrawler',
-				uaName: 'ptd-crawler',
-				uaUrl: 'http://wiki.github.com/bixo/bixo/bixocrawler',
-				uaCompany: 'Bixo Labs',
-				uaCompanyUrl: 'http://openbixo.org/',
-				uaIcon: 'bot_ptd-crawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bixocrawler'
-			}
-		},
-		'2138': {
-			userAgent: 'SBIder/Nutch-1.0-dev (http://www.sitesell.com/sbider.html)',
-			metadata: {
-				uaFamily: 'SBIder',
-				uaName: 'SBIder/1.0',
-				uaUrl: 'http://www.sitesell.com/sbider.html',
-				uaCompany: 'SiteSell',
-				uaCompanyUrl: 'http://www.sitesell.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SBIder'
-			}
-		},
-		'2145': {
-			userAgent: 'Ronzoobot/1.3 (http://www.ronzoo.com/about.php)',
-			metadata: {
-				uaFamily: 'Ronzoobot',
-				uaName: 'Ronzoobot/1.3',
-				uaUrl: 'http://www.ronzoo.com/about/',
-				uaCompany: 'Ronzoo',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_Ronzoobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ronzoobot'
-			}
-		},
-		'2155': {
-			userAgent: 'Linguee Bot (http://www.linguee.com/bot)',
-			metadata: {
-				uaFamily: 'Linguee Bot',
-				uaName: 'Linguee Bot',
-				uaUrl: 'http://www.linguee.com/bot',
-				uaCompany: 'Linguee GmbH',
-				uaCompanyUrl: 'http://www.linguee.com/',
-				uaIcon: 'bot_Linguee.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Linguee Bot'
-			}
-		},
-		'2162': {
-			userAgent: 'baypup/colbert (Baypup; http://www.baypup.com/webmasters; jason@baypup.com)',
-			metadata: {
-				uaFamily: 'baypup',
-				uaName: 'baypup/colbert',
-				uaUrl: 'http://www.baypup.com/webmasters',
-				uaCompany: 'Flatland Industries, Inc.',
-				uaCompanyUrl: 'http://www.flatlandindustries.com/',
-				uaIcon: 'bot_Baypup.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=baypup'
-			}
-		},
-		'2170': {
-			userAgent: 'CorpusCrawler 2.0.0 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.0',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2175': {
-			userAgent: 'ThumbShots-Bot (+http://thumbshots.in/bot.html)',
-			metadata: {
-				uaFamily: 'ThumbShots-Bot',
-				uaName: 'ThumbShots-Bot',
-				uaUrl: 'http://thumbshots.in/bot.html',
-				uaCompany: 'Kristian Fischer',
-				uaCompanyUrl: 'http://www.kfsw.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ThumbShots-Bot'
-			}
-		},
-		'2181': {
-			userAgent: 'CorpusCrawler 2.0.8 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.8',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2183': {
-			userAgent: 'TinEye/1.1 (http://tineye.com/crawler.html)',
-			metadata: {
-				uaFamily: 'TinEye',
-				uaName: 'TinEye/1.1',
-				uaUrl: 'http://tineye.com/crawler.html',
-				uaCompany: 'Id\xe9e Inc.',
-				uaCompanyUrl: 'http://ideeinc.com/',
-				uaIcon: 'bot_TinEye.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TinEye'
-			}
-		},
-		'2185': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.3.2; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.3.2',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'2188': {
-			userAgent: 'Mozilla/5.0 (compatible; aiHitBot/1.0-DS; +http://www.aihit.com/)',
-			metadata: {
-				uaFamily: 'aiHitBot',
-				uaName: 'aiHitBot/1.0-DS',
-				uaUrl: '',
-				uaCompany: 'aiHit Ltd.',
-				uaCompanyUrl: 'http://aihit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aiHitBot'
-			}
-		},
-		'2194': {
-			userAgent: 'CorpusCrawler 2.0.9 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.9',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2195': {
-			userAgent: 'MnoGoSearch/3.2.37',
-			metadata: {
-				uaFamily: 'MnoGoSearch',
-				uaName: 'MnoGoSearch/3.2.37',
-				uaUrl: 'http://www.mnogosearch.org/products.html',
-				uaCompany: 'Lavtech.Com',
-				uaCompanyUrl: 'http://www.lavtech.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MnoGoSearch'
-			}
-		},
-		'2196': {
-			userAgent: 'MojeekBot/0.2 (archi; http://www.mojeek.com/bot.html)',
-			metadata: {
-				uaFamily: 'MojeekBot',
-				uaName: 'MojeekBot/0.2',
-				uaUrl: 'http://www.mojeek.com/bot.html',
-				uaCompany: 'Mojeek Ltd.',
-				uaCompanyUrl: 'http://www.mojeek.com/',
-				uaIcon: 'bot_MojeekBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MojeekBot'
-			}
-		},
-		'2197': {
-			userAgent: 'Pingdom.com_bot_version_1.4_(http://www.pingdom.com/)',
-			metadata: {
-				uaFamily: 'pingdom.com_bot',
-				uaName: 'pingdom.com_bot 1.4',
-				uaUrl: '',
-				uaCompany: 'Pingdom AB',
-				uaCompanyUrl: 'http://www.pingdom.com/',
-				uaIcon: 'bot_pingdomcom_bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=pingdom.com_bot'
-			}
-		},
-		'2205': {
-			userAgent: 'Mozilla/5.0 (compatible; XmarksFetch/1.0; +http://www.xmarks.com/about/crawler; info@xmarks.com)',
-			metadata: {
-				uaFamily: 'XmarksFetch',
-				uaName: 'XmarksFetch/1.0',
-				uaUrl: 'http://www.xmarks.com/about/crawler',
-				uaCompany: 'Xmarks, Inc.',
-				uaCompanyUrl: 'http://www.xmarks.com/',
-				uaIcon: 'bot_XmarksFetch.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=XmarksFetch'
-			}
-		},
-		'2212': {
-			userAgent: 'CorpusCrawler 2.0.10 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.10',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2223': {
-			userAgent: 'Mozilla/5.0 (compatible; aiHitBot/1.0; +http://www.aihit.com/)',
-			metadata: {
-				uaFamily: 'aiHitBot',
-				uaName: 'aiHitBot/1.0',
-				uaUrl: '',
-				uaCompany: 'aiHit Ltd.',
-				uaCompanyUrl: 'http://aihit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aiHitBot'
-			}
-		},
-		'2233': {
-			userAgent: 'Orgbybot/OrgbyBot v1.3 (Spider; http://orgby.com/bot/  ; Orgby.com Search Engine)',
-			metadata: {
-				uaFamily: 'OrgbyBot',
-				uaName: 'OrgbyBot/1.3',
-				uaUrl: 'http://orgby.com/bot/',
-				uaCompany: 'Orgby.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OrgbyBot'
-			}
-		},
-		'2235': {
-			userAgent: 'CorpusCrawler 2.0.12 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.12',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2239': {
-			userAgent: 'CorpusCrawler 2.0.13 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.13',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2241': {
-			userAgent: 'CorpusCrawler 2.0.14 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.14',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2242': {
-			userAgent: 'CorpusCrawler 2.0.15 (http://corpora.fi.muni.cz/crawler/)',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.15',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2246': {
-			userAgent: 'Mozilla/5.0 (compatible; Semager/1.4; http://www.semager.de/blog/semager-bots/)',
-			metadata: {
-				uaFamily: 'Semager',
-				uaName: 'Semager/1.4',
-				uaUrl: 'http://www.semager.de/blog/semager-bots/',
-				uaCompany: 'NG-Marketing',
-				uaCompanyUrl: 'http://www.ng-marketing.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Semager'
-			}
-		},
-		'2279': {
-			userAgent: 'yacybot (amd64 Linux 2.6.32-gentoo; java 1.6.0_17; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'2300': {
-			userAgent: 'yacybot (x86 Windows 2003 5.2; java 1.6.0_16; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'2773': {
-			userAgent: 'CorpusCrawler 2.0.17 (http://corpora.fi.muni.cz/crawler/);Project:CzCorpus',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.17',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2844': {
-			userAgent: 'CorpusCrawler 2.0.19 (http://corpora.fi.muni.cz/crawler/);Project:CzCorpus',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.19',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2937': {
-			userAgent: 'CorpusCrawler 2.0.20 (http://corpora.fi.muni.cz/crawler/);Project:CzCorpus',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.20',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2947': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.14.2 +http://www.webarchiv.cz)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/1.14.2',
-				uaUrl: 'http://crawler.archive.org/',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'2948': {
-			userAgent: 'CorpusCrawler 2.0.21 (http://corpora.fi.muni.cz/crawler/);Project:CzCorpus',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.21',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2952': {
-			userAgent: 'CorpusCrawler 2.0.22 (http://corpora.fi.muni.cz/crawler/);Project:CzCorpus',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.22',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'2999': {
-			userAgent: 'CorpusCrawler 2.0.24 (http://corpora.fi.muni.cz/crawler/);Project:CzCorpus',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.24',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'3002': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; FeedFinder-2.0; http://bloggz.se/crawler)',
-			metadata: {
-				uaFamily: 'FeedFinder/bloggz.se',
-				uaName: 'FeedFinder-2.0',
-				uaUrl: 'http://bloggz.se/crawler/',
-				uaCompany: 'Triop AB',
-				uaCompanyUrl: 'http://triop.se/',
-				uaIcon: 'bot_FeedFinder_bloggz.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FeedFinder/bloggz.se'
-			}
-		},
-		'3003': {
-			userAgent: 'CorpusCrawler 2.0.25 (http://corpora.fi.muni.cz/crawler/);Project:CzCorpus',
-			metadata: {
-				uaFamily: 'CorpusCrawler',
-				uaName: 'CorpusCrawler 2.0.25',
-				uaUrl: 'http://corpora.fi.muni.cz/crawler/',
-				uaCompany: 'NLP - at the Faculty of Informatics, Masaryk University, Brno',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlplab',
-				uaIcon: 'bot_CorpusCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CorpusCrawler'
-			}
-		},
-		'3034': {
-			userAgent: 'yacybot (i386 Linux 2.6.26-2-686; java 1.6.0_0; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'3132': {
-			userAgent: 'SeznamBot/2.0-Test (+http://fulltext.sblog.cz/robot/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/2.0-test',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'3142': {
-			userAgent: 'SEOENGBot/1.2 (+http://learn.seoeng.com/seoengbot.htm)',
-			metadata: {
-				uaFamily: 'SEOENGBot',
-				uaName: 'SEOENGBot/1.2 old',
-				uaUrl: 'http://www.seoengine.com/seoengbot.htm',
-				uaCompany: 'SEO Engine',
-				uaCompanyUrl: 'http://www.seoengine.com/',
-				uaIcon: 'bot_SEOENGBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SEOENGBot'
-			}
-		},
-		'3203': {
-			userAgent: 'Mozilla/5.0 (compatible; ScoutJet; http://www.scoutjet.com/)',
-			metadata: {
-				uaFamily: 'ScoutJet',
-				uaName: 'ScoutJet',
-				uaUrl: 'http://www.scoutjet.com/',
-				uaCompany: 'blekko, inc.',
-				uaCompanyUrl: 'http://blekko.com/',
-				uaIcon: 'bot_ScoutJet.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ScoutJet'
-			}
-		},
-		'3221': {
-			userAgent: 'yacybot (i386 Linux 2.6.31-18-generic; java 1.6.0_0; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'3235': {
-			userAgent: 'Mozilla/4.0 (compatible; HostTracker.com/1.0;+http://host-tracker.com/)',
-			metadata: {
-				uaFamily: 'HostTracker.com',
-				uaName: 'HostTracker.com/1.0',
-				uaUrl: 'http://host-tracker.com/',
-				uaCompany: 'host-tracker.com ',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_HostTracker.com.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HostTracker.com'
-			}
-		},
-		'3236': {
-			userAgent: 'Mozilla/5.0 (compatible; AportWorm/3.2; +http://www.aport.ru/help)',
-			metadata: {
-				uaFamily: 'AportWorm',
-				uaName: 'AportWorm/3.2',
-				uaUrl: 'http://www.aport.ru/help/',
-				uaCompany: 'Golden Telecom',
-				uaCompanyUrl: 'http://goldentelecom.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AportWorm'
-			}
-		},
-		'3238': {
-			userAgent: 'yacybot (i386 Linux 2.6.30-2-686; java 1.6.0_0; SystemV/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'3292': {
-			userAgent: 'Karneval-Bot (Version: 1.06, powered by www.karnevalsuchmaschine.de +http://www.karnevalsuchmaschine.de/bot.html)',
-			metadata: {
-				uaFamily: 'Karneval-Bot',
-				uaName: 'Karneval-Bot/1.06',
-				uaUrl: 'http://www.karnevalsuchmaschine.de/zeige/bot.html',
-				uaCompany: 'F\xf6deration Europ\xe4ischer Narren',
-				uaCompanyUrl: 'http://www.fen-sued.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Karneval-Bot'
-			}
-		},
-		'3333': {
-			userAgent: 'Mozilla/5.0 (compatible; dotSemantic/1.0; +http://www.dotsemantic.org)',
-			metadata: {
-				uaFamily: 'dotSemantic',
-				uaName: 'dotSemantic/1.0',
-				uaUrl: 'http://www.dotsemantic.org',
-				uaCompany: 'dotSemantic Projekt',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=dotSemantic'
-			}
-		},
-		'3379': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/1.0; +http://www.seoprofiler.com/bot/ )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/1.0',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'3398': {
-			userAgent: 'L.webis/0.44 (http://webalgo.iit.cnr.it/index.php?pg=lwebis)',
-			metadata: {
-				uaFamily: 'L.webis',
-				uaName: 'L.webis/0.44',
-				uaUrl: 'http://webalgo.iit.cnr.it/index.php?pg=lwebis',
-				uaCompany: 'Institute of Informatics and Telematics (IIT)',
-				uaCompanyUrl: 'http://www.iit.cnr.it/',
-				uaIcon: 'bot_L.webis.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=L.webis'
-			}
-		},
-		'3409': {
-			userAgent: 'Cityreview Robot (+http://www.cityreview.org/crawler/)',
-			metadata: {
-				uaFamily: 'cityreview',
-				uaName: 'cityreview',
-				uaUrl: 'http://www.cityreview.org/crawler/',
-				uaCompany: 'SISTRIX GmbH',
-				uaCompanyUrl: 'http://www.sistrix.com/',
-				uaIcon: 'bot_cityreview.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=cityreview'
-			}
-		},
-		'3415': {
-			userAgent: 'Ruky-Roboter (Version: 1.06, powered by www.ruky.de +http://www.ruky.de/bot.html)',
-			metadata: {
-				uaFamily: 'Ruky-Roboter',
-				uaName: 'Ruky-Roboter/1.06',
-				uaUrl: 'http://www.ruky.de/zeige/bot.html',
-				uaCompany: 'ruky.de',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ruky-Roboter'
-			}
-		},
-		'3422': {
-			userAgent: 'Mozilla/5.0 (compatible; abby/1.0; +http://www.ellerdale.com/crawler.html)',
-			metadata: {
-				uaFamily: 'abby',
-				uaName: 'abby/1.0',
-				uaUrl: 'http://www.ellerdale.com/crawler.html',
-				uaCompany: 'Ellerdale Inc.',
-				uaCompanyUrl: 'http://www.ellerdale.com/',
-				uaIcon: 'bot_abby.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=abby'
-			}
-		},
-		'3441': {
-			userAgent: '^Nail (http://CaretNail.com)',
-			metadata: {
-				uaFamily: '^Nail',
-				uaName: '^Nail',
-				uaUrl: 'http://caret.us.com/caretnail/index.html',
-				uaCompany: 'HydraByte, Inc.',
-				uaCompanyUrl: 'http://www.hydrabyte.com/',
-				uaIcon: 'bot_Nail.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=^Nail'
-			}
-		},
-		'3445': {
-			userAgent: 'ichiro/4.0 (http://help.goo.ne.jp/door/crawler.html)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/4.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'3561': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/1.1; +http://www.seoprofiler.com/bot/ )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/1.1',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'3589': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/1.2; +http://www.seoprofiler.com/bot/ )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/1.2',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'3600': {
-			userAgent: 'HolmesBot (http://holmes.ge)',
-			metadata: {
-				uaFamily: 'HolmesBot',
-				uaName: 'HolmesBot',
-				uaUrl: '',
-				uaCompany: 'Georgian Railway Telecom',
-				uaCompanyUrl: 'http://grt.ge/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HolmesBot'
-			}
-		},
-		'3703': {
-			userAgent: 'Mozilla/5.0 (compatible; Falconsbot; +http://ws.nju.edu.cn/falcons/)',
-			metadata: {
-				uaFamily: 'Falconsbot',
-				uaName: 'Falconsbot',
-				uaUrl: 'http://ws.nju.edu.cn/falcons/contact_us.jsp',
-				uaCompany: 'Institute of Web Science',
-				uaCompanyUrl: 'http://iws.seu.edu.cn/page/english/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Falconsbot'
-			}
-		},
-		'3734': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/2.0; +http://www.seoprofiler.com/bot/ )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/2.0',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'4000': {
-			userAgent: 'Mozilla/4.0 (Toread-Crawler/1.1; +http://news.toread.cc/crawler.php)',
-			metadata: {
-				uaFamily: 'Toread-Crawler',
-				uaName: 'Toread-Crawler/1.1',
-				uaUrl: 'http://news.toread.cc/crawler.php',
-				uaCompany: 'sidefeed, Inc',
-				uaCompanyUrl: 'http://sidefeed.com/',
-				uaIcon: 'bot_Toread-Crawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Toread-Crawler'
-			}
-		},
-		'4095': {
-			userAgent: 'msnbot/2.0b (+http://search.msn.com/msnbot.htm).',
-			metadata: {
-				uaFamily: 'MSNBot',
-				uaName: 'MSNBot/2.0b + .',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSNBot'
-			}
-		},
-		'4097': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/2.0.1; +http://www.seoprofiler.com/bot/ )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/2.0.1',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'4185': {
-			userAgent: 'Mozilla/5.0 (compatible; Speedy Spider; http://www.entireweb.com/about/search_tech/speedy_spider/)',
-			metadata: {
-				uaFamily: 'Speedy',
-				uaName: 'Speedy Spider',
-				uaUrl: '',
-				uaCompany: 'Entireweb Sweden AB',
-				uaCompanyUrl: 'http://www.entireweb.com/',
-				uaIcon: 'bot_Speedy.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Speedy'
-			}
-		},
-		'4264': {
-			userAgent: 'L.webis/0.50 (http://webalgo.iit.cnr.it/index.php?pg=lwebis)',
-			metadata: {
-				uaFamily: 'L.webis',
-				uaName: 'L.webis/0.50',
-				uaUrl: 'http://webalgo.iit.cnr.it/index.php?pg=lwebis',
-				uaCompany: 'Institute of Informatics and Telematics (IIT)',
-				uaCompanyUrl: 'http://www.iit.cnr.it/',
-				uaIcon: 'bot_L.webis.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=L.webis'
-			}
-		},
-		'4336': {
-			userAgent: 'Nuhk/2.4 ( http://www.neti.ee/cgi-bin/abi/Otsing/Nuhk/)',
-			metadata: {
-				uaFamily: 'Nuhk',
-				uaName: 'Nuhk/2.4',
-				uaUrl: 'http://www.neti.ee/cgi-bin/abi/Otsing/Nuhk/',
-				uaCompany: 'Elion',
-				uaCompanyUrl: 'http://www.neti.ee/',
-				uaIcon: 'bot_Nuhk.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nuhk'
-			}
-		},
-		'4337': {
-			userAgent: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)',
-			metadata: {
-				uaFamily: 'Speedy',
-				uaName: 'Speedy Spider',
-				uaUrl: '',
-				uaCompany: 'Entireweb Sweden AB',
-				uaCompanyUrl: 'http://www.entireweb.com/',
-				uaIcon: 'bot_Speedy.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Speedy'
-			}
-		},
-		'4377': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/2.0.2; +http://www.seoprofiler.com/bot/ )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/2.0.2',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'4411': {
-			userAgent: 'msnbot/2.0b (+http://search.msn.com/msnbot.htm)._',
-			metadata: {
-				uaFamily: 'MSNBot',
-				uaName: 'MSNBot/2.0b + ._',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSNBot'
-			}
-		},
-		'4423': {
-			userAgent: 'yacybot (amd64 Linux 2.6.28-18-generic; java 1.6.0_16; GMT/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'4437': {
-			userAgent: 'SeznamBot/3.0-alpha (+http://fulltext.sblog.cz/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.0-alpha',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'4501': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1 + FairShare-http://fairshare.cc)',
-			metadata: {
-				uaFamily: 'FairShare',
-				uaName: 'FairShare',
-				uaUrl: 'http://support.attributor.com/kbfairshare/doku.php',
-				uaCompany: 'Attributor Corporation',
-				uaCompanyUrl: 'http://www.attributor.com/',
-				uaIcon: 'bot_FairShare.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FairShare'
-			}
-		},
-		'4512': {
-			userAgent: 'Mozilla/5.0 (compatible; Search17Bot/1.1; http://www.search17.com/bot.php)',
-			metadata: {
-				uaFamily: 'Search17Bot',
-				uaName: 'Search17Bot/1.1',
-				uaUrl: 'http://www.search17.com/bot.php',
-				uaCompany: 'search17.com',
-				uaCompanyUrl: 'http://www.search17.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Search17Bot'
-			}
-		},
-		'4519': {
-			userAgent: 'Mozilla/5.0 (compatible; BlinkaCrawler/1.0; +http://www.blinka.jp/crawler/)',
-			metadata: {
-				uaFamily: 'BlinkaCrawler',
-				uaName: 'BlinkaCrawler/1.0',
-				uaUrl: 'http://www.blinka.jp/crawler/',
-				uaCompany: 'Blinka project',
-				uaCompanyUrl: 'http://www.blinka.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BlinkaCrawler'
-			}
-		},
-		'4546': {
-			userAgent: 'Web-sniffer/1.0.31 (+http://web-sniffer.net/)',
-			metadata: {
-				uaFamily: 'Web-sniffer',
-				uaName: 'Web-sniffer/1.0.31',
-				uaUrl: '',
-				uaCompany: 'Lingo4you GbR',
-				uaCompanyUrl: 'http://www.lingo4u.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Web-sniffer'
-			}
-		},
-		'4589': {
-			userAgent: 'MetaURI API +metauri.com',
-			metadata: {
-				uaFamily: 'MetaURI',
-				uaName: 'MetaURI',
-				uaUrl: 'http://metauri.com/static/about',
-				uaCompany: 'Stateless Systems',
-				uaCompanyUrl: 'http://statelesssystems.com/',
-				uaIcon: 'bot_MetaURI.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetaURI'
-			}
-		},
-		'4590': {
-			userAgent: 'L.webis/0.51 (http://webalgo.iit.cnr.it/index.php?pg=lwebis)',
-			metadata: {
-				uaFamily: 'L.webis',
-				uaName: 'L.webis/0.51',
-				uaUrl: 'http://webalgo.iit.cnr.it/index.php?pg=lwebis',
-				uaCompany: 'Institute of Informatics and Telematics (IIT)',
-				uaCompanyUrl: 'http://www.iit.cnr.it/',
-				uaIcon: 'bot_L.webis.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=L.webis'
-			}
-		},
-		'4591': {
-			userAgent: 'L.webis/0.53 (http://webalgo.iit.cnr.it/index.php?pg=lwebis)',
-			metadata: {
-				uaFamily: 'L.webis',
-				uaName: 'L.webis/0.53',
-				uaUrl: 'http://webalgo.iit.cnr.it/index.php?pg=lwebis',
-				uaCompany: 'Institute of Informatics and Telematics (IIT)',
-				uaCompanyUrl: 'http://www.iit.cnr.it/',
-				uaIcon: 'bot_L.webis.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=L.webis'
-			}
-		},
-		'4722': {
-			userAgent: 'Mozilla/5.0 (FauBot/0.1; +http://buzzvolume.com/fau/)',
-			metadata: {
-				uaFamily: 'FauBot',
-				uaName: 'FauBot/0.1',
-				uaUrl: 'http://buzzvolume.com/fau',
-				uaCompany: 'BuzzVolume',
-				uaCompanyUrl: 'http://buzzvolume.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FauBot'
-			}
-		},
-		'4726': {
-			userAgent: 'Googlebot-Video/1.0',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot-Video/1.0',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1061943',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'4730': {
-			userAgent: 'Eurobot/1.2 (http://eurobot.ayell.eu)',
-			metadata: {
-				uaFamily: 'Eurobot',
-				uaName: 'Eurobot/1.2',
-				uaUrl: 'http://eurobot.ayell.eu/',
-				uaCompany: 'Ayell Euronet',
-				uaCompanyUrl: 'http://www.ayell.eu/',
-				uaIcon: 'bot_eurobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Eurobot'
-			}
-		},
-		'4733': {
-			userAgent: 'Mozilla/5.0 (compatible; bixolabs/1.0; +http://bixolabs.com/crawler/general; crawler@bixolabs.com)',
-			metadata: {
-				uaFamily: 'bixocrawler',
-				uaName: 'bixolabs/1.0',
-				uaUrl: 'http://wiki.github.com/bixo/bixo/bixocrawler',
-				uaCompany: 'Bixo Labs',
-				uaCompanyUrl: 'http://openbixo.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bixocrawler'
-			}
-		},
-		'4747': {
-			userAgent: 'yacybot (x86 Windows XP 5.1; java 1.6.0_18; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'4830': {
-			userAgent: 'yacybot (i386 Linux 2.6.31-21-generic; java 1.6.0_0; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'4844': {
-			userAgent: 'livedoor ScreenShot/0.10',
-			metadata: {
-				uaFamily: 'livedoor ScreenShot',
-				uaName: 'livedoor ScreenShot/0.10',
-				uaUrl: 'http://helpguide.livedoor.com/help/screenshot/qa/grp584?id=3042',
-				uaCompany: 'livedoor Co.,Ltd.',
-				uaCompanyUrl: 'http://corp.livedoor.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=livedoor ScreenShot'
-			}
-		},
-		'4846': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.3.3; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.3.3',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'4853': {
-			userAgent: 'findlinks/1.1.6-beta1 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.6-beta1',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'4866': {
-			userAgent: 'nodestackbot/0.1 (bot@nodestack.com http://nodestack.com/bot.html)',
-			metadata: {
-				uaFamily: 'nodestackbot',
-				uaName: 'nodestackbot/0.1',
-				uaUrl: 'http://nodestack.com/bot.html',
-				uaCompany: 'nodestack.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=nodestackbot'
-			}
-		},
-		'4876': {
-			userAgent: 'Mozilla/5.0 (compatible; Plukkie/1.3; http://www.botje.com/plukkie.htm)',
-			metadata: {
-				uaFamily: 'Plukkie',
-				uaName: 'Plukkie/1.3',
-				uaUrl: 'http://www.botje.com/plukkie.htm',
-				uaCompany: 'botje.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Plukkie'
-			}
-		},
-		'4888': {
-			userAgent: 'Mozilla/5.0 ( compatible; SETOOZBOT/0.30 ; http://www.setooz.com/bot.html )',
-			metadata: {
-				uaFamily: 'Setoozbot',
-				uaName: 'SETOOZBOT/0.30 a',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot'
-			}
-		},
-		'4898': {
-			userAgent: 'Yaanb/1.5.001 (compatible; Win64;)',
-			metadata: {
-				uaFamily: 'Yaanb',
-				uaName: 'Yaanb/1.5.001',
-				uaUrl: 'http://www.yaanb.com/company/?p=bot',
-				uaCompany: 'Yaanb',
-				uaCompanyUrl: 'http://www.yaanb.com/company/',
-				uaIcon: 'bot_Yaanb.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yaanb'
-			}
-		},
-		'4907': {
-			userAgent: 'Mozilla/5.0 ( compatible; SETOOZBOT/0.30 ; http://www.setooz.com/bot.html ; agentname at setooz dot_com )',
-			metadata: {
-				uaFamily: 'Setoozbot',
-				uaName: 'SETOOZBOT/0.30 b',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot'
-			}
-		},
-		'4911': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/2.0.3; +http://www.seoprofiler.com/bot/ )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/2.0.3',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'4914': {
-			userAgent: 'Yaanb/1.5.001 (compatible; Win64;+http://www.yaanb.com/company/bot.hmtl)',
-			metadata: {
-				uaFamily: 'Yaanb',
-				uaName: 'Yaanb/1.5.001 b',
-				uaUrl: 'http://www.yaanb.com/company/?p=bot',
-				uaCompany: 'Yaanb',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_Yaanb.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yaanb'
-			}
-		},
-		'4922': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/2.0.4; +http://www.seoprofiler.com/bot )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/2.0.4',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'4936': {
-			userAgent: 'R6_CommentReader(www.radian6.com/crawler)',
-			metadata: {
-				uaFamily: 'R6 bot',
-				uaName: 'R6_CommentReader',
-				uaUrl: 'http://www.radian6.com/crawler/',
-				uaCompany: 'Radian6 Technologies Inc',
-				uaCompanyUrl: 'http://www.radian6.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=R6 bot'
-			}
-		},
-		'4939': {
-			userAgent: 'CamontSpider/1.0 +http://epweb2.ph.bham.ac.uk/user/slater/camont/info.html',
-			metadata: {
-				uaFamily: 'CamontSpider',
-				uaName: 'CamontSpider/1.0',
-				uaUrl: 'http://epweb2.ph.bham.ac.uk/user/slater/camont/info.html',
-				uaCompany: 'Camtology consortium',
-				uaCompanyUrl: 'http://www.hep.phy.cam.ac.uk/~parker/camtology/about.html',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CamontSpider'
-			}
-		},
-		'4940': {
-			userAgent: 'Pompos/1.3 http://dir.com/pompos.html',
-			metadata: {
-				uaFamily: 'Pompos',
-				uaName: 'Pompos/1.3',
-				uaUrl: 'http://dir.com/pompos.html',
-				uaCompany: 'Iliad',
-				uaCompanyUrl: 'http://www.iliad.fr/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Pompos'
-			}
-		},
-		'4946': {
-			userAgent: 'FyberSpider/1.3 (http://www.fybersearch.com/fyberspider.php)',
-			metadata: {
-				uaFamily: 'FyberSpider',
-				uaName: 'FyberSpider/1.3',
-				uaUrl: 'http://www.fybersearch.com/fyberspider.php',
-				uaCompany: 'FyberSearch',
-				uaCompanyUrl: 'http://www.fybersearch.com/',
-				uaIcon: 'bot_FyberSpider.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FyberSpider'
-			}
-		},
-		'4966': {
-			userAgent: 'Googlebot/2.1 (+http://www.google.com/bot.html)',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot/2.1',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1061943',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'4974': {
-			userAgent: 'yacybot (amd64 Linux 2.6.26-2-amd64; java 1.6.0_0; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'4975': {
-			userAgent: 'yacybot (i386 Linux 2.6.32-22-generic; java 1.6.0_20; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'4977': {
-			userAgent: 'CatchBot/2.0; +http://www.catchbot.com',
-			metadata: {
-				uaFamily: 'CatchBot',
-				uaName: 'CatchBot/2.0',
-				uaUrl: 'http://www.catchbot.com/',
-				uaCompany: 'Reed Business Information Pty Limited',
-				uaCompanyUrl: 'http://www.reedbusiness.com/',
-				uaIcon: 'bot_CatchBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CatchBot'
-			}
-		},
-		'4996': {
-			userAgent: 'magpie-crawler/1.1 (U; Linux amd64; en-GB; +http://www.brandwatch.net)',
-			metadata: {
-				uaFamily: 'magpie-crawler',
-				uaName: 'magpie-crawler/1.1',
-				uaUrl: 'http://www.brandwatch.com/how-it-works/gathering-data/',
-				uaCompany: 'Brandwatch',
-				uaCompanyUrl: 'http://www.brandwatch.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=magpie-crawler'
-			}
-		},
-		'4999': {
-			userAgent: 'Mozilla/5.0 (compatible; XML Sitemaps Generator; http://www.xml-sitemaps.com) Gecko XML-Sitemaps/1.0',
-			metadata: {
-				uaFamily: 'XML Sitemaps Generator',
-				uaName: 'XML Sitemaps Generator/1.0',
-				uaUrl: 'http://www.xml-sitemaps.com/',
-				uaCompany: 'xml-sitemaps.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=XML Sitemaps Generator'
-			}
-		},
-		'5003': {
-			userAgent: 'Mozilla/5.0 (compatible; Nigma.ru/3.0; crawler@nigma.ru)',
-			metadata: {
-				uaFamily: 'Nigma.ru',
-				uaName: 'Nigma.ru/3.0',
-				uaUrl: '',
-				uaCompany: 'Nigma.ru',
-				uaCompanyUrl: 'http://nigma.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nigma.ru'
-			}
-		},
-		'5006': {
-			userAgent: 'TwengaBot-Discover (http://www.twenga.fr/bot-discover.html)',
-			metadata: {
-				uaFamily: 'TwengaBot',
-				uaName: 'TwengaBot-Discover',
-				uaUrl: 'http://www.twenga.com/bot.html',
-				uaCompany: 'Twenga SA',
-				uaCompanyUrl: 'http://www.twenga.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TwengaBot'
-			}
-		},
-		'5007': {
-			userAgent: 'Zookabot/2.0;++http://zookabot.com',
-			metadata: {
-				uaFamily: 'Zookabot',
-				uaName: 'Zookabot/2.0',
-				uaUrl: 'http://zookabot.com/',
-				uaCompany: 'Hwacha ApS',
-				uaCompanyUrl: 'http://hwacha.dk/',
-				uaIcon: 'bot_Zookabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Zookabot'
-			}
-		},
-		'5010': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexBot/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'5014': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexImages/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'5016': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexBot/3.0; MirrorDetector; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexBot/3.0-MirrorDetector',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'5052': {
-			userAgent: 'findlinks/1.1.6-beta2 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.6-beta2',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5056': {
-			userAgent: 'netEstate RSS crawler (+http://www.rss-directory.info/)',
-			metadata: {
-				uaFamily: 'netEstate Crawler',
-				uaName: 'netEstate RSS crawler',
-				uaUrl: '',
-				uaCompany: 'netEstate GmbH',
-				uaCompanyUrl: 'http://www.netestate.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=netEstate Crawler'
-			}
-		},
-		'5057': {
-			userAgent: 'Mozilla/5.0 (compatible; Qualidator.com Bot 1.0;)',
-			metadata: {
-				uaFamily: 'Qualidator.com Bot',
-				uaName: 'Qualidator.com Bot 1.0',
-				uaUrl: 'http://www.qualidator.com/Web/de/Support/FAQ_OnlineTestStatistiken.htm',
-				uaCompany: 'seven49.net GmbH',
-				uaCompanyUrl: 'http://www.seven49.net/',
-				uaIcon: 'bot_Qualidator.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Qualidator.com Bot'
-			}
-		},
-		'5065': {
-			userAgent: 'Mozilla/5.0 (compatible; VideoSurf_bot +http://www.videosurf.com/bot.html)',
-			metadata: {
-				uaFamily: 'VideoSurf_bot',
-				uaName: 'VideoSurf_bot',
-				uaUrl: 'http://www.videosurf.com/bot.html',
-				uaCompany: 'VideoSurf Inc.',
-				uaCompanyUrl: 'http://www.videosurf.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=VideoSurf_bot'
-			}
-		},
-		'5066': {
-			userAgent: 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.19; aggregator:Spinn3r (Spinn3r 3.1); http://spinn3r.com/robot) Gecko/2010040121 Firefox/3.0.19',
-			metadata: {
-				uaFamily: 'Spinn3r',
-				uaName: 'Spinn3r 3.1',
-				uaUrl: 'http://spinn3r.com/robot',
-				uaCompany: 'Tailrank Inc',
-				uaCompanyUrl: 'http://tailrank.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Spinn3r'
-			}
-		},
-		'5077': {
-			userAgent: 'Mozilla/5.0 (compatible; AboutUsBot Johnny5/2.0; +http://www.AboutUs.org/)',
-			metadata: {
-				uaFamily: 'AboutUsBot',
-				uaName: 'AboutUsBot Johnny5/2.0',
-				uaUrl: 'http://www.aboutus.org/AboutUs:Bot',
-				uaCompany: 'AboutUs, Inc.',
-				uaCompanyUrl: 'http://www.aboutus.org/AboutUs.org',
-				uaIcon: 'bot_AboutUsBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AboutUsBot'
-			}
-		},
-		'5090': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexWebmaster/2.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexWebmaster/2.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'5092': {
-			userAgent: 'nrsbot/6.0(loopip.com/robot.html)',
-			metadata: {
-				uaFamily: 'NetResearchServer',
-				uaName: 'nrsbot/6.0',
-				uaUrl: 'http://loopip.com/robot.html',
-				uaCompany: 'LoopIP LLC',
-				uaCompanyUrl: 'http://loopip.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NetResearchServer'
-			}
-		},
-		'5100': {
-			userAgent: 'Mozilla/5.0 (compatible; Butterfly/1.0; +http://labs.topsy.com/butterfly/) Gecko/2009032608 Firefox/3.0.8',
-			metadata: {
-				uaFamily: 'Butterfly',
-				uaName: 'Butterfly/1.0 a',
-				uaUrl: 'http://labs.topsy.com/butterfly.html',
-				uaCompany: 'Topsy Labs',
-				uaCompanyUrl: 'http://labs.topsy.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Butterfly'
-			}
-		},
-		'5145': {
-			userAgent: 'StatoolsBot (+http://www.statools.com/bot.html)',
-			metadata: {
-				uaFamily: 'StatoolsBot',
-				uaName: 'StatoolsBot',
-				uaUrl: 'http://www.statools.com/bot.html',
-				uaCompany: 'StaTools.com',
-				uaCompanyUrl: 'http://www.statools.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=StatoolsBot'
-			}
-		},
-		'5165': {
-			userAgent: 'Mozilla/5.0 (compatible; Hailoobot/1.2; +http://www.hailoo.com/spider.html)',
-			metadata: {
-				uaFamily: 'Hailoobot',
-				uaName: 'Hailoobot/1.2',
-				uaUrl: 'http://www.hailoo.com/spider.html',
-				uaCompany: 'Hailoo',
-				uaCompanyUrl: 'http://www.hailoo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Hailoobot'
-			}
-		},
-		'5176': {
-			userAgent: 'yacybot (amd64 Linux 2.6.26-2-amd64; java 1.6.0_20; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'5180': {
-			userAgent: 'Lijit Crawler (+http://www.lijit.com/robot/crawler)',
-			metadata: {
-				uaFamily: 'Lijit',
-				uaName: 'Lijit',
-				uaUrl: 'http://www.lijit.com/robot/crawler',
-				uaCompany: 'Lijit Networks Inc.',
-				uaCompanyUrl: 'http://www.lijit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Lijit'
-			}
-		},
-		'5183': {
-			userAgent: 'WMCAI-robot (http://www.topicmaster.jp/wmcai/crawler.html)',
-			metadata: {
-				uaFamily: 'WMCAI_robot',
-				uaName: 'WMCAI_robot',
-				uaUrl: 'http://www.topicmaster.jp/wmcai/crawler.html',
-				uaCompany: 'NTT Corporation',
-				uaCompanyUrl: 'http://www.ntt.co.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WMCAI_robot'
-			}
-		},
-		'5187': {
-			userAgent: 'eCairn-Grabber/1.0 (+http://ecairn.com/grabber) curl/7.15',
-			metadata: {
-				uaFamily: 'eCairn-Grabber',
-				uaName: 'eCairn-Grabber/1.0',
-				uaUrl: 'http://ecairn.com/grabber',
-				uaCompany: 'eCairn Inc.',
-				uaCompanyUrl: 'http://ecairn.com/',
-				uaIcon: 'bot_eCairn-Grabber.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=eCairn-Grabber'
-			}
-		},
-		'5188': {
-			userAgent: 'Stroke.cz (http://stroke.cz)',
-			metadata: {
-				uaFamily: 'Strokebot',
-				uaName: 'Strokebot',
-				uaUrl: 'http://stroke.cz/oou/',
-				uaCompany: 'care4u, s. r. o.',
-				uaCompanyUrl: 'http://care4u.cz/',
-				uaIcon: 'bot_strokebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Strokebot'
-			}
-		},
-		'5202': {
-			userAgent: 'JUST-CRAWLER(+http://www.justsystems.com/jp/tech/crawler/)',
-			metadata: {
-				uaFamily: 'JUST-CRAWLER',
-				uaName: 'JUST-CRAWLER',
-				uaUrl: 'http://www.justsystems.com/jp/tech/crawler/',
-				uaCompany: 'JustSystems Corporation',
-				uaCompanyUrl: 'http://www.justsystems.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=JUST-CRAWLER'
-			}
-		},
-		'5216': {
-			userAgent: 'yacybot (x86 Windows 2003 5.2; java 1.6.0_20; America/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'5218': {
-			userAgent: 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; DomainDB-1.1; http://domaindb.com/crawler/)',
-			metadata: {
-				uaFamily: 'DomainDB',
-				uaName: 'DomainDB/1.1',
-				uaUrl: 'http://domaindb.com/crawler/',
-				uaCompany: 'Triop AB',
-				uaCompanyUrl: 'http://triop.se/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DomainDB'
-			}
-		},
-		'5228': {
-			userAgent: 'Ocelli/1.4 (http://www.globalspec.com/Ocelli)',
-			metadata: {
-				uaFamily: 'Ocelli',
-				uaName: 'Ocelli/1.4',
-				uaUrl: 'http://www.globalspec.com/Ocelli',
-				uaCompany: 'GlobalSpec, Inc.',
-				uaCompanyUrl: 'http://www.globalspec.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ocelli'
-			}
-		},
-		'5231': {
-			userAgent: 'Mozilla/5.0 (compatible; SSLBot/1.0;  http://www.sslstats.com/sslbot)',
-			metadata: {
-				uaFamily: 'SSLBot',
-				uaName: 'SSLBot/1.0',
-				uaUrl: 'http://www.sslstats.com/sslbot/',
-				uaCompany: 'sslstats.com',
-				uaCompanyUrl: 'http://www.sslstats.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SSLBot'
-			}
-		},
-		'5238': {
-			userAgent: 'Mozilla/5.0 (compatible; bixolabs/1.0; +http://bixolabs.com/crawler/general; crawler@mail.bixolabs.com)',
-			metadata: {
-				uaFamily: 'bixocrawler',
-				uaName: 'bixolabs/1.0',
-				uaUrl: 'http://wiki.github.com/bixo/bixo/bixocrawler',
-				uaCompany: 'Bixo Labs',
-				uaCompanyUrl: 'http://openbixo.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bixocrawler'
-			}
-		},
-		'5243': {
-			userAgent: 'findlinks/1.1.6-beta1 (+http://wortschatz.uni-leipzig.de/findlinks/; YaCy 0.1; yacy.net)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.6-beta1 Yacy',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5249': {
-			userAgent: 'yacybot (x86 Windows XP 5.1; java 1.6.0_21; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'5272': {
-			userAgent: 'Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)',
-			metadata: {
-				uaFamily: 'archive.org_bot',
-				uaName: 'archive.org_bot',
-				uaUrl: 'http://www.archive.org/details/archive.org_bot',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=archive.org_bot'
-			}
-		},
-		'5275': {
-			userAgent: 'Mozilla/4.0 (compatible;  Vagabondo/4.0; http://webagent.wise-guys.nl/)',
-			metadata: {
-				uaFamily: 'Vagabondo',
-				uaName: 'Vagabondo/4.0',
-				uaUrl: 'http://webagent.wise-guys.nl/',
-				uaCompany: 'WiseGuys Internet BV',
-				uaCompanyUrl: 'http://www.wise-guys.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Vagabondo'
-			}
-		},
-		'5276': {
-			userAgent: 'yacybot (amd64 Linux 2.6.18-164.15.1.el5xen; java 1.6.0_0; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'5277': {
-			userAgent: 'findlinks/1.1.6-beta3 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.6-beta3',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5278': {
-			userAgent: 'yacybot (amd64 Windows 7 6.1; java 1.6.0_18; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'5280': {
-			userAgent: 'Mozilla/5.0 (compatible; MetamojiCrawler/1.0; +http://www.metamoji.com/jp/crawler.html',
-			metadata: {
-				uaFamily: 'MetamojiCrawler',
-				uaName: 'MetamojiCrawler/1.0',
-				uaUrl: 'http://www.metamoji.com/jp/crawler.html',
-				uaCompany: 'MetaMoJi Corporation',
-				uaCompanyUrl: 'http://www.metamoji.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetamojiCrawler'
-			}
-		},
-		'5281': {
-			userAgent: 'yacybot (amd64 Windows 7 6.1; java 1.6.0_21; Europe/fr) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'5292': {
-			userAgent: 'findlinks/1.1.6-beta4 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.6-beta4',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5302': {
-			userAgent: 'HuaweiSymantecSpider/1.0+DSE-support@huaweisymantec.com+(compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR ; http://www.huaweisymantec.com/en/IRL/spider)',
-			metadata: {
-				uaFamily: 'HuaweiSymantecSpider',
-				uaName: 'HuaweiSymantecSpider/1.0',
-				uaUrl: 'http://www.huaweisymantec.com/en/IRL/spider/',
-				uaCompany: 'Huawei Symantec Technologies Co.,Ltd.',
-				uaCompanyUrl: 'http://www.huaweisymantec.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HuaweiSymantecSpider'
-			}
-		},
-		'5311': {
-			userAgent: 'Mozilla/5.0 (compatible; 008/0.83; http://www.80legs.com/webcrawler.html;) Gecko/2008032620',
-			metadata: {
-				uaFamily: '80legs',
-				uaName: '80legs/0.83 b',
-				uaUrl: 'http://www.80legs.com/webcrawler.html',
-				uaCompany: 'Computational Crawling, LP',
-				uaCompanyUrl: 'http://compucrawl.com/',
-				uaIcon: 'bot_80legs.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=80legs'
-			}
-		},
-		'5322': {
-			userAgent: 'yacybot (amd64 Linux 2.6.31-22-server; java 1.6.0_18; Asia/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'5352': {
-			userAgent: 'findlinks/1.1.6-beta5 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.6-beta5',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5357': {
-			userAgent: 'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
-			metadata: {
-				uaFamily: 'bingbot',
-				uaName: 'bingbot/2.0',
-				uaUrl: 'http://www.bing.com/webmaster/help/which-crawlers-does-bing-use-8c184ec0',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bingbot'
-			}
-		},
-		'5360': {
-			userAgent: 'PostPost/1.0 (+http://postpo.st/crawlers)',
-			metadata: {
-				uaFamily: 'PostPost',
-				uaName: 'PostPost/1.0',
-				uaUrl: 'http://postpost.com/crawlers',
-				uaCompany: 'Boathouse group',
-				uaCompanyUrl: 'http://www.boathouseinc.com/',
-				uaIcon: 'bot_PostPost.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PostPost'
-			}
-		},
-		'5361': {
-			userAgent: 'WebWatch/Robot_txtChecker',
-			metadata: {
-				uaFamily: 'WebWatch/Robot_txtChecker',
-				uaName: 'WebWatch/Robot_txtChecker',
-				uaUrl: 'http://www.ukoln.ac.uk/web-focus/webwatch/services/robots-txt/',
-				uaCompany: 'UKOLN',
-				uaCompanyUrl: 'http://www.ukoln.ac.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebWatch/Robot_txtChecker'
-			}
-		},
-		'5362': {
-			userAgent: 'Robots_Tester_http_www.searchenginepromotionhelp.com',
-			metadata: {
-				uaFamily: 'Robots_Tester',
-				uaName: 'Robots_Tester',
-				uaUrl: 'http://www.searchenginepromotionhelp.com/m/robots-text-tester/robots-checker.php',
-				uaCompany: 'Search Engine Promotion Help',
-				uaCompanyUrl: 'http://www.searchenginepromotionhelp.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Robots_Tester'
-			}
-		},
-		'5376': {
-			userAgent: 'Mozilla/5.0 (compatible; Peew/1.0; http://www.peew.de/crawler/)',
-			metadata: {
-				uaFamily: 'Peew',
-				uaName: 'Peew/1.0',
-				uaUrl: 'http://www.peew.de/crawler/',
-				uaCompany: 'Marco Schmidt',
-				uaCompanyUrl: 'http://www.peew.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Peew'
-			}
-		},
-		'5380': {
-			userAgent: 'gonzo/1[P] (+http://www.suchen.de/faq.html)',
-			metadata: {
-				uaFamily: 'gonzo',
-				uaName: 'gonzo/1',
-				uaUrl: 'http://www.suchen.de/faq.html',
-				uaCompany: 'SEARCHTEQ',
-				uaCompanyUrl: 'http://www.searchteq.de/',
-				uaIcon: 'bot_gonzo.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=gonzo'
-			}
-		},
-		'5386': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/2.1; +http://www.seoprofiler.com/bot )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/2.1',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'5389': {
-			userAgent: 'WikioFeedBot 1.0 (http://www.wikio.com)',
-			metadata: {
-				uaFamily: 'WikioFeedBot',
-				uaName: 'WikioFeedBot 1.0',
-				uaUrl: '',
-				uaCompany: 'Wikio',
-				uaCompanyUrl: 'http://www.wikio.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WikioFeedBot'
-			}
-		},
-		'5611': {
-			userAgent: 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)',
-			metadata: {
-				uaFamily: 'FacebookExternalHit',
-				uaName: 'FacebookExternalHit/1.1',
-				uaUrl: 'http://www.facebook.com/externalhit_uatext.php',
-				uaCompany: 'Facebook',
-				uaCompanyUrl: 'http://www.facebook.com/',
-				uaIcon: 'bot_facebook.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FacebookExternalHit'
-			}
-		},
-		'5620': {
-			userAgent: 'Qirina Hurdler v. 1.05 10.11.01 (+http://www.qirina.com/hurdler.html)',
-			metadata: {
-				uaFamily: 'Qirina Hurdler',
-				uaName: 'Qirina Hurdler v. 1.05 10.11.01',
-				uaUrl: 'http://www.qirina.com/hurdler.html',
-				uaCompany: 'Locust Swarm',
-				uaCompanyUrl: 'http://www.locustswarm.com/',
-				uaIcon: 'bot_QirinaHurdler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Qirina Hurdler'
-			}
-		},
-		'5623': {
-			userAgent: 'Mozilla/5.0 (compatible; AntBot/1.0; +http://www.ant.com/)',
-			metadata: {
-				uaFamily: 'AntBot',
-				uaName: 'AntBot/1.0',
-				uaUrl: '',
-				uaCompany: 'Ant.com',
-				uaCompanyUrl: 'http://www.ant.com/',
-				uaIcon: 'bot_AntBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AntBot'
-			}
-		},
-		'5635': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; d2.watchmouse.com)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 d2.watchmouse.com',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5636': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; liz)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 liz',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5637': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; d3.watchmouse.com)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 d3.watchmouse.com',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5638': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; gab)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 gab',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5639': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; ny)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 ny',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5640': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; se.watchmouse.com)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 se.watchmouse.com',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5641': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; it)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 it',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5642': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; hk)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 hk',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5643': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; bc.watchmouse.com)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 bc',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5644': {
-			userAgent: 'WatchMouse/18990 (http://watchmouse.com/ ; uk)',
-			metadata: {
-				uaFamily: 'WatchMouse',
-				uaName: 'WatchMouse/18990 uk',
-				uaUrl: 'http://www.watchmouse.com/',
-				uaCompany: 'WatchMouse',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_WatchMouse.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WatchMouse'
-			}
-		},
-		'5646': {
-			userAgent: 'findlinks/2.0 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.0',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5655': {
-			userAgent: 'Zookabot/2.1;++http://zookabot.com',
-			metadata: {
-				uaFamily: 'ZookaBot',
-				uaName: 'ZookaBot/2.1',
-				uaUrl: 'http://zookabot.com/',
-				uaCompany: 'Hwacha ApS',
-				uaCompanyUrl: 'http://hwacha.dk/',
-				uaIcon: 'bot_Zookabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZookaBot'
-			}
-		},
-		'5665': {
-			userAgent: 'CatchBot/3.0; +http://www.catchbot.com',
-			metadata: {
-				uaFamily: 'CatchBot',
-				uaName: 'CatchBot/3.0',
-				uaUrl: 'http://www.catchbot.com/',
-				uaCompany: 'Reed Business Information Pty Limited',
-				uaCompanyUrl: 'http://www.reedbusiness.com/',
-				uaIcon: 'bot_CatchBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CatchBot'
-			}
-		},
-		'5683': {
-			userAgent: 'Mozilla/5.0 (compatible; MojeekBot/0.2; http://www.mojeek.com/bot.html#relaunch)',
-			metadata: {
-				uaFamily: 'MojeekBot',
-				uaName: 'MojeekBot/0.2 Relaunch',
-				uaUrl: 'http://www.mojeek.com/bot.html',
-				uaCompany: 'Mojeek Ltd.',
-				uaCompanyUrl: 'http://www.mojeek.com/',
-				uaIcon: 'bot_MojeekBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MojeekBot'
-			}
-		},
-		'5685': {
-			userAgent: 'findlinks/1.1.6-beta6 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.6-beta6',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5701': {
-			userAgent: 'WebAlta Crawler/1.3.25 (http://www.webalta.net/ru/about_webmaster.html) (Windows; U; Windows NT 5.1; ru-RU)',
-			metadata: {
-				uaFamily: 'WebAlta Crawler',
-				uaName: 'WebAlta Crawler/1.3.25',
-				uaUrl: 'http://www.webalta.net/ru/about_webmaster.html',
-				uaCompany: 'Webalta',
-				uaCompanyUrl: 'http://www.webalta.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebAlta Crawler'
-			}
-		},
-		'5710': {
-			userAgent: 'wikiwix-bot-3.0',
-			metadata: {
-				uaFamily: 'wikiwix-bot',
-				uaName: 'wikiwix-bot/3.0',
-				uaUrl: '',
-				uaCompany: 'wikiwix.com',
-				uaCompanyUrl: 'http://www.wikiwix.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=wikiwix-bot'
-			}
-		},
-		'5715': {
-			userAgent: 'findlinks/2.0.1 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.0.1',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5718': {
-			userAgent: 'yrspider (Mozilla/5.0 (compatible; YRSpider; +http://www.yunrang.com/yrspider.html))',
-			metadata: {
-				uaFamily: 'YRSpider',
-				uaName: 'YRSpider',
-				uaUrl: 'http://www.yunrang.com/yrspider.html',
-				uaCompany: 'yunrang',
-				uaCompanyUrl: 'http://www.yunrang.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YRSpider'
-			}
-		},
-		'5727': {
-			userAgent: 'Mozilla/5.0 (compatible; Urlfilebot/2.2; +http://urlfile.com/bot.html)',
-			metadata: {
-				uaFamily: 'Urlfilebot (Urlbot)',
-				uaName: 'Urlfilebot/2.2',
-				uaUrl: 'http://urlfile.com/bot.html',
-				uaCompany: 'Urlfile',
-				uaCompanyUrl: 'http://urlfile.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Urlfilebot (Urlbot)'
-			}
-		},
-		'5748': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/3.0; +http://www.seoprofiler.com/bot )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/3.0',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'5802': {
-			userAgent: 'Mozilla/5.0 (compatible; suggybot v0.01a, http://blog.suggy.com/was-ist-suggy/suggy-webcrawler/)',
-			metadata: {
-				uaFamily: 'suggybot',
-				uaName: 'suggybot/0.01a',
-				uaUrl: 'http://blog.suggy.com/was-ist-suggy/suggy-webcrawler/',
-				uaCompany: 'Suggy GbR',
-				uaCompanyUrl: 'http://www.suggy.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=suggybot'
-			}
-		},
-		'5806': {
-			userAgent: 'EuripBot/1.1 (+http://www.eurip.com) GetRobots',
-			metadata: {
-				uaFamily: 'EuripBot',
-				uaName: 'EuripBot/1.1',
-				uaUrl: 'http://www.eurip.com/service/webmaster/euripbot.html',
-				uaCompany: 'EURIP - European Internet Portal',
-				uaCompanyUrl: 'http://www.eurip.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EuripBot'
-			}
-		},
-		'5818': {
-			userAgent: 'Mozilla/5.0 (compatible; Ezooms/1.0; ezooms.bot@gmail.com)',
-			metadata: {
-				uaFamily: 'Ezooms',
-				uaName: 'Ezooms/1.0',
-				uaUrl: '',
-				uaCompany: 'dotnetdotcom.org',
-				uaCompanyUrl: 'http://www.dotnetdotcom.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ezooms'
-			}
-		},
-		'5828': {
-			userAgent: 'thumbshots-de-bot (+http://www.thumbshots.de/)',
-			metadata: {
-				uaFamily: 'thumbshots-de-Bot',
-				uaName: 'thumbshots-de-bot',
-				uaUrl: 'http://www.thumbshots.de/content-39-seite_auszuschliessen.html',
-				uaCompany: 'Mobile & More Mobilkommunikation GmbH',
-				uaCompanyUrl: 'http://www.mobile-more.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=thumbshots-de-Bot'
-			}
-		},
-		'5839': {
-			userAgent: 'TwengaBot',
-			metadata: {
-				uaFamily: 'TwengaBot',
-				uaName: 'TwengaBot',
-				uaUrl: 'http://www.twenga.com/bot.html',
-				uaCompany: 'Twenga SA',
-				uaCompanyUrl: 'http://www.twenga.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=TwengaBot'
-			}
-		},
-		'5843': {
-			userAgent: 'findlinks/2.0.2 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.0.2',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'5846': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexMedia/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'Mozilla/5.0 (compatible; YandexMedia/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'5857': {
-			userAgent: 'SeznamBot/3.0-beta (+http://fulltext.sblog.cz/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.0-beta',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'5859': {
-			userAgent: 'OpenCalaisSemanticProxy',
-			metadata: {
-				uaFamily: 'OpenCalaisSemanticProxy',
-				uaName: 'OpenCalaisSemanticProxy',
-				uaUrl: 'http://www.opencalais.com/open-calais-semanticproxy-robot-agent-name',
-				uaCompany: 'Thomson Reuters',
-				uaCompanyUrl: 'http://thomsonreuters.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenCalaisSemanticProxy'
-			}
-		},
-		'5860': {
-			userAgent: 'Covario-IDS/1.0 (Covario; http://www.covario.com/ids; support at covario dot com)',
-			metadata: {
-				uaFamily: 'Covario-IDS',
-				uaName: 'Covario-IDS/1.0',
-				uaUrl: 'http://www.covario.com/ids',
-				uaCompany: 'Covario Inc.',
-				uaCompanyUrl: 'http://www.covario.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Covario-IDS'
-			}
-		},
-		'5862': {
-			userAgent: 'Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.0.1; compatible; iCjobs Stellenangebote Jobs; http://www.icjobs.de) Gecko/20100401 iCjobs/3.2.3',
-			metadata: {
-				uaFamily: 'iCjobs',
-				uaName: 'iCjobs/3.2.3',
-				uaUrl: 'http://www.icjobs.de/bot.htm',
-				uaCompany: 'Intelligence Competence Center AG',
-				uaCompanyUrl: 'http://www.iccenter.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=iCjobs'
-			}
-		},
-		'5902': {
-			userAgent: 'ichiro/5.0 (http://help.goo.ne.jp/door/crawler.html)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/5.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'5909': {
-			userAgent: 'Mozilla/5.0 (compatible; CligooRobot/2.0; +http://www.cligoo.de/wk/technik.php)',
-			metadata: {
-				uaFamily: 'CligooRobot',
-				uaName: 'CligooRobot/2.0',
-				uaUrl: 'http://www.cligoo.de/wk/technik.php',
-				uaCompany: 'cligoo medien service UG',
-				uaCompanyUrl: 'http://www.cligoo.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CligooRobot'
-			}
-		},
-		'5939': {
-			userAgent: 'nWormFeedFinder (http://www.nworm.com)',
-			metadata: {
-				uaFamily: 'nworm',
-				uaName: 'nwormFeedFinder',
-				uaUrl: 'http://www.nworm.com/crawlers.php',
-				uaCompany: 'Daniel Schlicker (mangora IT)',
-				uaCompanyUrl: 'http://www.mangora.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=nworm'
-			}
-		},
-		'5960': {
-			userAgent: 'MetaGeneratorCrawler/1.1 (www.metagenerator.info)',
-			metadata: {
-				uaFamily: 'MetaGeneratorCrawler',
-				uaName: 'MetaGeneratorCrawler/1.1',
-				uaUrl: 'http://www.metagenerator.info/',
-				uaCompany: 'Jan Bogutzki',
-				uaCompanyUrl: 'http://jan.bogutzki.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetaGeneratorCrawler'
-			}
-		},
-		'5982': {
-			userAgent: 'Y!J-BRO/YFSJ crawler (compatible; Mozilla 4.0; MSIE 5.5; http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html; YahooFeedSeekerJp/2.0)',
-			metadata: {
-				uaFamily: 'Yahoo! JAPAN',
-				uaName: 'Y!J-BRO/YFSJ',
-				uaUrl: 'http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo! JAPAN'
-			}
-		},
-		'5987': {
-			userAgent: 'Mozilla/5.0 (compatible; oBot/2.3.1; +http://www-935.ibm.com/services/us/index.wss/detail/iss/a1029077?cntxt=a1027244)',
-			metadata: {
-				uaFamily: 'oBot',
-				uaName: 'oBot/2.3.1 b',
-				uaUrl: 'http://filterdb.iss.net/crawler/',
-				uaCompany: 'IBM Germany Research & Development GmbH',
-				uaCompanyUrl: 'http://www.ibm.com/ibm/de/de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=oBot'
-			}
-		},
-		'5999': {
-			userAgent: 'SEOENGBot/1.2 (+http://learn.seoengine.com/seoengbot.htm)',
-			metadata: {
-				uaFamily: 'SEOENGBot',
-				uaName: 'SEOENGBot/1.2',
-				uaUrl: 'http://www.seoengine.com/seoengbot.htm',
-				uaCompany: 'SEO Engine',
-				uaCompanyUrl: 'http://www.seoengine.com/',
-				uaIcon: 'bot_SEOENGBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SEOENGBot'
-			}
-		},
-		'6001': {
-			userAgent: 'Zookabot/2.2;++http://zookabot.com',
-			metadata: {
-				uaFamily: 'Zookabot',
-				uaName: 'Zookabot/2.2',
-				uaUrl: 'http://zookabot.com/',
-				uaCompany: 'Hwacha ApS',
-				uaCompanyUrl: 'http://hwacha.dk/',
-				uaIcon: 'bot_Zookabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Zookabot'
-			}
-		},
-		'6010': {
-			userAgent: 'msnbot-NewsBlogs/2.0b (+http://search.msn.com/msnbot.htm)',
-			metadata: {
-				uaFamily: 'MSNBot',
-				uaName: 'msnbot-NewsBlogs/2.0b',
-				uaUrl: 'http://search.msn.com/msnbot.htm',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MSNBot'
-			}
-		},
-		'6011': {
-			userAgent: 'findlinks/2.0.4 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.0.4',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'6024': {
-			userAgent: 'quickobot/quickobot-1 (Quicko Labs; http://quicko.co; robot at quicko dot co)',
-			metadata: {
-				uaFamily: 'quickobot',
-				uaName: 'quickobot-1',
-				uaUrl: 'http://www.searchenabler.com/quickobot/',
-				uaCompany: 'Quicko Labs Pvt Ltd. ',
-				uaCompanyUrl: 'http://www.searchenabler.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=quickobot'
-			}
-		},
-		'6038': {
-			userAgent: 'SeznamBot/3.0-beta (+http://fulltext.sblog.cz/), I',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.0-beta',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'6040': {
-			userAgent: 'Mozilla/5.0 (compatible; SEODat/0.1 http://crawler.seodat.com)',
-			metadata: {
-				uaFamily: 'SEODat',
-				uaName: 'SEODat/0.1',
-				uaUrl: '',
-				uaCompany: 'SEODAT',
-				uaCompanyUrl: 'http://www.seodat.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SEODat'
-			}
-		},
-		'6044': {
-			userAgent: 'linkdex.com/v2.0',
-			metadata: {
-				uaFamily: 'linkdex.com',
-				uaName: 'linkdex.com/v2.0',
-				uaUrl: '',
-				uaCompany: 'Linkdex Limited',
-				uaCompanyUrl: 'http://www.linkdex.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=linkdex.com'
-			}
-		},
-		'6065': {
-			userAgent: 'UnwindFetchor/1.0 (+http://www.gnip.com/)',
-			metadata: {
-				uaFamily: 'UnwindFetchor',
-				uaName: 'UnwindFetchor/1.0',
-				uaUrl: '',
-				uaCompany: 'Gnip, inc.',
-				uaCompanyUrl: 'http://gnip.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=UnwindFetchor'
-			}
-		},
-		'6068': {
-			userAgent: 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (FlipboardProxy/0.0.5; +http://flipboard.com/browserproxy)',
-			metadata: {
-				uaFamily: 'FlipboardProxy',
-				uaName: 'FlipboardProxy/0.0.5',
-				uaUrl: 'http://flipboard.com/browserproxy',
-				uaCompany: 'Flipboard, Inc.',
-				uaCompanyUrl: 'http://flipboard.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FlipboardProxy'
-			}
-		},
-		'6109': {
-			userAgent: 'Sitedomain-Bot(Sitedomain-Bot 1.0, http://www.sitedomain.de/sitedomain-bot/)',
-			metadata: {
-				uaFamily: 'Sitedomain-Bot',
-				uaName: 'Sitedomain-Bot 1.0',
-				uaUrl: 'http://www.sitedomain.de/sitedomain-bot/',
-				uaCompany: 'Sitedomain.de',
-				uaCompanyUrl: 'http://www.sitedomain.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sitedomain-Bot'
-			}
-		},
-		'6114': {
-			userAgent: 'Nuhk/2.4 (+http://www.neti.ee/cgi-bin/abi/otsing.html)',
-			metadata: {
-				uaFamily: 'Nuhk',
-				uaName: 'Nuhk/2.4 b',
-				uaUrl: 'http://www.neti.ee/cgi-bin/abi/Otsing/Nuhk/',
-				uaCompany: 'Elion',
-				uaCompanyUrl: 'http://www.neti.ee/',
-				uaIcon: 'bot_Nuhk.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nuhk'
-			}
-		},
-		'6134': {
-			userAgent: 'Mail.RU/2.0',
-			metadata: {
-				uaFamily: 'Mail.Ru bot',
-				uaName: 'Mail.RU/2.0',
-				uaUrl: 'http://go.mail.ru/help/robots',
-				uaCompany: 'Mail.Ru Group',
-				uaCompanyUrl: 'http://corp.mail.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mail.Ru bot'
-			}
-		},
-		'6146': {
-			userAgent: 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.0; trendictionbot0.4.2; trendiction media ssppiiddeerr; http://www.trendiction.com/bot/; please let us know of any problems; ssppiiddeerr at trendiction.com) Gecko/20071127 Firefox/2.0.0.11',
-			metadata: {
-				uaFamily: 'trendictionbot',
-				uaName: 'trendictionbot0.4.2',
-				uaUrl: 'http://www.trendiction.de/bot',
-				uaCompany: 'Trendiction S.A.',
-				uaCompanyUrl: 'http://www.trendiction.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=trendictionbot'
-			}
-		},
-		'6177': {
-			userAgent: 'findlinks/1.1.3-beta9 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/1.1.3-beta9',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'6189': {
-			userAgent: 'SeznamBot/3.0 (+http://fulltext.sblog.cz/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.0',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'6192': {
-			userAgent: 'SeznamBot/3.0-test (+http://fulltext.sblog.cz/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.0-test',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'6202': {
-			userAgent: 'FlightDeckReportsBot/2.0 (http://www.flightdeckreports.com/pages/bot)',
-			metadata: {
-				uaFamily: 'FlightDeckReportsBot',
-				uaName: 'FlightDeckReportsBot/2.0',
-				uaUrl: 'http://www.flightdeckreports.com/pages/bot',
-				uaCompany: 'Flight Deck Reports, LLC.',
-				uaCompanyUrl: 'http://www.flightdeckreports.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=FlightDeckReportsBot'
-			}
-		},
-		'6214': {
-			userAgent: 'SeznamBot/3.0-test (+http://fulltext.sblog.cz/), I',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.0-test',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'6225': {
-			userAgent: 'Mozilla/5.0 (compatible; NetcraftSurveyAgent/1.0; +info@netcraft.com)',
-			metadata: {
-				uaFamily: 'NetcraftSurveyAgent',
-				uaName: 'NetcraftSurveyAgent/1.0',
-				uaUrl: '',
-				uaCompany: 'Netcraft Ltd',
-				uaCompanyUrl: 'http://www.netcraft.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NetcraftSurveyAgent'
-			}
-		},
-		'6226': {
-			userAgent: 'GarlikCrawler/1.1 (http://garlik.com/, crawler@garik.com)',
-			metadata: {
-				uaFamily: 'GarlikCrawler',
-				uaName: 'GarlikCrawler/1.1',
-				uaUrl: '',
-				uaCompany: 'Garlik Limited',
-				uaCompanyUrl: 'http://www.garlik.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GarlikCrawler'
-			}
-		},
-		'6229': {
-			userAgent: 'Setooz/Nutch-1.0 (http://www.setooz.com)',
-			metadata: {
-				uaFamily: 'Setoozbot',
-				uaName: 'Setoozbot/1.0',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot'
-			}
-		},
-		'6231': {
-			userAgent: 'BacklinkCrawler (http://www.backlinktest.com/crawler.html)',
-			metadata: {
-				uaFamily: 'BacklinkCrawler',
-				uaName: 'BacklinkCrawler',
-				uaUrl: 'http://www.backlinktest.com/crawler.html',
-				uaCompany: '2.0Promotion GbR',
-				uaCompanyUrl: 'http://2.0promotion.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BacklinkCrawler'
-			}
-		},
-		'6234': {
-			userAgent: 'OpenWebSpider v0.1.2.B (http://www.openwebspider.org/)',
-			metadata: {
-				uaFamily: 'OpenWebSpider',
-				uaName: 'OpenWebSpider v0.1.2.B',
-				uaUrl: 'http://www.openwebspider.org/',
-				uaCompany: 'Stefano Alimonti',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenWebSpider'
-			}
-		},
-		'6237': {
-			userAgent: 'http://arachnode.net 2.5',
-			metadata: {
-				uaFamily: 'arachnode.net',
-				uaName: 'arachnode.net/2.5',
-				uaUrl: 'http://arachnode.codeplex.com/',
-				uaCompany: 'arachnode.net, llc',
-				uaCompanyUrl: 'http://arachnode.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=arachnode.net'
-			}
-		},
-		'6243': {
-			userAgent: 'Mozilla/5.0 (compatible; Evrinid Iudex 1.0.0; +http://www.evri.com/evrinid)',
-			metadata: {
-				uaFamily: 'EvriNid',
-				uaName: 'EvriNid/1.0.0',
-				uaUrl: 'http://corporate.evri.com/about-us/evrinid/',
-				uaCompany: 'Evri Inc.',
-				uaCompanyUrl: 'http://corporate.evri.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EvriNid'
-			}
-		},
-		'6244': {
-			userAgent: 'Mozilla/5.0 (compatible; discobot/1.0; +http://discoveryengine.com/discobot.html)',
-			metadata: {
-				uaFamily: 'discoverybot',
-				uaName: 'discobot/1.0',
-				uaUrl: 'http://discoveryengine.com/discoverybot.html',
-				uaCompany: 'discoveryengine.com. ',
-				uaCompanyUrl: 'http://www.discoveryengine.com/',
-				uaIcon: 'bot_discobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=discoverybot'
-			}
-		},
-		'6245': {
-			userAgent: 'Nymesis/2.0 (http://nymesis.com)',
-			metadata: {
-				uaFamily: 'Nymesis',
-				uaName: 'Nymesis/2.0',
-				uaUrl: 'http://www.nymesis.com/about/',
-				uaCompany: 'nymesis.com',
-				uaCompanyUrl: 'http://www.nymesis.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Nymesis'
-			}
-		},
-		'6246': {
-			userAgent: 'Abrave Spider v4 Robot 1 (http://robot.abrave.co.uk)',
-			metadata: {
-				uaFamily: 'Abrave Spider',
-				uaName: 'Abrave Spider/4-1',
-				uaUrl: 'http://robot.abrave.co.uk/',
-				uaCompany: 'Gallent Limited',
-				uaCompanyUrl: 'http://www.gallent.co.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Abrave Spider'
-			}
-		},
-		'6247': {
-			userAgent: 'Abrave Spider v4 Robot 2 (http://robot.abrave.co.uk)',
-			metadata: {
-				uaFamily: 'Abrave Spider',
-				uaName: 'Abrave Spider/4-2',
-				uaUrl: 'http://robot.abrave.co.uk/',
-				uaCompany: 'Gallent Limited',
-				uaCompanyUrl: 'http://www.gallent.co.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Abrave Spider'
-			}
-		},
-		'6252': {
-			userAgent: 'RankurBot/Rankur2.1 (http://rankur.com; info at rankur dot com)',
-			metadata: {
-				uaFamily: 'RankurBot',
-				uaName: 'RankurBot/2.1',
-				uaUrl: 'http://rankur.com/technology.html',
-				uaCompany: 'Advance Solutions EU Ltd.',
-				uaCompanyUrl: 'http://www.advancesolutions.eu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=RankurBot'
-			}
-		},
-		'6270': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.4.0; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.4.0',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'6280': {
-			userAgent: 'crawler4j (http://code.google.com/p/crawler4j/)',
-			metadata: {
-				uaFamily: 'Crawler4j',
-				uaName: 'Crawler4j',
-				uaUrl: 'http://code.google.com/p/crawler4j/',
-				uaCompany: 'Yasser Ganjisaffar',
-				uaCompanyUrl: 'http://www.ics.uci.edu/~yganjisa/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Crawler4j'
-			}
-		},
-		'6288': {
-			userAgent: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) Speedy Spider for SpeedyAds (http://www.entireweb.com/about/search_tech/speedy_spider/)',
-			metadata: {
-				uaFamily: 'Speedy',
-				uaName: 'Speedy Spider',
-				uaUrl: '',
-				uaCompany: 'Entireweb Sweden AB',
-				uaCompanyUrl: 'http://www.entireweb.com/',
-				uaIcon: 'bot_Speedy.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Speedy'
-			}
-		},
-		'6298': {
-			userAgent: 'findlinks/2.0.9 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.0.9',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'6304': {
-			userAgent: 'Mozilla/5.0 (compatible; NerdByNature.Bot; http://www.nerdbynature.net/bot)',
-			metadata: {
-				uaFamily: 'NerdByNature.Bot',
-				uaName: 'NerdByNature.Bot',
-				uaUrl: 'http://www.nerdbynature.net/bot',
-				uaCompany: 'W3 Solutions GmbH',
-				uaCompanyUrl: 'http://www.w3solutions.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NerdByNature.Bot'
-			}
-		},
-		'6312': {
-			userAgent: 'findlinks/2.1 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.1',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'6326': {
-			userAgent: 'findlinks/2.1.3 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.1.3',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'6329': {
-			userAgent: 'Mozilla/5.0 (compatible; SISTRIX Crawler; http://crawler.sistrix.net/)',
-			metadata: {
-				uaFamily: 'sistrix',
-				uaName: 'sistrix',
-				uaUrl: 'http://crawler.sistrix.net/',
-				uaCompany: 'SISTRIX GmbH',
-				uaCompanyUrl: 'http://www.sistrix.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sistrix'
-			}
-		},
-		'6352': {
-			userAgent: 'Mozilla/5.0 (compatible; Plukkie/1.4; http://www.botje.com/plukkie.htm)',
-			metadata: {
-				uaFamily: 'Plukkie',
-				uaName: 'Plukkie/1.4',
-				uaUrl: 'http://www.botje.com/plukkie.htm',
-				uaCompany: 'botje.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Plukkie'
-			}
-		},
-		'6353': {
-			userAgent: 'GarlikCrawler/1.1 (http://garlik.com/, crawler@garlik.com)',
-			metadata: {
-				uaFamily: 'GarlikCrawler',
-				uaName: 'GarlikCrawler/1.1 b',
-				uaUrl: '',
-				uaCompany: 'Garlik Limited',
-				uaCompanyUrl: 'http://www.garlik.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GarlikCrawler'
-			}
-		},
-		'6399': {
-			userAgent: 'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)',
-			metadata: {
-				uaFamily: 'Baiduspider',
-				uaName: 'Baiduspider/2.0',
-				uaUrl: 'http://www.baidu.com/search/spider.htm',
-				uaCompany: 'Baidu',
-				uaCompanyUrl: 'http://www.baidu.com/',
-				uaIcon: 'bot_baiduspider.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Baiduspider'
-			}
-		},
-		'6404': {
-			userAgent: 'Mozilla/5.0 (compatible; AhrefsBot/1.0; +http://ahrefs.com/robot/)',
-			metadata: {
-				uaFamily: 'AhrefsBot',
-				uaName: 'AhrefsBot/1.0',
-				uaUrl: 'http://ahrefs.com/robot/',
-				uaCompany: 'Ahrefs.com',
-				uaCompanyUrl: 'http://ahrefs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AhrefsBot'
-			}
-		},
-		'6436': {
-			userAgent: 'Mozilla/5.0 (compatible; MojeekBot/0.2; http://www.mojeek.com/bot.html)',
-			metadata: {
-				uaFamily: 'MojeekBot',
-				uaName: 'MojeekBot/0.2',
-				uaUrl: 'http://www.mojeek.com/bot.html',
-				uaCompany: 'Mojeek Ltd.',
-				uaCompanyUrl: 'http://www.mojeek.com/',
-				uaIcon: 'bot_MojeekBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MojeekBot'
-			}
-		},
-		'6506': {
-			userAgent: 'SEOENGWorldBot/1.0 (+http://www.seoengine.com/seoengbot.htm)',
-			metadata: {
-				uaFamily: 'SEOENGBot',
-				uaName: 'SEOENGBot/1.0',
-				uaUrl: 'http://www.seoengine.com/seoengbot.htm',
-				uaCompany: 'SEO Engine',
-				uaCompanyUrl: 'http://www.seoengine.com/',
-				uaIcon: 'bot_SEOENGBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SEOENGBot'
-			}
-		},
-		'6514': {
-			userAgent: 'Mozilla/5.0 (compatible; socketcrawler; http://nlp.fi.muni.cz/projects/biwec/)',
-			metadata: {
-				uaFamily: 'biwec',
-				uaName: 'biwec',
-				uaUrl: 'http://nlp.fi.muni.cz/projects/biwec/',
-				uaCompany: 'Centre for Natural Language Processing',
-				uaCompanyUrl: 'http://muni.cz/fi/335300?lang=en',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=biwec'
-			}
-		},
-		'6515': {
-			userAgent: 'Wotbox/2.0 (bot@wotbox.com; http://www.wotbox.com)',
-			metadata: {
-				uaFamily: 'Wotbox',
-				uaName: 'Wotbox/2.0',
-				uaUrl: 'http://www.wotbox.com/bot/',
-				uaCompany: 'Wotbox Team',
-				uaCompanyUrl: 'http://www.wotbox.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Wotbox'
-			}
-		},
-		'6578': {
-			userAgent: 'Mozilla/5.0 (compatible; Thumbshots.ru; +http://thumbshots.ru/bot) Firefox/3',
-			metadata: {
-				uaFamily: 'Thumbshots.ru',
-				uaName: 'Thumbshots.ru',
-				uaUrl: 'http://thumbshots.ru/bot',
-				uaCompany: 'Sonorth Technologies',
-				uaCompanyUrl: 'http://www.sonorth.com/tech/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Thumbshots.ru'
-			}
-		},
-		'6583': {
-			userAgent: 'JikeSpider Mozilla/5.0 (compatible; JikeSpider; +http://shoulu.jike.com/spider.html)',
-			metadata: {
-				uaFamily: 'JikeSpider',
-				uaName: 'JikeSpider',
-				uaUrl: 'http://shoulu.jike.com/spider.html',
-				uaCompany: 'jike.com',
-				uaCompanyUrl: 'http://www.jike.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=JikeSpider'
-			}
-		},
-		'6592': {
-			userAgent: 'Aboundex/0.2 (http://www.aboundex.com/crawler/)',
-			metadata: {
-				uaFamily: 'Aboundexbot',
-				uaName: 'Aboundexbot/0.2',
-				uaUrl: 'http://www.aboundex.com/crawler/',
-				uaCompany: 'Aboundex.com',
-				uaCompanyUrl: 'http://www.aboundex.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Aboundexbot'
-			}
-		},
-		'6598': {
-			userAgent: 'Mozilla/5.0 (compatible; SEOkicks-Robot +http://www.seokicks.de/robot.html)',
-			metadata: {
-				uaFamily: 'SEOkicks-Robot',
-				uaName: 'SEOkicks-Robot',
-				uaUrl: 'http://www.seokicks.de/robot.html',
-				uaCompany: 'Torsten R\xfcckert Internetdienstleistungen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SEOkicks-Robot'
-			}
-		},
-		'6603': {
-			userAgent: 'Y!J-BRW/1.0 crawler (http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html)',
-			metadata: {
-				uaFamily: 'Yahoo! JAPAN',
-				uaName: 'Y!J-BRW/1.0',
-				uaUrl: 'http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo! JAPAN'
-			}
-		},
-		'6612': {
-			userAgent: 'The Lemur Web Crawler/Nutch-1.3 (Lemur Web Crawler; http://boston.lti.cs.cmu.edu/crawler_12/; admin@lemurproject.org)',
-			metadata: {
-				uaFamily: 'LemurWebCrawler',
-				uaName: 'LemurWebCrawler',
-				uaUrl: 'http://boston.lti.cs.cmu.edu/crawler_12/',
-				uaCompany: 'Language Technologies Institute',
-				uaCompanyUrl: 'http://www.lti.cs.cmu.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LemurWebCrawler'
-			}
-		},
-		'6625': {
-			userAgent: 'LapozzBot/1.5 (+http://robot.lapozz.hu) ',
-			metadata: {
-				uaFamily: 'LapozzBot',
-				uaName: 'LapozzBot/1.5',
-				uaUrl: 'http://robot.lapozz.hu/',
-				uaCompany: 'lapozz.hu',
-				uaCompanyUrl: 'http://www.lapozz.hu/',
-				uaIcon: 'bot_lapozzbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LapozzBot'
-			}
-		},
-		'6630': {
-			userAgent: 'CovarioIDS/1.1 (http://www.covario.com/ids; support at covario dot com)',
-			metadata: {
-				uaFamily: 'Covario-IDS',
-				uaName: 'CovarioIDS/1.1',
-				uaUrl: 'http://www.covario.com/ids',
-				uaCompany: 'Covario, Inc.',
-				uaCompanyUrl: 'http://www.covario.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Covario-IDS'
-			}
-		},
-		'6647': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/3.1.0-RC1 +http://boston.lti.cs.cmu.edu/crawler_12/)',
-			metadata: {
-				uaFamily: 'LemurWebCrawler',
-				uaName: 'LemurWebCrawler',
-				uaUrl: 'http://boston.lti.cs.cmu.edu/crawler_12/',
-				uaCompany: 'Language Technologies Institute',
-				uaCompanyUrl: 'http://www.lti.cs.cmu.edu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=LemurWebCrawler'
-			}
-		},
-		'6679': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-34-server; java 1.6.0_26; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'6680': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.6.0_29; Europe/fr) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'6708': {
-			userAgent: 'SEOENGBot/1.2 (+http://www.seoengine.com/seoengbot.htm)',
-			metadata: {
-				uaFamily: 'SEOENGBot',
-				uaName: 'SEOENGBot/1.2 new',
-				uaUrl: 'http://www.seoengine.com/seoengbot.htm',
-				uaCompany: 'SEO Engine',
-				uaCompanyUrl: 'http://www.seoengine.com/',
-				uaIcon: 'bot_SEOENGBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SEOENGBot'
-			}
-		},
-		'6712': {
-			userAgent: 'findlinks/2.1.5 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.1.5',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'6721': {
-			userAgent: 'Ronzoobot/1.5 (http://www.ronzoo.com/about/)',
-			metadata: {
-				uaFamily: 'Ronzoobot',
-				uaName: 'Ronzoobot/1.5',
-				uaUrl: 'http://www.ronzoo.com/about/',
-				uaCompany: 'Ronzoo',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_Ronzoobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ronzoobot'
-			}
-		},
-		'6735': {
-			userAgent: 'netEstate NE Crawler (+http://www.sengine.info/)',
-			metadata: {
-				uaFamily: 'netEstate Crawler',
-				uaName: 'netEstate NE Crawler',
-				uaUrl: '',
-				uaCompany: 'netEstate GmbH',
-				uaCompanyUrl: 'http://www.netestate.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=netEstate Crawler'
-			}
-		},
-		'6739': {
-			userAgent: 'PagePeeker.com',
-			metadata: {
-				uaFamily: 'PagePeeker',
-				uaName: 'PagePeeker',
-				uaUrl: 'http://pagepeeker.com/robots',
-				uaCompany: 'PagePeeker.com',
-				uaCompanyUrl: 'http://pagepeeker.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PagePeeker'
-			}
-		},
-		'6751': {
-			userAgent: 'Mozilla/5.0 (compatible; AhrefsBot/2.0; +http://ahrefs.com/robot/)',
-			metadata: {
-				uaFamily: 'AhrefsBot',
-				uaName: 'AhrefsBot/2.0',
-				uaUrl: 'http://ahrefs.com/robot/',
-				uaCompany: 'Ahrefs.com',
-				uaCompanyUrl: 'http://ahrefs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AhrefsBot'
-			}
-		},
-		'6770': {
-			userAgent: 'SemrushBot/0.9',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.9',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'6776': {
-			userAgent: 'Mozilla/5.0 (compatible; WBSearchBot/1.1; +http://www.warebay.com/bot.html)',
-			metadata: {
-				uaFamily: 'WBSearchBot',
-				uaName: 'WBSearchBot/1.1',
-				uaUrl: 'http://www.warebay.com/bot.html',
-				uaCompany: 'Ware Bay',
-				uaCompanyUrl: 'http://www.warebay.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WBSearchBot'
-			}
-		},
-		'6802': {
-			userAgent: 'Mozilla/5.0 (compatible; DCPbot/1.0; +http://domains.checkparams.com/)',
-			metadata: {
-				uaFamily: 'DCPbot',
-				uaName: 'DCPbot/1.0',
-				uaUrl: 'http://domains.checkparams.com/',
-				uaCompany: 'CheckParams',
-				uaCompanyUrl: 'http://checkparams.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DCPbot'
-			}
-		},
-		'6816': {
-			userAgent: 'Mozilla/5.0 (compatible; SpiderLing (a SPIDER for LINGustic research); http://nlp.fi.muni.cz/projects/biwec/)',
-			metadata: {
-				uaFamily: 'SpiderLing',
-				uaName: 'SpiderLing',
-				uaUrl: 'http://nlp.fi.muni.cz/projects/biwec/',
-				uaCompany: 'Natural Language Processing Centre',
-				uaCompanyUrl: 'http://nlp.fi.muni.cz/en/nlpc',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SpiderLing'
-			}
-		},
-		'6826': {
-			userAgent: 'Mozilla/5.0 (compatible; oBot/2.3.1; +http://filterdb.iss.net/crawler/)',
-			metadata: {
-				uaFamily: 'oBot',
-				uaName: 'oBot/2.3.1',
-				uaUrl: 'http://filterdb.iss.net/crawler/',
-				uaCompany: 'IBM Germany Research &amp; Development GmbH',
-				uaCompanyUrl: 'http://www.ibm.com/ibm/de/de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=oBot'
-			}
-		},
-		'6829': {
-			userAgent: 'Mozilla/5.0 (compatible; JikeSpider; +http://shoulu.jike.com/spider.html)',
-			metadata: {
-				uaFamily: 'JikeSpider',
-				uaName: 'JikeSpider b',
-				uaUrl: 'http://shoulu.jike.com/spider.html',
-				uaCompany: 'jike.com',
-				uaCompanyUrl: 'http://www.jike.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=JikeSpider'
-			}
-		},
-		'6835': {
-			userAgent: 'SETOOZBOT/5.0 ( compatible; SETOOZBOT/0.30 ; http://www.setooz.com/bot.html )',
-			metadata: {
-				uaFamily: 'Setoozbot',
-				uaName: 'SETOOZBOT/0.30',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot'
-			}
-		},
-		'6837': {
-			userAgent: 'SETOOZBOT/5.0 ( http://www.setooz.com/bot.html )',
-			metadata: {
-				uaFamily: 'Setoozbot',
-				uaName: 'SETOOZBOT/5.0',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Setoozbot'
-			}
-		},
-		'6840': {
-			userAgent: 'Updownerbot (+http://www.updowner.com/bot)',
-			metadata: {
-				uaFamily: 'Updownerbot',
-				uaName: 'Updownerbot',
-				uaUrl: 'http://www.updowner.com/bot',
-				uaCompany: 'updowner.com',
-				uaCompanyUrl: 'http://www.updowner.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Updownerbot'
-			}
-		},
-		'6877': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.4.1; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.4.1',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'6884': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.0.0-14-generic; java 1.6.0_23; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'6892': {
-			userAgent: 'Mozilla/5.0 (compatible; Semager/1.4c; +http://www.semager.de/blog/semager-bots/)',
-			metadata: {
-				uaFamily: 'Semager',
-				uaName: 'Semager/1.4c',
-				uaUrl: 'http://www.semager.de/blog/semager-bots/',
-				uaCompany: 'NG-Marketing',
-				uaCompanyUrl: 'http://www.ng-marketing.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Semager'
-			}
-		},
-		'6896': {
-			userAgent: 'yacybot (freeworld/global; i386 Linux 2.6.37.6-0.5-desktop; java 1.6.0_20; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'6905': {
-			userAgent: 'Acoon v4.1.0 (www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon v4.1.0',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'6914': {
-			userAgent: 'Mozilla/5.0 (compatible; OpenindexDeepSpider/Nutch-1.5-dev; +http://openindex.io/spider.html; systemsATopenindexDOTio)',
-			metadata: {
-				uaFamily: 'OpenindexSpider',
-				uaName: 'OpenindexDeepSpider',
-				uaUrl: 'http://www.openindex.io/en/webmasters/spider.html',
-				uaCompany: 'Openindex B.V.',
-				uaCompanyUrl: 'http://www.openindex.io/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenindexSpider'
-			}
-		},
-		'6921': {
-			userAgent: 'Yeti-FeedItemCrawler/1.0 (NHN Corp.; http://help.naver.com/robots/)',
-			metadata: {
-				uaFamily: 'NaverBot',
-				uaName: 'Yeti-FeedItemCrawler/1.0',
-				uaUrl: 'http://help.naver.com/robots/',
-				uaCompany: 'NHN Corporation',
-				uaCompanyUrl: 'http://www.nhncorp.com/',
-				uaIcon: 'bot_NaverBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NaverBot'
-			}
-		},
-		'6922': {
-			userAgent: 'Mozilla/5.0 (compatible; discobot/2.0; +http://discoveryengine.com/discobot.html)',
-			metadata: {
-				uaFamily: 'discoverybot',
-				uaName: 'discobot/2.0',
-				uaUrl: 'http://discoveryengine.com/discoverybot.html',
-				uaCompany: 'discoveryengine.com. ',
-				uaCompanyUrl: 'http://www.discoveryengine.com/',
-				uaIcon: 'bot_discobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=discoverybot'
-			}
-		},
-		'6929': {
-			userAgent: 'Mozilla/5.0 (compatible; WASALive-Bot ; http://blog.wasalive.com/wasalive-bots/)',
-			metadata: {
-				uaFamily: 'WASALive-Bot',
-				uaName: ' WASALive-Bot',
-				uaUrl: 'http://blog.wasalive.com/wasalive-bots/',
-				uaCompany: 'WASALive',
-				uaCompanyUrl: 'http://www.wasalive.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WASALive-Bot'
-			}
-		},
-		'6937': {
-			userAgent: 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.5) Gecko/2010033101 Gentoo Firefox/3.0.5 (Dot TK - spider 3.0)',
-			metadata: {
-				uaFamily: 'Dot TK - spider',
-				uaName: 'Dot TK - spider 3.0',
-				uaUrl: '',
-				uaCompany: 'Dot TK Limited',
-				uaCompanyUrl: 'http://www.dot.tk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Dot TK - spider'
-			}
-		},
-		'6945': {
-			userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.51 (KHTML, like Gecko; Google Web Preview) Chrome/12.0.742 Safari/534.51',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Google Web Preview',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1062498',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'6947': {
-			userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko; Google Web Preview) Chrome/11.0.696 Safari/534.24 ',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Google Web Preview',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1062498',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'6948': {
-			userAgent: 'Mozilla/5.0 (en-us) AppleWebKit/525.13 (KHTML, like Gecko; Google Web Preview) Version/3.1 Safari/525.13',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Google Web Preview',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1062498',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'6961': {
-			userAgent: 'Visbot/2.0 (+http://www.visvo.com/en/webmasters.jsp;bot@visvo.com)',
-			metadata: {
-				uaFamily: 'Visbot',
-				uaName: 'Visbot/2.0',
-				uaUrl: 'http://www.visvo.com/webmasters.htm',
-				uaCompany: 'Visvo Inc.',
-				uaCompanyUrl: 'http://www.visvo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Visbot'
-			}
-		},
-		'6962': {
-			userAgent: 'Mozilla/5.0 (compatible; UASlinkChecker/1.0; +http://user-agent-string.info/UASlinkChecker)',
-			metadata: {
-				uaFamily: 'UASlinkChecker',
-				uaName: 'UASlinkChecker/1.0',
-				uaUrl: 'http://user-agent-string.info/UASlinkChecker',
-				uaCompany: 'Jaroslav Mallat',
-				uaCompanyUrl: 'http://mallat.cz/',
-				uaIcon: 'bot_UASlinkChecker.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=UASlinkChecker'
-			}
-		},
-		'6968': {
-			userAgent: 'yacybot (webportal/global; amd64 Linux 2.6.32-5-amd64; java 1.6.0_18; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'6974': {
-			userAgent: 'PostPost/1.0 (+http://postpost.com/crawlers)',
-			metadata: {
-				uaFamily: 'PostPost',
-				uaName: 'PostPost/1.0',
-				uaUrl: 'http://postpost.com/crawlers',
-				uaCompany: 'Boathouse group',
-				uaCompanyUrl: 'http://www.boathouseinc.com/',
-				uaIcon: 'bot_PostPost.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PostPost'
-			}
-		},
-		'6977': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-5-amd64; java 1.6.0_18; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'6978': {
-			userAgent: 'Pixray-Seeker/1.1 (Pixray-Seeker; crawler@pixray.com)',
-			metadata: {
-				uaFamily: 'Pixray-Seeker',
-				uaName: 'Pixray-Seeker/1.1',
-				uaUrl: 'http://www.pixray.com/pixraybot',
-				uaCompany: 'PIXRAY GmbH.',
-				uaCompanyUrl: 'http://www.pixray.com/',
-				uaIcon: 'bot_PixraySeeker.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Pixray-Seeker'
-			}
-		},
-		'6999': {
-			userAgent: 'ichiro/3.0 (http://help.goo.ne.jp/help/article/1142)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/3.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'7001': {
-			userAgent: 'Acoon v4.9.5 (www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon v4.9.5',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7005': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.4.2; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.4.2',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'7008': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.0.0-15-server; java 1.6.0_23; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7009': {
-			userAgent: 'Acoon v4.10.1 (www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon v4.10.1',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7012': {
-			userAgent: 'Mozilla/5.0 (compatible; Moatbot/2.2; +http://www.moat.com/pages/moatbot)',
-			metadata: {
-				uaFamily: 'Moatbot',
-				uaName: 'Moatbot/2.2',
-				uaUrl: 'http://www.moat.com/pages/moatbot',
-				uaCompany: 'Moat Inc.',
-				uaCompanyUrl: 'http://www.moat.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Moatbot'
-			}
-		},
-		'7013': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexNews/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexNews/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7014': {
-			userAgent: 'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Exabot-Thumbnails)',
-			metadata: {
-				uaFamily: 'Exabot',
-				uaName: 'Exabot-Thumbnails',
-				uaUrl: 'http://www.exabot.com/go/robot',
-				uaCompany: 'Exalead S.A.',
-				uaCompanyUrl: 'http://www.exalead.com/',
-				uaIcon: 'bot_Exabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Exabot'
-			}
-		},
-		'7015': {
-			userAgent: 'Mozilla/5.0 (compatible; Apercite; +http://www.apercite.fr/robot/index.html)',
-			metadata: {
-				uaFamily: 'Apercite',
-				uaName: 'Apercite',
-				uaUrl: 'http://www.apercite.fr/robot/index.html',
-				uaCompany: 'Apercite',
-				uaCompanyUrl: 'http://www.apercite.fr/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Apercite'
-			}
-		},
-		'7018': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexMetrika/2.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexMetrika/2.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7039': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.1-gentoo-r2; java 1.6.0_22; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7044': {
-			userAgent: 'Ronzoobot/1.6 (http://www.ronzoo.com/about/)',
-			metadata: {
-				uaFamily: 'Ronzoobot',
-				uaName: 'Ronzoobot/1.6',
-				uaUrl: 'http://www.ronzoo.com/about/',
-				uaCompany: 'Ronzoo',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_Ronzoobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Ronzoobot'
-			}
-		},
-		'7045': {
-			userAgent: 'Mozilla/5.0 (compatible; OpenindexDeepSpider/Nutch-1.5-dev; +http://www.openindex.io/en/webmasters/spider.html; systemsATopenindexDOTio)',
-			metadata: {
-				uaFamily: 'OpenindexSpider',
-				uaName: 'OpenindexDeepSpider',
-				uaUrl: 'http://www.openindex.io/en/webmasters/spider.html',
-				uaCompany: 'Openindex B.V.',
-				uaCompanyUrl: 'http://www.openindex.io/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenindexSpider'
-			}
-		},
-		'7051': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.0.0-12-generic; java 1.6.0_26; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7053': {
-			userAgent: 'gonzo2[p] (+http://www.suchen.de/faq.html)',
-			metadata: {
-				uaFamily: 'gonzo',
-				uaName: 'gonzo2',
-				uaUrl: 'http://www.suchen.de/faq.html',
-				uaCompany: 'SEARCHTEQ',
-				uaCompanyUrl: 'http://www.searchteq.de/',
-				uaIcon: 'bot_gonzo.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=gonzo'
-			}
-		},
-		'7055': {
-			userAgent: 'Mozilla/5.0 (compatible; OpenindexShallowSpider/Nutch-1.5-dev; +http://www.openindex.io/en/webmasters/spider.html; systemsATopenindexDOTio)',
-			metadata: {
-				uaFamily: 'OpenindexSpider',
-				uaName: 'OpenindexShalooowSpider',
-				uaUrl: 'http://www.openindex.io/en/webmasters/spider.html',
-				uaCompany: 'Openindex B.V.',
-				uaCompanyUrl: 'http://www.openindex.io/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenindexSpider'
-			}
-		},
-		'7060': {
-			userAgent: 'SemrushBot/Nutch-1.5-SNAPSHOT',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'7063': {
-			userAgent: 'Pixray-Seeker/1.1 (Pixray-Seeker; http://www.pixray.com/pixraybot; crawler@pixray.com)',
-			metadata: {
-				uaFamily: 'Pixray-Seeker',
-				uaName: 'Pixray-Seeker/1.1',
-				uaUrl: 'http://www.pixray.com/pixraybot',
-				uaCompany: 'PIXRAY GmbH.',
-				uaCompanyUrl: 'http://www.pixray.com/',
-				uaIcon: 'bot_PixraySeeker.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Pixray-Seeker'
-			}
-		},
-		'7070': {
-			userAgent: 'PagePeeker.com (info: http://pagepeeker.com/robots)',
-			metadata: {
-				uaFamily: 'PagePeeker',
-				uaName: 'PagePeeker',
-				uaUrl: 'http://pagepeeker.com/robots',
-				uaCompany: 'PagePeeker.com',
-				uaCompanyUrl: 'http://pagepeeker.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PagePeeker'
-			}
-		},
-		'7072': {
-			userAgent: 'Mozilla/5.0 (compatible;WI Job Roboter Spider Version 3;+http://www.webintegration.at)',
-			metadata: {
-				uaFamily: 'Job Roboter Spider',
-				uaName: 'Job Roboter Spider 3',
-				uaUrl: 'http://www.webintegration.at/jobroboter_suchmaschine',
-				uaCompany: 'Web Integration IT Service GmbH',
-				uaCompanyUrl: 'http://www.webintegration.at/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Job Roboter Spider'
-			}
-		},
-		'7079': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.1-gentoo-r2; java 1.6.0_24; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7083': {
-			userAgent: 'EdisterBot (http://www.edister.com/bot.html)',
-			metadata: {
-				uaFamily: 'EdisterBot',
-				uaName: 'EdisterBot',
-				uaUrl: 'http://www.edister.com/bot.html',
-				uaCompany: 'Jonathan Leger',
-				uaCompanyUrl: 'http://www.jonathanleger.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EdisterBot'
-			}
-		},
-		'7084': {
-			userAgent: 'Factbot 1.09 (see http://www.factbites.com/webmasters.php)',
-			metadata: {
-				uaFamily: 'factbot',
-				uaName: 'Factbot 1.09',
-				uaUrl: 'http://www.factbites.com/webmasters.php',
-				uaCompany: 'Rapid Intelligence Pty Ltd',
-				uaCompanyUrl: 'http://www.rapint.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=factbot'
-			}
-		},
-		'7092': {
-			userAgent: 'yacybot (webportal-global; amd64 Linux 2.6.32-5-amd64; java 1.6.0_18; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7096': {
-			userAgent: 'SemrushBot/0.91',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.91',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'7106': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/1.14.3 +http://www.accelobot.com)',
-			metadata: {
-				uaFamily: 'Accelobot',
-				uaName: 'Accelobot',
-				uaUrl: 'http://www.accelobot.com/',
-				uaCompany: 'NetBase Solutions, Inc.',
-				uaCompanyUrl: 'http://www.netbase.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Accelobot'
-			}
-		},
-		'7107': {
-			userAgent: 'Mozilla/5.0 (compatible; OpenindexDeepSpider/Nutch-1.5-dev; +http://www.openindex.io/en/webmasters/spider.html)',
-			metadata: {
-				uaFamily: 'OpenindexSpider',
-				uaName: 'OpenindexDeepSpider',
-				uaUrl: 'http://www.openindex.io/en/webmasters/spider.html',
-				uaCompany: 'Openindex B.V.',
-				uaCompanyUrl: 'http://www.openindex.io/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenindexSpider'
-			}
-		},
-		'7112': {
-			userAgent: 'Acoon v4.10.3 (www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon v4.10.3',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7113': {
-			userAgent: 'Mozilla/5.0 (compatible; IstellaBot/1.01.18 +http://www.tiscali.it/)',
-			metadata: {
-				uaFamily: 'IstellaBot',
-				uaName: 'IstellaBot/1.01.18',
-				uaUrl: '',
-				uaCompany: 'Tiscali Italia S.p.a',
-				uaCompanyUrl: 'http://www.tiscali.it/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IstellaBot'
-			}
-		},
-		'7119': {
-			userAgent: 'Mozilla/5.0 (compatible; imbot/0.1 +http://internetmemory.org/en/)',
-			metadata: {
-				uaFamily: 'imbot',
-				uaName: 'imbot/0.1',
-				uaUrl: '',
-				uaCompany: 'Internet Memory Foundation (formerly European Archive)',
-				uaCompanyUrl: 'http://internetmemory.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=imbot'
-			}
-		},
-		'7126': {
-			userAgent: 'SeznamBot/3.0 (HaF+http://fulltext.sblog.cz/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.0',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'7132': {
-			userAgent: 'Mozilla/5.0 (compatible; OpenindexShallowSpider/Nutch-1.5-dev; +http://www.openindex.io/en/webmasters/spider.html)',
-			metadata: {
-				uaFamily: 'OpenindexSpider',
-				uaName: 'OpenindexShalooowSpider',
-				uaUrl: 'http://www.openindex.io/en/webmasters/spider.html',
-				uaCompany: 'Openindex B.V.',
-				uaCompanyUrl: 'http://www.openindex.io/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenindexSpider'
-			}
-		},
-		'7133': {
-			userAgent: 'Mozilla/5.0 (compatible; YioopBot; +http://www.yioop.com/bot.php)',
-			metadata: {
-				uaFamily: 'YioopBot',
-				uaName: 'YioopBot',
-				uaUrl: 'http://www.yioop.com/bot.php',
-				uaCompany: 'Chris Pollett',
-				uaCompanyUrl: 'http://pollett.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YioopBot'
-			}
-		},
-		'7138': {
-			userAgent: 'Mozilla/5.0 (compatible; SWEBot/1.0; +http://swebot.net)',
-			metadata: {
-				uaFamily: 'SWEBot',
-				uaName: 'SWEBot/1.0',
-				uaUrl: 'http://swebot.net/',
-				uaCompany: 'swebot.net',
-				uaCompanyUrl: 'http://swebot.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SWEBot'
-			}
-		},
-		'7139': {
-			userAgent: 'Zookabot/2.4;++http://zookabot.com',
-			metadata: {
-				uaFamily: 'Zookabot',
-				uaName: 'Zookabot/2.4',
-				uaUrl: 'http://zookabot.com/',
-				uaCompany: 'Hwacha ApS',
-				uaCompanyUrl: 'http://hwacha.dk/',
-				uaIcon: 'bot_Zookabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Zookabot'
-			}
-		},
-		'7143': {
-			userAgent: 'DuckDuckPreview/1.0; (+http://duckduckgo.com/duckduckpreview.html)',
-			metadata: {
-				uaFamily: 'DuckDuckPreview',
-				uaName: 'DuckDuckPreview/1.0',
-				uaUrl: 'http://duckduckgo.com/duckduckpreview.html',
-				uaCompany: 'DuckDuckGo, Inc.',
-				uaCompanyUrl: 'http://duckduckgo.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DuckDuckPreview'
-			}
-		},
-		'7153': {
-			userAgent: 'percbotspider <ops@percolate.com>',
-			metadata: {
-				uaFamily: 'percbotspider',
-				uaName: 'percbotspider',
-				uaUrl: '',
-				uaCompany: 'Percolate Industries, Inc.',
-				uaCompanyUrl: 'http://percolate.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=percbotspider'
-			}
-		},
-		'7155': {
-			userAgent: 'Mozilla/5.0 (compatible; SWEBot/1.0; +http://swebot-crawler.net)',
-			metadata: {
-				uaFamily: 'SWEBot',
-				uaName: 'SWEBot/1.0',
-				uaUrl: 'http://swebot.net/',
-				uaCompany: 'swebot.net',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SWEBot'
-			}
-		},
-		'7159': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexCatalog/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexCatalog/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7160': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexDirect/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexDirect/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7161': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexImageResizer/2.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexImageResizer/2.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7162': {
-			userAgent: 'Castabot/0.1 (+http://topixtream.com/)',
-			metadata: {
-				uaFamily: 'Castabot',
-				uaName: 'Castabot/0.1',
-				uaUrl: '',
-				uaCompany: 'Ronan Amicel',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Castabot'
-			}
-		},
-		'7163': {
-			userAgent: 'ShowyouBot (http://showyou.com/crawler)',
-			metadata: {
-				uaFamily: 'ShowyouBot',
-				uaName: 'ShowyouBot',
-				uaUrl: '',
-				uaCompany: 'Remixation, Inc',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ShowyouBot'
-			}
-		},
-		'7164': {
-			userAgent: 'Mozilla/5.0 (compatible; DCPbot/1.1; +http://domains.checkparams.com/)',
-			metadata: {
-				uaFamily: 'DCPbot',
-				uaName: 'DCPbot/1.1',
-				uaUrl: 'http://domains.checkparams.com/',
-				uaCompany: 'CheckParams',
-				uaCompanyUrl: 'http://checkparams.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DCPbot'
-			}
-		},
-		'7172': {
-			userAgent: 'Yandex.Server/2009.5',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'Yandex.Server/2009.5',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7173': {
-			userAgent: 'Yandex.Server/2010.9',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'Yandex.Server/2010.9',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7177': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-5-amd64; java 1.6.0_18; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7178': {
-			userAgent: 'Acoon v4.10.4 (www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon v4.10.4',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7211': {
-			userAgent: 'Mozilla/5.0 (compatible; MetaJobBot; http://www.metajob.at/crawler)',
-			metadata: {
-				uaFamily: 'MetaJobBot',
-				uaName: 'MetaJobBot',
-				uaUrl: 'http://www.metajob.at/the/crawler',
-				uaCompany: 'Dr. Manfred Schauer',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetaJobBot'
-			}
-		},
-		'7217': {
-			userAgent: 'RADaR-Bot/Nutch-1.3 (http://radar-bot.com/)',
-			metadata: {
-				uaFamily: 'RADaR-Bot',
-				uaName: 'RADaR-Bot',
-				uaUrl: 'http://radar-bot.com/',
-				uaCompany: 'Queryable Corp',
-				uaCompanyUrl: 'http://www.inboxq.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=RADaR-Bot'
-			}
-		},
-		'7225': {
-			userAgent: 'Mozilla/5.0 (compatible; heritrix/3.1.1-SNAPSHOT-20120116.200628 +http://www.archive.org/details/archive.org_bot)',
-			metadata: {
-				uaFamily: 'heritrix',
-				uaName: 'heritrix/3.1.1',
-				uaUrl: 'http://www.archive.org/details/archive.org_bot',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=heritrix'
-			}
-		},
-		'7230': {
-			userAgent: 'AddThis.com robot tech.support@clearspring.com',
-			metadata: {
-				uaFamily: 'AddThis.com',
-				uaName: 'AddThis.com robot',
-				uaUrl: '',
-				uaCompany: 'Clearspring Technologies, Inc.',
-				uaCompanyUrl: 'http://www.clearspring.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AddThis.com'
-			}
-		},
-		'7238': {
-			userAgent: 'Mozilla/5.0 (compatible; Netseer crawler/2.0; +http://www.netseer.com/crawler.html; crawler@netseer.com)',
-			metadata: {
-				uaFamily: 'Netseer',
-				uaName: 'Netseer crawler/2.0',
-				uaUrl: 'http://www.netseer.com/crawler.html',
-				uaCompany: 'NetSeer, Inc.',
-				uaCompanyUrl: 'http://www.netseer.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Netseer'
-			}
-		},
-		'7243': {
-			userAgent: 'Mozilla/5.0 (compatible; EventGuruBot/1.0; +http://www.eventguru.com/spider.html)',
-			metadata: {
-				uaFamily: 'EventGuruBot',
-				uaName: 'EventGuruBot/1.0',
-				uaUrl: 'http://www.eventguru.com/spider.html',
-				uaCompany: 'Matt Wells',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EventGuruBot'
-			}
-		},
-		'7252': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.26-2-amd64; java 1.6.0_18; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7253': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows Server 2008 6.0; java 1.7.0_03; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7258': {
-			userAgent: 'SAMSUNG-SGH-E250/1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 UP.Browser/6.2.3.3.c.1.101 (GUI) MMP/2.0 (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot-Mobile/2.1',
-				uaUrl: 'http://googlewebmastercentral.blogspot.com/2011/12/introducing-smartphone-googlebot-mobile.html',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'7259': {
-			userAgent: 'DoCoMo/2.0 N905i(c100;TB;W24H16) (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot-Mobile/2.1',
-				uaUrl: 'http://googlewebmastercentral.blogspot.com/2011/12/introducing-smartphone-googlebot-mobile.html',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'7260': {
-			userAgent: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 (compatible; Googlebot-Mobile/2.1; +http://www.google.com/bot.html)',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot-Mobile/2.1',
-				uaUrl: 'http://googlewebmastercentral.blogspot.com/2011/12/introducing-smartphone-googlebot-mobile.html',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'7263': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.6.0_24; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7265': {
-			userAgent: 'Acoon v4.10.5 (www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'Acoon v4.10.5',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7267': {
-			userAgent: 'SemrushBot/0.92',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.92',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'7278': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-custom; java 1.6.0_26; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7285': {
-			userAgent: 'OpenAcoon v4.10.5 (www.openacoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'OpenAcoon v4.10.5',
-				uaUrl: 'http://www.openacoon.de/',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7300': {
-			userAgent: 'Mozilla/5.0 (compatible; gofind; +http://govid.mobi/bot.php)',
-			metadata: {
-				uaFamily: 'YioopBot',
-				uaName: 'gofind',
-				uaUrl: 'http://govid.mobi/bot.php',
-				uaCompany: 'Chris Pollett',
-				uaCompanyUrl: 'http://pollett.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YioopBot'
-			}
-		},
-		'7303': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.1.10-hardened; java 1.7.0_03-icedtea; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7304': {
-			userAgent: 'yacybot (freeworld/global; x86_64 Mac OS X 10.6.8; java 1.6.0_29; Asia/ru) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7305': {
-			userAgent: 'yacybot (freeworld/global; i386 Linux 2.6.32-39-generic-pae; java 1.6.0_20; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7306': {
-			userAgent: 'yacybot (freeworld/global; i386 Linux 3.0.0-17-generic-pae; java 1.6.0_23; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7307': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-5-amd64; java 1.6.0_26; Atlantic/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7308': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.0.0-17-generic; java 1.6.0_23; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7309': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.13-1-ARCH; java 1.7.0_03-icedtea; Europe/fr) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7317': {
-			userAgent: 'Twikle/1.0 , http://twikle.com , contact@twikle.com',
-			metadata: {
-				uaFamily: 'Twikle',
-				uaName: 'Twikle/1.0',
-				uaUrl: '',
-				uaCompany: 'NATEVIA',
-				uaCompanyUrl: 'http://www.natevia.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Twikle'
-			}
-		},
-		'7320': {
-			userAgent: 'Mozilla/5.0 (compatible; aiHitBot/1.1; +http://www.aihit.com/)',
-			metadata: {
-				uaFamily: 'aiHitBot',
-				uaName: 'aiHitBot/1.1',
-				uaUrl: '',
-				uaCompany: 'aiHit Ltd.',
-				uaCompanyUrl: 'http://aihit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aiHitBot'
-			}
-		},
-		'7321': {
-			userAgent: 'AcoonBot/4.10.5 (+http://www.acoon.de)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'AcoonBot/4.10.5',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7322': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.0.0-17-generic; java 1.6.0_23; America/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7323': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-5-xen-amd64; java 1.6.0_18; Europe/fr) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7324': {
-			userAgent: 'yacybot (freeworld/global; i386 Linux 3.0.0-17-generic; java 1.6.0_23; America/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7325': {
-			userAgent: 'yacybot (freeworld/global; x86 Windows 7 6.1; java 1.6.0_31; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7333': {
-			userAgent: 'Mozilla/5.0 (compatible; AhrefsBot/3.0; +http://ahrefs.com/robot/)',
-			metadata: {
-				uaFamily: 'AhrefsBot',
-				uaName: 'AhrefsBot/3.0',
-				uaUrl: 'http://ahrefs.com/robot/',
-				uaCompany: 'Ahrefs.com',
-				uaCompanyUrl: 'http://ahrefs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AhrefsBot'
-			}
-		},
-		'7338': {
-			userAgent: 'findlinks/2.2 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.2',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'7340': {
-			userAgent: 'Mozilla/5.0 (compatible; Blekkobot; ScoutJet; +http://blekko.com/about/blekkobot)',
-			metadata: {
-				uaFamily: 'Blekkobot',
-				uaName: 'Blekkobot',
-				uaUrl: 'http://blekko.com/about/blekkobot',
-				uaCompany: 'Blekko Inc.',
-				uaCompanyUrl: 'http://blekko.com/',
-				uaIcon: 'bot_blekkobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Blekkobot'
-			}
-		},
-		'7343': {
-			userAgent: 'Mozilla/5.0 (compatible; Mail.RU/2.0)',
-			metadata: {
-				uaFamily: 'Mail.Ru bot',
-				uaName: 'Mail.RU/2.0',
-				uaUrl: 'http://go.mail.ru/help/robots',
-				uaCompany: 'Mail.Ru Group',
-				uaCompanyUrl: 'http://corp.mail.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mail.Ru bot'
-			}
-		},
-		'7347': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-40-server; java 1.6.0_20; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7348': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.1.10-1-desktop; java 1.6.0_22; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7349': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.38-14-generic; java 1.6.0_22; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7362': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-23-generic; java 1.6.0_24; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7363': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.6.0_31; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7364': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-21-generic; java 1.7.0_03-icedtea; America/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7365': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-2-amd64; java 1.6.0_24; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7366': {
-			userAgent: 'Mozilla/5.0 (compatible; AcoonBot/4.10.6; +http://www.acoon.de/robot.asp)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'AcoonBot/4.10.6',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7369': {
-			userAgent: 'Mozilla/5.0 (compatible; CareerBot/1.1; +http://www.career-x.de/bot.html)',
-			metadata: {
-				uaFamily: 'CareerBot',
-				uaName: 'CareerBot/1.1',
-				uaUrl: 'http://www.career-x.de/bot.html',
-				uaCompany: 'career-x GmbH',
-				uaCompanyUrl: 'http://www.career-x.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CareerBot'
-			}
-		},
-		'7373': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-40-generic; java 1.6.0_20; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7374': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows Server 2008 R2 6.1; java 1.6.0_31; America/pt) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7375': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.4.3; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.4.3',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'7380': {
-			userAgent: 'Mozilla/5.0 (compatible; HomeTags/1.0; +http://www.hometags.nl/bot)',
-			metadata: {
-				uaFamily: 'HomeTags',
-				uaName: 'HomeTags/1.0',
-				uaUrl: 'http://www.hometags.nl/bot',
-				uaCompany: 'HomeTags.nl',
-				uaCompanyUrl: 'http://www.hometags.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HomeTags'
-			}
-		},
-		'7381': {
-			userAgent: 'Y!J-BRJ/YATS crawler (http://listing.yahoo.co.jp/support/faq/int/other/other_001.html)',
-			metadata: {
-				uaFamily: 'Yahoo! JAPAN',
-				uaName: 'Y!J-BRJ/YATS',
-				uaUrl: 'http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'bot_yahoo!slurp.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo! JAPAN'
-			}
-		},
-		'7384': {
-			userAgent: 'Mozilla/5.0 (compatible; UnisterBot; crawler@unister.de)',
-			metadata: {
-				uaFamily: 'UnisterBot',
-				uaName: 'UnisterBot',
-				uaUrl: '',
-				uaCompany: 'Unister Holding GmbH',
-				uaCompanyUrl: 'http://www.unister.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=UnisterBot'
-			}
-		},
-		'7387': {
-			userAgent: 'findlinks/2.0.5 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.0.5',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'7399': {
-			userAgent: 'findlinks/2.5 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.5',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'7402': {
-			userAgent: 'KeywordDensityRobot/0.8 (http://www.seocentro.com/tools/search-engines/keyword-density.html)',
-			metadata: {
-				uaFamily: 'KeywordDensityRobot',
-				uaName: 'KeywordDensityRobot/0.8',
-				uaUrl: 'http://www.seocentro.com/tools/seo/keyword-density.html',
-				uaCompany: 'SeoCentro',
-				uaCompanyUrl: 'http://www.seocentro.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=KeywordDensityRobot'
-			}
-		},
-		'7404': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.38-8-generic; java 1.6.0_22; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7405': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.1.10-1.9-default; java 1.6.0_24; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7406': {
-			userAgent: 'Mozilla/5.0 (compatible; MSIE or Firefox mutant; not on Windows server; + http://tab.search.daum.net/aboutWebSearch.html) Daumoa/3.0',
-			metadata: {
-				uaFamily: 'Daumoa',
-				uaName: 'Daumoa/3.0',
-				uaUrl: 'http://tab.search.daum.net/aboutWebSearch_en.html',
-				uaCompany: 'Daum Communications Corp.',
-				uaCompanyUrl: 'http://info.daum.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Daumoa'
-			}
-		},
-		'7409': {
-			userAgent: 'Mozilla/5.0 (compatible; AcoonBot/4.10.7; +http://www.acoon.de/robot.asp)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'AcoonBot/4.10.7',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7411': {
-			userAgent: 'coccoc',
-			metadata: {
-				uaFamily: 'coccoc',
-				uaName: 'coccoc',
-				uaUrl: 'http://help.coccoc.com/',
-				uaCompany: 'Coc Coc',
-				uaCompanyUrl: 'http://coccoc.vn/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=coccoc'
-			}
-		},
-		'7414': {
-			userAgent: 'Influencebot/0.9; (Automatic classification of websites; http://www.influencebox.com/; info@influencebox.com)',
-			metadata: {
-				uaFamily: 'Influencebot',
-				uaName: 'Influencebot/0.9',
-				uaUrl: 'http://www.influencebox.com/',
-				uaCompany: 'Frank',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Influencebot'
-			}
-		},
-		'7420': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-5-amd64; java 1.6.0_18; US/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7421': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows Server 2008 R2 6.1; java 1.6.0_29; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7422': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.6.0_31; America/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7423': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.3.4-1-ARCH; java 1.6.0_24; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7424': {
-			userAgent: 'RyzeCrawler/1.1.1 ( http://www.domain2day.nl/crawler/)',
-			metadata: {
-				uaFamily: 'RyzeCrawler',
-				uaName: 'RyzeCrawler/1.1.1',
-				uaUrl: 'http://www.domain2day.nl/crawler/',
-				uaCompany: 'Domain2day',
-				uaCompanyUrl: 'http://www.domain2day.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=RyzeCrawler'
-			}
-		},
-		'7426': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexFavicons/1.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexFavicons/1.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7427': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexAntivirus/2.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexAntivirus/2.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7428': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexVideo/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexVideo/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7429': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexMedia/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexMedia/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7430': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexBlogs/0.99; robot; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexBlogs/0.99',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7433': {
-			userAgent: 'Mozilla/5.0 (compatible; YandexZakladki/3.0; +http://yandex.com/bots)',
-			metadata: {
-				uaFamily: 'YandexBot',
-				uaName: 'YandexZakladki/3.0',
-				uaUrl: 'http://yandex.com/bots',
-				uaCompany: 'Yandex LLC',
-				uaCompanyUrl: 'http://company.yandex.com/',
-				uaIcon: 'bot_Yandex.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YandexBot'
-			}
-		},
-		'7437': {
-			userAgent: 'Mozilla/5.0 (compatible; PaperLiBot/2.1; http://support.paper.li/entries/20023257-what-is-paper-li)',
-			metadata: {
-				uaFamily: 'PaperLiBot',
-				uaName: 'PaperLiBot/2.1',
-				uaUrl: 'http://support.paper.li/entries/20023257-what-is-paper-li',
-				uaCompany: 'Paper.li',
-				uaCompanyUrl: 'http://paper.li/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PaperLiBot'
-			}
-		},
-		'7438': {
-			userAgent: 'WeSEE:Search/0.1 (Alpha, http://www.wesee.com/en/support/bot/)',
-			metadata: {
-				uaFamily: 'WeSEE:Search',
-				uaName: 'WeSEE:Search/0.1 (Alpha)',
-				uaUrl: 'http://www.wesee.com/en/support/bot/',
-				uaCompany: 'WeSEE Ltd',
-				uaCompanyUrl: 'http://www.wesee.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WeSEE:Search'
-			}
-		},
-		'7442': {
-			userAgent: 'Mozilla/5.0 (compatible; bnf.fr_bot; +http://www.bnf.fr/fr/outils/a.dl_web_capture_robot.html)',
-			metadata: {
-				uaFamily: 'bnf.fr_bot',
-				uaName: 'bnf.fr_bot',
-				uaUrl: 'http://www.bnf.fr/fr/outils/a.dl_web_capture_robot.html',
-				uaCompany: 'Bibliothe`que nationale de France',
-				uaCompanyUrl: 'http://www.bnf.fr/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bnf.fr_bot'
-			}
-		},
-		'7458': {
-			userAgent: 'Mozilla/5.0 (compatible; AcoonBot/4.10.8; +http://www.acoon.de/robot.asp)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'AcoonBot/4.10.8',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7462': {
-			userAgent: 'Mozilla/5.0 (compatible; aiHitBot-BP/1.1; +http://www.aihit.com/)',
-			metadata: {
-				uaFamily: 'aiHitBot',
-				uaName: 'aiHitBot-BP/1.1',
-				uaUrl: '',
-				uaCompany: 'aiHit Ltd',
-				uaCompanyUrl: 'http://aihit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aiHitBot'
-			}
-		},
-		'7467': {
-			userAgent: 'findlinks/2.6 (+http://wortschatz.uni-leipzig.de/findlinks/)',
-			metadata: {
-				uaFamily: 'findlinks',
-				uaName: 'findlinks/2.6',
-				uaUrl: 'http://wortschatz.uni-leipzig.de/findlinks/',
-				uaCompany: 'Universit\xe4t Leipzig',
-				uaCompanyUrl: 'http://www.uni-leipzig.de/',
-				uaIcon: 'bot_findlinks.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=findlinks'
-			}
-		},
-		'7469': {
-			userAgent: 'Mozilla/5.0 (compatible; UptimeRobot/1.0; http://www.uptimerobot.com/)',
-			metadata: {
-				uaFamily: 'UptimeRobot',
-				uaName: 'UptimeRobot/1.0',
-				uaUrl: 'http://www.uptimerobot.com/',
-				uaCompany: 'Umut Muhaddisoglu, Daniel Rimille',
-				uaCompanyUrl: 'http://www.webresourcesdepot.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=UptimeRobot'
-			}
-		},
-		'7477': {
-			userAgent: 'Mozilla/5.0 (compatible; AcoonBot/4.11.0; +http://www.acoon.de/robot.asp)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'AcoonBot/4.11.0',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7494': {
-			userAgent: 'Mozilla/5.0 (compatible; Finderbots finder bot; +http://wiki.github.com/bixo/bixo/bixocrawler; bixo-dev@yahoogroups.com)',
-			metadata: {
-				uaFamily: 'bixocrawler',
-				uaName: 'bixo',
-				uaUrl: 'http://wiki.github.com/bixo/bixo/bixocrawler',
-				uaCompany: 'Bixo Labs',
-				uaCompanyUrl: 'http://openbixo.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bixocrawler'
-			}
-		},
-		'7510': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-41-server; java 1.6.0_26; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7511': {
-			userAgent: 'yacybot (freeworld/global; i386 Linux 3.2.0-23-generic-pae; java 1.7.0_03; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7512': {
-			userAgent: 'yacybot (freeworld/global; x86 Windows 2003 5.2; java 1.6.0_32; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7513': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-24-generic; java 1.6.0_24; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7525': {
-			userAgent: 'MIA DEV/search:robot/0.0.1 (This is the MIA Bot - crawling for mia research project. If you feel unhappy and do not want to be visited by our crawler send an email to spider@neofonie.de; http://spider.neofonie.de; spider@neofonie.de)',
-			metadata: {
-				uaFamily: 'MIA Bot',
-				uaName: 'MIA Bot',
-				uaUrl: 'http://spider.neofonie.de',
-				uaCompany: 'Neofonie GmbH',
-				uaCompanyUrl: 'http://www.neofonie.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MIA Bot'
-			}
-		},
-		'7542': {
-			userAgent: 'infohelfer/1.1.0 (http://www.infohelfer.de/)',
-			metadata: {
-				uaFamily: 'Infohelfer',
-				uaName: 'Infohelfer/1.0',
-				uaUrl: 'http://www.infohelfer.de/crawler.php',
-				uaCompany: 'ITam GmbH',
-				uaCompanyUrl: 'http://www.itam-gmbh.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Infohelfer'
-			}
-		},
-		'7544': {
-			userAgent: 'Mozilla/5.0 (compatible; AcoonBot/4.11.1; +http://www.acoon.de/robot.asp)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'AcoonBot/4.11.1',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: 'http://www.acoon.de/',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'7548': {
-			userAgent: 'coccoc/1.0 ()',
-			metadata: {
-				uaFamily: 'coccoc',
-				uaName: 'coccoc/1.0',
-				uaUrl: 'http://help.coccoc.com/',
-				uaCompany: 'Coc Coc',
-				uaCompanyUrl: 'http://coccoc.vn/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=coccoc'
-			}
-		},
-		'7563': {
-			userAgent: 'Mozilla/5.0 (compatible; OpenindexSpider/Nutch-1.5-dev; +http://www.openindex.io/en/webmasters/spider.html)',
-			metadata: {
-				uaFamily: 'OpenindexSpider',
-				uaName: 'OpenindexSpider',
-				uaUrl: 'http://www.openindex.io/en/webmasters/spider.html',
-				uaCompany: 'Openindex B.V.',
-				uaCompanyUrl: 'http://www.openindex.io/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenindexSpider'
-			}
-		},
-		'7577': {
-			userAgent: 'wsAnalyzer/1.0; ++http://www.wsanalyzer.com/bot.html',
-			metadata: {
-				uaFamily: 'wsAnalyzer',
-				uaName: 'wsAnalyzer/1.0',
-				uaUrl: 'http://www.wsanalyzer.com/bot.html',
-				uaCompany: 'wsAnalyzer.com',
-				uaCompanyUrl: 'http://www.wsanalyzer.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=wsAnalyzer'
-			}
-		},
-		'7579': {
-			userAgent: 'Mozilla/5.0 (compatible; AhrefsBot/3.1; +http://ahrefs.com/robot/)',
-			metadata: {
-				uaFamily: 'AhrefsBot',
-				uaName: 'AhrefsBot/3.1',
-				uaUrl: 'http://ahrefs.com/robot/',
-				uaCompany: 'Ahrefs.com',
-				uaCompanyUrl: 'http://ahrefs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AhrefsBot'
-			}
-		},
-		'7596': {
-			userAgent: 'Wotbox/2.01 (+http://www.wotbox.com/bot/)',
-			metadata: {
-				uaFamily: 'Wotbox',
-				uaName: 'Wotbox/2.01',
-				uaUrl: 'http://www.wotbox.com/bot/',
-				uaCompany: 'Wotbox Team',
-				uaCompanyUrl: 'http://www.wotbox.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Wotbox'
-			}
-		},
-		'7605': {
-			userAgent: 'Mozilla/5.0 (compatible; ProCogBot/1.0; +http://www.procog.com/spider.html)',
-			metadata: {
-				uaFamily: 'ProCogBot',
-				uaName: 'ProCogBot/1.0',
-				uaUrl: 'http://www.procog.com/spider.html',
-				uaCompany: 'ProCog.com',
-				uaCompanyUrl: 'http://www.procog.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ProCogBot'
-			}
-		},
-		'7606': {
-			userAgent: 'Mozilla/5.0 (compatible; OpenindexSpider; +http://www.openindex.io/en/webmasters/spider.html)',
-			metadata: {
-				uaFamily: 'OpenindexSpider',
-				uaName: 'OpenindexSpider',
-				uaUrl: 'http://www.openindex.io/en/webmasters/spider.html',
-				uaCompany: 'Openindex B.V.',
-				uaCompanyUrl: 'http://www.openindex.io/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenindexSpider'
-			}
-		},
-		'7622': {
-			userAgent: 'Woko 3.0',
-			metadata: {
-				uaFamily: 'Woko',
-				uaName: 'Woko 3.0',
-				uaUrl: 'http://www.woko.cz/akce.phtml?ukaz=osluzbe',
-				uaCompany: 'Internet Info, s.r.o.',
-				uaCompanyUrl: 'http://www.iinfo.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Woko'
-			}
-		},
-		'7624': {
-			userAgent: 'EasyBib AutoCite (http://content.easybib.com/autocite/)',
-			metadata: {
-				uaFamily: 'EasyBib AutoCite',
-				uaName: 'EasyBib AutoCite',
-				uaUrl: 'http://content.easybib.com/autocite/',
-				uaCompany: 'ImagineEasy Solutions.',
-				uaCompanyUrl: 'http://www.imagineeasy.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=EasyBib AutoCite'
-			}
-		},
-		'7625': {
-			userAgent: 'Mozilla/5.0 (compatible;  Page2RSS/0.7; +http://page2rss.com/)',
-			metadata: {
-				uaFamily: 'Page2RSS',
-				uaName: 'Page2RSS/0.7',
-				uaUrl: '',
-				uaCompany: 'Page Two Technologies LLC',
-				uaCompanyUrl: 'http://page2rss.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Page2RSS'
-			}
-		},
-		'7628': {
-			userAgent: 'Woko robot 3.0',
-			metadata: {
-				uaFamily: 'Woko',
-				uaName: 'Woko robot 3.0',
-				uaUrl: 'http://www.woko.cz/akce.phtml?ukaz=osluzbe',
-				uaCompany: 'Internet Info, s.r.o.',
-				uaCompanyUrl: 'http://www.iinfo.cz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Woko'
-			}
-		},
-		'7632': {
-			userAgent: 'Mozilla/5.0 (compatible; Infohelfer/1.2.0; +http://www.infohelfer.de/crawler.php)',
-			metadata: {
-				uaFamily: 'Infohelfer',
-				uaName: 'Infohelfer/1.2.0',
-				uaUrl: 'http://www.infohelfer.de/crawler.php',
-				uaCompany: 'ITam GmbH',
-				uaCompanyUrl: 'http://www.itam-gmbh.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Infohelfer'
-			}
-		},
-		'7634': {
-			userAgent: 'Mozilla/5.0 (compatible; WebNL; +http://www.web.nl/webmasters/spider.html; helpdesk@web.nl)',
-			metadata: {
-				uaFamily: 'WebNL',
-				uaName: 'WebNL',
-				uaUrl: 'http://www.web.nl/webmasters/spider.html',
-				uaCompany: 'CRIO B.V.',
-				uaCompanyUrl: 'http://www.crio.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebNL'
-			}
-		},
-		'7651': {
-			userAgent: 'Y!J-BSC/1.0 crawler (http://help.yahoo.co.jp/help/jp/blog-search/)',
-			metadata: {
-				uaFamily: 'Yahoo! JAPAN',
-				uaName: 'Y!J-BSC/1.0',
-				uaUrl: 'http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html',
-				uaCompany: 'Yahoo Japan Corporation',
-				uaCompanyUrl: 'http://www.yahoo.co.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo! JAPAN'
-			}
-		},
-		'7655': {
-			userAgent: 'Mozilla/5.0 (compatible; proximic; +http://www.proximic.com/info/spider.php)',
-			metadata: {
-				uaFamily: 'proximic',
-				uaName: 'proximic',
-				uaUrl: 'http://www.proximic.com/info/spider.php',
-				uaCompany: 'Proximic, Inc.',
-				uaCompanyUrl: 'http://www.proximic.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=proximic'
-			}
-		},
-		'7671': {
-			userAgent: 'Sogou Web Spider',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'Sogou web spider',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'7675': {
-			userAgent: 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.0; trendictionbot0.5.0; trendiction search; http://www.trendiction.de/bot; please let us know of any problems; web at trendiction.com) Gecko/20071127 Firefox/3.0.0.11',
-			metadata: {
-				uaFamily: 'trendictionbot ',
-				uaName: 'trendictionbot0.5.0',
-				uaUrl: 'http://www.trendiction.de/bot',
-				uaCompany: 'Trendiction S.A.',
-				uaCompanyUrl: 'http://www.trendiction.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=trendictionbot '
-			}
-		},
-		'7676': {
-			userAgent: 'ichiro/3.0 (http://search.goo.ne.jp/option/use/sub4/sub4-1/)',
-			metadata: {
-				uaFamily: 'ichiro',
-				uaName: 'ichiro/3.0',
-				uaUrl: 'http://search.goo.ne.jp/option/use/sub4/sub4-1/',
-				uaCompany: 'NTT-Resonant Inc.',
-				uaCompanyUrl: 'http://www.nttr.co.jp/',
-				uaIcon: 'bot_ichiro.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ichiro'
-			}
-		},
-		'7696': {
-			userAgent: 'bot-pge.chlooe.com/1.0.0 (+http://www.chlooe.com/)',
-			metadata: {
-				uaFamily: 'bot-pge.chlooe.com',
-				uaName: 'bot-pge.chlooe.com/1.0.0',
-				uaUrl: 'http://bot-pge.chlooe.com/',
-				uaCompany: 'Chlooe.com',
-				uaCompanyUrl: 'http://www.chlooe.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bot-pge.chlooe.com'
-			}
-		},
-		'7697': {
-			userAgent: 'Mozilla/5.0(compatible; Sosospider/2.0; +http://help.soso.com/webspider.htm)',
-			metadata: {
-				uaFamily: 'Sosospider',
-				uaName: 'Sosospider/2.0',
-				uaUrl: 'http://help.soso.com/webspider.htm',
-				uaCompany: 'Tencent, Inc.',
-				uaCompanyUrl: 'http://www.tencent.com/',
-				uaIcon: 'bot_soso.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sosospider'
-			}
-		},
-		'7717': {
-			userAgent: 'Mozilla/5.0 (compatible; GrapeshotCrawler/2.0; +http://www.grapeshot.co.uk/crawler.php)',
-			metadata: {
-				uaFamily: 'GrapeshotCrawler',
-				uaName: 'GrapeshotCrawler/2.0',
-				uaUrl: 'http://www.grapeshot.co.uk/crawler.php',
-				uaCompany: 'Grapeshot Limited',
-				uaCompanyUrl: 'http://www.grapeshot.co.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GrapeshotCrawler'
-			}
-		},
-		'7718': {
-			userAgent: 'Mozilla/5.0 (compatible; grapeFX/0.9; crawler@grapeshot.co.uk',
-			metadata: {
-				uaFamily: 'GrapeshotCrawler',
-				uaName: 'grapeFX/0.9',
-				uaUrl: 'http://www.grapeshot.co.uk/crawler.php',
-				uaCompany: 'Grapeshot Limited',
-				uaCompanyUrl: 'http://www.grapeshot.co.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GrapeshotCrawler'
-			}
-		},
-		'7726': {
-			userAgent: 'Mozilla/5.0 (compatible; Infohelfer/1.3.0; +http://www.infohelfer.de/crawler.php)',
-			metadata: {
-				uaFamily: 'Infohelfer',
-				uaName: 'Infohelfer/1.3.0',
-				uaUrl: 'http://www.infohelfer.de/crawler.php',
-				uaCompany: 'ITam GmbH',
-				uaCompanyUrl: 'http://www.itam-gmbh.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Infohelfer'
-			}
-		},
-		'7727': {
-			userAgent: 'coccoc/1.0 (http://help.coccoc.vn/)',
-			metadata: {
-				uaFamily: 'coccoc',
-				uaName: 'coccoc/1.0',
-				uaUrl: 'http://help.coccoc.com/',
-				uaCompany: 'Coc Coc',
-				uaCompanyUrl: 'http://coccoc.vn/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=coccoc'
-			}
-		},
-		'7729': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.6.0_25; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'7732': {
-			userAgent: 'Bad-Neighborhood Link Analyzer (http://www.bad-neighborhood.com/)',
-			metadata: {
-				uaFamily: 'Bad-Neighborhood',
-				uaName: 'Bad-Neighborhood Link Analyzer',
-				uaUrl: 'http://www.bad-neighborhood.com/text-link-tool.htm',
-				uaCompany: 'Michael VanDeMar',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Bad-Neighborhood'
-			}
-		},
-		'7733': {
-			userAgent: 'Bad Neighborhood Header Detector (http://www.bad-neighborhood.com/header_detector.php)',
-			metadata: {
-				uaFamily: 'Bad-Neighborhood',
-				uaName: 'Bad Neighborhood Header Detector',
-				uaUrl: 'http://www.bad-neighborhood.com/header_detector.php',
-				uaCompany: 'Michael VanDeMar',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Bad-Neighborhood'
-			}
-		},
-		'7747': {
-			userAgent: 'Whoismindbot/1.0 (+http://www.whoismind.com/bot.html)',
-			metadata: {
-				uaFamily: 'Whoismindbot',
-				uaName: 'Whoismindbot/1.0',
-				uaUrl: 'http://www.whoismind.com/bot.html',
-				uaCompany: 'WhoisMind',
-				uaCompanyUrl: 'http://www.whoismind.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Whoismindbot'
-			}
-		},
-		'7748': {
-			userAgent: 'webinatorbot 1.0; +http://www.webinator.de',
-			metadata: {
-				uaFamily: 'webinatorbot',
-				uaName: 'webinatorbot 1.0',
-				uaUrl: '',
-				uaCompany: 'HighSignal UG',
-				uaCompanyUrl: 'http://www.highsignal.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=webinatorbot'
-			}
-		},
-		'7754': {
-			userAgent: 'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm',
-			metadata: {
-				uaFamily: 'bingbot',
-				uaName: 'bingbot/2.0',
-				uaUrl: 'http://www.bing.com/webmaster/help/which-crawlers-does-bing-use-8c184ec0',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bingbot'
-			}
-		},
-		'7757': {
-			userAgent: 'search.KumKie.com',
-			metadata: {
-				uaFamily: 'search.KumKie.com',
-				uaName: 'search.KumKie.com',
-				uaUrl: '',
-				uaCompany: 'Gifts Next Day',
-				uaCompanyUrl: 'http://giftsnextday.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=search.KumKie.com'
-			}
-		},
-		'7764': {
-			userAgent: 'Mozilla/5.0 (compatible; DripfeedBot/2.0; +http://dripfeedbookmark.com/bot.html',
-			metadata: {
-				uaFamily: 'DripfeedBot',
-				uaName: 'DripfeedBot/2.0',
-				uaUrl: 'http://dripfeedbookmark.com/bot.html',
-				uaCompany: 'dripfeedbookmark.com',
-				uaCompanyUrl: 'http://dripfeedbookmark.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=DripfeedBot'
-			}
-		},
-		'7776': {
-			userAgent: 'Mozilla/5.0 (compatible; SemrushBot/0.95; +http://www.semrush.com/bot.html)',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.95',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'7780': {
-			userAgent: 'ZumBot/1.0 (ZUM Search; http://help.zum.com/inquiry)',
-			metadata: {
-				uaFamily: 'ZumBot',
-				uaName: 'ZumBot/1.0',
-				uaUrl: 'http://help.zum.com/inquiry',
-				uaCompany: 'ZUMinternet Corp',
-				uaCompanyUrl: 'http://www.zuminternet.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZumBot'
-			}
-		},
-		'7784': {
-			userAgent: 'Pixray-Seeker/2.0 (Pixray-Seeker; http://www.pixray.com/pixraybot; crawler@pixray.com)',
-			metadata: {
-				uaFamily: 'Pixray-Seeker',
-				uaName: 'Pixray-Seeker/2.0',
-				uaUrl: 'http://www.pixray.com/pixraybot',
-				uaCompany: 'PIXRAY GmbH.',
-				uaCompanyUrl: 'http://www.pixray.com/',
-				uaIcon: 'bot_PixraySeeker.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Pixray-Seeker'
-			}
-		},
-		'7790': {
-			userAgent: 'Mozilla/5.0 (compatible; discoverybot/2.0; +http://discoveryengine.com/discoverybot.html)',
-			metadata: {
-				uaFamily: 'discoverybot',
-				uaName: 'discoverybot/2.0',
-				uaUrl: 'http://discoveryengine.com/discoverybot.html',
-				uaCompany: 'discoveryengine.com.',
-				uaCompanyUrl: 'http://www.discoveryengine.com/',
-				uaIcon: 'bot_discobot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=discoverybot'
-			}
-		},
-		'7799': {
-			userAgent: 'rogerbot/1.0 (http://www.seomoz.org/dp/rogerbot, rogerbot-crawler@seomoz.org)',
-			metadata: {
-				uaFamily: 'rogerbot',
-				uaName: 'rogerbot/1.0',
-				uaUrl: 'http://moz.com/help/pro/what-is-rogerbot-',
-				uaCompany: 'SEOmoz, Inc.',
-				uaCompanyUrl: 'http://moz.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=rogerbot'
-			}
-		},
-		'7816': {
-			userAgent: 'Mozilla/5.0 (compatible; Plukkie/1.5; http://www.botje.com/plukkie.htm)',
-			metadata: {
-				uaFamily: 'Plukkie',
-				uaName: 'Plukkie/1.3',
-				uaUrl: 'http://www.botje.com/plukkie.htm',
-				uaCompany: 'botje.com',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Plukkie'
-			}
-		},
-		'7819': {
-			userAgent: 'www.integromedb.org/Crawler',
-			metadata: {
-				uaFamily: 'IntegromeDB',
-				uaName: 'IntegromeDB',
-				uaUrl: 'http://www.integromedb.org/Crawler',
-				uaCompany: 'BiologicalNetworks',
-				uaCompanyUrl: 'http://www.biologicalnetworks.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IntegromeDB'
-			}
-		},
-		'7832': {
-			userAgent: 'drupact/0.7; http://www.arocom.de/drupact',
-			metadata: {
-				uaFamily: 'drupact',
-				uaName: 'drupact/0.7',
-				uaUrl: 'http://www.arocom.de/drupact',
-				uaCompany: 'arocom GmbH',
-				uaCompanyUrl: 'http://www.arocom.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=drupact'
-			}
-		},
-		'7833': {
-			userAgent: 'peerindex/0.1 (http://www.peerindex.com/; crawler AT peerindex DOT com)',
-			metadata: {
-				uaFamily: 'peerindex',
-				uaName: 'peerindex/0.1',
-				uaUrl: '',
-				uaCompany: 'PeerIndex',
-				uaCompanyUrl: 'http://www.peerindex.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=peerindex'
-			}
-		},
-		'7841': {
-			userAgent: 'WillyBot/1.1 (http://www.willyfogg.com/info/willybot)',
-			metadata: {
-				uaFamily: 'WillyBot',
-				uaName: 'WillyBot/1.1',
-				uaUrl: 'http://willyfogg.com/info/willybot',
-				uaCompany: 'WillyFogg.com ',
-				uaCompanyUrl: 'http://willyfogg.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WillyBot'
-			}
-		},
-		'7843': {
-			userAgent: 'Mozilla/5.0 (compatible; AhrefsBot/4.0; +http://ahrefs.com/robot/)',
-			metadata: {
-				uaFamily: 'AhrefsBot',
-				uaName: 'AhrefsBot/4.0',
-				uaUrl: 'http://ahrefs.com/robot/',
-				uaCompany: 'Ahrefs.com',
-				uaCompanyUrl: 'http://ahrefs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AhrefsBot'
-			}
-		},
-		'7854': {
-			userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.21 (KHTML, like Gecko) Chrome/19.0.1042.0 Safari/535.21 PagePeeker/2.1; +http://pagepeeker.com/robots/',
-			metadata: {
-				uaFamily: 'PagePeeker',
-				uaName: 'PagePeeker/2.1',
-				uaUrl: 'http://pagepeeker.com/robots',
-				uaCompany: 'PagePeeker.com',
-				uaCompanyUrl: 'http://pagepeeker.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PagePeeker'
-			}
-		},
-		'7856': {
-			userAgent: 'netEstate NE Crawler (+http://www.website-datenbank.de/)',
-			metadata: {
-				uaFamily: 'netEstate Crawler',
-				uaName: 'netEstate NE Crawler',
-				uaUrl: '',
-				uaCompany: 'netEstate GmbH',
-				uaCompanyUrl: 'http://www.netestate.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=netEstate Crawler'
-			}
-		},
-		'7888': {
-			userAgent: 'MeMoNewsBot/2.0 (http://www.memonews.com/en/crawler)',
-			metadata: {
-				uaFamily: 'MeMoNewsBot',
-				uaName: 'MeMoNewsBot/2.0',
-				uaUrl: 'http://www.memonews.com/en/crawler',
-				uaCompany: 'MeMo News AG',
-				uaCompanyUrl: 'http://www.memonews.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MeMoNewsBot'
-			}
-		},
-		'7889': {
-			userAgent: 'Mozilla/5.0 (compatible; pmoz.info ODP link checker; +http://pmoz.info/doc/botinfo.htm)',
-			metadata: {
-				uaFamily: 'pmoz.info ODP link checker',
-				uaName: 'pmoz.info ODP link checker',
-				uaUrl: 'http://pmoz.info/doc/botinfo.htm',
-				uaCompany: 'PlantRob',
-				uaCompanyUrl: 'http://www.robsplants.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=pmoz.info ODP link checker'
-			}
-		},
-		'7912': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/3.1; +http://www.seoprofiler.com/bot )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/3.1',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'7927': {
-			userAgent: 'Mozilla/5.0 (compatible; CompSpyBot/1.0; +http://www.compspy.com/spider.html)',
-			metadata: {
-				uaFamily: 'CompSpyBot',
-				uaName: 'CompSpyBot/1.0',
-				uaUrl: 'http://www.compspy.com/spider.html',
-				uaCompany: 'compspy.com',
-				uaCompanyUrl: 'http://www.compspy.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CompSpyBot'
-			}
-		},
-		'7959': {
-			userAgent: 'Mozilla/5.0 (compatible; Peepowbot/1.0; +http://www.peepow.com/bot.php)',
-			metadata: {
-				uaFamily: 'Peepowbot',
-				uaName: 'Peepowbot/1.0',
-				uaUrl: 'http://www.peepow.com/bot.php',
-				uaCompany: 'peepow.com',
-				uaCompanyUrl: 'http://peepow.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Peepowbot'
-			}
-		},
-		'7975': {
-			userAgent: 'HubSpot Connect 1.0 (http://dev.hubspot.com/)',
-			metadata: {
-				uaFamily: 'HubSpot Connect',
-				uaName: 'HubSpot Connect 1.0',
-				uaUrl: '',
-				uaCompany: 'HubSpot Inc.',
-				uaCompanyUrl: 'http://www.hubspot.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HubSpot Connect'
-			}
-		},
-		'7984': {
-			userAgent: 'Mozilla/5.0 (compatible; Mail.RU_Bot/2.0)',
-			metadata: {
-				uaFamily: 'Mail.Ru bot',
-				uaName: 'Mail.RU_Bot/2.0',
-				uaUrl: 'http://go.mail.ru/help/robots',
-				uaCompany: 'Mail.Ru Group',
-				uaCompanyUrl: 'http://corp.mail.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mail.Ru bot'
-			}
-		},
-		'7995': {
-			userAgent: 'Mozilla/5.0 (compatible; IstellaBot/1.10.2 +http://www.tiscali.it/)',
-			metadata: {
-				uaFamily: 'IstellaBot',
-				uaName: 'IstellaBot/1.10.2',
-				uaUrl: '',
-				uaCompany: 'Tiscali Italia S.p.a',
-				uaCompanyUrl: 'http://www.tiscali.it/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=IstellaBot'
-			}
-		},
-		'8061': {
-			userAgent: 'Pixray-Seeker/2.0 (http://www.pixray.com/pixraybot; crawler@pixray.com)',
-			metadata: {
-				uaFamily: 'Pixray-Seeker',
-				uaName: 'Pixray-Seeker/2.0',
-				uaUrl: 'http://www.pixray.com/pixraybot',
-				uaCompany: 'PIXRAY GmbH.',
-				uaCompanyUrl: 'http://www.pixray.com/',
-				uaIcon: 'bot_PixraySeeker.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Pixray-Seeker'
-			}
-		},
-		'8066': {
-			userAgent: 'Mozilla/5.0 (compatible; SearchmetricsBot; http://www.searchmetrics.com/en/searchmetrics-bot/)',
-			metadata: {
-				uaFamily: 'SearchmetricsBot',
-				uaName: 'SearchmetricsBot',
-				uaUrl: 'http://www.searchmetrics.com/en/searchmetrics-bot/',
-				uaCompany: 'Searchmetrics GmbH',
-				uaCompanyUrl: 'http://www.searchmetrics.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SearchmetricsBot'
-			}
-		},
-		'8083': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-3-amd64; java 1.6.0_24; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'8096': {
-			userAgent: 'Mozilla/5.0 (compatible; Genieo/1.0 http://www.genieo.com/webfilter.html)',
-			metadata: {
-				uaFamily: 'Genieo Web filter',
-				uaName: 'Genieo/1.0',
-				uaUrl: 'http://www.genieo.com/webfilter.html',
-				uaCompany: 'Genieo',
-				uaCompanyUrl: 'http://www.genieo.com',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Genieo Web filter'
-			}
-		},
-		'8107': {
-			userAgent: 'yacybot (freeworld/global; i386 Linux 2.6.32-5-686; java 1.6.0_18; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'8114': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.6.0_23; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'8131': {
-			userAgent: 'facebookplatform/1.0 (+http://developers.facebook.com)',
-			metadata: {
-				uaFamily: 'facebookplatform',
-				uaName: 'facebookplatform/1.0',
-				uaUrl: 'http://en.wikipedia.org/wiki/Facebook_Platform',
-				uaCompany: 'Facebook',
-				uaCompanyUrl: 'http://www.facebook.com/',
-				uaIcon: 'bot_facebook.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=facebookplatform'
-			}
-		},
-		'8134': {
-			userAgent: 'Mozilla/5.0 (compatible; Infohelfer/1.3.3; +http://www.infohelfer.de/crawler.php)',
-			metadata: {
-				uaFamily: 'Infohelfer',
-				uaName: 'Infohelfer/1.3.3',
-				uaUrl: 'http://www.infohelfer.de/crawler.php',
-				uaCompany: 'ITam GmbH',
-				uaCompanyUrl: 'http://www.itam-gmbh.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Infohelfer'
-			}
-		},
-		'8138': {
-			userAgent: 'Mozilla/5.0 (compatible; HomeTags/1.0;  http://www.hometags.nl/bot)',
-			metadata: {
-				uaFamily: 'HomeTags',
-				uaName: 'HomeTags/1.0',
-				uaUrl: 'http://www.hometags.nl/bot',
-				uaCompany: 'HomeTags.nl',
-				uaCompanyUrl: 'http://www.hometags.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HomeTags'
-			}
-		},
-		'8170': {
-			userAgent: 'Mozilla/5.0 (compatible; Qseero; +http://www.q0.com)',
-			metadata: {
-				uaFamily: 'Qseero',
-				uaName: 'Qseero',
-				uaUrl: '',
-				uaCompany: 'Qseero, Inc.',
-				uaCompanyUrl: 'http://q0.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Qseero'
-			}
-		},
-		'8179': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-32-generic; java 1.6.0_24; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'8184': {
-			userAgent: 'Mozilla/5.0 (compatible; Esribot/1.0; http://www.esrihu.hu/)',
-			metadata: {
-				uaFamily: 'Esribot',
-				uaName: 'Esribot/1.0',
-				uaUrl: '',
-				uaCompany: 'ESRI Magyarorsz\xe1g Kft.',
-				uaCompanyUrl: 'http://www.esrihu.hu/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Esribot'
-			}
-		},
-		'8191': {
-			userAgent: 'wscheck.com/1.0.0 (+http://wscheck.com/)',
-			metadata: {
-				uaFamily: 'wscheck.com',
-				uaName: 'wscheck.com/1.0.0',
-				uaUrl: '',
-				uaCompany: 'AsiaWS',
-				uaCompanyUrl: 'http://asiaws.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=wscheck.com'
-			}
-		},
-		'8192': {
-			userAgent: 'bot.wsowner.com/1.0.0 (+http://wsowner.com/)',
-			metadata: {
-				uaFamily: 'bot.wsowner.com',
-				uaName: 'bot.wsowner.com/1.0.0',
-				uaUrl: '',
-				uaCompany: 'AsiaWS',
-				uaCompanyUrl: 'http://asiaws.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bot.wsowner.com'
-			}
-		},
-		'8208': {
-			userAgent: 'Yepi/1.0 (NHN Corp.; http://help.naver.com/robots/)',
-			metadata: {
-				uaFamily: 'NaverBot',
-				uaName: 'Yepi/1.0',
-				uaUrl: 'http://help.naver.com/robots/',
-				uaCompany: 'NHN Corporation',
-				uaCompanyUrl: 'http://www.nhncorp.com/',
-				uaIcon: 'bot_NaverBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NaverBot'
-			}
-		},
-		'8247': {
-			userAgent: 'Mozilla/5.0 (compatible; Mail.RU_Bot/2.0; +http://go.mail.ru/help/robots)',
-			metadata: {
-				uaFamily: 'Mail.Ru bot',
-				uaName: 'Mail.RU_Bot/2.0',
-				uaUrl: 'http://go.mail.ru/help/robots',
-				uaCompany: 'Mail.Ru Group',
-				uaCompanyUrl: 'http://corp.mail.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mail.Ru bot'
-			}
-		},
-		'8297': {
-			userAgent: 'yacybot (freeworld-global; amd64 Linux 3.2.0-4-amd64; java 1.6.0_24; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'8300': {
-			userAgent: 'Mozilla/5.0 (compatible; emefgebot/beta; +http://emefge.de/bot.html)',
-			metadata: {
-				uaFamily: 'emefgebot',
-				uaName: 'emefgebot/beta',
-				uaUrl: 'http://emefge.de/bot.html',
-				uaCompany: 'Bayern Anzeiger UG',
-				uaCompanyUrl: 'http://bayernanzeiger.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=emefgebot'
-			}
-		},
-		'8318': {
-			userAgent: 'Mozilla/5.0 (compatible; YioopBot; +http://173.13.143.74/bot.php)',
-			metadata: {
-				uaFamily: 'YioopBot',
-				uaName: 'YioopBot',
-				uaUrl: 'http://www.yioop.com/bot.php',
-				uaCompany: 'Chris Pollett',
-				uaCompanyUrl: 'http://pollett.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=YioopBot'
-			}
-		},
-		'8329': {
-			userAgent: 'Sogou web spider/4.0',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'Sogou web spider/4.0',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'8397': {
-			userAgent: 'Y!J-BRJ/YATS crawler (http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html)',
-			metadata: {
-				uaFamily: 'Yahoo! JAPAN',
-				uaName: 'Y!J-BRJ/YATS',
-				uaUrl: 'http://help.yahoo.co.jp/help/jp/search/indexing/indexing-15.html',
-				uaCompany: 'Yahoo Japan Corporation',
-				uaCompanyUrl: 'http://www.yahoo.co.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Yahoo! JAPAN'
-			}
-		},
-		'8406': {
-			userAgent: 'yacybot (freeworld-global; amd64 Linux 3.2.0-35-generic; java 1.7.0_09; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'8429': {
-			userAgent: 'OpenWebSpider v0.1.4 (http://www.openwebspider.org/)',
-			metadata: {
-				uaFamily: 'OpenWebSpider',
-				uaName: 'OpenWebSpider v0.1.4',
-				uaUrl: 'http://www.openwebspider.org/',
-				uaCompany: 'Stefano Alimonti',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=OpenWebSpider'
-			}
-		},
-		'8487': {
-			userAgent: 'emefgebot/beta (+http://emefge.de/bot.html)',
-			metadata: {
-				uaFamily: 'emefgebot',
-				uaName: 'emefgebot/beta',
-				uaUrl: 'http://emefge.de/bot.html',
-				uaCompany: 'Bayern Anzeiger UG',
-				uaCompanyUrl: 'http://bayernanzeiger.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=emefgebot'
-			}
-		},
-		'8574': {
-			userAgent: 'coccoc/1.0 (http://help.coccoc.com/)',
-			metadata: {
-				uaFamily: 'coccoc',
-				uaName: 'coccoc/1.0',
-				uaUrl: 'http://help.coccoc.com/',
-				uaCompany: 'Coc Coc',
-				uaCompanyUrl: 'http://coccoc.vn/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=coccoc'
-			}
-		},
-		'8586': {
-			userAgent: 'ExB Language Crawler 2.1.5 (+http://www.exb.de/crawler)',
-			metadata: {
-				uaFamily: 'ExB Language Crawler',
-				uaName: 'ExB Language Crawler 2.1.5',
-				uaUrl: 'http://www.exb.de/crawler/',
-				uaCompany: 'ExB Communication Systems GmbH',
-				uaCompanyUrl: 'http://www.exb.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ExB Language Crawler'
-			}
-		},
-		'8590': {
-			userAgent: 'Mozilla/4.0 (compatible;  Vagabondo/4.0; webcrawler at wise-guys dot nl; http://webagent.wise-guys.nl/; http://www.wise-guys.nl/)',
-			metadata: {
-				uaFamily: 'Vagabondo',
-				uaName: 'Vagabondo/4.0',
-				uaUrl: 'http://webagent.wise-guys.nl/',
-				uaCompany: 'WiseGuys Internet BV',
-				uaCompanyUrl: 'http://www.wise-guys.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Vagabondo'
-			}
-		},
-		'8607': {
-			userAgent: 'ExB Language Crawler 2.1.2 (+http://www.exb.de/crawler)',
-			metadata: {
-				uaFamily: 'ExB Language Crawler',
-				uaName: 'ExB Language Crawler 2.1.2',
-				uaUrl: 'http://www.exb.de/crawler/',
-				uaCompany: 'ExB Communication Systems GmbH',
-				uaCompanyUrl: 'http://www.exb.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ExB Language Crawler'
-			}
-		},
-		'8694': {
-			userAgent: 'Mozilla/5.0 (compatible; special_archiver/3.1.1 +http://www.archive.org/details/archive.org_bot)',
-			metadata: {
-				uaFamily: 'archive.org_bot',
-				uaName: 'special_archiver/3.1.1',
-				uaUrl: 'http://www.archive.org/details/archive.org_bot',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=archive.org_bot'
-			}
-		},
-		'8743': {
-			userAgent: 'Mozilla/5.0 (compatible; NLNZ_IAHarvester2013 +http://natlib.govt.nz/about-us/current-initiatives/web-harvest-2013)',
-			metadata: {
-				uaFamily: 'NLNZ_IAHarvester2013',
-				uaName: 'NLNZ_IAHarvester2013',
-				uaUrl: 'http://natlib.govt.nz/publishers-and-authors/web-harvesting/2013-nz-web-harvest',
-				uaCompany: 'National Library of New Zealand',
-				uaCompanyUrl: 'http://natlib.govt.nz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=NLNZ_IAHarvester2013'
-			}
-		},
-		'8833': {
-			userAgent: 'Zookabot/2.5;++http://zookabot.com',
-			metadata: {
-				uaFamily: 'Zookabot',
-				uaName: 'Zookabot/2.5',
-				uaUrl: 'http://zookabot.com/',
-				uaCompany: 'Hwacha ApS',
-				uaCompanyUrl: 'http://hwacha.dk/',
-				uaIcon: 'bot_Zookabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Zookabot'
-			}
-		},
-		'8866': {
-			userAgent: 'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm) SitemapProbe',
-			metadata: {
-				uaFamily: 'bingbot',
-				uaName: 'bingbot SitemapProbe',
-				uaUrl: 'http://www.bing.com/webmaster/help/which-crawlers-does-bing-use-8c184ec0',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bingbot'
-			}
-		},
-		'8902': {
-			userAgent: 'Mozilla/5.0 (compatible; ZumBot/1.0; http://help.zum.com/inquiry)',
-			metadata: {
-				uaFamily: 'ZumBot',
-				uaName: 'ZumBot/1.0',
-				uaUrl: 'http://help.zum.com/inquiry',
-				uaCompany: 'ZUMinternet Corp',
-				uaCompanyUrl: 'http://www.zuminternet.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ZumBot'
-			}
-		},
-		'9010': {
-			userAgent: 'Mozilla/5.0 (compatible; 4SeoHuntBot; +http://4seohunt.biz/about.html)',
-			metadata: {
-				uaFamily: '4seohuntBot',
-				uaName: '4seohuntBot',
-				uaUrl: 'http://4seohunt.biz/about.html',
-				uaCompany: '4seohunt.biz',
-				uaCompanyUrl: 'http://4seohunt.biz/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=4seohuntBot'
-			}
-		},
-		'9020': {
-			userAgent: 'fastbot crawler beta 2.0 (+http://www.fastbot.de)',
-			metadata: {
-				uaFamily: 'fastbot crawler',
-				uaName: 'fastbot crawler beta 2.0',
-				uaUrl: 'http://www.fastbot.de/',
-				uaCompany: 'http://www.pagedesign.de/',
-				uaCompanyUrl: 'Pagedesign GmbH',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=fastbot crawler'
-			}
-		},
-		'9065': {
-			userAgent: 'fastbot.de crawler 2.0 beta (http://www.fastbot.de)',
-			metadata: {
-				uaFamily: 'fastbot crawler',
-				uaName: 'fastbot.de crawler beta 2.0',
-				uaUrl: 'http://www.fastbot.de/',
-				uaCompany: 'http://www.pagedesign.de/',
-				uaCompanyUrl: 'Pagedesign GmbH',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=fastbot crawler'
-			}
-		},
-		'9116': {
-			userAgent: 'Mozilla/5.0+(compatible;+PiplBot;++http://www.pipl.com/bot/)',
-			metadata: {
-				uaFamily: 'PiplBot',
-				uaName: 'PiplBot',
-				uaUrl: 'http://pipl.com/bot/',
-				uaCompany: 'pipl.com',
-				uaCompanyUrl: 'http://pipl.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=PiplBot'
-			}
-		},
-		'9165': {
-			userAgent: 'rogerbot/1.0 (http://www.seomoz.org/dp/rogerbot, rogerbot-crawler+shiny@seomoz.org)',
-			metadata: {
-				uaFamily: 'rogerbot',
-				uaName: 'rogerbot/1.0',
-				uaUrl: 'http://moz.com/help/pro/what-is-rogerbot-',
-				uaCompany: 'SEOmoz, Inc.',
-				uaCompanyUrl: 'http://moz.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=rogerbot'
-			}
-		},
-		'9239': {
-			userAgent: 'Grahambot/0.1 (+http://www.sunaga-lab.com/graham-bot)',
-			metadata: {
-				uaFamily: 'Grahambot',
-				uaName: 'Grahambot/0.1',
-				uaUrl: 'http://www.sunaga-lab.com/graham-bot',
-				uaCompany: 'Sunagarabo',
-				uaCompanyUrl: 'http://sunagae.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Grahambot'
-			}
-		},
-		'9240': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.5.0-27-generic; java 1.7.0_03; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'9262': {
-			userAgent: 'SolomonoBot/1.04 (http://www.solomono.ru)',
-			metadata: {
-				uaFamily: 'SolomonoBot',
-				uaName: 'SolomonoBot/1.04',
-				uaUrl: 'http://solomono.ru/about/',
-				uaCompany: 'Solomono',
-				uaCompanyUrl: 'http://solomono.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SolomonoBot'
-			}
-		},
-		'9280': {
-			userAgent: 'Mozilla/5.0 (compatible; SemrushBot/0.96.2; +http://www.semrush.com/bot.html)',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.96.2',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'9288': {
-			userAgent: 'bl.uk_lddc_bot/3.1.1 (+http://www.bl.uk/aboutus/legaldeposit/websites/websites/faqswebmaster/index.html)',
-			metadata: {
-				uaFamily: 'bl.uk_lddc_bot',
-				uaName: 'bl.uk_lddc_bot/3.1.1',
-				uaUrl: 'http://www.bl.uk/aboutus/legaldeposit/websites/websites/faqswebmaster/index.html',
-				uaCompany: 'British Library',
-				uaCompanyUrl: 'http://www.bl.uk/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bl.uk_lddc_bot'
-			}
-		},
-		'9298': {
-			userAgent: 'Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20110814 Firefox/6.0 Google (+https://developers.google.com/+/web/snippet/)',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Googlebot snippet',
-				uaUrl: 'https://developers.google.com/+/web/snippet/',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'9332': {
-			userAgent: 'BacklinkCrawler V (http://www.backlinktest.com/crawler.html)',
-			metadata: {
-				uaFamily: 'BacklinkCrawler',
-				uaName: 'BacklinkCrawler V',
-				uaUrl: 'http://www.backlinktest.com/crawler.html',
-				uaCompany: '2.0Promotion GbR',
-				uaCompanyUrl: 'http://2.0promotion.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BacklinkCrawler'
-			}
-		},
-		'9346': {
-			userAgent: 'Automattic Analytics Crawler/0.1; http://wordpress.com/crawler/',
-			metadata: {
-				uaFamily: 'Automattic Analytics Crawler',
-				uaName: 'Automattic Analytics Crawler/0.1',
-				uaUrl: 'http://wordpress.com/crawler/',
-				uaCompany: 'Automattic Inc.',
-				uaCompanyUrl: 'http://automattic.com/',
-				uaIcon: 'AutomatticCrawler.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Automattic Analytics Crawler'
-			}
-		},
-		'9389': {
-			userAgent: 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6 Ara.com.tr AraBot 1.0',
-			metadata: {
-				uaFamily: 'AraBot',
-				uaName: 'AraBot 1.0',
-				uaUrl: '',
-				uaCompany: ' ARA ?leti\u015fim Telekom\xfcnikasyon ?nternet Al?\u015fveri\u015f Reklam Tic. Ltd. \u015eti.',
-				uaCompanyUrl: 'http://www.ara.com.tr/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AraBot'
-			}
-		},
-		'9410': {
-			userAgent: 'Aboundex/0.3 (http://www.aboundex.com/crawler/)',
-			metadata: {
-				uaFamily: 'Aboundexbot',
-				uaName: 'Aboundexbot/0.3',
-				uaUrl: 'http://www.aboundex.com/crawler/',
-				uaCompany: 'Aboundex.com',
-				uaCompanyUrl: 'http://www.aboundex.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Aboundexbot'
-			}
-		},
-		'9427': {
-			userAgent: 'Peeplo Screenshot Bot/0.20 ( abuse at peeplo dot_com )',
-			metadata: {
-				uaFamily: 'Peeplo Screenshot Bot',
-				uaName: 'Peeplo Screenshot Bot/0.20',
-				uaUrl: '',
-				uaCompany: 'MOQU ADV Srl',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Peeplo Screenshot Bot'
-			}
-		},
-		'9453': {
-			userAgent: 'CCBot/2.0',
-			metadata: {
-				uaFamily: 'CCBot',
-				uaName: 'CCBot/2.0',
-				uaUrl: 'http://commoncrawl.org/research/',
-				uaCompany: 'CommonCrawl Foundation',
-				uaCompanyUrl: 'http://www.commoncrawl.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CCBot'
-			}
-		},
-		'9455': {
-			userAgent: 'Mozilla/5.0 (compatible; ProCogSEOBot/1.0; +http://www.procog.com/ )',
-			metadata: {
-				uaFamily: 'ProCogSEOBot',
-				uaName: 'ProCogSEOBot/1.0',
-				uaUrl: '',
-				uaCompany: 'ProCog.com',
-				uaCompanyUrl: 'http://www.procog.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ProCogSEOBot'
-			}
-		},
-		'9540': {
-			userAgent: 'MetaURI API/2.0 +metauri.com',
-			metadata: {
-				uaFamily: 'MetaURI API',
-				uaName: 'MetaURI API/2.0',
-				uaUrl: '',
-				uaCompany: 'stateless systems',
-				uaCompanyUrl: 'http://statelesssystems.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetaURI API'
-			}
-		},
-		'9577': {
-			userAgent: 'Dlvr.it/1.0 (http://dlvr.it/)',
-			metadata: {
-				uaFamily: 'Dlvr.it/1.0',
-				uaName: 'Dlvr.it/1.0',
-				uaUrl: 'http://support.dlvr.it/entries/23499527-How-do-I-block-dlvr-it-from-retrieving-the-feeds-on-my-site-',
-				uaCompany: 'dlvr.it',
-				uaCompanyUrl: 'http://dlvr.it/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Dlvr.it/1.0'
-			}
-		},
-		'9652': {
-			userAgent: 'Mozilla/5.0 (compatible; GeliyooBot/1.0; +http://www.geliyoo.com/)',
-			metadata: {
-				uaFamily: 'GeliyooBot',
-				uaName: 'GeliyooBot/1.0',
-				uaUrl: '',
-				uaCompany: 'Geliyoo Bili\u015fim Ar-Ge Tic. Ltd. \u015eti.',
-				uaCompanyUrl: 'http://www.geliyoobilisim.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GeliyooBot'
-			}
-		},
-		'9653': {
-			userAgent: 'ExB Language Crawler 2.1.1 (+http://www.exb.de/crawler)',
-			metadata: {
-				uaFamily: 'ExB Language Crawler',
-				uaName: 'ExB Language Crawler 2.1.1',
-				uaUrl: 'http://www.exb.de/crawler/',
-				uaCompany: 'ExB Communication Systems GmbH',
-				uaCompanyUrl: 'http://www.exb.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ExB Language Crawler'
-			}
-		},
-		'9655': {
-			userAgent: 'Mozilla/5.0 (compatible; 200PleaseBot/1.0; +http://www.200please.com/bot)',
-			metadata: {
-				uaFamily: '200PleaseBot',
-				uaName: '200PleaseBot/1.0',
-				uaUrl: 'http://www.200please.com/bot',
-				uaCompany: '200please.com',
-				uaCompanyUrl: 'http://www.200please.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=200PleaseBot'
-			}
-		},
-		'9673': {
-			userAgent: 'yacybot (webportal-global; amd64 Windows 7 6.1; java 1.7.0_04; America/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'9675': {
-			userAgent: 'Mozilla/5.0 (compatible; Linux x86_64; Mail.RU_Bot/2.0; +http://go.mail.ru/help/robots)',
-			metadata: {
-				uaFamily: 'Mail.Ru bot',
-				uaName: 'Mail.RU_Bot/2.0',
-				uaUrl: 'http://go.mail.ru/help/robots',
-				uaCompany: 'Mail.Ru Group',
-				uaCompanyUrl: 'http://corp.mail.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Mail.Ru bot'
-			}
-		},
-		'9681': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-4-amd64; java 1.6.0_27; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'9682': {
-			userAgent: 'yacybot (freeworld/global; i386 Linux 3.4.2-linode44; java 1.6.0_27; America/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'9691': {
-			userAgent: 'Mozilla/5.0 (compatible; GeliyooBot/1.0beta; +http://www.geliyoo.com/)',
-			metadata: {
-				uaFamily: 'GeliyooBot',
-				uaName: 'GeliyooBot/1.0beta',
-				uaUrl: '',
-				uaCompany: 'Geliyoo Bili\u015fim Ar-Ge Tic. Ltd. \u015eti.',
-				uaCompanyUrl: 'http://www.geliyoobilisim.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=GeliyooBot'
-			}
-		},
-		'9694': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.8.0-21-generic; java 1.6.0_27; Pacific/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'9717': {
-			userAgent: 'Sogou web spider/4.0l-2m!',
-			metadata: {
-				uaFamily: 'sogou spider',
-				uaName: 'Sogou web spider/4.0l-2m!',
-				uaUrl: 'http://www.sogou.com/docs/help/webmasters.htm#07',
-				uaCompany: 'SOGOU.COM',
-				uaCompanyUrl: 'http://www.sogou.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=sogou spider'
-			}
-		},
-		'9737': {
-			userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko; Google Web Preview) Chrome/22.0.1229 Safari/537.4',
-			metadata: {
-				uaFamily: 'Googlebot',
-				uaName: 'Google Web Preview',
-				uaUrl: 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1062498',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'bot_googlebot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Googlebot'
-			}
-		},
-		'9781': {
-			userAgent: 'Mozilla/5.0 (compatible; uMBot-FC/1.0; mailto: crawling@ubermetrics-technologies.com)',
-			metadata: {
-				uaFamily: 'uMBot',
-				uaName: 'uMBot-FC/1.0',
-				uaUrl: '',
-				uaCompany: 'uberMetrics Technologies GmbH',
-				uaCompanyUrl: 'http://www.ubermetrics-technologies.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=uMBot'
-			}
-		},
-		'9784': {
-			userAgent: 'Mozilla/5.0 (compatible; coccoc/1.0; +http://help.coccoc.com/)',
-			metadata: {
-				uaFamily: 'coccoc',
-				uaName: 'coccoc/1.0',
-				uaUrl: 'http://help.coccoc.com/',
-				uaCompany: 'Coc Coc',
-				uaCompanyUrl: 'http://coccoc.vn/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=coccoc'
-			}
-		},
-		'9832': {
-			userAgent: 'Mozilla/5.0 (compatible; Mozilla; +http://wiki.github.com/bixo/bixo/bixocrawler; bixo-dev@yahoogroups.com)',
-			metadata: {
-				uaFamily: 'bixocrawler',
-				uaName: 'bixocrawler',
-				uaUrl: 'http://wiki.github.com/bixo/bixo/bixocrawler',
-				uaCompany: 'Bixo Labs',
-				uaCompanyUrl: 'http://openbixo.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bixocrawler'
-			}
-		},
-		'9839': {
-			userAgent: 'Mozilla/5.0 (compatible; aiHitBot/2.7; +http://www.aihit.com/)',
-			metadata: {
-				uaFamily: 'aiHitBot',
-				uaName: 'aiHitBot/2.7',
-				uaUrl: '',
-				uaCompany: 'aiHit Ltd',
-				uaCompanyUrl: 'http://aihit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aiHitBot'
-			}
-		},
-		'9852': {
-			userAgent: 'Mozilla/5.0 (compatible; GigaBot/1.0; +http://www.gigablast.com/ )',
-			metadata: {
-				uaFamily: 'Gigabot',
-				uaName: 'Gigabot/1.0',
-				uaUrl: 'http://www.gigablast.com/spider.html',
-				uaCompany: 'Gigablast Inc',
-				uaCompanyUrl: 'http://www.gigablast.com/',
-				uaIcon: 'bot_gigabot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Gigabot'
-			}
-		},
-		'9868': {
-			userAgent: 'CirrusExplorer/1.1 (http://www.cireu.com/explorer.php)',
-			metadata: {
-				uaFamily: 'CirrusExplorer',
-				uaName: 'CirrusExplorer/1.1',
-				uaUrl: 'http://www.cireu.com/explorer.php',
-				uaCompany: 'cireu.com',
-				uaCompanyUrl: 'http://www.cireu.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CirrusExplorer'
-			}
-		},
-		'9874': {
-			userAgent: 'Mozilla/5.0 (compatible; uMBot-LN/1.0; mailto: crawling@ubermetrics-technologies.com)',
-			metadata: {
-				uaFamily: 'uMBot',
-				uaName: 'uMBot-LN/1.0',
-				uaUrl: '',
-				uaCompany: 'uberMetrics Technologies GmbH',
-				uaCompanyUrl: 'http://www.ubermetrics-technologies.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=uMBot'
-			}
-		},
-		'9875': {
-			userAgent: 'Crowsnest/0.5 (+http://www.crowsnest.tv/)',
-			metadata: {
-				uaFamily: 'Crowsnest',
-				uaName: 'Crowsnest/0.5',
-				uaUrl: '',
-				uaCompany: 'Gocro, Inc.',
-				uaCompanyUrl: 'http://www.gocro.jp/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Crowsnest'
-			}
-		},
-		'9877': {
-			userAgent: 'QuerySeekerSpider ( http://queryseeker.com/bot.html )',
-			metadata: {
-				uaFamily: 'QuerySeekerSpider',
-				uaName: 'QuerySeekerSpider',
-				uaUrl: 'http://queryseeker.com/bot.html',
-				uaCompany: 'QueryEye Inc.',
-				uaCompanyUrl: 'http://queryeye.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=QuerySeekerSpider'
-			}
-		},
-		'9905': {
-			userAgent: 'ownCloud Server Crawler',
-			metadata: {
-				uaFamily: 'ownCloud Server Crawler',
-				uaName: 'ownCloud Server Crawler',
-				uaUrl: '',
-				uaCompany: 'ownCloud comunity',
-				uaCompanyUrl: 'http://owncloud.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ownCloud Server Crawler'
-			}
-		},
-		'9918': {
-			userAgent: 'Mozilla/5.0 (compatible; rogerBot/1.0; UrlCrawler; http://www.seomoz.org/dp/rogerbot)',
-			metadata: {
-				uaFamily: 'rogerbot',
-				uaName: 'rogerbot/1.0',
-				uaUrl: 'http://moz.com/help/pro/what-is-rogerbot-',
-				uaCompany: 'SEOmoz, Inc.',
-				uaCompanyUrl: 'http://moz.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=rogerbot'
-			}
-		},
-		'9925': {
-			userAgent: 'Mozilla/5.0 (compatible; SemrushBot/0.96.3; +http://www.semrush.com/bot.html)',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.96.3',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'9949': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.8.0-23-generic; java 1.6.0_27; Pacific/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10008': {
-			userAgent: 'BLEXBot',
-			metadata: {
-				uaFamily: 'BLEXBot',
-				uaName: 'BLEXBot',
-				uaUrl: 'http://webmeup-crawler.com/',
-				uaCompany: 'WebMeUp',
-				uaCompanyUrl: 'http://webmeup.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BLEXBot'
-			}
-		},
-		'10035': {
-			userAgent: 'Mozilla/5.0 (compatible; CloudServerMarketSpider/1.0; +http://www.cloudservermarket.com/spider.html)',
-			metadata: {
-				uaFamily: 'CloudServerMarketSpider',
-				uaName: 'CloudServerMarketSpider/1.0',
-				uaUrl: 'http://www.cloudservermarket.com/spider.html',
-				uaCompany: 'CloudServerMarket.com',
-				uaCompanyUrl: 'http://www.cloudservermarket.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CloudServerMarketSpider'
-			}
-		},
-		'10057': {
-			userAgent: 'Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup.com/crawler.html)',
-			metadata: {
-				uaFamily: 'BLEXBot',
-				uaName: 'BLEXBot/1.0',
-				uaUrl: 'http://webmeup-crawler.com/',
-				uaCompany: 'WebMeUp',
-				uaCompanyUrl: 'http://webmeup.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BLEXBot'
-			}
-		},
-		'10073': {
-			userAgent: 'Mozilla/5.0(compatible;Sosospider/2.0;+http://help.soso.com/webspider.htm)',
-			metadata: {
-				uaFamily: 'Sosospider',
-				uaName: 'Sosospider/2.0',
-				uaUrl: 'http://help.soso.com/webspider.htm',
-				uaCompany: 'Tencent, Inc.',
-				uaCompanyUrl: 'http://www.tencent.com/',
-				uaIcon: 'bot_soso.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Sosospider'
-			}
-		},
-		'10078': {
-			userAgent: 'Mozilla/5.0 (compatible; firmilybot/0.3; +http://www.firmily.com/bot.php',
-			metadata: {
-				uaFamily: 'firmilybot',
-				uaName: 'firmilybot/0.3',
-				uaUrl: 'http://www.firmily.com/bot.php',
-				uaCompany: 'Firmily',
-				uaCompanyUrl: 'http://www.firmily.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=firmilybot'
-			}
-		},
-		'10084': {
-			userAgent: 'MetaHeadersBot (+http://www.metaheaders.com/bot.html)',
-			metadata: {
-				uaFamily: 'MetaHeadersBot',
-				uaName: 'MetaHeadersBot',
-				uaUrl: 'http://www.metaheaders.net/bot.html',
-				uaCompany: 'metaheaders.net',
-				uaCompanyUrl: 'http://www.metaheaders.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MetaHeadersBot'
-			}
-		},
-		'10101': {
-			userAgent: 'Mozilla/5.0 (compatible; meanpathbot/1.0; +http://www.meanpath.com/meanpathbot.html)',
-			metadata: {
-				uaFamily: 'meanpathbot',
-				uaName: 'meanpathbot/1.0',
-				uaUrl: 'http://www.meanpath.com/meanpathbot.html',
-				uaCompany: 'meanpath, Inc.',
-				uaCompanyUrl: 'https://meanpath.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=meanpathbot'
-			}
-		},
-		'10107': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.7.0_09; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10108': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows XP 5.2; java 1.7.0_04; America/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10126': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.8.13-gentoo; java 1.7.0_21; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10140': {
-			userAgent: 'Mozilla/5.0 (compatible; AMZNKAssocBot/4.0 +http://affiliate-program.amazon.com)',
-			metadata: {
-				uaFamily: 'AMZNKAssocBot',
-				uaName: 'AMZNKAssocBot/4.0',
-				uaUrl: 'https://affiliate-program.amazon.com/gp/associates/help/t21/a14',
-				uaCompany: 'Amazon.com, Inc.',
-				uaCompanyUrl: 'http://www.amazon.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AMZNKAssocBot'
-			}
-		},
-		'10182': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 2.6.32-49-server; java 1.6.0_27; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10228': {
-			userAgent: 'Mozilla/5.0 (compatible; AcoonBot/4.12.1; +http://www.acoon.de/robot.asp)',
-			metadata: {
-				uaFamily: 'AcoonBot',
-				uaName: 'AcoonBot/4.12.1',
-				uaUrl: 'http://www.acoon.de/robot.asp',
-				uaCompany: 'Acoon GmbH',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_Acoon.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AcoonBot'
-			}
-		},
-		'10237': {
-			userAgent: 'Mozilla/5.0 (compatible; linkdexbot/2.0; +http://www.linkdex.com/about/bots/)',
-			metadata: {
-				uaFamily: 'linkdexbot',
-				uaName: 'linkdexbot/2.0',
-				uaUrl: 'http://www.linkdex.com/about/bots/',
-				uaCompany: 'Linkdex Limited.',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=linkdexbot'
-			}
-		},
-		'10241': {
-			userAgent: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b',
-			metadata: {
-				uaFamily: 'BingPreview',
-				uaName: 'BingPreview/1.0b',
-				uaUrl: 'http://www.bing.com/blogs/site_blogs/b/webmaster/archive/2012/10/26/page-snapshots-in-bing-windows-8-app-to-bring-new-crawl-traffic-to-sites.aspx',
-				uaCompany: 'Microsoft Corporation',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'bot_msnbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BingPreview'
-			}
-		},
-		'10246': {
-			userAgent: 'Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)',
-			metadata: {
-				uaFamily: 'AhrefsBot',
-				uaName: 'AhrefsBot/5.0',
-				uaUrl: 'http://ahrefs.com/robot/',
-				uaCompany: 'Ahrefs.com',
-				uaCompanyUrl: 'http://ahrefs.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=AhrefsBot'
-			}
-		},
-		'10293': {
-			userAgent: 'Mozilla/5.0 (compatible; SeznamBot/3.1-test1; +http://fulltext.sblog.cz/)',
-			metadata: {
-				uaFamily: 'SeznamBot',
-				uaName: 'SeznamBot/3.1-test',
-				uaUrl: 'http://napoveda.seznam.cz/en/indexing-the-web.html',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeznamBot'
-			}
-		},
-		'10301': {
-			userAgent: 'yacybot (webportal-global; x86 Windows Vista 6.0; java 1.7.0_25; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10308': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.7.0_25; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10342': {
-			userAgent: 'SeoCheckBot (FischerNetzDesign Seo Checker, info@fischernetzdesign.de)',
-			metadata: {
-				uaFamily: 'SeoCheckBot',
-				uaName: 'SeoCheckBot',
-				uaUrl: 'http://www.kfsw.de/bot.html',
-				uaCompany: 'Kristian Fischer',
-				uaCompanyUrl: 'http://www.kfsw.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeoCheckBot'
-			}
-		},
-		'10349': {
-			userAgent: 'Mozilla/5.0 (compatible; woriobot support [at] zite [dot] com +http://zite.com)',
-			metadata: {
-				uaFamily: 'woriobot',
-				uaName: 'woriobot',
-				uaUrl: '',
-				uaCompany: 'Zite',
-				uaCompanyUrl: 'http://zite.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=woriobot'
-			}
-		},
-		'10356': {
-			userAgent: 'SeoCheck (FischerNetzDesign Seo Checker, info@fischernetzdesign.de)',
-			metadata: {
-				uaFamily: 'SeoCheckBot',
-				uaName: 'SeoCheck',
-				uaUrl: 'http://www.kfsw.de/bot.html',
-				uaCompany: 'Kristian Fischer',
-				uaCompanyUrl: 'http://www.kfsw.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeoCheckBot'
-			}
-		},
-		'10374': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.2.0-4-amd64; java 1.7.0_03; Etc/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10444': {
-			userAgent: 'Mozilla/5.0 (compatible; SemrushBot/0.96.4; +http://www.semrush.com/bot.html)',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.96.4',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'10448': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows NT (unknown) 6.2; java 1.7.0_05; Africa/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10481': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 7 6.1; java 1.7.0_04; Asia/ja) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10498': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows Server 2008 R2 6.1; java 1.7.0_25; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10503': {
-			userAgent: 'ScreenerBot Crawler Beta 2.0 (+http://www.ScreenerBot.com)',
-			metadata: {
-				uaFamily: 'ScreenerBot Crawler',
-				uaName: 'ScreenerBot Crawler Beta 2.0',
-				uaUrl: 'http://www.screenerbot.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=ScreenerBot Crawler'
-			}
-		},
-		'10537': {
-			userAgent: 'Mozilla/5.0 (compatible; Mozilla/5.0; +http://wiki.github.com/bixo/bixo/bixocrawler; bixo-dev@yahoogroups.com)',
-			metadata: {
-				uaFamily: 'bixocrawler',
-				uaName: 'bixocrawler',
-				uaUrl: 'http://wiki.github.com/bixo/bixo/bixocrawler',
-				uaCompany: 'Bixo Labs',
-				uaCompanyUrl: 'http://openbixo.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bixocrawler'
-			}
-		},
-		'10555': {
-			userAgent: 'Semantifire1/0.20 ( http://www.setooz.com/oozbot.html ; agentname at setooz dot_com )',
-			metadata: {
-				uaFamily: 'Semantifire',
-				uaName: 'Semantifire1/0.20',
-				uaUrl: 'http://www.setooz.com/oozbot.html',
-				uaCompany: 'SETU Software Systems (P) Ltd.',
-				uaCompanyUrl: 'http://www.setusoftware.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Semantifire'
-			}
-		},
-		'10562': {
-			userAgent: 'Mozilla/5.0 (compatible; BIXOCRAWLER; +http://wiki.github.com/bixo/bixo/bixocrawler; bixo-dev@yahoogroups.com)',
-			metadata: {
-				uaFamily: 'bixocrawler',
-				uaName: 'bixocrawler',
-				uaUrl: 'http://wiki.github.com/bixo/bixo/bixocrawler',
-				uaCompany: 'Bixo Labs',
-				uaCompanyUrl: 'http://openbixo.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=bixocrawler'
-			}
-		},
-		'10576': {
-			userAgent: 'Mozilla/5.0 (compatible; socialbm_bot/1.0; +http://spider.socialbm.net)',
-			metadata: {
-				uaFamily: 'socialbm_bot',
-				uaName: 'socialbm_bot/1.0',
-				uaUrl: 'http://spider.socialbm.net/',
-				uaCompany: 'Martin Junker - social-bookmarking.net',
-				uaCompanyUrl: 'http://www.social-bookmarking.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=socialbm_bot'
-			}
-		},
-		'10604': {
-			userAgent: 'rogerbot/1.0 (http://moz.com/help/pro/what-is-rogerbot-, rogerbot-crawler+shiny@moz.com)',
-			metadata: {
-				uaFamily: 'rogerbot',
-				uaName: 'rogerbot/1.0',
-				uaUrl: 'http://moz.com/help/pro/what-is-rogerbot-',
-				uaCompany: 'SEOmoz, Inc.',
-				uaCompanyUrl: 'http://moz.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=rogerbot'
-			}
-		},
-		'10615': {
-			userAgent: 'CCResearchBot/1.0 commoncrawl.org/research//Nutch-1.7-SNAPSHOT',
-			metadata: {
-				uaFamily: 'CCResearchBot',
-				uaName: 'CCResearchBot/1.0',
-				uaUrl: 'http://commoncrawl.org/research/',
-				uaCompany: 'CommonCrawl Foundation',
-				uaCompanyUrl: 'http://www.commoncrawl.org/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CCResearchBot'
-			}
-		},
-		'10635': {
-			userAgent: 'Mozilla/5.0 (compatible; MJ12bot/v1.4.4; http://www.majestic12.co.uk/bot.php?+)',
-			metadata: {
-				uaFamily: 'MJ12bot',
-				uaName: 'MJ12bot/v1.4.4',
-				uaUrl: 'http://majestic12.co.uk/bot.php',
-				uaCompany: 'Majestic-12',
-				uaCompanyUrl: 'http://www.majestic12.co.uk/',
-				uaIcon: 'bot_mj12bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MJ12bot'
-			}
-		},
-		'10658': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.5.0-27-generic; java 1.7.0_25; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10691': {
-			userAgent: 'Mozilla/5.0 (compatible; SemrushBot/0.97; +http://www.semrush.com/bot.html)',
-			metadata: {
-				uaFamily: 'SemrushBot',
-				uaName: 'SemrushBot/0.97',
-				uaUrl: 'http://www.semrush.com/bot.html',
-				uaCompany: 'SEOQuake Team',
-				uaCompanyUrl: 'http://www.seoquaketeam.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SemrushBot'
-			}
-		},
-		'10708': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/4.0a; +http://www.seoprofiler.com/bot )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/4.0a',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'10822': {
-			userAgent: 'yacybot (freeworld/global; amd64 Windows 8 6.2; java 1.7.0_25; Europe/de) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10823': {
-			userAgent: 'Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup-crawler.com/)',
-			metadata: {
-				uaFamily: 'BLEXBot',
-				uaName: 'BLEXBot/1.0',
-				uaUrl: 'http://webmeup-crawler.com/',
-				uaCompany: 'WebMeUp',
-				uaCompanyUrl: 'http://webmeup.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BLEXBot'
-			}
-		},
-		'10847': {
-			userAgent: 'Mozilla/5.0 (compatible; MojeekBot/0.5; http://www.mojeek.com/bot.html)',
-			metadata: {
-				uaFamily: 'MojeekBot',
-				uaName: 'MojeekBot/0.5',
-				uaUrl: 'http://www.mojeek.com/bot.html',
-				uaCompany: 'Mojeek Ltd.',
-				uaCompanyUrl: 'http://www.mojeek.com/',
-				uaIcon: 'bot_MojeekBot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MojeekBot'
-			}
-		},
-		'10913': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.8.0-19-generic; java 1.7.0_25; Europe/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'10923': {
-			userAgent: 'Cliqz Bot (+http://www.cliqz.com)',
-			metadata: {
-				uaFamily: 'CliqzBot',
-				uaName: 'Cliqz Bot',
-				uaUrl: '',
-				uaCompany: '10betterpages GmbH',
-				uaCompanyUrl: 'http://www.10betterpages.com/',
-				uaIcon: 'bot_cliqzbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=CliqzBot'
-			}
-		},
-		'10990': {
-			userAgent: 'KrOWLer/0.0.1, matentzn at cs dot man dot ac dot uk',
-			metadata: {
-				uaFamily: 'KrOWLer',
-				uaName: 'KrOWLer/0.0.1',
-				uaUrl: '',
-				uaCompany: 'Nico Matentzoglu',
-				uaCompanyUrl: 'http://nico.matentzoglu.net/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=KrOWLer'
-			}
-		},
-		'11025': {
-			userAgent: 'Cliqzbot/0.1 (+http://cliqz.com +cliqzbot@cliqz.com)',
-			metadata: {
-				uaFamily: 'Cliqzbot',
-				uaName: 'Cliqzbot/0.1',
-				uaUrl: '',
-				uaCompany: '10betterpages GmbH',
-				uaCompanyUrl: 'http://www.10betterpages.com/',
-				uaIcon: 'bot_cliqzbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Cliqzbot'
-			}
-		},
-		'11039': {
-			userAgent: 'Mozilla/4.0 (compatible;HostTracker/2.0;+http://www.host-tracker.com/)',
-			metadata: {
-				uaFamily: 'HostTracker',
-				uaName: 'HostTracker/2.0',
-				uaUrl: '',
-				uaCompany: 'HostTracker, Ltd.',
-				uaCompanyUrl: 'http://www.host-tracker.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=HostTracker'
-			}
-		},
-		'11045': {
-			userAgent: 'Mozilla/5.0 (compatible; linkdexbot/2.1; +http://www.linkdex.com/about/bots/)',
-			metadata: {
-				uaFamily: 'linkdexbot',
-				uaName: 'linkdexbot/2.1',
-				uaUrl: 'http://www.linkdex.com/about/bots/',
-				uaCompany: 'Linkdex Limited.',
-				uaCompanyUrl: '',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=linkdexbot'
-			}
-		},
-		'11058': {
-			userAgent: 'BUbiNG (+http://law.di.unimi.it/BUbiNG.html)',
-			metadata: {
-				uaFamily: 'BUbiNG',
-				uaName: 'BUbiNG',
-				uaUrl: 'http://law.di.unimi.it/BUbiNG.html',
-				uaCompany: ' Universit\xe0 degli studi di Milano.',
-				uaCompanyUrl: 'http://www.unimi.it/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=BUbiNG'
-			}
-		},
-		'11068': {
-			userAgent: 'Mozilla/5.0 (compatible; parsijoo; +http://www.parsijoo.ir/; ehsan.mousakazemi@gmail.com)',
-			metadata: {
-				uaFamily: 'parsijoo',
-				uaName: 'parsijoo',
-				uaUrl: '',
-				uaCompany: ' Community Atmosphere',
-				uaCompanyUrl: 'http://parsijoo.ir/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=parsijoo'
-			}
-		},
-		'11079': {
-			userAgent: 'Mozilla/5.0 (compatible; spbot/4.0b; +http://www.seoprofiler.com/bot )',
-			metadata: {
-				uaFamily: 'spbot',
-				uaName: 'spbot/4.0b',
-				uaUrl: 'http://www.seoprofiler.com/bot/',
-				uaCompany: 'Axandra GmbH',
-				uaCompanyUrl: 'http://www.axandra.com/',
-				uaIcon: 'bot_spbot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=spbot'
-			}
-		},
-		'11139': {
-			userAgent: 'Speedy Spider (Submit your site at http://www.entireweb.com/free_submission/)',
-			metadata: {
-				uaFamily: 'Speedy',
-				uaName: 'Speedy Spider',
-				uaUrl: '',
-				uaCompany: 'Entireweb Sweden AB',
-				uaCompanyUrl: 'http://www.entireweb.com/',
-				uaIcon: 'bot_Speedy.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Speedy'
-			}
-		},
-		'11253': {
-			userAgent: 'Mozilla/5.0 (compatible; alexa site audit/1.0; +http://www.alexa.com/help/webmasters; siteaudit@alexa.com)',
-			metadata: {
-				uaFamily: 'alexa site audit',
-				uaName: 'alexa site audit/1.0',
-				uaUrl: 'http://www.alexa.com/siteaudit',
-				uaCompany: 'Alexa Internet, Inc.',
-				uaCompanyUrl: 'http://www.alexa.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=alexa site audit'
-			}
-		},
-		'11255': {
-			userAgent: 'A6-Indexer/1.0 (http://www.a6corp.com/a6-web-scraping-policy/)',
-			metadata: {
-				uaFamily: 'A6-Indexer',
-				uaName: 'A6-Indexer/1.0',
-				uaUrl: 'http://www.a6corp.com/a6-web-scraping-policy/',
-				uaCompany: 'A6 Corporation',
-				uaCompanyUrl: 'http://www.a6corp.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=A6-Indexer'
-			}
-		},
-		'11256': {
-			userAgent: 'yacybot (freeworld/global; amd64 Linux 3.10.15-1-MANJARO; java 1.7.0_40; Asia/en) http://yacy.net/bot.html',
-			metadata: {
-				uaFamily: 'yacybot',
-				uaName: 'yacybot',
-				uaUrl: 'http://yacy.net/bot.html',
-				uaCompany: 'Michael Christen',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_yacybot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=yacybot'
-			}
-		},
-		'11265': {
-			userAgent: 'Mozilla/5.0 (Compatible; Vedma/0.91Beta; +http://www.vedma.ru/bot.htm)',
-			metadata: {
-				uaFamily: 'Vedma',
-				uaName: 'Vedma/0.91Beta',
-				uaUrl: 'http://www.vedma.ru/bot.htm',
-				uaCompany: 'vedma.ru',
-				uaCompanyUrl: 'http://www.vedma.ru/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Vedma'
-			}
-		},
-		'11312': {
-			userAgent: 'Mozilla/5.0 (compatible; WebThumbnail/3.x; Website Thumbnail Generator; +http://webthumbnail.org)',
-			metadata: {
-				uaFamily: 'WebThumbnail',
-				uaName: 'WebThumbnail/3.x',
-				uaUrl: '',
-				uaCompany: 'hellworx - Lukasz Cepowski',
-				uaCompanyUrl: 'http://www.hellworx.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=WebThumbnail'
-			}
-		},
-		'11323': {
-			userAgent: 'Mozilla/5.0 (compatible; archive.org_bot; Wayback Machine Live Record; +http://archive.org/details/archive.org_bot)',
-			metadata: {
-				uaFamily: 'archive.org_bot',
-				uaName: 'archive.org_bot',
-				uaUrl: 'http://www.archive.org/details/archive.org_bot',
-				uaCompany: 'Internet Archive',
-				uaCompanyUrl: 'http://www.archive.org/',
-				uaIcon: 'bot_heritrix.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=archive.org_bot'
-			}
-		},
-		'11331': {
-			userAgent: 'SeoCheckBot (Seo-Check, http://www.kfsw.de/bot.html)',
-			metadata: {
-				uaFamily: 'SeoCheckBot',
-				uaName: 'SeoCheckBot',
-				uaUrl: 'http://www.kfsw.de/bot.html',
-				uaCompany: 'Kristian Fischer',
-				uaCompanyUrl: 'http://www.kfsw.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=SeoCheckBot'
-			}
-		},
-		'11343': {
-			userAgent: 'MiaDev/0.0.1 (MIA Bot for research project MIA (www.MIA-marktplatz.de); http://www.mia-marktplatz.de/spider; spider@mia-marktplatz.de)',
-			metadata: {
-				uaFamily: 'MiaDev',
-				uaName: 'MiaDev/0.0.1',
-				uaUrl: 'http://www.mia-marktplatz.de/spider',
-				uaCompany: 'Technische Universit\xe4t Berlin',
-				uaCompanyUrl: 'http://www.dima.tu-berlin.de/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=MiaDev'
-			}
-		},
-		'11351': {
-			userAgent: 'Mozilla/5.0 (compatible; aiHitBot/2.8; +http://endb-consolidated.aihit.com/)',
-			metadata: {
-				uaFamily: 'aiHitBot',
-				uaName: 'aiHitBot/2.8',
-				uaUrl: '',
-				uaCompany: 'aiHit Ltd',
-				uaCompanyUrl: 'http://aihit.com/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=aiHitBot'
-			}
-		},
-		'11377': {
-			userAgent: 'Baiduspider-image+(+http://www.baidu.com/search/spider.htm)',
-			metadata: {
-				uaFamily: 'Baiduspider',
-				uaName: 'Baiduspider-image',
-				uaUrl: 'http://www.baidu.com/search/spider.htm',
-				uaCompany: 'Baidu',
-				uaCompanyUrl: '',
-				uaIcon: 'bot_baiduspider.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Baiduspider'
-			}
-		},
-		'11378': {
-			userAgent: 'Fetch/2.0a (CMS Detection/Web/SEO analysis tool, see http://guess.scritch.org)',
-			metadata: {
-				uaFamily: 'Fetch-Guess',
-				uaName: 'Fetch/2.0a',
-				uaUrl: '',
-				uaCompany: 'Ivo van der Wijk',
-				uaCompanyUrl: 'http://www.m3r.nl/',
-				uaIcon: 'bot.png',
-				uaInfoUrl: '/list-of-ua/bot-detail?bot=Fetch-Guess'
-			}
-		},
-		order: [
-			'1490',
-			'9655',
-			'9010',
-			'1773',
-			'1633',
-			'1871',
-			'5311',
-			'11255',
-			'3422',
-			'6592',
-			'9410',
-			'1941',
-			'1735',
-			'5077',
-			'6246',
-			'6247',
-			'859',
-			'892',
-			'7106',
-			'162',
-			'512',
-			'1273',
-			'1282',
-			'1287',
-			'1297',
-			'1685',
-			'6905',
-			'7001',
-			'7009',
-			'7112',
-			'7178',
-			'7265',
-			'7285',
-			'7321',
-			'7366',
-			'7409',
-			'7458',
-			'7477',
-			'7544',
-			'10228',
-			'829',
-			'7230',
-			'1705',
-			'494',
-			'676',
-			'715',
-			'6404',
-			'6751',
-			'7333',
-			'7579',
-			'7843',
-			'10246',
-			'2102',
-			'2188',
-			'2223',
-			'7320',
-			'7462',
-			'9839',
-			'11351',
-			'89',
-			'1555',
-			'1550',
-			'11253',
-			'90',
-			'148',
-			'214',
-			'236',
-			'278',
-			'394',
-			'471',
-			'671',
-			'1849',
-			'128',
-			'2110',
-			'10140',
-			'5623',
-			'7015',
-			'3236',
-			'9389',
-			'2057',
-			'6237',
-			'5272',
-			'8694',
-			'11323',
-			'1042',
-			'37',
-			'131',
-			'411',
-			'694',
-			'890',
-			'9346',
-			'2050',
-			'6231',
-			'9332',
-			'7732',
-			'7733',
-			'14',
-			'1474',
-			'6399',
-			'11377',
-			'2125',
-			'1770',
-			'2162',
-			'2063',
-			'285',
-			'360',
-			'566',
-			'712',
-			'602',
-			'789',
-			'5357',
-			'7754',
-			'8866',
-			'10241',
-			'2022',
-			'6514',
-			'2135',
-			'4733',
-			'5238',
-			'7494',
-			'9832',
-			'10562',
-			'10537',
-			'9288',
-			'548',
-			'580',
-			'665',
-			'749',
-			'7340',
-			'10008',
-			'10057',
-			'10823',
-			'4519',
-			'1726',
-			'1637',
-			'1754',
-			'7442',
-			'146',
-			'328',
-			'456',
-			'833',
-			'1479',
-			'7696',
-			'8192',
-			'1733',
-			'1753',
-			'1752',
-			'237',
-			'11058',
-			'1516',
-			'5100',
-			'817',
-			'4939',
-			'7369',
-			'7162',
-			'1481',
-			'5665',
-			'4977',
-			'499',
-			'588',
-			'742',
-			'928',
-			'969',
-			'1482',
-			'1238',
-			'9453',
-			'10615',
-			'184',
-			'200',
-			'207',
-			'263',
-			'327',
-			'560',
-			'594',
-			'824',
-			'1023',
-			'812',
-			'959',
-			'1270',
-			'9868',
-			'76',
-			'3409',
-			'393',
-			'5909',
-			'10923',
-			'11025',
-			'10035',
-			'7411',
-			'7548',
-			'7727',
-			'8574',
-			'9784',
-			'608',
-			'7927',
-			'32',
-			'80',
-			'688',
-			'1495',
-			'2170',
-			'2181',
-			'2194',
-			'2212',
-			'2242',
-			'2235',
-			'2239',
-			'2241',
-			'2952',
-			'2999',
-			'3003',
-			'2773',
-			'2844',
-			'2937',
-			'2948',
-			'5860',
-			'6630',
-			'6280',
-			'9875',
-			'317',
-			'725',
-			'755',
-			'422',
-			'630',
-			'807',
-			'967',
-			'1150',
-			'1466',
-			'7406',
-			'1530',
-			'6802',
-			'7164',
-			'1568',
-			'731',
-			'752',
-			'652',
-			'811',
-			'938',
-			'1137',
-			'1164',
-			'1214',
-			'1771',
-			'6244',
-			'6922',
-			'7790',
-			'1650',
-			'9577',
-			'1731',
-			'5218',
-			'6937',
-			'1459',
-			'3333',
-			'7764',
-			'7832',
-			'1225',
-			'7143',
-			'117',
-			'7624',
-			'5187',
-			'556',
-			'569',
-			'600',
-			'7083',
-			'488',
-			'597',
-			'1115',
-			'1169',
-			'1323',
-			'192',
-			'564',
-			'8300',
-			'8487',
-			'1198',
-			'1205',
-			'1027',
-			'547',
-			'8184',
-			'5806',
-			'1500',
-			'4730',
-			'7243',
-			'6243',
-			'679',
-			'753',
-			'1994',
-			'7014',
-			'425',
-			'8586',
-			'8607',
-			'9653',
-			'5818',
-			'1523',
-			'5611',
-			'8131',
-			'1061',
-			'7084',
-			'4501',
-			'1717',
-			'3703',
-			'312',
-			'809',
-			'1005',
-			'47',
-			'9020',
-			'9065',
-			'4722',
-			'808',
-			'1595',
-			'3002',
-			'11378',
-			'118',
-			'1856',
-			'5292',
-			'5352',
-			'5646',
-			'5685',
-			'5715',
-			'4853',
-			'5052',
-			'5243',
-			'5277',
-			'5843',
-			'6011',
-			'6177',
-			'6298',
-			'6312',
-			'6326',
-			'6712',
-			'7338',
-			'7387',
-			'7399',
-			'7467',
-			'10078',
-			'1582',
-			'844',
-			'876',
-			'877',
-			'925',
-			'6202',
-			'6068',
-			'1536',
-			'1870',
-			'1663',
-			'306',
-			'804',
-			'851',
-			'531',
-			'1035',
-			'4946',
-			'217',
-			'137',
-			'303',
-			'741',
-			'6226',
-			'6353',
-			'9691',
-			'9652',
-			'190',
-			'215',
-			'8096',
-			'1133',
-			'1052',
-			'920',
-			'9852',
-			'1573',
-			'45',
-			'656',
-			'657',
-			'226',
-			'2133',
-			'2132',
-			'5380',
-			'7053',
-			'25',
-			'31',
-			'982',
-			'4726',
-			'4966',
-			'6945',
-			'6948',
-			'6947',
-			'7258',
-			'7259',
-			'7260',
-			'9737',
-			'9298',
-			'9239',
-			'7717',
-			'7718',
-			'1932',
-			'5165',
-			'756',
-			'1872',
-			'1546',
-			'1658',
-			'1704',
-			'1887',
-			'2026',
-			'2016',
-			'2021',
-			'2081',
-			'2079',
-			'2947',
-			'7225',
-			'623',
-			'1519',
-			'1583',
-			'517',
-			'554',
-			'669',
-			'927',
-			'3600',
-			'7380',
-			'8138',
-			'281',
-			'307',
-			'11039',
-			'3235',
-			'805',
-			'5302',
-			'7975',
-			'761',
-			'155',
-			'1461',
-			'1738',
-			'1765',
-			'1044',
-			'124',
-			'144',
-			'223',
-			'540',
-			'1197',
-			'3445',
-			'5902',
-			'6999',
-			'7676',
-			'5862',
-			'764',
-			'378',
-			'81',
-			'168',
-			'7119',
-			'7414',
-			'85',
-			'7542',
-			'7632',
-			'7726',
-			'8134',
-			'7819',
-			'882',
-			'167',
-			'197',
-			'242',
-			'267',
-			'729',
-			'1220',
-			'7113',
-			'7995',
-			'1540',
-			'1859',
-			'797',
-			'6583',
-			'6829',
-			'7072',
-			'5202',
-			'5',
-			'1599',
-			'391',
-			'1524',
-			'1484',
-			'3292',
-			'1542',
-			'7402',
-			'539',
-			'479',
-			'10990',
-			'396',
-			'633',
-			'83',
-			'266',
-			'405',
-			'4264',
-			'4590',
-			'4591',
-			'3398',
-			'631',
-			'632',
-			'6625',
-			'881',
-			'778',
-			'6612',
-			'6647',
-			'1780',
-			'5180',
-			'1504',
-			'2155',
-			'481',
-			'483',
-			'1798',
-			'6044',
-			'1475',
-			'10237',
-			'11045',
-			'774',
-			'130',
-			'678',
-			'4844',
-			'20',
-			'820',
-			'4996',
-			'1210',
-			'1502',
-			'6134',
-			'7343',
-			'7984',
-			'8247',
-			'9675',
-			'10101',
-			'525',
-			'609',
-			'7888',
-			'5960',
-			'10084',
-			'7211',
-			'5280',
-			'114',
-			'295',
-			'496',
-			'4589',
-			'9540',
-			'7525',
-			'11343',
-			'125',
-			'232',
-			'326',
-			'520',
-			'689',
-			'1676',
-			'1517',
-			'1602',
-			'1908',
-			'1909',
-			'2024',
-			'2185',
-			'4846',
-			'6270',
-			'6877',
-			'7005',
-			'7375',
-			'10635',
-			'1213',
-			'1283',
-			'994',
-			'1247',
-			'1867',
-			'2195',
-			'7012',
-			'1563',
-			'2196',
-			'5683',
-			'6436',
-			'10847',
-			'538',
-			'135',
-			'350',
-			'624',
-			'1533',
-			'2120',
-			'416',
-			'562',
-			'587',
-			'865',
-			'3',
-			'1497',
-			'1180',
-			'1468',
-			'4095',
-			'4411',
-			'6010',
-			'252',
-			'546',
-			'791',
-			'1024',
-			'977',
-			'442',
-			'528',
-			'813',
-			'2028',
-			'1476',
-			'1494',
-			'6921',
-			'8208',
-			'814',
-			'6304',
-			'832',
-			'6225',
-			'5056',
-			'6735',
-			'7856',
-			'873',
-			'1095',
-			'5092',
-			'7238',
-			'368',
-			'771',
-			'1102',
-			'563',
-			'38',
-			'465',
-			'515',
-			'5003',
-			'290',
-			'201',
-			'209',
-			'282',
-			'294',
-			'341',
-			'431',
-			'1072',
-			'8743',
-			'4866',
-			'349',
-			'366',
-			'4336',
-			'6114',
-			'335',
-			'480',
-			'82',
-			'84',
-			'86',
-			'100',
-			'120',
-			'133',
-			'177',
-			'321',
-			'323',
-			'338',
-			'343',
-			'382',
-			'482',
-			'484',
-			'485',
-			'491',
-			'493',
-			'710',
-			'716',
-			'917',
-			'1089',
-			'2087',
-			'5939',
-			'6245',
-			'164',
-			'178',
-			'5987',
-			'6826',
-			'5228',
-			'93',
-			'116',
-			'308',
-			'109',
-			'219',
-			'355',
-			'5859',
-			'6914',
-			'7045',
-			'7055',
-			'7107',
-			'7132',
-			'7563',
-			'7606',
-			'6234',
-			'8429',
-			'310',
-			'1681',
-			'2233',
-			'1496',
-			'9905',
-			'1037',
-			'1040',
-			'7625',
-			'253',
-			'6739',
-			'7070',
-			'7854',
-			'398',
-			'886',
-			'7437',
-			'1938',
-			'11068',
-			'9427',
-			'7959',
-			'7833',
-			'5376',
-			'7153',
-			'2197',
-			'690',
-			'9116',
-			'6978',
-			'7063',
-			'7784',
-			'8061',
-			'1895',
-			'2073',
-			'4876',
-			'6352',
-			'7816',
-			'7889',
-			'141',
-			'616',
-			'4940',
-			'760',
-			'5360',
-			'6974',
-			'7605',
-			'9455',
-			'7655',
-			'56',
-			'5620',
-			'1982',
-			'8170',
-			'5057',
-			'914',
-			'9877',
-			'6024',
-			'1815',
-			'4936',
-			'7217',
-			'6252',
-			'856',
-			'337',
-			'5362',
-			'1711',
-			'7799',
-			'9165',
-			'9918',
-			'10604',
-			'2145',
-			'2078',
-			'6721',
-			'7044',
-			'1601',
-			'3415',
-			'7424',
-			'1816',
-			'1906',
-			'88',
-			'123',
-			'606',
-			'2138',
-			'1950',
-			'1779',
-			'462',
-			'501',
-			'9',
-			'1565',
-			'3203',
-			'10503',
-			'301',
-			'7757',
-			'4512',
-			'8066',
-			'2246',
-			'6892',
-			'10555',
-			'6770',
-			'7060',
-			'7096',
-			'7267',
-			'7776',
-			'9280',
-			'9925',
-			'10691',
-			'10444',
-			'151',
-			'221',
-			'10342',
-			'10356',
-			'11331',
-			'6040',
-			'3142',
-			'5999',
-			'6506',
-			'6708',
-			'6598',
-			'1522',
-			'1469',
-			'1703',
-			'4907',
-			'4888',
-			'6229',
-			'6835',
-			'6837',
-			'1463',
-			'1464',
-			'1992',
-			'3132',
-			'4437',
-			'5857',
-			'6038',
-			'6189',
-			'6192',
-			'6214',
-			'7126',
-			'10293',
-			'1562',
-			'262',
-			'536',
-			'747',
-			'7163',
-			'208',
-			'227',
-			'911',
-			'1480',
-			'6329',
-			'6109',
-			'874',
-			'1866',
-			'101',
-			'408',
-			'754',
-			'815',
-			'825',
-			'921',
-			'835',
-			'1600',
-			'10576',
-			'1471',
-			'1470',
-			'523',
-			'768',
-			'770',
-			'773',
-			'1936',
-			'7671',
-			'8329',
-			'9717',
-			'9262',
-			'1853',
-			'7697',
-			'10073',
-			'4911',
-			'4922',
-			'3379',
-			'5386',
-			'5748',
-			'3561',
-			'3734',
-			'3589',
-			'4097',
-			'4377',
-			'7912',
-			'10708',
-			'11079',
-			'999',
-			'1885',
-			'4185',
-			'4337',
-			'6288',
-			'11139',
-			'6816',
-			'1784',
-			'5066',
-			'934',
-			'1472',
-			'296',
-			'435',
-			'545',
-			'392',
-			'410',
-			'5231',
-			'132',
-			'5145',
-			'567',
-			'1092',
-			'2099',
-			'5188',
-			'5802',
-			'2098',
-			'235',
-			'7138',
-			'7155',
-			'1078',
-			'204',
-			'333',
-			'470',
-			'565',
-			'96',
-			'1772',
-			'1971',
-			'1727',
-			'1728',
-			'352',
-			'412',
-			'445',
-			'447',
-			'645',
-			'646',
-			'648',
-			'961',
-			'962',
-			'963',
-			'964',
-			'965',
-			'966',
-			'218',
-			'2004',
-			'2175',
-			'194',
-			'5828',
-			'6578',
-			'2003',
-			'2183',
-			'1838',
-			'4000',
-			'1293',
-			'6146',
-			'7675',
-			'489',
-			'703',
-			'40',
-			'1763',
-			'5006',
-			'5839',
-			'1462',
-			'1759',
-			'7317',
-			'6962',
-			'9781',
-			'9874',
-			'7384',
-			'6065',
-			'345',
-			'437',
-			'6840',
-			'1662',
-			'7469',
-			'1505',
-			'5727',
-			'439',
-			'1766',
-			'5275',
-			'8590',
-			'11265',
-			'658',
-			'329',
-			'195',
-			'5065',
-			'376',
-			'629',
-			'798',
-			'6961',
-			'612',
-			'698',
-			'888',
-			'222',
-			'1567',
-			'225',
-			'1586',
-			'1619',
-			'929',
-			'6929',
-			'5642',
-			'5639',
-			'5640',
-			'5641',
-			'5643',
-			'5644',
-			'5635',
-			'5636',
-			'5637',
-			'5638',
-			'6776',
-			'4546',
-			'902',
-			'922',
-			'5701',
-			'153',
-			'170',
-			'765',
-			'788',
-			'1751',
-			'7748',
-			'1478',
-			'7634',
-			'469',
-			'758',
-			'11312',
-			'5361',
-			'786',
-			'861',
-			'7438',
-			'7747',
-			'5389',
-			'5710',
-			'872',
-			'7841',
-			'406',
-			'1805',
-			'238',
-			'415',
-			'452',
-			'5183',
-			'7622',
-			'7628',
-			'1501',
-			'10349',
-			'6515',
-			'7596',
-			'7577',
-			'8191',
-			'626',
-			'364',
-			'2205',
-			'340',
-			'4999',
-			'4898',
-			'4914',
-			'1653',
-			'1604',
-			'1645',
-			'1712',
-			'1776',
-			'1894',
-			'1957',
-			'2017',
-			'2071',
-			'2088',
-			'2091',
-			'2279',
-			'2300',
-			'3034',
-			'3238',
-			'3221',
-			'5281',
-			'5322',
-			'4830',
-			'4423',
-			'4747',
-			'4974',
-			'4975',
-			'5216',
-			'5176',
-			'5249',
-			'5276',
-			'5278',
-			'6679',
-			'6680',
-			'6884',
-			'6896',
-			'6968',
-			'6977',
-			'7008',
-			'7039',
-			'7051',
-			'7079',
-			'7092',
-			'7177',
-			'7252',
-			'7253',
-			'7263',
-			'7278',
-			'7303',
-			'7304',
-			'7305',
-			'7306',
-			'7307',
-			'7308',
-			'7309',
-			'7322',
-			'7323',
-			'7324',
-			'7325',
-			'7362',
-			'7363',
-			'7347',
-			'7348',
-			'7349',
-			'7364',
-			'7365',
-			'7373',
-			'7374',
-			'7404',
-			'7405',
-			'7420',
-			'7421',
-			'7422',
-			'7423',
-			'7510',
-			'7511',
-			'7512',
-			'7513',
-			'7729',
-			'8179',
-			'8107',
-			'8114',
-			'8083',
-			'9240',
-			'9682',
-			'9694',
-			'8297',
-			'9681',
-			'8406',
-			'10108',
-			'9673',
-			'10182',
-			'9949',
-			'10126',
-			'10107',
-			'10481',
-			'10913',
-			'10498',
-			'10374',
-			'10658',
-			'10448',
-			'10301',
-			'10308',
-			'10822',
-			'11256',
-			'4',
-			'193',
-			'1564',
-			'1793',
-			'1548',
-			'1558',
-			'5982',
-			'6603',
-			'7381',
-			'7651',
-			'8397',
-			'605',
-			'1458',
-			'1690',
-			'1869',
-			'1943',
-			'5010',
-			'5014',
-			'5016',
-			'5090',
-			'5846',
-			'7013',
-			'7018',
-			'7159',
-			'7160',
-			'7161',
-			'7172',
-			'7173',
-			'7426',
-			'7427',
-			'7428',
-			'7429',
-			'7430',
-			'7433',
-			'1512',
-			'7133',
-			'7300',
-			'8318',
-			'653',
-			'728',
-			'1818',
-			'891',
-			'1507',
-			'1509',
-			'5718',
-			'43',
-			'581',
-			'5655',
-			'5007',
-			'6001',
-			'7139',
-			'8833',
-			'913',
-			'7780',
-			'8902',
-			'140',
-			'159',
-			'401',
-			'3441'
-		]
-	},
-	os: {
-		'1': {
-			osFamily: 'Windows',
-			osName: 'Windows XP',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_XP',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windowsxp.png'
-		},
-		'2': {
-			osFamily: 'Windows',
-			osName: 'Windows 2000',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_2000',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows.png'
-		},
-		'3': {
-			osFamily: 'Windows',
-			osName: 'Windows 2003 Server',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_2003',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windowsxp.png'
-		},
-		'4': {
-			osFamily: 'Windows',
-			osName: 'Windows 95',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_95',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows.png'
-		},
-		'5': {
-			osFamily: 'Windows',
-			osName: 'Windows 98',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_98',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows.png'
-		},
-		'6': {
-			osFamily: 'Windows',
-			osName: 'Windows 3.x',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_3.x',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows.png'
-		},
-		'7': {
-			osFamily: 'Windows',
-			osName: 'Windows CE',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_CE',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windowsce.png'
-		},
-		'8': {
-			osFamily: 'Windows',
-			osName: 'Windows ME',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_me',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows.png'
-		},
-		'9': {
-			osFamily: 'Windows',
-			osName: 'Windows Vista',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_Vista',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windowsvista.png'
-		},
-		'10': {
-			osFamily: 'JVM',
-			osName: 'JVM (Platform Micro Edition)',
-			osUrl: 'http://en.wikipedia.org/wiki/Java_Platform,_Micro_Edition',
-			osCompany: 'Sun Microsystems, Inc.',
-			osCompanyUrl: 'http://en.wikipedia.org/wiki/Sun_Microsystems',
-			osIcon: 'java.png'
-		},
-		'11': {
-			osFamily: 'Linux',
-			osName: 'Linux (CentOS)',
-			osUrl: 'http://www.centos.org/',
-			osCompany: 'CentOS Project',
-			osCompanyUrl: 'http://www.centos.org/',
-			osIcon: 'linux_centos.png'
-		},
-		'12': {
-			osFamily: 'Linux',
-			osName: 'Linux (Ubuntu)',
-			osUrl: 'http://www.ubuntu.com/',
-			osCompany: 'Canonical Ltd.',
-			osCompanyUrl: 'http://www.canonical.com/',
-			osIcon: 'linux_ubuntu.png'
-		},
-		'13': {
-			osFamily: 'Linux',
-			osName: 'Linux (Debian)',
-			osUrl: 'http://www.debian.org/',
-			osCompany: 'Software in the Public Interest, Inc.',
-			osCompanyUrl: 'http://www.spi-inc.org/',
-			osIcon: 'linux_debian.png'
-		},
-		'14': {
-			osFamily: 'Linux',
-			osName: 'Linux (Fedora)',
-			osUrl: 'http://fedoraproject.org/',
-			osCompany: 'Red Hat, Inc.',
-			osCompanyUrl: 'http://www.redhat.com/',
-			osIcon: 'linux_fedora.png'
-		},
-		'15': {
-			osFamily: 'Linux',
-			osName: 'Linux (Gentoo)',
-			osUrl: 'http://www.gentoo.org/',
-			osCompany: 'Gentoo Foundation, Inc.',
-			osCompanyUrl: 'http://www.gentoo.org/foundation/en/',
-			osIcon: 'linux_gentoo.png'
-		},
-		'16': {
-			osFamily: 'Linux',
-			osName: 'Linux (Linspire)',
-			osUrl: 'http://en.wikipedia.org/wiki/Linspire',
-			osCompany: 'Linspire, Inc.',
-			osCompanyUrl: 'http://www.linspire.com/',
-			osIcon: 'linux_linspire.png'
-		},
-		'17': {
-			osFamily: 'Linux',
-			osName: 'Linux (Mandriva)',
-			osUrl: 'http://www.mandriva.com/',
-			osCompany: '',
-			osCompanyUrl: '',
-			osIcon: 'linux_mandriva.png'
-		},
-		'18': {
-			osFamily: 'Linux',
-			osName: 'Linux (RedHat)',
-			osUrl: 'http://en.wikipedia.org/wiki/Red_Hat_Enterprise_Linux',
-			osCompany: 'Red Hat, Inc.',
-			osCompanyUrl: 'http://www.redhat.com/',
-			osIcon: 'linux_redhat.png'
-		},
-		'19': {
-			osFamily: 'Linux',
-			osName: 'Linux',
-			osUrl: 'http://en.wikipedia.org/wiki/Linux',
-			osCompany: '',
-			osCompanyUrl: '',
-			osIcon: 'linux.png'
-		},
-		'20': {
-			osFamily: 'Linux',
-			osName: 'Linux (Slackware)',
-			osUrl: 'http://www.slackware.com/',
-			osCompany: 'Slackware Linux, Inc.',
-			osCompanyUrl: '',
-			osIcon: 'linux_slackware.png'
-		},
-		'21': {
-			osFamily: 'Linux',
-			osName: 'Linux (Kanotix)',
-			osUrl: 'http://kanotix.com/',
-			osCompany: '',
-			osCompanyUrl: '',
-			osIcon: 'linux_kanotix.png'
-		},
-		'22': {
-			osFamily: 'Linux',
-			osName: 'Linux (SUSE)',
-			osUrl: 'http://www.suse.com/',
-			osCompany: 'Novell, Inc.',
-			osCompanyUrl: 'http://www.novell.com/home/',
-			osIcon: 'linux_suse.png'
-		},
-		'23': {
-			osFamily: 'Linux',
-			osName: 'Linux (Knoppix)',
-			osUrl: 'http://knoppix.net/',
-			osCompany: 'Klaus Knopper',
-			osCompanyUrl: 'http://www.knopper.net/knopper/',
-			osIcon: 'linux_knoppix.png'
-		},
-		'24': {
-			osFamily: 'BSD',
-			osName: 'NetBSD',
-			osUrl: 'http://www.netbsd.org/',
-			osCompany: 'NetBSD Foundation, Inc.',
-			osCompanyUrl: '',
-			osIcon: 'netbsd.png'
-		},
-		'25': {
-			osFamily: 'BSD',
-			osName: 'FreeBSD',
-			osUrl: 'http://www.freebsd.org/',
-			osCompany: 'FreeBSD Foundation',
-			osCompanyUrl: 'http://www.freebsdfoundation.org/',
-			osIcon: 'freebsd.png'
-		},
-		'26': {
-			osFamily: 'BSD',
-			osName: 'OpenBSD',
-			osUrl: 'http://www.openbsd.org/',
-			osCompany: '',
-			osCompanyUrl: '',
-			osIcon: 'openbsd.png'
-		},
-		'29': {
-			osFamily: 'Solaris',
-			osName: 'Solaris',
-			osUrl: 'http://en.wikipedia.org/wiki/Solaris_%28operating_system%29',
-			osCompany: 'Sun Microsystems, Inc.',
-			osCompanyUrl: 'http://en.wikipedia.org/wiki/Sun_Microsystems',
-			osIcon: 'solaris.png'
-		},
-		'30': {
-			osFamily: 'Amiga OS',
-			osName: 'Amiga OS',
-			osUrl: 'http://www.amigaos.net/',
-			osCompany: 'Commodore International Limited',
-			osCompanyUrl: 'http://en.wikipedia.org/wiki/Commodore_International',
-			osIcon: 'amiga.png'
-		},
-		'31': {
-			osFamily: 'IRIX',
-			osName: 'IRIX',
-			osUrl: 'http://www.sgi.com/products/software/irix/',
-			osCompany: 'Silicon Graphics, Inc.',
-			osCompanyUrl: 'http://www.sgi.com/',
-			osIcon: 'irix.png'
-		},
-		'32': {
-			osFamily: 'OpenVMS',
-			osName: 'OpenVMS',
-			osUrl: 'http://h71000.www7.hp.com/',
-			osCompany: 'Hewlett-Packard Development Company, L.P.',
-			osCompanyUrl: 'http://www.hp.com/',
-			osIcon: 'openvms.png'
-		},
-		'33': {
-			osFamily: 'BeOS',
-			osName: 'BeOS',
-			osUrl: '',
-			osCompany: 'Be, Inc.',
-			osCompanyUrl: 'http://www.beincorporated.com/',
-			osIcon: 'beos.png'
-		},
-		'34': {
-			osFamily: 'Symbian OS',
-			osName: 'Symbian OS',
-			osUrl: 'http://en.wikipedia.org/wiki/Symbian_OS',
-			osCompany: 'Symbian Foundation',
-			osCompanyUrl: 'http://licensing.symbian.org/',
-			osIcon: 'symbian.png'
-		},
-		'35': {
-			osFamily: 'Palm OS',
-			osName: 'Palm OS',
-			osUrl: 'http://en.wikipedia.org/wiki/Palm_OS',
-			osCompany: 'Palm, Inc.',
-			osCompanyUrl: 'http://en.wikipedia.org/wiki/Palm,_Inc.',
-			osIcon: 'palmos.png'
-		},
-		'37': {
-			osFamily: 'Windows',
-			osName: 'MSN TV (WebTV)',
-			osUrl: 'http://en.wikipedia.org/wiki/MSN_TV',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'webtv.png'
-		},
-		'39': {
-			osFamily: 'OS/2',
-			osName: 'OS/2 Warp',
-			osUrl: 'http://en.wikipedia.org/wiki/OS/2_Warp#The_.22Warp.22_years',
-			osCompany: 'IBM Corporation',
-			osCompanyUrl: 'http://www.ibm.com/',
-			osIcon: 'os2warp.png'
-		},
-		'40': {
-			osFamily: 'RISK OS',
-			osName: 'RISK OS',
-			osUrl: '',
-			osCompany: 'RISCOS Ltd',
-			osCompanyUrl: 'http://www.riscos.com/',
-			osIcon: 'riskos.png'
-		},
-		'41': {
-			osFamily: 'HP-UX',
-			osName: 'HP-UX',
-			osUrl: 'http://www.hp.com/products1/unix/',
-			osCompany: 'Hewlett-Packard Development Company, L.P.',
-			osCompanyUrl: 'http://www.hp.com/',
-			osIcon: 'hpux.png'
-		},
-		'42': {
-			osFamily: 'Nintendo',
-			osName: 'Nintendo Wii',
-			osUrl: 'http://en.wikipedia.org/wiki/Nintendo_Wii',
-			osCompany: 'Nintendo of America Inc.',
-			osCompanyUrl: 'http://www.nintendo.com/',
-			osIcon: 'wii.png'
-		},
-		'43': {
-			osFamily: 'Windows',
-			osName: 'Windows',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows.png'
-		},
-		'44': {
-			osFamily: 'Mac OS',
-			osName: 'Mac OS',
-			osUrl: 'http://en.wikipedia.org/wiki/Mac_OS',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macos.png'
-		},
-		'45': {
-			osFamily: 'AIX',
-			osName: 'AIX',
-			osUrl: 'http://en.wikipedia.org/wiki/IBM_AIX',
-			osCompany: 'IBM Corporation',
-			osCompanyUrl: 'http://www.ibm.com/',
-			osIcon: 'aix.png'
-		},
-		'46': {
-			osFamily: 'Windows',
-			osName: 'Windows NT',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_NT',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows.png'
-		},
-		'47': {
-			osFamily: 'JVM',
-			osName: 'JVM (Java)',
-			osUrl: 'http://en.wikipedia.org/wiki/Jvm',
-			osCompany: 'Sun Microsystems, Inc.',
-			osCompanyUrl: 'http://en.wikipedia.org/wiki/Sun_Microsystems',
-			osIcon: 'java.png'
-		},
-		'49': {
-			osFamily: 'Plan 9',
-			osName: 'Plan 9',
-			osUrl: 'http://plan9.bell-labs.com/plan9/',
-			osCompany: 'Lucent Technologies',
-			osCompanyUrl: 'http://www.lucent.com/',
-			osIcon: 'plan9.png'
-		},
-		'50': {
-			osFamily: 'BlackBerry OS',
-			osName: 'BlackBerry OS',
-			osUrl: 'http://en.wikipedia.org/wiki/BlackBerry_OS',
-			osCompany: 'BlackBerry Ltd',
-			osCompanyUrl: 'http://www.blackberry.com/',
-			osIcon: 'rim_os.png'
-		},
-		'52': {
-			osFamily: 'QNX',
-			osName: 'QNX x86pc',
-			osUrl: 'http://www.qnx.com/',
-			osCompany: 'QNX Software Systems',
-			osCompanyUrl: 'http://www.qnx.com/',
-			osIcon: 'qnx.png'
-		},
-		'53': {
-			osFamily: 'MorphOS',
-			osName: 'MorphOS',
-			osUrl: 'http://www.morphos-team.net/',
-			osCompany: 'MorphOS development team',
-			osCompanyUrl: '',
-			osIcon: 'morphos.png'
-		},
-		'55': {
-			osFamily: 'Linux',
-			osName: 'Linux (VectorLinux)',
-			osUrl: 'http://vectorlinux.com/',
-			osCompany: 'Robert S. Lange',
-			osCompanyUrl: '',
-			osIcon: 'linux_vector.png'
-		},
-		'56': {
-			osFamily: 'Linux',
-			osName: 'Linux (Mint)',
-			osUrl: 'http://linuxmint.com/',
-			osCompany: 'clem',
-			osCompanyUrl: '',
-			osIcon: 'linuxmint.png'
-		},
-		'57': {
-			osFamily: 'SCO',
-			osName: 'SCO OpenServer',
-			osUrl: 'http://www.sco.com/products/openserver/',
-			osCompany: 'The SCO Group',
-			osCompanyUrl: 'http://www.sco.com/',
-			osIcon: 'sco.png'
-		},
-		'58': {
-			osFamily: 'Linux',
-			osName: 'Linux (Arch Linux)',
-			osUrl: 'http://www.archlinux.org/',
-			osCompany: 'Judd Vinet',
-			osCompanyUrl: 'http://www.zeroflux.org/',
-			osIcon: 'linux_archlinux.png'
-		},
-		'59': {
-			osFamily: 'SkyOS',
-			osName: 'SkyOS',
-			osUrl: 'http://www.skyos.org/',
-			osCompany: 'SkyOS Team',
-			osCompanyUrl: 'http://www.skyos.org/',
-			osIcon: 'skyos.png'
-		},
-		'61': {
-			osFamily: 'BSD',
-			osName: 'DragonFly BSD',
-			osUrl: 'http://www.dragonflybsd.org/',
-			osCompany: 'DragonFly BSD Team',
-			osCompanyUrl: 'http://www.dragonflybsd.org/team/',
-			osIcon: 'dragonflybsd.png'
-		},
-		'62': {
-			osFamily: 'Android',
-			osName: 'Android',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'64': {
-			osFamily: 'Windows',
-			osName: 'Windows 7',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_7',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows-7.png'
-		},
-		'65': {
-			osFamily: 'iOS',
-			osName: 'iOS',
-			osUrl: 'http://en.wikipedia.org/wiki/IOS',
-			osCompany: 'Apple Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'iphone.png'
-		},
-		'69': {
-			osFamily: 'webOS',
-			osName: 'webOS',
-			osUrl: 'http://en.wikipedia.org/wiki/WebOS',
-			osCompany: 'Hewlett-Packard',
-			osCompanyUrl: 'http://en.wikipedia.org/wiki/Palm,_Inc.',
-			osIcon: 'webos.png'
-		},
-		'70': {
-			osFamily: 'Haiku OS',
-			osName: 'Haiku OS',
-			osUrl: 'http://www.haiku-os.org/',
-			osCompany: 'Haiku Inc.',
-			osCompanyUrl: 'http://www.haiku-os.org/about/haiku_inc',
-			osIcon: 'haiku.png'
-		},
-		'72': {
-			osFamily: 'DangerOS',
-			osName: 'Danger Hiptop',
-			osUrl: 'http://en.wikipedia.org/wiki/DangerOS',
-			osCompany: 'Danger, Inc.',
-			osCompanyUrl: 'http://en.wikipedia.org/wiki/Danger_%28company%29',
-			osIcon: 'dangeros.png'
-		},
-		'74': {
-			osFamily: 'Syllable',
-			osName: 'Syllable',
-			osUrl: 'http://syllable.org/',
-			osCompany: 'Kristian Van Der Vliet, Kaj de Vos, Rick Caudill, Arno Klenke, Henrik Isaksson',
-			osCompanyUrl: '',
-			osIcon: 'syllable.png'
-		},
-		'75': {
-			osFamily: 'Linux',
-			osName: 'Linux (Maemo)',
-			osUrl: 'http://maemo.org/',
-			osCompany: 'Nokia',
-			osCompanyUrl: 'http://www.nokia.com/',
-			osIcon: 'maemo.png'
-		},
-		'83': {
-			osFamily: 'OS X',
-			osName: 'OS X 10.4 Tiger',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'84': {
-			osFamily: 'OS X',
-			osName: 'OS X 10.5 Leopard',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'85': {
-			osFamily: 'OS X',
-			osName: 'OS X 10.6 Snow Leopard',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'86': {
-			osFamily: 'OS X',
-			osName: 'OS X',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'87': {
-			osFamily: 'OS/2',
-			osName: 'OS/2',
-			osUrl: 'http://en.wikipedia.org/wiki/OS/2',
-			osCompany: 'IBM Corporation',
-			osCompanyUrl: 'http://www.ibm.com/',
-			osIcon: 'os2.png'
-		},
-		'88': {
-			osFamily: 'Windows',
-			osName: 'Windows Mobile',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_Mobile',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windowsMobile.png'
-		},
-		'90': {
-			osFamily: 'OS X',
-			osName: 'OS X 10.3 Panther',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'91': {
-			osFamily: 'MINIX',
-			osName: 'MINIX 3 ',
-			osUrl: 'http://www.minix3.org/',
-			osCompany: 'Andrew S. Tanenbaum',
-			osCompanyUrl: 'http://www.cs.vu.nl/~ast/',
-			osIcon: 'minix.png'
-		},
-		'92': {
-			osFamily: 'Linux',
-			osName: 'PClinuxOS',
-			osUrl: 'http://www.pclinuxos.com/',
-			osCompany: 'Bill Reynolds ("Texstar")',
-			osCompanyUrl: '',
-			osIcon: 'pclinuxos.png'
-		},
-		'93': {
-			osFamily: 'Linux',
-			osName: 'Joli OS',
-			osUrl: 'http://www.jolicloud.com/',
-			osCompany: 'Tariq Krim and Romain Huet',
-			osCompanyUrl: '',
-			osIcon: 'jolicloud.png'
-		},
-		'94': {
-			osFamily: 'XrossMediaBar (XMB)',
-			osName: 'XrossMediaBar (XMB)',
-			osUrl: 'http://en.wikipedia.org/wiki/XrossMediaBar',
-			osCompany: 'Sony Computer Entertainment',
-			osCompanyUrl: 'http://www.scei.co.jp/',
-			osIcon: 'XMB.png'
-		},
-		'95': {
-			osFamily: 'AROS',
-			osName: 'AROS',
-			osUrl: 'http://en.wikipedia.org/wiki/AROS_Research_Operating_System',
-			osCompany: 'AROS Development Team',
-			osCompanyUrl: '',
-			osIcon: 'aros.png'
-		},
-		'96': {
-			osFamily: 'Windows',
-			osName: 'Windows Phone 7',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_Phone_7',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windowsMobile.png'
-		},
-		'97': {
-			osFamily: 'Linux',
-			osName: 'Chrome OS',
-			osUrl: 'http://en.wikipedia.org/wiki/Chrome_OS',
-			osCompany: 'Google Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'ChromiumOS.png'
-		},
-		'98': {
-			osFamily: 'Nintendo',
-			osName: 'Nintendo DS',
-			osUrl: 'http://www.nintendods.com/',
-			osCompany: 'Nintendo of America Inc.',
-			osCompanyUrl: 'http://www.nintendo.com/',
-			osIcon: 'nintendoDS.png'
-		},
-		'99': {
-			osFamily: 'Linux',
-			osName: 'GNU OS',
-			osUrl: 'http://www.gnu.org/',
-			osCompany: 'Free Software Foundation, Inc.',
-			osCompanyUrl: 'http://www.fsf.org/',
-			osIcon: 'gnu_os.png'
-		},
-		'100': {
-			osFamily: 'Windows',
-			osName: 'Windows 8',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_8',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows8.png'
-		},
-		'101': {
-			osFamily: 'RIM OS',
-			osName: 'BlackBerry Tablet OS 1',
-			osUrl: 'http://en.wikipedia.org/wiki/BlackBerry_Tablet_OS',
-			osCompany: 'Research In Motion Limited',
-			osCompanyUrl: 'http://www.rim.com/',
-			osIcon: 'rim_os.png'
-		},
-		'102': {
-			osFamily: 'Bada',
-			osName: 'Bada',
-			osUrl: 'http://www.bada.com/',
-			osCompany: 'Samsung Electronics',
-			osCompanyUrl: 'http://www.samsung.com/',
-			osIcon: 'bada.png'
-		},
-		'103': {
-			osFamily: 'Android',
-			osName: 'Android 1.5 Cupcake',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'104': {
-			osFamily: 'Android',
-			osName: 'Android 1.6 Donut',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'105': {
-			osFamily: 'Android',
-			osName: 'Android 2.0/1 Eclair',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'106': {
-			osFamily: 'Android',
-			osName: 'Android 2.2.x Froyo',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'107': {
-			osFamily: 'Android',
-			osName: 'Android 2.3.x Gingerbread',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'108': {
-			osFamily: 'Android',
-			osName: 'Android 3.x Honeycomb',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'110': {
-			osFamily: 'Android',
-			osName: 'Android 1.0',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'111': {
-			osFamily: 'Android',
-			osName: 'Android 4.0.x Ice Cream Sandwich',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'112': {
-			osFamily: 'OS X',
-			osName: 'OS X 10.7 Lion',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'113': {
-			osFamily: 'Tizen',
-			osName: 'Tizen 1',
-			osUrl: 'https://www.tizen.org/',
-			osCompany: 'Tizen Project',
-			osCompanyUrl: 'https://www.tizen.org/',
-			osIcon: 'tizen.png'
-		},
-		'114': {
-			osFamily: 'unknown',
-			osName: 'unknown',
-			osUrl: '',
-			osCompany: '',
-			osCompanyUrl: '',
-			osIcon: 'unknown.png'
-		},
-		'115': {
-			osFamily: 'Inferno OS',
-			osName: 'Inferno OS',
-			osUrl: 'http://en.wikipedia.org/wiki/Inferno_%28operating_system%29',
-			osCompany: 'Vita Nuova Holdings Ltd',
-			osCompanyUrl: 'http://www.vitanuova.com/',
-			osIcon: 'inferno.png'
-		},
-		'116': {
-			osFamily: 'OS X',
-			osName: 'OS X 10.8 Mountain Lion',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'117': {
-			osFamily: 'iOS',
-			osName: 'iOS 4',
-			osUrl: 'http://en.wikipedia.org/wiki/IOS',
-			osCompany: 'Apple Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'iphone.png'
-		},
-		'118': {
-			osFamily: 'iOS',
-			osName: 'iOS 5',
-			osUrl: 'http://en.wikipedia.org/wiki/IOS_5',
-			osCompany: 'Apple Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'iphone.png'
-		},
-		'119': {
-			osFamily: 'RIM OS',
-			osName: 'BlackBerry Tablet OS 2',
-			osUrl: 'http://en.wikipedia.org/wiki/BlackBerry_Tablet_OS',
-			osCompany: 'Research In Motion Limited',
-			osCompanyUrl: 'http://www.rim.com/',
-			osIcon: 'rim_os.png'
-		},
-		'120': {
-			osFamily: 'Android',
-			osName: 'Android 4.1.x Jelly Bean',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'121': {
-			osFamily: 'iOS',
-			osName: 'iOS 6',
-			osUrl: 'http://en.wikipedia.org/wiki/IOS_6',
-			osCompany: 'Apple Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'iphone.png'
-		},
-		'122': {
-			osFamily: 'LiveArea',
-			osName: 'LiveArea',
-			osUrl: 'http://en.wikipedia.org/wiki/LiveArea',
-			osCompany: 'Sony Computer Entertainment',
-			osCompanyUrl: 'http://www.scei.co.jp/',
-			osIcon: 'ps-vitaLiveArea.png'
-		},
-		'123': {
-			osFamily: 'Windows',
-			osName: 'Xbox patform',
-			osUrl: 'http://en.wikipedia.org/wiki/Xbox#Operating_system',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'Xbox.png'
-		},
-		'124': {
-			osFamily: 'Android',
-			osName: 'Android 4.2 Jelly Bean',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'125': {
-			osFamily: 'Firefox OS',
-			osName: 'Firefox OS',
-			osUrl: 'http://www.mozilla.org/firefoxos/',
-			osCompany: 'Mozilla Foundation',
-			osCompanyUrl: 'http://www.mozilla.org/',
-			osIcon: 'firefoxos.png'
-		},
-		'126': {
-			osFamily: 'Windows',
-			osName: 'Windows RT',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_RT',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windows8.png'
-		},
-		'127': {
-			osFamily: 'Windows',
-			osName: 'Windows Phone 8',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_Phone_8',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'windowsPhone8.png'
-		},
-		'128': {
-			osFamily: 'Linux',
-			osName: 'Linux (Mageia)',
-			osUrl: 'http://www.mageia.org/',
-			osCompany: 'Mageia.Org',
-			osCompanyUrl: 'http://www.mageia.org/',
-			osIcon: 'linux_mageia.png'
-		},
-		'129': {
-			osFamily: 'iOS',
-			osName: 'iOS 7',
-			osUrl: 'http://en.wikipedia.org/wiki/IOS_7',
-			osCompany: 'Apple Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'iphone.png'
-		},
-		'130': {
-			osFamily: 'Windows',
-			osName: 'Windows 8.1',
-			osUrl: 'http://en.wikipedia.org/wiki/Windows_8#Windows_8.1',
-			osCompany: 'Microsoft Corporation.',
-			osCompanyUrl: 'http://www.microsoft.com/',
-			osIcon: 'win81.png'
-		},
-		'131': {
-			osFamily: 'Android',
-			osName: 'Android 4.3 Jelly Bean',
-			osUrl: 'http://en.wikipedia.org/wiki/Android_%28operating_system%29',
-			osCompany: 'Google, Inc.',
-			osCompanyUrl: 'http://www.google.com/',
-			osIcon: 'android.png'
-		},
-		'132': {
-			osFamily: 'OS X',
-			osName: 'OS X 10.9 Mavericks',
-			osUrl: 'http://www.apple.com/osx/',
-			osCompany: 'Apple Computer, Inc.',
-			osCompanyUrl: 'http://www.apple.com/',
-			osIcon: 'macosx.png'
-		},
-		'133': {
-			osFamily: 'Nintendo',
-			osName: 'Nintendo 3DS',
-			osUrl: 'http://www.nintendo.com/3ds',
-			osCompany: 'Nintendo of America Inc.',
-			osCompanyUrl: 'http://www.nintendo.com/',
-			osIcon: 'nintendoDS.png'
-		},
-		'134': {
-			osFamily: 'Tizen',
-			osName: 'Tizen 2',
-			osUrl: 'https://www.tizen.org/',
-			osCompany: 'Tizen Project',
-			osCompanyUrl: 'https://www.tizen.org/',
-			osIcon: 'tizen.png'
-		},
-		order: [
-			'1',
-			'2',
-			'3',
-			'4',
-			'5',
-			'6',
-			'7',
-			'8',
-			'9',
-			'10',
-			'11',
-			'12',
-			'13',
-			'14',
-			'15',
-			'16',
-			'17',
-			'18',
-			'19',
-			'20',
-			'21',
-			'22',
-			'23',
-			'24',
-			'25',
-			'26',
-			'29',
-			'30',
-			'31',
-			'32',
-			'33',
-			'34',
-			'35',
-			'37',
-			'39',
-			'40',
-			'41',
-			'42',
-			'43',
-			'44',
-			'45',
-			'46',
-			'47',
-			'49',
-			'50',
-			'52',
-			'53',
-			'55',
-			'56',
-			'57',
-			'58',
-			'59',
-			'61',
-			'62',
-			'64',
-			'65',
-			'69',
-			'70',
-			'72',
-			'74',
-			'75',
-			'83',
-			'84',
-			'85',
-			'86',
-			'87',
-			'88',
-			'90',
-			'91',
-			'92',
-			'93',
-			'94',
-			'95',
-			'96',
-			'97',
-			'98',
-			'99',
-			'100',
-			'101',
-			'102',
-			'103',
-			'104',
-			'105',
-			'106',
-			'107',
-			'108',
-			'110',
-			'111',
-			'112',
-			'113',
-			'114',
-			'115',
-			'116',
-			'117',
-			'118',
-			'119',
-			'120',
-			'121',
-			'122',
-			'123',
-			'124',
-			'125',
-			'126',
-			'127',
-			'128',
-			'129',
-			'130',
-			'131',
-			'132',
-			'133',
-			'134'
-		]
-	},
-	browser: {
-		'1': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Camino',
-				uaUrl: 'http://caminobrowser.org/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'camino.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Camino'
-			}
-		},
-		'2': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'SeaMonkey',
-				uaUrl: 'http://www.seamonkey-project.org/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'seamonkey.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SeaMonkey'
-			}
-		},
-		'3': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firefox',
-				uaUrl: 'http://www.firefox.com/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firefox'
-			}
-		},
-		'4': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Netscape Navigator',
-				uaUrl: 'http://en.wikipedia.org/wiki/Netscape_Navigator',
-				uaCompany: 'Netscape Communications Corp.',
-				uaCompanyUrl: 'http://en.wikipedia.org/wiki/Netscape_Communications_Corporation',
-				uaIcon: 'netscape.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Netscape Navigator'
-			}
-		},
-		'5': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Epiphany',
-				uaUrl: 'http://projects.gnome.org/epiphany/',
-				uaCompany: 'GNOME Foundation',
-				uaCompanyUrl: 'http://www.gnome.org/',
-				uaIcon: 'epiphany.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Epiphany'
-			}
-		},
-		'6': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Galeon',
-				uaUrl: 'http://galeon.sourceforge.net/',
-				uaCompany: 'GNOME Foundation',
-				uaCompanyUrl: 'http://www.gnome.org/',
-				uaIcon: 'galeon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Galeon'
-			}
-		},
-		'7': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Flock',
-				uaUrl: 'http://en.wikipedia.org/wiki/Flock_%28web_browser%29',
-				uaCompany: 'Flock, Inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'flock.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Flock'
-			}
-		},
-		'8': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Minimo',
-				uaUrl: 'http://www.mozilla.org/projects/minimo/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'minimo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Minimo'
-			}
-		},
-		'9': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'K-Meleon',
-				uaUrl: 'http://kmeleon.sourceforge.net/',
-				uaCompany: 'Christophe Thibault, Dorian ...',
-				uaCompanyUrl: '',
-				uaIcon: 'k-meleon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=K-Meleon'
-			}
-		},
-		'10': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'K-Ninja',
-				uaUrl: 'http://www.geocities.com/grenleef/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'k-ninja.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=K-Ninja'
-			}
-		},
-		'11': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Kazehakase',
-				uaUrl: 'http://kazehakase.sourceforge.jp/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'kazehakase.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Kazehakase'
-			}
-		},
-		'14': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firebird (old name for Firefox)',
-				uaUrl: 'http://www.firefox.com/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'phoenix.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firebird (old name for Firefox)'
-			}
-		},
-		'15': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Phoenix (old name for Firefox)',
-				uaUrl: 'http://en.wikipedia.org/wiki/Mozilla_Phoenix',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'phoenix.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Phoenix (old name for Firefox)'
-			}
-		},
-		'16': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Konqueror',
-				uaUrl: 'http://www.konqueror.org/',
-				uaCompany: 'KDE e.V.',
-				uaCompanyUrl: 'http://ev.kde.org/',
-				uaIcon: 'konqueror2.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Konqueror'
-			}
-		},
-		'17': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Opera',
-				uaUrl: 'http://www.opera.com/',
-				uaCompany: 'Opera Software ASA.',
-				uaCompanyUrl: 'http://www.opera.com/',
-				uaIcon: 'opera.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Opera'
-			}
-		},
-		'18': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'OmniWeb',
-				uaUrl: 'http://www.omnigroup.com/applications/omniweb/',
-				uaCompany: 'Omni Development, Inc.',
-				uaCompanyUrl: 'http://www.omnigroup.com/',
-				uaIcon: 'omniweb.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=OmniWeb'
-			}
-		},
-		'19': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Sunrise',
-				uaUrl: 'http://www.sunrisebrowser.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'sunrise.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Sunrise'
-			}
-		},
-		'21': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Shiira',
-				uaUrl: 'http://en.wikipedia.org/wiki/Shiira',
-				uaCompany: 'Shiira Project',
-				uaCompanyUrl: '',
-				uaIcon: 'shiira.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Shiira'
-			}
-		},
-		'22': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Safari',
-				uaUrl: 'http://en.wikipedia.org/wiki/Safari_%28web_browser%29',
-				uaCompany: 'Apple Inc.',
-				uaCompanyUrl: 'http://www.apple.com/',
-				uaIcon: 'safari.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Safari'
-			}
-		},
-		'23': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Dillo',
-				uaUrl: 'http://www.dillo.org/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'dillo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Dillo'
-			}
-		},
-		'24': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'iCab',
-				uaUrl: 'http://www.icab.de/',
-				uaCompany: 'Alexander Clauss',
-				uaCompanyUrl: '',
-				uaIcon: 'icab.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iCab'
-			}
-		},
-		'25': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Lynx',
-				uaUrl: 'http://lynx.isc.org/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'lynx.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Lynx'
-			}
-		},
-		'27': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Elinks',
-				uaUrl: 'http://elinks.or.cz/',
-				uaCompany: 'Mikulas Patocka',
-				uaCompanyUrl: '',
-				uaIcon: 'elinks.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Elinks'
-			}
-		},
-		'28': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'Wget',
-				uaUrl: 'http://www.gnu.org/software/wget/',
-				uaCompany: 'Free Software Foundation, Inc.',
-				uaCompanyUrl: 'http://www.gnu.org/',
-				uaIcon: 'wget.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Wget'
-			}
-		},
-		'29': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Amiga Aweb',
-				uaUrl: 'http://www.amitrix.com/aweb.html',
-				uaCompany: 'AmiTrix Development Inc.',
-				uaCompanyUrl: 'http://www.amitrix.com/',
-				uaIcon: 'aweb.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Amiga Aweb'
-			}
-		},
-		'30': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Amiga Voyager',
-				uaUrl: 'http://v3.vapor.com/',
-				uaCompany: 'VaporWare',
-				uaCompanyUrl: 'http://www.vapor.com/',
-				uaIcon: 'voyager.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Amiga Voyager'
-			}
-		},
-		'31': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'IBrowse',
-				uaUrl: 'http://www.ibrowse-dev.net/',
-				uaCompany: 'Stefan Burstr\xf6m',
-				uaCompanyUrl: '',
-				uaIcon: 'ibrowse.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IBrowse'
-			}
-		},
-		'32': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Openwave Mobile Browser',
-				uaUrl: 'http://www.openwave.com/',
-				uaCompany: 'Openwave Systems Inc.',
-				uaCompanyUrl: 'http://www.openwave.com/',
-				uaIcon: 'openwave.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Openwave Mobile Browser'
-			}
-		},
-		'33': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'NetFront',
-				uaUrl: 'http://www.access-company.com/',
-				uaCompany: 'ACCESS CO.,LTD',
-				uaCompanyUrl: 'http://www.access-company.com/',
-				uaIcon: 'netfront.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetFront'
-			}
-		},
-		'35': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'IE',
-				uaUrl: 'http://en.wikipedia.org/wiki/Internet_Explorer',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'msie.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IE'
-			}
-		},
-		'39': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'Offline Explorer',
-				uaUrl: 'http://www.metaproducts.com/',
-				uaCompany: 'MetaProducts Corporation.',
-				uaCompanyUrl: '',
-				uaIcon: 'offline_explorer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Offline Explorer'
-			}
-		},
-		'40': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'AOL Explorer',
-				uaUrl: 'http://daol.aol.com/software/',
-				uaCompany: 'America Online, Inc.',
-				uaCompanyUrl: 'http://www.aol.com/',
-				uaIcon: 'aol.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=AOL Explorer'
-			}
-		},
-		'41': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Avant Browser',
-				uaUrl: 'http://avantbrowser.com/',
-				uaCompany: 'Avant Force',
-				uaCompanyUrl: 'http://avantbrowser.com/',
-				uaIcon: 'avantbrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Avant Browser'
-			}
-		},
-		'42': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'AvantGo',
-				uaUrl: 'http://en.wikipedia.org/wiki/AvantGo',
-				uaCompany: 'Sybase Inc.',
-				uaCompanyUrl: 'http://www.sybase.com/',
-				uaIcon: 'avantgo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=AvantGo'
-			}
-		},
-		'43': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Blazer',
-				uaUrl: 'http://en.wikipedia.org/wiki/Blazer_(web_browser)',
-				uaCompany: 'Bluelark Systems',
-				uaCompanyUrl: '',
-				uaIcon: 'blazer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Blazer'
-			}
-		},
-		'44': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Crazy Browser',
-				uaUrl: 'http://www.crazybrowser.com/',
-				uaCompany: 'CrazyBrowser.com',
-				uaCompanyUrl: 'http://www.crazybrowser.com/',
-				uaIcon: 'crazybrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Crazy Browser'
-			}
-		},
-		'45': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Deepnet Explorer',
-				uaUrl: 'http://www.deepnetexplorer.com/',
-				uaCompany: 'Deepnet Technologies Ltd',
-				uaCompanyUrl: 'http://www.deepnetexplorer.com/',
-				uaIcon: 'deepnet.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Deepnet Explorer'
-			}
-		},
-		'46': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'HTTrack',
-				uaUrl: 'http://www.httrack.com/',
-				uaCompany: 'Xavier Roche',
-				uaCompanyUrl: 'http://www.httrack.com/',
-				uaIcon: 'httrack.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=HTTrack'
-			}
-		},
-		'47': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'IceWeasel',
-				uaUrl: 'http://www.gnu.org/software/gnuzilla/',
-				uaCompany: 'Software in the Public Interest, Inc.',
-				uaCompanyUrl: 'http://www.spi-inc.org/',
-				uaIcon: 'iceweasel.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IceWeasel'
-			}
-		},
-		'48': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'iRider',
-				uaUrl: 'http://www.irider.com/irider/index.htm',
-				uaCompany: 'Wymea Bay',
-				uaCompanyUrl: 'http://www.irider.com/company/index.htm',
-				uaIcon: 'irider.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iRider'
-			}
-		},
-		'49': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'iSiloX',
-				uaUrl: 'http://www.isilox.com/',
-				uaCompany: 'DC & Co.',
-				uaCompanyUrl: 'http://www.isilox.com/',
-				uaIcon: 'isilox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iSiloX'
-			}
-		},
-		'50': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'KKman',
-				uaUrl: 'http://www.kkbox.com.tw/kkman/index.html',
-				uaCompany: 'KKBOX Inc. ',
-				uaCompanyUrl: 'http://www.kkbox-inc.com/',
-				uaIcon: 'kkman.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=KKman'
-			}
-		},
-		'51': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'libwww-perl',
-				uaUrl: 'http://search.cpan.org/dist/libwww-perl/',
-				uaCompany: 'Gisle Aas',
-				uaCompanyUrl: '',
-				uaIcon: 'libwwwperl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=libwww-perl'
-			}
-		},
-		'52': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Lunascape',
-				uaUrl: 'http://www.lunascape.tv/',
-				uaCompany: 'Lunascape & Co., Ltd.',
-				uaCompanyUrl: 'http://www.lunascape.co.jp/',
-				uaIcon: 'lunascape.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Lunascape'
-			}
-		},
-		'53': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Maxthon',
-				uaUrl: 'http://www.maxthon.com/',
-				uaCompany: 'Maxthon International Limited.',
-				uaCompanyUrl: 'http://www.maxthon.com/',
-				uaIcon: 'maxthon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Maxthon'
-			}
-		},
-		'54': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Mozilla',
-				uaUrl: 'http://en.wikipedia.org/wiki/Mozilla',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.com/',
-				uaIcon: 'mozilla.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Mozilla'
-			}
-		},
-		'55': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'MultiZilla',
-				uaUrl: 'http://multizilla.mozdev.org/',
-				uaCompany: 'HJ van Rantwijk',
-				uaCompanyUrl: 'http://multizilla.mozdev.org/',
-				uaIcon: 'multizilla.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=MultiZilla'
-			}
-		},
-		'56': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'NetCaptor',
-				uaUrl: 'http://en.wikipedia.org/wiki/NetCaptor',
-				uaCompany: 'Stilesoft Inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'netcaptor.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetCaptor'
-			}
-		},
-		'57': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'NetBox',
-				uaUrl: 'http://www.netgem.com/',
-				uaCompany: 'Netgem',
-				uaCompanyUrl: 'http://www.netgem.com/',
-				uaIcon: 'netgem.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetBox'
-			}
-		},
-		'58': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'NetSurf',
-				uaUrl: 'http://www.netsurf-browser.org/',
-				uaCompany: "NetSurf's Development Team",
-				uaCompanyUrl: 'http://www.netsurf-browser.org/about/team',
-				uaIcon: 'netsurf.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetSurf'
-			}
-		},
-		'59': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Sleipnir',
-				uaUrl: 'http://en.wikipedia.org/wiki/Sleipnir_%28browser%29',
-				uaCompany: 'Fenrir Inc.',
-				uaCompanyUrl: 'http://www.fenrir-inc.com/',
-				uaIcon: 'sleipnir.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Sleipnir'
-			}
-		},
-		'61': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Swiftfox',
-				uaUrl: 'http://www.getswiftfox.com/',
-				uaCompany: 'Jason Halme',
-				uaCompanyUrl: '',
-				uaIcon: 'swiftfox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Swiftfox'
-			}
-		},
-		'62': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'Teleport Pro',
-				uaUrl: 'http://www.tenmax.com/teleport/pro/home.htm',
-				uaCompany: 'Tennyson Maxwell Information Systems, Inc.',
-				uaCompanyUrl: 'http://www.tenmax.com/',
-				uaIcon: 'teleportpro.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Teleport Pro'
-			}
-		},
-		'71': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'WebCopier',
-				uaUrl: 'http://www.maximumsoft.com/products/wc_index.html',
-				uaCompany: 'MaximumSoft Corp.',
-				uaCompanyUrl: 'http://www.maximumsoft.com/',
-				uaIcon: 'webcopier.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WebCopier'
-			}
-		},
-		'74': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Phaseout',
-				uaUrl: 'http://www.phaseout.net/',
-				uaCompany: 'PhaseOut.net',
-				uaCompanyUrl: 'http://www.phaseout.net/',
-				uaIcon: 'phaseout.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Phaseout'
-			}
-		},
-		'79': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Thunderbird',
-				uaUrl: 'http://www.mozilla.com/en-US/thunderbird/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'thunderbird.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Thunderbird'
-			}
-		},
-		'81': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Doris',
-				uaUrl: 'http://www.anygraaf.fi/browser/indexe.htm',
-				uaCompany: 'Anygraaf',
-				uaCompanyUrl: 'http://www.anygraaf.fi/',
-				uaIcon: 'doris.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Doris'
-			}
-		},
-		'82': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Enigma browser',
-				uaUrl: 'http://www.suttondesigns.com/',
-				uaCompany: 'Advanced Search Technologies, Inc.',
-				uaCompanyUrl: 'http://www.advancedsearchcorp.com/',
-				uaIcon: 'enigmabrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Enigma browser'
-			}
-		},
-		'85': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Jakarta Commons-HttpClient',
-				uaUrl: 'http://jakarta.apache.org/commons/httpclient/',
-				uaCompany: 'Apache Software Foundation',
-				uaCompanyUrl: 'http://www.apache.org/',
-				uaIcon: 'jakarta.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Jakarta Commons-HttpClient'
-			}
-		},
-		'86': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'cURL',
-				uaUrl: 'http://curl.haxx.se/',
-				uaCompany: 'team Haxx',
-				uaCompanyUrl: 'http://www.haxx.se/',
-				uaIcon: 'curl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=cURL'
-			}
-		},
-		'87': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Amaya',
-				uaUrl: 'http://www.w3.org/Amaya/',
-				uaCompany: 'World Wide Web Consortium',
-				uaCompanyUrl: 'http://www.w3.org/',
-				uaIcon: 'amaya.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Amaya'
-			}
-		},
-		'88': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'GetRight',
-				uaUrl: 'http://www.getright.com/',
-				uaCompany: 'Headlight Software, Inc.',
-				uaCompanyUrl: 'http://www.headlightinc.com/',
-				uaIcon: 'getright.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GetRight'
-			}
-		},
-		'89': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Off By One',
-				uaUrl: 'http://offbyone.com/',
-				uaCompany: 'Home Page Software Inc.',
-				uaCompanyUrl: 'http://homepagesw.com/',
-				uaIcon: 'offbyone.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Off By One'
-			}
-		},
-		'90': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Python-urllib',
-				uaUrl: 'http://www.python.org/doc/current/lib/module-urllib.html',
-				uaCompany: 'Python Software Foundation',
-				uaCompanyUrl: 'http://www.python.org/psf/',
-				uaIcon: 'pythonurllib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Python-urllib'
-			}
-		},
-		'91': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'w3m',
-				uaUrl: 'http://w3m.sourceforge.net/',
-				uaCompany: 'Sakamoto Hironori',
-				uaCompanyUrl: 'http://www2u.biglobe.ne.jp/%7Ehsaka/',
-				uaIcon: 'w3m.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=w3m'
-			}
-		},
-		'93': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'WebZIP',
-				uaUrl: 'http://www.spidersoft.com/webzip/',
-				uaCompany: 'Spidersoft',
-				uaCompanyUrl: 'http://www.spidersoft.com/',
-				uaIcon: 'webzip.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WebZIP'
-			}
-		},
-		'94': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'ICE browser',
-				uaUrl: 'http://www.icesoft.com/products/icebrowser.html',
-				uaCompany: 'ICEsoft Technologies Inc.',
-				uaCompanyUrl: 'http://www.icesoft.com/',
-				uaIcon: 'icebrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=ICE browser'
-			}
-		},
-		'96': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'IceApe',
-				uaUrl: 'http://www.debian.org/',
-				uaCompany: 'Software in the Public Interest, Inc.',
-				uaCompanyUrl: 'http://www.spi-inc.org/',
-				uaIcon: 'seamonkey.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IceApe'
-			}
-		},
-		'99': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'HotJava',
-				uaUrl: 'http://java.sun.com/products/archive/hotjava/index.html',
-				uaCompany: 'Sun Microsystems, Inc.',
-				uaCompanyUrl: 'http://www.sun.com/',
-				uaIcon: 'hotjava.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=HotJava'
-			}
-		},
-		'100': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'JoBo',
-				uaUrl: 'http://www.matuschek.net/jobo/',
-				uaCompany: 'Daniel Matuschek',
-				uaCompanyUrl: 'http://www.matuschek.net/',
-				uaIcon: 'jobo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=JoBo'
-			}
-		},
-		'105': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'POE-Component-Client-HTTP',
-				uaUrl: 'http://search.cpan.org/dist/POE-Component-Client-HTTP/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'perl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=POE-Component-Client-HTTP'
-			}
-		},
-		'111': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Snoopy',
-				uaUrl: 'http://sourceforge.net/projects/snoopy',
-				uaCompany: 'Andrei Zmievski',
-				uaCompanyUrl: '',
-				uaIcon: 'unknown.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Snoopy'
-			}
-		},
-		'117': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'NCSA Mosaic',
-				uaUrl: 'http://www.ncsa.uiuc.edu/Projects/mosaic.html',
-				uaCompany: 'NCSA',
-				uaCompanyUrl: 'http://www.ncsa.uiuc.edu/',
-				uaIcon: 'ncsa.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NCSA Mosaic'
-			}
-		},
-		'119': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Kapiko',
-				uaUrl: 'http://ufoxlab.googlepages.com/',
-				uaCompany: 'Ufox lab.',
-				uaCompanyUrl: '',
-				uaIcon: 'kapiko.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Kapiko'
-			}
-		},
-		'120': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Chrome',
-				uaUrl: 'http://www.google.com/chrome',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'chrome.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Chrome'
-			}
-		},
-		'121': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Adobe AIR runtime',
-				uaUrl: 'http://www.adobe.com/products/air/',
-				uaCompany: 'Adobe Systems',
-				uaCompanyUrl: 'http://www.adobe.com/',
-				uaIcon: 'adobeair.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Adobe AIR runtime'
-			}
-		},
-		'122': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'LWP::Simple',
-				uaUrl: 'http://search.cpan.org/perldoc?LWP::Simple',
-				uaCompany: 'CPAN',
-				uaCompanyUrl: 'http://cpan.org/',
-				uaIcon: 'lwp.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LWP::Simple'
-			}
-		},
-		'123': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'WWW::Mechanize',
-				uaUrl: 'http://search.cpan.org/dist/WWW-Mechanize/',
-				uaCompany: 'CPAN',
-				uaCompanyUrl: 'http://cpan.org/',
-				uaIcon: 'lwp.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WWW::Mechanize'
-			}
-		},
-		'124': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'Xenu',
-				uaUrl: 'http://home.snafu.de/tilman/xenulink.html',
-				uaCompany: 'Tilman Hausherr',
-				uaCompanyUrl: 'http://home.snafu.de/tilman/index.html',
-				uaIcon: 'xenu.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Xenu'
-			}
-		},
-		'125': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'SiteSucker',
-				uaUrl: 'http://www.sitesucker.us/',
-				uaCompany: 'Rick Cranisky',
-				uaCompanyUrl: '',
-				uaIcon: 'sitesucker.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SiteSucker'
-			}
-		},
-		'126': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Arora',
-				uaUrl: 'http://arora.googlecode.com/',
-				uaCompany: 'Benjamin Meyer',
-				uaCompanyUrl: 'http://www.blogger.com/profile/00185079236289035707',
-				uaIcon: 'arora.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Arora'
-			}
-		},
-		'128': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firefox (Shiretoko)',
-				uaUrl: 'http://www.mozilla.org/projects/firefox/3.1a1/releasenotes/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firefox (Shiretoko)'
-			}
-		},
-		'129': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firefox (Minefield)',
-				uaUrl: 'http://www.mozilla.org/projects/minefield/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firefox (Minefield)'
-			}
-		},
-		'130': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Iron',
-				uaUrl: 'http://www.srware.net/en/software_srware_iron.php',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'iron.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Iron'
-			}
-		},
-		'131': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Lobo',
-				uaUrl: 'http://lobobrowser.org/java-browser.jsp',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'lobo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Lobo'
-			}
-		},
-		'132': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Links',
-				uaUrl: 'http://links.twibright.com/',
-				uaCompany: 'Twibright Labs',
-				uaCompanyUrl: 'http://twibright.com/',
-				uaIcon: 'links2.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Links'
-			}
-		},
-		'133': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Mobile Firefox',
-				uaUrl: 'http://www.mozilla.com/mobile/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Mobile Firefox'
-			}
-		},
-		'134': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Lotus Notes',
-				uaUrl: 'http://www.ibm.com/software/lotus/products/notes/',
-				uaCompany: 'IBM',
-				uaCompanyUrl: 'http://www.ibm.com/',
-				uaIcon: 'lotusnotes.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Lotus Notes'
-			}
-		},
-		'135': {
-			typeId: '6',
-			metadata: {
-				uaFamily: 'Klondike',
-				uaUrl: 'http://web.archive.org/web/20071012053920/www.apachesoftware.com/products.html',
-				uaCompany: 'Apache Software Consulting Inc.',
-				uaCompanyUrl: 'http://web.archive.org/web/*/www.apachesoftware.com',
-				uaIcon: 'klondike.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Klondike'
-			}
-		},
-		'136': {
-			typeId: '6',
-			metadata: {
-				uaFamily: 'WapTiger',
-				uaUrl: 'http://www.waptiger.com/waptiger/',
-				uaCompany: 'infotiger',
-				uaCompanyUrl: 'http://www.infotiger.com/',
-				uaIcon: 'wap.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WapTiger'
-			}
-		},
-		'137': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'W3C Validator',
-				uaUrl: 'http://validator.w3.org/',
-				uaCompany: 'World Wide Web Consortium',
-				uaCompanyUrl: 'http://www.w3.org/',
-				uaIcon: 'w3.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=W3C Validator'
-			}
-		},
-		'138': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'W3C Checklink',
-				uaUrl: 'http://validator.w3.org/checklink',
-				uaCompany: 'World Wide Web Consortium',
-				uaCompanyUrl: 'http://www.w3.org/',
-				uaIcon: 'w3.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=W3C Checklink'
-			}
-		},
-		'139': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'HTMLParser',
-				uaUrl: 'http://htmlparser.sourceforge.net/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'htmlparser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=HTMLParser'
-			}
-		},
-		'140': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Java',
-				uaUrl: 'http://www.sun.com/java/',
-				uaCompany: 'Sun Microsystems, Inc.',
-				uaCompanyUrl: 'http://www.sun.com/',
-				uaIcon: 'java.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Java'
-			}
-		},
-		'141': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Bolt',
-				uaUrl: 'http://boltbrowser.com/',
-				uaCompany: 'Bitstream',
-				uaCompanyUrl: '',
-				uaIcon: 'bolt.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Bolt'
-			}
-		},
-		'142': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Demeter',
-				uaUrl: 'http://www.hurrikenux.com/Demeter/',
-				uaCompany: 'hurrikenux Creative',
-				uaCompanyUrl: 'http://www.hurrikenux.com/',
-				uaIcon: 'demeter.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Demeter'
-			}
-		},
-		'143': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'FeedParser',
-				uaUrl: 'http://feedparser.org/',
-				uaCompany: 'Mark Pilgrim',
-				uaCompanyUrl: 'http://diveintomark.org/',
-				uaIcon: 'lib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=FeedParser'
-			}
-		},
-		'144': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Orca',
-				uaUrl: 'http://www.orcabrowser.com/',
-				uaCompany: 'Avant Force team',
-				uaCompanyUrl: 'http://www.avantforce.com/',
-				uaIcon: 'orca.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Orca'
-			}
-		},
-		'145': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Fluid',
-				uaUrl: 'http://fluidapp.com/',
-				uaCompany: 'Todd Ditchendorf',
-				uaCompanyUrl: 'http://www.ditchnet.org/wp/',
-				uaIcon: 'fluid.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Fluid'
-			}
-		},
-		'146': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Bookdog',
-				uaUrl: 'http://sheepsystems.com/products/bookdog/',
-				uaCompany: 'Sheep Systems',
-				uaCompanyUrl: 'http://sheepsystems.com/',
-				uaIcon: 'bookdog.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Bookdog'
-			}
-		},
-		'147': {
-			typeId: '50',
-			metadata: {
-				uaFamily: 'Anonymouse.org',
-				uaUrl: 'http://anonymouse.org/',
-				uaCompany: 'Anonymous S.A.',
-				uaCompanyUrl: 'http://anonymouse.org/',
-				uaIcon: 'anonymouse_org.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Anonymouse.org'
-			}
-		},
-		'148': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Midori',
-				uaUrl: 'http://twotoasts.de/index.php/midori/',
-				uaCompany: 'Christian Dywan',
-				uaCompanyUrl: 'http://www.twotoasts.de/',
-				uaIcon: 'midori.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Midori'
-			}
-		},
-		'149': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Boxxe',
-				uaUrl: '',
-				uaCompany: 'Team boxee',
-				uaCompanyUrl: 'http://www.boxee.tv/',
-				uaIcon: 'boxee.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Boxxe'
-			}
-		},
-		'150': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'gPodder',
-				uaUrl: 'http://gpodder.org/',
-				uaCompany: 'Thomas Perl and the gPodder Team',
-				uaCompanyUrl: '',
-				uaIcon: 'gpodder.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=gPodder'
-			}
-		},
-		'151': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Obigo',
-				uaUrl: 'http://en.wikipedia.org/wiki/Obigo_Browser',
-				uaCompany: 'Obigo Ltd',
-				uaCompanyUrl: 'http://www.obigo.com/',
-				uaIcon: 'obigo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Obigo'
-			}
-		},
-		'152': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'SEMC Browser',
-				uaUrl: '',
-				uaCompany: 'Sony Ericsson Mobile Communications AB',
-				uaCompanyUrl: 'http://www.sonyericsson.com/',
-				uaIcon: 'semc.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SEMC Browser'
-			}
-		},
-		'153': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firefox (GranParadiso)',
-				uaUrl: 'https://wiki.mozilla.org/Firefox3',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firefox (GranParadiso)'
-			}
-		},
-		'154': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'WDG Validator',
-				uaUrl: 'http://www.htmlhelp.com/tools/validator/',
-				uaCompany: 'Web Design Group',
-				uaCompanyUrl: 'http://www.htmlhelp.com/',
-				uaIcon: 'wdg.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WDG Validator'
-			}
-		},
-		'155': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'WDG CSSCheck',
-				uaUrl: 'http://www.htmlhelp.com/tools/csscheck/',
-				uaCompany: 'Web Design Group',
-				uaCompanyUrl: 'http://www.htmlhelp.com/',
-				uaIcon: 'wdg.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WDG CSSCheck'
-			}
-		},
-		'156': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'WDG Page Valet',
-				uaUrl: 'http://valet.htmlhelp.com/page/',
-				uaCompany: 'Web Design Group',
-				uaCompanyUrl: 'http://www.htmlhelp.com/',
-				uaIcon: 'wdg.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WDG Page Valet'
-			}
-		},
-		'157': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'IE Mobile',
-				uaUrl: 'http://www.microsoft.com/windowsmobile/en-us/downloads/microsoft/internet-explorer-mobile.mspx',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'iemobile.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IE Mobile'
-			}
-		},
-		'158': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'BlackBerry Browser',
-				uaUrl: 'http://www.blackberry.com/',
-				uaCompany: 'Research In Motion Limited',
-				uaCompanyUrl: 'http://www.rim.com/',
-				uaIcon: 'blackberry.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BlackBerry Browser'
-			}
-		},
-		'159': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Polaris',
-				uaUrl: 'http://www.infraware.co.kr/eng/01_product/product02.asp',
-				uaCompany: 'Infraware',
-				uaCompanyUrl: 'http://www.infraware.co.kr/',
-				uaIcon: 'polaris.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Polaris'
-			}
-		},
-		'160': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Hv3',
-				uaUrl: 'http://tkhtml.tcl.tk/hv3.html',
-				uaCompany: 'tkhtml.tcl.tk',
-				uaCompanyUrl: 'http://tkhtml.tcl.tk/',
-				uaIcon: 'hv3.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Hv3'
-			}
-		},
-		'161': {
-			typeId: '6',
-			metadata: {
-				uaFamily: 'WinWap',
-				uaUrl: 'http://www.winwap.com/mobile_applications/winwap_browser',
-				uaCompany: 'Winwap Technologies',
-				uaCompanyUrl: 'http://www.winwap.com/',
-				uaIcon: 'winwap.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WinWap'
-			}
-		},
-		'162': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'XBMC',
-				uaUrl: 'http://xbmc.org/',
-				uaCompany: 'Team-XBMC',
-				uaCompanyUrl: 'http://xbmc.org/about/team/',
-				uaIcon: 'xbmc.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=XBMC'
-			}
-		},
-		'163': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'XML-RPC for PHP',
-				uaUrl: 'http://phpxmlrpc.sourceforge.net/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'php-xmlrpc.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=XML-RPC for PHP'
-			}
-		},
-		'165': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'FlyCast',
-				uaUrl: 'http://www.flycast.fm/',
-				uaCompany: 'FlyCast Inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'flycast.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=FlyCast'
-			}
-		},
-		'166': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Bloglines',
-				uaUrl: 'http://www.bloglines.com/',
-				uaCompany: 'IAS Search & Media',
-				uaCompanyUrl: 'http://www.iac.com/',
-				uaIcon: 'bloglines.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Bloglines'
-			}
-		},
-		'167': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Gregarius',
-				uaUrl: 'http://devlog.gregarius.net/',
-				uaCompany: 'Marco Bonetti',
-				uaCompanyUrl: 'http://www.linkedin.com/in/mbonetti',
-				uaIcon: 'gregarius.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Gregarius'
-			}
-		},
-		'168': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'SimplePie',
-				uaUrl: 'http://simplepie.org/',
-				uaCompany: 'Ryan Parman and Geoffrey Sneddon',
-				uaCompanyUrl: '',
-				uaIcon: 'simplepie.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SimplePie'
-			}
-		},
-		'169': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'PycURL',
-				uaUrl: 'http://pycurl.sourceforge.net/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'curl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PycURL'
-			}
-		},
-		'170': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Apple-PubSub',
-				uaUrl: 'http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/pubsub.1.html',
-				uaCompany: 'Apple Inc.',
-				uaCompanyUrl: 'http://www.apple.com/',
-				uaIcon: 'apple.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Apple-PubSub'
-			}
-		},
-		'171': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Feedfetcher-Google',
-				uaUrl: 'http://www.google.com/feedfetcher.html',
-				uaCompany: 'Google',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'feedfetcher-google.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Feedfetcher-Google'
-			}
-		},
-		'172': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'FeedValidator',
-				uaUrl: 'http://feedvalidator.org/',
-				uaCompany: 'Mark Pilgrim',
-				uaCompanyUrl: 'http://diveintomark.org/',
-				uaIcon: 'feedvalidator.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=FeedValidator'
-			}
-		},
-		'173': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'MagpieRSS',
-				uaUrl: 'http://magpierss.sourceforge.net/',
-				uaCompany: 'kellan',
-				uaCompanyUrl: '',
-				uaIcon: 'magpierss.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=MagpieRSS'
-			}
-		},
-		'174': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'BlogBridge',
-				uaUrl: 'http://www.blogbridge.com/',
-				uaCompany: 'Salas Associates, Inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'blogbridge.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BlogBridge'
-			}
-		},
-		'175': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Miro',
-				uaUrl: 'http://www.getmiro.com/',
-				uaCompany: 'Participatory Culture Foundation',
-				uaCompanyUrl: 'http://www.participatoryculture.org/',
-				uaIcon: 'miro.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Miro'
-			}
-		},
-		'176': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Liferea',
-				uaUrl: 'http://liferea.sourceforge.net/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'liferea.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Liferea'
-			}
-		},
-		'177': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Seznam RSS reader',
-				uaUrl: '',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznamrssreader.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Seznam RSS reader'
-			}
-		},
-		'178': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'PHP',
-				uaUrl: 'http://php.net/',
-				uaCompany: 'The PHP Group',
-				uaCompanyUrl: '',
-				uaIcon: 'php.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PHP'
-			}
-		},
-		'179': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'REL Link Checker Lite',
-				uaUrl: 'http://www.relsoftware.com/rlc/',
-				uaCompany: 'REL Software, Inc.',
-				uaCompanyUrl: 'http://www.relsoftware.com/company/',
-				uaIcon: 'RELlinkchecker.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=REL Link Checker Lite'
-			}
-		},
-		'180': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'CPG Dragonfly RSS Module',
-				uaUrl: 'http://dragonflycms.org/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'dragonflycms.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=CPG Dragonfly RSS Module'
-			}
-		},
-		'181': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Newsbeuter',
-				uaUrl: 'http://www.newsbeuter.org/',
-				uaCompany: 'Andreas Krennmair',
-				uaCompanyUrl: 'http://synflood.at/',
-				uaIcon: 'newsbeuter.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Newsbeuter'
-			}
-		},
-		'182': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'W3C CSS Validator',
-				uaUrl: 'http://jigsaw.w3.org/css-validator/',
-				uaCompany: 'World Wide Web Consortium',
-				uaCompanyUrl: 'http://www.w3.org/',
-				uaIcon: 'w3.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=W3C CSS Validator'
-			}
-		},
-		'183': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'PHP link checker',
-				uaUrl: 'http://www.hotscripts.com/listing/php-link-checker/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'php.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PHP link checker'
-			}
-		},
-		'184': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'GoldenPod',
-				uaUrl: 'http://random.zerodogg.org/goldenpod',
-				uaCompany: 'Eskild Hustvedt',
-				uaCompanyUrl: 'http://random.zerodogg.org/',
-				uaIcon: 'perl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GoldenPod'
-			}
-		},
-		'185': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Cheshire',
-				uaUrl: 'http://greenhouse.aol.com/prod.jsp?prod_id=32',
-				uaCompany: 'America Online, Inc.',
-				uaCompanyUrl: 'http://www.aol.com/',
-				uaIcon: 'aol.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Cheshire'
-			}
-		},
-		'187': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'CometBird',
-				uaUrl: 'http://www.cometbird.com/',
-				uaCompany: 'cometbird.com',
-				uaCompanyUrl: '',
-				uaIcon: 'cometbird.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=CometBird'
-			}
-		},
-		'188': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'IceCat',
-				uaUrl: 'http://www.gnu.org/software/gnuzilla/',
-				uaCompany: 'Free Software Foundation, Inc.',
-				uaCompanyUrl: 'http://www.fsf.org/',
-				uaIcon: 'icecat.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IceCat'
-			}
-		},
-		'189': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Stainless',
-				uaUrl: 'http://www.stainlessapp.com/',
-				uaCompany: 'Mesa Dynamics, LLC',
-				uaCompanyUrl: 'http://www.mesadynamics.com/',
-				uaIcon: 'stainless.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Stainless'
-			}
-		},
-		'190': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Prism',
-				uaUrl: 'http://prism.mozilla.com/',
-				uaCompany: 'Mozilla Labs',
-				uaCompanyUrl: 'http://labs.mozilla.com/',
-				uaIcon: 'prism.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Prism'
-			}
-		},
-		'191': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'MPlayer',
-				uaUrl: 'http://www.mplayerhq.hu/',
-				uaCompany: 'The MPlayer Project',
-				uaCompanyUrl: '',
-				uaIcon: 'mplayer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=MPlayer'
-			}
-		},
-		'192': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'ActiveXperts Network Monitor',
-				uaUrl: 'http://www.activexperts.com/activmonitor/',
-				uaCompany: 'ActiveXperts Software B.V.',
-				uaCompanyUrl: 'http://www.activexperts.com/',
-				uaIcon: 'activexperts-network-monitor.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=ActiveXperts Network Monitor'
-			}
-		},
-		'193': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Motorola Internet Browser',
-				uaUrl: 'http://www.motorola.com/content.jsp?globalObjectId=1827-4343',
-				uaCompany: 'Motorola, Inc.',
-				uaCompanyUrl: 'http://www.motorola.com/',
-				uaIcon: 'mib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Motorola Internet Browser'
-			}
-		},
-		'194': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Abilon',
-				uaUrl: '',
-				uaCompany: 'SisyphSoft',
-				uaCompanyUrl: 'http://web.archive.org/web/20050721080030/http://www.abilon.org/',
-				uaIcon: 'abilon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Abilon'
-			}
-		},
-		'195': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'HTTP nagios plugin',
-				uaUrl: '',
-				uaCompany: 'Nagios Enterprises, LLC.',
-				uaCompanyUrl: 'http://www.nagios.org/',
-				uaIcon: 'nagios.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=HTTP nagios plugin'
-			}
-		},
-		'196': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Windows Media Player',
-				uaUrl: 'http://www.microsoft.com/windows/windowsmedia/',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'wmp.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Windows Media Player'
-			}
-		},
-		'197': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'VLC media player',
-				uaUrl: 'http://www.videolan.org/vlc/',
-				uaCompany: 'VideoLAN team',
-				uaCompanyUrl: 'http://www.videolan.org/',
-				uaIcon: 'vlc.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=VLC media player'
-			}
-		},
-		'198': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'P3P Validator',
-				uaUrl: 'http://www.w3.org/P3P/validator.html',
-				uaCompany: 'World Wide Web Consortium',
-				uaCompanyUrl: 'http://www.w3.org/',
-				uaIcon: 'w3.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=P3P Validator'
-			}
-		},
-		'199': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'CSE HTML Validator',
-				uaUrl: 'http://online.htmlvalidator.com/php/onlinevallite.php',
-				uaCompany: 'AI Internet Solutions',
-				uaCompanyUrl: 'http://www.htmlvalidator.com/',
-				uaIcon: 'csehtmlvalidator.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=CSE HTML Validator'
-			}
-		},
-		'200': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Omea Reader',
-				uaUrl: 'http://www.jetbrains.com/omea/reader/',
-				uaCompany: 'JetBrains',
-				uaCompanyUrl: 'http://www.jetbrains.com/',
-				uaIcon: 'omeareader.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Omea Reader'
-			}
-		},
-		'201': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'GSiteCrawler',
-				uaUrl: 'http://gsitecrawler.com/',
-				uaCompany: 'SOFTplus Entwicklungen GmbH',
-				uaCompanyUrl: 'http://www.softplus.net/',
-				uaIcon: 'gsitecrawler.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GSiteCrawler'
-			}
-		},
-		'202': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'YahooFeedSeeker',
-				uaUrl: 'http://publisher.yahoo.com/rssguide',
-				uaCompany: 'Yahoo! Inc',
-				uaCompanyUrl: 'http://www.yahoo.com/',
-				uaIcon: 'YahooFeedSeeker.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=YahooFeedSeeker'
-			}
-		},
-		'204': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'TheWorld Browser',
-				uaUrl: 'http://www.theworld.cn/twen/',
-				uaCompany: 'Phoenix Studio',
-				uaCompanyUrl: 'http://www.phoenixstudio.org/',
-				uaIcon: 'the_world.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=TheWorld Browser'
-			}
-		},
-		'205': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'WebCollage',
-				uaUrl: 'http://www.jwz.org/webcollage/',
-				uaCompany: 'Jamie Zawinski',
-				uaCompanyUrl: 'http://www.jwz.org/',
-				uaIcon: 'webcollage.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WebCollage'
-			}
-		},
-		'206': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'NewsGatorOnline',
-				uaUrl: 'http://www.newsgator.com/',
-				uaCompany: 'NewsGator Technologies, Inc.',
-				uaCompanyUrl: 'http://www.newsgator.com/companyinfo/default.aspx',
-				uaIcon: 'newsgator-online.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NewsGatorOnline'
-			}
-		},
-		'207': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'PRTG Network Monitor',
-				uaUrl: 'http://www.paessler.com/prtg',
-				uaCompany: 'Paessler AG',
-				uaCompanyUrl: 'http://www.paessler.com/',
-				uaIcon: 'PRTG_Network_Monitor.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PRTG Network Monitor'
-			}
-		},
-		'208': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Songbird',
-				uaUrl: 'http://getsongbird.com/',
-				uaCompany: 'Pioneers of the Inevitable',
-				uaCompanyUrl: 'http://getsongbird.com/about/',
-				uaIcon: 'songbird.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Songbird'
-			}
-		},
-		'209': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'RSS Radio',
-				uaUrl: 'http://www.dorada.co.uk/',
-				uaCompany: 'Dorada Software',
-				uaCompanyUrl: '',
-				uaIcon: 'rssradio.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=RSS Radio'
-			}
-		},
-		'210': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Feed::Find',
-				uaUrl: 'http://search.cpan.org/dist/Feed-Find/',
-				uaCompany: 'Benjamin Trott',
-				uaCompanyUrl: '',
-				uaIcon: 'perl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Feed::Find'
-			}
-		},
-		'211': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Palm Pre web browser',
-				uaUrl: 'http://www.palm.com/us/products/phones/pre/index.html',
-				uaCompany: 'Palm Inc.',
-				uaCompanyUrl: 'http://www.palm.com/',
-				uaIcon: 'palmpre.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Palm Pre web browser'
-			}
-		},
-		'212': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firefox (BonEcho)',
-				uaUrl: 'http://www.mozilla.org/projects/bonecho/releases/2.0a1.html',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firefox (BonEcho)'
-			}
-		},
-		'213': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'QuickTime',
-				uaUrl: 'http://www.apple.com/quicktime/',
-				uaCompany: 'Apple Inc.',
-				uaCompanyUrl: 'http://www.apple.com/',
-				uaIcon: 'quicktime.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=QuickTime'
-			}
-		},
-		'214': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'PHPcrawl',
-				uaUrl: 'http://phpcrawl.cuab.de/',
-				uaCompany: 'Uwe Hunfeld',
-				uaCompanyUrl: '',
-				uaIcon: 'php.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PHPcrawl'
-			}
-		},
-		'216': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'GreenBrowser',
-				uaUrl: 'http://www.morequick.com/indexen.htm',
-				uaCompany: 'More Quick Tools',
-				uaCompanyUrl: 'http://www.morequick.com/',
-				uaIcon: 'green_browser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GreenBrowser'
-			}
-		},
-		'217': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Awasu',
-				uaUrl: 'http://www.awasu.com/',
-				uaCompany: 'Awasu Pty. Ltd.',
-				uaCompanyUrl: '',
-				uaIcon: 'awasu.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Awasu'
-			}
-		},
-		'218': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'CorePlayer',
-				uaUrl: 'http://www.coreplayer.com/',
-				uaCompany: 'CoreCodec, inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'CorePlayer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=CorePlayer'
-			}
-		},
-		'219': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'QtWeb',
-				uaUrl: 'http://www.qtweb.net/',
-				uaCompany: 'QtWeb.NET',
-				uaCompanyUrl: '',
-				uaIcon: 'qt_web.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=QtWeb'
-			}
-		},
-		'220': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'TeaShark',
-				uaUrl: 'http://www.teashark.com/',
-				uaCompany: 'TeaShark',
-				uaCompanyUrl: '',
-				uaIcon: 'teashark.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=TeaShark'
-			}
-		},
-		'221': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'LibSoup',
-				uaUrl: 'http://live.gnome.org/LibSoup',
-				uaCompany: 'The GNOME Project',
-				uaCompanyUrl: 'http://www.gnome.org/',
-				uaIcon: 'libsoup.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LibSoup'
-			}
-		},
-		'222': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'NetNewsWire',
-				uaUrl: 'http://www.newsgator.com/Individuals/NetNewsWire/',
-				uaCompany: 'NewsGator Technologies, Inc.',
-				uaCompanyUrl: 'http://www.newsgator.com/',
-				uaIcon: 'netnewswire.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetNewsWire'
-			}
-		},
-		'223': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Google App Engine',
-				uaUrl: 'http://code.google.com/appengine/',
-				uaCompany: 'Google',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'google_appengine.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Google App Engine'
-			}
-		},
-		'225': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'UC Browser',
-				uaUrl: 'http://www.ucweb.com/English/UCbrowser/index.html',
-				uaCompany: 'UCWEB Technology Ltd.',
-				uaCompanyUrl: 'http://www.ucweb.com/',
-				uaIcon: 'ucweb.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=UC Browser'
-			}
-		},
-		'226': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Nokia Web Browser',
-				uaUrl: 'http://nokia.com/browser',
-				uaCompany: 'Nokia',
-				uaCompanyUrl: 'http://www.nokia.com/',
-				uaIcon: 'nokia.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Nokia Web Browser'
-			}
-		},
-		'227': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'LFTP',
-				uaUrl: 'http://lftp.yar.ru/',
-				uaCompany: 'Alexander V. Lukyanov',
-				uaCompanyUrl: '',
-				uaIcon: 'lftp.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LFTP'
-			}
-		},
-		'228': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Oregano',
-				uaUrl: 'http://www.oreganouk.net/oregano2.html',
-				uaCompany: 'Genesys Developments Ltd',
-				uaCompanyUrl: 'http://www.oreganouk.net/',
-				uaIcon: 'oregano.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Oregano'
-			}
-		},
-		'229': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Summer',
-				uaUrl: 'http://wrya.net/services/trac/summer',
-				uaCompany: 'Robin Sonefors',
-				uaCompanyUrl: 'http://flukkost.nu/',
-				uaIcon: 'libsummer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Summer'
-			}
-		},
-		'230': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Acoo Browser',
-				uaUrl: 'http://www.acoobrowser.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'acco.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Acoo Browser'
-			}
-		},
-		'231': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'NewsFox',
-				uaUrl: 'http://newsfox.mozdev.org/',
-				uaCompany: 'NewsFox team',
-				uaCompanyUrl: 'http://newsfox.mozdev.org/team.html',
-				uaIcon: 'newsfox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NewsFox'
-			}
-		},
-		'232': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Hydra Browser',
-				uaUrl: 'http://hydrabrowser.com/',
-				uaCompany: 'Quantum',
-				uaCompanyUrl: '',
-				uaIcon: 'hydrabrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Hydra Browser'
-			}
-		},
-		'233': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'wKiosk',
-				uaUrl: 'http://www.app4mac.com/store/index.php?target=products&product_id=9',
-				uaCompany: 'app4mac Inc.',
-				uaCompanyUrl: 'http://www.app4mac.com/',
-				uaIcon: 'wkiosk.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=wKiosk'
-			}
-		},
-		'234': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Paparazzi!',
-				uaUrl: 'http://derailer.org/paparazzi/',
-				uaCompany: 'Nate Weaver (Wevah)',
-				uaCompanyUrl: 'http://derailer.org/',
-				uaIcon: 'paparazzi.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Paparazzi!'
-			}
-		},
-		'235': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'xine',
-				uaUrl: 'http://www.xine-project.org/',
-				uaCompany: 'xine team',
-				uaCompanyUrl: 'http://www.xine-project.org/authors',
-				uaIcon: 'xine.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=xine'
-			}
-		},
-		'236': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'webfs',
-				uaUrl: 'http://plan9.bell-labs.com/magic/man2html/4/webfs',
-				uaCompany: 'Lucent Technologies',
-				uaCompanyUrl: 'http://plan9.bell-labs.com/plan9/',
-				uaIcon: 'plan9.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=webfs'
-			}
-		},
-		'237': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'NewsBreak',
-				uaUrl: 'http://www.iliumsoft.com/site/nw/newsbreak.php',
-				uaCompany: 'Ilium Software, Inc.',
-				uaCompanyUrl: 'http://www.iliumsoft.com/',
-				uaIcon: 'newsbreak.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NewsBreak'
-			}
-		},
-		'238': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'LinkbackPlugin for Laconica',
-				uaUrl: 'http://laconi.ca/',
-				uaCompany: 'Laconica Developer Community',
-				uaCompanyUrl: 'http://laconi.ca/trac/wiki/DeveloperCommunity',
-				uaIcon: 'laconica.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LinkbackPlugin for Laconica'
-			}
-		},
-		'239': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Microsoft WebDAV client',
-				uaUrl: '',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'webdav.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Microsoft WebDAV client'
-			}
-		},
-		'240': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'GnomeVFS',
-				uaUrl: 'http://developer.gnome.org/doc/API/2.0/gnome-vfs-2',
-				uaCompany: 'The GNOME Project',
-				uaCompanyUrl: 'http://www.gnome.org/',
-				uaIcon: 'webdav.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GnomeVFS'
-			}
-		},
-		'241': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Uzbl',
-				uaUrl: 'http://www.uzbl.org/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'uzbl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Uzbl'
-			}
-		},
-		'242': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'Cynthia',
-				uaUrl: 'http://www.contentquality.com/',
-				uaCompany: 'HiSoftware Inc.',
-				uaCompanyUrl: 'http://www.hisoftware.com/',
-				uaIcon: 'cynthia.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Cynthia'
-			}
-		},
-		'243': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Sage',
-				uaUrl: 'http://sage.mozdev.org',
-				uaCompany: 'Peter Andrews',
-				uaCompanyUrl: 'http://petea.org/',
-				uaIcon: 'sage.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Sage'
-			}
-		},
-		'244': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Banshee',
-				uaUrl: 'http://banshee-project.org/',
-				uaCompany: 'Novell, Inc.',
-				uaCompanyUrl: 'http://www.novell.com/',
-				uaIcon: 'banshee.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Banshee'
-			}
-		},
-		'245': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Wyzo',
-				uaUrl: 'http://www.wyzo.com/',
-				uaCompany: 'Radical Software Ltd.',
-				uaCompanyUrl: 'http://www.radicalsoft.com/',
-				uaIcon: 'wyzo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Wyzo'
-			}
-		},
-		'246': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'RSSOwl',
-				uaUrl: 'http://www.rssowl.org/',
-				uaCompany: 'Benjamin Pasero',
-				uaCompanyUrl: '',
-				uaIcon: 'rssowl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=RSSOwl'
-			}
-		},
-		'247': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'ABrowse',
-				uaUrl: 'http://en.wikipedia.org/wiki/ABrowse',
-				uaCompany: 'Kurt Skauen',
-				uaCompanyUrl: 'http://www.syllable.org/',
-				uaIcon: 'abrowse.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=ABrowse'
-			}
-		},
-		'248': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Funambol Outlook Sync Client',
-				uaUrl: 'https://www.forge.funambol.org/download/',
-				uaCompany: 'Funambol, Inc.',
-				uaCompanyUrl: 'http://funambol.com/',
-				uaIcon: 'funambol-outlook.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Funambol Outlook Sync Client'
-			}
-		},
-		'249': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Funambol Mozilla Sync Client',
-				uaUrl: 'https://mozilla-plugin.forge.funambol.org/ ',
-				uaCompany: 'Carlo Codega',
-				uaCompanyUrl: 'http://sazilla.blogspot.com',
-				uaIcon: 'funambol-mozilla.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Funambol Mozilla Sync Client'
-			}
-		},
-		'250': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'RSS Menu',
-				uaUrl: 'http://www.edot-studios.com/webgroups2/index.php?menu_item=212',
-				uaCompany: 'e dot studios',
-				uaCompanyUrl: 'http://www.edot-studios.com/',
-				uaIcon: 'rss_menu.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=RSS Menu'
-			}
-		},
-		'251': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'foobar2000',
-				uaUrl: 'http://www.foobar2000.org/',
-				uaCompany: 'Peter Pawlowski',
-				uaCompanyUrl: '',
-				uaIcon: 'foobar2000.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=foobar2000'
-			}
-		},
-		'252': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'GStreamer',
-				uaUrl: 'http://gstreamer.freedesktop.org/',
-				uaCompany: 'GStreamer community',
-				uaCompanyUrl: 'http://gstreamer.freedesktop.org/',
-				uaIcon: 'GStreamer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GStreamer'
-			}
-		},
-		'253': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'NetFront Mobile Content Viewer',
-				uaUrl: 'http://www.access-company.com/products/mobile_solutions/netfrontmobile/contentviewer/index.html',
-				uaCompany: 'ACCESS CO., LTD.',
-				uaCompanyUrl: 'http://www.access-company.com/',
-				uaIcon: 'netfront.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetFront Mobile Content Viewer'
-			}
-		},
-		'254': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'PHP OpenID library',
-				uaUrl: 'http://openidenabled.com/php-openid/',
-				uaCompany: 'JanRain, Inc.',
-				uaCompanyUrl: 'http://www.janrain.com/',
-				uaIcon: 'PHP_OpenID_lib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PHP OpenID library'
-			}
-		},
-		'255': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Blackbird',
-				uaUrl: 'http://www.blackbirdbrowser.com/',
-				uaCompany: '40A, Inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'blackbird.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Blackbird'
-			}
-		},
-		'256': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'GreatNews',
-				uaUrl: 'http://www.curiostudio.com/',
-				uaCompany: 'Curio Studio',
-				uaCompanyUrl: '',
-				uaIcon: 'GreatNews.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GreatNews'
-			}
-		},
-		'257': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'DeskBrowse',
-				uaUrl: 'http://www.deskbrowse.org/',
-				uaCompany: 'Off Leash Developments, Inc',
-				uaCompanyUrl: 'http://offleashdevelopments.com/',
-				uaIcon: 'deskbrowse.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=DeskBrowse'
-			}
-		},
-		'258': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Tulip Chain',
-				uaUrl: 'http://ostermiller.org/tulipchain/',
-				uaCompany: 'Stephen "deadsea" Ostermiller',
-				uaCompanyUrl: 'http://ostermiller.org/',
-				uaIcon: 'TulipChain.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Tulip Chain'
-			}
-		},
-		'259': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'Axel',
-				uaUrl: 'http://axel.alioth.debian.org/',
-				uaCompany: 'Y Giridhar Appaji Nag',
-				uaCompanyUrl: 'http://www.appaji.net/',
-				uaIcon: 'terminal.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Axel'
-			}
-		},
-		'260': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'MicroB',
-				uaUrl: 'http://en.wikipedia.org/wiki/MicroB',
-				uaCompany: 'maemo project',
-				uaCompanyUrl: 'http://maemo.org/',
-				uaIcon: 'microb.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=MicroB'
-			}
-		},
-		'261': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Tear',
-				uaUrl: 'http://tear.garage.maemo.org/',
-				uaCompany: 'Kamen Bundev',
-				uaCompanyUrl: 'http://bundyo.org/',
-				uaIcon: 'tear.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Tear'
-			}
-		},
-		'262': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'LinkExaminer',
-				uaUrl: 'http://www.analogx.com/contents/download/Network/lnkexam/Freeware.htm',
-				uaCompany: 'AnalogX, LLC.',
-				uaCompanyUrl: 'http://www.analogx.com/',
-				uaIcon: 'LinkExaminer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LinkExaminer'
-			}
-		},
-		'263': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Abolimba',
-				uaUrl: 'http://www.aborange.de/products/freeware/abolimba-multibrowser.php',
-				uaCompany: 'Mathias Gerlach, Jochen Milchsack',
-				uaCompanyUrl: 'http://www.aborange.de/',
-				uaIcon: 'abolimba.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Abolimba'
-			}
-		},
-		'264': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Beonex',
-				uaUrl: 'http://www.beonex.com/',
-				uaCompany: 'Ben Bucksch',
-				uaCompanyUrl: 'http://www.bucksch.org/',
-				uaIcon: 'beonex.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Beonex'
-			}
-		},
-		'265': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'DocZilla',
-				uaUrl: 'http://www.doczilla.com/',
-				uaCompany: 'CITEC',
-				uaCompanyUrl: 'http://www.citec.com/',
-				uaIcon: 'doczilla.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=DocZilla'
-			}
-		},
-		'266': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'retawq',
-				uaUrl: 'http://retawq.sourceforge.net/',
-				uaCompany: 'Arne Thoma\xdfen',
-				uaCompanyUrl: '',
-				uaIcon: 'terminal.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=retawq'
-			}
-		},
-		'267': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Jasmine',
-				uaUrl: '',
-				uaCompany: 'SAMSUNG',
-				uaCompanyUrl: 'http://www.samsung.com/',
-				uaIcon: 'jasmine.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Jasmine'
-			}
-		},
-		'268': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Opera Mini',
-				uaUrl: 'http://www.operamini.com',
-				uaCompany: 'Opera Software ASA.',
-				uaCompanyUrl: 'http://www.opera.com/',
-				uaIcon: 'opera.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Opera Mini'
-			}
-		},
-		'269': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Dooble',
-				uaUrl: 'http://dooble.sourceforge.net/',
-				uaCompany: 'Dooble team',
-				uaCompanyUrl: '',
-				uaIcon: 'dooble.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Dooble'
-			}
-		},
-		'270': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Madfox',
-				uaUrl: 'http://en.wikipedia.org/wiki/Madfox',
-				uaCompany: 'Robin Lu',
-				uaCompanyUrl: '',
-				uaIcon: 'madfox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Madfox'
-			}
-		},
-		'271': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'DownloadStudio',
-				uaUrl: 'http://www.conceiva.com/products/downloadstudio/default.asp',
-				uaCompany: 'Conceiva',
-				uaCompanyUrl: 'http://www.conceiva.com/',
-				uaIcon: 'downloadstudio.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=DownloadStudio'
-			}
-		},
-		'272': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'WinPodder',
-				uaUrl: 'http://winpodder.com/',
-				uaCompany: 'Mike Versteeg',
-				uaCompanyUrl: 'http://mikeversteeg.com/',
-				uaIcon: 'winpodder.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WinPodder'
-			}
-		},
-		'273': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Bunjalloo',
-				uaUrl: 'http://code.google.com/p/quirkysoft/',
-				uaCompany: 'quirkysoft',
-				uaCompanyUrl: '',
-				uaIcon: 'bunjalloo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Bunjalloo'
-			}
-		},
-		'274': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'LinkChecker',
-				uaUrl: 'http://linkchecker.sourceforge.net/',
-				uaCompany: 'Bastian Kleineidam',
-				uaCompanyUrl: '',
-				uaIcon: 'LinkChecker.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LinkChecker'
-			}
-		},
-		'276': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'urlgrabber',
-				uaUrl: 'http://linux.duke.edu/projects/urlgrabber/',
-				uaCompany: 'Michael Stenner and Ryan Tomayko',
-				uaCompanyUrl: '',
-				uaIcon: 'php.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=urlgrabber'
-			}
-		},
-		'277': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Spicebird',
-				uaUrl: 'http://www.spicebird.com/',
-				uaCompany: 'Synovel Technologies',
-				uaCompanyUrl: 'http://www.synovel.com/',
-				uaIcon: 'spicebird.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Spicebird'
-			}
-		},
-		'278': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firefox (Namoroka)',
-				uaUrl: 'https://wiki.mozilla.org/Firefox/Namoroka',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firefox (Namoroka)'
-			}
-		},
-		'279': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Rekonq',
-				uaUrl: 'http://rekonq.kde.org/',
-				uaCompany: 'Andrea Diamantini',
-				uaCompanyUrl: 'http://www.adjam.org/',
-				uaIcon: 'rekonq.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Rekonq'
-			}
-		},
-		'280': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'Multipage Validator',
-				uaUrl: 'http://www.validator.ca/',
-				uaCompany: 'R\xe9seau Proze',
-				uaCompanyUrl: 'http://www.proze.net/',
-				uaIcon: 'MultipageValidator.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Multipage Validator'
-			}
-		},
-		'281': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'X-Smiles',
-				uaUrl: 'http://www.xsmiles.org/',
-				uaCompany: 'X-Smiles.org',
-				uaCompanyUrl: '',
-				uaIcon: 'x-smiles.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=X-Smiles'
-			}
-		},
-		'282': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'WinHTTP',
-				uaUrl: 'http://msdn.microsoft.com/en-us/library/aa382925(VS.85).aspx',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'DLLicon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WinHTTP'
-			}
-		},
-		'283': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'Xaldon WebSpider',
-				uaUrl: 'http://www.xaldon.de/products_webspider.html',
-				uaCompany: 'xaldon Technologies',
-				uaCompanyUrl: 'http://www.xaldon.de/',
-				uaIcon: 'XaldonWebSpider.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Xaldon WebSpider'
-			}
-		},
-		'284': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Seznam WAP Proxy',
-				uaUrl: 'http://www.smobil.cz/mobilni-vyhledavani',
-				uaCompany: 'Seznam.cz, a.s.',
-				uaCompanyUrl: 'http://www.seznam.cz/',
-				uaIcon: 'seznam.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Seznam WAP Proxy'
-			}
-		},
-		'285': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Google Wireless Transcoder',
-				uaUrl: 'http://google.com/gwt/n',
-				uaCompany: 'Google',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'feedfetcher-google.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Google Wireless Transcoder'
-			}
-		},
-		'286': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Google Listen',
-				uaUrl: 'http://listen.googlelabs.com/',
-				uaCompany: 'Google',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'google_listen.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Google Listen'
-			}
-		},
-		'287': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Typhoeus',
-				uaUrl: 'https://github.com/typhoeus/typhoeus',
-				uaCompany: 'Paul Dix',
-				uaCompanyUrl: 'http://www.pauldix.net/',
-				uaIcon: 'typhoeus.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Typhoeus'
-			}
-		},
-		'288': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'OWB',
-				uaUrl: 'http://www.sand-labs.org/owb',
-				uaCompany: 'Sand-labs.org',
-				uaCompanyUrl: 'http://www.sand-labs.org/',
-				uaIcon: 'owb.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=OWB'
-			}
-		},
-		'289': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Browzar',
-				uaUrl: 'http://www.browzar.com/',
-				uaCompany: 'Browzar Ltd',
-				uaCompanyUrl: '',
-				uaIcon: 'browzar.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Browzar'
-			}
-		},
-		'290': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Claws Mail GtkHtml2 plugin',
-				uaUrl: 'http://www.claws-mail.org/plugin.php?plugin=gtkhtml2',
-				uaCompany: 'Colin Leroy',
-				uaCompanyUrl: '',
-				uaIcon: 'Claws_Mail_GtkHtml_plugin.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Claws Mail GtkHtml2 plugin'
-			}
-		},
-		'291': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Vuze',
-				uaUrl: 'http://www.vuze.com/',
-				uaCompany: 'Vuze, Inc',
-				uaCompanyUrl: '',
-				uaIcon: 'vuze.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Vuze'
-			}
-		},
-		'292': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'GlobalMojo',
-				uaUrl: 'http://globalmojo.com/',
-				uaCompany: 'KPG VENTURES',
-				uaCompanyUrl: 'http://www.kpgventures.com/',
-				uaIcon: 'globalmojo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GlobalMojo'
-			}
-		},
-		'293': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'GOM Player',
-				uaUrl: 'http://www.gomlab.com/',
-				uaCompany: 'GRETECH CORP.',
-				uaCompanyUrl: 'http://www.gretech.com/',
-				uaIcon: 'GomPlayer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GOM Player'
-			}
-		},
-		'294': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Python-webchecker',
-				uaUrl: 'http://www.python.org/doc/essays/ppt/sd99east/sld070.htm',
-				uaCompany: 'Guido van Rossum/Sam Bayer',
-				uaCompanyUrl: '',
-				uaIcon: 'pythonurllib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Python-webchecker'
-			}
-		},
-		'296': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'W3C mobileOK Checker',
-				uaUrl: 'http://validator.w3.org/mobile/',
-				uaCompany: 'World Wide Web Consortium',
-				uaCompanyUrl: 'http://www.w3.org/',
-				uaIcon: 'w3.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=W3C mobileOK Checker'
-			}
-		},
-		'297': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Siege',
-				uaUrl: 'http://www.joedog.org/index/siege-home',
-				uaCompany: 'Joe Dog Software',
-				uaCompanyUrl: 'http://www.joedog.org/',
-				uaIcon: 'joedog.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Siege'
-			}
-		},
-		'298': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'iSiloXC',
-				uaUrl: 'http://www.isilox.com/',
-				uaCompany: 'DC & Co.',
-				uaCompanyUrl: 'http://www.isilox.com/',
-				uaIcon: 'terminal.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iSiloXC'
-			}
-		},
-		'299': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'AB (Apache Bench)',
-				uaUrl: 'http://en.wikipedia.org/wiki/ApacheBench',
-				uaCompany: 'Apache Software Foundation',
-				uaCompanyUrl: 'http://www.apache.org/',
-				uaIcon: 'ab.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=AB (Apache Bench)'
-			}
-		},
-		'300': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'anw LoadControl',
-				uaUrl: 'http://webtool.anw.de/analyze/?ladezeit',
-				uaCompany: 'ANW GmbH & Co. KG',
-				uaCompanyUrl: 'http://www.anw.de/',
-				uaIcon: 'anw.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=anw LoadControl'
-			}
-		},
-		'301': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'anw HTMLChecker',
-				uaUrl: 'http://webtool.topsubmit.de/analyze/?html',
-				uaCompany: 'ANW GmbH & Co. KG',
-				uaCompanyUrl: 'http://www.anw.de/',
-				uaIcon: 'anw.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=anw HTMLChecker'
-			}
-		},
-		'302': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Edbrowse',
-				uaUrl: 'http://edbrowse.sourceforge.net/',
-				uaCompany: 'Karl Dahlke',
-				uaCompanyUrl: '',
-				uaIcon: 'Edbrowse.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Edbrowse'
-			}
-		},
-		'303': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'muCommander',
-				uaUrl: 'http://www.mucommander.com/',
-				uaCompany: 'Maxence Bernard',
-				uaCompanyUrl: '',
-				uaIcon: 'muCommander.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=muCommander'
-			}
-		},
-		'304': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'XMPlay',
-				uaUrl: 'http://www.xmplay.com/',
-				uaCompany: 'un4seen developments',
-				uaCompanyUrl: 'http://www.un4seen.com/',
-				uaIcon: 'XMPlay.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=XMPlay'
-			}
-		},
-		'305': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'NFReader',
-				uaUrl: 'http://www.gaijin.at/dlnfreader.php',
-				uaCompany: 'Gaijin.at',
-				uaCompanyUrl: 'http://www.gaijin.at/',
-				uaIcon: 'NFReader.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NFReader'
-			}
-		},
-		'306': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'uZard Web',
-				uaUrl: 'http://www.uzard.com/',
-				uaCompany: 'Logicplant Co.',
-				uaCompanyUrl: 'http://www.logicplant.com/',
-				uaIcon: 'uzard.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=uZard Web'
-			}
-		},
-		'307': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Indy Library',
-				uaUrl: 'http://www.indyproject.org/',
-				uaCompany: 'Chad Z. Hower (Kudzu) and the Indy Pit Crew',
-				uaCompanyUrl: '',
-				uaIcon: 'DLLicon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Indy Library'
-			}
-		},
-		'308': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Multi-Browser XP',
-				uaUrl: 'http://www.multibrowser.de/',
-				uaCompany: 'Binh Nguyen-Huu',
-				uaCompanyUrl: '',
-				uaIcon: 'Multi-BrowserXP.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Multi-Browser XP'
-			}
-		},
-		'309': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'LinkWalker',
-				uaUrl: '',
-				uaCompany: 'BDProtect Inc',
-				uaCompanyUrl: 'http://www.brandprotect.com/',
-				uaIcon: 'LinkWalker.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LinkWalker'
-			}
-		},
-		'310': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'NetPositive',
-				uaUrl: 'http://en.wikipedia.org/wiki/NetPositive',
-				uaCompany: 'Be Inc.',
-				uaCompanyUrl: 'http://en.wikipedia.org/wiki/Be_Inc.',
-				uaIcon: 'netpositive.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetPositive'
-			}
-		},
-		'311': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Radio Downloader',
-				uaUrl: 'http://www.nerdoftheherd.com/tools/radiodld/',
-				uaCompany: 'Matt Robinson',
-				uaCompanyUrl: 'http://www.nerdoftheherd.com/',
-				uaIcon: 'RadioDownloader.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Radio Downloader'
-			}
-		},
-		'312': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'WebStripper',
-				uaUrl: 'http://webstripper.net/',
-				uaCompany: 'Mike Sutton',
-				uaCompanyUrl: 'http://solentsoftware.com/',
-				uaIcon: 'webstripper.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WebStripper'
-			}
-		},
-		'313': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Cyberduck',
-				uaUrl: 'http://cyberduck.ch/',
-				uaCompany: 'David Kocher',
-				uaCompanyUrl: 'dkocher.name',
-				uaIcon: 'Cyberduck.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Cyberduck'
-			}
-		},
-		'314': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'WorldWideWeb',
-				uaUrl: 'http://www.w3.org/People/Berners-Lee/WorldWideWeb',
-				uaCompany: 'Tim Berners-Lee',
-				uaCompanyUrl: 'http://www.w3.org/People/Berners-Lee/Overview.html',
-				uaIcon: '1stBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WorldWideWeb'
-			}
-		},
-		'315': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'iVideo',
-				uaUrl: 'http://tinyurl.com/DownloadiVideo',
-				uaCompany: 'ZETZ mobile',
-				uaCompanyUrl: 'http://www.zetzmobile.com/',
-				uaIcon: 'iVideo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iVideo'
-			}
-		},
-		'316': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'RSS Popper',
-				uaUrl: 'http://www.rsspopper.com/',
-				uaCompany: 'Paradisoft',
-				uaCompanyUrl: 'http://www.paradisoft.com/',
-				uaIcon: 'rss.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=RSS Popper'
-			}
-		},
-		'317': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Jamcast',
-				uaUrl: 'http://www.sdstechnologies.com/',
-				uaCompany: 'Software Development Solutions, Inc.',
-				uaCompanyUrl: 'http://www.sdstechnologies.com/',
-				uaIcon: 'Jamcast.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Jamcast'
-			}
-		},
-		'318': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Comodo Dragon',
-				uaUrl: 'http://www.comodo.com/home/browsers-toolbars/browser.php',
-				uaCompany: 'Comodo Group, Inc.',
-				uaCompanyUrl: 'http://www.comodo.com/',
-				uaIcon: 'Comodo_Dragon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Comodo Dragon'
-			}
-		},
-		'319': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'SuperBot',
-				uaUrl: 'http://www.sparkleware.com/superbot/index.html',
-				uaCompany: 'Sparkleware',
-				uaCompanyUrl: 'http://www.sparkleware.com/',
-				uaIcon: 'SuperBot.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SuperBot'
-			}
-		},
-		'320': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'My Internet Browser',
-				uaUrl: 'http://myinternetbrowser.webove-stranky.org/',
-				uaCompany: 'Media WebPublishing',
-				uaCompanyUrl: '',
-				uaIcon: 'MyInternetBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=My Internet Browser'
-			}
-		},
-		'321': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Opera Mobile',
-				uaUrl: 'http://www.opera.com/mobile/',
-				uaCompany: 'Opera Software ASA.',
-				uaCompanyUrl: 'http://www.opera.com/',
-				uaIcon: 'opera.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Opera Mobile'
-			}
-		},
-		'322': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Kirix Strata',
-				uaUrl: 'http://www.kirix.com/',
-				uaCompany: 'Kirix Corporation',
-				uaCompanyUrl: 'http://www.kirix.com/about-us.html',
-				uaIcon: 'kirix-strata.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Kirix Strata'
-			}
-		},
-		'323': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'TT Explorer',
-				uaUrl: 'http://tt.qq.com/',
-				uaCompany: 'Tencent',
-				uaCompanyUrl: 'http://www.tencent.com/',
-				uaIcon: 'tt_explorer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=TT Explorer'
-			}
-		},
-		'324': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'LBrowser',
-				uaUrl: 'http://wiki.freespire.org/index.php/Web_Browser',
-				uaCompany: 'Xandros Incorporated',
-				uaCompanyUrl: 'http://www.xandros.com/',
-				uaIcon: 'LBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LBrowser'
-			}
-		},
-		'325': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Outlook 2007',
-				uaUrl: 'http://en.wikipedia.org/wiki/Microsoft_Outlook',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'outlook-2007.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Outlook 2007'
-			}
-		},
-		'326': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Outlook 2010',
-				uaUrl: 'http://en.wikipedia.org/wiki/Microsoft_Outlook',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'outlook-2010.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Outlook 2010'
-			}
-		},
-		'327': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Windows Live Mail',
-				uaUrl: 'http://download.live.com/wlmail',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'Windows_Live_Mail.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Windows Live Mail'
-			}
-		},
-		'328': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Tjusig',
-				uaUrl: 'http://www.tjusig.cz/',
-				uaCompany: 'Luk\xe1\u0161 Ingr',
-				uaCompanyUrl: '',
-				uaIcon: 'tjusig.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Tjusig'
-			}
-		},
-		'329': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'SiteKiosk',
-				uaUrl: 'http://www.sitekiosk.com/SiteKiosk/Default.aspx',
-				uaCompany: 'PROVISIO GmbH / LLC',
-				uaCompanyUrl: 'http://www.provisio.com/',
-				uaIcon: 'sitekiosk.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SiteKiosk'
-			}
-		},
-		'330': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'The Bat!',
-				uaUrl: 'http://www.ritlabs.com/en/products/thebat/',
-				uaCompany: 'RITLabs SRL',
-				uaCompanyUrl: 'http://www.ritlabs.com/',
-				uaIcon: 'thebat.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=The Bat!'
-			}
-		},
-		'331': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Novell BorderManager',
-				uaUrl: 'http://www.novell.com/products/bordermanager/',
-				uaCompany: 'Novell, Inc',
-				uaCompanyUrl: 'http://www.novell.com/',
-				uaIcon: 'Novell_BorderManager.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Novell BorderManager'
-			}
-		},
-		'332': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Shredder',
-				uaUrl: 'http://www.mozillamessaging.com/en-US/thunderbird/3.0a1/releasenotes/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'thunderbird.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Shredder'
-			}
-		},
-		'333': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Public Radio Player',
-				uaUrl: 'http://www.publicradioplayer.org/',
-				uaCompany: 'Public Radio Exchange (PRX)',
-				uaCompanyUrl: 'http://www.prx.org/',
-				uaIcon: 'PRP.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Public Radio Player'
-			}
-		},
-		'334': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Rss Bandit',
-				uaUrl: 'http://rssbandit.org/',
-				uaCompany: 'Infragistics, Inc.',
-				uaCompanyUrl: 'http://www.infragistics.com/',
-				uaIcon: 'RssBandit.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Rss Bandit'
-			}
-		},
-		'335': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Postbox',
-				uaUrl: 'http://www.postbox-inc.com/',
-				uaCompany: 'Postbox, Inc.',
-				uaCompanyUrl: 'http://www.postbox-inc.com/',
-				uaIcon: 'postbox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Postbox'
-			}
-		},
-		'336': {
-			typeId: '10',
-			metadata: {
-				uaFamily: '2Bone LinkChecker',
-				uaUrl: 'http://www.2bone.com/links/linkchecker.shtml',
-				uaCompany: '2Bone',
-				uaCompanyUrl: 'http://www.2bone.com/',
-				uaIcon: '2bone.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=2Bone LinkChecker'
-			}
-		},
-		'337': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'Checkbot',
-				uaUrl: 'http://degraaff.org/checkbot/',
-				uaCompany: 'Hans de Graaff',
-				uaCompanyUrl: 'http://degraaff.org/',
-				uaIcon: 'perl.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Checkbot'
-			}
-		},
-		'338': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'GcMail',
-				uaUrl: 'http://www.gcmail.de/',
-				uaCompany: 'Monika Verse',
-				uaCompanyUrl: '',
-				uaIcon: 'gcmail.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GcMail'
-			}
-		},
-		'339': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Swiftweasel',
-				uaUrl: 'http://swiftweasel.tuxfamily.org/',
-				uaCompany: 'SticKK',
-				uaCompanyUrl: '',
-				uaIcon: 'swiftweasel.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Swiftweasel'
-			}
-		},
-		'340': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Fastladder FeedFetcher',
-				uaUrl: 'http://fastladder.com/',
-				uaCompany: 'livedoor Co.,Ltd. ',
-				uaCompanyUrl: 'http://corp.livedoor.com/',
-				uaIcon: 'fastladderFeedFetcher.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Fastladder FeedFetcher'
-			}
-		},
-		'341': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Firefox (Lorentz)',
-				uaUrl: 'http://www.mozilla.com/en-US/firefox/lorentz/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'firefox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Firefox (Lorentz)'
-			}
-		},
-		'342': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Pocket Tunes',
-				uaUrl: 'http://www.pocket-tunes.com/',
-				uaCompany: 'NormSoft, Inc.',
-				uaCompanyUrl: 'http://www.normsoft.com/',
-				uaIcon: 'PocketTunes.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Pocket Tunes'
-			}
-		},
-		'343': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'SharpReader',
-				uaUrl: 'http://www.sharpreader.net/',
-				uaCompany: 'Luke Hutteman',
-				uaCompanyUrl: 'http://www.hutteman.com/',
-				uaIcon: 'sharpreader.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SharpReader'
-			}
-		},
-		'344': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'YeahReader',
-				uaUrl: 'http://www.yeahreader.com/',
-				uaCompany: 'ExtraLabs Software',
-				uaCompanyUrl: 'http://www.extralabs.net/',
-				uaIcon: 'YeahReader.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=YeahReader'
-			}
-		},
-		'345': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Pale Moon',
-				uaUrl: 'http://www.palemoon.org/',
-				uaCompany: 'Moonchild Productions',
-				uaCompanyUrl: 'http://www.moonchildproductions.net/',
-				uaIcon: 'pale_moon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Pale Moon'
-			}
-		},
-		'346': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Holmes',
-				uaUrl: 'http://www.ucw.cz/holmes/',
-				uaCompany: 'Martin Mare\u0161 and Robert \u0160palek',
-				uaCompanyUrl: '',
-				uaIcon: 'holmes.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Holmes'
-			}
-		},
-		'347': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Google Earth',
-				uaUrl: 'http://earth.google.com/',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://google.com/',
-				uaIcon: 'google_earth.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Google Earth'
-			}
-		},
-		'348': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'ROME library',
-				uaUrl: 'https://rome.dev.java.net/',
-				uaCompany: 'A. Abdelnur, P. Chanezon and E. Chien',
-				uaCompanyUrl: '',
-				uaIcon: 'ROME_lib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=ROME library'
-			}
-		},
-		'349': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Akregator',
-				uaUrl: 'http://akregator.kde.org/',
-				uaCompany: '',
-				uaCompanyUrl: 's',
-				uaIcon: 'akregator.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Akregator'
-			}
-		},
-		'350': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Mini Browser',
-				uaUrl: 'http://dmkho.tripod.com/',
-				uaCompany: 'DMKHO',
-				uaCompanyUrl: '',
-				uaIcon: 'minibrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Mini Browser'
-			}
-		},
-		'351': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Espial TV Browser',
-				uaUrl: 'http://www.espial.com/products/evo_browser/',
-				uaCompany: 'Espial Group',
-				uaCompanyUrl: 'http://www.espial.com/',
-				uaIcon: 'EspialTVBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Espial TV Browser'
-			}
-		},
-		'352': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'UltraBrowser ',
-				uaUrl: 'http://www.ultrabrowser.com/',
-				uaCompany: 'UltraBrowser.com, Inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'UltraBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=UltraBrowser '
-			}
-		},
-		'353': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'BrowseX',
-				uaUrl: 'http://pdqi.com/browsex/',
-				uaCompany: 'Peter MacDonald',
-				uaCompanyUrl: 'http://pdqi.com/',
-				uaIcon: 'browsex.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BrowseX'
-			}
-		},
-		'354': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Android Webkit',
-				uaUrl: 'http://developer.android.com/reference/android/webkit/package-summary.html',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'androidWebkit.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Android Webkit'
-			}
-		},
-		'355': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Weltweitimnetz Browser',
-				uaUrl: 'http://weltweitimnetz.de/software/Browser.en.page',
-				uaCompany: 'Philipp Ruppel',
-				uaCompanyUrl: 'http://weltweitimnetz.de/',
-				uaIcon: 'WeltweitimnetzBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Weltweitimnetz Browser'
-			}
-		},
-		'356': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'PocoMail',
-				uaUrl: 'http://www.pocomail.com/',
-				uaCompany: 'Poco Systems Inc',
-				uaCompanyUrl: 'http://www.pocosystems.com/',
-				uaIcon: 'pocomail.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PocoMail'
-			}
-		},
-		'357': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Element Browser',
-				uaUrl: 'http://www.elementsoftware.co.uk/software/elementbrowser/',
-				uaCompany: 'Element Software UK.',
-				uaCompanyUrl: 'http://www.elementsoftware.co.uk/',
-				uaIcon: 'elementbrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Element Browser'
-			}
-		},
-		'358': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'SlimBrowser',
-				uaUrl: 'http://slimbrowser.flashpeak.com/',
-				uaCompany: 'FlashPeak Inc.',
-				uaCompanyUrl: 'http://www.flashpeak.com/',
-				uaIcon: 'slimbrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SlimBrowser'
-			}
-		},
-		'359': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'LeechCraft',
-				uaUrl: 'http://leechcraft.org/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'LeechCraft.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=LeechCraft'
-			}
-		},
-		'360': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'HTTP_Request2',
-				uaUrl: 'http://pear.php.net/package/http_request2',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'php.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=HTTP_Request2'
-			}
-		},
-		'361': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Conkeror',
-				uaUrl: 'http://conkeror.org/',
-				uaCompany: 'Mozilla Foundation',
-				uaCompanyUrl: 'http://www.mozilla.org/',
-				uaIcon: 'conkeror.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Conkeror'
-			}
-		},
-		'362': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Dolphin',
-				uaUrl: 'http://www.dolphin-browser.com/',
-				uaCompany: 'Samsung',
-				uaCompanyUrl: 'http://www.samsung.com/',
-				uaIcon: 'dolphin.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Dolphin'
-			}
-		},
-		'363': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Netvibes feed reader',
-				uaUrl: '',
-				uaCompany: 'Netvibes team',
-				uaCompanyUrl: 'http://about.netvibes.com/',
-				uaIcon: 'netvibes.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Netvibes feed reader'
-			}
-		},
-		'364': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Chilkat HTTP .NET',
-				uaUrl: 'http://www.chilkatsoft.com/HttpDotNet.asp',
-				uaCompany: 'Chilkat Software, Inc.',
-				uaCompanyUrl: 'http://www.chilkatsoft.com/',
-				uaIcon: 'chilkat.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Chilkat HTTP .NET'
-			}
-		},
-		'365': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'IXR lib',
-				uaUrl: 'http://scripts.incutio.com/xmlrpc/',
-				uaCompany: 'Incutio Ltd.',
-				uaCompanyUrl: 'http://www.incutio.com/',
-				uaIcon: 'Incutio.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IXR lib'
-			}
-		},
-		'366': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Web-sniffer',
-				uaUrl: 'http://web-sniffer.net/',
-				uaCompany: 'Lingo4you GbR',
-				uaCompanyUrl: 'http://www.lingo4u.de/',
-				uaIcon: 'Web-sniffer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Web-sniffer'
-			}
-		},
-		'367': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Atomic Email Hunter',
-				uaUrl: 'http://www.massmailsoftware.com/extractweb/',
-				uaCompany: 'AtomPark Software Inc.',
-				uaCompanyUrl: 'http://www.atompark.com/',
-				uaIcon: 'Atomic_Email_Hunter.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Atomic Email Hunter'
-			}
-		},
-		'368': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'iGetter',
-				uaUrl: 'http://www.igetter.net/',
-				uaCompany: 'Presenta Ltd.',
-				uaCompanyUrl: '',
-				uaIcon: 'iGetter.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iGetter'
-			}
-		},
-		'369': {
-			typeId: '1',
-			metadata: {
-				uaFamily: 'webfetch',
-				uaUrl: 'http://tony.aiu.to/sa/webfetch/',
-				uaCompany: 'Tony Aiuto',
-				uaCompanyUrl: 'http://tony.aiu.to/',
-				uaIcon: 'terminal.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=webfetch'
-			}
-		},
-		'370': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Apache Synapse',
-				uaUrl: 'http://synapse.apache.org/',
-				uaCompany: 'Apache Software Foundation',
-				uaCompanyUrl: 'http://www.apache.org/',
-				uaIcon: 'ab.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Apache Synapse'
-			}
-		},
-		'371': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'lolifox',
-				uaUrl: 'http://lolifox.com/',
-				uaCompany: 'Atachi Hayashime',
-				uaCompanyUrl: '',
-				uaIcon: 'lolifox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=lolifox'
-			}
-		},
-		'372': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'SkipStone',
-				uaUrl: 'http://www.muhri.net/skipstone/',
-				uaCompany: 'Maher Awamy',
-				uaCompanyUrl: 'http://www.muhri.net/',
-				uaIcon: 'skipStone.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SkipStone'
-			}
-		},
-		'373': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Powermarks',
-				uaUrl: 'http://www.kaylon.com/power.html',
-				uaCompany: 'Kaylon Technologies Inc.',
-				uaCompanyUrl: 'http://www.kaylon.com/',
-				uaIcon: 'powermarks.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Powermarks'
-			}
-		},
-		'374': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Safari RSS reader',
-				uaUrl: 'http://www.apple.com/safari/',
-				uaCompany: 'Apple Inc.',
-				uaCompanyUrl: 'http://www.apple.com/',
-				uaIcon: 'rss.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Safari RSS reader'
-			}
-		},
-		'375': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Google Friend Connect',
-				uaUrl: 'http://www.google.com/friendconnect/',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'google_friend_connect.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Google Friend Connect'
-			}
-		},
-		'376': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Feed Viewer',
-				uaUrl: 'http://feedviewer.codeplex.com/',
-				uaCompany: 'vasek7',
-				uaCompanyUrl: 'http://www.codeplex.com/site/users/view/vasek7',
-				uaIcon: 'rss.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Feed Viewer'
-			}
-		},
-		'377': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'RockMelt',
-				uaUrl: 'http://www.rockmelt.com/',
-				uaCompany: 'Rockmelt, Inc.',
-				uaCompanyUrl: 'http://www.rockmelt.com/',
-				uaIcon: 'rockmelt.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=RockMelt'
-			}
-		},
-		'378': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Epic',
-				uaUrl: 'http://www.epicbrowser.com/',
-				uaCompany: 'Hidden Reflex',
-				uaCompanyUrl: 'http://www.hiddenreflex.com/',
-				uaIcon: 'epic.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Epic'
-			}
-		},
-		'379': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'InternetSurfboard',
-				uaUrl: 'http://inetsurfboard.sourceforge.net/',
-				uaCompany: 'Philipp Ruppel',
-				uaCompanyUrl: '',
-				uaIcon: 'internetSurfboard.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=InternetSurfboard'
-			}
-		},
-		'380': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Vonkeror',
-				uaUrl: 'http://zzo38computer.cjb.net/vonkeror/',
-				uaCompany: 'zzo38',
-				uaCompanyUrl: 'http://zzo38computer.cjb.net/',
-				uaIcon: 'conkeror.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Vonkeror'
-			}
-		},
-		'381': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'IE RSS reader',
-				uaUrl: 'http://en.wikipedia.org/wiki/Windows_RSS_Platform',
-				uaCompany: 'Microsoft',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'rss.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IE RSS reader'
-			}
-		},
-		'382': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Trileet NewsRoom',
-				uaUrl: 'http://feedmonger.blogspot.com/',
-				uaCompany: 'Trileet Inc.',
-				uaCompanyUrl: 'http://www.trileet.com/',
-				uaIcon: 'rss.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Trileet NewsRoom'
-			}
-		},
-		'383': {
-			typeId: '10',
-			metadata: {
-				uaFamily: 'Validator.nu',
-				uaUrl: 'http://validator.nu/',
-				uaCompany: 'Henri Sivonen',
-				uaCompanyUrl: 'http://hsivonen.iki.fi/author/',
-				uaIcon: 'validator_nu.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Validator.nu'
-			}
-		},
-		'384': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Zend_Http_Client',
-				uaUrl: 'http://framework.zend.com/manual/en/zend.http.html',
-				uaCompany: 'Zend Technologies Ltd.',
-				uaCompanyUrl: 'http://www.zend.com/',
-				uaIcon: 'zend_http_client.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Zend_Http_Client'
-			}
-		},
-		'385': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Skyfire',
-				uaUrl: 'http://www.skyfire.com/',
-				uaCompany: 'Skyfire Labs, Inc.',
-				uaCompanyUrl: 'http://www.skyfire.com/about',
-				uaIcon: 'skyfire.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Skyfire'
-			}
-		},
-		'386': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'GO Browser',
-				uaUrl: 'http://www.gobrowser.cn/',
-				uaCompany: 'GO Dev Team',
-				uaCompanyUrl: '',
-				uaIcon: 'go_browser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=GO Browser'
-			}
-		},
-		'387': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Surf',
-				uaUrl: 'http://surf.suckless.org/',
-				uaCompany: 'suckless.org',
-				uaCompanyUrl: 'http://suckless.org/',
-				uaIcon: 'surf.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Surf'
-			}
-		},
-		'388': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'iGooMap',
-				uaUrl: 'http://www.pointworks.de/software/igoomap/index.php',
-				uaCompany: 'PointWorks.de',
-				uaCompanyUrl: 'http://www.pointworks.de/',
-				uaIcon: 'igoomap.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iGooMap'
-			}
-		},
-		'389': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'iTunes',
-				uaUrl: 'http://www.apple.com/itunes/',
-				uaCompany: 'Apple Inc.',
-				uaCompanyUrl: 'http://www.apple.com/',
-				uaIcon: 'itunes.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iTunes'
-			}
-		},
-		'390': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'BlackHawk',
-				uaUrl: 'http://www.netgate.sk/blackhawk/help/welcome-to-blackhawk-web-browser.html',
-				uaCompany: 'NETGATE Technologies s.r.o. ',
-				uaCompanyUrl: 'http://www.netgate.sk/',
-				uaIcon: 'blackhawk.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BlackHawk'
-			}
-		},
-		'392': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Kindle Browser',
-				uaUrl: 'http://en.wikipedia.org/wiki/Amazon_Kindle',
-				uaCompany: 'Amazon.com',
-				uaCompanyUrl: 'http://www.amazon.com/',
-				uaIcon: 'kindle.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Kindle Browser'
-			}
-		},
-		'393': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Microsoft Office Existence Discovery',
-				uaUrl: 'http://blogs.msdn.com/b/vsofficedeveloper/archive/2008/03/11/office-existence-discovery-protocol.aspx',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'webdav.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Microsoft Office Existence Discovery'
-			}
-		},
-		'394': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Mobile Safari',
-				uaUrl: 'http://en.wikipedia.org/wiki/Safari_%28web_browser%29',
-				uaCompany: 'Apple Inc.',
-				uaCompanyUrl: 'http://www.apple.com/',
-				uaIcon: 'safari.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Mobile Safari'
-			}
-		},
-		'395': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'BrownRecluse',
-				uaUrl: 'http://softbytelabs.com/us/br/index.html',
-				uaCompany: 'SoftByte Labs, Inc.',
-				uaCompanyUrl: 'http://softbytelabs.com/',
-				uaIcon: 'BrownRecluse.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BrownRecluse'
-			}
-		},
-		'396': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'BookmarkTracker',
-				uaUrl: 'http://www.bookmarktracker.com/',
-				uaCompany: 'BookmarkTracker.com, Inc.',
-				uaCompanyUrl: '',
-				uaIcon: 'BookmarkTracker.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BookmarkTracker'
-			}
-		},
-		'397': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'BinGet',
-				uaUrl: 'http://www.bin-co.com/php/scripts/load/',
-				uaCompany: 'Binny VA',
-				uaCompanyUrl: 'http://binnyva.com/',
-				uaIcon: 'php.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BinGet'
-			}
-		},
-		'399': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Webian Shell',
-				uaUrl: 'http://webian.org/shell/',
-				uaCompany: 'Ben Francis',
-				uaCompanyUrl: 'http://tola.me.uk/',
-				uaIcon: 'webianshell.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Webian Shell'
-			}
-		},
-		'400': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Kylo',
-				uaUrl: 'http://kylo.tv/',
-				uaCompany: 'Hillcrest Laboratories',
-				uaCompanyUrl: 'http://hillcrestlabs.com/',
-				uaIcon: 'kylo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Kylo'
-			}
-		},
-		'401': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Fireweb Navigator',
-				uaUrl: 'http://www.arsslensoft.tk/?q=node/7',
-				uaCompany: 'Arsslensoft Foundation',
-				uaCompanyUrl: 'http://www.arsslensoft.fi5.us/',
-				uaIcon: 'Fireweb.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Fireweb Navigator'
-			}
-		},
-		'402': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Evolution/Camel.Stream',
-				uaUrl: 'http://live.gnome.org/Evolution/Camel.Stream',
-				uaCompany: 'GNOME Project',
-				uaCompanyUrl: 'http://www.gnome.org/',
-				uaIcon: 'DLLicon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Evolution/Camel.Stream'
-			}
-		},
-		'403': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'EventMachine',
-				uaUrl: 'http://rubyeventmachine.com/',
-				uaCompany: '',
-				uaCompanyUrl: '',
-				uaIcon: 'DLLicon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=EventMachine'
-			}
-		},
-		'404': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Sundance',
-				uaUrl: 'http://www.digola.com/sundance.html',
-				uaCompany: 'Digola',
-				uaCompanyUrl: 'http://www.digola.com/',
-				uaIcon: 'sundance.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Sundance'
-			}
-		},
-		'405': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Chromium',
-				uaUrl: 'http://dev.chromium.org/Home',
-				uaCompany: 'Google Inc. and contributors',
-				uaCompanyUrl: '',
-				uaIcon: 'chromium.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Chromium'
-			}
-		},
-		'406': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Columbus',
-				uaUrl: 'http://www.columbus-browser.com/',
-				uaCompany: 'Hipgnosis Vision',
-				uaCompanyUrl: 'http://www.hipgnosis.ro/',
-				uaIcon: 'columbus.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Columbus'
-			}
-		},
-		'407': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Plex Media Center',
-				uaUrl: 'http://www.plexapp.com/',
-				uaCompany: 'Plex comunity',
-				uaCompanyUrl: '',
-				uaIcon: 'plex.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Plex Media Center'
-			}
-		},
-		'408': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'WebRender',
-				uaUrl: 'http://webrender.99k.org/',
-				uaCompany: 'Anand Bose',
-				uaCompanyUrl: 'http://anandbose.99k.org/',
-				uaIcon: 'webrender.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WebRender'
-			}
-		},
-		'409': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'CoolNovo',
-				uaUrl: 'http://coolnovo.com/',
-				uaCompany: 'Maple Studio',
-				uaCompanyUrl: '',
-				uaIcon: 'coolnovo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=CoolNovo'
-			}
-		},
-		'410': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Usejump',
-				uaUrl: 'http://www.usejump.com/',
-				uaCompany: 'Usejump team',
-				uaCompanyUrl: '',
-				uaIcon: 'usejump.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Usejump'
-			}
-		},
-		'411': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Sundial',
-				uaUrl: 'http://www.sundialbrowser.com/',
-				uaCompany: 'Unifiedroot',
-				uaCompanyUrl: 'http://www.unifiedroot.com/',
-				uaIcon: 'sundial.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Sundial'
-			}
-		},
-		'412': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Alienforce',
-				uaUrl: 'http://sourceforge.net/projects/alienforce/',
-				uaCompany: 'KBclub Universal',
-				uaCompanyUrl: 'http://kbclub.users.sourceforge.net/',
-				uaIcon: 'alienforce.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Alienforce'
-			}
-		},
-		'413': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Google Rich Snippets Testing Tool',
-				uaUrl: 'http://www.google.com/webmasters/tools/richsnippets',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'feedfetcher-google.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Google Rich Snippets Testing Tool'
-			}
-		},
-		'414': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'HTML2JPG',
-				uaUrl: 'http://www.html2jpg.com/',
-				uaCompany: 'BVBA Adygo',
-				uaCompanyUrl: 'http://www.adygo.com/',
-				uaIcon: 'html2jpg.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=HTML2JPG'
-			}
-		},
-		'415': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'iCatcher!',
-				uaUrl: 'http://joeisanerd.com/apps/iCatcher',
-				uaCompany: 'Joe Isanerd',
-				uaCompanyUrl: 'http://joeisanerd.com/',
-				uaIcon: 'iCatcher.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=iCatcher!'
-			}
-		},
-		'416': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Baidu Browser',
-				uaUrl: 'http://liulanqi.baidu.com/',
-				uaCompany: 'Baidu, Inc.',
-				uaCompanyUrl: 'http://www.baidu.com/',
-				uaIcon: 'baidubrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Baidu Browser'
-			}
-		},
-		'417': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Sogou Explorer',
-				uaUrl: 'http://ie.sogou.com/',
-				uaCompany: 'Sohu.com, Inc.',
-				uaCompanyUrl: 'http://www.sohu.com/',
-				uaIcon: 'sogouexplorer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Sogou Explorer'
-			}
-		},
-		'418': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'MPlayer2',
-				uaUrl: 'http://www.mplayer2.org/',
-				uaCompany: 'mplayer2 project',
-				uaCompanyUrl: '',
-				uaIcon: 'mplayer.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=MPlayer2'
-			}
-		},
-		'419': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'ZipZap',
-				uaUrl: 'http://www.zipzaphome.com/',
-				uaCompany: 'JE Rhoads Company, LLC',
-				uaCompanyUrl: 'http://www.jerhoads.com/',
-				uaIcon: 'zipzap.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=ZipZap'
-			}
-		},
-		'420': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'QupZilla',
-				uaUrl: 'http://www.qupzilla.com/',
-				uaCompany: 'David Rosca',
-				uaCompanyUrl: '',
-				uaIcon: 'qupzilla.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=QupZilla'
-			}
-		},
-		'421': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Patriott',
-				uaUrl: 'http://madgroup.x10.mx/patriott1.php',
-				uaCompany: 'MadWorks Group.',
-				uaCompanyUrl: 'http://madgroup.x10.mx/',
-				uaIcon: 'patriott.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Patriott'
-			}
-		},
-		'422': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Tizen Browser',
-				uaUrl: 'https://www.tizen.org/',
-				uaCompany: 'Tizen Project',
-				uaCompanyUrl: 'https://www.tizen.org/',
-				uaIcon: 'tizen.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Tizen Browser'
-			}
-		},
-		'423': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Chrome Mobile',
-				uaUrl: 'http://www.google.com/intl/en/chrome/browser/mobile/',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'chrome.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Chrome Mobile'
-			}
-		},
-		'424': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'Winamp for Android',
-				uaUrl: 'http://www.winamp.com/android',
-				uaCompany: 'Nullsoft, Inc.',
-				uaCompanyUrl: 'http://en.wikipedia.org/wiki/Nullsoft',
-				uaIcon: 'winamp.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Winamp for Android'
-			}
-		},
-		'425': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Apache internal dummy connection',
-				uaUrl: 'http://wiki.apache.org/httpd/InternalDummyConnection',
-				uaCompany: 'Apache Software Foundation',
-				uaCompanyUrl: 'http://www.apache.org/',
-				uaIcon: 'ab.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Apache internal dummy connection'
-			}
-		},
-		'426': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'NineSky',
-				uaUrl: 'http://ninesky.com/',
-				uaCompany: 'ninesky.com',
-				uaCompanyUrl: '',
-				uaIcon: 'ninesky.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NineSky'
-			}
-		},
-		'427': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Maple browser',
-				uaUrl: 'http://www.freethetvchallenge.com/details/faq',
-				uaCompany: 'Samsung',
-				uaCompanyUrl: 'http://www.samsung.com/',
-				uaIcon: 'maple.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Maple browser'
-			}
-		},
-		'428': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'wOSBrowser',
-				uaUrl: '',
-				uaCompany: 'Hewlett-Packard',
-				uaCompanyUrl: 'http://www.hp.com/',
-				uaIcon: 'webos.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=wOSBrowser'
-			}
-		},
-		'429': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Nokia SyncML Client',
-				uaUrl: 'http://www.developer.nokia.com/Community/Wiki/SyncML_Client_API',
-				uaCompany: 'Nokia',
-				uaCompanyUrl: 'http://www.nokia.com/',
-				uaIcon: 'nokiaSyncML.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Nokia SyncML Client'
-			}
-		},
-		'430': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Charon',
-				uaUrl: 'http://en.wikipedia.org/wiki/Charon_%28web_browser%29',
-				uaCompany: 'Vita Nuova Holdings Ltd',
-				uaCompanyUrl: 'http://www.vitanuova.com/',
-				uaIcon: 'charon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Charon'
-			}
-		},
-		'432': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'JS-Kit/Echo',
-				uaUrl: 'http://sites.google.com/site/echocomments/home',
-				uaCompany: 'Echo',
-				uaCompanyUrl: 'http://aboutecho.com/',
-				uaIcon: 'JS-Kit.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=JS-Kit/Echo'
-			}
-		},
-		'433': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Podkicker',
-				uaUrl: 'http://www.podkicker.com/',
-				uaCompany: 'skiplist',
-				uaCompanyUrl: '',
-				uaIcon: 'podkicker.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Podkicker'
-			}
-		},
-		'434': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Python-requests',
-				uaUrl: 'http://python-requests.org/',
-				uaCompany: 'Kenneth Reitz',
-				uaCompanyUrl: 'http://kennethreitz.com/',
-				uaIcon: 'pythonurllib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Python-requests'
-			}
-		},
-		'436': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Atomic Web Browser',
-				uaUrl: 'http://atomicwebbrowser.com/',
-				uaCompany: 'Richard Trautvetter',
-				uaCompanyUrl: '',
-				uaIcon: 'AtomicWebBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Atomic Web Browser'
-			}
-		},
-		'437': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'Reeder',
-				uaUrl: 'http://reederapp.com/',
-				uaCompany: 'Silvio Rizzi',
-				uaCompanyUrl: 'http://madeatgloria.com/',
-				uaIcon: 'reader.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Reeder'
-			}
-		},
-		'438': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'WordPress pingback',
-				uaUrl: 'http://codex.wordpress.org/Introduction_to_Blogging#Pingbacks',
-				uaCompany: 'wordpress.org',
-				uaCompanyUrl: 'http://wordpress.org/',
-				uaIcon: 'wordpress.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=WordPress pingback'
-			}
-		},
-		'439': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'TenFourFox',
-				uaUrl: 'http://www.floodgap.com/software/tenfourfox/',
-				uaCompany: 'Cameron Kaiser',
-				uaCompanyUrl: 'http://www.floodgap.com/',
-				uaIcon: 'TenFourFox.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=TenFourFox'
-			}
-		},
-		'440': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'PEAR HTTP_Request',
-				uaUrl: 'http://pear.php.net/package/HTTP_Request',
-				uaCompany: 'Richard Heyes',
-				uaCompanyUrl: '',
-				uaIcon: 'php.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PEAR HTTP_Request'
-			}
-		},
-		'441': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'D+',
-				uaUrl: 'http://dplus-browser.sourceforge.net/',
-				uaCompany: 'Benjamin Johnson',
-				uaCompanyUrl: 'http://obeythepenguin.users.sourceforge.net/',
-				uaIcon: 'dillo.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=D+'
-			}
-		},
-		'442': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'zBrowser',
-				uaUrl: 'http://sites.google.com/site/zeromusparadoxe01/zbrowser',
-				uaCompany: 'Bastien Pederencino',
-				uaCompanyUrl: 'http://sites.google.com/site/zeromusparadoxe01/',
-				uaIcon: 'zBrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=zBrowser'
-			}
-		},
-		'443': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'SlimBoat',
-				uaUrl: 'http://slimboat.com/',
-				uaCompany: 'FlashPeak Inc.',
-				uaCompanyUrl: 'http://www.flashpeak.com/',
-				uaIcon: 'slimboat.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SlimBoat'
-			}
-		},
-		'445': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Mechanize',
-				uaUrl: 'http://mechanize.rubyforge.org/',
-				uaCompany: 'Aaron Patterson',
-				uaCompanyUrl: 'http://tenderlovemaking.com/',
-				uaIcon: 'ruby_on_rails.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Mechanize'
-			}
-		},
-		'446': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'HTMLayout',
-				uaUrl: 'http://www.terrainformatica.com/htmlayout/main.whtm',
-				uaCompany: 'Terra Informatica Software, Inc.',
-				uaCompanyUrl: 'http://www.terrainformatica.com/',
-				uaIcon: 'DLLicon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=HTMLayout'
-			}
-		},
-		'447': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'SaaYaa Explorer',
-				uaUrl: 'http://www.saayaa.com/',
-				uaCompany: 'RuanMei.com',
-				uaCompanyUrl: 'http://www.ruanmei.com/',
-				uaIcon: 'SaaYaa.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SaaYaa Explorer'
-			}
-		},
-		'448': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Ryouko',
-				uaUrl: 'http://sourceforge.net/projects/ryouko/',
-				uaCompany: 'Daniel Sim',
-				uaCompanyUrl: 'http://sourceforge.net/users/foxhead128/',
-				uaIcon: 'ryouko.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Ryouko'
-			}
-		},
-		'449': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Anemone',
-				uaUrl: 'http://anemone.rubyforge.org/',
-				uaCompany: 'Chris Kite',
-				uaCompanyUrl: 'http://www.chriskite.com/',
-				uaIcon: 'DLLicon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Anemone'
-			}
-		},
-		'450': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Sparrow',
-				uaUrl: 'http://sprw.me/',
-				uaCompany: 'Google Inc.',
-				uaCompanyUrl: 'http://www.google.com/',
-				uaIcon: 'sparrow.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Sparrow'
-			}
-		},
-		'451': {
-			typeId: '18',
-			metadata: {
-				uaFamily: 'SubStream',
-				uaUrl: 'http://itunes.apple.com/us/app/substream/id389906706?mt=8',
-				uaCompany: 'Figment, Inc.',
-				uaCompanyUrl: 'http://www.figmentdevelopment.com/',
-				uaIcon: 'SubStream.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=SubStream'
-			}
-		},
-		'452': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Barca',
-				uaUrl: 'http://www.pocosystems.com/home/index.php?option=content&task=category&sectionid=2&id=9&Itemid=27',
-				uaCompany: 'Poco Systems Inc',
-				uaCompanyUrl: 'http://www.pocosystems.com/',
-				uaIcon: 'barca.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Barca'
-			}
-		},
-		'453': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'A1 Sitemap Generator',
-				uaUrl: 'http://www.microsystools.com/products/sitemap-generator/',
-				uaCompany: 'Microsys',
-				uaCompanyUrl: 'http://www.microsystools.com/home/microsys.php',
-				uaIcon: 'A1sitemapGenerator.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=A1 Sitemap Generator'
-			}
-		},
-		'454': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'PS Vita browser',
-				uaUrl: '',
-				uaCompany: 'Sony Computer Entertainment',
-				uaCompanyUrl: 'http://www.scei.co.jp/',
-				uaIcon: 'ps-vita-browser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PS Vita browser'
-			}
-		},
-		'455': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'QQbrowser',
-				uaUrl: 'http://browser.qq.com/',
-				uaCompany: 'Tencent Ltd.',
-				uaCompanyUrl: 'http://www.tencent.com/',
-				uaIcon: 'QQbrowser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=QQbrowser'
-			}
-		},
-		'456': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Beamrise',
-				uaUrl: 'http://www.beamrise.com/',
-				uaCompany: 'SIEN S.A.',
-				uaCompanyUrl: 'http://www.sien.com/',
-				uaIcon: 'beamrise.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Beamrise'
-			}
-		},
-		'457': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Yandex.Browser',
-				uaUrl: 'http://browser.yandex.com/',
-				uaCompany: 'Yandex ',
-				uaCompanyUrl: 'http://yandex.com/',
-				uaIcon: 'Yandex.Browser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Yandex.Browser'
-			}
-		},
-		'458': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Silk',
-				uaUrl: 'http://amazonsilk.wordpress.com/',
-				uaCompany: 'Amazon.com, Inc.',
-				uaCompanyUrl: 'http://www.amazon.com/',
-				uaIcon: 'amazon_silk.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Silk'
-			}
-		},
-		'459': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'Apache-HttpClient',
-				uaUrl: 'http://hc.apache.org/httpcomponents-client-ga/',
-				uaCompany: 'Apache Software Foundation',
-				uaCompanyUrl: 'http://www.apache.org/',
-				uaIcon: 'jakarta.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Apache-HttpClient'
-			}
-		},
-		'460': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Nintendo Browser',
-				uaUrl: 'http://en.wikipedia.org/wiki/Wii_u',
-				uaCompany: 'Nintendo of America Inc.',
-				uaCompanyUrl: 'http://www.nintendo.com/',
-				uaIcon: 'wii.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Nintendo Browser'
-			}
-		},
-		'461': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Dell Web Monitor',
-				uaUrl: '',
-				uaCompany: 'Quest Software',
-				uaCompanyUrl: 'http://www.quest.com/',
-				uaIcon: 'dell.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Dell Web Monitor'
-			}
-		},
-		'462': {
-			typeId: '15',
-			metadata: {
-				uaFamily: 'FeedDemon',
-				uaUrl: 'http://www.feeddemon.com/',
-				uaCompany: 'NewsGator Technologies, Inc.',
-				uaCompanyUrl: 'http://www.newsgator.com/',
-				uaIcon: 'FeedDemon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=FeedDemon'
-			}
-		},
-		'463': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'XML-RPC for Ruby',
-				uaUrl: 'http://www.ntecs.de/ruby/xmlrpc4r/howto.html',
-				uaCompany: 'Michael Neumann',
-				uaCompanyUrl: 'http://www.ntecs.de/',
-				uaIcon: 'ruby-on-rails.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=XML-RPC for Ruby'
-			}
-		},
-		'464': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'Pattern',
-				uaUrl: 'http://www.clips.ua.ac.be/pages/pattern',
-				uaCompany: 'Computational Linguistics & Psycholinguistics Research Center ',
-				uaCompanyUrl: 'http://www.clips.ua.ac.be/',
-				uaIcon: 'pythonurllib.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Pattern'
-			}
-		},
-		'465': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Eudora',
-				uaUrl: 'http://www.eudora.com/archive.html',
-				uaCompany: 'Qualcomm Incorporated.',
-				uaCompanyUrl: 'http://www.qualcomm.com/',
-				uaIcon: 'eudora.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Eudora'
-			}
-		},
-		'466': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Apple Mail',
-				uaUrl: 'http://en.wikipedia.org/wiki/Apple_mail',
-				uaCompany: 'Apple Inc.',
-				uaCompanyUrl: 'http://www.apple.com/',
-				uaIcon: 'apple-mail.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Apple Mail'
-			}
-		},
-		'467': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Polarity',
-				uaUrl: 'http://polarityweb.webs.com/',
-				uaCompany: 'Stanley Lim',
-				uaCompanyUrl: '',
-				uaIcon: 'polarity.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Polarity'
-			}
-		},
-		'468': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Superbird',
-				uaUrl: 'http://superbird.me/',
-				uaCompany: 'The Superbird Authors',
-				uaCompanyUrl: '',
-				uaIcon: 'superbird.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Superbird'
-			}
-		},
-		'469': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'NetFront Life',
-				uaUrl: 'http://gl.access-company.com/files/legacy/products/nflife/app_browser2.html',
-				uaCompany: 'ACCESS CO., LTD.',
-				uaCompanyUrl: 'http://www.access-company.com/',
-				uaIcon: 'netfrontlife.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=NetFront Life'
-			}
-		},
-		'470': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'YRC Weblink',
-				uaUrl: 'http://weblink.justyrc.com/',
-				uaCompany: 'YRC Group Inc.',
-				uaCompanyUrl: 'http://www.justyrc.com/',
-				uaIcon: 'yrc_webling.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=YRC Weblink'
-			}
-		},
-		'471': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'IceDragon',
-				uaUrl: 'http://www.comodo.com/home/browsers-toolbars/icedragon-browser.php',
-				uaCompany: 'Comodo Group, Inc.',
-				uaCompanyUrl: 'http://www.comodo.com/',
-				uaIcon: 'icedragon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=IceDragon'
-			}
-		},
-		'473': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'Outlook 2013',
-				uaUrl: 'http://en.wikipedia.org/wiki/Microsoft_Outlook',
-				uaCompany: 'Microsoft Corporation.',
-				uaCompanyUrl: 'http://www.microsoft.com/',
-				uaIcon: 'outlook2013.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Outlook 2013'
-			}
-		},
-		'474': {
-			typeId: '5',
-			metadata: {
-				uaFamily: 'RestSharp',
-				uaUrl: 'http://restsharp.org/',
-				uaCompany: 'John Sheehan',
-				uaCompanyUrl: 'http://john-sheehan.com/',
-				uaIcon: 'DLLicon.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=RestSharp'
-			}
-		},
-		'475': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Yandex.Browser mobile',
-				uaUrl: 'http://mobil.yandex.com/',
-				uaCompany: 'Yandex ',
-				uaCompanyUrl: 'http://yandex.com/',
-				uaIcon: 'Yandex.Browser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Yandex.Browser mobile'
-			}
-		},
-		'476': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Puffin',
-				uaUrl: 'http://www.puffinbrowser.com/',
-				uaCompany: 'CloudMosa Inc.',
-				uaCompanyUrl: 'http://www.cloudmosa.com/',
-				uaIcon: 'puffin.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Puffin'
-			}
-		},
-		'477': {
-			typeId: '0',
-			metadata: {
-				uaFamily: 'Roccat browser',
-				uaUrl: 'http://www.runecats.com/roccat.html',
-				uaCompany: 'Runecats',
-				uaCompanyUrl: 'http://runecats.com/',
-				uaIcon: 'roccat.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Roccat browser'
-			}
-		},
-		'478': {
-			typeId: '4',
-			metadata: {
-				uaFamily: 'AirMail',
-				uaUrl: 'http://airmailapp.com/',
-				uaCompany: 'Bloop S.R.L.',
-				uaCompanyUrl: 'http://bloop.info/',
-				uaIcon: 'airmail.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=AirMail'
-			}
-		},
-		'479': {
-			typeId: '0',
-			metadata: {
-				uaFamily: '3DS Browser',
-				uaUrl: 'http://en.wikipedia.org/wiki/Internet_Browser_(Nintendo_3DS)',
-				uaCompany: 'Nintendo of America Inc.',
-				uaCompanyUrl: 'http://www.nintendo.com/',
-				uaIcon: '3DS-Browser.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=3DS Browser'
-			}
-		},
-		'481': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'BrowserEmulator',
-				uaUrl: 'http://www.dejavu.org/emulator.htm',
-				uaCompany: 'Metamatrix AB',
-				uaCompanyUrl: 'http://www.metamatrix.se/',
-				uaIcon: 'browseremulator.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=BrowserEmulator'
-			}
-		},
-		'482': {
-			typeId: '3',
-			metadata: {
-				uaFamily: 'Palm WebPro',
-				uaUrl: 'http://www.hpwebos.com/us/support/handbooks/tungstent/webbrowser_hb.pdf',
-				uaCompany: 'Palm Inc.',
-				uaCompanyUrl: 'http://www.palm.com/',
-				uaIcon: 'palmWebPro.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=Palm WebPro'
-			}
-		},
-		'483': {
-			typeId: '20',
-			metadata: {
-				uaFamily: 'PhantomJS',
-				uaUrl: 'http://phantomjs.org/',
-				uaCompany: 'Ariya Hidayat',
-				uaCompanyUrl: 'http://ariya.ofilabs.com/about',
-				uaIcon: 'PhantomJS.png',
-				uaInfoUrl: '/list-of-ua/browser-detail?browser=PhantomJS'
-			}
-		},
-		order: [
-			'1',
-			'2',
-			'3',
-			'4',
-			'5',
-			'6',
-			'7',
-			'8',
-			'9',
-			'10',
-			'11',
-			'14',
-			'15',
-			'16',
-			'17',
-			'18',
-			'19',
-			'21',
-			'22',
-			'23',
-			'24',
-			'25',
-			'27',
-			'28',
-			'29',
-			'30',
-			'31',
-			'32',
-			'33',
-			'35',
-			'39',
-			'40',
-			'41',
-			'42',
-			'43',
-			'44',
-			'45',
-			'46',
-			'47',
-			'48',
-			'49',
-			'50',
-			'51',
-			'52',
-			'53',
-			'54',
-			'55',
-			'56',
-			'57',
-			'58',
-			'59',
-			'61',
-			'62',
-			'71',
-			'74',
-			'79',
-			'81',
-			'82',
-			'85',
-			'86',
-			'87',
-			'88',
-			'89',
-			'90',
-			'91',
-			'93',
-			'94',
-			'96',
-			'99',
-			'100',
-			'105',
-			'111',
-			'117',
-			'119',
-			'120',
-			'121',
-			'122',
-			'123',
-			'124',
-			'125',
-			'126',
-			'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',
-			'165',
-			'166',
-			'167',
-			'168',
-			'169',
-			'170',
-			'171',
-			'172',
-			'173',
-			'174',
-			'175',
-			'176',
-			'177',
-			'178',
-			'179',
-			'180',
-			'181',
-			'182',
-			'183',
-			'184',
-			'185',
-			'187',
-			'188',
-			'189',
-			'190',
-			'191',
-			'192',
-			'193',
-			'194',
-			'195',
-			'196',
-			'197',
-			'198',
-			'199',
-			'200',
-			'201',
-			'202',
-			'204',
-			'205',
-			'206',
-			'207',
-			'208',
-			'209',
-			'210',
-			'211',
-			'212',
-			'213',
-			'214',
-			'216',
-			'217',
-			'218',
-			'219',
-			'220',
-			'221',
-			'222',
-			'223',
-			'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',
-			'256',
-			'257',
-			'258',
-			'259',
-			'260',
-			'261',
-			'262',
-			'263',
-			'264',
-			'265',
-			'266',
-			'267',
-			'268',
-			'269',
-			'270',
-			'271',
-			'272',
-			'273',
-			'274',
-			'276',
-			'277',
-			'278',
-			'279',
-			'280',
-			'281',
-			'282',
-			'283',
-			'284',
-			'285',
-			'286',
-			'287',
-			'288',
-			'289',
-			'290',
-			'291',
-			'292',
-			'293',
-			'294',
-			'296',
-			'297',
-			'298',
-			'299',
-			'300',
-			'301',
-			'302',
-			'303',
-			'304',
-			'305',
-			'306',
-			'307',
-			'308',
-			'309',
-			'310',
-			'311',
-			'312',
-			'313',
-			'314',
-			'315',
-			'316',
-			'317',
-			'318',
-			'319',
-			'320',
-			'321',
-			'322',
-			'323',
-			'324',
-			'325',
-			'326',
-			'327',
-			'328',
-			'329',
-			'330',
-			'331',
-			'332',
-			'333',
-			'334',
-			'335',
-			'336',
-			'337',
-			'338',
-			'339',
-			'340',
-			'341',
-			'342',
-			'343',
-			'344',
-			'345',
-			'346',
-			'347',
-			'348',
-			'349',
-			'350',
-			'351',
-			'352',
-			'353',
-			'354',
-			'355',
-			'356',
-			'357',
-			'358',
-			'359',
-			'360',
-			'361',
-			'362',
-			'363',
-			'364',
-			'365',
-			'366',
-			'367',
-			'368',
-			'369',
-			'370',
-			'371',
-			'372',
-			'373',
-			'374',
-			'375',
-			'376',
-			'377',
-			'378',
-			'379',
-			'380',
-			'381',
-			'382',
-			'383',
-			'384',
-			'385',
-			'386',
-			'387',
-			'388',
-			'389',
-			'390',
-			'392',
-			'393',
-			'394',
-			'395',
-			'396',
-			'397',
-			'399',
-			'400',
-			'401',
-			'402',
-			'403',
-			'404',
-			'405',
-			'406',
-			'407',
-			'408',
-			'409',
-			'410',
-			'411',
-			'412',
-			'413',
-			'414',
-			'415',
-			'416',
-			'417',
-			'418',
-			'419',
-			'420',
-			'421',
-			'422',
-			'423',
-			'424',
-			'425',
-			'426',
-			'427',
-			'428',
-			'429',
-			'430',
-			'432',
-			'433',
-			'434',
-			'436',
-			'437',
-			'438',
-			'439',
-			'440',
-			'441',
-			'442',
-			'443',
-			'445',
-			'446',
-			'447',
-			'448',
-			'449',
-			'450',
-			'451',
-			'452',
-			'453',
-			'454',
-			'455',
-			'456',
-			'457',
-			'458',
-			'459',
-			'460',
-			'461',
-			'462',
-			'463',
-			'464',
-			'465',
-			'466',
-			'467',
-			'468',
-			'469',
-			'470',
-			'471',
-			'473',
-			'474',
-			'475',
-			'476',
-			'477',
-			'478',
-			'479',
-			'481',
-			'482',
-			'483'
-		]
-	},
-	browserType: {
-		'0': 'Browser',
-		'1': 'Offline Browser',
-		'3': 'Mobile Browser',
-		'4': 'Email client',
-		'5': 'Library',
-		'6': 'Wap Browser',
-		'10': 'Validator',
-		'15': 'Feed Reader',
-		'18': 'Multimedia Player',
-		'20': 'Other',
-		'50': 'Useragent Anonymizer',
-		order: [
-			'0',
-			'1',
-			'3',
-			'4',
-			'5',
-			'6',
-			'10',
-			'15',
-			'18',
-			'20',
-			'50'
-		]
-	},
-	browserReg: {
-		'1': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*seamonkey\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '2'
-		},
-		'2': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*camino\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '1'
-		},
-		'3': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*firefox\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '3'
-		},
-		'4': {
-			regexp: /mozilla[\s\S]*netscape[0-9]?\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '4'
-		},
-		'5': {
-			regexp: /mozilla[\s\S]*gecko\/[0-9]+[\s\S]*epiphany\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '5'
-		},
-		'6': {
-			regexp: /mozilla[\s\S]*gecko\/[0-9]+[\s\S]*galeon\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '6'
-		},
-		'7': {
-			regexp: /mozilla[\s\S]*gecko\/[0-9]+[\s\S]*flock\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '7'
-		},
-		'8': {
-			regexp: /mozilla[\s\S]*gecko\/[0-9]+[\s\S]*minimo\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '8'
-		},
-		'9': {
-			regexp: /mozilla[\s\S]*gecko\/[0-9]+[\s\S]*k\-meleon\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '9'
-		},
-		'10': {
-			regexp: /mozilla[\s\S]*gecko\/[0-9]+[\s\S]*k-ninja\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '10'
-		},
-		'11': {
-			regexp: /mozilla[\s\S]*gecko[\s\S]*kazehakase\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '11'
-		},
-		'14': {
-			regexp: /mozilla[\s\S]*rv[ :][0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*firebird\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '14'
-		},
-		'15': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*phoenix\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '15'
-		},
-		'16': {
-			regexp: /mozilla[\s\S]*konqueror\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '16'
-		},
-		'17': {
-			regexp: /mozilla[\s\S]*opera ([0-9][0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '17'
-		},
-		'18': {
-			regexp: /^opera\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '17'
-		},
-		'19': {
-			regexp: /mozilla[\s\S]*applewebkit\/[0-9]+[\s\S]*omniweb\/v[0-9\.]+/i,
-			browserId: '18'
-		},
-		'20': {
-			regexp: /mozilla[\s\S]*applewebkit\/[0-9]+[\s\S]*sunrisebrowser\/([0-9a-z\+\-\.]+)/i,
-			browserId: '19'
-		},
-		'22': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*shiira\/([0-9a-z\+\-\.]+)[\s\S]*safari/i,
-			browserId: '21'
-		},
-		'23': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*\/[0-9a-z\+\-\.]+[\s\S]*safari\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '22'
-		},
-		'24': {
-			regexp: /dillo\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '23'
-		},
-		'25': {
-			regexp: /icab[ \/]([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '24'
-		},
-		'26': {
-			regexp: /^lynx\/([0-9a-z\.]+)[\s\S]*/i,
-			browserId: '25'
-		},
-		'28': {
-			regexp: /^elinks \(([0-9a-z\.]+)[\s\S]*/i,
-			browserId: '27'
-		},
-		'29': {
-			regexp: /^elinks\/([0-9a-z\.]+)[\s\S]*/i,
-			browserId: '27'
-		},
-		'30': {
-			regexp: /^elinks$/i,
-			browserId: '27'
-		},
-		'31': {
-			regexp: /^Wget\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '28'
-		},
-		'32': {
-			regexp: /Amiga\-Aweb\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '29'
-		},
-		'33': {
-			regexp: /AmigaVoyager\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '30'
-		},
-		'34': {
-			regexp: /IBrowse\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '31'
-		},
-		'35': {
-			regexp: /UP\.Browser\/([0-9a-zA-Z\.]+)[\s\S]*/,
-			browserId: '32'
-		},
-		'36': {
-			regexp: /UP\/([0-9a-zA-Z\.]+)[\s\S]*/,
-			browserId: '32'
-		},
-		'37': {
-			regexp: /NetFront\/([0-9a-z\.]+)[\s\S]*/i,
-			browserId: '33'
-		},
-		'39': {
-			regexp: /mozilla\/[\s\S]*MSIE ([0-9b\.]+)[\s\S]*/i,
-			browserId: '35'
-		},
-		'42': {
-			regexp: /offline explorer\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '39'
-		},
-		'44': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*AOL ([0-9a-z\+\-\.]+)/i,
-			browserId: '40'
-		},
-		'45': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*America Online Browser ([0-9a-z\+\-\.]+)/i,
-			browserId: '40'
-		},
-		'46': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Avant Browser ([0-9a-z\+\-\.]+)/i,
-			browserId: '41'
-		},
-		'47': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Avant Browser/i,
-			browserId: '41'
-		},
-		'48': {
-			regexp: /mozilla[\s\S]*AvantGo ([0-9a-z\+\-\.]+)/i,
-			browserId: '42'
-		},
-		'49': {
-			regexp: /mozilla[\s\S]*Blazer\/([0-9a-z\+\-\.]+)/i,
-			browserId: '43'
-		},
-		'50': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Crazy Browser ([0-9a-z \+\-\.]+)/i,
-			browserId: '44'
-		},
-		'51': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Deepnet Explorer ([0-9a-z\+\-\.]+)/i,
-			browserId: '45'
-		},
-		'52': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Deepnet Explorer/i,
-			browserId: '45'
-		},
-		'53': {
-			regexp: /mozilla[\s\S]*HTTrack ([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '46'
-		},
-		'54': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*IceWeasel\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '47'
-		},
-		'55': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*iRider ([0-9a-z\+\-\.]+)/i,
-			browserId: '48'
-		},
-		'56': {
-			regexp: /[\s\S]*isilox\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '49'
-		},
-		'57': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*KKman([0-9a-z\+\-\.]+)/i,
-			browserId: '50'
-		},
-		'58': {
-			regexp: /libwww\-perl\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '51'
-		},
-		'59': {
-			regexp: /mozilla[\s\S]*Lunascape\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '52'
-		},
-		'60': {
-			regexp: /mozilla[\s\S]*Maxthon ([0-9a-z\+\-\.]+)/i,
-			browserId: '53'
-		},
-		'61': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*MyIE2/i,
-			browserId: '53'
-		},
-		'62': {
-			regexp: /mozilla[\s\S]*(rv:[0-9\.]+)[\s\S]*gecko\/[0-9]+[\s\S]*/i,
-			browserId: '54'
-		},
-		'63': {
-			regexp: /mozilla[\s\S]*MultiZilla ([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '55'
-		},
-		'64': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*NetCaptor ([0-9a-z\+\-\.]+)/i,
-			browserId: '56'
-		},
-		'65': {
-			regexp: /Netgem\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '57'
-		},
-		'66': {
-			regexp: /netsurf\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '58'
-		},
-		'67': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Sleipnir\/([0-9a-z\+\-\.]+)/i,
-			browserId: '59'
-		},
-		'69': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*firefox\/([0-9a-z\+\-\.]+)[\s\S]*swiftfox/i,
-			browserId: '61'
-		},
-		'70': {
-			regexp: /Teleport Pro\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '62'
-		},
-		'77': {
-			regexp: /sunrise[ \/]([0-9a-z\+\-\.\/]+)/i,
-			browserId: '19'
-		},
-		'78': {
-			regexp: /mozilla[\s\S]*galeon\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '6'
-		},
-		'79': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*\(KHTML, like Gecko\)$/i,
-			browserId: '466'
-		},
-		'80': {
-			regexp: /Openwave/i,
-			browserId: '32'
-		},
-		'81': {
-			regexp: /MSIE ([0-9a-z\+\-\.]+)[\s\S]*windows ce/i,
-			browserId: '157'
-		},
-		'82': {
-			regexp: /mozilla[\s\S]*\/[0-9\.]+[\s\S]*gecko[\s\S]*firefox[\s\S]*/i,
-			browserId: '3'
-		},
-		'83': {
-			regexp: /mozilla[\s\S]*(rv:[0-9\.]+)[\s\S]*/i,
-			browserId: '54'
-		},
-		'86': {
-			regexp: /webcopier[\s\S]*v([0-9a-z\.]+)/i,
-			browserId: '71'
-		},
-		'89': {
-			regexp: /MSIE[\s\S]*PhaseOut/i,
-			browserId: '74'
-		},
-		'94': {
-			regexp: /^Mozilla[\s\S]*Thunderbird\/([0-9a-zA-Z\.]+)/i,
-			browserId: '79'
-		},
-		'95': {
-			regexp: /^DoCoMo\//i,
-			browserId: '33'
-		},
-		'97': {
-			regexp: /doris\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '81'
-		},
-		'98': {
-			regexp: /^Enigma browser$/i,
-			browserId: '82'
-		},
-		'100': {
-			regexp: /lwp\-request\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '51'
-		},
-		'102': {
-			regexp: /Jakarta Commons-HttpClient\/([0-9a-zA-Z\.\-]+)/i,
-			browserId: '85'
-		},
-		'103': {
-			regexp: /IBrowse/i,
-			browserId: '31'
-		},
-		'104': {
-			regexp: /^curl ([0-9a-zA-Z\.\-]+)/i,
-			browserId: '86'
-		},
-		'105': {
-			regexp: /Aweb[\s\S]*Amiga/i,
-			browserId: '29'
-		},
-		'106': {
-			regexp: /amaya\/([0-9a-zA-Z\.\-+]+)/i,
-			browserId: '87'
-		},
-		'107': {
-			regexp: /GetRight\/([0-9a-zA-Z\.\-\+]+)/i,
-			browserId: '88'
-		},
-		'108': {
-			regexp: /^Mozilla[\s\S]*OmniWeb\/([1-9a-zA-z\.\-]+)/i,
-			browserId: '18'
-		},
-		'109': {
-			regexp: /Mozilla[\s\S]*OffByOne/i,
-			browserId: '89'
-		},
-		'110': {
-			regexp: /Python\-urllib\/([0-9a-zA-Z\.\-]+)/i,
-			browserId: '90'
-		},
-		'111': {
-			regexp: /w3m\/([0-9a-zA-z\-\+\.]+)/i,
-			browserId: '91'
-		},
-		'113': {
-			regexp: /^WebZIP\/([0-9a-zA-Z\.\-]+)/i,
-			browserId: '93'
-		},
-		'114': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Shiira\/([0-9a-zA-z\.\-]+)/i,
-			browserId: '21'
-		},
-		'115': {
-			regexp: /ICEbrowser\/([0-9a-z_\.\-]+)/i,
-			browserId: '94'
-		},
-		'117': {
-			regexp: /Blazer ([0-9\.]+)/i,
-			browserId: '43'
-		},
-		'118': {
-			regexp: /Iceape\/([0-9a-zA-z\.\-]+)/i,
-			browserId: '96'
-		},
-		'120': {
-			regexp: /Jakarta Commons\-HttpClient/i,
-			browserId: '85'
-		},
-		'122': {
-			regexp: /HotJava\/([0-9a-zA-Z\.\- ]+)/i,
-			browserId: '99'
-		},
-		'123': {
-			regexp: /JoBo\/([0-9a-z\.\-]+)/i,
-			browserId: '100'
-		},
-		'126': {
-			regexp: /Sleipnir Version ([0-9a-z\.]+)/i,
-			browserId: '59'
-		},
-		'130': {
-			regexp: /poe-component-client-http\/([0-9a-z\.\-]+)/i,
-			browserId: '105'
-		},
-		'137': {
-			regexp: /snoopy v([1-9\.]+)/i,
-			browserId: '111'
-		},
-		'138': {
-			regexp: /Lynx/i,
-			browserId: '25'
-		},
-		'139': {
-			regexp: /libwww\-perl/i,
-			browserId: '51'
-		},
-		'141': {
-			regexp: /NetFront([0-9a-z\.]+)[\s\S]*/i,
-			browserId: '33'
-		},
-		'143': {
-			regexp: /^opera ([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '17'
-		},
-		'147': {
-			regexp: /NCSA_Mosaic\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '117'
-		},
-		'149': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*kapiko\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '119'
-		},
-		'150': {
-			regexp: /mozilla[\s\S]*chrome\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '120'
-		},
-		'151': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*AdobeAIR\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '121'
-		},
-		'152': {
-			regexp: /^lwp-trivial\/([0-9.]+)$/i,
-			browserId: '122'
-		},
-		'153': {
-			regexp: /^WWW-Mechanize\/([0-9a-z\+\-\.]+)/i,
-			browserId: '123'
-		},
-		'155': {
-			regexp: /^Xenu Link Sleuth ([0-9a-z\+\-\.]+)$/i,
-			browserId: '124'
-		},
-		'156': {
-			regexp: /^SiteSucker\/([0-9a-z\.]+)/i,
-			browserId: '125'
-		},
-		'157': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*arora\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '126'
-		},
-		'160': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*Shiretoko\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '128'
-		},
-		'161': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*Minefield\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '129'
-		},
-		'162': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*iron\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '130'
-		},
-		'163': {
-			regexp: /mozilla[\s\S][\s\S]*lobo\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '131'
-		},
-		'164': {
-			regexp: /^links \(([0-9a-z\.]+)[\s\S]*/i,
-			browserId: '132'
-		},
-		'165': {
-			regexp: /mozilla[\s\S]*PlayStation\ Portable[\s\S]*/i,
-			browserId: '33'
-		},
-		'166': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Maxthon/i,
-			browserId: '53'
-		},
-		'167': {
-			regexp: /Netbox\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '57'
-		},
-		'169': {
-			regexp: /^Mozilla\/(3\.0)[\s\S]*Sun\)$/i,
-			browserId: '99'
-		},
-		'170': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*fennec\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '133'
-		},
-		'171': {
-			regexp: /mozilla[\s\S]*Lotus-Notes\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '134'
-		},
-		'172': {
-			regexp: /^klondike\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '135'
-		},
-		'173': {
-			regexp: /^WapTiger\/5[\s\S]0 \(http:\/\/www\.waptiger\.com\/[\s\S]*/i,
-			browserId: '136'
-		},
-		'174': {
-			regexp: /^W3C_Validator\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '137'
-		},
-		'175': {
-			regexp: /^W3C-checklink\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '138'
-		},
-		'176': {
-			regexp: /^HTMLParser\/([0-9a-z\.]+)$/i,
-			browserId: '139'
-		},
-		'177': {
-			regexp: /^LWP::Simple\/([0-9a-z\.]+)$/i,
-			browserId: '122'
-		},
-		'178': {
-			regexp: /^Java\/([0-9a-z\._]+)/i,
-			browserId: '140'
-		},
-		'179': {
-			regexp: /Bolt\/([0-9\.]+)/i,
-			browserId: '141'
-		},
-		'180': {
-			regexp: /Demeter\/([0-9\.]+)/i,
-			browserId: '142'
-		},
-		'181': {
-			regexp: /^UniversalFeedParser\/([0-9\.]+)/i,
-			browserId: '143'
-		},
-		'182': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*shiira[\s\S]*safari/i,
-			browserId: '21'
-		},
-		'183': {
-			regexp: /mozilla[\s\S]*firefox[\s\S]*orca\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '144'
-		},
-		'184': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*fluid\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '145'
-		},
-		'185': {
-			regexp: /Bookdog\/([0-9\.]+)/i,
-			browserId: '146'
-		},
-		'186': {
-			regexp: /http:\/\/Anonymouse[\s\S]org\/ \(Unix\)/i,
-			browserId: '147'
-		},
-		'187': {
-			regexp: /^Midori\/([0-9\.]+)/i,
-			browserId: '148'
-		},
-		'188': {
-			regexp: /boxee[\s\S]*\([\s\S]*\ ([0-9a-zA-Z\.]+)\)/i,
-			browserId: '149'
-		},
-		'189': {
-			regexp: /^gPodder\/([0-9\.]+)/i,
-			browserId: '150'
-		},
-		'190': {
-			regexp: /^Samsung-[a-zA-Z09]+[\s\S]*AU-MIC-[a-zA-Z0-9]+\/([0-9\.]+)/i,
-			browserId: '151'
-		},
-		'191': {
-			regexp: /^SonyEricsson[\s\S]*SEMC-Browser\/([0-9\.]+)/i,
-			browserId: '152'
-		},
-		'192': {
-			regexp: /NF-Browser\/([0-9\.]+)/i,
-			browserId: '33'
-		},
-		'193': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*GranParadiso\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '153'
-		},
-		'194': {
-			regexp: /^WDG_Validator\/([0-9\.]+)/i,
-			browserId: '154'
-		},
-		'195': {
-			regexp: /^CSSCheck\/([0-9\.]+)/i,
-			browserId: '155'
-		},
-		'196': {
-			regexp: /^Page Valet\/([0-9a-z\.]+)/i,
-			browserId: '156'
-		},
-		'197': {
-			regexp: /IEMobile ([0-9\.]+)/i,
-			browserId: '157'
-		},
-		'198': {
-			regexp: /mozilla[\s\S]*Lunascape ([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '52'
-		},
-		'199': {
-			regexp: /BlackBerry/i,
-			browserId: '158'
-		},
-		'200': {
-			regexp: /Obigo[\s\S]*Profile\/MIDP/i,
-			browserId: '151'
-		},
-		'201': {
-			regexp: /Browser\/Teleca|Teleca\/[\s\S]*MIDP/i,
-			browserId: '151'
-		},
-		'202': {
-			regexp: /Polaris\/([0-9\.]+)/i,
-			browserId: '159'
-		},
-		'203': {
-			regexp: /Hv3\/([0-9a-z\.])/i,
-			browserId: '160'
-		},
-		'204': {
-			regexp: /^WinWAP\/([0-9\.]+)/i,
-			browserId: '161'
-		},
-		'205': {
-			regexp: /^XBMC\/([0-9a-z\.\-]+)/i,
-			browserId: '162'
-		},
-		'206': {
-			regexp: /^XML-RPC for PHP ([0-9a-z\.]+)$/i,
-			browserId: '163'
-		},
-		'207': {
-			regexp: /^OmniWeb\/([0-9a-z\.\-]+)/i,
-			browserId: '18'
-		},
-		'208': {
-			regexp: /^FlyCast\/([0-9\.]+)/i,
-			browserId: '165'
-		},
-		'209': {
-			regexp: /^Bloglines\/([0-9\.]+)/i,
-			browserId: '166'
-		},
-		'210': {
-			regexp: /^Gregarius\/([0-9\.]+)/i,
-			browserId: '167'
-		},
-		'211': {
-			regexp: /^SimplePie\/([0-9a-z\. ]+)/i,
-			browserId: '168'
-		},
-		'212': {
-			regexp: /^PycURL\/([0-9\.]+)$/i,
-			browserId: '169'
-		},
-		'213': {
-			regexp: /^Apple-PubSub\/([0-9\.]+)$/i,
-			browserId: '170'
-		},
-		'214': {
-			regexp: /^Feedfetcher-Google[\s\S]*http:\/\/www\.google\.com\/feedfetcher\.html/i,
-			browserId: '171'
-		},
-		'215': {
-			regexp: /^FeedValidator\/([0-9\.]+)$/i,
-			browserId: '172'
-		},
-		'216': {
-			regexp: /^MagpieRSS\/([0-9\.]+)/i,
-			browserId: '173'
-		},
-		'217': {
-			regexp: /^BlogBridge ([0-9\.]+)/i,
-			browserId: '174'
-		},
-		'218': {
-			regexp: /Miro\/([0-9a-z\-\.]+)[\s\S]*http:\/\/www\.getmiro\.com\//i,
-			browserId: '175'
-		},
-		'219': {
-			regexp: /^Liferea\/([0-9\.]+)[\s\S]*http:\/\/liferea\.sf\.net\//i,
-			browserId: '176'
-		},
-		'220': {
-			regexp: /^HomePage Rss Reader ([0-9\.]+)/i,
-			browserId: '177'
-		},
-		'221': {
-			regexp: /^PHP\/([0-9a-z\.\-]+)$/i,
-			browserId: '178'
-		},
-		'222': {
-			regexp: /^REL Link Checker Lite ([0-9\.]+)$/i,
-			browserId: '179'
-		},
-		'223': {
-			regexp: /^CPG RSS Module File Reader/i,
-			browserId: '180'
-		},
-		'224': {
-			regexp: /^Dragonfly File Reader/i,
-			browserId: '180'
-		},
-		'225': {
-			regexp: /^CPG Dragonfly RSS Module Feed Viewer/i,
-			browserId: '180'
-		},
-		'226': {
-			regexp: /^newsbeuter\/([0-9\.]+)/i,
-			browserId: '181'
-		},
-		'227': {
-			regexp: /^Jigsaw\/[0-9\.]+ W3C_CSS_Validator_JFouffa\/([0-9\.]+)$/i,
-			browserId: '182'
-		},
-		'228': {
-			regexp: /^FPLinkChecker\/([0-9\.]+)$/i,
-			browserId: '183'
-		},
-		'229': {
-			regexp: /^GoldenPod ([0-9\.]+)/i,
-			browserId: '184'
-		},
-		'230': {
-			regexp: /Cheshire\/([0-9a-z\.]+)/i,
-			browserId: '185'
-		},
-		'231': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*chimera\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '1'
-		},
-		'232': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*CometBird\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '187'
-		},
-		'233': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*IceCat\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '188'
-		},
-		'234': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*Stainless\/([0-9a-z\+\-\.]+)[\s\S]*safari/i,
-			browserId: '189'
-		},
-		'235': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Prism\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '190'
-		},
-		'236': {
-			regexp: /^curl\/([0-9a-zA-Z\.\-]+)/i,
-			browserId: '86'
-		},
-		'237': {
-			regexp: /^MPlayer\//i,
-			browserId: '191'
-		},
-		'238': {
-			regexp: /^Mozilla\/4\.0[\s\S]*Win32[\s\S]*ActiveXperts\.Http\.([0-9\.]+)/i,
-			browserId: '192'
-		},
-		'239': {
-			regexp: /^MOT[\s\S]*MIB\/([0-9\.]+)/i,
-			browserId: '193'
-		},
-		'240': {
-			regexp: /^Abilon$/i,
-			browserId: '194'
-		},
-		'241': {
-			regexp: /^check_http\/([0-9a-z\.]+) \(nagios\-plugins/i,
-			browserId: '195'
-		},
-		'242': {
-			regexp: /^Windows\-Media\-Player\/([0-9\.]+)$/i,
-			browserId: '196'
-		},
-		'243': {
-			regexp: /^VLC media player \- version ([0-9a-z\-\.]+) [\s\S]* VideoLAN team$/i,
-			browserId: '197'
-		},
-		'244': {
-			regexp: /^P3P Validator$/i,
-			browserId: '198'
-		},
-		'245': {
-			regexp: /^CSE HTML Validator Lite Online/i,
-			browserId: '199'
-		},
-		'246': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Navigator\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '4'
-		},
-		'247': {
-			regexp: /^JetBrains Omea Reader ([0-9\.]+)/i,
-			browserId: '200'
-		},
-		'248': {
-			regexp: /^GSiteCrawler\/([0-9a-z\.]+)/i,
-			browserId: '201'
-		},
-		'249': {
-			regexp: /^YahooFeedSeeker\/([0-9\.]+)/i,
-			browserId: '202'
-		},
-		'250': {
-			regexp: /^Democracy\/([0-9\.]+)/i,
-			browserId: '175'
-		},
-		'251': {
-			regexp: /^Java([0-9\._]+)$/i,
-			browserId: '140'
-		},
-		'253': {
-			regexp: /^mozilla\/[\s\S]*MSIE [0-9\.]+[\s\S]*TheWorld/i,
-			browserId: '204'
-		},
-		'254': {
-			regexp: /^webcollage\/([0-9\.]+)$/i,
-			browserId: '205'
-		},
-		'255': {
-			regexp: /^webcollage\-noporn\/([0-9\.]+)$/i,
-			browserId: '205'
-		},
-		'256': {
-			regexp: /^webcollage\.[a-z]+\/([0-9\.]+)$/i,
-			browserId: '205'
-		},
-		'257': {
-			regexp: /^webcollage1\/([0-9\.]+)$/i,
-			browserId: '205'
-		},
-		'258': {
-			regexp: /^NewsGatorOnline\/([0-9\.]+) \(http:\/\/www\.newsgator\.com/i,
-			browserId: '206'
-		},
-		'259': {
-			regexp: /^Mozilla[\s\S]*PRTG Network Monitor/i,
-			browserId: '207'
-		},
-		'260': {
-			regexp: /^Web Downloader\/([0-9\.]+)$/i,
-			browserId: '39'
-		},
-		'261': {
-			regexp: /^Opera\/[0-9\.]+[\s\S]*Presto\/[0-9\.]+ Version\/([0-9\.]+)$/i,
-			browserId: '17'
-		},
-		'262': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Songbird\/([0-9\.]+)/i,
-			browserId: '208'
-		},
-		'263': {
-			regexp: /^Avant Browser/i,
-			browserId: '41'
-		},
-		'264': {
-			regexp: /^RSS_Radio ([0-9\.]+)$/i,
-			browserId: '209'
-		},
-		'265': {
-			regexp: /^Feed::Find\/([0-9\.]+)$/i,
-			browserId: '210'
-		},
-		'266': {
-			regexp: /^Mozilla\/[\s\S]*webOS\/[0-9\.]+[\s\S]*AppleWebKit[\s\S]*Pre\/([0-9\.]+)$/i,
-			browserId: '211'
-		},
-		'267': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*BonEcho\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '212'
-		},
-		'268': {
-			regexp: /^QuickTime\/([0-9\.]+)/,
-			browserId: '213'
-		},
-		'269': {
-			regexp: /^QuickTime[\s\S]*qtver=([0-9\.a-z]+)/i,
-			browserId: '213'
-		},
-		'270': {
-			regexp: /^PHPCrawl$/i,
-			browserId: '214'
-		},
-		'271': {
-			regexp: /mozilla[\s\S]*Linux armv7l[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*Tablet browser ([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '260'
-		},
-		'272': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*GreenBrowser/i,
-			browserId: '216'
-		},
-		'273': {
-			regexp: /^Awasu\/([0-9a-z\.]+)$/i,
-			browserId: '217'
-		},
-		'274': {
-			regexp: /^CorePlayer[\s\S]*CorePlayer\/([0-9\._]+)$/i,
-			browserId: '218'
-		},
-		'275': {
-			regexp: /^Mozilla\/[\s\S]*AppleWebKit[\s\S]*QtWeb Internet Browser\/([0-9\.]+)/i,
-			browserId: '219'
-		},
-		'276': {
-			regexp: /^Mozilla\/[\s\S]*AppleWebKit[\s\S]*TeaShark\/([0-9\.]+)$/i,
-			browserId: '220'
-		},
-		'277': {
-			regexp: /^libsoup\/([0-9a-z\.]+)$/i,
-			browserId: '221'
-		},
-		'278': {
-			regexp: /^Mozilla\/[\s\S]*AppleWebKit[\s\S]*NetNewsWire\/([0-9a-z\.]+)$/i,
-			browserId: '222'
-		},
-		'279': {
-			regexp: /^NetNewsWire\/([0-9a-z\.]+)[\s\S]*http:\/\/www\.newsgator\.com\/Individuals\/NetNews/i,
-			browserId: '222'
-		},
-		'280': {
-			regexp: /http:\/\/code\.google\.com\/appengine/i,
-			browserId: '223'
-		},
-		'281': {
-			regexp: /UCWEB/i,
-			browserId: '225'
-		},
-		'287': {
-			regexp: /NokiaN93/i,
-			browserId: '226'
-		},
-		'289': {
-			regexp: /Nokia[\s\S]*SymbianOS[\s\S]*Series60/i,
-			browserId: '226'
-		},
-		'292': {
-			regexp: /SymbianOS[\s\S]*Series60[\s\S]*Nokia[\s\S]*AppleWebKit/i,
-			browserId: '226'
-		},
-		'293': {
-			regexp: /^lftp\/([0-9a-z\.]+)$/,
-			browserId: '227'
-		},
-		'294': {
-			regexp: /^WinWAP-SPBE\/([0-9\.]+)/i,
-			browserId: '161'
-		},
-		'295': {
-			regexp: /^Mozilla[\s\S]*RISC[\s\S]*Oregano ([0-9\.]+)/i,
-			browserId: '228'
-		},
-		'296': {
-			regexp: /^libsummer\/([0-9\.]+)/i,
-			browserId: '229'
-		},
-		'297': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Acoo Browser/i,
-			browserId: '230'
-		},
-		'298': {
-			regexp: /^Mozilla[\s\S]*NewsFox\/([0-9\.]+)/i,
-			browserId: '231'
-		},
-		'299': {
-			regexp: /^Mozilla[\s\S]*Danger hiptop/i,
-			browserId: '33'
-		},
-		'300': {
-			regexp: /Mozilla[\s\S]*MSIE[\s\S]*Hydra Browser/i,
-			browserId: '232'
-		},
-		'301': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*wKiosk/i,
-			browserId: '233'
-		},
-		'302': {
-			regexp: /Mozilla\/[\s\S]*AppleWebKit[\s\S]*Paparazzi!\/([0-9a-z\.]+)/i,
-			browserId: '234'
-		},
-		'303': {
-			regexp: /^xine\/([0-9a-z\.]+)/i,
-			browserId: '235'
-		},
-		'304': {
-			regexp: /^webfs\/([0-9\.]+) \(plan 9\)$/i,
-			browserId: '236'
-		},
-		'305': {
-			regexp: /^Ilium Software NewsBreak/i,
-			browserId: '237'
-		},
-		'306': {
-			regexp: /^LinkbackPlugin\/([0-9a-z\.]+) Laconica\//i,
-			browserId: '238'
-		},
-		'307': {
-			regexp: /^Microsoft Data Access Internet Publishing Provider DAV/i,
-			browserId: '239'
-		},
-		'308': {
-			regexp: /^gvfs\/([0-9a-z\.]+)/i,
-			browserId: '240'
-		},
-		'309': {
-			regexp: /^Webkit\/[\s\S]*Uzbl/i,
-			browserId: '241'
-		},
-		'310': {
-			regexp: /^Uzbl[\s\S]*Webkit/i,
-			browserId: '241'
-		},
-		'311': {
-			regexp: /^Cynthia ([0-9\.]+)$/i,
-			browserId: '242'
-		},
-		'312': {
-			regexp: /^Mozilla\/5\.0 \(Sage\)$/i,
-			browserId: '243'
-		},
-		'313': {
-			regexp: /^Banshee ([0-9a-z\.]+)[\s\S]*http:\/\/banshee-project\.org/i,
-			browserId: '244'
-		},
-		'314': {
-			regexp: /^Mozilla\/[\s\S]*Gecko[\s\S]* Firefox[\s\S]*Wyzo\/([0-9a-z\.]+)/i,
-			browserId: '245'
-		},
-		'315': {
-			regexp: /^RSSOwl\/([0-9]\.[0-9]\.[0-9])/i,
-			browserId: '246'
-		},
-		'316': {
-			regexp: /^Mozilla\/[\s\S]*ABrowse ([0-9\.]+)[\s\S]*Syllable/i,
-			browserId: '247'
-		},
-		'317': {
-			regexp: /^Funambol Outlook Plug-in[\s\S]*([0-9\.]+)$/i,
-			browserId: '248'
-		},
-		'318': {
-			regexp: /^Funambol Mozilla Sync Client v([0-9\.]+)$/i,
-			browserId: '249'
-		},
-		'319': {
-			regexp: /^RSS Menu\/([0-9\.]+)/i,
-			browserId: '250'
-		},
-		'320': {
-			regexp: /^foobar2000\/([0-9a-z\._]+$)/i,
-			browserId: '251'
-		},
-		'321': {
-			regexp: /^GStreamer souphttpsrc libsoup\/[0-9\.]+$/i,
-			browserId: '252'
-		},
-		'322': {
-			regexp: /^Mozilla\/[\s\S]*Mobile Content Viewer\/([0-9\.]+)[\s\S]*NetFront/i,
-			browserId: '253'
-		},
-		'323': {
-			regexp: /^php-openid\/([0-9\.]+)/i,
-			browserId: '254'
-		},
-		'324': {
-			regexp: /NCSA Mosaic\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '117'
-		},
-		'325': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Blackbird\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '255'
-		},
-		'326': {
-			regexp: /^Mozilla\/4[\s\S]0 \(compatible; MSIE ([0-9\.]+); Windows/i,
-			browserId: '35'
-		},
-		'327': {
-			regexp: /ICE browser\/([0-9a-z_\.\-]+)/i,
-			browserId: '94'
-		},
-		'328': {
-			regexp: /^GreatNews\/([0-9\.]+)$/i,
-			browserId: '256'
-		},
-		'329': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*DeskBrowse\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '257'
-		},
-		'330': {
-			regexp: /^TulipChain\/([0-9\.]+)[\s\S]*ostermiller[\s\S]org\/tulipchain[\s\S]*Java/i,
-			browserId: '258'
-		},
-		'331': {
-			regexp: /^Mozilla\/[\s\S]*AppleWebKit\/[\s\S]*Maxthon\/([0-9\.]+)/i,
-			browserId: '53'
-		},
-		'332': {
-			regexp: /^Axel ([0-9\.]+)/i,
-			browserId: '259'
-		},
-		'333': {
-			regexp: /^Mozilla\/[\s\S]*Linux[\s\S]*AppleWebKit[\s\S]*tear/i,
-			browserId: '261'
-		},
-		'334': {
-			regexp: /^LinkExaminer\/([0-9\.]+) \(Windows\)$/i,
-			browserId: '262'
-		},
-		'335': {
-			regexp: /^Mozilla\/[\s\S]*MSIE[\s\S]*http:\/\/www\.Abolimba\.de/i,
-			browserId: '263'
-		},
-		'336': {
-			regexp: /^Mozilla\/[\s\S]*Gecko\/[\s\S]*Beonex\/([0-9a-z\.\-]+)/i,
-			browserId: '264'
-		},
-		'337': {
-			regexp: /^DocZilla\/([0-9\.]+)[\s\S]*Gecko\//i,
-			browserId: '265'
-		},
-		'338': {
-			regexp: /^retawq\/([0-9a-z\.]+)[\s\S]*\(text\)$/i,
-			browserId: '266'
-		},
-		'339': {
-			regexp: /^SAMSUNG[\s\S]*Jasmine\/([0-9\.]+)/i,
-			browserId: '267'
-		},
-		'340': {
-			regexp: /Opera\/[\s\S]*Opera Mini\/([0-9\.]+)/i,
-			browserId: '268'
-		},
-		'341': {
-			regexp: /Mozilla\/[\s\S]*AppleWebKit[\s\S]*Dooble/i,
-			browserId: '269'
-		},
-		'342': {
-			regexp: /Mozilla\/[\s\S]*Gecko[\s\S]*Firefox[\s\S]*Madfox\/([0-9a-z\.]+)/i,
-			browserId: '270'
-		},
-		'343': {
-			regexp: /^DownloadStudio\/([0-9\.]+)$/i,
-			browserId: '271'
-		},
-		'344': {
-			regexp: /^WinPodder[\s\S]*http:\/\/winpodder\.com/i,
-			browserId: '272'
-		},
-		'345': {
-			regexp: /^Bunjalloo\/([0-9\.]+)[\s\S]*Nintendo/i,
-			browserId: '273'
-		},
-		'346': {
-			regexp: /^LinkChecker\/([0-9\.]+)[\s\S]*linkchecker\.sourceforge\.net/i,
-			browserId: '274'
-		},
-		'348': {
-			regexp: /urlgrabber\/([0-9\.]+)/i,
-			browserId: '276'
-		},
-		'349': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Spicebird\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '277'
-		},
-		'350': {
-			regexp: /[\s\S]*Obigo Browser ([0-9\.]+)/i,
-			browserId: '151'
-		},
-		'351': {
-			regexp: /ObigoInternetBrowser/i,
-			browserId: '151'
-		},
-		'352': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*Namoroka\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '278'
-		},
-		'353': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*rekonq[\/]{0,1}([0-9a-z\.]+){0,1}[\s\S]*/i,
-			browserId: '279'
-		},
-		'354': {
-			regexp: /^W3C_Multipage_Validator\/([0-9a-z\.]+)[\s\S]*http:\/\/www\.validator\.ca\//i,
-			browserId: '280'
-		},
-		'355': {
-			regexp: /^X\-Smiles\/([0-9a-z\.]+)/i,
-			browserId: '281'
-		},
-		'356': {
-			regexp: /WinHttp/i,
-			browserId: '282'
-		},
-		'357': {
-			regexp: /^Xaldon_WebSpider\/([0-9a-z\.]+)/i,
-			browserId: '283'
-		},
-		'358': {
-			regexp: /^Xaldon WebSpider ([0-9a-z\.]+)/i,
-			browserId: '283'
-		},
-		'359': {
-			regexp: /\/szn-mobile-transcoder/i,
-			browserId: '284'
-		},
-		'360': {
-			regexp: /^SZN-Image-Resizer$/i,
-			browserId: '284'
-		},
-		'361': {
-			regexp: /Google Wireless Transcoder/i,
-			browserId: '285'
-		},
-		'362': {
-			regexp: /^Google-Listen\/([0-9a-z\.]+)/i,
-			browserId: '286'
-		},
-		'363': {
-			regexp: /^Typhoeus[\s\S]*http:\/\/github[\s\S]com\/pauldix\/typhoeus/i,
-			browserId: '287'
-		},
-		'364': {
-			regexp: /^Mozilla\/[\s\S]*Origyn Web Browser/i,
-			browserId: '288'
-		},
-		'365': {
-			regexp: /mozilla[\s\S]*MSIE [0-9a-z\+\-\.]+[\s\S]*Browzar/i,
-			browserId: '289'
-		},
-		'366': {
-			regexp: /^Claws Mail GtkHtml2 plugin ([0-9a-z\.]+)[\s\S]*http:\/\/www[\s\S]claws-mail[\s\S]org\/plugins[\s\S]php/i,
-			browserId: '290'
-		},
-		'367': {
-			regexp: /Python\-urllib$/i,
-			browserId: '90'
-		},
-		'368': {
-			regexp: /^Azureus ([0-9a-z\.]+)/i,
-			browserId: '291'
-		},
-		'369': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*GlobalMojo\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '292'
-		},
-		'370': {
-			regexp: /^GomPlayer ([0-9, ]+)/i,
-			browserId: '293'
-		},
-		'371': {
-			regexp: /^Python-webchecker\/([0-9]+)$/i,
-			browserId: '294'
-		},
-		'372': {
-			regexp: /^W3C-mobileOK\/DDC-([0-9\.]+)[\s\S]* http:\/\/www[\s\S]w3[\s\S]org\/2006\/07\/mobileok-ddc/i,
-			browserId: '296'
-		},
-		'373': {
-			regexp: /^JoeDog\/[\s\S]*Siege ([0-9\.]+)/i,
-			browserId: '297'
-		},
-		'374': {
-			regexp: /^iSiloXC\/([0-9\.]+)/i,
-			browserId: '298'
-		},
-		'375': {
-			regexp: /^ApacheBench\/([0-9a-z\-\.]+)$/i,
-			browserId: '299'
-		},
-		'376': {
-			regexp: /^anw webtool LoadControl\/([0-9\.]+)$/i,
-			browserId: '300'
-		},
-		'377': {
-			regexp: /^topSUBMIT[\s\S]de HTMLChecker\/([0-9\.]+)$/i,
-			browserId: '301'
-		},
-		'378': {
-			regexp: /^edbrowse\/([0-9\.\-]+)/i,
-			browserId: '302'
-		},
-		'379': {
-			regexp: /^muCommander v([0-9\.]+)/i,
-			browserId: '303'
-		},
-		'380': {
-			regexp: /^muCommander-file-API/i,
-			browserId: '303'
-		},
-		'381': {
-			regexp: /^XMPlay\/([0-9\.]+)$/i,
-			browserId: '304'
-		},
-		'382': {
-			regexp: /^NFReader\/([0-9\.]+)/i,
-			browserId: '305'
-		},
-		'383': {
-			regexp: /^Mozilla\/[\s\S]*uZardWeb\/([0-9\.]+)/i,
-			browserId: '306'
-		},
-		'384': {
-			regexp: /^Mozilla\/3[\s\S]0 \(compatible; Indy Library\)$/i,
-			browserId: '307'
-		},
-		'385': {
-			regexp: /^Mozilla\/[\s\S]*MSIE[\s\S]*Multi\-Browser ([0-9\.]+)[\s\S]*www\.multibrowser\.de/i,
-			browserId: '308'
-		},
-		'386': {
-			regexp: /^LinkWalker\/([0-9\.]+)[\s\S]*www\.seventwentyfour\.com/i,
-			browserId: '309'
-		},
-		'387': {
-			regexp: /^Mozilla[\s\S]*compatible[\s\S]*NetPositive\/([0-9\.]+)/i,
-			browserId: '310'
-		},
-		'388': {
-			regexp: /^Radio Downloader ([0-9\.]+)$/i,
-			browserId: '311'
-		},
-		'389': {
-			regexp: /^WebStripper\/([0-9\.]+)/i,
-			browserId: '312'
-		},
-		'390': {
-			regexp: /^Cyberduck\/([0-9\.]+)/i,
-			browserId: '313'
-		},
-		'391': {
-			regexp: /^WorldWideweb \(NEXT\)$/i,
-			browserId: '314'
-		},
-		'392': {
-			regexp: /^iVideo ([a-z0-9\.\ ]+)[\s\S]*iPhone OS/i,
-			browserId: '315'
-		},
-		'393': {
-			regexp: /^Mozilla\/4[\s\S]0 \(compatible; RSS Popper\)$/i,
-			browserId: '316'
-		},
-		'394': {
-			regexp: /^Win[\s\S]*Jamcast\/([0-9\.]+)/i,
-			browserId: '317'
-		},
-		'395': {
-			regexp: /^Jamcast ([0-9\.]+)$/i,
-			browserId: '317'
-		},
-		'396': {
-			regexp: /mozilla[\s\S]*Comodo_Dragon\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '318'
-		},
-		'397': {
-			regexp: /Mozilla\/4[\s\S]*OS\/2/i,
-			browserId: '4'
-		},
-		'398': {
-			regexp: /^SuperBot\/([0-9\.]+)/i,
-			browserId: '319'
-		},
-		'399': {
-			regexp: /^MyIBrow\/([0-9\.]+)[\s\S]*Windows/i,
-			browserId: '320'
-		},
-		'400': {
-			regexp: /Opera mobi[\s\S]*Version\/([0-9\.]+)/i,
-			browserId: '321'
-		},
-		'401': {
-			regexp: /Opera Mobi[\s\S]*Opera ([0-9\.]+)/i,
-			browserId: '321'
-		},
-		'402': {
-			regexp: /Opera ([0-9\.]+)[\s\S]*Opera Mobi/i,
-			browserId: '321'
-		},
-		'403': {
-			regexp: /^Mozilla[\s\S]*Gecko[\s\S]*Strata\/([0-9\.]+)/i,
-			browserId: '322'
-		},
-		'404': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*TencentTraveler/i,
-			browserId: '323'
-		},
-		'405': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*TencentTraveler ([0-9\.]+)/i,
-			browserId: '323'
-		},
-		'406': {
-			regexp: /^Mozilla[\s\S]*rv:[0-9\.]+[\s\S]*Gecko[\s\S]*Firefox[\s\S]*LBrowser\/([0-9a-z\-\.]+)/i,
-			browserId: '324'
-		},
-		'407': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*MSOffice 12/i,
-			browserId: '325'
-		},
-		'408': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*MSOffice 14/i,
-			browserId: '326'
-		},
-		'409': {
-			regexp: /^Outlook-Express\/7\.0 \(MSIE 7\.0[\s\S]*Windows/i,
-			browserId: '327'
-		},
-		'410': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows[\s\S]*Tjusig ([0-9\.]+)/i,
-			browserId: '328'
-		},
-		'411': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows[\s\S]*SiteKiosk ([0-9\.]+)/,
-			browserId: '329'
-		},
-		'412': {
-			regexp: /^The Bat! ([0-9\.]+)$/i,
-			browserId: '330'
-		},
-		'413': {
-			regexp: /^Mozilla[\s\S]*compatible[\s\S]*BorderManager ([0-9\.]+)/i,
-			browserId: '331'
-		},
-		'414': {
-			regexp: /^Mozilla[\s\S]*Shredder\/([0-9a-zA-Z\.]+)/i,
-			browserId: '332'
-		},
-		'415': {
-			regexp: /^PublicRadioPlayer\/([0-9\.]+)/i,
-			browserId: '333'
-		},
-		'416': {
-			regexp: /^PublicRadioApp\/([0-9\.]+)/i,
-			browserId: '333'
-		},
-		'417': {
-			regexp: /PLAYSTATION 3/i,
-			browserId: '33'
-		},
-		'418': {
-			regexp: /^RssBandit\/([0-9\.]+)/i,
-			browserId: '334'
-		},
-		'419': {
-			regexp: /^Microsoft Office\/14[\s\S]*MSOffice 14/i,
-			browserId: '326'
-		},
-		'420': {
-			regexp: /^Mozilla[\s\S]*Postbox\/([0-9a-zA-Z\.]+)/i,
-			browserId: '335'
-		},
-		'421': {
-			regexp: /^Postbox ([0-9a-z\.]+)/i,
-			browserId: '335'
-		},
-		'422': {
-			regexp: /^2Bone_LinkChecker\/([0-9\.]+)/i,
-			browserId: '336'
-		},
-		'423': {
-			regexp: /^Checkbot\/([0-9\.]+)/i,
-			browserId: '337'
-		},
-		'424': {
-			regexp: /^GcMail Browser\/([0-9\.]+)/i,
-			browserId: '338'
-		},
-		'425': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Swiftweasel\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '339'
-		},
-		'426': {
-			regexp: /^Fastladder FeedFetcher\/([0-9\.]+)[\s\S]*fastladder[\s\S]com/i,
-			browserId: '340'
-		},
-		'427': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Lorentz\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '341'
-		},
-		'428': {
-			regexp: /^PocketTunes\/([0-9a-z\.]+)$/i,
-			browserId: '342'
-		},
-		'429': {
-			regexp: /^SharpReader\/([0-9\.]+)/i,
-			browserId: '343'
-		},
-		'430': {
-			regexp: /^YeahReader/i,
-			browserId: '344'
-		},
-		'431': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*Palemoon\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '345'
-		},
-		'432': {
-			regexp: /^holmes\/([0-9\.]+)/i,
-			browserId: '346'
-		},
-		'433': {
-			regexp: /^mozilla[\s\S]*AppleWebKit[\s\S]*Google Earth\/([0-9\.]+)/i,
-			browserId: '347'
-		},
-		'434': {
-			regexp: /mozilla[\s\S]*flock\/([0-9\.]+)[\s\S]*chrome/i,
-			browserId: '7'
-		},
-		'435': {
-			regexp: /^Rome Client \(http:\/\/tinyurl\.com\/64t5n\) Ver: ([0-9\.]+)/i,
-			browserId: '348'
-		},
-		'436': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko[\s\S]*myibrow\/([0-9a-z\.]+)/i,
-			browserId: '320'
-		},
-		'437': {
-			regexp: /^Akregator\/([0-9\.]+)[\s\S]*librss\/remnants/i,
-			browserId: '349'
-		},
-		'438': {
-			regexp: /HTC[\s\S]*Opera\/([0-9\.]+)[\s\S]*Windows/i,
-			browserId: '321'
-		},
-		'439': {
-			regexp: /^Mozilla[\s\S]*Windows[\s\S]*AppleWebKit[\s\S]*MiniBrowser\/([0-9\.]+)/i,
-			browserId: '350'
-		},
-		'440': {
-			regexp: /^Mozilla[\s\S]*Escape ([0-9\.]+)/i,
-			browserId: '351'
-		},
-		'441': {
-			regexp: /^Mozilla[\s\S]*Windows[\s\S]*UltraBrowser ([0-9\.]+)/i,
-			browserId: '352'
-		},
-		'442': {
-			regexp: /^Mozilla[\s\S]*BrowseX \(([0-9\.]+)/i,
-			browserId: '353'
-		},
-		'443': {
-			regexp: /Mozilla[\s\S]*Linux[\s\S]*Android[\s\S]*AppleWebKit[\s\S]*Version\/([0-9\.]+)/i,
-			browserId: '354'
-		},
-		'444': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*WeltweitimnetzBrowser\/([0-9\.]+)/i,
-			browserId: '355'
-		},
-		'445': {
-			regexp: /^Pocomail\/([0-9\.]+)/i,
-			browserId: '356'
-		},
-		'446': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Element Browser ([0-9\.]+)/i,
-			browserId: '357'
-		},
-		'447': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*SlimBrowser/i,
-			browserId: '358'
-		},
-		'448': {
-			regexp: /^LeechCraft/i,
-			browserId: '359'
-		},
-		'449': {
-			regexp: /^LeechCraft[\s\S]*LeechCraft\/Poshuku ([0-9a-z\-\.]+)/i,
-			browserId: '359'
-		},
-		'450': {
-			regexp: /^HTTP_Request2\/([0-9\.]+)/i,
-			browserId: '360'
-		},
-		'451': {
-			regexp: /^Mozilla[\s\S]*Gecko[\s\S]*Conkeror\/([0-9\.]+)/i,
-			browserId: '361'
-		},
-		'452': {
-			regexp: /^Mozilla[\s\S]*Dolfin\/([0-9\.]+)/i,
-			browserId: '362'
-		},
-		'453': {
-			regexp: /^SAMSUNG[\s\S]*Dolfin\/([0-9\.]+)/i,
-			browserId: '362'
-		},
-		'455': {
-			regexp: /^Netvibes[\s\S]*http:\/\/www\.netvibes\.com/i,
-			browserId: '363'
-		},
-		'456': {
-			regexp: /^Chilkat\/([0-9\.]+) \(\+http:\/\/www\.chilkatsoft\.com\/ChilkatHttpUA\.asp\)/i,
-			browserId: '364'
-		},
-		'457': {
-			regexp: /^The Incutio XML-RPC PHP Library/i,
-			browserId: '365'
-		},
-		'458': {
-			regexp: /^Web-sniffer\/([0-9\.]+)[\s\S]*web-sniffer\.net\/\)$/i,
-			browserId: '366'
-		},
-		'459': {
-			regexp: /^Atomic_Email_Hunter\/([0-9\.]+)$/i,
-			browserId: '367'
-		},
-		'460': {
-			regexp: /^iGetter\/([0-9a-z\.]+)[\s\S]*/i,
-			browserId: '368'
-		},
-		'461': {
-			regexp: /^webfetch\/([0-9\.]+)/i,
-			browserId: '369'
-		},
-		'462': {
-			regexp: /^Mozilla\/4\.0 \(compatible; Synapse\)$/i,
-			browserId: '370'
-		},
-		'463': {
-			regexp: /^Mozilla\/[\s\S]*Gecko[\s\S]*lolifox\/([0-9\.]+)/i,
-			browserId: '371'
-		},
-		'464': {
-			regexp: /^Mozilla[\s\S]*SkipStone ([0-9\.]+)/i,
-			browserId: '372'
-		},
-		'465': {
-			regexp: /^Mozilla\/[\s\S]*compatible[\s\S]*Powermarks\/([0-9\.]+)/i,
-			browserId: '373'
-		},
-		'466': {
-			regexp: /^AppleSyndication\/([0-9\.]+)$/i,
-			browserId: '374'
-		},
-		'467': {
-			regexp: /^GoogleFriendConnect\/([0-9\.]+)$/i,
-			browserId: '375'
-		},
-		'468': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*RockMelt\/([0-9a-z\.]+)/i,
-			browserId: '377'
-		},
-		'469': {
-			regexp: /^Mozilla[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*Epic\/([0-9\.]+)/i,
-			browserId: '378'
-		},
-		'470': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*InternetSurfboard\/([0-9\.a-z]+)/i,
-			browserId: '379'
-		},
-		'471': {
-			regexp: /^Mozilla[\s\S]*Gecko[\s\S]*Vonkeror\/([0-9\.]+)/i,
-			browserId: '380'
-		},
-		'472': {
-			regexp: /^Windows-RSS-Platform\/([0-9\.]+)[\s\S]*MSIE[\s\S]* Windows/i,
-			browserId: '381'
-		},
-		'473': {
-			regexp: /^Trileet NewsRoom[\s\S]*feedmonger\.blogspot\.com/i,
-			browserId: '382'
-		},
-		'474': {
-			regexp: /^Validator[\s\S]nu\/([0-9\.]+)$/i,
-			browserId: '383'
-		},
-		'475': {
-			regexp: /^Zend_Http_Client$/i,
-			browserId: '384'
-		},
-		'476': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Skyfire\/([0-9\.]+)/i,
-			browserId: '385'
-		},
-		'477': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*GoBrowser\/([0-9\.]+)/i,
-			browserId: '386'
-		},
-		'478': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*GoBrowser/i,
-			browserId: '386'
-		},
-		'479': {
-			regexp: /\/GoBrowser\/([0-9\.]+)/i,
-			browserId: '386'
-		},
-		'480': {
-			regexp: /^Surf\/([0-9\.]+)[\s\S]*AppleWebKit/i,
-			browserId: '387'
-		},
-		'481': {
-			regexp: /^iGooMap\/([0-9a-z\.]+)[\s\S]*pointworks/i,
-			browserId: '388'
-		},
-		'482': {
-			regexp: /^Xenu Link Sleuth\/([0-9a-z\+\-\.]+)$/i,
-			browserId: '124'
-		},
-		'483': {
-			regexp: /^iTunes\/([0-9\.]+)/i,
-			browserId: '389'
-		},
-		'484': {
-			regexp: /^Mozilla[\s\S]*WebKi[\s\S]*BlackHawk\/([0-9\.]+)[\s\S]*Chrome/i,
-			browserId: '390'
-		},
-		'485': {
-			regexp: /^Typhoeus[\s\S]*http:\/\/github[\s\S]com\/dbalatero\/typhoeus/i,
-			browserId: '287'
-		},
-		'486': {
-			regexp: /^Mozilla[\s\S]*Linux[\s\S]*Kindle\/([0-9\.]+)/i,
-			browserId: '392'
-		},
-		'487': {
-			regexp: /^Microsoft Office Existence Discovery/i,
-			browserId: '393'
-		},
-		'488': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*version\/([0-9a-z\+\-\.]+)[\s\S]*mobile[\s\S]*safari\/[0-9a-z\+\-\.]+[\s\S]*/i,
-			browserId: '394'
-		},
-		'489': {
-			regexp: /^Outlook-Express\/7\.0 \(MSIE 6\.0[\s\S]*Windows/i,
-			browserId: '327'
-		},
-		'490': {
-			regexp: /^BrownReclusePro v([0-9\.]+)[\s\S]*SoftByteLabs[\s\S]com/i,
-			browserId: '395'
-		},
-		'491': {
-			regexp: /^ColdFusion \(BookmarkTracker\.com\)$/i,
-			browserId: '396'
-		},
-		'492': {
-			regexp: /^BinGet\/([0-9a-zA-Z\.]+)/i,
-			browserId: '397'
-		},
-		'493': {
-			regexp: /^Mozilla[\s\S]*Gecko\/[0-9]+[\s\S]*WebianShell\/([0-9a-z\.]+)/i,
-			browserId: '399'
-		},
-		'494': {
-			regexp: /^Mozilla\/[\s\S]*Gecko\/[\s\S]*Firefox\/[\s\S]*Kylo\/([0-9\.]+)$/i,
-			browserId: '400'
-		},
-		'495': {
-			regexp: /^Outlook-Express\/7\.0 \(MSIE 8[\s\S]*Windows/i,
-			browserId: '327'
-		},
-		'496': {
-			regexp: /^Mozilla\/[\s\S]*Treco[\s\S]*Fireweb Navigator\/([0-9a-z\.]+)/i,
-			browserId: '401'
-		},
-		'497': {
-			regexp: /^CamelHttpStream\/([0-9\.]+)/i,
-			browserId: '402'
-		},
-		'498': {
-			regexp: /mozilla[\s\S]*AppleWebKit\/[\s\S]*epiphany\/([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '5'
-		},
-		'499': {
-			regexp: /mozilla[\s\S]*rv:[0-9\.]+[\s\S]*Whistler[\s\S]*myibrow\/([0-9a-z\.]+)/i,
-			browserId: '320'
-		},
-		'500': {
-			regexp: /^Feed Viewer ([0-9\.]+)$/i,
-			browserId: '376'
-		},
-		'501': {
-			regexp: /^Mozilla[\s\S]*MSIE ([0-9\.]+)[\s\S]*XBLWP7/i,
-			browserId: '157'
-		},
-		'502': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows Phone[\s\S]*IEMobile\/([0-9\.]+)/i,
-			browserId: '157'
-		},
-		'503': {
-			regexp: /^EventMachine HttpClient/i,
-			browserId: '403'
-		},
-		'504': {
-			regexp: /Mozilla[\s\S]*Windows[\s\S]* Sundance\/([0-9a-z\.]+)/i,
-			browserId: '404'
-		},
-		'505': {
-			regexp: /Sundance[\s\S]*Windows[\s\S]*Version\/([0-9a-z\.]+)/i,
-			browserId: '404'
-		},
-		'506': {
-			regexp: /^Mozilla[\s\S]*Chromium\/([0-9a-z\+\-\.]+)[\s\S]*chrome[\s\S]*/i,
-			browserId: '405'
-		},
-		'507': {
-			regexp: /^Mozilla[\s\S]* AppleWebKit[\s\S]*Mobile/i,
-			browserId: '394'
-		},
-		'508': {
-			regexp: /Mozilla\/[\s\S]*AppleWebKit[\s\S]*Columbus\/([0-9\.]+)/i,
-			browserId: '406'
-		},
-		'509': {
-			regexp: /mozilla[\s\S]*iphone[\s\S]*os[\s\S]*/i,
-			browserId: '394'
-		},
-		'510': {
-			regexp: /Opera[\s\S]*Opera Mobi/i,
-			browserId: '321'
-		},
-		'511': {
-			regexp: /nokiac3[\s\S]*safari/i,
-			browserId: '394'
-		},
-		'512': {
-			regexp: /series60[\s\S]*applewebkit[\s\S]*/i,
-			browserId: '226'
-		},
-		'513': {
-			regexp: /mozilla[\s\S]*ipad[\s\S]*os[\s\S]*/i,
-			browserId: '394'
-		},
-		'514': {
-			regexp: /^Plex\/([0-9\.]+)[\s\S]*plexapp\.com/i,
-			browserId: '407'
-		},
-		'515': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]* WebRender/i,
-			browserId: '408'
-		},
-		'516': {
-			regexp: /^Mozilla[\s\S]*RIM Tablet OS[\s\S]*AppleWebKit[\s\S]*Safari/i,
-			browserId: '158'
-		},
-		'517': {
-			regexp: /Mozilla[\s\S]*Chrome[\s\S]*CoolNovo\/([a-z0-9\.]+)/i,
-			browserId: '409'
-		},
-		'518': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*Usejump\/([0-9a-z\.]+)/i,
-			browserId: '410'
-		},
-		'519': {
-			regexp: /Mozilla[\s\S]*Gecko[\s\S]*Sundial\/([0-9a-z_\.]+)/i,
-			browserId: '411'
-		},
-		'520': {
-			regexp: /Symbian[\s\S]* NokiaBrowser/i,
-			browserId: '226'
-		},
-		'521': {
-			regexp: /Mozilla[\s\S]*Gecko[\s\S]*Alienforce\/([0-9a-z\.]+)/i,
-			browserId: '412'
-		},
-		'522': {
-			regexp: /^Googlebot-richsnippets/i,
-			browserId: '413'
-		},
-		'523': {
-			regexp: /^HTML2JPG[\s\S]*http:\/\/www[\s\S]html2jpg[\s\S]com/i,
-			browserId: '414'
-		},
-		'524': {
-			regexp: /^iCatcher! ([0-9\.]+)[\s\S]*iPhone OS/i,
-			browserId: '415'
-		},
-		'525': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*baidubrowser\/([0-9a-z\.]+)/i,
-			browserId: '416'
-		},
-		'526': {
-			regexp: /Mozilla[\s\S]*MSIE[\s\S]*Windows[\s\S]*baidubrowser ([0-9a-z\.]+)/i,
-			browserId: '416'
-		},
-		'527': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*SE ([0-9a-z\.]+) MetaSr/i,
-			browserId: '417'
-		},
-		'528': {
-			regexp: /Mozilla[\s\S]*MSIE[\s\S]* Windows[\s\S]*SE ([0-9a-z\.]+) MetaSr/i,
-			browserId: '417'
-		},
-		'529': {
-			regexp: /^MPlayer ([0-9\.]+)/i,
-			browserId: '418'
-		},
-		'530': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*ZipZap ([0-9\.]+)/i,
-			browserId: '419'
-		},
-		'531': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*QupZilla\/([0-9a-z\.\-]+)/i,
-			browserId: '420'
-		},
-		'532': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*Patriott::Browser\/([0-9\.]+)/i,
-			browserId: '421'
-		},
-		'533': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*SLP Browser\/([0-9\.]+)/i,
-			browserId: '422'
-		},
-		'534': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Tizen Browser|Tizenbrowser\/([0-9\.]+)/i,
-			browserId: '422'
-		},
-		'535': {
-			regexp: /Mozilla[\s\S]*Android[\s\S]*AppleWebKit[\s\S]*CrMo\/([0-9\.]+)/i,
-			browserId: '423'
-		},
-		'536': {
-			regexp: /^Plex\/([0-9\.]+)[\s\S]*Android/i,
-			browserId: '407'
-		},
-		'537': {
-			regexp: /^WAFA\/([0-9\.]+)[\s\S]*Android/i,
-			browserId: '424'
-		},
-		'538': {
-			regexp: /^Apache[\s\S]*internal dummy connection/i,
-			browserId: '425'
-		},
-		'539': {
-			regexp: /^Mozilla[\s\S]*Android [\s\S]*Ninesky\-android\-mobile\/([0-9\.]+)/i,
-			browserId: '426'
-		},
-		'540': {
-			regexp: /^Mozilla[\s\S]*Linux\/SmartTV[\s\S]*AppleWebKit[\s\S]*WebBrowser[\s\S]*SmartTV/i,
-			browserId: '427'
-		},
-		'541': {
-			regexp: /Mozilla[\s\S]*Linux[\s\S]*webOS[\s\S]*webOSBrowser\/([0-9\.]+)/i,
-			browserId: '428'
-		},
-		'542': {
-			regexp: /Mozilla[\s\S]*Linux[\s\S]*hpwOS[\s\S]*wOSBrowser\/([0-9\.]+)/i,
-			browserId: '428'
-		},
-		'543': {
-			regexp: /Nokia SyncML HTTP Client/i,
-			browserId: '429'
-		},
-		'544': {
-			regexp: /^Mozilla.*Charon.*Inferno/,
-			browserId: '430'
-		},
-		'545': {
-			regexp: /^JS\-Kit URL Resolver[\s\S]*js-kit\.com/i,
-			browserId: '432'
-		},
-		'546': {
-			regexp: /^Outlook-Express\/7\.0 \(MSIE 9[\s\S]*Windows/i,
-			browserId: '327'
-		},
-		'547': {
-			regexp: /^PocoMail ([0-9\.]+)/i,
-			browserId: '356'
-		},
-		'548': {
-			regexp: /^Podkicker\/([0-9\.]+)/i,
-			browserId: '433'
-		},
-		'549': {
-			regexp: /^Podkicker Pro\/([0-9\.]+)/i,
-			browserId: '433'
-		},
-		'550': {
-			regexp: /^python-requests\/([0-9\.]+)/i,
-			browserId: '434'
-		},
-		'551': {
-			regexp: /^AtomicBrowser\/([0-9\.]+)[\s\S]*CFNetwork/i,
-			browserId: '436'
-		},
-		'552': {
-			regexp: /^Reeder\/([0-9\.]+)[\s\S]*CFNetwork/i,
-			browserId: '437'
-		},
-		'553': {
-			regexp: /^Mozilla[\s\S]*Mobile[\s\S]*rv[\s\S]*Gecko[\s\S]*Firefox\/([0-9\.]+)/i,
-			browserId: '133'
-		},
-		'554': {
-			regexp: /Mozilla[\s\S]*Mac[\s\S]*rv[\s\S]*Gecko[\s\S]*Firefox\/([0-9a-b\.]+)[\s\S]*TenFourFox/i,
-			browserId: '439'
-		},
-		'555': {
-			regexp: /^PEAR HTTP_Request class \( http:\/\/pear[\s\S]php[\s\S]net\/ \)/i,
-			browserId: '440'
-		},
-		'556': {
-			regexp: /Mozilla[\s\S]*compatible[\s\S]*DPlus ([0-9\.]+)/i,
-			browserId: '441'
-		},
-		'557': {
-			regexp: /^WordPress\/[0-9\.]+; http:\/\//i,
-			browserId: '438'
-		},
-		'558': {
-			regexp: /Mozilla[\s\S]*Windows[\s\S]*Gecko[\s\S]*Firefox[\s\S]*AvantBrowser\/Tri-Core/i,
-			browserId: '41'
-		},
-		'559': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*zBrowser\/SpringSun-([0-9\.]+)/i,
-			browserId: '442'
-		},
-		'560': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*zBrowser\/NigtSky-([0-9\.]+)/i,
-			browserId: '442'
-		},
-		'561': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*KHTML[\s\S]*SlimBoat\/([0-9\.]+)/i,
-			browserId: '443'
-		},
-		'562': {
-			regexp: /Opera[\s\S]*Opera Tablet[\s\S]*Presto[\s\S]*Version\/([0-9\.]+)/i,
-			browserId: '321'
-		},
-		'563': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome\/([0-9\.]+)[\s\S]*Mobile Safari/i,
-			browserId: '423'
-		},
-		'564': {
-			regexp: /^Mozilla[\s\S]*iPhone[\s\S]*AppleWebKit[\s\S]*CriOS\/([0-9\.]+)[\s\S]*Mobile[\s\S]*Safari/i,
-			browserId: '423'
-		},
-		'565': {
-			regexp: /^Mechanize\/([0-9\.]+)[\s\S]*Ruby[\s\S]*github[\s\S]com\/tenderlove\/mechanize/i,
-			browserId: '445'
-		},
-		'566': {
-			regexp: /^htmlayout ([0-9\.]+)[\s\S]*Win[\s\S]*www\.terrainformatica\.com/i,
-			browserId: '446'
-		},
-		'567': {
-			regexp: /^The Bat! Voyager ([0-9\.]+)$/i,
-			browserId: '330'
-		},
-		'568': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows[\s\S]*SaaYaa/i,
-			browserId: '447'
-		},
-		'569': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Qt\/[0-9\.]+[\s\S]*Ryouko\/([0-9\.]+)[\s\S]*Safari/i,
-			browserId: '448'
-		},
-		'570': {
-			regexp: /^Anemone\/([0-9\.]+)$/i,
-			browserId: '449'
-		},
-		'571': {
-			regexp: /^Mozilla[\s\S]*OS X[\s\S]*AppleWebKit[\s\S]*KHTML[\s\S]*Sparrow\/([0-9\.]+)/i,
-			browserId: '450'
-		},
-		'572': {
-			regexp: /^SubStream\/([0-9\.]+)[\s\S]* CFNetwork/i,
-			browserId: '451'
-		},
-		'573': {
-			regexp: /^Mozilla[\s\S]*iPad[\s\S]*AppleWebKit[\s\S]*CriOS\/([0-9\.]+)[\s\S]*Mobile[\s\S]*Safari/i,
-			browserId: '423'
-		},
-		'574': {
-			regexp: /^Barca\/([0-9\.]+)/i,
-			browserId: '452'
-		},
-		'575': {
-			regexp: /^BarcaPro\/([0-9\.]+)/i,
-			browserId: '452'
-		},
-		'576': {
-			regexp: /A1 Sitemap Generator\/([0-9\.]+)[\s\S]*microsystools[\s\S]com/i,
-			browserId: '453'
-		},
-		'577': {
-			regexp: /^Mozilla[\s\S]*Playstation Vita[\s\S]*AppleWebKit[\s\S]*Silk\/([0-9\.]+)/i,
-			browserId: '454'
-		},
-		'578': {
-			regexp: /^MQQBrowser\/([0-9\.]+)/i,
-			browserId: '455'
-		},
-		'579': {
-			regexp: /^MQQBrowser\/(Mini[0-9\.]+)/i,
-			browserId: '455'
-		},
-		'580': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*Beamrise\/([0-9\.]+)/i,
-			browserId: '456'
-		},
-		'581': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Beamrise\/([0-9\.]+)[\s\S]*Chrome/i,
-			browserId: '456'
-		},
-		'582': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*YaBrowser\/([0-9\.]+)/i,
-			browserId: '457'
-		},
-		'583': {
-			regexp: /^Mozilla[\s\S]*Silk\/([0-9\.\-]+)[\s\S]*safari/i,
-			browserId: '458'
-		},
-		'584': {
-			regexp: /^Apache-HttpClient\/([0-9\.]+)/i,
-			browserId: '459'
-		},
-		'585': {
-			regexp: /^Mozilla.*Nintendo WiiU.*AppleWebKit.*NX.*NintendoBrowser\/([0-9\.]+)/,
-			browserId: '460'
-		},
-		'586': {
-			regexp: /^DellWebMonitor\/([0-9\.]+)/,
-			browserId: '461'
-		},
-		'587': {
-			regexp: /^FeedDemon\/([0-9\.]+)[\s\S]*(www\.feeddemon\.com|www\.newsgator\.com)/i,
-			browserId: '462'
-		},
-		'588': {
-			regexp: /^XMLRPC::Client \(Ruby ([0-9\.]+)\)$/i,
-			browserId: '463'
-		},
-		'589': {
-			regexp: /^PocomailPE\/([0-9\.]+)/i,
-			browserId: '356'
-		},
-		'590': {
-			regexp: /Pattern\/([0-9\.]+)[\s\S]*[\s\S]clips\.ua\.ac\.be\/pages\/pattern/i,
-			browserId: '464'
-		},
-		'592': {
-			regexp: /^Eudora\/?([0-9a-z\.]+)*/i,
-			browserId: '465'
-		},
-		'593': {
-			regexp: /^Mozilla[\s\S]*Windows[\s\S]*Gecko[\s\S]*Polarity\/([0-9\.]+)/i,
-			browserId: '467'
-		},
-		'594': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Superbird\/([0-9\.]+)/i,
-			browserId: '468'
-		},
-		'595': {
-			regexp: /^Microsoft Office\/14[\s\S]*Microsoft Outlook 14/i,
-			browserId: '326'
-		},
-		'596': {
-			regexp: /mozilla[\s\S]*AppleWebKit[\s\S]*NetFrontLifeBrowser\/([0-9\.]+)/i,
-			browserId: '469'
-		},
-		'597': {
-			regexp: /mozilla[\s\S]*applewebkit[\s\S]*\/[0-9a-z\+\-\.]+[\s\S]*version\/([0-9a-z\+\-\.]+)[\s\S]*safari\/[0-9a-z\+\-\.]+[\s\S]*/i,
-			browserId: '22'
-		},
-		'598': {
-			regexp: /^Mozilla[\s\S]*ASUS Transformer Pad[\s\S]*AppleWebKit[\s\S]*Chrome\/([0-9\.]+)[\s\S]*Safari/i,
-			browserId: '423'
-		},
-		'599': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*OPR\/([0-9\.]+)/i,
-			browserId: '321'
-		},
-		'600': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*YRCWeblink\/([0-9\.]+)[\s\S]*Safari/i,
-			browserId: '470'
-		},
-		'601': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*OPR\/([0-9\.]+)/i,
-			browserId: '17'
-		},
-		'602': {
-			regexp: /Mozilla[\s\S]*Gecko[\s\S]*Firefox[\s\S]*IceDragon\/([0-9\.]+)/i,
-			browserId: '471'
-		},
-		'603': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*YaBrowser\/([0-9\.]+)[\s\S]*Chrome/i,
-			browserId: '457'
-		},
-		'604': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*Safari[\s\S]*Midori\/([0-9\.]+)/i,
-			browserId: '148'
-		},
-		'605': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*Dooble\/([0-9\.]+)[\s\S]*Safari/i,
-			browserId: '269'
-		},
-		'606': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*UCBrowser\/([0-9\.]+)[\s\S]*Mobile[\s\S]*Safari/i,
-			browserId: '225'
-		},
-		'607': {
-			regexp: /^Microsoft Office\/15[\s\S]*Microsoft Outlook 15/i,
-			browserId: '473'
-		},
-		'608': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Microsoft Outlook 15/i,
-			browserId: '473'
-		},
-		'609': {
-			regexp: /^Typhoeus[\s\S]*https:\/\/github[\s\S]com\/typhoeus\/typhoeus/i,
-			browserId: '287'
-		},
-		'610': {
-			regexp: /^RestSharp ([0-9\.]+)$/i,
-			browserId: '474'
-		},
-		'611': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*YaBrowser\/([0-9\.]+)[\s\S]*Mobile/i,
-			browserId: '475'
-		},
-		'612': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*Chrome[\s\S]*Safari[\s\S]*Puffin\/([0-9\.]+)/i,
-			browserId: '476'
-		},
-		'613': {
-			regexp: /Mozilla[\s\S]*Windows NT 6\.[\s\S]*Trident\/7\.0[\s\S]*rv:([0-9\.]+)/i,
-			browserId: '35'
-		},
-		'614': {
-			regexp: /Mozilla[\s\S]*AppleWebKit[\s\S]*Roccat\/([0-9\.]+)[\s\S]*R/i,
-			browserId: '477'
-		},
-		'615': {
-			regexp: /^Airmail ([0-9\.]+)[\s\S]*Mac OS X/i,
-			browserId: '478'
-		},
-		'616': {
-			regexp: /^Mozilla[\s\S]*Nintendo 3DS/i,
-			browserId: '479'
-		},
-		'617': {
-			regexp: /^Mozilla[\s\S]*Tizen 2[\s\S]*Version\/([0-9\.]+)[\s\S]*Mobile Safari/i,
-			browserId: '422'
-		},
-		'619': {
-			regexp: /mozilla[\s\S]*Linux armv7l[\s\S]*rv:[0-9\.]+[\s\S]*gecko\/[0-9]+[\s\S]*maemo browser ([0-9a-z\+\-\.]+)[\s\S]*/i,
-			browserId: '260'
-		},
-		'620': {
-			regexp: /^Mozilla[\s\S]*Polaris ([0-9\.])/i,
-			browserId: '159'
-		},
-		'621': {
-			regexp: /^Mozilla[\s\S]*BB10[\s\S]*Touch[\s\S]*AppleWebKit[\s\S]*Mobile/i,
-			browserId: '158'
-		},
-		'622': {
-			regexp: /^BrowserEmulator\/0\.9 see http:\/\/dejavu\.org/i,
-			browserId: '481'
-		},
-		'623': {
-			regexp: /^Mozilla\/5\.0[\s\S]*SymbianOS\/[0-9\.]+[\s\S]*AppleWebKit[\s\S]*KHTML[\s\S]*Safari\/[0-9\.]+/i,
-			browserId: '226'
-		},
-		'624': {
-			regexp: /^Mozilla[\s\S]*PalmOS[\s\S]*WebPro\/([0-9\.]+)[\s\S]*Palm/i,
-			browserId: '482'
-		},
-		'625': {
-			regexp: /^Mozilla[\s\S]*AppleWebKit[\s\S]*PhantomJS\/([0-9\.]+) Safari/i,
-			browserId: '483'
-		},
-		order: [
-			'599',
-			'539',
-			'596',
-			'208',
-			'583',
-			'611',
-			'2',
-			'11',
-			'49',
-			'69',
-			'94',
-			'149',
-			'197',
-			'218',
-			'359',
-			'361',
-			'414',
-			'443',
-			'535',
-			'563',
-			'564',
-			'571',
-			'573',
-			'578',
-			'579',
-			'598',
-			'612',
-			'621',
-			'199',
-			'407',
-			'408',
-			'419',
-			'541',
-			'595',
-			'608',
-			'5',
-			'593',
-			'59',
-			'117',
-			'157',
-			'175',
-			'179',
-			'180',
-			'184',
-			'203',
-			'230',
-			'232',
-			'233',
-			'234',
-			'235',
-			'266',
-			'322',
-			'396',
-			'403',
-			'406',
-			'409',
-			'439',
-			'446',
-			'489',
-			'494',
-			'495',
-			'498',
-			'533',
-			'534',
-			'546',
-			'561',
-			'577',
-			'580',
-			'581',
-			'582',
-			'594',
-			'603',
-			'614',
-			'617',
-			'170',
-			'278',
-			'410',
-			'411',
-			'444',
-			'476',
-			'506',
-			'508',
-			'515',
-			'517',
-			'520',
-			'553',
-			'554',
-			'558',
-			'559',
-			'560',
-			'600',
-			'601',
-			'602',
-			'604',
-			'605',
-			'606',
-			'7',
-			'162',
-			'22',
-			'54',
-			'60',
-			'61',
-			'114',
-			'163',
-			'182',
-			'183',
-			'314',
-			'331',
-			'340',
-			'369',
-			'431',
-			'434',
-			'436',
-			'440',
-			'441',
-			'442',
-			'452',
-			'463',
-			'468',
-			'469',
-			'470',
-			'471',
-			'484',
-			'488',
-			'496',
-			'502',
-			'507',
-			'516',
-			'519',
-			'521',
-			'525',
-			'526',
-			'527',
-			'528',
-			'530',
-			'531',
-			'532',
-			'569',
-			'499',
-			'246',
-			'400',
-			'401',
-			'402',
-			'509',
-			'513',
-			'562',
-			'438',
-			'510',
-			'511',
-			'150',
-			'261',
-			'271',
-			'342',
-			'422',
-			'486',
-			'512',
-			'619',
-			'1',
-			'3',
-			'4',
-			'6',
-			'8',
-			'9',
-			'10',
-			'14',
-			'15',
-			'16',
-			'19',
-			'20',
-			'303',
-			'24',
-			'25',
-			'26',
-			'28',
-			'29',
-			'30',
-			'31',
-			'32',
-			'33',
-			'35',
-			'36',
-			'37',
-			'223',
-			'42',
-			'304',
-			'44',
-			'45',
-			'46',
-			'48',
-			'50',
-			'51',
-			'53',
-			'55',
-			'56',
-			'57',
-			'58',
-			'63',
-			'64',
-			'65',
-			'66',
-			'67',
-			'70',
-			'77',
-			'78',
-			'80',
-			'302',
-			'86',
-			'89',
-			'97',
-			'98',
-			'100',
-			'102',
-			'104',
-			'106',
-			'107',
-			'108',
-			'109',
-			'110',
-			'111',
-			'113',
-			'115',
-			'327',
-			'118',
-			'120',
-			'122',
-			'123',
-			'371',
-			'126',
-			'130',
-			'300',
-			'169',
-			'301',
-			'137',
-			'141',
-			'147',
-			'151',
-			'152',
-			'153',
-			'156',
-			'155',
-			'160',
-			'161',
-			'164',
-			'167',
-			'171',
-			'172',
-			'173',
-			'174',
-			'176',
-			'177',
-			'178',
-			'181',
-			'185',
-			'186',
-			'187',
-			'188',
-			'189',
-			'192',
-			'194',
-			'195',
-			'196',
-			'198',
-			'204',
-			'205',
-			'206',
-			'207',
-			'209',
-			'210',
-			'211',
-			'212',
-			'213',
-			'214',
-			'215',
-			'216',
-			'217',
-			'219',
-			'220',
-			'221',
-			'222',
-			'224',
-			'225',
-			'226',
-			'227',
-			'228',
-			'229',
-			'231',
-			'236',
-			'238',
-			'241',
-			'244',
-			'247',
-			'248',
-			'249',
-			'250',
-			'251',
-			'253',
-			'258',
-			'260',
-			'262',
-			'264',
-			'265',
-			'267',
-			'272',
-			'273',
-			'274',
-			'275',
-			'276',
-			'277',
-			'279',
-			'295',
-			'293',
-			'294',
-			'287',
-			'289',
-			'296',
-			'292',
-			'297',
-			'298',
-			'305',
-			'306',
-			'307',
-			'308',
-			'311',
-			'313',
-			'316',
-			'317',
-			'318',
-			'320',
-			'321',
-			'323',
-			'324',
-			'325',
-			'328',
-			'329',
-			'330',
-			'333',
-			'334',
-			'335',
-			'336',
-			'337',
-			'338',
-			'339',
-			'341',
-			'345',
-			'346',
-			'348',
-			'349',
-			'352',
-			'353',
-			'354',
-			'355',
-			'360',
-			'362',
-			'364',
-			'365',
-			'366',
-			'367',
-			'370',
-			'372',
-			'373',
-			'374',
-			'375',
-			'376',
-			'377',
-			'378',
-			'379',
-			'381',
-			'383',
-			'384',
-			'385',
-			'386',
-			'387',
-			'388',
-			'389',
-			'390',
-			'391',
-			'393',
-			'394',
-			'395',
-			'399',
-			'405',
-			'412',
-			'413',
-			'415',
-			'416',
-			'418',
-			'420',
-			'423',
-			'424',
-			'425',
-			'426',
-			'427',
-			'428',
-			'433',
-			'435',
-			'437',
-			'445',
-			'447',
-			'449',
-			'450',
-			'451',
-			'458',
-			'459',
-			'461',
-			'466',
-			'472',
-			'473',
-			'474',
-			'475',
-			'477',
-			'478',
-			'482',
-			'487',
-			'490',
-			'493',
-			'497',
-			'500',
-			'503',
-			'504',
-			'505',
-			'514',
-			'518',
-			'524',
-			'537',
-			'540',
-			'542',
-			'543',
-			'544',
-			'545',
-			'547',
-			'548',
-			'549',
-			'550',
-			'551',
-			'552',
-			'555',
-			'556',
-			'557',
-			'565',
-			'566',
-			'567',
-			'568',
-			'570',
-			'572',
-			'576',
-			'584',
-			'585',
-			'587',
-			'588',
-			'589',
-			'590',
-			'592',
-			'607',
-			'610',
-			'613',
-			'615',
-			'616',
-			'620',
-			'622',
-			'623',
-			'624',
-			'625',
-			'17',
-			'404',
-			'47',
-			'52',
-			'79',
-			'82',
-			'166',
-			'193',
-			'239',
-			'18',
-			'34',
-			'103',
-			'105',
-			'138',
-			'139',
-			'143',
-			'190',
-			'191',
-			'201',
-			'237',
-			'242',
-			'243',
-			'245',
-			'268',
-			'269',
-			'270',
-			'280',
-			'299',
-			'309',
-			'310',
-			'312',
-			'357',
-			'358',
-			'397',
-			'455',
-			'457',
-			'479',
-			'481',
-			'491',
-			'492',
-			'501',
-			'529',
-			'536',
-			'480',
-			'62',
-			'202',
-			'240',
-			'254',
-			'255',
-			'256',
-			'257',
-			'319',
-			'350',
-			'392',
-			'462',
-			'464',
-			'465',
-			'483',
-			'522',
-			'597',
-			'23',
-			'95',
-			'165',
-			'200',
-			'259',
-			'281',
-			'315',
-			'332',
-			'343',
-			'344',
-			'363',
-			'368',
-			'380',
-			'382',
-			'398',
-			'417',
-			'421',
-			'429',
-			'430',
-			'448',
-			'453',
-			'456',
-			'460',
-			'467',
-			'485',
-			'523',
-			'538',
-			'574',
-			'575',
-			'586',
-			'609',
-			'351',
-			'83',
-			'263',
-			'432',
-			'326',
-			'39',
-			'81',
-			'356'
-		]
-	},
-	browserOs: {
-		'18': '44',
-		'23': '19',
-		'39': '43',
-		'43': '35',
-		'59': '43',
-		'62': '43',
-		'71': '43',
-		'82': '43',
-		'88': '43',
-		'93': '43',
-		'100': '47',
-		'124': '43',
-		'125': '44',
-		'146': '44',
-		'151': '10',
-		'152': '47',
-		'159': '10',
-		'170': '44',
-		'179': '43',
-		'194': '43',
-		'200': '43',
-		'201': '43',
-		'209': '43',
-		'217': '43',
-		'220': '10',
-		'221': '19',
-		'235': '19',
-		'239': '43',
-		'240': '19',
-		'248': '43',
-		'251': '43',
-		'256': '43',
-		'260': '75',
-		'261': '75',
-		'271': '43',
-		'272': '43',
-		'281': '47',
-		'282': '43',
-		'283': '43',
-		'286': '62',
-		'293': '43',
-		'304': '43',
-		'305': '43',
-		'310': '33',
-		'311': '43',
-		'312': '43',
-		'313': '44',
-		'316': '43',
-		'330': '43',
-		'334': '43',
-		'344': '43',
-		'349': '19',
-		'356': '43',
-		'367': '43',
-		'369': '43',
-		'373': '43',
-		'376': '43',
-		'385': '114',
-		'388': '86',
-		'393': '43',
-		'395': '43',
-		'414': '43',
-		'429': '34',
-		'436': '65',
-		'437': '65',
-		'452': '43',
-		'453': '43',
-		order: [
-			'18',
-			'23',
-			'39',
-			'43',
-			'59',
-			'62',
-			'71',
-			'82',
-			'88',
-			'93',
-			'100',
-			'124',
-			'125',
-			'146',
-			'151',
-			'152',
-			'159',
-			'170',
-			'179',
-			'194',
-			'200',
-			'201',
-			'209',
-			'217',
-			'220',
-			'221',
-			'235',
-			'239',
-			'240',
-			'248',
-			'251',
-			'256',
-			'260',
-			'261',
-			'271',
-			'272',
-			'281',
-			'282',
-			'283',
-			'286',
-			'293',
-			'304',
-			'305',
-			'310',
-			'311',
-			'312',
-			'313',
-			'316',
-			'330',
-			'334',
-			'344',
-			'349',
-			'356',
-			'367',
-			'369',
-			'373',
-			'376',
-			'385',
-			'388',
-			'393',
-			'395',
-			'414',
-			'429',
-			'436',
-			'437',
-			'452',
-			'453'
-		]
-	},
-	osReg: {
-		'1': {
-			regexp: /windows nt 5\.1/i,
-			osId: '1'
-		},
-		'3': {
-			regexp: /windows nt 5\.0/i,
-			osId: '2'
-		},
-		'4': {
-			regexp: /[\s\S]*windows nt 5\.2( |;)[\s\S]*/i,
-			osId: '3'
-		},
-		'5': {
-			regexp: /[\s\S]*windows 95[\s\S]*/i,
-			osId: '4'
-		},
-		'6': {
-			regexp: /[\s\S]*win95[\s\S]*/i,
-			osId: '4'
-		},
-		'7': {
-			regexp: /windows 98/i,
-			osId: '5'
-		},
-		'8': {
-			regexp: /[\s\S]*win16( |;)[\s\S]*/i,
-			osId: '6'
-		},
-		'9': {
-			regexp: /[\s\S]*win98( |;)[\s\S]*/i,
-			osId: '5'
-		},
-		'10': {
-			regexp: /[\s\S]*windows 4\.10( |;)[\s\S]*/i,
-			osId: '5'
-		},
-		'11': {
-			regexp: /windows ce|PocketPC/i,
-			osId: '7'
-		},
-		'12': {
-			regexp: /[\s\S]*windows me( |;)[\s\S]*/i,
-			osId: '8'
-		},
-		'13': {
-			regexp: /[\s\S]*windows nt 6\.0( |;)[\s\S]*/i,
-			osId: '9'
-		},
-		'14': {
-			regexp: /j2me/i,
-			osId: '10'
-		},
-		'15': {
-			regexp: /centos/i,
-			osId: '11'
-		},
-		'16': {
-			regexp: /ubuntu/i,
-			osId: '12'
-		},
-		'17': {
-			regexp: /linux[\s\S]*debian/i,
-			osId: '13'
-		},
-		'18': {
-			regexp: /linux[\s\S]*fedora/i,
-			osId: '14'
-		},
-		'19': {
-			regexp: /linux[\s\S]*gentoo/i,
-			osId: '15'
-		},
-		'20': {
-			regexp: /linux[\s\S]*linspire/i,
-			osId: '16'
-		},
-		'21': {
-			regexp: /linux[\s\S]*mandriva/i,
-			osId: '17'
-		},
-		'22': {
-			regexp: /linux[\s\S]*mdk/i,
-			osId: '17'
-		},
-		'23': {
-			regexp: /linux[\s\S]*redhat/i,
-			osId: '18'
-		},
-		'24': {
-			regexp: /linux/i,
-			osId: '19'
-		},
-		'25': {
-			regexp: /linux[\s\S]*slackware/i,
-			osId: '20'
-		},
-		'26': {
-			regexp: /linux[\s\S]*kanotix/i,
-			osId: '21'
-		},
-		'27': {
-			regexp: /linux[\s\S]*suse/i,
-			osId: '22'
-		},
-		'28': {
-			regexp: /linux[\s\S]*knoppix/i,
-			osId: '23'
-		},
-		'29': {
-			regexp: /[\s\S]*netbsd[\s\S]*/i,
-			osId: '24'
-		},
-		'30': {
-			regexp: /[\s\S]*freebsd[\s\S]*/i,
-			osId: '25'
-		},
-		'31': {
-			regexp: /[\s\S]*openbsd[\s\S]*/i,
-			osId: '26'
-		},
-		'34': {
-			regexp: /sunos/i,
-			osId: '29'
-		},
-		'35': {
-			regexp: /amiga/i,
-			osId: '30'
-		},
-		'36': {
-			regexp: /irix/i,
-			osId: '31'
-		},
-		'37': {
-			regexp: /open[\s\S]*vms/i,
-			osId: '32'
-		},
-		'38': {
-			regexp: /beos/i,
-			osId: '33'
-		},
-		'39': {
-			regexp: /symbian/i,
-			osId: '34'
-		},
-		'40': {
-			regexp: /palm/i,
-			osId: '35'
-		},
-		'42': {
-			regexp: /webtv/i,
-			osId: '37'
-		},
-		'43': {
-			regexp: /os\/2[\s\S]*warp/i,
-			osId: '39'
-		},
-		'44': {
-			regexp: /os\/2/i,
-			osId: '87'
-		},
-		'45': {
-			regexp: /RISC[\s\S]OS/i,
-			osId: '40'
-		},
-		'46': {
-			regexp: /hp-ux/i,
-			osId: '41'
-		},
-		'47': {
-			regexp: /Nintendo[\s\S]Wii/i,
-			osId: '42'
-		},
-		'48': {
-			regexp: /windows/i,
-			osId: '43'
-		},
-		'49': {
-			regexp: /mac_powerpc/i,
-			osId: '44'
-		},
-		'50': {
-			regexp: /Macintosh/i,
-			osId: '44'
-		},
-		'51': {
-			regexp: /aix/i,
-			osId: '45'
-		},
-		'52': {
-			regexp: /Win32/i,
-			osId: '43'
-		},
-		'53': {
-			regexp: /winnt/i,
-			osId: '46'
-		},
-		'54': {
-			regexp: /java\/[0-9a-z\.]+/i,
-			osId: '47'
-		},
-		'55': {
-			regexp: /[\s\S]*windows XP[\s\S]*/i,
-			osId: '1'
-		},
-		'56': {
-			regexp: /Series80\/2\.0/i,
-			osId: '34'
-		},
-		'57': {
-			regexp: /SonyEricssonP900/i,
-			osId: '34'
-		},
-		'58': {
-			regexp: /plan 9/i,
-			osId: '49'
-		},
-		'59': {
-			regexp: /NetFront[\s\S]*Profile\/MIDP/i,
-			osId: '10'
-		},
-		'60': {
-			regexp: /BlackBerry/i,
-			osId: '50'
-		},
-		'61': {
-			regexp: /Series90[\s\S]*Nokia7710/i,
-			osId: '34'
-		},
-		'63': {
-			regexp: /linux[\s\S]*\(Dropline GNOME\)[\s\S]*/i,
-			osId: '20'
-		},
-		'64': {
-			regexp: /Win 9x 4\.90/i,
-			osId: '8'
-		},
-		'65': {
-			regexp: /WinNT4\.0/i,
-			osId: '46'
-		},
-		'66': {
-			regexp: /linux[\s\S]*red hat/i,
-			osId: '18'
-		},
-		'67': {
-			regexp: /Solaris/i,
-			osId: '29'
-		},
-		'68': {
-			regexp: /QNX x86pc/i,
-			osId: '52'
-		},
-		'69': {
-			regexp: /Red Hat modified/i,
-			osId: '18'
-		},
-		'70': {
-			regexp: /Windows\-NT/i,
-			osId: '46'
-		},
-		'71': {
-			regexp: /MorphOS/i,
-			osId: '53'
-		},
-		'73': {
-			regexp: /CYGWIN_NT\-5[\s\S]0/i,
-			osId: '2'
-		},
-		'74': {
-			regexp: /powerpc\-apple/i,
-			osId: '44'
-		},
-		'75': {
-			regexp: /^DoCoMo[\s\S]*F900i/i,
-			osId: '34'
-		},
-		'76': {
-			regexp: /Vector Linux/i,
-			osId: '55'
-		},
-		'77': {
-			regexp: /riscos/i,
-			osId: '40'
-		},
-		'78': {
-			regexp: /Linux Mint/i,
-			osId: '56'
-		},
-		'79': {
-			regexp: /SCO_SV/i,
-			osId: '57'
-		},
-		'80': {
-			regexp: /suse\-linux/i,
-			osId: '22'
-		},
-		'81': {
-			regexp: /Arch Linux ([0-9a-zA-Z\.\-]+)/i,
-			osId: '58'
-		},
-		'82': {
-			regexp: /Gentoo i686/i,
-			osId: '15'
-		},
-		'83': {
-			regexp: /SkyOS/i,
-			osId: '59'
-		},
-		'84': {
-			regexp: /[\s\S]*windows 3\.1[\s\S]*/i,
-			osId: '6'
-		},
-		'85': {
-			regexp: /[\s\S]*dragonfly[\s\S]*/i,
-			osId: '61'
-		},
-		'86': {
-			regexp: /Android ([0-9\.]+)/i,
-			osId: '62'
-		},
-		'87': {
-			regexp: /windows nt 6\.1/i,
-			osId: '64'
-		},
-		'88': {
-			regexp: /[\s\S]*windows 2000( |;)[\s\S]*/i,
-			osId: '2'
-		},
-		'90': {
-			regexp: /iPhone OS 2_0/i,
-			osId: '65'
-		},
-		'92': {
-			regexp: /iPhone OS ([0-9_]+) like Mac OS X/i,
-			osId: '65'
-		},
-		'93': {
-			regexp: /NT4\.0/i,
-			osId: '46'
-		},
-		'94': {
-			regexp: /java[0-9a-z\.]+/i,
-			osId: '47'
-		},
-		'95': {
-			regexp: /webOS\/[\s\S]*AppleWebKit/i,
-			osId: '69'
-		},
-		'96': {
-			regexp: /BeOS[\s\S]*Haiku BePC/i,
-			osId: '70'
-		},
-		'98': {
-			regexp: /Windows NT 6\.0/i,
-			osId: '9'
-		},
-		'99': {
-			regexp: /macos/i,
-			osId: '44'
-		},
-		'100': {
-			regexp: /Series 60/i,
-			osId: '34'
-		},
-		'101': {
-			regexp: /os=Mac/i,
-			osId: '44'
-		},
-		'102': {
-			regexp: /Series60/i,
-			osId: '34'
-		},
-		'103': {
-			regexp: /Danger hiptop [0-9\.]+/i,
-			osId: '72'
-		},
-		'105': {
-			regexp: /Konqueror[\s\S]*SUSE/i,
-			osId: '22'
-		},
-		'106': {
-			regexp: /Konqueror[\s\S]*Fedora/i,
-			osId: '14'
-		},
-		'107': {
-			regexp: /Obigo[\s\S]*MIDP/i,
-			osId: '10'
-		},
-		'108': {
-			regexp: /Teleca[\s\S]*MIDP/i,
-			osId: '10'
-		},
-		'109': {
-			regexp: /Syllable/i,
-			osId: '74'
-		},
-		'110': {
-			regexp: /Windows_XP\/5[\s\S]1/i,
-			osId: '1'
-		},
-		'111': {
-			regexp: /SO=MAC10,6/i,
-			osId: '44'
-		},
-		'112': {
-			regexp: /so=Mac 10[\s\S]5[\s\S]8/i,
-			osId: '44'
-		},
-		'114': {
-			regexp: /[\s\S]*windows 7[\s\S]*/i,
-			osId: '64'
-		},
-		'115': {
-			regexp: /iPhone OS [0-9\.]+/i,
-			osId: '65'
-		},
-		'116': {
-			regexp: /Mac OS X (10_6|10\.6)/i,
-			osId: '85'
-		},
-		'117': {
-			regexp: /Mac OS X (10_5|10\.5)/i,
-			osId: '84'
-		},
-		'118': {
-			regexp: /Mac OS X (10_4|10\.4)/i,
-			osId: '83'
-		},
-		'119': {
-			regexp: /Mac OS X/i,
-			osId: '86'
-		},
-		'120': {
-			regexp: /Mozilla[\s\S]*Linux[\s\S]*Maemo/i,
-			osId: '75'
-		},
-		'121': {
-			regexp: /Windows NT 4/i,
-			osId: '46'
-		},
-		'122': {
-			regexp: /Windows ME/i,
-			osId: '8'
-		},
-		'123': {
-			regexp: /Windows 2000/i,
-			osId: '2'
-		},
-		'124': {
-			regexp: /S60; SymbOS/i,
-			osId: '34'
-		},
-		'125': {
-			regexp: /Windows Mobile/i,
-			osId: '88'
-		},
-		'126': {
-			regexp: /Darwin 10\.3/i,
-			osId: '90'
-		},
-		'127': {
-			regexp: /Minix 3/i,
-			osId: '91'
-		},
-		'128': {
-			regexp: /iPhone/i,
-			osId: '65'
-		},
-		'129': {
-			regexp: /Darwin/i,
-			osId: '44'
-		},
-		'130': {
-			regexp: /PCLinuxOS\/([0-9a-z\.\-]+)/i,
-			osId: '92'
-		},
-		'131': {
-			regexp: /^Mozilla\/[\s\S]*Linux[\s\S]*Jolicloud/i,
-			osId: '93'
-		},
-		'132': {
-			regexp: /PLAYSTATION 3/i,
-			osId: '94'
-		},
-		'133': {
-			regexp: /PlayStation Portable/i,
-			osId: '94'
-		},
-		'134': {
-			regexp: /SymbianOS/i,
-			osId: '34'
-		},
-		'135': {
-			regexp: /AROS/i,
-			osId: '95'
-		},
-		'136': {
-			regexp: /iPhone[\s\S]*like Mac OS X/i,
-			osId: '65'
-		},
-		'137': {
-			regexp: /iPad[\s\S]*OS[\s\S]*like Mac OS X/i,
-			osId: '65'
-		},
-		'138': {
-			regexp: /^HTC_HD2[\s\S]*Opera[\s\S]*windows/i,
-			osId: '96'
-		},
-		'139': {
-			regexp: /^Mozilla[\s\S]*CrOS[\s\S]*Chrome/i,
-			osId: '97'
-		},
-		'140': {
-			regexp: /Android[\s\S]*Linux[\s\S]*Opera Mobi/i,
-			osId: '62'
-		},
-		'141': {
-			regexp: /Nintendo DS/i,
-			osId: '98'
-		},
-		'142': {
-			regexp: /^Opera[\s\S]*Android/i,
-			osId: '62'
-		},
-		'143': {
-			regexp: /NokiaN97/i,
-			osId: '34'
-		},
-		'144': {
-			regexp: /Nokia[\s\S]*XpressMusic/i,
-			osId: '34'
-		},
-		'145': {
-			regexp: /NokiaE66/i,
-			osId: '34'
-		},
-		'146': {
-			regexp: /Nokia6700/i,
-			osId: '34'
-		},
-		'147': {
-			regexp: /\(GNU;/i,
-			osId: '99'
-		},
-		'148': {
-			regexp: /Unix/i,
-			osId: '19'
-		},
-		'149': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows[\s\S]* XBLWP7/i,
-			osId: '96'
-		},
-		'150': {
-			regexp: /Windows Phone OS 7/,
-			osId: '96'
-		},
-		'151': {
-			regexp: /windows nt 6\.2/i,
-			osId: '100'
-		},
-		'152': {
-			regexp: /RIM Tablet OS 1[0-9\.]+/i,
-			osId: '101'
-		},
-		'153': {
-			regexp: /Android/i,
-			osId: '62'
-		},
-		'154': {
-			regexp: /Bada\/[0-9\.]+/i,
-			osId: '102'
-		},
-		'155': {
-			regexp: /Android 1[\s\S]0/i,
-			osId: '110'
-		},
-		'156': {
-			regexp: /Android 1[\s\S]5/i,
-			osId: '103'
-		},
-		'157': {
-			regexp: /Android 1[\s\S]6/i,
-			osId: '104'
-		},
-		'158': {
-			regexp: /Android 2[\s\S]0|Android 2[\s\S]1/i,
-			osId: '105'
-		},
-		'159': {
-			regexp: /Android 2[\s\S]2/i,
-			osId: '106'
-		},
-		'160': {
-			regexp: /Android 2[\s\S]3|Android 2[\s\S]4/i,
-			osId: '107'
-		},
-		'161': {
-			regexp: /Android 3[\s\S]/i,
-			osId: '108'
-		},
-		'162': {
-			regexp: /Android Donut/i,
-			osId: '104'
-		},
-		'163': {
-			regexp: /Android Eclair/i,
-			osId: '105'
-		},
-		'164': {
-			regexp: /Android 4[\s\S]/i,
-			osId: '111'
-		},
-		'165': {
-			regexp: /Mac OS X (10_7|10\.7)/i,
-			osId: '112'
-		},
-		'166': {
-			regexp: /^Mozilla[\s\S]*Tizen\/1/i,
-			osId: '113'
-		},
-		'167': {
-			regexp: /Android-4[\s\S]/i,
-			osId: '111'
-		},
-		'168': {
-			regexp: /Android\/3/i,
-			osId: '108'
-		},
-		'169': {
-			regexp: /Linux.*hpwOS/,
-			osId: '69'
-		},
-		'170': {
-			regexp: /^Mozilla.*Charon.*Inferno/,
-			osId: '115'
-		},
-		'171': {
-			regexp: /Mac OS X (10_8|10\.8)/i,
-			osId: '116'
-		},
-		'172': {
-			regexp: /[\s\S]*Windows\-Vista/i,
-			osId: '9'
-		},
-		'173': {
-			regexp: /iPhone OS 5_[0-9_]+/i,
-			osId: '118'
-		},
-		'174': {
-			regexp: /iPhone OS 4_[0-9_]+/i,
-			osId: '117'
-		},
-		'175': {
-			regexp: /iPad[\s\S]*OS 5_[0-9_]+/i,
-			osId: '118'
-		},
-		'176': {
-			regexp: /RIM Tablet OS 2[0-9\.]+/i,
-			osId: '119'
-		},
-		'177': {
-			regexp: /Android 4\.1/i,
-			osId: '120'
-		},
-		'178': {
-			regexp: /iPad[\s\S]*OS 6_[0-9_]+/i,
-			osId: '121'
-		},
-		'179': {
-			regexp: /iPhone OS 6_[0-9_]+/i,
-			osId: '121'
-		},
-		'180': {
-			regexp: /PlayStation Vita/i,
-			osId: '122'
-		},
-		'181': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows NT 6[\s\S]1[\s\S]* Xbox/i,
-			osId: '123'
-		},
-		'182': {
-			regexp: /^XBMC[\s\S]*Xbox[\s\S]*www\.xbmc\.org/i,
-			osId: '123'
-		},
-		'183': {
-			regexp: /Android 4\.2/i,
-			osId: '124'
-		},
-		'184': {
-			regexp: /^Mozilla\/5\.0 \(Mobile; rv:[0-9\.]+[\s\S]*\) Gecko\/[0-9\.]+ Firefox\/[0-9\.]+$/i,
-			osId: '125'
-		},
-		'186': {
-			regexp: /windows nt 6\.2[\s\S]*ARM/i,
-			osId: '126'
-		},
-		'187': {
-			regexp: /^Mozilla[\s\S]*Windows Phone 8[\s\S]0/i,
-			osId: '127'
-		},
-		'188': {
-			regexp: /Linux[\s\S]*Mageia/i,
-			osId: '128'
-		},
-		'189': {
-			regexp: /iPhone OS 7_[0-9_]+/i,
-			osId: '129'
-		},
-		'190': {
-			regexp: /Windows NT 6\.3/i,
-			osId: '130'
-		},
-		'191': {
-			regexp: /Android 4\.3/i,
-			osId: '131'
-		},
-		'192': {
-			regexp: /Mac OS X (10_9|10\.9)/i,
-			osId: '132'
-		},
-		'193': {
-			regexp: /iPad[\s\S]*OS 7_[0-9_]+/i,
-			osId: '129'
-		},
-		'194': {
-			regexp: /Samsung[\s\S]*SmartTV/i,
-			osId: '19'
-		},
-		'195': {
-			regexp: /AppleTV/i,
-			osId: '86'
-		},
-		'196': {
-			regexp: /VectorLinux/i,
-			osId: '55'
-		},
-		'197': {
-			regexp: /^Mozilla[\s\S]*Nintendo 3DS/i,
-			osId: '133'
-		},
-		'198': {
-			regexp: /^Mozilla[\s\S]*Tizen 2/i,
-			osId: '134'
-		},
-		'199': {
-			regexp: /^Mozilla[\s\S]*BB10[\s\S]*Touch[\s\S]*AppleWebKit[\s\S]*Mobile/i,
-			osId: '50'
-		},
-		order: [
-			'40',
-			'64',
-			'71',
-			'173',
-			'174',
-			'175',
-			'178',
-			'179',
-			'186',
-			'189',
-			'193',
-			'92',
-			'67',
-			'90',
-			'102',
-			'136',
-			'138',
-			'181',
-			'177',
-			'183',
-			'191',
-			'60',
-			'96',
-			'149',
-			'155',
-			'156',
-			'157',
-			'158',
-			'159',
-			'160',
-			'161',
-			'162',
-			'163',
-			'164',
-			'166',
-			'167',
-			'168',
-			'198',
-			'125',
-			'1',
-			'5',
-			'3',
-			'4',
-			'56',
-			'6',
-			'7',
-			'8',
-			'9',
-			'10',
-			'11',
-			'12',
-			'13',
-			'14',
-			'15',
-			'16',
-			'17',
-			'18',
-			'19',
-			'20',
-			'21',
-			'22',
-			'23',
-			'25',
-			'26',
-			'27',
-			'28',
-			'29',
-			'30',
-			'31',
-			'116',
-			'34',
-			'35',
-			'36',
-			'37',
-			'38',
-			'42',
-			'43',
-			'45',
-			'46',
-			'47',
-			'53',
-			'57',
-			'58',
-			'59',
-			'61',
-			'63',
-			'65',
-			'66',
-			'68',
-			'69',
-			'70',
-			'137',
-			'73',
-			'75',
-			'76',
-			'77',
-			'78',
-			'79',
-			'80',
-			'81',
-			'83',
-			'84',
-			'86',
-			'87',
-			'88',
-			'117',
-			'95',
-			'98',
-			'118',
-			'103',
-			'110',
-			'134',
-			'114',
-			'115',
-			'120',
-			'124',
-			'130',
-			'131',
-			'132',
-			'139',
-			'140',
-			'150',
-			'151',
-			'152',
-			'153',
-			'154',
-			'165',
-			'169',
-			'170',
-			'171',
-			'172',
-			'176',
-			'180',
-			'182',
-			'184',
-			'188',
-			'190',
-			'192',
-			'194',
-			'195',
-			'196',
-			'197',
-			'199',
-			'119',
-			'24',
-			'82',
-			'105',
-			'106',
-			'107',
-			'108',
-			'123',
-			'121',
-			'39',
-			'44',
-			'55',
-			'85',
-			'122',
-			'187',
-			'93',
-			'133',
-			'48',
-			'49',
-			'50',
-			'51',
-			'52',
-			'54',
-			'109',
-			'74',
-			'135',
-			'94',
-			'100',
-			'101',
-			'111',
-			'112',
-			'127',
-			'141',
-			'142',
-			'143',
-			'144',
-			'145',
-			'146',
-			'147',
-			'99',
-			'126',
-			'128',
-			'148',
-			'129'
-		]
-	},
-	device: {
-		'1': {
-			deviceType: 'Other',
-			deviceIcon: 'other.png',
-			deviceInfoUrl: '/list-of-ua/device-detail?device=Other'
-		},
-		'2': {
-			deviceType: 'Personal computer',
-			deviceIcon: 'desktop.png',
-			deviceInfoUrl: '/list-of-ua/device-detail?device=Personal computer'
-		},
-		'3': {
-			deviceType: 'Smartphone',
-			deviceIcon: 'phone.png',
-			deviceInfoUrl: '/list-of-ua/device-detail?device=Smartphone'
-		},
-		'4': {
-			deviceType: 'Tablet',
-			deviceIcon: 'tablet.png',
-			deviceInfoUrl: '/list-of-ua/device-detail?device=Tablet'
-		},
-		'5': {
-			deviceType: 'Game console',
-			deviceIcon: 'console.png',
-			deviceInfoUrl: '/list-of-ua/device-detail?device=Game console'
-		},
-		'6': {
-			deviceType: 'Smart TV',
-			deviceIcon: 'smarttv.png',
-			deviceInfoUrl: '/list-of-ua/device-detail?device=Smart TV'
-		},
-		'7': {
-			deviceType: 'PDA',
-			deviceIcon: 'pda.png',
-			deviceInfoUrl: '/list-of-ua/device-detail?device=PDA'
-		},
-		order: [
-			'1',
-			'2',
-			'3',
-			'4',
-			'5',
-			'6',
-			'7'
-		]
-	},
-	deviceReg: {
-		'1': {
-			regexp: /iPad[\s\S]*OS[\s\S]*like Mac OS X/i,
-			deviceId: '4'
-		},
-		'2': {
-			regexp: /Nintendo/i,
-			deviceId: '5'
-		},
-		'3': {
-			regexp: /Playstation/i,
-			deviceId: '5'
-		},
-		'5': {
-			regexp: /PlayBook|RIM Tablet/i,
-			deviceId: '4'
-		},
-		'6': {
-			regexp: /Bada\/[0-9\.]+/i,
-			deviceId: '3'
-		},
-		'9': {
-			regexp: /^HbbTV/i,
-			deviceId: '6'
-		},
-		'10': {
-			regexp: /^Mozilla[\s\S]*Escape [0-9\.]+/i,
-			deviceId: '6'
-		},
-		'11': {
-			regexp: /^Mozilla[\s\S]*Linux[\s\S]*Kindle\/[0-9\.]+/i,
-			deviceId: '4'
-		},
-		'12': {
-			regexp: /Kindle Fire/i,
-			deviceId: '4'
-		},
-		'13': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*Transformer/i,
-			deviceId: '4'
-		},
-		'14': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows[\s\S]*ARM[\s\S]*Touch/i,
-			deviceId: '4'
-		},
-		'15': {
-			regexp: /^Mozilla[\s\S]*SmartHub[\s\S]*Linux/i,
-			deviceId: '6'
-		},
-		'16': {
-			regexp: /^Mozilla[\s\S]*SMART\-TV|SMARTTV[\s\S]*Linux/i,
-			deviceId: '6'
-		},
-		'17': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SMARTTVBOX/i,
-			deviceId: '6'
-		},
-		'18': {
-			regexp: /^Opera[\s\S]*Linux[\s\S]*HbbTV/i,
-			deviceId: '6'
-		},
-		'19': {
-			regexp: /^Mozilla[\s\S]*Chrome[\s\S]*GoogleTV/i,
-			deviceId: '6'
-		},
-		'20': {
-			regexp: /AppleTV/i,
-			deviceId: '6'
-		},
-		'21': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SGP311/i,
-			deviceId: '4'
-		},
-		'22': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SGPT12/i,
-			deviceId: '4'
-		},
-		'23': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*Sony Tablet P/i,
-			deviceId: '4'
-		},
-		'24': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SonySGP311/i,
-			deviceId: '4'
-		},
-		'25': {
-			regexp: /^Mozilla[\s\S]*Gecko[\s\S]*Firefox[\s\S]*Kylo\/([0-9\.]+)$/i,
-			deviceId: '6'
-		},
-		'26': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFTT[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'27': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFOT[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'28': {
-			regexp: /^Mozilla[\s\S]*Android|Linux[\s\S]*KFJWI[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'29': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFJWA[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'30': {
-			regexp: /j2me/i,
-			deviceId: '3'
-		},
-		'31': {
-			regexp: /Obigo[\s\S]*MIDP/i,
-			deviceId: '3'
-		},
-		'32': {
-			regexp: /Teleca[\s\S]*MIDP/i,
-			deviceId: '3'
-		},
-		'33': {
-			regexp: /^Mozilla[\s\S]*MSIE[\s\S]*Windows[\s\S]* Tablet PC [0-9\.]+/i,
-			deviceId: '4'
-		},
-		'34': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SurfTab/i,
-			deviceId: '4'
-		},
-		'35': {
-			regexp: /xbox/i,
-			deviceId: '5'
-		},
-		'36': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*OUYA/i,
-			deviceId: '5'
-		},
-		'37': {
-			regexp: /Opera Tablet/i,
-			deviceId: '4'
-		},
-		'38': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*POV_TV-HDMI[\s\S]* Safari/i,
-			deviceId: '6'
-		},
-		'40': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]* Enjoy/i,
-			deviceId: '4'
-		},
-		'41': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SmartTab/i,
-			deviceId: '4'
-		},
-		'42': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*ViewPad 10/i,
-			deviceId: '4'
-		},
-		'43': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*GT\-N8005|N8010|N8013|N8020/i,
-			deviceId: '4'
-		},
-		'44': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*GT\-P1000|P1010|P3100|P3105|P3110|P3113|P5100|P5110|P5113|P5200|P5210|P6200|P6201|P6210|P6211|P6800|P6810|P7110|P7300|P7310|P7320|P7500|P7510|P7511/i,
-			deviceId: '4'
-		},
-		'45': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SPH\-P500/i,
-			deviceId: '4'
-		},
-		'46': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SHW\-M380|M480K|M500|M305/i,
-			deviceId: '4'
-		},
-		'47': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SHV\-E230|E140/i,
-			deviceId: '4'
-		},
-		'48': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SGH\-I957M|I497|I467/i,
-			deviceId: '4'
-		},
-		'49': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*SCH\-I925|I915/i,
-			deviceId: '4'
-		},
-		'50': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*PocketBook A10|PocketBook A7/i,
-			deviceId: '4'
-		},
-		'51': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*Obreey SURFpad/i,
-			deviceId: '4'
-		},
-		'52': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*MZ505|MZ601|MZ603|MZ604|MZ605|MZ606|MZ607|MZ608|MZ609|MZ616|MZ617/i,
-			deviceId: '4'
-		},
-		'53': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*Xoom/i,
-			deviceId: '4'
-		},
-		'54': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*IdeaTab|SmartTabII7|Lenovo A1|K1 Build\/K1/i,
-			deviceId: '4'
-		},
-		'55': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*LG\-F200K|F200L|F200S/i,
-			deviceId: '4'
-		},
-		'56': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*HUAWEI MediaPad/i,
-			deviceId: '4'
-		},
-		'57': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*HTC PG09410/i,
-			deviceId: '4'
-		},
-		'58': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*Nexus 10/i,
-			deviceId: '4'
-		},
-		'59': {
-			regexp: /^Mozilla[\s\S]*Android[\s\S]*L-06C Build/i,
-			deviceId: '4'
-		},
-		'60': {
-			regexp: /^BlackBerry[0-9]+[\s\S]*Profile\/MIDP/i,
-			deviceId: '3'
-		},
-		'61': {
-			regexp: /^Mozilla[\s\S]*hp-tablet[\s\S]*hpwOS[\s\S]*TouchPad/i,
-			deviceId: '4'
-		},
-		'62': {
-			regexp: /^Mozilla[\s\S]*Linux[\s\S]*HbbTV/i,
-			deviceId: '6'
-		},
-		'63': {
-			regexp: /^Mozilla[\s\S]*Silk[\s\S]*Safari/i,
-			deviceId: '4'
-		},
-		'64': {
-			regexp: /^Mozilla[\s\S]*Tizen\/[0-9\.]+/i,
-			deviceId: '3'
-		},
-		'65': {
-			regexp: /^Mozilla[\s\S]*Windows Phone[\s\S]*ARM[\s\S]*NOKIA[\s\S]*Lumia 820/i,
-			deviceId: '3'
-		},
-		'66': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFJWI[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'67': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFSOWI[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'68': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFTHWI[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'69': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFTHWA[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'70': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFAPWI[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'71': {
-			regexp: /^Mozilla[\s\S]*linux[\s\S]*KFAPWA[\s\S]*Silk/i,
-			deviceId: '4'
-		},
-		'72': {
-			regexp: /^Mozilla[\s\S]*Windows Phone[\s\S]*ARM[\s\S]*NOKIA[\s\S]*Lumia 920/i,
-			deviceId: '3'
-		},
-		'73': {
-			regexp: /^Mozilla[\s\S]*PalmOS[\s\S]*WebPro[\s\S]*Palm/i,
-			deviceId: '7'
-		},
-		'74': {
-			regexp: /PalmSource[\s\S]*Blazer/i,
-			deviceId: '7'
-		},
-		'75': {
-			regexp: /^Mozilla[\s\S]*WebTV[\s\S]*MSIE/i,
-			deviceId: '6'
-		},
-		order: [
-			'9',
-			'64',
-			'65',
-			'72',
-			'51',
-			'52',
-			'50',
-			'49',
-			'47',
-			'53',
-			'75',
-			'46',
-			'45',
-			'44',
-			'43',
-			'42',
-			'41',
-			'40',
-			'54',
-			'55',
-			'74',
-			'73',
-			'71',
-			'70',
-			'69',
-			'68',
-			'66',
-			'62',
-			'61',
-			'59',
-			'58',
-			'57',
-			'56',
-			'38',
-			'1',
-			'23',
-			'22',
-			'21',
-			'10',
-			'19',
-			'18',
-			'17',
-			'16',
-			'11',
-			'15',
-			'67',
-			'24',
-			'25',
-			'26',
-			'36',
-			'34',
-			'33',
-			'13',
-			'48',
-			'29',
-			'28',
-			'27',
-			'60',
-			'5',
-			'3',
-			'6',
-			'2',
-			'12',
-			'14',
-			'63',
-			'20',
-			'31',
-			'32',
-			'37',
-			'30',
-			'35'
-		]
-	}
-};
-
-export {UAS_parser, UAS_cache};
-export default UAS_parser;

+ 63 - 0
src/core/operations/A1Z26CipherDecode.mjs

@@ -0,0 +1,63 @@
+/**
+ * @author Jarmo van Lenthe [github.com/jarmovanlenthe]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import {DELIM_OPTIONS} from "../lib/Delim";
+import OperationError from "../errors/OperationError";
+
+/**
+ * A1Z26 Cipher Decode operation
+ */
+class A1Z26CipherDecode extends Operation {
+
+    /**
+     * A1Z26CipherDecode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "A1Z26 Cipher Decode";
+        this.module = "Ciphers";
+        this.description = "Converts alphabet order numbers into their corresponding  alphabet character.<br><br>e.g. <code>1</code> becomes <code>a</code> and <code>2</code> becomes <code>b</code>.";
+        this.infoURL = "";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: DELIM_OPTIONS
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const delim = Utils.charRep(args[0] || "Space");
+
+        if (input.length === 0) {
+            return [];
+        }
+
+        const bites = input.split(delim);
+        let latin1 = "";
+        for (let i = 0; i < bites.length; i++) {
+            if (bites[i] < 1 || bites[i] > 26) {
+                throw new OperationError("Error: all numbers must be between 1 and 26.");
+            }
+            latin1 += Utils.chr(parseInt(bites[i], 10) + 96);
+        }
+        return latin1;
+    }
+
+}
+
+export default A1Z26CipherDecode;

+ 61 - 0
src/core/operations/A1Z26CipherEncode.mjs

@@ -0,0 +1,61 @@
+/**
+ * @author Jarmo van Lenthe [github.com/jarmovanlenthe]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import {DELIM_OPTIONS} from "../lib/Delim";
+
+/**
+ * A1Z26 Cipher Encode operation
+ */
+class A1Z26CipherEncode extends Operation {
+
+    /**
+     * A1Z26CipherEncode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "A1Z26 Cipher Encode";
+        this.module = "Ciphers";
+        this.description = "Converts alphabet characters into their corresponding alphabet order number.<br><br>e.g. <code>a</code> becomes <code>1</code> and <code>b</code> becomes <code>2</code>.<br><br>Non-alphabet characters are dropped.";
+        this.infoURL = "";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: DELIM_OPTIONS
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const delim = Utils.charRep(args[0] || "Space");
+        let output = "";
+
+        const sanitizedinput = input.toLowerCase(),
+            charcode = Utils.strToCharcode(sanitizedinput);
+
+        for (let i = 0; i < charcode.length; i++) {
+            const ordinal = charcode[i] - 96;
+
+            if (ordinal > 0 && ordinal <= 26) {
+                output += ordinal.toString(10) + delim;
+            }
+        }
+        return output.slice(0, -delim.length);
+    }
+
+}
+
+export default A1Z26CipherEncode;

+ 77 - 0
src/core/operations/ADD.mjs

@@ -0,0 +1,77 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import { bitOp, add, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
+
+/**
+ * ADD operation
+ */
+class ADD extends Operation {
+
+    /**
+     * ADD constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "ADD";
+        this.module = "Default";
+        this.description = "ADD the input with the given key (e.g. <code>fe023da5</code>), MOD 255";
+        this.infoURL = "https://wikipedia.org/wiki/Bitwise_operation#Bitwise_operators";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                "name": "Key",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": BITWISE_OP_DELIMS
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
+
+        return bitOp(input, key, add);
+    }
+
+    /**
+     * Highlight ADD
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight ADD in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default ADD;

+ 109 - 0
src/core/operations/AESDecrypt.mjs

@@ -0,0 +1,109 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import forge from "node-forge/dist/forge.min.js";
+import OperationError from "../errors/OperationError";
+
+/**
+ * AES Decrypt operation
+ */
+class AESDecrypt extends Operation {
+
+    /**
+     * AESDecrypt constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "AES Decrypt";
+        this.module = "Ciphers";
+        this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul><br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.<br><br><b>GCM Tag:</b> This field is ignored unless 'GCM' mode is used.";
+        this.infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Key",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "IV",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "Mode",
+                "type": "option",
+                "value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"]
+            },
+            {
+                "name": "Input",
+                "type": "option",
+                "value": ["Hex", "Raw"]
+            },
+            {
+                "name": "Output",
+                "type": "option",
+                "value": ["Raw", "Hex"]
+            },
+            {
+                "name": "GCM Tag",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     *
+     * @throws {OperationError} if cannot decrypt input or invalid key length
+     */
+    run(input, args) {
+        const key = Utils.convertToByteArray(args[0].string, args[0].option),
+            iv = Utils.convertToByteArray(args[1].string, args[1].option),
+            mode = args[2],
+            inputType = args[3],
+            outputType = args[4],
+            gcmTag = Utils.convertToByteString(args[5].string, args[5].option);
+
+        if ([16, 24, 32].indexOf(key.length) < 0) {
+            throw new OperationError(`Invalid key length: ${key.length} bytes
+
+The following algorithms will be used based on the size of the key:
+  16 bytes = AES-128
+  24 bytes = AES-192
+  32 bytes = AES-256`);
+        }
+
+        input = Utils.convertToByteString(input, inputType);
+
+        const decipher = forge.cipher.createDecipher("AES-" + mode, key);
+        decipher.start({
+            iv: iv,
+            tag: gcmTag
+        });
+        decipher.update(forge.util.createBuffer(input));
+        const result = decipher.finish();
+
+        if (result) {
+            return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
+        } else {
+            throw new OperationError("Unable to decrypt input with these parameters.");
+        }
+    }
+
+}
+
+export default AESDecrypt;

+ 107 - 0
src/core/operations/AESEncrypt.mjs

@@ -0,0 +1,107 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import forge from "node-forge/dist/forge.min.js";
+import OperationError from "../errors/OperationError";
+
+/**
+ * AES Encrypt operation
+ */
+class AESEncrypt extends Operation {
+
+    /**
+     * AESEncrypt constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "AES Encrypt";
+        this.module = "Ciphers";
+        this.description = "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.<br><br><b>Key:</b> The following algorithms will be used based on the size of the key:<ul><li>16 bytes = AES-128</li><li>24 bytes = AES-192</li><li>32 bytes = AES-256</li></ul>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.";
+        this.infoURL = "https://wikipedia.org/wiki/Advanced_Encryption_Standard";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Key",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "IV",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "Mode",
+                "type": "option",
+                "value": ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"]
+            },
+            {
+                "name": "Input",
+                "type": "option",
+                "value": ["Raw", "Hex"]
+            },
+            {
+                "name": "Output",
+                "type": "option",
+                "value": ["Hex", "Raw"]
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     *
+     * @throws {OperationError} if invalid key length
+     */
+    run(input, args) {
+        const key = Utils.convertToByteArray(args[0].string, args[0].option),
+            iv = Utils.convertToByteArray(args[1].string, args[1].option),
+            mode = args[2],
+            inputType = args[3],
+            outputType = args[4];
+
+        if ([16, 24, 32].indexOf(key.length) < 0) {
+            throw new OperationError(`Invalid key length: ${key.length} bytes
+
+The following algorithms will be used based on the size of the key:
+  16 bytes = AES-128
+  24 bytes = AES-192
+  32 bytes = AES-256`);
+        }
+
+        input = Utils.convertToByteString(input, inputType);
+
+        const cipher = forge.cipher.createCipher("AES-" + mode, key);
+        cipher.start({iv: iv});
+        cipher.update(forge.util.createBuffer(input));
+        cipher.finish();
+
+        if (outputType === "Hex") {
+            if (mode === "GCM") {
+                return cipher.output.toHex() + "\n\n" +
+                    "Tag: " + cipher.mode.tag.toHex();
+            }
+            return cipher.output.toHex();
+        } else {
+            if (mode === "GCM") {
+                return cipher.output.getBytes() + "\n\n" +
+                    "Tag: " + cipher.mode.tag.getBytes();
+            }
+            return cipher.output.getBytes();
+        }
+    }
+
+}
+
+export default AESEncrypt;

+ 77 - 0
src/core/operations/AND.mjs

@@ -0,0 +1,77 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import { bitOp, and, BITWISE_OP_DELIMS } from "../lib/BitwiseOp";
+
+/**
+ * AND operation
+ */
+class AND extends Operation {
+
+    /**
+     * AND constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "AND";
+        this.module = "Default";
+        this.description = "AND the input with the given key.<br>e.g. <code>fe023da5</code>";
+        this.infoURL = "https://wikipedia.org/wiki/Bitwise_operation#AND";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                "name": "Key",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": BITWISE_OP_DELIMS
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
+
+        return bitOp(input, key, and);
+    }
+
+    /**
+     * Highlight AND
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight AND in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default AND;

+ 46 - 0
src/core/operations/AddLineNumbers.mjs

@@ -0,0 +1,46 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+
+/**
+ * Add line numbers operation
+ */
+class AddLineNumbers extends Operation {
+
+    /**
+     * AddLineNumbers constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Add line numbers";
+        this.module = "Default";
+        this.description = "Adds line numbers to the output.";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const lines = input.split("\n"),
+            width = lines.length.toString().length;
+        let output = "";
+
+        for (let n = 0; n < lines.length; n++) {
+            output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n";
+        }
+        return output.slice(0, output.length-1);
+    }
+
+}
+
+export default AddLineNumbers;

+ 53 - 0
src/core/operations/Adler32Checksum.mjs

@@ -0,0 +1,53 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+
+/**
+ * Adler-32 Checksum operation
+ */
+class Adler32Checksum extends Operation {
+
+    /**
+     * Adler32Checksum constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Adler-32 Checksum";
+        this.module = "Crypto";
+        this.description = "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).<br><br>Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.";
+        this.infoURL = "https://wikipedia.org/wiki/Adler-32";
+        this.inputType = "byteArray";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const MOD_ADLER = 65521;
+        let a = 1,
+            b = 0;
+
+        for (let i = 0; i < input.length; i++) {
+            a += input[i];
+            b += a;
+        }
+
+        a %= MOD_ADLER;
+        b %= MOD_ADLER;
+
+        return Utils.hex(((b << 16) | a) >>> 0, 8);
+    }
+
+}
+
+export default Adler32Checksum;

+ 106 - 0
src/core/operations/AffineCipherDecode.mjs

@@ -0,0 +1,106 @@
+/**
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Affine Cipher Decode operation
+ */
+class AffineCipherDecode extends Operation {
+
+    /**
+     * AffineCipherDecode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Affine Cipher Decode";
+        this.module = "Ciphers";
+        this.description = "The Affine cipher is a type of monoalphabetic substitution cipher. To decrypt, each letter in an alphabet is mapped to its numeric equivalent, decrypted by a mathematical function, and converted back to a letter.";
+        this.infoURL = "https://wikipedia.org/wiki/Affine_cipher";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "a",
+                "type": "number",
+                "value": 1
+            },
+            {
+                "name": "b",
+                "type": "number",
+                "value": 0
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     *
+     * @throws {OperationError} if a or b values are invalid
+     */
+    run(input, args) {
+        const alphabet = "abcdefghijklmnopqrstuvwxyz",
+            [a, b] = args,
+            aModInv = Utils.modInv(a, 26); // Calculates modular inverse of a
+        let output = "";
+
+        if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) {
+            throw new OperationError("The values of a and b can only be integers.");
+        }
+
+        if (Utils.gcd(a, 26) !== 1) {
+            throw new OperationError("The value of `a` must be coprime to 26.");
+        }
+
+        for (let i = 0; i < input.length; i++) {
+            if (alphabet.indexOf(input[i]) >= 0) {
+                // Uses the affine decode function (y-b * A') % m = x (where m is length of the alphabet and A' is modular inverse)
+                output += alphabet[Utils.mod((alphabet.indexOf(input[i]) - b) * aModInv, 26)];
+            } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
+                // Same as above, accounting for uppercase
+                output += alphabet[Utils.mod((alphabet.indexOf(input[i].toLowerCase()) - b) * aModInv, 26)].toUpperCase();
+            } else {
+                // Non-alphabetic characters
+                output += input[i];
+            }
+        }
+        return output;
+    }
+
+    /**
+     * Highlight Affine Cipher Decode
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Affine Cipher Decode in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default AffineCipherDecode;

+ 78 - 0
src/core/operations/AffineCipherEncode.mjs

@@ -0,0 +1,78 @@
+/**
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import { affineEncode } from "../lib/Ciphers";
+
+/**
+ * Affine Cipher Encode operation
+ */
+class AffineCipherEncode extends Operation {
+
+    /**
+     * AffineCipherEncode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Affine Cipher Encode";
+        this.module = "Ciphers";
+        this.description = "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, <code>(ax + b) % 26</code>, and converted back to a letter.";
+        this.infoURL = "https://wikipedia.org/wiki/Affine_cipher";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "a",
+                "type": "number",
+                "value": 1
+            },
+            {
+                "name": "b",
+                "type": "number",
+                "value": 0
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        return affineEncode(input, args);
+    }
+
+    /**
+     * Highlight Affine Cipher Encode
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Affine Cipher Encode in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default AffineCipherEncode;

+ 184 - 0
src/core/operations/AnalyseHash.mjs

@@ -0,0 +1,184 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Analyse hash operation
+ */
+class AnalyseHash extends Operation {
+
+    /**
+     * AnalyseHash constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Analyse hash";
+        this.module = "Crypto";
+        this.description = "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.";
+        this.infoURL = "https://wikipedia.org/wiki/Comparison_of_cryptographic_hash_functions";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        input = input.replace(/\s/g, "");
+
+        let output = "",
+            possibleHashFunctions = [];
+        const byteLength = input.length / 2,
+            bitLength = byteLength * 8;
+
+        if (!/^[a-f0-9]+$/i.test(input)) {
+            throw new OperationError("Invalid hash");
+        }
+
+        output += "Hash length: " + input.length + "\n" +
+            "Byte length: " + byteLength + "\n" +
+            "Bit length:  " + bitLength + "\n\n" +
+            "Based on the length, this hash could have been generated by one of the following hashing functions:\n";
+
+        switch (bitLength) {
+            case 4:
+                possibleHashFunctions = [
+                    "Fletcher-4",
+                    "Luhn algorithm",
+                    "Verhoeff algorithm",
+                ];
+                break;
+            case 8:
+                possibleHashFunctions = [
+                    "Fletcher-8",
+                ];
+                break;
+            case 16:
+                possibleHashFunctions = [
+                    "BSD checksum",
+                    "CRC-16",
+                    "SYSV checksum",
+                    "Fletcher-16"
+                ];
+                break;
+            case 32:
+                possibleHashFunctions = [
+                    "CRC-32",
+                    "Fletcher-32",
+                    "Adler-32",
+                ];
+                break;
+            case 64:
+                possibleHashFunctions = [
+                    "CRC-64",
+                    "RIPEMD-64",
+                    "SipHash",
+                ];
+                break;
+            case 128:
+                possibleHashFunctions = [
+                    "MD5",
+                    "MD4",
+                    "MD2",
+                    "HAVAL-128",
+                    "RIPEMD-128",
+                    "Snefru",
+                    "Tiger-128",
+                ];
+                break;
+            case 160:
+                possibleHashFunctions = [
+                    "SHA-1",
+                    "SHA-0",
+                    "FSB-160",
+                    "HAS-160",
+                    "HAVAL-160",
+                    "RIPEMD-160",
+                    "Tiger-160",
+                ];
+                break;
+            case 192:
+                possibleHashFunctions = [
+                    "Tiger",
+                    "HAVAL-192",
+                ];
+                break;
+            case 224:
+                possibleHashFunctions = [
+                    "SHA-224",
+                    "SHA3-224",
+                    "ECOH-224",
+                    "FSB-224",
+                    "HAVAL-224",
+                ];
+                break;
+            case 256:
+                possibleHashFunctions = [
+                    "SHA-256",
+                    "SHA3-256",
+                    "BLAKE-256",
+                    "ECOH-256",
+                    "FSB-256",
+                    "GOST",
+                    "Grøstl-256",
+                    "HAVAL-256",
+                    "PANAMA",
+                    "RIPEMD-256",
+                    "Snefru",
+                ];
+                break;
+            case 320:
+                possibleHashFunctions = [
+                    "RIPEMD-320",
+                ];
+                break;
+            case 384:
+                possibleHashFunctions = [
+                    "SHA-384",
+                    "SHA3-384",
+                    "ECOH-384",
+                    "FSB-384",
+                ];
+                break;
+            case 512:
+                possibleHashFunctions = [
+                    "SHA-512",
+                    "SHA3-512",
+                    "BLAKE-512",
+                    "ECOH-512",
+                    "FSB-512",
+                    "Grøstl-512",
+                    "JH",
+                    "MD6",
+                    "Spectral Hash",
+                    "SWIFFT",
+                    "Whirlpool",
+                ];
+                break;
+            case 1024:
+                possibleHashFunctions = [
+                    "Fowler-Noll-Vo",
+                ];
+                break;
+            default:
+                possibleHashFunctions = [
+                    "Unknown"
+                ];
+                break;
+        }
+
+        return output + possibleHashFunctions.join("\n");
+    }
+
+}
+
+export default AnalyseHash;

+ 67 - 0
src/core/operations/AtbashCipher.mjs

@@ -0,0 +1,67 @@
+/**
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import { affineEncode } from "../lib/Ciphers";
+
+/**
+ * Atbash Cipher operation
+ */
+class AtbashCipher extends Operation {
+
+    /**
+     * AtbashCipher constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Atbash Cipher";
+        this.module = "Ciphers";
+        this.description = "Atbash is a mono-alphabetic substitution cipher originally used to encode the Hebrew alphabet. It has been modified here for use with the Latin alphabet.";
+        this.infoURL = "https://wikipedia.org/wiki/Atbash";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        return affineEncode(input, [25, 25]);
+    }
+
+    /**
+     * Highlight Atbash Cipher
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Atbash Cipher in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default AtbashCipher;

+ 49 - 0
src/core/operations/BSONDeserialise.mjs

@@ -0,0 +1,49 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bson from "bson";
+import OperationError from "../errors/OperationError";
+
+/**
+ * BSON deserialise operation
+ */
+class BSONDeserialise extends Operation {
+
+    /**
+     * BSONDeserialise constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "BSON deserialise";
+        this.module = "BSON";
+        this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be in a raw bytes format.";
+        this.infoURL = "https://wikipedia.org/wiki/BSON";
+        this.inputType = "ArrayBuffer";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {ArrayBuffer} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        if (!input.byteLength) return "";
+
+        try {
+            const data = bson.deserialize(new Buffer(input));
+            return JSON.stringify(data, null, 2);
+        } catch (err) {
+            throw new OperationError(err.toString());
+        }
+    }
+
+}
+
+export default BSONDeserialise;

+ 49 - 0
src/core/operations/BSONSerialise.mjs

@@ -0,0 +1,49 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bson from "bson";
+import OperationError from "../errors/OperationError";
+
+/**
+ * BSON serialise operation
+ */
+class BSONSerialise extends Operation {
+
+    /**
+     * BSONSerialise constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "BSON serialise";
+        this.module = "BSON";
+        this.description = "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.<br><br>Input data should be valid JSON.";
+        this.infoURL = "https://wikipedia.org/wiki/BSON";
+        this.inputType = "string";
+        this.outputType = "ArrayBuffer";
+        this.args = [];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {ArrayBuffer}
+     */
+    run(input, args) {
+        if (!input) return new ArrayBuffer();
+
+        try {
+            const data = JSON.parse(input);
+            return bson.serialize(data).buffer;
+        } catch (err) {
+            throw new OperationError(err.toString());
+        }
+    }
+
+}
+
+export default BSONSerialise;

+ 0 - 66
src/core/operations/Base.js

@@ -1,66 +0,0 @@
-/**
- * Numerical base operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @namespace
- */
-const Base = {
-
-    /**
-     * @constant
-     * @default
-     */
-    DEFAULT_RADIX: 36,
-
-    /**
-     * To Base operation.
-     *
-     * @param {number} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runTo: function(input, args) {
-        if (!input) {
-            throw ("Error: Input must be a number");
-        }
-        const radix = args[0] || Base.DEFAULT_RADIX;
-        if (radix < 2 || radix > 36) {
-            throw "Error: Radix argument must be between 2 and 36";
-        }
-        return input.toString(radix);
-    },
-
-
-    /**
-     * From Base operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {number}
-     */
-    runFrom: function(input, args) {
-        const radix = args[0] || Base.DEFAULT_RADIX;
-        if (radix < 2 || radix > 36) {
-            throw "Error: Radix argument must be between 2 and 36";
-        }
-
-        let number = input.replace(/\s/g, "").split("."),
-            result = parseInt(number[0], radix) || 0;
-
-        if (number.length === 1) return result;
-
-        // Fractional part
-        for (let i = 0; i < number[1].length; i++) {
-            const digit = parseInt(number[1][i], radix);
-            result += digit / Math.pow(radix, i+1);
-        }
-
-        return result;
-    },
-
-};
-
-export default Base;

+ 0 - 137
src/core/operations/Base58.js

@@ -1,137 +0,0 @@
-import Utils from "../Utils.js";
-
-
-/**
- * Base58 operations.
- *
- * @author tlwr [toby@toby.codes]
- * @copyright Crown Copyright 2017
- * @license Apache-2.0
- *
- * @namespace
- */
-const Base58 = {
-
-    /**
-     * @constant
-     * @default
-     */
-    ALPHABET_OPTIONS: [
-        {
-            name: "Bitcoin",
-            value: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
-        },
-        {
-            name: "Ripple",
-            value: "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
-        },
-    ],
-    /**
-     * @constant
-     * @default
-     */
-    REMOVE_NON_ALPH_CHARS: true,
-
-    /**
-     * To Base58 operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runTo: function(input, args) {
-        let alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value,
-            result = [0];
-
-        alphabet = Utils.expandAlphRange(alphabet).join("");
-
-        if (alphabet.length !== 58 ||
-            [].unique.call(alphabet).length !== 58) {
-            throw ("Error: alphabet must be of length 58");
-        }
-
-        if (input.length === 0) return "";
-
-        input.forEach(function(b) {
-            let carry = (result[0] << 8) + b;
-            result[0] = carry % 58;
-            carry = (carry / 58) | 0;
-
-            for (let i = 1; i < result.length; i++) {
-                carry += result[i] << 8;
-                result[i] = carry % 58;
-                carry = (carry / 58) | 0;
-            }
-
-            while (carry > 0) {
-                result.push(carry % 58);
-                carry = (carry / 58) | 0;
-            }
-        });
-
-        result = result.map(function(b) {
-            return alphabet[b];
-        }).reverse().join("");
-
-        while (result.length < input.length) {
-            result = alphabet[0] + result;
-        }
-
-        return result;
-    },
-
-
-    /**
-     * From Base58 operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFrom: function(input, args) {
-        let alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value,
-            removeNonAlphaChars = args[1] === undefined ? true : args[1],
-            result = [0];
-
-        alphabet = Utils.expandAlphRange(alphabet).join("");
-
-        if (alphabet.length !== 58 ||
-            [].unique.call(alphabet).length !== 58) {
-            throw ("Alphabet must be of length 58");
-        }
-
-        if (input.length === 0) return [];
-
-        [].forEach.call(input, function(c, charIndex) {
-            const index = alphabet.indexOf(c);
-
-            if (index === -1) {
-                if (removeNonAlphaChars) {
-                    return;
-                } else {
-                    throw ("Char '" + c + "' at position " + charIndex + " not in alphabet");
-                }
-            }
-
-            let carry = result[0] * 58 + index;
-            result[0] = carry & 0xFF;
-            carry = carry >> 8;
-
-            for (let i = 1; i < result.length; i++) {
-                carry += result[i] * 58;
-                result[i] = carry & 0xFF;
-                carry = carry >> 8;
-            }
-
-            while (carry > 0) {
-                result.push(carry & 0xFF);
-                carry = carry >> 8;
-            }
-        });
-
-        return result.reverse();
-    },
-
-};
-
-export default Base58;

+ 0 - 347
src/core/operations/Base64.js

@@ -1,347 +0,0 @@
-import Utils from "../Utils.js";
-
-
-/**
- * Base64 operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @namespace
- */
-const Base64 = {
-
-    /**
-     * @constant
-     * @default
-     */
-    ALPHABET: "A-Za-z0-9+/=",
-    /**
-     * @constant
-     * @default
-     */
-    ALPHABET_OPTIONS: [
-        {name: "Standard: A-Za-z0-9+/=", value: "A-Za-z0-9+/="},
-        {name: "URL safe: A-Za-z0-9-_", value: "A-Za-z0-9-_"},
-        {name: "Filename safe: A-Za-z0-9+-=", value: "A-Za-z0-9+\\-="},
-        {name: "itoa64: ./0-9A-Za-z=", value: "./0-9A-Za-z="},
-        {name: "XML: A-Za-z0-9_.", value: "A-Za-z0-9_."},
-        {name: "y64: A-Za-z0-9._-", value: "A-Za-z0-9._-"},
-        {name: "z64: 0-9a-zA-Z+/=", value: "0-9a-zA-Z+/="},
-        {name: "Radix-64: 0-9A-Za-z+/=", value: "0-9A-Za-z+/="},
-        {name: "Uuencoding: [space]-_", value: " -_"},
-        {name: "Xxencoding: +-0-9A-Za-z", value: "+\\-0-9A-Za-z"},
-        {name: "BinHex: !-,-0-689@A-NP-VX-Z[`a-fh-mp-r", value: "!-,-0-689@A-NP-VX-Z[`a-fh-mp-r"},
-        {name: "ROT13: N-ZA-Mn-za-m0-9+/=", value: "N-ZA-Mn-za-m0-9+/="},
-        {name: "UNIX crypt: ./0-9A-Za-z", value: "./0-9A-Za-z"},
-    ],
-
-    /**
-     * To Base64 operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runTo: function(input, args) {
-        const alphabet = args[0] || Base64.ALPHABET;
-        return Utils.toBase64(input, alphabet);
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    REMOVE_NON_ALPH_CHARS: true,
-
-    /**
-     * From Base64 operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFrom: function(input, args) {
-        let alphabet = args[0] || Base64.ALPHABET,
-            removeNonAlphChars = args[1];
-
-        return Utils.fromBase64(input, alphabet, "byteArray", removeNonAlphChars);
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    BASE32_ALPHABET: "A-Z2-7=",
-
-    /**
-     * To Base32 operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runTo32: function(input, args) {
-        if (!input) return "";
-
-        let alphabet = args[0] ?
-                Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
-            output = "",
-            chr1, chr2, chr3, chr4, chr5,
-            enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
-            i = 0;
-
-        while (i < input.length) {
-            chr1 = input[i++];
-            chr2 = input[i++];
-            chr3 = input[i++];
-            chr4 = input[i++];
-            chr5 = input[i++];
-
-            enc1 = chr1 >> 3;
-            enc2 = ((chr1 & 7) << 2) | (chr2 >> 6);
-            enc3 = (chr2 >> 1) & 31;
-            enc4 = ((chr2 & 1) << 4) | (chr3 >> 4);
-            enc5 = ((chr3 & 15) << 1) | (chr4 >> 7);
-            enc6 = (chr4 >> 2) & 31;
-            enc7 = ((chr4 & 3) << 3) | (chr5 >> 5);
-            enc8 = chr5 & 31;
-
-            if (isNaN(chr2)) {
-                enc3 = enc4 = enc5 = enc6 = enc7 = enc8 = 32;
-            } else if (isNaN(chr3)) {
-                enc5 = enc6 = enc7 = enc8 = 32;
-            } else if (isNaN(chr4)) {
-                enc6 = enc7 = enc8 = 32;
-            } else if (isNaN(chr5)) {
-                enc8 = 32;
-            }
-
-            output += alphabet.charAt(enc1) + alphabet.charAt(enc2) + alphabet.charAt(enc3) +
-                alphabet.charAt(enc4) + alphabet.charAt(enc5) + alphabet.charAt(enc6) +
-                alphabet.charAt(enc7) + alphabet.charAt(enc8);
-        }
-
-        return output;
-    },
-
-
-    /**
-     * From Base32 operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFrom32: function(input, args) {
-        if (!input) return [];
-
-        let alphabet = args[0] ?
-                Utils.expandAlphRange(args[0]).join("") : "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
-            removeNonAlphChars = args[0];
-
-        let output = [],
-            chr1, chr2, chr3, chr4, chr5,
-            enc1, enc2, enc3, enc4, enc5, enc6, enc7, enc8,
-            i = 0;
-
-        if (removeNonAlphChars) {
-            const re = new RegExp("[^" + alphabet.replace(/[\]\\\-^]/g, "\\$&") + "]", "g");
-            input = input.replace(re, "");
-        }
-
-        while (i < input.length) {
-            enc1 = alphabet.indexOf(input.charAt(i++));
-            enc2 = alphabet.indexOf(input.charAt(i++) || "=");
-            enc3 = alphabet.indexOf(input.charAt(i++) || "=");
-            enc4 = alphabet.indexOf(input.charAt(i++) || "=");
-            enc5 = alphabet.indexOf(input.charAt(i++) || "=");
-            enc6 = alphabet.indexOf(input.charAt(i++) || "=");
-            enc7 = alphabet.indexOf(input.charAt(i++) || "=");
-            enc8 = alphabet.indexOf(input.charAt(i++) || "=");
-
-            chr1 = (enc1 << 3) | (enc2 >> 2);
-            chr2 = ((enc2 & 3) << 6) | (enc3 << 1) | (enc4 >> 4);
-            chr3 = ((enc4 & 15) << 4) | (enc5 >> 1);
-            chr4 = ((enc5 & 1) << 7) | (enc6 << 2) | (enc7 >> 3);
-            chr5 = ((enc7 & 7) << 5) | enc8;
-
-            output.push(chr1);
-            if (enc2 & 3 !== 0 || enc3 !== 32) output.push(chr2);
-            if (enc4 & 15 !== 0 || enc5 !== 32) output.push(chr3);
-            if (enc5 & 1 !== 0 || enc6 !== 32) output.push(chr4);
-            if (enc7 & 7 !== 0 || enc8 !== 32) output.push(chr5);
-        }
-
-        return output;
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    SHOW_IN_BINARY: false,
-    /**
-     * @constant
-     * @default
-     */
-    OFFSETS_SHOW_VARIABLE: true,
-
-    /**
-     * Show Base64 offsets operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {html}
-     */
-    runOffsets: function(input, args) {
-        let alphabet = args[0] || Base64.ALPHABET,
-            showVariable = args[1],
-            offset0 = Utils.toBase64(input, alphabet),
-            offset1 = Utils.toBase64([0].concat(input), alphabet),
-            offset2 = Utils.toBase64([0, 0].concat(input), alphabet),
-            len0 = offset0.indexOf("="),
-            len1 = offset1.indexOf("="),
-            len2 = offset2.indexOf("="),
-            script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>",
-            staticSection = "",
-            padding = "";
-
-        if (input.length < 1) {
-            return "Please enter a string.";
-        }
-
-        // Highlight offset 0
-        if (len0 % 4 === 2) {
-            staticSection = offset0.slice(0, -3);
-            offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
-                staticSection + "</span>" +
-                "<span class='hlgreen'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
-                "<span class='hlred'>" + offset0.substr(offset0.length - 2) + "</span>";
-        } else if (len0 % 4 === 3) {
-            staticSection = offset0.slice(0, -2);
-            offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
-                staticSection + "</span>" +
-                "<span class='hlgreen'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
-                "<span class='hlred'>" + offset0.substr(offset0.length - 1) + "</span>";
-        } else {
-            staticSection = offset0;
-            offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64(staticSection, alphabet)) + "'>" +
-                staticSection + "</span>";
-        }
-
-        if (!showVariable) {
-            offset0 = staticSection;
-        }
-
-
-        // Highlight offset 1
-        padding = "<span class='hlred'>" + offset1.substr(0, 1) + "</span>" +
-            "<span class='hlgreen'>" + offset1.substr(1, 1) + "</span>";
-        offset1 = offset1.substr(2);
-        if (len1 % 4 === 2) {
-            staticSection = offset1.slice(0, -3);
-            offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
-                staticSection + "</span>" +
-                "<span class='hlgreen'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
-                "<span class='hlred'>" + offset1.substr(offset1.length - 2) + "</span>";
-        } else if (len1 % 4 === 3) {
-            staticSection = offset1.slice(0, -2);
-            offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
-                staticSection + "</span>" +
-                "<span class='hlgreen'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
-                "<span class='hlred'>" + offset1.substr(offset1.length - 1) + "</span>";
-        } else {
-            staticSection = offset1;
-            offset1 = padding +  "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64("AA" + staticSection, alphabet).slice(1)) + "'>" +
-                staticSection + "</span>";
-        }
-
-        if (!showVariable) {
-            offset1 = staticSection;
-        }
-
-        // Highlight offset 2
-        padding = "<span class='hlred'>" + offset2.substr(0, 2) + "</span>" +
-            "<span class='hlgreen'>" + offset2.substr(2, 1) + "</span>";
-        offset2 = offset2.substr(3);
-        if (len2 % 4 === 2) {
-            staticSection = offset2.slice(0, -3);
-            offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
-                staticSection + "</span>" +
-                "<span class='hlgreen'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
-                "<span class='hlred'>" + offset2.substr(offset2.length - 2) + "</span>";
-        } else if (len2 % 4 === 3) {
-            staticSection = offset2.slice(0, -2);
-            offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
-                staticSection + "</span>" +
-                "<span class='hlgreen'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
-                "<span class='hlred'>" + offset2.substr(offset2.length - 1) + "</span>";
-        } else {
-            staticSection = offset2;
-            offset2 = padding +  "<span data-toggle='tooltip' data-placement='top' title='" +
-                Utils.escapeHtml(Utils.fromBase64("AAA" + staticSection, alphabet).slice(2)) + "'>" +
-                staticSection + "</span>";
-        }
-
-        if (!showVariable) {
-            offset2 = staticSection;
-        }
-
-        return (showVariable ? "Characters highlighted in <span class='hlgreen'>green</span> could change if the input is surrounded by more data." +
-            "\nCharacters highlighted in <span class='hlred'>red</span> are for padding purposes only." +
-            "\nUnhighlighted characters are <span data-toggle='tooltip' data-placement='top' title='Tooltip on left'>static</span>." +
-            "\nHover over the static sections to see what they decode to on their own.\n" +
-            "\nOffset 0: " + offset0 +
-            "\nOffset 1: " + offset1 +
-            "\nOffset 2: " + offset2 +
-            script :
-            offset0 + "\n" + offset1 + "\n" + offset2);
-    },
-
-
-    /**
-     * Highlight to Base64
-     *
-     * @param {Object[]} pos
-     * @param {number} pos[].start
-     * @param {number} pos[].end
-     * @param {Object[]} args
-     * @returns {Object[]} pos
-     */
-    highlightTo: function(pos, args) {
-        pos[0].start = Math.floor(pos[0].start / 3 * 4);
-        pos[0].end = Math.ceil(pos[0].end / 3 * 4);
-        return pos;
-    },
-
-    /**
-     * Highlight from Base64
-     *
-     * @param {Object[]} pos
-     * @param {number} pos[].start
-     * @param {number} pos[].end
-     * @param {Object[]} args
-     * @returns {Object[]} pos
-     */
-    highlightFrom: function(pos, args) {
-        pos[0].start = Math.ceil(pos[0].start / 4 * 3);
-        pos[0].end = Math.floor(pos[0].end / 4 * 3);
-        return pos;
-    },
-
-};
-
-export default Base64;

+ 55 - 0
src/core/operations/Bcrypt.mjs

@@ -0,0 +1,55 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bcrypt from "bcryptjs";
+
+/**
+ * Bcrypt operation
+ */
+class Bcrypt extends Operation {
+
+    /**
+     * Bcrypt constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bcrypt";
+        this.module = "Crypto";
+        this.description = "bcrypt is a password hashing function designed by Niels Provos and David Mazi\xe8res, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count (rounds) can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.<br><br>Enter the password in the input to generate its hash.";
+        this.infoURL = "https://wikipedia.org/wiki/Bcrypt";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Rounds",
+                "type": "number",
+                "value": 10
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    async run(input, args) {
+        const rounds = args[0];
+        const salt = await bcrypt.genSalt(rounds);
+
+        return await bcrypt.hash(input, salt, null, p => {
+            // Progress callback
+            if (ENVIRONMENT_IS_WORKER())
+                self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
+        });
+
+    }
+
+}
+
+export default Bcrypt;

+ 56 - 0
src/core/operations/BcryptCompare.mjs

@@ -0,0 +1,56 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bcrypt from "bcryptjs";
+
+/**
+ * Bcrypt compare operation
+ */
+class BcryptCompare extends Operation {
+
+    /**
+     * BcryptCompare constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bcrypt compare";
+        this.module = "Crypto";
+        this.description = "Tests whether the input matches the given bcrypt hash. To test multiple possible passwords, use the 'Fork' operation.";
+        this.infoURL = "https://wikipedia.org/wiki/Bcrypt";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Hash",
+                "type": "string",
+                "value": ""
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    async run(input, args) {
+        const hash = args[0];
+
+        const match = await bcrypt.compare(input, hash, null, p => {
+            // Progress callback
+            if (ENVIRONMENT_IS_WORKER())
+                self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`);
+        });
+
+        return match ? "Match: " + input : "No match";
+
+    }
+
+}
+
+export default BcryptCompare;

+ 49 - 0
src/core/operations/BcryptParse.mjs

@@ -0,0 +1,49 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
+import bcrypt from "bcryptjs";
+
+/**
+ * Bcrypt parse operation
+ */
+class BcryptParse extends Operation {
+
+    /**
+     * BcryptParse constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bcrypt parse";
+        this.module = "Crypto";
+        this.description = "Parses a bcrypt hash to determine the number of rounds used, the salt, and the password hash.";
+        this.infoURL = "https://wikipedia.org/wiki/Bcrypt";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    async run(input, args) {
+        try {
+            return `Rounds: ${bcrypt.getRounds(input)}
+Salt: ${bcrypt.getSalt(input)}
+Password hash: ${input.split(bcrypt.getSalt(input))[1]}
+Full hash: ${input}`;
+        } catch (err) {
+            throw new OperationError("Error: " + err.toString());
+        }
+    }
+
+}
+
+export default BcryptParse;

+ 125 - 0
src/core/operations/BifidCipherDecode.mjs

@@ -0,0 +1,125 @@
+/**
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import { genPolybiusSquare } from "../lib/Ciphers";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Bifid Cipher Decode operation
+ */
+class BifidCipherDecode extends Operation {
+
+    /**
+     * BifidCipherDecode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bifid Cipher Decode";
+        this.module = "Ciphers";
+        this.description = "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.";
+        this.infoURL = "https://wikipedia.org/wiki/Bifid_cipher";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Keyword",
+                "type": "string",
+                "value": ""
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     *
+     * @throws {OperationError} if invalid key
+     */
+    run(input, args) {
+        const keywordStr = args[0].toUpperCase().replace("J", "I"),
+            keyword = keywordStr.split("").unique(),
+            alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
+            structure = [];
+
+        let output = "",
+            count = 0,
+            trans = "";
+
+        if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)
+            throw new OperationError("The key must consist only of letters in the English alphabet");
+
+        const polybius = genPolybiusSquare(keywordStr);
+
+        input.replace("J", "I").split("").forEach((letter) => {
+            const alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0;
+            let polInd;
+
+            if (alpInd) {
+                for (let i = 0; i < 5; i++) {
+                    polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
+                    if (polInd >= 0) {
+                        trans += `${i}${polInd}`;
+                    }
+                }
+
+                if (alpha.split("").indexOf(letter) >= 0) {
+                    structure.push(true);
+                } else if (alpInd) {
+                    structure.push(false);
+                }
+            } else {
+                structure.push(letter);
+            }
+        });
+
+        structure.forEach(pos => {
+            if (typeof pos === "boolean") {
+                const coords = [trans[count], trans[count+trans.length/2]];
+
+                output += pos ?
+                    polybius[coords[0]][coords[1]] :
+                    polybius[coords[0]][coords[1]].toLocaleLowerCase();
+                count++;
+            } else {
+                output += pos;
+            }
+        });
+
+        return output;
+    }
+
+    /**
+     * Highlight Bifid Cipher Decode
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Bifid Cipher Decode in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default BifidCipherDecode;

+ 130 - 0
src/core/operations/BifidCipherEncode.mjs

@@ -0,0 +1,130 @@
+/**
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2018
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
+import { genPolybiusSquare } from "../lib/Ciphers";
+
+/**
+ * Bifid Cipher Encode operation
+ */
+class BifidCipherEncode extends Operation {
+
+    /**
+     * BifidCipherEncode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bifid Cipher Encode";
+        this.module = "Ciphers";
+        this.description = "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.";
+        this.infoURL = "https://wikipedia.org/wiki/Bifid_cipher";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Keyword",
+                "type": "string",
+                "value": ""
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     *
+     * @throws {OperationError} if key is invalid
+     */
+    run(input, args) {
+        const keywordStr = args[0].toUpperCase().replace("J", "I"),
+            keyword = keywordStr.split("").unique(),
+            alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
+            xCo = [],
+            yCo = [],
+            structure = [];
+
+        let output = "",
+            count = 0;
+
+
+        if (!/^[A-Z]+$/.test(keywordStr) && keyword.length > 0)
+            throw new OperationError("The key must consist only of letters in the English alphabet");
+
+        const polybius = genPolybiusSquare(keywordStr);
+
+        input.replace("J", "I").split("").forEach(letter => {
+            const alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0;
+            let polInd;
+
+            if (alpInd) {
+                for (let i = 0; i < 5; i++) {
+                    polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
+                    if (polInd >= 0) {
+                        xCo.push(polInd);
+                        yCo.push(i);
+                    }
+                }
+
+                if (alpha.split("").indexOf(letter) >= 0) {
+                    structure.push(true);
+                } else if (alpInd) {
+                    structure.push(false);
+                }
+            } else {
+                structure.push(letter);
+            }
+        });
+
+        const trans = `${yCo.join("")}${xCo.join("")}`;
+
+        structure.forEach(pos => {
+            if (typeof pos === "boolean") {
+                const coords = trans.substr(2*count, 2).split("");
+
+                output += pos ?
+                    polybius[coords[0]][coords[1]] :
+                    polybius[coords[0]][coords[1]].toLocaleLowerCase();
+                count++;
+            } else {
+                output += pos;
+            }
+        });
+
+        return output;
+    }
+
+    /**
+     * Highlight Bifid Cipher Encode
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Bifid Cipher Encode in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default BifidCipherEncode;

+ 76 - 0
src/core/operations/BitShiftLeft.mjs

@@ -0,0 +1,76 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+
+/**
+ * Bit shift left operation
+ */
+class BitShiftLeft extends Operation {
+
+    /**
+     * BitShiftLeft constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bit shift left";
+        this.module = "Default";
+        this.description = "Shifts the bits in each byte towards the left by the specified amount.";
+        this.infoURL = "https://wikipedia.org/wiki/Bitwise_operation#Bit_shifts";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                "name": "Amount",
+                "type": "number",
+                "value": 1
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const amount = args[0];
+
+        return input.map(b => {
+            return (b << amount) & 0xff;
+        });
+    }
+
+    /**
+     * Highlight Bit shift left
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Bit shift left in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default BitShiftLeft;

+ 83 - 0
src/core/operations/BitShiftRight.mjs

@@ -0,0 +1,83 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+
+/**
+ * Bit shift right operation
+ */
+class BitShiftRight extends Operation {
+
+    /**
+     * BitShiftRight constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bit shift right";
+        this.module = "Default";
+        this.description = "Shifts the bits in each byte towards the right by the specified amount.<br><br><i>Logical shifts</i> replace the leftmost bits with zeros.<br><i>Arithmetic shifts</i> preserve the most significant bit (MSB) of the original byte keeping the sign the same (positive or negative).";
+        this.infoURL = "https://wikipedia.org/wiki/Bitwise_operation#Bit_shifts";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                "name": "Amount",
+                "type": "number",
+                "value": 1
+            },
+            {
+                "name": "Type",
+                "type": "option",
+                "value": ["Logical shift", "Arithmetic shift"]
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const amount = args[0],
+            type = args[1],
+            mask = type === "Logical shift" ? 0 : 0x80;
+
+        return input.map(b => {
+            return (b >>> amount) ^ (b & mask);
+        });
+    }
+
+    /**
+     * Highlight Bit shift right
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Bit shift right in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+
+}
+
+export default BitShiftRight;

+ 0 - 310
src/core/operations/BitwiseOp.js

@@ -1,310 +0,0 @@
-import Utils from "../Utils.js";
-import CryptoJS from "crypto-js";
-
-
-/**
- * Bitwise operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @namespace
- */
-const BitwiseOp = {
-
-    /**
-     * Runs bitwise operations across the input data.
-     *
-     * @private
-     * @param {byteArray} input
-     * @param {byteArray} key
-     * @param {function} func - The bitwise calculation to carry out
-     * @param {boolean} nullPreserving
-     * @param {string} scheme
-     * @returns {byteArray}
-     */
-    _bitOp: function (input, key, func, nullPreserving, scheme) {
-        if (!key || !key.length) key = [0];
-        let result = [],
-            x = null,
-            k = null,
-            o = null;
-
-        for (let i = 0; i < input.length; i++) {
-            k = key[i % key.length];
-            o = input[i];
-            x = nullPreserving && (o === 0 || o === k) ? o : func(o, k);
-            result.push(x);
-            if (scheme !== "Standard" && !(nullPreserving && (o === 0 || o === k))) {
-                switch (scheme) {
-                    case "Input differential":
-                        key[i % key.length] = x;
-                        break;
-                    case "Output differential":
-                        key[i % key.length] = o;
-                        break;
-                }
-            }
-        }
-
-        return result;
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    XOR_PRESERVE_NULLS: false,
-    /**
-     * @constant
-     * @default
-     */
-    XOR_SCHEME: ["Standard", "Input differential", "Output differential"],
-    /**
-     * @constant
-     * @default
-     */
-    KEY_FORMAT: ["Hex", "Base64", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1"],
-
-    /**
-     * XOR operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runXor: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || ""),
-            scheme = args[1],
-            nullPreserving = args[2];
-
-        key = Utils.wordArrayToByteArray(key);
-
-        return BitwiseOp._bitOp(input, key, BitwiseOp._xor, nullPreserving, scheme);
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    XOR_BRUTE_KEY_LENGTH: ["1", "2"],
-    /**
-     * @constant
-     * @default
-     */
-    XOR_BRUTE_SAMPLE_LENGTH: 100,
-    /**
-     * @constant
-     * @default
-     */
-    XOR_BRUTE_SAMPLE_OFFSET: 0,
-    /**
-     * @constant
-     * @default
-     */
-    XOR_BRUTE_PRINT_KEY: true,
-    /**
-     * @constant
-     * @default
-     */
-    XOR_BRUTE_OUTPUT_HEX: false,
-
-    /**
-     * XOR Brute Force operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runXorBrute: function (input, args) {
-        let keyLength = parseInt(args[0], 10),
-            sampleLength = args[1],
-            sampleOffset = args[2],
-            nullPreserving = args[3],
-            differential = args[4],
-            crib = args[5],
-            printKey = args[6],
-            outputHex = args[7],
-            regex;
-
-        let output = "",
-            result,
-            resultUtf8;
-
-        input = input.slice(sampleOffset, sampleOffset + sampleLength);
-
-        if (crib !== "") {
-            regex = new RegExp(crib, "im");
-        }
-
-
-        for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
-            result = BitwiseOp._bitOp(input, Utils.hexToByteArray(key.toString(16)), BitwiseOp._xor, nullPreserving, differential);
-            resultUtf8 = Utils.byteArrayToUtf8(result);
-            if (crib !== "" && resultUtf8.search(regex) === -1) continue;
-            if (printKey) output += "Key = " + Utils.hex(key, (2*keyLength)) + ": ";
-            if (outputHex)
-                output += Utils.byteArrayToHex(result) + "\n";
-            else
-                output += Utils.printable(resultUtf8, false) + "\n";
-            if (printKey) output += "\n";
-        }
-        return output;
-    },
-
-
-    /**
-     * NOT operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runNot: function (input, args) {
-        return BitwiseOp._bitOp(input, null, BitwiseOp._not);
-    },
-
-
-    /**
-     * AND operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runAnd: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
-
-        return BitwiseOp._bitOp(input, key, BitwiseOp._and);
-    },
-
-
-    /**
-     * OR operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runOr: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
-
-        return BitwiseOp._bitOp(input, key, BitwiseOp._or);
-    },
-
-
-    /**
-     * ADD operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runAdd: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
-
-        return BitwiseOp._bitOp(input, key, BitwiseOp._add);
-    },
-
-
-    /**
-     * SUB operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runSub: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
-
-        return BitwiseOp._bitOp(input, key, BitwiseOp._sub);
-    },
-
-
-    /**
-     * XOR bitwise calculation.
-     *
-     * @private
-     * @param {number} operand
-     * @param {number} key
-     * @returns {number}
-     */
-    _xor: function (operand, key) {
-        return operand ^ key;
-    },
-
-
-    /**
-     * NOT bitwise calculation.
-     *
-     * @private
-     * @param {number} operand
-     * @returns {number}
-     */
-    _not: function (operand, _) {
-        return ~operand & 0xff;
-    },
-
-
-    /**
-     * AND bitwise calculation.
-     *
-     * @private
-     * @param {number} operand
-     * @param {number} key
-     * @returns {number}
-     */
-    _and: function (operand, key) {
-        return operand & key;
-    },
-
-
-    /**
-     * OR bitwise calculation.
-     *
-     * @private
-     * @param {number} operand
-     * @param {number} key
-     * @returns {number}
-     */
-    _or: function (operand, key) {
-        return operand | key;
-    },
-
-
-    /**
-     * ADD bitwise calculation.
-     *
-     * @private
-     * @param {number} operand
-     * @param {number} key
-     * @returns {number}
-     */
-    _add: function (operand, key) {
-        return (operand + key) % 256;
-    },
-
-
-    /**
-     * SUB bitwise calculation.
-     *
-     * @private
-     * @param {number} operand
-     * @param {number} key
-     * @returns {number}
-     */
-    _sub: function (operand, key) {
-        const result = operand - key;
-        return (result < 0) ? 256 + result : result;
-    },
-
-};
-
-export default BitwiseOp;

+ 101 - 0
src/core/operations/BlowfishDecrypt.mjs

@@ -0,0 +1,101 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import OperationError from "../errors/OperationError";
+import { Blowfish } from "../vendor/Blowfish";
+import { toBase64 } from "../lib/Base64";
+import { toHexFast } from "../lib/Hex";
+
+/**
+ * Lookup table for Blowfish output types.
+ */
+const BLOWFISH_OUTPUT_TYPE_LOOKUP = {
+    Base64: 0, Hex: 1, String: 2, Raw: 3
+};
+/**
+ * Lookup table for Blowfish modes.
+ */
+const BLOWFISH_MODE_LOOKUP = {
+    ECB: 0, CBC: 1, PCBC: 2, CFB: 3, OFB: 4, CTR: 5
+};
+
+/**
+ * Blowfish Decrypt operation
+ */
+class BlowfishDecrypt extends Operation {
+
+    /**
+     * BlowfishDecrypt constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Blowfish Decrypt";
+        this.module = "Ciphers";
+        this.description = "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.";
+        this.infoURL = "https://wikipedia.org/wiki/Blowfish_(cipher)";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Key",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "IV",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "Mode",
+                "type": "option",
+                "value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
+            },
+            {
+                "name": "Input",
+                "type": "option",
+                "value": ["Hex", "Base64", "Raw"]
+            },
+            {
+                "name": "Output",
+                "type": "option",
+                "value": ["Raw", "Hex"]
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const key = Utils.convertToByteString(args[0].string, args[0].option),
+            iv = Utils.convertToByteArray(args[1].string, args[1].option),
+            [,, mode, inputType, outputType] = args;
+
+        if (key.length === 0) throw new OperationError("Enter a key");
+
+        input = inputType === "Raw" ? Utils.strToByteArray(input) : input;
+
+        Blowfish.setIV(toBase64(iv), 0);
+
+        const result = Blowfish.decrypt(input, key, {
+            outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.
+            cipherMode: BLOWFISH_MODE_LOOKUP[mode]
+        });
+
+        return outputType === "Hex" ? toHexFast(Utils.strToByteArray(result)) : result;
+    }
+
+}
+
+export default BlowfishDecrypt;

+ 102 - 0
src/core/operations/BlowfishEncrypt.mjs

@@ -0,0 +1,102 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import OperationError from "../errors/OperationError";
+import { Blowfish } from "../vendor/Blowfish";
+import { toBase64 } from "../lib/Base64";
+
+/**
+ * Lookup table for Blowfish output types.
+ */
+const BLOWFISH_OUTPUT_TYPE_LOOKUP = {
+    Base64: 0, Hex: 1, String: 2, Raw: 3
+};
+
+/**
+ * Lookup table for Blowfish modes.
+ */
+const BLOWFISH_MODE_LOOKUP = {
+    ECB: 0, CBC: 1, PCBC: 2, CFB: 3, OFB: 4, CTR: 5
+};
+
+
+/**
+ * Blowfish Encrypt operation
+ */
+class BlowfishEncrypt extends Operation {
+
+    /**
+     * BlowfishEncrypt constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Blowfish Encrypt";
+        this.module = "Ciphers";
+        this.description = "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.";
+        this.infoURL = "https://wikipedia.org/wiki/Blowfish_(cipher)";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Key",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "IV",
+                "type": "toggleString",
+                "value": "",
+                "toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
+            },
+            {
+                "name": "Mode",
+                "type": "option",
+                "value": ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"]
+            },
+            {
+                "name": "Input",
+                "type": "option",
+                "value": ["Raw", "Hex"]
+            },
+            {
+                "name": "Output",
+                "type": "option",
+                "value": ["Hex", "Base64", "Raw"]
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const key = Utils.convertToByteString(args[0].string, args[0].option),
+            iv = Utils.convertToByteArray(args[1].string, args[1].option),
+            [,, mode, inputType, outputType] = args;
+
+        if (key.length === 0) throw new OperationError("Enter a key");
+
+        input = Utils.convertToByteString(input, inputType);
+
+        Blowfish.setIV(toBase64(iv), 0);
+
+        const enc = Blowfish.encrypt(input, key, {
+            outputType: BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
+            cipherMode: BLOWFISH_MODE_LOOKUP[mode]
+        });
+
+        return outputType === "Raw" ? Utils.byteArrayToChars(enc) : enc;
+    }
+
+}
+
+export default BlowfishEncrypt;

+ 0 - 427
src/core/operations/ByteRepr.js

@@ -1,427 +0,0 @@
-/* globals app */
-import Utils from "../Utils.js";
-
-
-/**
- * Byte representation operations.
- *
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- *
- * @namespace
- */
-const ByteRepr = {
-
-    /**
-     * @constant
-     * @default
-     */
-    DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"],
-    /**
-     * @constant
-     * @default
-     */
-    HEX_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"],
-    /**
-     * @constant
-     * @default
-     */
-    BIN_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "None"],
-
-    /**
-     * To Hex operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runToHex: function(input, args) {
-        const delim = Utils.charRep[args[0] || "Space"];
-        return Utils.toHex(input, delim, 2);
-    },
-
-
-    /**
-     * From Hex operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFromHex: function(input, args) {
-        const delim = args[0] || "Space";
-        return Utils.fromHex(input, delim, 2);
-    },
-
-
-    /**
-     * To Octal operation.
-     *
-     * @author Matt C [matt@artemisbot.pw]
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runToOct: function(input, args) {
-        const delim = Utils.charRep[args[0] || "Space"];
-        return input.map(val => val.toString(8)).join(delim);
-    },
-
-
-    /**
-     * From Octal operation.
-     *
-     * @author Matt C [matt@artemisbot.pw]
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFromOct: function(input, args) {
-        const delim = Utils.charRep[args[0] || "Space"];
-        if (input.length === 0) return [];
-        return input.split(delim).map(val => parseInt(val, 8));
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    CHARCODE_BASE: 16,
-
-    /**
-     * To Charcode operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runToCharcode: function(input, args) {
-        let delim = Utils.charRep[args[0] || "Space"],
-            base = args[1],
-            output = "",
-            padding = 2,
-            ordinal;
-
-        if (base < 2 || base > 36) {
-            throw "Error: Base argument must be between 2 and 36";
-        }
-
-        for (let i = 0; i < input.length; i++) {
-            ordinal = Utils.ord(input[i]);
-
-            if (base === 16) {
-                if (ordinal < 256) padding = 2;
-                else if (ordinal < 65536) padding = 4;
-                else if (ordinal < 16777216) padding = 6;
-                else if (ordinal < 4294967296) padding = 8;
-                else padding = 2;
-
-                if (padding > 2 && app) app.options.attemptHighlight = false;
-
-                output += Utils.hex(ordinal, padding) + delim;
-            } else {
-                if (app) app.options.attemptHighlight = false;
-                output += ordinal.toString(base) + delim;
-            }
-        }
-
-        return output.slice(0, -delim.length);
-    },
-
-
-    /**
-     * From Charcode operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFromCharcode: function(input, args) {
-        let delim = Utils.charRep[args[0] || "Space"],
-            base = args[1],
-            bites = input.split(delim),
-            i = 0;
-
-        if (base < 2 || base > 36) {
-            throw "Error: Base argument must be between 2 and 36";
-        }
-
-        if (base !== 16 && app) {
-            app.options.attemptHighlight = false;
-        }
-
-        // Split into groups of 2 if the whole string is concatenated and
-        // too long to be a single character
-        if (bites.length === 1 && input.length > 17) {
-            bites = [];
-            for (i = 0; i < input.length; i += 2) {
-                bites.push(input.slice(i, i+2));
-            }
-        }
-
-        let latin1 = "";
-        for (i = 0; i < bites.length; i++) {
-            latin1 += Utils.chr(parseInt(bites[i], base));
-        }
-        return Utils.strToByteArray(latin1);
-    },
-
-
-    /**
-     * Highlight to hex
-     *
-     * @param {Object[]} pos
-     * @param {number} pos[].start
-     * @param {number} pos[].end
-     * @param {Object[]} args
-     * @returns {Object[]} pos
-     */
-    highlightTo: function(pos, args) {
-        let delim = Utils.charRep[args[0] || "Space"],
-            len = delim === "\r\n" ? 1 : delim.length;
-
-        pos[0].start = pos[0].start * (2 + len);
-        pos[0].end = pos[0].end * (2 + len) - len;
-
-        // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
-        if (delim === "0x" || delim === "\\x") {
-            pos[0].start += 2;
-            pos[0].end   += 2;
-        }
-        return pos;
-    },
-
-
-    /**
-     * Highlight to hex
-     *
-     * @param {Object[]} pos
-     * @param {number} pos[].start
-     * @param {number} pos[].end
-     * @param {Object[]} args
-     * @returns {Object[]} pos
-     */
-    highlightFrom: function(pos, args) {
-        let delim = Utils.charRep[args[0] || "Space"],
-            len = delim === "\r\n" ? 1 : delim.length,
-            width = len + 2;
-
-        // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
-        if (delim === "0x" || delim === "\\x") {
-            if (pos[0].start > 1) pos[0].start -= 2;
-            else pos[0].start = 0;
-            if (pos[0].end > 1) pos[0].end -= 2;
-            else pos[0].end = 0;
-        }
-
-        pos[0].start = pos[0].start === 0 ? 0 : Math.round(pos[0].start / width);
-        pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / width);
-        return pos;
-    },
-
-
-    /**
-     * To Decimal operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runToDecimal: function(input, args) {
-        const delim = Utils.charRep[args[0]];
-        return input.join(delim);
-    },
-
-
-    /**
-     * From Decimal operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFromDecimal: function(input, args) {
-        const delim = Utils.charRep[args[0]];
-        let byteStr = input.split(delim), output = [];
-        if (byteStr[byteStr.length-1] === "")
-            byteStr = byteStr.slice(0, byteStr.length-1);
-
-        for (let i = 0; i < byteStr.length; i++) {
-            output[i] = parseInt(byteStr[i], 10);
-        }
-        return output;
-    },
-
-
-    /**
-     * To Binary operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runToBinary: function(input, args) {
-        let delim = Utils.charRep[args[0] || "Space"],
-            output = "",
-            padding = 8;
-
-        for (let i = 0; i < input.length; i++) {
-            output += Utils.pad(input[i].toString(2), padding) + delim;
-        }
-
-        if (delim.length) {
-            return output.slice(0, -delim.length);
-        } else {
-            return output;
-        }
-    },
-
-
-    /**
-     * From Binary operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFromBinary: function(input, args) {
-        if (args[0] !== "None") {
-            const delimRegex = Utils.regexRep[args[0] || "Space"];
-            input = input.replace(delimRegex, "");
-        }
-
-        const output = [];
-        const byteLen = 8;
-        for (let i = 0; i < input.length; i += byteLen) {
-            output.push(parseInt(input.substr(i, byteLen), 2));
-        }
-        return output;
-    },
-
-
-    /**
-     * Highlight to binary
-     *
-     * @param {Object[]} pos
-     * @param {number} pos[].start
-     * @param {number} pos[].end
-     * @param {Object[]} args
-     * @returns {Object[]} pos
-     */
-    highlightToBinary: function(pos, args) {
-        const delim = Utils.charRep[args[0] || "Space"];
-        pos[0].start = pos[0].start * (8 + delim.length);
-        pos[0].end = pos[0].end * (8 + delim.length) - delim.length;
-        return pos;
-    },
-
-
-    /**
-     * Highlight from binary
-     *
-     * @param {Object[]} pos
-     * @param {number} pos[].start
-     * @param {number} pos[].end
-     * @param {Object[]} args
-     * @returns {Object[]} pos
-     */
-    highlightFromBinary: function(pos, args) {
-        const delim = Utils.charRep[args[0] || "Space"];
-        pos[0].start = pos[0].start === 0 ? 0 : Math.floor(pos[0].start / (8 + delim.length));
-        pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / (8 + delim.length));
-        return pos;
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    HEX_CONTENT_CONVERT_WHICH: ["Only special chars", "Only special chars including spaces", "All chars"],
-    /**
-     * @constant
-     * @default
-     */
-    HEX_CONTENT_SPACES_BETWEEN_BYTES: false,
-
-    /**
-     * To Hex Content operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runToHexContent: function(input, args) {
-        const convert = args[0];
-        const spaces = args[1];
-        if (convert === "All chars") {
-            let result = "|" + Utils.toHex(input) + "|";
-            if (!spaces) result = result.replace(/ /g, "");
-            return result;
-        }
-
-        let output = "",
-            inHex = false,
-            convertSpaces = convert === "Only special chars including spaces",
-            b;
-        for (let i = 0; i < input.length; i++) {
-            b = input[i];
-            if ((b === 32 && convertSpaces) || (b < 48 && b !== 32) || (b > 57 && b < 65) || (b > 90 && b < 97) || b > 122) {
-                if (!inHex) {
-                    output += "|";
-                    inHex = true;
-                } else if (spaces) output += " ";
-                output += Utils.toHex([b]);
-            } else {
-                if (inHex) {
-                    output += "|";
-                    inHex = false;
-                }
-                output += Utils.chr(input[i]);
-            }
-        }
-        if (inHex) output += "|";
-        return output;
-    },
-
-
-    /**
-     * From Hex Content operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runFromHexContent: function(input, args) {
-        const regex = /\|([a-f\d ]{2,})\|/gi;
-        let output = [], m, i = 0;
-        while ((m = regex.exec(input))) {
-            // Add up to match
-            for (; i < m.index;)
-                output.push(Utils.ord(input[i++]));
-
-            // Add match
-            const bytes = Utils.fromHex(m[1]);
-            if (bytes) {
-                for (let a = 0; a < bytes.length;)
-                    output.push(bytes[a++]);
-            } else {
-                // Not valid hex, print as normal
-                for (; i < regex.lastIndex;)
-                    output.push(Utils.ord(input[i++]));
-            }
-
-            i = regex.lastIndex;
-        }
-        // Add all after final match
-        for (; i < input.length;)
-            output.push(Utils.ord(input[i++]));
-
-        return output;
-    },
-
-};
-
-export default ByteRepr;

+ 56 - 0
src/core/operations/Bzip2Decompress.mjs

@@ -0,0 +1,56 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import bzip2 from "../vendor/bzip2";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Bzip2 Decompress operation
+ */
+class Bzip2Decompress extends Operation {
+
+    /**
+     * Bzip2Decompress constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bzip2 Decompress";
+        this.module = "Compression";
+        this.description = "Decompresses data using the Bzip2 algorithm.";
+        this.infoURL = "https://wikipedia.org/wiki/Bzip2";
+        this.inputType = "byteArray";
+        this.outputType = "string";
+        this.args = [];
+        this.patterns = [
+            {
+                "match": "^\\x42\\x5a\\x68",
+                "flags": "",
+                "args": []
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const compressed = new Uint8Array(input);
+
+        try {
+            const bzip2Reader = bzip2.array(compressed);
+            return bzip2.simple(bzip2Reader);
+        } catch (err) {
+            throw new OperationError(err);
+        }
+    }
+
+}
+
+export default Bzip2Decompress;

+ 41 - 0
src/core/operations/CRC16Checksum.mjs

@@ -0,0 +1,41 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import JSCRC from "js-crc";
+
+/**
+ * CRC-16 Checksum operation
+ */
+class CRC16Checksum extends Operation {
+
+    /**
+     * CRC16Checksum constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "CRC-16 Checksum";
+        this.module = "Crypto";
+        this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.<br><br>The CRC was invented by W. Wesley Peterson in 1961.";
+        this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check";
+        this.inputType = "ArrayBuffer";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {ArrayBuffer} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        return JSCRC.crc16(input);
+    }
+
+}
+
+export default CRC16Checksum;

+ 41 - 0
src/core/operations/CRC32Checksum.mjs

@@ -0,0 +1,41 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import JSCRC from "js-crc";
+
+/**
+ * CRC-32 Checksum operation
+ */
+class CRC32Checksum extends Operation {
+
+    /**
+     * CRC32Checksum constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "CRC-32 Checksum";
+        this.module = "Crypto";
+        this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.<br><br>The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975.";
+        this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check";
+        this.inputType = "ArrayBuffer";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {ArrayBuffer} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        return JSCRC.crc32(input);
+    }
+
+}
+
+export default CRC32Checksum;

+ 47 - 0
src/core/operations/CSSBeautify.mjs

@@ -0,0 +1,47 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import vkbeautify from "vkbeautify";
+import Operation from "../Operation";
+
+/**
+ * CSS Beautify operation
+ */
+class CSSBeautify extends Operation {
+
+    /**
+     * CSSBeautify constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "CSS Beautify";
+        this.module = "Code";
+        this.description = "Indents and prettifies Cascading Style Sheets (CSS) code.";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Indent string",
+                "type": "binaryShortString",
+                "value": "\\t"
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const indentStr = args[0];
+        return vkbeautify.css(input, indentStr);
+    }
+
+}
+
+export default CSSBeautify;

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov