Bläddra i källkod

Merge branch 'master' into features/add-pgp-kbpgp

Matt C 7 år sedan
förälder
incheckning
bfbefb7318
73 ändrade filer med 18808 tillägg och 15417 borttagningar
  1. 1 1
      .eslintrc.json
  2. 1 12
      .github/ISSUE_TEMPLATE.md
  3. 7 1
      .travis.yml
  4. 16 13
      README.md
  5. 10813 10552
      package-lock.json
  6. 122 112
      package.json
  7. 22 10
      src/core/Chef.js
  8. 16 2
      src/core/ChefWorker.js
  9. 99 31
      src/core/Dish.js
  10. 44 20
      src/core/FlowControl.js
  11. 6 0
      src/core/Recipe.js
  12. 130 138
      src/core/Utils.js
  13. 16 3
      src/core/config/Categories.js
  14. 3998 3930
      src/core/config/OperationConfig.js
  15. 0 1
      src/core/config/modules/CharEnc.js
  16. 4 2
      src/core/config/modules/Ciphers.js
  17. 13 6
      src/core/config/modules/Default.js
  18. 3 1
      src/core/config/modules/OpModules.js
  19. 23 0
      src/core/config/modules/URL.js
  20. 253 0
      src/core/operations/Arithmetic.js
  21. 9 8
      src/core/operations/BCD.js
  22. 7 5
      src/core/operations/Base.js
  23. 2 2
      src/core/operations/Base64.js
  24. 6 12
      src/core/operations/BitwiseOp.js
  25. 4 4
      src/core/operations/ByteRepr.js
  26. 373 173
      src/core/operations/Cipher.js
  27. 16 15
      src/core/operations/Code.js
  28. 3 3
      src/core/operations/Compress.js
  29. 20 21
      src/core/operations/Convert.js
  30. 32 5
      src/core/operations/Entropy.js
  31. 10 8
      src/core/operations/FileType.js
  32. 3 3
      src/core/operations/HTML.js
  33. 26 10
      src/core/operations/Hash.js
  34. 7 6
      src/core/operations/Hexdump.js
  35. 3 4
      src/core/operations/Image.js
  36. 1 1
      src/core/operations/MS.js
  37. 17 6
      src/core/operations/NetBIOS.js
  38. 62 6
      src/core/operations/Numberwang.js
  39. 1 0
      src/core/operations/OTP.js
  40. 160 0
      src/core/operations/PHP.js
  41. 4 5
      src/core/operations/PublicKey.js
  42. 2 2
      src/core/operations/SeqUtils.js
  43. 28 23
      src/core/operations/Tidy.js
  44. 27 47
      src/core/operations/URL.js
  45. 14 19
      src/core/operations/UUID.js
  46. 9 5
      src/web/App.js
  47. 217 0
      src/web/BindingsWaiter.js
  48. 4 7
      src/web/HighlighterWaiter.js
  49. 138 57
      src/web/InputWaiter.js
  50. 54 0
      src/web/LoaderWorker.js
  51. 18 6
      src/web/Manager.js
  52. 21 2
      src/web/OptionsWaiter.js
  53. 211 49
      src/web/OutputWaiter.js
  54. 4 2
      src/web/RecipeWaiter.js
  55. 25 5
      src/web/WorkerWaiter.js
  56. 104 34
      src/web/html/index.html
  57. 11 11
      src/web/index.js
  58. BIN
      src/web/static/images/copy-16x16.png
  59. BIN
      src/web/static/images/file-128x128.png
  60. BIN
      src/web/static/images/file-32x32.png
  61. 1 0
      src/web/static/images/fork_me.png
  62. 53 0
      src/web/stylesheets/components/_pane.css
  63. 22 1
      src/web/stylesheets/layout/_io.css
  64. 11 1
      src/web/stylesheets/utils/_overrides.css
  65. 5 0
      test/index.js
  66. 1298 0
      test/tests/operations/Cipher.js
  67. 22 0
      test/tests/operations/Code.js
  68. 27 11
      test/tests/operations/FlowControl.js
  69. 34 0
      test/tests/operations/NetBIOS.js
  70. 23 0
      test/tests/operations/OTP.js
  71. 68 0
      test/tests/operations/PHP.js
  72. 2 2
      test/tests/operations/SeqUtils.js
  73. 2 1
      webpack.config.js

+ 1 - 1
.eslintrc.json

@@ -35,7 +35,6 @@
         }],
         }],
 
 
         // disable rules from base configurations
         // disable rules from base configurations
-        "no-console": "off",
         "no-control-regex": "off",
         "no-control-regex": "off",
 
 
         // stylistic conventions
         // stylistic conventions
@@ -90,6 +89,7 @@
         "$": false,
         "$": false,
         "jQuery": false,
         "jQuery": false,
         "moment": false,
         "moment": false,
+        "log": false,
 
 
         "COMPILE_TIME": false,
         "COMPILE_TIME": false,
         "COMPILE_MSG": false,
         "COMPILE_MSG": false,

+ 1 - 12
.github/ISSUE_TEMPLATE.md

@@ -5,21 +5,10 @@
 <!-- Misc: -->
 <!-- Misc: -->
 
 
 ### Summary
 ### 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
 ### Example
 <!-- If describing a bug, tell us what happens instead of the expected behavior -->
 <!-- If describing a bug, tell us what happens instead of the expected behavior -->
 <!-- Include a link that triggers the bug if possible -->
 <!-- Include a link that triggers the bug if possible -->
 <!-- If you are requesting a new operation, include example input and output -->
 <!-- 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]()

+ 7 - 1
.travis.yml

@@ -39,4 +39,10 @@ deploy:
     on:
     on:
       tags: true
       tags: true
       branch: master
       branch: master
-
+notifications:
+    webhooks:
+        urls:
+            - https://webhooks.gitter.im/e/83c143a6822e218d5b34
+        on_success: change
+        on_failure: always
+        on_start: never

+ 16 - 13
README.md

@@ -2,9 +2,11 @@
 
 
 [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef)
 [![Build Status](https://travis-ci.org/gchq/CyberChef.svg?branch=master)](https://travis-ci.org/gchq/CyberChef)
 [![dependencies Status](https://david-dm.org/gchq/CyberChef/status.svg)](https://david-dm.org/gchq/CyberChef)
 [![dependencies Status](https://david-dm.org/gchq/CyberChef/status.svg)](https://david-dm.org/gchq/CyberChef)
-[![npm](http://img.shields.io/npm/v/cyberchef.svg)](https://www.npmjs.com/package/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://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)
 [![](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*
 #### *The Cyber Swiss Army Knife*
 
 
@@ -25,7 +27,7 @@ Cryptographic operations in CyberChef should not be relied upon to provide secur
 
 
 There are four main areas in CyberChef:
 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.
+ 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.
  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.
  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 can 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.
@@ -40,32 +42,32 @@ You can use as many operations as you like in simple or complex ways. Some examp
  - [Display multiple timestamps as full dates][7]
  - [Display multiple timestamps as full dates][7]
  - [Carry out different operations on data of different types][8]
  - [Carry out different operations on data of different types][8]
  - [Use parts of the input as arguments to operations][9]
  - [Use parts of the input as arguments to operations][9]
+ - [Perform AES decryption, extracting the IV from the beginning of the cipher stream][10]
 
 
 
 
 ## Features
 ## Features
 
 
  - Drag and drop
  - Drag and drop
      - Operations can be dragged in and out of the recipe list, or reorganised.
      - 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 can be dragged over the input box to load them directly into the browser.
  - Auto Bake
  - 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).
      - 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.
  - Breakpoints
  - Breakpoints
      - You can set breakpoints on any operation in your recipe to pause execution before running it.
      - 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.
      - 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
  - 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
  - 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.
      - 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
  - 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][10]).
+     - 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
  - 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
  - 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
 ## Browser support
@@ -98,6 +100,7 @@ CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/lice
   [5]: https://gchq.github.io/CyberChef/#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw
   [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
   [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
   [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',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
+  [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
   [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=XOR(%7B'option':'Hex','string':'3a'%7D,'',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4
+  [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,'',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4

+ 10813 - 10552
package-lock.json

@@ -1,10552 +1,10813 @@
-{
-  "name": "cyberchef",
-  "version": "6.4.0",
-  "lockfileVersion": 1,
-  "requires": true,
-  "dependencies": {
-    "HTML_CodeSniffer": {
-      "version": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
-      "dev": true
-    },
-    "JSONSelect": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
-      "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
-    },
-    "abab": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
-      "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=",
-      "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.4",
-      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
-      "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
-      "dev": true,
-      "requires": {
-        "mime-types": "2.1.17",
-        "negotiator": "0.6.1"
-      }
-    },
-    "access-sniff": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/access-sniff/-/access-sniff-3.0.1.tgz",
-      "integrity": "sha1-IJ4W63DAlaA79/yCnsrLfHeS9e4=",
-      "dev": true,
-      "requires": {
-        "HTML_CodeSniffer": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
-        "axios": "0.9.1",
-        "bluebird": "3.5.0",
-        "chalk": "1.1.3",
-        "commander": "2.11.0",
-        "glob": "7.1.2",
-        "jsdom": "9.12.0",
-        "mkdirp": "0.5.1",
-        "phantomjs-prebuilt": "2.1.15",
-        "rc": "1.2.1",
-        "underscore": "1.8.3",
-        "unixify": "0.2.1",
-        "validator": "5.7.0"
-      },
-      "dependencies": {
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        },
-        "underscore": {
-          "version": "1.8.3",
-          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
-          "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
-          "dev": true
-        }
-      }
-    },
-    "acorn": {
-      "version": "4.0.13",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
-      "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
-      "dev": true
-    },
-    "acorn-dynamic-import": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
-      "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
-      "dev": true,
-      "requires": {
-        "acorn": "4.0.13"
-      }
-    },
-    "acorn-globals": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
-      "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
-      "dev": true,
-      "requires": {
-        "acorn": "4.0.13"
-      }
-    },
-    "acorn-jsx": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
-      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
-      "dev": true,
-      "requires": {
-        "acorn": "3.3.0"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
-          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
-          "dev": true
-        }
-      }
-    },
-    "ajv": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz",
-      "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=",
-      "dev": true,
-      "requires": {
-        "co": "4.6.0",
-        "fast-deep-equal": "1.0.0",
-        "json-schema-traverse": "0.3.1",
-        "json-stable-stringify": "1.0.1"
-      }
-    },
-    "ajv-keywords": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz",
-      "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=",
-      "dev": true
-    },
-    "align-text": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
-      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
-      "dev": true,
-      "requires": {
-        "kind-of": "3.2.2",
-        "longest": "1.0.1",
-        "repeat-string": "1.6.1"
-      }
-    },
-    "alphanum-sort": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
-      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
-      "dev": true
-    },
-    "amdefine": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
-      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
-    },
-    "ansi-escapes": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
-      "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==",
-      "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=",
-      "dev": true
-    },
-    "ansi-styles": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-      "dev": true
-    },
-    "anymatch": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
-      "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
-      "dev": true,
-      "requires": {
-        "micromatch": "2.3.11",
-        "normalize-path": "2.1.1"
-      }
-    },
-    "argparse": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
-      "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
-      "dev": true,
-      "requires": {
-        "sprintf-js": "1.0.3"
-      }
-    },
-    "arr-diff": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
-      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
-      "dev": true,
-      "requires": {
-        "arr-flatten": "1.1.0"
-      }
-    },
-    "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
-    },
-    "array-equal": {
-      "version": "1.0.0",
-      "resolved": "https://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.1",
-      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz",
-      "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=",
-      "dev": true
-    },
-    "array-includes": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
-      "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
-      "dev": true,
-      "requires": {
-        "define-properties": "1.1.2",
-        "es-abstract": "1.9.0"
-      }
-    },
-    "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.3"
-      }
-    },
-    "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.2.1",
-      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
-      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
-      "dev": true
-    },
-    "arrify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
-      "dev": true
-    },
-    "asap": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
-      "dev": true,
-      "optional": true
-    },
-    "asn1": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
-      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
-      "dev": true
-    },
-    "asn1.js": {
-      "version": "4.9.1",
-      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
-      "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=",
-      "dev": true,
-      "requires": {
-        "bn.js": "4.11.8",
-        "inherits": "2.0.3",
-        "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"
-      }
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true
-    },
-    "async": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
-      "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
-      "dev": true,
-      "requires": {
-        "lodash": "4.17.4"
-      }
-    },
-    "async-each": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
-      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
-      "dev": true
-    },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
-    },
-    "autoprefixer": {
-      "version": "6.7.7",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
-      "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
-      "dev": true,
-      "requires": {
-        "browserslist": "1.7.7",
-        "caniuse-db": "1.0.30000741",
-        "normalize-range": "0.1.2",
-        "num2fraction": "1.2.2",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      },
-      "dependencies": {
-        "browserslist": {
-          "version": "1.7.7",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
-          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
-          "dev": true,
-          "requires": {
-            "caniuse-db": "1.0.30000741",
-            "electron-to-chromium": "1.3.24"
-          }
-        }
-      }
-    },
-    "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.6.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
-      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
-      "dev": true
-    },
-    "axios": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-0.9.1.tgz",
-      "integrity": "sha1-lWCLFkR+4psDNYmFTD/H7iwGv24=",
-      "dev": true,
-      "requires": {
-        "follow-redirects": "0.0.7"
-      }
-    },
-    "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=",
-      "dev": true,
-      "requires": {
-        "chalk": "1.1.3",
-        "esutils": "2.0.2",
-        "js-tokens": "3.0.2"
-      }
-    },
-    "babel-core": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
-      "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
-      "dev": true,
-      "requires": {
-        "babel-code-frame": "6.26.0",
-        "babel-generator": "6.26.0",
-        "babel-helpers": "6.24.1",
-        "babel-messages": "6.23.0",
-        "babel-register": "6.26.0",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0",
-        "babylon": "6.18.0",
-        "convert-source-map": "1.5.1",
-        "debug": "2.6.9",
-        "json5": "0.5.1",
-        "lodash": "4.17.4",
-        "minimatch": "3.0.4",
-        "path-is-absolute": "1.0.1",
-        "private": "0.1.7",
-        "slash": "1.0.0",
-        "source-map": "0.5.7"
-      }
-    },
-    "babel-generator": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
-      "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
-      "dev": true,
-      "requires": {
-        "babel-messages": "6.23.0",
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0",
-        "detect-indent": "4.0.0",
-        "jsesc": "1.3.0",
-        "lodash": "4.17.4",
-        "source-map": "0.5.7",
-        "trim-right": "1.0.1"
-      }
-    },
-    "babel-helper-bindify-decorators": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz",
-      "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-builder-binary-assignment-operator-visitor": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
-      "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
-      "dev": true,
-      "requires": {
-        "babel-helper-explode-assignable-expression": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-call-delegate": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
-      "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
-      "dev": true,
-      "requires": {
-        "babel-helper-hoist-variables": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-define-map": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
-      "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
-      "dev": true,
-      "requires": {
-        "babel-helper-function-name": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0",
-        "lodash": "4.17.4"
-      }
-    },
-    "babel-helper-explode-assignable-expression": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
-      "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-explode-class": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz",
-      "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=",
-      "dev": true,
-      "requires": {
-        "babel-helper-bindify-decorators": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-function-name": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
-      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
-      "dev": true,
-      "requires": {
-        "babel-helper-get-function-arity": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-get-function-arity": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
-      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-hoist-variables": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
-      "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-optimise-call-expression": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
-      "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-regex": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
-      "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0",
-        "lodash": "4.17.4"
-      }
-    },
-    "babel-helper-remap-async-to-generator": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
-      "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
-      "dev": true,
-      "requires": {
-        "babel-helper-function-name": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helper-replace-supers": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
-      "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
-      "dev": true,
-      "requires": {
-        "babel-helper-optimise-call-expression": "6.24.1",
-        "babel-messages": "6.23.0",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-helpers": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
-      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0"
-      }
-    },
-    "babel-loader": {
-      "version": "7.1.2",
-      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz",
-      "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==",
-      "dev": true,
-      "requires": {
-        "find-cache-dir": "1.0.0",
-        "loader-utils": "1.1.0",
-        "mkdirp": "0.5.1"
-      }
-    },
-    "babel-messages": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
-      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-check-es2015-constants": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
-      "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-syntax-async-functions": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
-      "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
-      "dev": true
-    },
-    "babel-plugin-syntax-async-generators": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
-      "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
-      "dev": true
-    },
-    "babel-plugin-syntax-class-constructor-call": {
-      "version": "6.18.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
-      "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=",
-      "dev": true
-    },
-    "babel-plugin-syntax-class-properties": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
-      "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
-      "dev": true
-    },
-    "babel-plugin-syntax-decorators": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
-      "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
-      "dev": true
-    },
-    "babel-plugin-syntax-do-expressions": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
-      "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=",
-      "dev": true
-    },
-    "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-syntax-exponentiation-operator": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
-      "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
-      "dev": true
-    },
-    "babel-plugin-syntax-export-extensions": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
-      "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=",
-      "dev": true
-    },
-    "babel-plugin-syntax-function-bind": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
-      "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=",
-      "dev": true
-    },
-    "babel-plugin-syntax-object-rest-spread": {
-      "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
-      "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
-      "dev": true
-    },
-    "babel-plugin-syntax-trailing-function-commas": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
-      "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
-      "dev": true
-    },
-    "babel-plugin-transform-async-generator-functions": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz",
-      "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=",
-      "dev": true,
-      "requires": {
-        "babel-helper-remap-async-to-generator": "6.24.1",
-        "babel-plugin-syntax-async-generators": "6.13.0",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-async-to-generator": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
-      "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
-      "dev": true,
-      "requires": {
-        "babel-helper-remap-async-to-generator": "6.24.1",
-        "babel-plugin-syntax-async-functions": "6.13.0",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-class-constructor-call": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz",
-      "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-syntax-class-constructor-call": "6.18.0",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-class-properties": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz",
-      "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
-      "dev": true,
-      "requires": {
-        "babel-helper-function-name": "6.24.1",
-        "babel-plugin-syntax-class-properties": "6.13.0",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-decorators": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz",
-      "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=",
-      "dev": true,
-      "requires": {
-        "babel-helper-explode-class": "6.24.1",
-        "babel-plugin-syntax-decorators": "6.13.0",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-do-expressions": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz",
-      "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-syntax-do-expressions": "6.13.0",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-arrow-functions": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
-      "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-block-scoped-functions": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
-      "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-block-scoping": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
-      "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0",
-        "lodash": "4.17.4"
-      }
-    },
-    "babel-plugin-transform-es2015-classes": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
-      "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
-      "dev": true,
-      "requires": {
-        "babel-helper-define-map": "6.26.0",
-        "babel-helper-function-name": "6.24.1",
-        "babel-helper-optimise-call-expression": "6.24.1",
-        "babel-helper-replace-supers": "6.24.1",
-        "babel-messages": "6.23.0",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-computed-properties": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
-      "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-destructuring": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
-      "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-duplicate-keys": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
-      "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-for-of": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
-      "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-function-name": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
-      "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
-      "dev": true,
-      "requires": {
-        "babel-helper-function-name": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-literals": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
-      "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-modules-amd": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
-      "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-modules-commonjs": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
-      "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-transform-strict-mode": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-modules-systemjs": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
-      "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
-      "dev": true,
-      "requires": {
-        "babel-helper-hoist-variables": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-modules-umd": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
-      "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-object-super": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
-      "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
-      "dev": true,
-      "requires": {
-        "babel-helper-replace-supers": "6.24.1",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-parameters": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
-      "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
-      "dev": true,
-      "requires": {
-        "babel-helper-call-delegate": "6.24.1",
-        "babel-helper-get-function-arity": "6.24.1",
-        "babel-runtime": "6.26.0",
-        "babel-template": "6.26.0",
-        "babel-traverse": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-shorthand-properties": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
-      "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-spread": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
-      "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-sticky-regex": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
-      "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
-      "dev": true,
-      "requires": {
-        "babel-helper-regex": "6.26.0",
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-template-literals": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
-      "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-typeof-symbol": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
-      "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-es2015-unicode-regex": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
-      "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
-      "dev": true,
-      "requires": {
-        "babel-helper-regex": "6.26.0",
-        "babel-runtime": "6.26.0",
-        "regexpu-core": "2.0.0"
-      }
-    },
-    "babel-plugin-transform-exponentiation-operator": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
-      "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
-      "dev": true,
-      "requires": {
-        "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
-        "babel-plugin-syntax-exponentiation-operator": "6.13.0",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-export-extensions": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz",
-      "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-syntax-export-extensions": "6.13.0",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-function-bind": {
-      "version": "6.22.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz",
-      "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-syntax-function-bind": "6.13.0",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-object-rest-spread": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
-      "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-syntax-object-rest-spread": "6.13.0",
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-regenerator": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
-      "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
-      "dev": true,
-      "requires": {
-        "regenerator-transform": "0.10.1"
-      }
-    },
-    "babel-plugin-transform-runtime": {
-      "version": "6.23.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz",
-      "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0"
-      }
-    },
-    "babel-plugin-transform-strict-mode": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
-      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0"
-      }
-    },
-    "babel-polyfill": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
-      "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "core-js": "2.5.1",
-        "regenerator-runtime": "0.10.5"
-      }
-    },
-    "babel-preset-env": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.0.tgz",
-      "integrity": "sha512-OVgtQRuOZKckrILgMA5rvctvFZPv72Gua9Rt006AiPoB0DJKGN07UmaQA+qRrYgK71MVct8fFhT0EyNWYorVew==",
-      "dev": true,
-      "requires": {
-        "babel-plugin-check-es2015-constants": "6.22.0",
-        "babel-plugin-syntax-trailing-function-commas": "6.22.0",
-        "babel-plugin-transform-async-to-generator": "6.24.1",
-        "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
-        "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
-        "babel-plugin-transform-es2015-block-scoping": "6.26.0",
-        "babel-plugin-transform-es2015-classes": "6.24.1",
-        "babel-plugin-transform-es2015-computed-properties": "6.24.1",
-        "babel-plugin-transform-es2015-destructuring": "6.23.0",
-        "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
-        "babel-plugin-transform-es2015-for-of": "6.23.0",
-        "babel-plugin-transform-es2015-function-name": "6.24.1",
-        "babel-plugin-transform-es2015-literals": "6.22.0",
-        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
-        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
-        "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
-        "babel-plugin-transform-es2015-modules-umd": "6.24.1",
-        "babel-plugin-transform-es2015-object-super": "6.24.1",
-        "babel-plugin-transform-es2015-parameters": "6.24.1",
-        "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
-        "babel-plugin-transform-es2015-spread": "6.22.0",
-        "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
-        "babel-plugin-transform-es2015-template-literals": "6.22.0",
-        "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
-        "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
-        "babel-plugin-transform-exponentiation-operator": "6.24.1",
-        "babel-plugin-transform-regenerator": "6.26.0",
-        "browserslist": "2.4.0",
-        "invariant": "2.2.2",
-        "semver": "5.4.1"
-      }
-    },
-    "babel-preset-es2015": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz",
-      "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-check-es2015-constants": "6.22.0",
-        "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
-        "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
-        "babel-plugin-transform-es2015-block-scoping": "6.26.0",
-        "babel-plugin-transform-es2015-classes": "6.24.1",
-        "babel-plugin-transform-es2015-computed-properties": "6.24.1",
-        "babel-plugin-transform-es2015-destructuring": "6.23.0",
-        "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
-        "babel-plugin-transform-es2015-for-of": "6.23.0",
-        "babel-plugin-transform-es2015-function-name": "6.24.1",
-        "babel-plugin-transform-es2015-literals": "6.22.0",
-        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
-        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
-        "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
-        "babel-plugin-transform-es2015-modules-umd": "6.24.1",
-        "babel-plugin-transform-es2015-object-super": "6.24.1",
-        "babel-plugin-transform-es2015-parameters": "6.24.1",
-        "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
-        "babel-plugin-transform-es2015-spread": "6.22.0",
-        "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
-        "babel-plugin-transform-es2015-template-literals": "6.22.0",
-        "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
-        "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
-        "babel-plugin-transform-regenerator": "6.26.0"
-      }
-    },
-    "babel-preset-stage-0": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz",
-      "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-transform-do-expressions": "6.22.0",
-        "babel-plugin-transform-function-bind": "6.22.0",
-        "babel-preset-stage-1": "6.24.1"
-      }
-    },
-    "babel-preset-stage-1": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz",
-      "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-transform-class-constructor-call": "6.24.1",
-        "babel-plugin-transform-export-extensions": "6.22.0",
-        "babel-preset-stage-2": "6.24.1"
-      }
-    },
-    "babel-preset-stage-2": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz",
-      "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-syntax-dynamic-import": "6.18.0",
-        "babel-plugin-transform-class-properties": "6.24.1",
-        "babel-plugin-transform-decorators": "6.24.1",
-        "babel-preset-stage-3": "6.24.1"
-      }
-    },
-    "babel-preset-stage-3": {
-      "version": "6.24.1",
-      "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz",
-      "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=",
-      "dev": true,
-      "requires": {
-        "babel-plugin-syntax-trailing-function-commas": "6.22.0",
-        "babel-plugin-transform-async-generator-functions": "6.24.1",
-        "babel-plugin-transform-async-to-generator": "6.24.1",
-        "babel-plugin-transform-exponentiation-operator": "6.24.1",
-        "babel-plugin-transform-object-rest-spread": "6.26.0"
-      }
-    },
-    "babel-register": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
-      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
-      "dev": true,
-      "requires": {
-        "babel-core": "6.26.0",
-        "babel-runtime": "6.26.0",
-        "core-js": "2.5.1",
-        "home-or-tmp": "2.0.0",
-        "lodash": "4.17.4",
-        "mkdirp": "0.5.1",
-        "source-map-support": "0.4.18"
-      }
-    },
-    "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=",
-      "dev": true,
-      "requires": {
-        "core-js": "2.5.1",
-        "regenerator-runtime": "0.11.0"
-      },
-      "dependencies": {
-        "regenerator-runtime": {
-          "version": "0.11.0",
-          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
-          "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==",
-          "dev": true
-        }
-      }
-    },
-    "babel-template": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
-      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
-      "dev": true,
-      "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=",
-      "dev": true,
-      "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.9",
-        "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=",
-      "dev": true,
-      "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==",
-      "dev": true
-    },
-    "balanced-match": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-      "dev": true
-    },
-    "base64-js": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
-      "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
-      "dev": true
-    },
-    "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.1",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
-      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "tweetnacl": "0.14.5"
-      }
-    },
-    "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
-    },
-    "binary-extensions": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
-      "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
-      "dev": true
-    },
-    "bluebird": {
-      "version": "3.5.0",
-      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
-      "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=",
-      "dev": true
-    },
-    "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-parser": {
-      "version": "1.18.2",
-      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
-      "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
-      "dev": true,
-      "requires": {
-        "bytes": "3.0.0",
-        "content-type": "1.0.4",
-        "debug": "2.6.9",
-        "depd": "1.1.1",
-        "http-errors": "1.6.2",
-        "iconv-lite": "0.4.19",
-        "on-finished": "2.3.0",
-        "qs": "6.5.1",
-        "raw-body": "2.3.2",
-        "type-is": "1.6.15"
-      }
-    },
-    "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.1",
-        "deep-equal": "1.0.1",
-        "dns-equal": "1.0.0",
-        "dns-txt": "2.0.2",
-        "multicast-dns": "6.1.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
-    },
-    "boom": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
-      "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
-      "dev": true,
-      "requires": {
-        "hoek": "4.2.0"
-      }
-    },
-    "bootstrap": {
-      "version": "3.3.7",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz",
-      "integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E="
-    },
-    "bootstrap-colorpicker": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/bootstrap-colorpicker/-/bootstrap-colorpicker-2.5.2.tgz",
-      "integrity": "sha512-krzBno9AMUwI2+IDwMvjnpqpa2f8womW0CCKmEcxGzVkolCFrt22jjMjzx1NZqB8C1DUdNgZP4LfyCsgpHRiYA==",
-      "requires": {
-        "jquery": "3.2.1"
-      }
-    },
-    "bootstrap-switch": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/bootstrap-switch/-/bootstrap-switch-3.3.4.tgz",
-      "integrity": "sha1-cOCusqh3wNx2aZHeEI4hcPwpov8="
-    },
-    "brace-expansion": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-      "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-      "dev": true,
-      "requires": {
-        "balanced-match": "1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "braces": {
-      "version": "1.8.5",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
-      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
-      "dev": true,
-      "requires": {
-        "expand-range": "1.8.2",
-        "preserve": "0.2.0",
-        "repeat-element": "1.1.2"
-      }
-    },
-    "brorand": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
-      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
-      "dev": true
-    },
-    "browserify-aes": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz",
-      "integrity": "sha512-WYCMOT/PtGTlpOKFht0YJFYcPy6pLCR98CtWfzK13zoynLlBMvAdEMSRGmgnJCw2M2j/5qxBkinZQFobieM8dQ==",
-      "dev": true,
-      "requires": {
-        "buffer-xor": "1.0.3",
-        "cipher-base": "1.0.4",
-        "create-hash": "1.1.3",
-        "evp_bytestokey": "1.0.3",
-        "inherits": "2.0.3",
-        "safe-buffer": "5.1.1"
-      }
-    },
-    "browserify-cipher": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
-      "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
-      "dev": true,
-      "requires": {
-        "browserify-aes": "1.0.8",
-        "browserify-des": "1.0.0",
-        "evp_bytestokey": "1.0.3"
-      }
-    },
-    "browserify-des": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
-      "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
-      "dev": true,
-      "requires": {
-        "cipher-base": "1.0.4",
-        "des.js": "1.0.0",
-        "inherits": "2.0.3"
-      }
-    },
-    "browserify-rsa": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
-      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
-      "dev": true,
-      "requires": {
-        "bn.js": "4.11.8",
-        "randombytes": "2.0.5"
-      }
-    },
-    "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.11.8",
-        "browserify-rsa": "4.0.1",
-        "create-hash": "1.1.3",
-        "create-hmac": "1.1.6",
-        "elliptic": "6.4.0",
-        "inherits": "2.0.3",
-        "parse-asn1": "5.1.0"
-      }
-    },
-    "browserify-zlib": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
-      "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
-      "dev": true,
-      "requires": {
-        "pako": "0.2.9"
-      }
-    },
-    "browserslist": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.4.0.tgz",
-      "integrity": "sha512-aM2Gt4x9bVlCUteADBS6JP0F+2tMWKM1jQzUulVROtdFWFIcIVvY76AJbr7GDqy0eDhn+PcnpzzivGxY4qiaKQ==",
-      "dev": true,
-      "requires": {
-        "caniuse-lite": "1.0.30000741",
-        "electron-to-chromium": "1.3.24"
-      }
-    },
-    "buffer": {
-      "version": "4.9.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
-      "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
-      "dev": true,
-      "requires": {
-        "base64-js": "1.2.1",
-        "ieee754": "1.1.8",
-        "isarray": "1.0.0"
-      }
-    },
-    "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": "3.0.0",
-      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
-      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
-      "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="
-    },
-    "caller-path": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
-      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
-      "dev": true,
-      "requires": {
-        "callsites": "0.2.0"
-      }
-    },
-    "callsites": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
-      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
-      "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.3.2",
-        "upper-case": "1.1.3"
-      }
-    },
-    "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": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
-      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
-      "dev": true,
-      "requires": {
-        "camelcase": "2.1.1",
-        "map-obj": "1.0.1"
-      }
-    },
-    "caniuse-api": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
-      "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
-      "dev": true,
-      "requires": {
-        "browserslist": "1.7.7",
-        "caniuse-db": "1.0.30000741",
-        "lodash.memoize": "4.1.2",
-        "lodash.uniq": "4.5.0"
-      },
-      "dependencies": {
-        "browserslist": {
-          "version": "1.7.7",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
-          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
-          "dev": true,
-          "requires": {
-            "caniuse-db": "1.0.30000741",
-            "electron-to-chromium": "1.3.24"
-          }
-        }
-      }
-    },
-    "caniuse-db": {
-      "version": "1.0.30000741",
-      "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000741.tgz",
-      "integrity": "sha1-C+WREdQiHyH2ErUO5dZ4caLEp6U=",
-      "dev": true
-    },
-    "caniuse-lite": {
-      "version": "1.0.30000741",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000741.tgz",
-      "integrity": "sha1-vFJrwgRua8OHN8/XfTAm7wS49GQ=",
-      "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"
-      }
-    },
-    "center-align": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
-      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
-      "dev": true,
-      "requires": {
-        "align-text": "0.1.4",
-        "lazy-cache": "1.0.4"
-      }
-    },
-    "chalk": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-      "dev": true,
-      "requires": {
-        "ansi-styles": "2.2.1",
-        "escape-string-regexp": "1.0.5",
-        "has-ansi": "2.0.0",
-        "strip-ansi": "3.0.1",
-        "supports-color": "2.0.0"
-      }
-    },
-    "chokidar": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
-      "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
-      "dev": true,
-      "requires": {
-        "anymatch": "1.3.2",
-        "async-each": "1.0.1",
-        "fsevents": "1.1.3",
-        "glob-parent": "2.0.0",
-        "inherits": "2.0.3",
-        "is-binary-path": "1.0.1",
-        "is-glob": "2.0.1",
-        "path-is-absolute": "1.0.1",
-        "readdirp": "2.1.0"
-      }
-    },
-    "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.3",
-        "safe-buffer": "5.1.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="
-    },
-    "clap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
-      "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
-      "dev": true,
-      "requires": {
-        "chalk": "1.1.3"
-      }
-    },
-    "clean-css": {
-      "version": "4.1.9",
-      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz",
-      "integrity": "sha1-Nc7ornaHpJuYA09w3gDE7dOCYwE=",
-      "dev": true,
-      "requires": {
-        "source-map": "0.5.7"
-      }
-    },
-    "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": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
-      "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
-      "dev": true,
-      "requires": {
-        "center-align": "0.1.3",
-        "right-align": "0.1.3",
-        "wordwrap": "0.0.2"
-      },
-      "dependencies": {
-        "wordwrap": {
-          "version": "0.0.2",
-          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
-          "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
-          "dev": true
-        }
-      }
-    },
-    "clone": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz",
-      "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=",
-      "dev": true
-    },
-    "co": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
-      "dev": true
-    },
-    "coa": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
-      "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
-      "dev": true,
-      "requires": {
-        "q": "1.5.0"
-      }
-    },
-    "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
-    },
-    "coffee-script": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz",
-      "integrity": "sha1-EpOLz5vhlI+gBvkuDEyegXBRCMA=",
-      "dev": true
-    },
-    "color": {
-      "version": "0.11.4",
-      "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
-      "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
-      "dev": true,
-      "requires": {
-        "clone": "1.0.2",
-        "color-convert": "1.9.0",
-        "color-string": "0.3.0"
-      }
-    },
-    "color-convert": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
-      "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
-      "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
-    },
-    "color-string": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
-      "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
-      "dev": true,
-      "requires": {
-        "color-name": "1.1.3"
-      }
-    },
-    "colormin": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
-      "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
-      "dev": true,
-      "requires": {
-        "color": "0.11.4",
-        "css-color-names": "0.0.4",
-        "has": "1.0.1"
-      }
-    },
-    "colors": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
-      "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
-    },
-    "combined-stream": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
-      "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
-      "dev": true,
-      "requires": {
-        "delayed-stream": "1.0.0"
-      }
-    },
-    "commander": {
-      "version": "2.11.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
-      "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
-      "dev": true
-    },
-    "commondir": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
-      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
-      "dev": true
-    },
-    "compressible": {
-      "version": "2.0.11",
-      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.11.tgz",
-      "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=",
-      "dev": true,
-      "requires": {
-        "mime-db": "1.30.0"
-      }
-    },
-    "compression": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz",
-      "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=",
-      "dev": true,
-      "requires": {
-        "accepts": "1.3.4",
-        "bytes": "3.0.0",
-        "compressible": "2.0.11",
-        "debug": "2.6.9",
-        "on-headers": "1.0.1",
-        "safe-buffer": "5.1.1",
-        "vary": "1.1.2"
-      }
-    },
-    "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.0",
-      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
-      "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
-      "dev": true,
-      "requires": {
-        "inherits": "2.0.3",
-        "readable-stream": "2.3.3",
-        "typedarray": "0.0.6"
-      }
-    },
-    "connect-history-api-fallback": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz",
-      "integrity": "sha1-5R0X+PDvDbkKZP20feMFFVbp8Wk=",
-      "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"
-      }
-    },
-    "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
-    },
-    "content-type-parser": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz",
-      "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=",
-      "dev": true
-    },
-    "convert-source-map": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
-      "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
-      "dev": true
-    },
-    "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
-    },
-    "core-js": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
-      "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=",
-      "dev": true
-    },
-    "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": "2.2.2",
-      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
-      "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
-      "dev": true,
-      "requires": {
-        "is-directory": "0.3.1",
-        "js-yaml": "3.7.0",
-        "minimist": "1.2.0",
-        "object-assign": "4.1.1",
-        "os-homedir": "1.0.2",
-        "parse-json": "2.2.0",
-        "require-from-string": "1.2.1"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        }
-      }
-    },
-    "create-ecdh": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
-      "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
-      "dev": true,
-      "requires": {
-        "bn.js": "4.11.8",
-        "elliptic": "6.4.0"
-      }
-    },
-    "create-hash": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
-      "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
-      "dev": true,
-      "requires": {
-        "cipher-base": "1.0.4",
-        "inherits": "2.0.3",
-        "ripemd160": "2.0.1",
-        "sha.js": "2.4.9"
-      }
-    },
-    "create-hmac": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
-      "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
-      "dev": true,
-      "requires": {
-        "cipher-base": "1.0.4",
-        "create-hash": "1.1.3",
-        "inherits": "2.0.3",
-        "ripemd160": "2.0.1",
-        "safe-buffer": "5.1.1",
-        "sha.js": "2.4.9"
-      }
-    },
-    "cross-spawn": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
-      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
-      "dev": true,
-      "requires": {
-        "lru-cache": "4.1.1",
-        "shebang-command": "1.2.0",
-        "which": "1.2.14"
-      }
-    },
-    "cryptiles": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
-      "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
-      "dev": true,
-      "requires": {
-        "boom": "5.2.0"
-      },
-      "dependencies": {
-        "boom": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
-          "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
-          "dev": true,
-          "requires": {
-            "hoek": "4.2.0"
-          }
-        }
-      }
-    },
-    "crypto-api": {
-      "version": "0.7.5",
-      "resolved": "https://registry.npmjs.org/crypto-api/-/crypto-api-0.7.5.tgz",
-      "integrity": "sha1-TCc3K8s85mnSKNV7NZG8YRjFKdU="
-    },
-    "crypto-browserify": {
-      "version": "3.11.1",
-      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz",
-      "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==",
-      "dev": true,
-      "requires": {
-        "browserify-cipher": "1.0.0",
-        "browserify-sign": "4.0.4",
-        "create-ecdh": "4.0.0",
-        "create-hash": "1.1.3",
-        "create-hmac": "1.1.6",
-        "diffie-hellman": "5.0.2",
-        "inherits": "2.0.3",
-        "pbkdf2": "3.0.14",
-        "public-encrypt": "4.0.0",
-        "randombytes": "2.0.5"
-      }
-    },
-    "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-color-names": {
-      "version": "0.0.4",
-      "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
-      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
-      "dev": true
-    },
-    "css-loader": {
-      "version": "0.28.7",
-      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.7.tgz",
-      "integrity": "sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==",
-      "dev": true,
-      "requires": {
-        "babel-code-frame": "6.26.0",
-        "css-selector-tokenizer": "0.7.0",
-        "cssnano": "3.10.0",
-        "icss-utils": "2.1.0",
-        "loader-utils": "1.1.0",
-        "lodash.camelcase": "4.3.0",
-        "object-assign": "4.1.1",
-        "postcss": "5.2.17",
-        "postcss-modules-extract-imports": "1.1.0",
-        "postcss-modules-local-by-default": "1.2.0",
-        "postcss-modules-scope": "1.1.0",
-        "postcss-modules-values": "1.3.0",
-        "postcss-value-parser": "3.3.0",
-        "source-list-map": "2.0.0"
-      }
-    },
-    "css-select": {
-      "version": "1.2.0",
-      "resolved": "https://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.0",
-        "domutils": "1.5.1",
-        "nth-check": "1.0.1"
-      }
-    },
-    "css-selector-tokenizer": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
-      "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
-      "dev": true,
-      "requires": {
-        "cssesc": "0.1.0",
-        "fastparse": "1.1.1",
-        "regexpu-core": "1.0.0"
-      },
-      "dependencies": {
-        "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.3.3",
-            "regjsgen": "0.2.0",
-            "regjsparser": "0.1.5"
-          }
-        }
-      }
-    },
-    "css-what": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
-      "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=",
-      "dev": true
-    },
-    "cssesc": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
-      "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
-      "dev": true
-    },
-    "cssnano": {
-      "version": "3.10.0",
-      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
-      "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
-      "dev": true,
-      "requires": {
-        "autoprefixer": "6.7.7",
-        "decamelize": "1.2.0",
-        "defined": "1.0.0",
-        "has": "1.0.1",
-        "object-assign": "4.1.1",
-        "postcss": "5.2.17",
-        "postcss-calc": "5.3.1",
-        "postcss-colormin": "2.2.2",
-        "postcss-convert-values": "2.6.1",
-        "postcss-discard-comments": "2.0.4",
-        "postcss-discard-duplicates": "2.1.0",
-        "postcss-discard-empty": "2.1.0",
-        "postcss-discard-overridden": "0.1.1",
-        "postcss-discard-unused": "2.2.3",
-        "postcss-filter-plugins": "2.0.2",
-        "postcss-merge-idents": "2.1.7",
-        "postcss-merge-longhand": "2.0.2",
-        "postcss-merge-rules": "2.1.2",
-        "postcss-minify-font-values": "1.0.5",
-        "postcss-minify-gradients": "1.0.5",
-        "postcss-minify-params": "1.2.2",
-        "postcss-minify-selectors": "2.1.1",
-        "postcss-normalize-charset": "1.1.1",
-        "postcss-normalize-url": "3.0.8",
-        "postcss-ordered-values": "2.2.3",
-        "postcss-reduce-idents": "2.4.0",
-        "postcss-reduce-initial": "1.0.1",
-        "postcss-reduce-transforms": "1.0.4",
-        "postcss-svgo": "2.1.6",
-        "postcss-unique-selectors": "2.0.2",
-        "postcss-value-parser": "3.3.0",
-        "postcss-zindex": "2.2.0"
-      }
-    },
-    "csso": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
-      "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
-      "dev": true,
-      "requires": {
-        "clap": "1.2.3",
-        "source-map": "0.5.7"
-      }
-    },
-    "cssom": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
-      "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=",
-      "dev": true
-    },
-    "cssstyle": {
-      "version": "0.2.37",
-      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
-      "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
-      "dev": true,
-      "requires": {
-        "cssom": "0.3.2"
-      }
-    },
-    "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.2"
-      }
-    },
-    "d": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
-      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
-      "dev": true,
-      "requires": {
-        "es5-ext": "0.10.30"
-      }
-    },
-    "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"
-      }
-    },
-    "datauri": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/datauri/-/datauri-1.0.5.tgz",
-      "integrity": "sha1-0JddGrbI8uDOPKQ7qkU5vhLSiaA=",
-      "dev": true,
-      "requires": {
-        "image-size": "0.3.5",
-        "mimer": "0.2.1",
-        "semver": "5.4.1"
-      },
-      "dependencies": {
-        "image-size": {
-          "version": "0.3.5",
-          "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.3.5.tgz",
-          "integrity": "sha1-gyQOqy+1sAsEqrjHSwRx6cunrYw=",
-          "dev": true
-        }
-      }
-    },
-    "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.7.0"
-      }
-    },
-    "debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-      "dev": true,
-      "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
-    },
-    "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.4.2",
-      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
-      "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
-      "dev": true
-    },
-    "deep-for-each": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/deep-for-each/-/deep-for-each-1.0.6.tgz",
-      "integrity": "sha1-r6DOJJxYSSqXIFOUeKGNN+GxC64=",
-      "dev": true,
-      "requires": {
-        "is-plain-object": "2.0.4"
-      }
-    },
-    "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="
-    },
-    "define-properties": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
-      "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
-      "dev": true,
-      "requires": {
-        "foreach": "2.0.5",
-        "object-keys": "1.0.11"
-      }
-    },
-    "defined": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
-      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
-      "dev": true
-    },
-    "del": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
-      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
-      "dev": true,
-      "requires": {
-        "globby": "5.0.0",
-        "is-path-cwd": "1.0.0",
-        "is-path-in-cwd": "1.0.0",
-        "object-assign": "4.1.1",
-        "pify": "2.3.0",
-        "pinkie-promise": "2.0.1",
-        "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
-    },
-    "depd": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
-      "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
-      "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.3",
-        "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-indent": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
-      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
-      "dev": true,
-      "requires": {
-        "repeating": "2.0.1"
-      }
-    },
-    "detect-node": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz",
-      "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
-      "dev": true
-    },
-    "diff": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
-      "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww=="
-    },
-    "diffie-hellman": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
-      "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
-      "dev": true,
-      "requires": {
-        "bn.js": "4.11.8",
-        "miller-rabin": "4.0.1",
-        "randombytes": "2.0.5"
-      }
-    },
-    "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.2.2",
-      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.2.2.tgz",
-      "integrity": "sha512-kN+DjfGF7dJGUL7nWRktL9Z18t1rWP3aQlyZdY8XlpvU3Nc6GeFTQApftcjtWKxAZfiggZSGrCEoszNgvnpwDg==",
-      "dev": true,
-      "requires": {
-        "ip": "1.1.5",
-        "safe-buffer": "5.1.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.1.1"
-      }
-    },
-    "doctrine": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
-      "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=",
-      "dev": true,
-      "requires": {
-        "esutils": "2.0.2",
-        "isarray": "1.0.0"
-      }
-    },
-    "dom-converter": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz",
-      "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=",
-      "dev": true,
-      "requires": {
-        "utila": "0.3.3"
-      },
-      "dependencies": {
-        "utila": {
-          "version": "0.3.3",
-          "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
-          "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
-          "dev": true
-        }
-      }
-    },
-    "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.3",
-        "entities": "1.1.1"
-      },
-      "dependencies": {
-        "domelementtype": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
-          "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
-          "dev": true
-        }
-      }
-    },
-    "domain-browser": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
-      "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=",
-      "dev": true
-    },
-    "domelementtype": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
-      "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
-      "dev": true
-    },
-    "domhandler": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz",
-      "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=",
-      "dev": true,
-      "requires": {
-        "domelementtype": "1.3.0"
-      }
-    },
-    "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.1.0",
-        "domelementtype": "1.3.0"
-      }
-    },
-    "duplexify": {
-      "version": "3.5.1",
-      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz",
-      "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==",
-      "dev": true,
-      "requires": {
-        "end-of-stream": "1.4.0",
-        "inherits": "2.0.3",
-        "readable-stream": "2.3.3",
-        "stream-shift": "1.0.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.1",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
-      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "jsbn": "0.1.1"
-      },
-      "dependencies": {
-        "jsbn": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-          "dev": true,
-          "optional": true
-        }
-      }
-    },
-    "ee-first": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
-      "dev": true
-    },
-    "electron-to-chromium": {
-      "version": "1.3.24",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz",
-      "integrity": "sha1-m3uIuwXOufoBahd4M8wt3jiPIbY=",
-      "dev": true
-    },
-    "elliptic": {
-      "version": "6.4.0",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
-      "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
-      "dev": true,
-      "requires": {
-        "bn.js": "4.11.8",
-        "brorand": "1.1.0",
-        "hash.js": "1.1.3",
-        "hmac-drbg": "1.0.1",
-        "inherits": "2.0.3",
-        "minimalistic-assert": "1.0.0",
-        "minimalistic-crypto-utils": "1.0.1"
-      }
-    },
-    "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.1",
-      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
-      "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
-      "dev": true
-    },
-    "end-of-stream": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
-      "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=",
-      "dev": true,
-      "requires": {
-        "once": "1.4.0"
-      }
-    },
-    "enhanced-resolve": {
-      "version": "3.4.1",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
-      "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11",
-        "memory-fs": "0.4.1",
-        "object-assign": "4.1.1",
-        "tapable": "0.2.8"
-      }
-    },
-    "entities": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
-      "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
-      "dev": true
-    },
-    "errno": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz",
-      "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=",
-      "dev": true,
-      "requires": {
-        "prr": "0.0.0"
-      }
-    },
-    "error-ex": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
-      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
-      "dev": true,
-      "requires": {
-        "is-arrayish": "0.2.1"
-      }
-    },
-    "es-abstract": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz",
-      "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==",
-      "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.1.1",
-      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
-      "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
-      "dev": true,
-      "requires": {
-        "is-callable": "1.1.3",
-        "is-date-object": "1.0.1",
-        "is-symbol": "1.0.1"
-      }
-    },
-    "es5-ext": {
-      "version": "0.10.30",
-      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz",
-      "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=",
-      "dev": true,
-      "requires": {
-        "es6-iterator": "2.0.1",
-        "es6-symbol": "3.1.1"
-      }
-    },
-    "es6-iterator": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
-      "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
-      "dev": true,
-      "requires": {
-        "d": "1.0.0",
-        "es5-ext": "0.10.30",
-        "es6-symbol": "3.1.1"
-      }
-    },
-    "es6-map": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
-      "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
-      "dev": true,
-      "requires": {
-        "d": "1.0.0",
-        "es5-ext": "0.10.30",
-        "es6-iterator": "2.0.1",
-        "es6-set": "0.1.5",
-        "es6-symbol": "3.1.1",
-        "event-emitter": "0.3.5"
-      }
-    },
-    "es6-promise": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz",
-      "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI="
-    },
-    "es6-promisify": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
-      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
-      "requires": {
-        "es6-promise": "4.0.5"
-      }
-    },
-    "es6-set": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
-      "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
-      "dev": true,
-      "requires": {
-        "d": "1.0.0",
-        "es5-ext": "0.10.30",
-        "es6-iterator": "2.0.1",
-        "es6-symbol": "3.1.1",
-        "event-emitter": "0.3.5"
-      }
-    },
-    "es6-symbol": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
-      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
-      "dev": true,
-      "requires": {
-        "d": "1.0.0",
-        "es5-ext": "0.10.30"
-      }
-    },
-    "es6-weak-map": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
-      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
-      "dev": true,
-      "requires": {
-        "d": "1.0.0",
-        "es5-ext": "0.10.30",
-        "es6-iterator": "2.0.1",
-        "es6-symbol": "3.1.1"
-      }
-    },
-    "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=",
-      "dev": true
-    },
-    "escodegen": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
-      "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
-      "requires": {
-        "esprima": "3.1.3",
-        "estraverse": "4.2.0",
-        "esutils": "2.0.2",
-        "optionator": "0.8.2",
-        "source-map": "0.5.7"
-      },
-      "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": "4.8.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.8.0.tgz",
-      "integrity": "sha1-Ip7w41Tg5h2DfHqA/fuoJeGZgV4=",
-      "dev": true,
-      "requires": {
-        "ajv": "5.2.3",
-        "babel-code-frame": "6.26.0",
-        "chalk": "2.1.0",
-        "concat-stream": "1.6.0",
-        "cross-spawn": "5.1.0",
-        "debug": "3.1.0",
-        "doctrine": "2.0.0",
-        "eslint-scope": "3.7.1",
-        "espree": "3.5.1",
-        "esquery": "1.0.0",
-        "estraverse": "4.2.0",
-        "esutils": "2.0.2",
-        "file-entry-cache": "2.0.0",
-        "functional-red-black-tree": "1.0.1",
-        "glob": "7.1.2",
-        "globals": "9.18.0",
-        "ignore": "3.3.5",
-        "imurmurhash": "0.1.4",
-        "inquirer": "3.3.0",
-        "is-resolvable": "1.0.0",
-        "js-yaml": "3.10.0",
-        "json-stable-stringify": "1.0.1",
-        "levn": "0.3.0",
-        "lodash": "4.17.4",
-        "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",
-        "require-uncached": "1.0.3",
-        "semver": "5.4.1",
-        "strip-ansi": "4.0.0",
-        "strip-json-comments": "2.0.1",
-        "table": "4.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.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "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"
-          }
-        },
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "js-yaml": {
-          "version": "3.10.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
-          "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
-          "dev": true,
-          "requires": {
-            "argparse": "1.0.9",
-            "esprima": "4.0.0"
-          }
-        },
-        "progress": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
-          "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
-          "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": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "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.2.0",
-        "estraverse": "4.2.0"
-      }
-    },
-    "esmangle": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/esmangle/-/esmangle-1.0.1.tgz",
-      "integrity": "sha1-2bs3uPjq+/Tm1O1reqKVarvTxMI=",
-      "requires": {
-        "escodegen": "1.3.3",
-        "escope": "1.0.3",
-        "esprima": "1.1.1",
-        "esshorten": "1.1.1",
-        "estraverse": "1.5.1",
-        "esutils": "1.0.0",
-        "optionator": "0.3.0",
-        "source-map": "0.1.43"
-      },
-      "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.1",
-            "esutils": "1.0.0",
-            "source-map": "0.1.43"
-          }
-        },
-        "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.2",
-            "type-check": "0.3.2"
-          }
-        },
-        "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.3",
-            "fast-levenshtein": "1.0.7",
-            "levn": "0.2.5",
-            "prelude-ls": "1.1.2",
-            "type-check": "0.3.2",
-            "wordwrap": "0.0.3"
-          }
-        },
-        "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": "1.0.1"
-          }
-        },
-        "wordwrap": {
-          "version": "0.0.3",
-          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
-          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
-        }
-      }
-    },
-    "espree": {
-      "version": "3.5.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz",
-      "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=",
-      "dev": true,
-      "requires": {
-        "acorn": "5.1.2",
-        "acorn-jsx": "3.0.1"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz",
-          "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==",
-          "dev": true
-        }
-      }
-    },
-    "esprima": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
-      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
-    },
-    "esquery": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
-      "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
-      "dev": true,
-      "requires": {
-        "estraverse": "4.2.0"
-      }
-    },
-    "esrecurse": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
-      "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
-      "dev": true,
-      "requires": {
-        "estraverse": "4.2.0",
-        "object-assign": "4.1.1"
-      }
-    },
-    "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.3",
-        "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
-    },
-    "event-emitter": {
-      "version": "0.3.5",
-      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
-      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
-      "dev": true,
-      "requires": {
-        "d": "1.0.0",
-        "es5-ext": "0.10.30"
-      }
-    },
-    "eventemitter2": {
-      "version": "0.4.14",
-      "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
-      "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
-      "dev": true
-    },
-    "eventemitter3": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
-      "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
-      "dev": true
-    },
-    "events": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
-      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
-      "dev": true
-    },
-    "eventsource": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
-      "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
-      "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.7.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
-      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
-      "dev": true,
-      "requires": {
-        "cross-spawn": "5.1.0",
-        "get-stream": "3.0.0",
-        "is-stream": "1.1.0",
-        "npm-run-path": "2.0.2",
-        "p-finally": "1.0.0",
-        "signal-exit": "3.0.2",
-        "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": "0.1.5",
-      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
-      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
-      "dev": true,
-      "requires": {
-        "is-posix-bracket": "0.1.1"
-      }
-    },
-    "expand-range": {
-      "version": "1.8.2",
-      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
-      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
-      "dev": true,
-      "requires": {
-        "fill-range": "2.2.3"
-      }
-    },
-    "exports-loader": {
-      "version": "0.6.4",
-      "resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.6.4.tgz",
-      "integrity": "sha1-1w/GEhl1s1/BKDDPUnVL4nQPyIY=",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0",
-        "source-map": "0.5.7"
-      }
-    },
-    "express": {
-      "version": "4.16.1",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.16.1.tgz",
-      "integrity": "sha512-STB7LZ4N0L+81FJHGla2oboUHTk4PaN1RsOkoRh9OSeEKylvF5hwKYVX1xCLFaCT7MD0BNG/gX2WFMLqY6EMBw==",
-      "dev": true,
-      "requires": {
-        "accepts": "1.3.4",
-        "array-flatten": "1.1.1",
-        "body-parser": "1.18.2",
-        "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.1",
-        "encodeurl": "1.0.1",
-        "escape-html": "1.0.3",
-        "etag": "1.8.1",
-        "finalhandler": "1.1.0",
-        "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.2",
-        "qs": "6.5.1",
-        "range-parser": "1.2.0",
-        "safe-buffer": "5.1.1",
-        "send": "0.16.1",
-        "serve-static": "1.13.1",
-        "setprototypeof": "1.1.0",
-        "statuses": "1.3.1",
-        "type-is": "1.6.15",
-        "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.1",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
-      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
-      "dev": true
-    },
-    "external-editor": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz",
-      "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==",
-      "dev": true,
-      "requires": {
-        "iconv-lite": "0.4.19",
-        "jschardet": "1.5.1",
-        "tmp": "0.0.33"
-      }
-    },
-    "extglob": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
-      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
-      "dev": true,
-      "requires": {
-        "is-extglob": "1.0.0"
-      }
-    },
-    "extract-text-webpack-plugin": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.1.tgz",
-      "integrity": "sha512-zv0/Cg2mU8uMzeQQ3oyfJvZU4Iv/GbQYUIr/HU+8pZetT/0W3xj6XAbxoG4gsp8SbnYcFd4BOsCAZPl9NvplPw==",
-      "dev": true,
-      "requires": {
-        "async": "2.5.0",
-        "loader-utils": "1.1.0",
-        "schema-utils": "0.3.0",
-        "webpack-sources": "1.0.1"
-      }
-    },
-    "extract-zip": {
-      "version": "1.6.5",
-      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz",
-      "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=",
-      "dev": true,
-      "requires": {
-        "concat-stream": "1.6.0",
-        "debug": "2.2.0",
-        "mkdirp": "0.5.0",
-        "yauzl": "2.4.1"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
-          "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
-          "dev": true,
-          "requires": {
-            "ms": "0.7.1"
-          }
-        },
-        "mkdirp": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
-          "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
-          "dev": true,
-          "requires": {
-            "minimist": "0.0.8"
-          }
-        },
-        "ms": {
-          "version": "0.7.1",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
-          "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
-          "dev": true
-        }
-      }
-    },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true
-    },
-    "fast-deep-equal": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
-      "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
-      "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.1",
-      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
-      "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
-      "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.7.0"
-      }
-    },
-    "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"
-      }
-    },
-    "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.3.0",
-        "object-assign": "4.1.1"
-      }
-    },
-    "file-loader": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.4.tgz",
-      "integrity": "sha512-E4mCBrAVk8pB6VmuCW/rbHvtQDy2sknh0G4c2c449Q5qC7fCkL1P6sZGxQXWPaAxXBdU8WsTzPEB973Ei8vkxg==",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0",
-        "schema-utils": "0.3.0"
-      }
-    },
-    "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
-    },
-    "filename-regex": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
-      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
-      "dev": true
-    },
-    "fill-range": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
-      "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
-      "dev": true,
-      "requires": {
-        "is-number": "2.1.0",
-        "isobject": "2.1.0",
-        "randomatic": "1.1.7",
-        "repeat-element": "1.1.2",
-        "repeat-string": "1.6.1"
-      },
-      "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"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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.1.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.15"
-      },
-      "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.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        }
-      }
-    },
-    "flat-cache": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
-      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
-      "dev": true,
-      "requires": {
-        "circular-json": "0.3.3",
-        "del": "2.2.2",
-        "graceful-fs": "4.1.11",
-        "write": "0.2.1"
-      }
-    },
-    "flatten": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
-      "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
-      "dev": true
-    },
-    "follow-redirects": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz",
-      "integrity": "sha1-NLkLqyqRGqNHVx2pDyK9NuzYqRk=",
-      "dev": true,
-      "requires": {
-        "debug": "2.6.9",
-        "stream-consume": "0.1.0"
-      }
-    },
-    "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": "0.1.5",
-      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
-      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
-      "dev": true,
-      "requires": {
-        "for-in": "1.0.2"
-      }
-    },
-    "foreach": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
-      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
-      "dev": true
-    },
-    "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.1",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
-      "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
-      "dev": true,
-      "requires": {
-        "asynckit": "0.4.0",
-        "combined-stream": "1.0.5",
-        "mime-types": "2.1.17"
-      }
-    },
-    "forwarded": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
-      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
-      "dev": true
-    },
-    "fresh": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
-      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
-      "dev": true
-    },
-    "fs-extra": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
-      "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11",
-        "jsonfile": "2.4.0",
-        "klaw": "1.3.1"
-      }
-    },
-    "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.1.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
-      "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "nan": "2.8.0",
-        "node-pre-gyp": "0.6.39"
-      },
-      "dependencies": {
-        "abbrev": {
-          "version": "1.1.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "ajv": {
-          "version": "4.11.8",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "co": "4.6.0",
-            "json-stable-stringify": "1.0.1"
-          }
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "bundled": true,
-          "dev": true
-        },
-        "aproba": {
-          "version": "1.1.1",
-          "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.2.9"
-          }
-        },
-        "asn1": {
-          "version": "0.2.3",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "assert-plus": {
-          "version": "0.2.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "asynckit": {
-          "version": "0.4.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "aws-sign2": {
-          "version": "0.6.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "aws4": {
-          "version": "1.6.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "balanced-match": {
-          "version": "0.4.2",
-          "bundled": true,
-          "dev": true
-        },
-        "bcrypt-pbkdf": {
-          "version": "1.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "tweetnacl": "0.14.5"
-          }
-        },
-        "block-stream": {
-          "version": "0.0.9",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "inherits": "2.0.3"
-          }
-        },
-        "boom": {
-          "version": "2.10.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "hoek": "2.16.3"
-          }
-        },
-        "brace-expansion": {
-          "version": "1.1.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "balanced-match": "0.4.2",
-            "concat-map": "0.0.1"
-          }
-        },
-        "buffer-shims": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "caseless": {
-          "version": "0.12.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "co": {
-          "version": "4.6.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "code-point-at": {
-          "version": "1.1.0",
-          "bundled": true,
-          "dev": true
-        },
-        "combined-stream": {
-          "version": "1.0.5",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "delayed-stream": "1.0.0"
-          }
-        },
-        "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
-        },
-        "cryptiles": {
-          "version": "2.0.5",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "boom": "2.10.1"
-          }
-        },
-        "dashdash": {
-          "version": "1.14.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "assert-plus": "1.0.0"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "bundled": true,
-              "dev": true,
-              "optional": true
-            }
-          }
-        },
-        "debug": {
-          "version": "2.6.8",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "deep-extend": {
-          "version": "0.4.2",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "delayed-stream": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "delegates": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "detect-libc": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "ecc-jsbn": {
-          "version": "0.1.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "jsbn": "0.1.1"
-          }
-        },
-        "extend": {
-          "version": "3.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "extsprintf": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true
-        },
-        "forever-agent": {
-          "version": "0.6.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "form-data": {
-          "version": "2.1.4",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "asynckit": "0.4.0",
-            "combined-stream": "1.0.5",
-            "mime-types": "2.1.15"
-          }
-        },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "fstream": {
-          "version": "1.0.11",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "graceful-fs": "4.1.11",
-            "inherits": "2.0.3",
-            "mkdirp": "0.5.1",
-            "rimraf": "2.6.1"
-          }
-        },
-        "fstream-ignore": {
-          "version": "1.0.5",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "fstream": "1.0.11",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4"
-          }
-        },
-        "gauge": {
-          "version": "2.7.4",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "aproba": "1.1.1",
-            "console-control-strings": "1.1.0",
-            "has-unicode": "2.0.1",
-            "object-assign": "4.1.1",
-            "signal-exit": "3.0.2",
-            "string-width": "1.0.2",
-            "strip-ansi": "3.0.1",
-            "wide-align": "1.1.2"
-          }
-        },
-        "getpass": {
-          "version": "0.1.7",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "assert-plus": "1.0.0"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "bundled": true,
-              "dev": true,
-              "optional": true
-            }
-          }
-        },
-        "glob": {
-          "version": "7.1.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        },
-        "graceful-fs": {
-          "version": "4.1.11",
-          "bundled": true,
-          "dev": true
-        },
-        "har-schema": {
-          "version": "1.0.5",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "har-validator": {
-          "version": "4.2.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ajv": "4.11.8",
-            "har-schema": "1.0.5"
-          }
-        },
-        "has-unicode": {
-          "version": "2.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "hawk": {
-          "version": "3.1.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "boom": "2.10.1",
-            "cryptiles": "2.0.5",
-            "hoek": "2.16.3",
-            "sntp": "1.0.9"
-          }
-        },
-        "hoek": {
-          "version": "2.16.3",
-          "bundled": true,
-          "dev": true
-        },
-        "http-signature": {
-          "version": "1.1.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "assert-plus": "0.2.0",
-            "jsprim": "1.4.0",
-            "sshpk": "1.13.0"
-          }
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "once": "1.4.0",
-            "wrappy": "1.0.2"
-          }
-        },
-        "inherits": {
-          "version": "2.0.3",
-          "bundled": true,
-          "dev": true
-        },
-        "ini": {
-          "version": "1.3.4",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "number-is-nan": "1.0.1"
-          }
-        },
-        "is-typedarray": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "isstream": {
-          "version": "0.1.2",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "jodid25519": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "jsbn": "0.1.1"
-          }
-        },
-        "jsbn": {
-          "version": "0.1.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "json-schema": {
-          "version": "0.2.3",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "json-stable-stringify": {
-          "version": "1.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "jsonify": "0.0.0"
-          }
-        },
-        "json-stringify-safe": {
-          "version": "5.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "jsonify": {
-          "version": "0.0.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "jsprim": {
-          "version": "1.4.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "assert-plus": "1.0.0",
-            "extsprintf": "1.0.2",
-            "json-schema": "0.2.3",
-            "verror": "1.3.6"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "bundled": true,
-              "dev": true,
-              "optional": true
-            }
-          }
-        },
-        "mime-db": {
-          "version": "1.27.0",
-          "bundled": true,
-          "dev": true
-        },
-        "mime-types": {
-          "version": "2.1.15",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "mime-db": "1.27.0"
-          }
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "brace-expansion": "1.1.7"
-          }
-        },
-        "minimist": {
-          "version": "0.0.8",
-          "bundled": true,
-          "dev": true
-        },
-        "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
-        },
-        "node-pre-gyp": {
-          "version": "0.6.39",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "detect-libc": "1.0.2",
-            "hawk": "3.1.3",
-            "mkdirp": "0.5.1",
-            "nopt": "4.0.1",
-            "npmlog": "4.1.0",
-            "rc": "1.2.1",
-            "request": "2.81.0",
-            "rimraf": "2.6.1",
-            "semver": "5.3.0",
-            "tar": "2.2.1",
-            "tar-pack": "3.4.0"
-          }
-        },
-        "nopt": {
-          "version": "4.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "abbrev": "1.1.0",
-            "osenv": "0.1.4"
-          }
-        },
-        "npmlog": {
-          "version": "4.1.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "are-we-there-yet": "1.1.4",
-            "console-control-strings": "1.1.0",
-            "gauge": "2.7.4",
-            "set-blocking": "2.0.0"
-          }
-        },
-        "number-is-nan": {
-          "version": "1.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "oauth-sign": {
-          "version": "0.8.2",
-          "bundled": true,
-          "dev": true,
-          "optional": 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.0.2"
-          }
-        },
-        "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.4",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "os-homedir": "1.0.2",
-            "os-tmpdir": "1.0.2"
-          }
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "performance-now": {
-          "version": "0.2.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "process-nextick-args": {
-          "version": "1.0.7",
-          "bundled": true,
-          "dev": true
-        },
-        "punycode": {
-          "version": "1.4.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "qs": {
-          "version": "6.4.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "rc": {
-          "version": "1.2.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "deep-extend": "0.4.2",
-            "ini": "1.3.4",
-            "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.2.9",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "buffer-shims": "1.0.0",
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "1.0.0",
-            "process-nextick-args": "1.0.7",
-            "string_decoder": "1.0.1",
-            "util-deprecate": "1.0.2"
-          }
-        },
-        "request": {
-          "version": "2.81.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "aws-sign2": "0.6.0",
-            "aws4": "1.6.0",
-            "caseless": "0.12.0",
-            "combined-stream": "1.0.5",
-            "extend": "3.0.1",
-            "forever-agent": "0.6.1",
-            "form-data": "2.1.4",
-            "har-validator": "4.2.1",
-            "hawk": "3.1.3",
-            "http-signature": "1.1.1",
-            "is-typedarray": "1.0.0",
-            "isstream": "0.1.2",
-            "json-stringify-safe": "5.0.1",
-            "mime-types": "2.1.15",
-            "oauth-sign": "0.8.2",
-            "performance-now": "0.2.0",
-            "qs": "6.4.0",
-            "safe-buffer": "5.0.1",
-            "stringstream": "0.0.5",
-            "tough-cookie": "2.3.2",
-            "tunnel-agent": "0.6.0",
-            "uuid": "3.0.1"
-          }
-        },
-        "rimraf": {
-          "version": "2.6.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "glob": "7.1.2"
-          }
-        },
-        "safe-buffer": {
-          "version": "5.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "semver": {
-          "version": "5.3.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
-        },
-        "sntp": {
-          "version": "1.0.9",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "hoek": "2.16.3"
-          }
-        },
-        "sshpk": {
-          "version": "1.13.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "asn1": "0.2.3",
-            "assert-plus": "1.0.0",
-            "bcrypt-pbkdf": "1.0.1",
-            "dashdash": "1.14.1",
-            "ecc-jsbn": "0.1.1",
-            "getpass": "0.1.7",
-            "jodid25519": "1.0.2",
-            "jsbn": "0.1.1",
-            "tweetnacl": "0.14.5"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "bundled": true,
-              "dev": true,
-              "optional": true
-            }
-          }
-        },
-        "string-width": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "code-point-at": "1.1.0",
-            "is-fullwidth-code-point": "1.0.0",
-            "strip-ansi": "3.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.0.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "safe-buffer": "5.0.1"
-          }
-        },
-        "stringstream": {
-          "version": "0.0.5",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ansi-regex": "2.1.1"
-          }
-        },
-        "strip-json-comments": {
-          "version": "2.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "tar": {
-          "version": "2.2.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "block-stream": "0.0.9",
-            "fstream": "1.0.11",
-            "inherits": "2.0.3"
-          }
-        },
-        "tar-pack": {
-          "version": "3.4.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "debug": "2.6.8",
-            "fstream": "1.0.11",
-            "fstream-ignore": "1.0.5",
-            "once": "1.4.0",
-            "readable-stream": "2.2.9",
-            "rimraf": "2.6.1",
-            "tar": "2.2.1",
-            "uid-number": "0.0.6"
-          }
-        },
-        "tough-cookie": {
-          "version": "2.3.2",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "punycode": "1.4.1"
-          }
-        },
-        "tunnel-agent": {
-          "version": "0.6.0",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "safe-buffer": "5.0.1"
-          }
-        },
-        "tweetnacl": {
-          "version": "0.14.5",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "uid-number": {
-          "version": "0.0.6",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "util-deprecate": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true
-        },
-        "uuid": {
-          "version": "3.0.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "verror": {
-          "version": "1.3.6",
-          "bundled": true,
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "extsprintf": "1.0.2"
-          }
-        },
-        "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
-        }
-      }
-    },
-    "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
-    },
-    "get-caller-file": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
-      "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
-      "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": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
-      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
-      "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.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.6",
-        "inherits": "2.0.3",
-        "minimatch": "3.0.4",
-        "once": "1.4.0",
-        "path-is-absolute": "1.0.1"
-      }
-    },
-    "glob-base": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
-      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
-      "dev": true,
-      "requires": {
-        "glob-parent": "2.0.0",
-        "is-glob": "2.0.1"
-      }
-    },
-    "glob-parent": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
-      "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
-      "dev": true,
-      "requires": {
-        "is-glob": "2.0.1"
-      }
-    },
-    "globals": {
-      "version": "9.18.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
-      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
-      "dev": true
-    },
-    "globby": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
-      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
-      "dev": true,
-      "requires": {
-        "array-union": "1.0.2",
-        "arrify": "1.0.1",
-        "glob": "7.0.6",
-        "object-assign": "4.1.1",
-        "pify": "2.3.0",
-        "pinkie-promise": "2.0.1"
-      }
-    },
-    "google-code-prettify": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/google-code-prettify/-/google-code-prettify-1.0.5.tgz",
-      "integrity": "sha1-n0d/Ik2/piNy5e+AOn4VdBBAAIQ="
-    },
-    "graceful-fs": {
-      "version": "4.1.11",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
-      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
-      "dev": true
-    },
-    "grunt": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.1.tgz",
-      "integrity": "sha1-6HeHZOlEsY8yuw8QuQeEdcnftWs=",
-      "dev": true,
-      "requires": {
-        "coffee-script": "1.10.0",
-        "dateformat": "1.0.12",
-        "eventemitter2": "0.4.14",
-        "exit": "0.1.2",
-        "findup-sync": "0.3.0",
-        "glob": "7.0.6",
-        "grunt-cli": "1.2.0",
-        "grunt-known-options": "1.1.0",
-        "grunt-legacy-log": "1.0.0",
-        "grunt-legacy-util": "1.0.0",
-        "iconv-lite": "0.4.19",
-        "js-yaml": "3.5.5",
-        "minimatch": "3.0.4",
-        "nopt": "3.0.6",
-        "path-is-absolute": "1.0.1",
-        "rimraf": "2.2.8"
-      },
-      "dependencies": {
-        "esprima": {
-          "version": "2.7.3",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
-          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
-          "dev": true
-        },
-        "grunt-cli": {
-          "version": "1.2.0",
-          "resolved": "https://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.7"
-          }
-        },
-        "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.9",
-            "esprima": "2.7.3"
-          }
-        }
-      }
-    },
-    "grunt-accessibility": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/grunt-accessibility/-/grunt-accessibility-5.0.0.tgz",
-      "integrity": "sha1-/uK+5WHjPOl8lfk/7ogEPfFFokk=",
-      "dev": true,
-      "requires": {
-        "access-sniff": "3.0.1"
-      }
-    },
-    "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"
-      }
-    },
-    "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.5.2",
-        "indent-string": "2.1.0",
-        "pad-stream": "1.2.0"
-      },
-      "dependencies": {
-        "async": {
-          "version": "1.5.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-          "dev": true
-        }
-      }
-    },
-    "grunt-contrib-clean": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.1.0.tgz",
-      "integrity": "sha1-Vkq/LQN4qYOhW54/MO51tzjEBjg=",
-      "dev": true,
-      "requires": {
-        "async": "1.5.2",
-        "rimraf": "2.6.2"
-      },
-      "dependencies": {
-        "async": {
-          "version": "1.5.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-          "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.6"
-          }
-        }
-      }
-    },
-    "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.3",
-        "file-sync-cmp": "0.1.1"
-      }
-    },
-    "grunt-eslint": {
-      "version": "20.1.0",
-      "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-20.1.0.tgz",
-      "integrity": "sha512-VZlDOLrB2KKefDDcx/wR8rEEz7smDwDKVblmooa+itdt/2jWw3ee2AiZB5Ap4s4AoRY0pbHRjZ3HHwY8uKR9Rw==",
-      "dev": true,
-      "requires": {
-        "chalk": "2.1.0",
-        "eslint": "4.8.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.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-execute": {
-      "version": "0.2.2",
-      "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.2.2.tgz",
-      "integrity": "sha1-TpRf5XlZzA3neZCDtrQq7ZYWNQo=",
-      "dev": true
-    },
-    "grunt-jsdoc": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.2.0.tgz",
-      "integrity": "sha512-3/HzvzcG7gxlm4YefR5ELbsUB/bIFCeX3CbUeAANKGMfNUZ2tDQ+Pp0YRb/VWHjyu+v8wG6n1PD8yIjubjEDeg==",
-      "dev": true,
-      "requires": {
-        "cross-spawn": "3.0.1",
-        "jsdoc": "3.5.5"
-      },
-      "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.1.1",
-            "which": "1.2.14"
-          }
-        }
-      }
-    },
-    "grunt-known-options": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz",
-      "integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=",
-      "dev": true
-    },
-    "grunt-legacy-log": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz",
-      "integrity": "sha1-+4bxgJhHvAfcR4Q/ns1srLYt8tU=",
-      "dev": true,
-      "requires": {
-        "colors": "1.1.2",
-        "grunt-legacy-log-utils": "1.0.0",
-        "hooker": "0.2.3",
-        "lodash": "3.10.1",
-        "underscore.string": "3.2.3"
-      },
-      "dependencies": {
-        "colors": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
-          "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
-          "dev": true
-        },
-        "lodash": {
-          "version": "3.10.1",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
-          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
-          "dev": true
-        }
-      }
-    },
-    "grunt-legacy-log-utils": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz",
-      "integrity": "sha1-p7ji0Ps1taUPSvmG/BEnSevJbz0=",
-      "dev": true,
-      "requires": {
-        "chalk": "1.1.3",
-        "lodash": "4.3.0"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
-          "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=",
-          "dev": true
-        }
-      }
-    },
-    "grunt-legacy-util": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz",
-      "integrity": "sha1-OGqnjcbtUJhsKxiVcmWxtIq7m4Y=",
-      "dev": true,
-      "requires": {
-        "async": "1.5.2",
-        "exit": "0.1.2",
-        "getobject": "0.1.0",
-        "hooker": "0.2.3",
-        "lodash": "4.3.0",
-        "underscore.string": "3.2.3",
-        "which": "1.2.14"
-      },
-      "dependencies": {
-        "async": {
-          "version": "1.5.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-          "dev": true
-        },
-        "lodash": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
-          "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=",
-          "dev": true
-        }
-      }
-    },
-    "grunt-webpack": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/grunt-webpack/-/grunt-webpack-3.0.2.tgz",
-      "integrity": "sha512-ghSkdCdvbF1SpI46qDT9FYqw5ZP5sSYbEQU/DwzoJE1K42xizAZ5Rv3kzpaRdJT4yvu8/6fO5+wne3/y0n74QA==",
-      "dev": true,
-      "requires": {
-        "deep-for-each": "1.0.6",
-        "lodash": "4.17.4"
-      }
-    },
-    "handle-thing": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz",
-      "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=",
-      "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.0.3",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
-      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
-      "dev": true,
-      "requires": {
-        "ajv": "5.2.3",
-        "har-schema": "2.0.0"
-      }
-    },
-    "has": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
-      "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
-      "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=",
-      "dev": true,
-      "requires": {
-        "ansi-regex": "2.1.1"
-      }
-    },
-    "has-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-      "dev": true
-    },
-    "hash-base": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
-      "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
-      "dev": true,
-      "requires": {
-        "inherits": "2.0.3"
-      }
-    },
-    "hash.js": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
-      "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
-      "dev": true,
-      "requires": {
-        "inherits": "2.0.3",
-        "minimalistic-assert": "1.0.0"
-      }
-    },
-    "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.1.0",
-        "pinkie-promise": "2.0.1"
-      }
-    },
-    "hawk": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
-      "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
-      "dev": true,
-      "requires": {
-        "boom": "4.3.1",
-        "cryptiles": "3.1.2",
-        "hoek": "4.2.0",
-        "sntp": "2.0.2"
-      }
-    },
-    "he": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
-      "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
-      "dev": true
-    },
-    "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.1.3",
-        "minimalistic-assert": "1.0.0",
-        "minimalistic-crypto-utils": "1.0.1"
-      }
-    },
-    "hoek": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
-      "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==",
-      "dev": true
-    },
-    "home-or-tmp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
-      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
-      "dev": true,
-      "requires": {
-        "os-homedir": "1.0.2",
-        "os-tmpdir": "1.0.2"
-      }
-    },
-    "hooker": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
-      "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
-      "dev": true
-    },
-    "hosted-git-info": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
-      "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
-      "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.3",
-        "obuf": "1.1.1",
-        "readable-stream": "2.3.3",
-        "wbuf": "1.7.2"
-      }
-    },
-    "html-comment-regex": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
-      "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
-      "dev": true
-    },
-    "html-encoding-sniffer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz",
-      "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=",
-      "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.5",
-      "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.5.tgz",
-      "integrity": "sha512-g+1+NBycQI0fGnggd52JM8TRUweG7+9W2wrtjGitMAqc4G7maweAHvVAAjz9veHseIH3tYKE2lk2USGSoewIrQ==",
-      "dev": true,
-      "requires": {
-        "camel-case": "3.0.0",
-        "clean-css": "4.1.9",
-        "commander": "2.11.0",
-        "he": "1.1.1",
-        "ncname": "1.0.0",
-        "param-case": "2.1.1",
-        "relateurl": "0.2.7",
-        "uglify-js": "3.1.3"
-      }
-    },
-    "html-webpack-plugin": {
-      "version": "2.30.1",
-      "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz",
-      "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=",
-      "dev": true,
-      "requires": {
-        "bluebird": "3.5.0",
-        "html-minifier": "3.5.5",
-        "loader-utils": "0.2.17",
-        "lodash": "4.17.4",
-        "pretty-error": "2.1.1",
-        "toposort": "1.0.6"
-      },
-      "dependencies": {
-        "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.2.0",
-            "emojis-list": "2.1.0",
-            "json5": "0.5.1",
-            "object-assign": "4.1.1"
-          }
-        }
-      }
-    },
-    "htmlparser2": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
-      "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=",
-      "dev": true,
-      "requires": {
-        "domelementtype": "1.3.0",
-        "domhandler": "2.1.0",
-        "domutils": "1.1.6",
-        "readable-stream": "1.0.34"
-      },
-      "dependencies": {
-        "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.3.0"
-          }
-        },
-        "isarray": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "1.0.34",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
-          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
-          "dev": true,
-          "requires": {
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "0.0.1",
-            "string_decoder": "0.10.31"
-          }
-        },
-        "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
-        }
-      }
-    },
-    "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.2",
-      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
-      "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
-      "dev": true,
-      "requires": {
-        "depd": "1.1.1",
-        "inherits": "2.0.3",
-        "setprototypeof": "1.0.3",
-        "statuses": "1.3.1"
-      },
-      "dependencies": {
-        "setprototypeof": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
-          "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
-          "dev": true
-        }
-      }
-    },
-    "http-parser-js": {
-      "version": "0.4.8",
-      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.8.tgz",
-      "integrity": "sha512-jmHp99g6/fLx0pRNJqzsQgjsclCHAY7NhIeA3/U+bsGNvgbvUCQFQY9m5AYpqpAxY/2VcikfbKpjQozSTiz0jA==",
-      "dev": true
-    },
-    "http-proxy": {
-      "version": "1.16.2",
-      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
-      "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=",
-      "dev": true,
-      "requires": {
-        "eventemitter3": "1.2.0",
-        "requires-port": "1.0.0"
-      }
-    },
-    "http-proxy-middleware": {
-      "version": "0.17.4",
-      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz",
-      "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=",
-      "dev": true,
-      "requires": {
-        "http-proxy": "1.16.2",
-        "is-glob": "3.1.0",
-        "lodash": "4.17.4",
-        "micromatch": "2.3.11"
-      },
-      "dependencies": {
-        "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-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.1"
-          }
-        }
-      }
-    },
-    "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.4.1",
-        "sshpk": "1.13.1"
-      }
-    },
-    "https-browserify": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
-      "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=",
-      "dev": true
-    },
-    "iced-error": {
-      "version": "0.0.12",
-      "resolved": "https://registry.npmjs.org/iced-error/-/iced-error-0.0.12.tgz",
-      "integrity": "sha1-4KhhRigXzwzpdLE/ymEtOg1dEL4="
-    },
-    "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.3"
-      }
-    },
-    "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.19",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
-      "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
-      "dev": true
-    },
-    "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": "2.1.0",
-      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz",
-      "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
-      "dev": true,
-      "requires": {
-        "postcss": "6.0.12"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "ieee754": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
-      "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
-      "dev": true
-    },
-    "ignore": {
-      "version": "3.3.5",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
-      "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==",
-      "dev": true
-    },
-    "image-size": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
-      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
-      "dev": true,
-      "optional": true
-    },
-    "imports-loader": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.7.1.tgz",
-      "integrity": "sha1-8gS180cCoywdt9SNidXoZ6BEElM=",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0",
-        "source-map": "0.5.7"
-      }
-    },
-    "imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "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.1"
-      }
-    },
-    "indexes-of": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
-      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
-      "dev": true
-    },
-    "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.4.0",
-        "wrappy": "1.0.2"
-      }
-    },
-    "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.4",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
-      "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
-      "dev": true
-    },
-    "ink-docstrap": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/ink-docstrap/-/ink-docstrap-1.3.0.tgz",
-      "integrity": "sha1-6QBeW7kCXMmpvo5ErYf4rViIyB0=",
-      "dev": true,
-      "requires": {
-        "moment": "2.18.1",
-        "sanitize-html": "1.14.1"
-      }
-    },
-    "inquirer": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
-      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
-      "dev": true,
-      "requires": {
-        "ansi-escapes": "3.0.0",
-        "chalk": "2.1.0",
-        "cli-cursor": "2.1.0",
-        "cli-width": "2.2.0",
-        "external-editor": "2.0.5",
-        "figures": "2.0.0",
-        "lodash": "4.17.4",
-        "mute-stream": "0.0.7",
-        "run-async": "2.3.0",
-        "rx-lite": "4.0.8",
-        "rx-lite-aggregates": "4.0.8",
-        "string-width": "2.1.1",
-        "strip-ansi": "4.0.0",
-        "through": "2.3.8"
-      },
-      "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.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "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": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "internal-ip": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz",
-      "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=",
-      "dev": true,
-      "requires": {
-        "meow": "3.7.0"
-      }
-    },
-    "interpret": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz",
-      "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=",
-      "dev": true
-    },
-    "invariant": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
-      "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
-      "dev": true,
-      "requires": {
-        "loose-envify": "1.3.1"
-      }
-    },
-    "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
-    },
-    "ipaddr.js": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
-      "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=",
-      "dev": true
-    },
-    "is-absolute-url": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
-      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
-      "dev": true
-    },
-    "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.10.0"
-      }
-    },
-    "is-buffer": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
-      "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
-      "dev": true
-    },
-    "is-builtin-module": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
-      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
-      "dev": true,
-      "requires": {
-        "builtin-modules": "1.1.1"
-      }
-    },
-    "is-callable": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
-      "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
-      "dev": true
-    },
-    "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-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-dotfile": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
-      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
-      "dev": true
-    },
-    "is-equal-shallow": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
-      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
-      "dev": true,
-      "requires": {
-        "is-primitive": "2.0.0"
-      }
-    },
-    "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": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
-      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
-      "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.1"
-      }
-    },
-    "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-glob": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
-      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
-      "dev": true,
-      "requires": {
-        "is-extglob": "1.0.0"
-      }
-    },
-    "is-number": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
-      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
-      "dev": true,
-      "requires": {
-        "kind-of": "3.2.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.0",
-      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
-      "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
-      "dev": true,
-      "requires": {
-        "is-path-inside": "1.0.0"
-      }
-    },
-    "is-path-inside": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
-      "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
-      "dev": true,
-      "requires": {
-        "path-is-inside": "1.0.2"
-      }
-    },
-    "is-plain-obj": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
-      "dev": true
-    },
-    "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-posix-bracket": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
-      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
-      "dev": true
-    },
-    "is-primitive": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
-      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
-      "dev": true
-    },
-    "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-resolvable": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
-      "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
-      "dev": true,
-      "requires": {
-        "tryit": "1.0.3"
-      }
-    },
-    "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-svg": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
-      "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
-      "dev": true,
-      "requires": {
-        "html-comment-regex": "1.1.1"
-      }
-    },
-    "is-symbol": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
-      "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
-      "dev": true
-    },
-    "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-utf8": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
-      "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
-    },
-    "isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "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
-    },
-    "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.10",
-        "escodegen": "0.0.21",
-        "esprima": "1.0.4",
-        "jison-lex": "0.2.1",
-        "lex-parser": "0.1.4",
-        "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.4",
-            "estraverse": "0.0.4",
-            "source-map": "0.5.7"
-          }
-        },
-        "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.4",
-        "nomnom": "1.5.2"
-      }
-    },
-    "jquery": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
-      "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c="
-    },
-    "js-base64": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
-      "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==",
-      "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-sha3": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz",
-      "integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA="
-    },
-    "js-tokens": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-      "dev": true
-    },
-    "js-yaml": {
-      "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
-      "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
-      "dev": true,
-      "requires": {
-        "argparse": "1.0.9",
-        "esprima": "2.7.3"
-      },
-      "dependencies": {
-        "esprima": {
-          "version": "2.7.3",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
-          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
-          "dev": true
-        }
-      }
-    },
-    "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.2"
-      }
-    },
-    "jsbn": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
-      "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA="
-    },
-    "jschardet": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz",
-      "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==",
-      "dev": true
-    },
-    "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.11"
-          }
-        },
-        "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.3.0",
-      "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.3.0.tgz",
-      "integrity": "sha1-Lqrv2eyo2LeIRTlKHM6diJa+++E=",
-      "dev": true,
-      "requires": {
-        "lodash": "4.17.4"
-      }
-    },
-    "jsdom": {
-      "version": "9.12.0",
-      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz",
-      "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=",
-      "dev": true,
-      "requires": {
-        "abab": "1.0.4",
-        "acorn": "4.0.13",
-        "acorn-globals": "3.1.0",
-        "array-equal": "1.0.0",
-        "content-type-parser": "1.0.1",
-        "cssom": "0.3.2",
-        "cssstyle": "0.2.37",
-        "escodegen": "1.9.0",
-        "html-encoding-sniffer": "1.0.1",
-        "nwmatcher": "1.4.2",
-        "parse5": "1.5.1",
-        "request": "2.83.0",
-        "sax": "1.2.4",
-        "symbol-tree": "3.2.2",
-        "tough-cookie": "2.3.3",
-        "webidl-conversions": "4.0.2",
-        "whatwg-encoding": "1.0.1",
-        "whatwg-url": "4.8.0",
-        "xml-name-validator": "2.0.1"
-      }
-    },
-    "jsesc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
-      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
-      "dev": true
-    },
-    "json-loader": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
-      "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
-      "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.3.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
-      "dev": true
-    },
-    "json-stable-stringify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
-      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
-      "dev": true,
-      "requires": {
-        "jsonify": "0.0.0"
-      }
-    },
-    "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": "0.5.1",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
-      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
-      "dev": true
-    },
-    "jsonfile": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
-      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11"
-      }
-    },
-    "jsonify": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
-      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
-      "dev": true
-    },
-    "jsonpath": {
-      "version": "0.2.12",
-      "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-0.2.12.tgz",
-      "integrity": "sha1-W/nZEftGFsHjNwvs658NskrjTNI=",
-      "requires": {
-        "esprima": "1.2.2",
-        "jison": "0.4.13",
-        "static-eval": "0.2.3",
-        "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="
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "jsrsasign": {
-      "version": "8.0.4",
-      "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.4.tgz",
-      "integrity": "sha1-P3uCOIRPEmtJanVW7J9LUR+V+GE="
-    },
-    "kbpgp": {
-      "version": "2.0.76",
-      "resolved": "https://registry.npmjs.org/kbpgp/-/kbpgp-2.0.76.tgz",
-      "integrity": "sha1-qKtufM8279812BNdfJb/bpSLMAI=",
-      "requires": {
-        "bn": "1.0.1",
-        "bzip-deflate": "1.0.0",
-        "deep-equal": "1.0.1",
-        "iced-error": "0.0.12",
-        "iced-lock": "1.1.0",
-        "iced-runtime": "1.0.3",
-        "keybase-ecurve": "1.0.0",
-        "keybase-nacl": "1.0.10",
-        "minimist": "1.2.0",
-        "pgp-utils": "0.0.34",
-        "purepack": "1.0.4",
-        "triplesec": "3.0.26",
-        "tweetnacl": "0.13.3"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
-        },
-        "tweetnacl": {
-          "version": "0.13.3",
-          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz",
-          "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y="
-        }
-      }
-    },
-    "kew": {
-      "version": "0.7.0",
-      "resolved": "https://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.1"
-      }
-    },
-    "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.3",
-        "tweetnacl": "0.13.3",
-        "uint64be": "1.0.1"
-      },
-      "dependencies": {
-        "tweetnacl": {
-          "version": "0.13.3",
-          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz",
-          "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y="
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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.11"
-      }
-    },
-    "lazy-cache": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
-      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
-      "dev": true
-    },
-    "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"
-      }
-    },
-    "less": {
-      "version": "2.7.2",
-      "resolved": "https://registry.npmjs.org/less/-/less-2.7.2.tgz",
-      "integrity": "sha1-No1sxz4fsDmBGDKAkYdDxdz5s98=",
-      "dev": true,
-      "requires": {
-        "errno": "0.1.4",
-        "graceful-fs": "4.1.11",
-        "image-size": "0.5.5",
-        "mime": "1.4.1",
-        "mkdirp": "0.5.1",
-        "promise": "7.3.1",
-        "request": "2.83.0",
-        "source-map": "0.5.7"
-      }
-    },
-    "less-loader": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.0.5.tgz",
-      "integrity": "sha1-rhVadAbKxqzSk9eFWH/P8PR4xN0=",
-      "dev": true,
-      "requires": {
-        "clone": "2.1.1",
-        "loader-utils": "1.1.0",
-        "pify": "2.3.0"
-      },
-      "dependencies": {
-        "clone": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
-          "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
-          "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="
-    },
-    "load-json-file": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
-      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11",
-        "parse-json": "2.2.0",
-        "pify": "2.3.0",
-        "pinkie-promise": "2.0.1",
-        "strip-bom": "2.0.0"
-      }
-    },
-    "loader-runner": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
-      "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
-      "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.2.0",
-        "emojis-list": "2.1.0",
-        "json5": "0.5.1"
-      }
-    },
-    "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.4",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
-      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
-    },
-    "lodash.camelcase": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
-      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
-      "dev": true
-    },
-    "lodash.memoize": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
-      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
-      "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
-    },
-    "lodash.uniq": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
-      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
-      "dev": true
-    },
-    "loglevel": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.5.0.tgz",
-      "integrity": "sha512-OQ2jhWI5G2qsvO0UFNyCQWgKl/tFiwuPIXxELzACeUO2FqstN/R7mmL09+nhv6xOWVPPojQO1A90sCEoJSgBcQ==",
-      "dev": true
-    },
-    "longest": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
-      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
-      "dev": true
-    },
-    "loose-envify": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-      "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-      "dev": true,
-      "requires": {
-        "js-tokens": "3.0.2"
-      }
-    },
-    "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.2"
-      }
-    },
-    "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.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
-      "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
-      "dev": true,
-      "requires": {
-        "pseudomap": "1.0.2",
-        "yallist": "2.1.2"
-      }
-    },
-    "macaddress": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
-      "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=",
-      "dev": true
-    },
-    "make-dir": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
-      "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
-      "dev": true,
-      "requires": {
-        "pify": "3.0.0"
-      },
-      "dependencies": {
-        "pify": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
-          "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
-    },
-    "marked": {
-      "version": "0.3.6",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz",
-      "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=",
-      "dev": true
-    },
-    "math-expression-evaluator": {
-      "version": "1.2.17",
-      "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
-      "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
-      "dev": true
-    },
-    "md5.js": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
-      "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
-      "dev": true,
-      "requires": {
-        "hash-base": "3.0.4",
-        "inherits": "2.0.3"
-      },
-      "dependencies": {
-        "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.3",
-            "safe-buffer": "5.1.1"
-          }
-        }
-      }
-    },
-    "media-typer": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
-      "dev": true
-    },
-    "mem": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
-      "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
-      "dev": true,
-      "requires": {
-        "mimic-fn": "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.4",
-        "readable-stream": "2.3.3"
-      }
-    },
-    "meow": {
-      "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
-      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
-      "dev": true,
-      "requires": {
-        "camelcase-keys": "2.1.0",
-        "decamelize": "1.2.0",
-        "loud-rejection": "1.6.0",
-        "map-obj": "1.0.1",
-        "minimist": "1.2.0",
-        "normalize-package-data": "2.4.0",
-        "object-assign": "4.1.1",
-        "read-pkg-up": "1.0.1",
-        "redent": "1.0.0",
-        "trim-newlines": "1.0.0"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        }
-      }
-    },
-    "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": "2.3.11",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
-      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
-      "dev": true,
-      "requires": {
-        "arr-diff": "2.0.0",
-        "array-unique": "0.2.1",
-        "braces": "1.8.5",
-        "expand-brackets": "0.1.5",
-        "extglob": "0.3.2",
-        "filename-regex": "2.0.1",
-        "is-extglob": "1.0.0",
-        "is-glob": "2.0.1",
-        "kind-of": "3.2.2",
-        "normalize-path": "2.1.1",
-        "object.omit": "2.0.1",
-        "parse-glob": "3.0.4",
-        "regex-cache": "0.4.4"
-      }
-    },
-    "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.11.8",
-        "brorand": "1.1.0"
-      }
-    },
-    "mime": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
-      "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
-      "dev": true
-    },
-    "mime-db": {
-      "version": "1.30.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
-      "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
-      "dev": true
-    },
-    "mime-types": {
-      "version": "2.1.17",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
-      "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
-      "dev": true,
-      "requires": {
-        "mime-db": "1.30.0"
-      }
-    },
-    "mimer": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.2.1.tgz",
-      "integrity": "sha1-xjxaF/6GQj9RYahdVcPtUYm6r/w=",
-      "dev": true
-    },
-    "mimic-fn": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
-      "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
-      "dev": true
-    },
-    "minimalistic-assert": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
-      "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
-      "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.8"
-      }
-    },
-    "minimist": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-      "dev": true
-    },
-    "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "dev": true,
-      "requires": {
-        "minimist": "0.0.8"
-      }
-    },
-    "moment": {
-      "version": "2.18.1",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
-      "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
-    },
-    "moment-timezone": {
-      "version": "0.5.13",
-      "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.13.tgz",
-      "integrity": "sha1-mc5cfYJyYusPH3AgRBd/YHRde5A=",
-      "requires": {
-        "moment": "2.18.1"
-      }
-    },
-    "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": "1.0.3"
-      }
-    },
-    "ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-      "dev": true
-    },
-    "multicast-dns": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.1.1.tgz",
-      "integrity": "sha1-bn3oalcIcqsXBYrepxYLvsqBTd4=",
-      "dev": true,
-      "requires": {
-        "dns-packet": "1.2.2",
-        "thunky": "0.1.0"
-      }
-    },
-    "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
-    },
-    "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.8.0",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
-      "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=",
-      "dev": true,
-      "optional": true
-    },
-    "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
-    },
-    "ncname": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz",
-      "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=",
-      "dev": true,
-      "requires": {
-        "xml-char-classes": "1.0.0"
-      }
-    },
-    "negotiator": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
-      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
-      "dev": true
-    },
-    "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.4"
-      }
-    },
-    "node-forge": {
-      "version": "0.6.33",
-      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.33.tgz",
-      "integrity": "sha1-RjgRh59XPUUVWtap9D3ClujoXrw=",
-      "dev": true
-    },
-    "node-libs-browser": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz",
-      "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=",
-      "dev": true,
-      "requires": {
-        "assert": "1.4.1",
-        "browserify-zlib": "0.1.4",
-        "buffer": "4.9.1",
-        "console-browserify": "1.1.0",
-        "constants-browserify": "1.0.0",
-        "crypto-browserify": "3.11.1",
-        "domain-browser": "1.1.7",
-        "events": "1.1.1",
-        "https-browserify": "0.0.1",
-        "os-browserify": "0.2.1",
-        "path-browserify": "0.0.0",
-        "process": "0.11.10",
-        "punycode": "1.4.1",
-        "querystring-es3": "0.2.1",
-        "readable-stream": "2.3.3",
-        "stream-browserify": "2.0.1",
-        "stream-http": "2.7.2",
-        "string_decoder": "0.10.31",
-        "timers-browserify": "2.0.4",
-        "tty-browserify": "0.0.0",
-        "url": "0.11.0",
-        "util": "0.10.3",
-        "vm-browserify": "0.0.4"
-      },
-      "dependencies": {
-        "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
-        }
-      }
-    },
-    "node-md6": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/node-md6/-/node-md6-0.1.0.tgz",
-      "integrity": "sha1-9WH0WyszY1K4KXbFHMoRR9U5N/U="
-    },
-    "nomnom": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz",
-      "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=",
-      "requires": {
-        "colors": "0.5.1",
-        "underscore": "1.1.7"
-      },
-      "dependencies": {
-        "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.1.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.5.0",
-        "is-builtin-module": "1.0.0",
-        "semver": "5.4.1",
-        "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.1.0"
-      }
-    },
-    "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
-    },
-    "normalize-url": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
-      "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
-      "dev": true,
-      "requires": {
-        "object-assign": "4.1.1",
-        "prepend-http": "1.0.4",
-        "query-string": "4.3.4",
-        "sort-keys": "1.1.2"
-      }
-    },
-    "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.1"
-      }
-    },
-    "nth-check": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
-      "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
-      "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.2",
-      "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.2.tgz",
-      "integrity": "sha512-QMkCGQFYp5p+zwU3INntLmz1HMfSx9dMVJMYKmE1yuSf/22Wjo6VPFa405mCLUuQn9lbQvH2DZN9lt10ZNvtAg==",
-      "dev": true
-    },
-    "oauth-sign": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
-      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
-      "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-keys": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
-      "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
-      "dev": true
-    },
-    "object.omit": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
-      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
-      "dev": true,
-      "requires": {
-        "for-own": "0.1.5",
-        "is-extendable": "0.1.1"
-      }
-    },
-    "obuf": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz",
-      "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=",
-      "dev": true
-    },
-    "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.0.2"
-      }
-    },
-    "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.1.0"
-      }
-    },
-    "opn": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz",
-      "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==",
-      "dev": true,
-      "requires": {
-        "is-wsl": "1.1.0"
-      }
-    },
-    "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.6",
-        "levn": "0.3.0",
-        "prelude-ls": "1.1.2",
-        "type-check": "0.3.2",
-        "wordwrap": "1.0.0"
-      }
-    },
-    "original": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz",
-      "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=",
-      "dev": true,
-      "requires": {
-        "url-parse": "1.0.5"
-      },
-      "dependencies": {
-        "url-parse": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz",
-          "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=",
-          "dev": true,
-          "requires": {
-            "querystringify": "0.0.4",
-            "requires-port": "1.0.0"
-          }
-        }
-      }
-    },
-    "os-browserify": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz",
-      "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=",
-      "dev": true
-    },
-    "os-homedir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
-      "dev": true
-    },
-    "os-locale": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
-      "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
-      "dev": true,
-      "requires": {
-        "execa": "0.7.0",
-        "lcid": "1.0.0",
-        "mem": "1.1.0"
-      }
-    },
-    "os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-      "dev": true
-    },
-    "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-finally": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
-      "dev": true
-    },
-    "p-limit": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
-      "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
-      "dev": true
-    },
-    "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
-    },
-    "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.7.0",
-        "pumpify": "1.3.5",
-        "repeating": "2.0.1",
-        "split2": "1.1.1",
-        "through2": "2.0.3"
-      }
-    },
-    "pako": {
-      "version": "0.2.9",
-      "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
-      "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
-      "dev": true
-    },
-    "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.3.2"
-      }
-    },
-    "parse-asn1": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
-      "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
-      "dev": true,
-      "requires": {
-        "asn1.js": "4.9.1",
-        "browserify-aes": "1.0.8",
-        "create-hash": "1.1.3",
-        "evp_bytestokey": "1.0.3",
-        "pbkdf2": "3.0.14"
-      }
-    },
-    "parse-glob": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
-      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
-      "dev": true,
-      "requires": {
-        "glob-base": "0.3.0",
-        "is-dotfile": "1.0.3",
-        "is-extglob": "1.0.0",
-        "is-glob": "2.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.3.1"
-      }
-    },
-    "parse5": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
-      "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=",
-      "dev": true
-    },
-    "parseurl": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
-      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
-      "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-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": "https://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-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.11",
-        "pify": "2.3.0",
-        "pinkie-promise": "2.0.1"
-      }
-    },
-    "pbkdf2": {
-      "version": "3.0.14",
-      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
-      "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
-      "dev": true,
-      "requires": {
-        "create-hash": "1.1.3",
-        "create-hmac": "1.1.6",
-        "ripemd160": "2.0.1",
-        "safe-buffer": "5.1.1",
-        "sha.js": "2.4.9"
-      }
-    },
-    "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.12",
-        "iced-runtime": "1.0.3"
-      }
-    },
-    "phantomjs-prebuilt": {
-      "version": "2.1.15",
-      "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.15.tgz",
-      "integrity": "sha1-IPhugtM0nFBZF1J3RbekEeCLOQM=",
-      "dev": true,
-      "requires": {
-        "es6-promise": "4.0.5",
-        "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.14"
-      },
-      "dependencies": {
-        "ajv": {
-          "version": "4.11.8",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
-          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
-          "dev": true,
-          "requires": {
-            "co": "4.6.0",
-            "json-stable-stringify": "1.0.1"
-          }
-        },
-        "assert-plus": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
-          "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
-          "dev": true
-        },
-        "aws-sign2": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
-          "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
-          "dev": true
-        },
-        "boom": {
-          "version": "2.10.1",
-          "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
-          "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
-          "dev": true,
-          "requires": {
-            "hoek": "2.16.3"
-          }
-        },
-        "cryptiles": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
-          "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
-          "dev": true,
-          "requires": {
-            "boom": "2.10.1"
-          }
-        },
-        "form-data": {
-          "version": "2.1.4",
-          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
-          "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
-          "dev": true,
-          "requires": {
-            "asynckit": "0.4.0",
-            "combined-stream": "1.0.5",
-            "mime-types": "2.1.17"
-          }
-        },
-        "har-schema": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
-          "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
-          "dev": true
-        },
-        "har-validator": {
-          "version": "4.2.1",
-          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
-          "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
-          "dev": true,
-          "requires": {
-            "ajv": "4.11.8",
-            "har-schema": "1.0.5"
-          }
-        },
-        "hawk": {
-          "version": "3.1.3",
-          "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
-          "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
-          "dev": true,
-          "requires": {
-            "boom": "2.10.1",
-            "cryptiles": "2.0.5",
-            "hoek": "2.16.3",
-            "sntp": "1.0.9"
-          }
-        },
-        "hoek": {
-          "version": "2.16.3",
-          "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
-          "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
-          "dev": true
-        },
-        "http-signature": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
-          "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
-          "dev": true,
-          "requires": {
-            "assert-plus": "0.2.0",
-            "jsprim": "1.4.1",
-            "sshpk": "1.13.1"
-          }
-        },
-        "performance-now": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
-          "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
-          "dev": true
-        },
-        "qs": {
-          "version": "6.4.0",
-          "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
-          "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
-          "dev": true
-        },
-        "request": {
-          "version": "2.81.0",
-          "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
-          "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
-          "dev": true,
-          "requires": {
-            "aws-sign2": "0.6.0",
-            "aws4": "1.6.0",
-            "caseless": "0.12.0",
-            "combined-stream": "1.0.5",
-            "extend": "3.0.1",
-            "forever-agent": "0.6.1",
-            "form-data": "2.1.4",
-            "har-validator": "4.2.1",
-            "hawk": "3.1.3",
-            "http-signature": "1.1.1",
-            "is-typedarray": "1.0.0",
-            "isstream": "0.1.2",
-            "json-stringify-safe": "5.0.1",
-            "mime-types": "2.1.17",
-            "oauth-sign": "0.8.2",
-            "performance-now": "0.2.0",
-            "qs": "6.4.0",
-            "safe-buffer": "5.1.1",
-            "stringstream": "0.0.5",
-            "tough-cookie": "2.3.3",
-            "tunnel-agent": "0.6.0",
-            "uuid": "3.1.0"
-          }
-        },
-        "sntp": {
-          "version": "1.0.9",
-          "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
-          "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
-          "dev": true,
-          "requires": {
-            "hoek": "2.16.3"
-          }
-        }
-      }
-    },
-    "pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "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.4"
-      }
-    },
-    "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"
-      }
-    },
-    "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
-    },
-    "portfinder": {
-      "version": "1.0.13",
-      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz",
-      "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=",
-      "dev": true,
-      "requires": {
-        "async": "1.5.2",
-        "debug": "2.6.9",
-        "mkdirp": "0.5.1"
-      },
-      "dependencies": {
-        "async": {
-          "version": "1.5.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
-          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
-          "dev": true
-        }
-      }
-    },
-    "postcss": {
-      "version": "5.2.17",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz",
-      "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=",
-      "dev": true,
-      "requires": {
-        "chalk": "1.1.3",
-        "js-base64": "2.3.2",
-        "source-map": "0.5.7",
-        "supports-color": "3.2.3"
-      },
-      "dependencies": {
-        "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
-          "dev": true,
-          "requires": {
-            "has-flag": "1.0.0"
-          }
-        }
-      }
-    },
-    "postcss-calc": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
-      "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17",
-        "postcss-message-helpers": "2.0.0",
-        "reduce-css-calc": "1.3.0"
-      }
-    },
-    "postcss-colormin": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
-      "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
-      "dev": true,
-      "requires": {
-        "colormin": "1.1.2",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-convert-values": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz",
-      "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-css-variables": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/postcss-css-variables/-/postcss-css-variables-0.8.0.tgz",
-      "integrity": "sha512-ilcsJMhq09HOsQ2RzXm+fPQNEwMN3kLab6IYpcL5EH8E1EKvBrWQRsiWONWqjWPAKHFMWkEvJTHJJzP9m1E0yQ==",
-      "dev": true,
-      "requires": {
-        "escape-string-regexp": "1.0.5",
-        "extend": "3.0.1",
-        "postcss": "6.0.12"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "postcss-discard-comments": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
-      "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17"
-      }
-    },
-    "postcss-discard-duplicates": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz",
-      "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17"
-      }
-    },
-    "postcss-discard-empty": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
-      "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17"
-      }
-    },
-    "postcss-discard-overridden": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
-      "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17"
-      }
-    },
-    "postcss-discard-unused": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
-      "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17",
-        "uniqs": "2.0.0"
-      }
-    },
-    "postcss-filter-plugins": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz",
-      "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17",
-        "uniqid": "4.1.1"
-      }
-    },
-    "postcss-import": {
-      "version": "11.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.0.0.tgz",
-      "integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=",
-      "dev": true,
-      "requires": {
-        "postcss": "6.0.12",
-        "postcss-value-parser": "3.3.0",
-        "read-cache": "1.0.0",
-        "resolve": "1.1.7"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "postcss-load-config": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
-      "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
-      "dev": true,
-      "requires": {
-        "cosmiconfig": "2.2.2",
-        "object-assign": "4.1.1",
-        "postcss-load-options": "1.2.0",
-        "postcss-load-plugins": "2.3.0"
-      }
-    },
-    "postcss-load-options": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
-      "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=",
-      "dev": true,
-      "requires": {
-        "cosmiconfig": "2.2.2",
-        "object-assign": "4.1.1"
-      }
-    },
-    "postcss-load-plugins": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
-      "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=",
-      "dev": true,
-      "requires": {
-        "cosmiconfig": "2.2.2",
-        "object-assign": "4.1.1"
-      }
-    },
-    "postcss-loader": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.6.tgz",
-      "integrity": "sha512-HIq7yy1hh9KI472Y38iSRV4WupZUNy6zObkxQM/ZuInoaE2+PyX4NcO6jjP5HG5mXL7j5kcNEl0fAG4Kva7O9w==",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0",
-        "postcss": "6.0.12",
-        "postcss-load-config": "1.2.0",
-        "schema-utils": "0.3.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "postcss-merge-idents": {
-      "version": "2.1.7",
-      "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz",
-      "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=",
-      "dev": true,
-      "requires": {
-        "has": "1.0.1",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-merge-longhand": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz",
-      "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17"
-      }
-    },
-    "postcss-merge-rules": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz",
-      "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=",
-      "dev": true,
-      "requires": {
-        "browserslist": "1.7.7",
-        "caniuse-api": "1.6.1",
-        "postcss": "5.2.17",
-        "postcss-selector-parser": "2.2.3",
-        "vendors": "1.0.1"
-      },
-      "dependencies": {
-        "browserslist": {
-          "version": "1.7.7",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
-          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
-          "dev": true,
-          "requires": {
-            "caniuse-db": "1.0.30000741",
-            "electron-to-chromium": "1.3.24"
-          }
-        }
-      }
-    },
-    "postcss-message-helpers": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz",
-      "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=",
-      "dev": true
-    },
-    "postcss-minify-font-values": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz",
-      "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=",
-      "dev": true,
-      "requires": {
-        "object-assign": "4.1.1",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-minify-gradients": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
-      "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-minify-params": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz",
-      "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=",
-      "dev": true,
-      "requires": {
-        "alphanum-sort": "1.0.2",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0",
-        "uniqs": "2.0.0"
-      }
-    },
-    "postcss-minify-selectors": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz",
-      "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=",
-      "dev": true,
-      "requires": {
-        "alphanum-sort": "1.0.2",
-        "has": "1.0.1",
-        "postcss": "5.2.17",
-        "postcss-selector-parser": "2.2.3"
-      }
-    },
-    "postcss-modules-extract-imports": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz",
-      "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=",
-      "dev": true,
-      "requires": {
-        "postcss": "6.0.12"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "postcss-modules-local-by-default": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
-      "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
-      "dev": true,
-      "requires": {
-        "css-selector-tokenizer": "0.7.0",
-        "postcss": "6.0.12"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "postcss-modules-scope": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
-      "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
-      "dev": true,
-      "requires": {
-        "css-selector-tokenizer": "0.7.0",
-        "postcss": "6.0.12"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "postcss-modules-values": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
-      "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
-      "dev": true,
-      "requires": {
-        "icss-replace-symbols": "1.1.0",
-        "postcss": "6.0.12"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.12",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
-          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.1.0",
-            "source-map": "0.5.7",
-            "supports-color": "4.4.0"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "postcss-normalize-charset": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz",
-      "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17"
-      }
-    },
-    "postcss-normalize-url": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz",
-      "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=",
-      "dev": true,
-      "requires": {
-        "is-absolute-url": "2.1.0",
-        "normalize-url": "1.9.1",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-ordered-values": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz",
-      "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-reduce-idents": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz",
-      "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-reduce-initial": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz",
-      "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
-      "dev": true,
-      "requires": {
-        "postcss": "5.2.17"
-      }
-    },
-    "postcss-reduce-transforms": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz",
-      "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=",
-      "dev": true,
-      "requires": {
-        "has": "1.0.1",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0"
-      }
-    },
-    "postcss-selector-parser": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
-      "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
-      "dev": true,
-      "requires": {
-        "flatten": "1.0.2",
-        "indexes-of": "1.0.1",
-        "uniq": "1.0.1"
-      }
-    },
-    "postcss-svgo": {
-      "version": "2.1.6",
-      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz",
-      "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=",
-      "dev": true,
-      "requires": {
-        "is-svg": "2.1.0",
-        "postcss": "5.2.17",
-        "postcss-value-parser": "3.3.0",
-        "svgo": "0.7.2"
-      }
-    },
-    "postcss-unique-selectors": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz",
-      "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=",
-      "dev": true,
-      "requires": {
-        "alphanum-sort": "1.0.2",
-        "postcss": "5.2.17",
-        "uniqs": "2.0.0"
-      }
-    },
-    "postcss-value-parser": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
-      "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
-      "dev": true
-    },
-    "postcss-zindex": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz",
-      "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=",
-      "dev": true,
-      "requires": {
-        "has": "1.0.1",
-        "postcss": "5.2.17",
-        "uniqs": "2.0.0"
-      }
-    },
-    "prelude-ls": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
-    },
-    "prepend-http": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
-      "dev": true
-    },
-    "preserve": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
-      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
-      "dev": true
-    },
-    "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.0"
-      }
-    },
-    "private": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz",
-      "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=",
-      "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": "1.0.7",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
-      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
-      "dev": true
-    },
-    "progress": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
-      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74="
-    },
-    "promise": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
-      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "asap": "2.0.6"
-      }
-    },
-    "proxy-addr": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
-      "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
-      "dev": true,
-      "requires": {
-        "forwarded": "0.1.2",
-        "ipaddr.js": "1.5.2"
-      }
-    },
-    "prr": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
-      "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=",
-      "dev": true
-    },
-    "pseudomap": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
-      "dev": true
-    },
-    "public-encrypt": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
-      "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
-      "dev": true,
-      "requires": {
-        "bn.js": "4.11.8",
-        "browserify-rsa": "4.0.1",
-        "create-hash": "1.1.3",
-        "parse-asn1": "5.1.0",
-        "randombytes": "2.0.5"
-      }
-    },
-    "pump": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz",
-      "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=",
-      "dev": true,
-      "requires": {
-        "end-of-stream": "1.4.0",
-        "once": "1.4.0"
-      }
-    },
-    "pumpify": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz",
-      "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=",
-      "dev": true,
-      "requires": {
-        "duplexify": "3.5.1",
-        "inherits": "2.0.3",
-        "pump": "1.0.2"
-      }
-    },
-    "punycode": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
-      "dev": true
-    },
-    "purepack": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/purepack/-/purepack-1.0.4.tgz",
-      "integrity": "sha1-CGKC/ZOShfWGZLqam7oxzbFlzNI="
-    },
-    "q": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
-      "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
-      "dev": true
-    },
-    "qs": {
-      "version": "6.5.1",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
-      "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
-      "dev": true
-    },
-    "query-string": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
-      "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
-      "dev": true,
-      "requires": {
-        "object-assign": "4.1.1",
-        "strict-uri-encode": "1.1.0"
-      }
-    },
-    "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": "0.0.4",
-      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz",
-      "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=",
-      "dev": true
-    },
-    "randomatic": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
-      "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
-      "dev": true,
-      "requires": {
-        "is-number": "3.0.0",
-        "kind-of": "4.0.0"
-      },
-      "dependencies": {
-        "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.2.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"
-              }
-            }
-          }
-        },
-        "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"
-          }
-        }
-      }
-    },
-    "randombytes": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
-      "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "5.1.1"
-      }
-    },
-    "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": "2.3.2",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
-      "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
-      "dev": true,
-      "requires": {
-        "bytes": "3.0.0",
-        "http-errors": "1.6.2",
-        "iconv-lite": "0.4.19",
-        "unpipe": "1.0.0"
-      }
-    },
-    "rc": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
-      "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
-      "dev": true,
-      "requires": {
-        "deep-extend": "0.4.2",
-        "ini": "1.3.4",
-        "minimist": "1.2.0",
-        "strip-json-comments": "2.0.1"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "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.1.0",
-        "normalize-package-data": "2.4.0",
-        "path-type": "1.1.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.1.2",
-        "read-pkg": "1.1.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.1.0",
-            "pinkie-promise": "2.0.1"
-          }
-        },
-        "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.1"
-          }
-        }
-      }
-    },
-    "readable-stream": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
-      "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
-      "dev": true,
-      "requires": {
-        "core-util-is": "1.0.2",
-        "inherits": "2.0.3",
-        "isarray": "1.0.0",
-        "process-nextick-args": "1.0.7",
-        "safe-buffer": "5.1.1",
-        "string_decoder": "1.0.3",
-        "util-deprecate": "1.0.2"
-      }
-    },
-    "readdirp": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
-      "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11",
-        "minimatch": "3.0.4",
-        "readable-stream": "2.3.3",
-        "set-immediate-shim": "1.0.1"
-      }
-    },
-    "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"
-      }
-    },
-    "reduce-css-calc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
-      "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
-      "dev": true,
-      "requires": {
-        "balanced-match": "0.4.2",
-        "math-expression-evaluator": "1.2.17",
-        "reduce-function-call": "1.0.2"
-      },
-      "dependencies": {
-        "balanced-match": {
-          "version": "0.4.2",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
-          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
-          "dev": true
-        }
-      }
-    },
-    "reduce-function-call": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
-      "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
-      "dev": true,
-      "requires": {
-        "balanced-match": "0.4.2"
-      },
-      "dependencies": {
-        "balanced-match": {
-          "version": "0.4.2",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
-          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
-          "dev": true
-        }
-      }
-    },
-    "regenerate": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
-      "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
-      "dev": true
-    },
-    "regenerator-runtime": {
-      "version": "0.10.5",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
-      "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
-      "dev": true
-    },
-    "regenerator-transform": {
-      "version": "0.10.1",
-      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
-      "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
-      "dev": true,
-      "requires": {
-        "babel-runtime": "6.26.0",
-        "babel-types": "6.26.0",
-        "private": "0.1.7"
-      }
-    },
-    "regex-cache": {
-      "version": "0.4.4",
-      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
-      "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
-      "dev": true,
-      "requires": {
-        "is-equal-shallow": "0.1.3"
-      }
-    },
-    "regexp-quote": {
-      "version": "0.0.0",
-      "resolved": "https://registry.npmjs.org/regexp-quote/-/regexp-quote-0.0.0.tgz",
-      "integrity": "sha1-Hg9GUMhi3L/tVP1CsUjpuxch/PI=",
-      "dev": true
-    },
-    "regexpu-core": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
-      "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
-      "dev": true,
-      "requires": {
-        "regenerate": "1.3.3",
-        "regjsgen": "0.2.0",
-        "regjsparser": "0.1.5"
-      }
-    },
-    "regjsgen": {
-      "version": "0.2.0",
-      "resolved": "https://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"
-      },
-      "dependencies": {
-        "jsesc": {
-          "version": "0.5.0",
-          "resolved": "https://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.1",
-      "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz",
-      "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=",
-      "dev": true,
-      "requires": {
-        "css-select": "1.2.0",
-        "dom-converter": "0.1.4",
-        "htmlparser2": "3.3.0",
-        "strip-ansi": "3.0.1",
-        "utila": "0.3.3"
-      },
-      "dependencies": {
-        "utila": {
-          "version": "0.3.3",
-          "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
-          "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
-          "dev": true
-        }
-      }
-    },
-    "repeat-element": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
-      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
-      "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.2"
-      }
-    },
-    "request": {
-      "version": "2.83.0",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
-      "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
-      "dev": true,
-      "requires": {
-        "aws-sign2": "0.7.0",
-        "aws4": "1.6.0",
-        "caseless": "0.12.0",
-        "combined-stream": "1.0.5",
-        "extend": "3.0.1",
-        "forever-agent": "0.6.1",
-        "form-data": "2.3.1",
-        "har-validator": "5.0.3",
-        "hawk": "6.0.2",
-        "http-signature": "1.2.0",
-        "is-typedarray": "1.0.0",
-        "isstream": "0.1.2",
-        "json-stringify-safe": "5.0.1",
-        "mime-types": "2.1.17",
-        "oauth-sign": "0.8.2",
-        "performance-now": "2.1.0",
-        "qs": "6.5.1",
-        "safe-buffer": "5.1.1",
-        "stringstream": "0.0.5",
-        "tough-cookie": "2.3.3",
-        "tunnel-agent": "0.6.0",
-        "uuid": "3.1.0"
-      }
-    },
-    "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"
-      }
-    },
-    "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": "1.2.1",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
-      "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
-      "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
-    },
-    "require-uncached": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
-      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
-      "dev": true,
-      "requires": {
-        "caller-path": "0.1.0",
-        "resolve-from": "1.0.1"
-      }
-    },
-    "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.1.7",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
-      "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
-      "dev": true
-    },
-    "resolve-from": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
-      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
-      "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.1",
-        "signal-exit": "3.0.2"
-      }
-    },
-    "right-align": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
-      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
-      "dev": true,
-      "requires": {
-        "align-text": "0.1.4"
-      }
-    },
-    "rimraf": {
-      "version": "2.2.8",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
-      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
-      "dev": true
-    },
-    "ripemd160": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
-      "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
-      "dev": true,
-      "requires": {
-        "hash-base": "2.0.2",
-        "inherits": "2.0.3"
-      }
-    },
-    "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"
-      }
-    },
-    "rx-lite": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
-      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
-      "dev": true
-    },
-    "rx-lite-aggregates": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
-      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
-      "dev": true,
-      "requires": {
-        "rx-lite": "4.0.8"
-      }
-    },
-    "safe-buffer": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
-      "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
-      "dev": true
-    },
-    "sanitize-html": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.14.1.tgz",
-      "integrity": "sha1-cw/6Ikm98YMz7/5FsoYXPJxa0Lg=",
-      "dev": true,
-      "requires": {
-        "htmlparser2": "3.9.2",
-        "regexp-quote": "0.0.0",
-        "xtend": "4.0.1"
-      },
-      "dependencies": {
-        "domhandler": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
-          "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
-          "dev": true,
-          "requires": {
-            "domelementtype": "1.3.0"
-          }
-        },
-        "htmlparser2": {
-          "version": "3.9.2",
-          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
-          "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
-          "dev": true,
-          "requires": {
-            "domelementtype": "1.3.0",
-            "domhandler": "2.4.1",
-            "domutils": "1.5.1",
-            "entities": "1.1.1",
-            "inherits": "2.0.3",
-            "readable-stream": "2.3.3"
-          }
-        }
-      }
-    },
-    "sax": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-      "dev": true
-    },
-    "schema-utils": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
-      "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=",
-      "dev": true,
-      "requires": {
-        "ajv": "5.2.3"
-      }
-    },
-    "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.1",
-      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.1.tgz",
-      "integrity": "sha1-v4y3uDJWxFUeMTR8YxF3jbme7FI=",
-      "dev": true,
-      "requires": {
-        "node-forge": "0.6.33"
-      }
-    },
-    "semver": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
-      "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
-      "dev": true
-    },
-    "send": {
-      "version": "0.16.1",
-      "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
-      "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
-      "dev": true,
-      "requires": {
-        "debug": "2.6.9",
-        "depd": "1.1.1",
-        "destroy": "1.0.4",
-        "encodeurl": "1.0.1",
-        "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.3.1"
-      }
-    },
-    "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.1",
-      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
-      "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
-      "dev": true,
-      "requires": {
-        "encodeurl": "1.0.1",
-        "escape-html": "1.0.3",
-        "parseurl": "1.3.2",
-        "send": "0.16.1"
-      }
-    },
-    "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-immediate-shim": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
-      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
-      "dev": true
-    },
-    "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.9",
-      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz",
-      "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==",
-      "dev": true,
-      "requires": {
-        "inherits": "2.0.3",
-        "safe-buffer": "5.1.1"
-      }
-    },
-    "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.5.3",
-      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz",
-      "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=",
-      "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
-    },
-    "sladex-blowfish": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/sladex-blowfish/-/sladex-blowfish-0.8.1.tgz",
-      "integrity": "sha1-y431Dra7sJgchCjGzl6B8H5kZrE="
-    },
-    "slash": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
-      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
-      "dev": true
-    },
-    "slice-ansi": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
-      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
-      "dev": true,
-      "requires": {
-        "is-fullwidth-code-point": "2.0.0"
-      }
-    },
-    "sntp": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz",
-      "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=",
-      "dev": true,
-      "requires": {
-        "hoek": "4.2.0"
-      }
-    },
-    "sockjs": {
-      "version": "0.3.18",
-      "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz",
-      "integrity": "sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc=",
-      "dev": true,
-      "requires": {
-        "faye-websocket": "0.10.0",
-        "uuid": "2.0.3"
-      },
-      "dependencies": {
-        "uuid": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
-          "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
-          "dev": true
-        }
-      }
-    },
-    "sockjs-client": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz",
-      "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=",
-      "dev": true,
-      "requires": {
-        "debug": "2.6.9",
-        "eventsource": "0.1.6",
-        "faye-websocket": "0.11.1",
-        "inherits": "2.0.3",
-        "json3": "3.3.2",
-        "url-parse": "1.1.9"
-      },
-      "dependencies": {
-        "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.7.0"
-          }
-        }
-      }
-    },
-    "sort-keys": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
-      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
-      "dev": true,
-      "requires": {
-        "is-plain-obj": "1.1.0"
-      }
-    },
-    "sortablejs": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.6.1.tgz",
-      "integrity": "sha1-0SDRA/u59gx9sngUoThAcubG4IM="
-    },
-    "source-list-map": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
-      "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
-      "dev": true
-    },
-    "source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
-    },
-    "source-map-support": {
-      "version": "0.4.18",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
-      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
-      "dev": true,
-      "requires": {
-        "source-map": "0.5.7"
-      }
-    },
-    "spdx-correct": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
-      "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
-      "dev": true,
-      "requires": {
-        "spdx-license-ids": "1.2.2"
-      }
-    },
-    "spdx-expression-parse": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
-      "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
-      "dev": true
-    },
-    "spdx-license-ids": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
-      "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
-      "dev": true
-    },
-    "spdy": {
-      "version": "3.4.7",
-      "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz",
-      "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=",
-      "dev": true,
-      "requires": {
-        "debug": "2.6.9",
-        "handle-thing": "1.2.5",
-        "http-deceiver": "1.2.7",
-        "safe-buffer": "5.1.1",
-        "select-hose": "2.0.0",
-        "spdy-transport": "2.0.20"
-      }
-    },
-    "spdy-transport": {
-      "version": "2.0.20",
-      "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz",
-      "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=",
-      "dev": true,
-      "requires": {
-        "debug": "2.6.9",
-        "detect-node": "2.0.3",
-        "hpack.js": "2.1.6",
-        "obuf": "1.1.1",
-        "readable-stream": "2.3.3",
-        "safe-buffer": "5.1.1",
-        "wbuf": "1.7.2"
-      }
-    },
-    "split.js": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.3.5.tgz",
-      "integrity": "sha1-YuLOZtLPkcx3SqXwdJ/yUTgDn1A="
-    },
-    "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.3"
-      }
-    },
-    "sprintf-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-      "dev": true
-    },
-    "sshpk": {
-      "version": "1.13.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
-      "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
-      "dev": true,
-      "requires": {
-        "asn1": "0.2.3",
-        "assert-plus": "1.0.0",
-        "bcrypt-pbkdf": "1.0.1",
-        "dashdash": "1.14.1",
-        "ecc-jsbn": "0.1.1",
-        "getpass": "0.1.7",
-        "jsbn": "0.1.1",
-        "tweetnacl": "0.14.5"
-      },
-      "dependencies": {
-        "jsbn": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-          "dev": true,
-          "optional": true
-        }
-      }
-    },
-    "static-eval": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-0.2.3.tgz",
-      "integrity": "sha1-Aj8XrJ/uQm6niMEuo5IG3Bdfiyo=",
-      "requires": {
-        "escodegen": "0.0.28"
-      },
-      "dependencies": {
-        "escodegen": {
-          "version": "0.0.28",
-          "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.28.tgz",
-          "integrity": "sha1-Dk/xcV8yh3XWyrUaxEpAbNer/9M=",
-          "requires": {
-            "esprima": "1.0.4",
-            "estraverse": "1.3.2",
-            "source-map": "0.5.7"
-          }
-        },
-        "esprima": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
-          "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
-        },
-        "estraverse": {
-          "version": "1.3.2",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.3.2.tgz",
-          "integrity": "sha1-N8K4k+8T1yPydth41g2FNRUqbEI="
-        }
-      }
-    },
-    "statuses": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
-      "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
-      "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.3",
-        "readable-stream": "2.3.3"
-      }
-    },
-    "stream-consume": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz",
-      "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=",
-      "dev": true
-    },
-    "stream-http": {
-      "version": "2.7.2",
-      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz",
-      "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==",
-      "dev": true,
-      "requires": {
-        "builtin-status-codes": "3.0.0",
-        "inherits": "2.0.3",
-        "readable-stream": "2.3.3",
-        "to-arraybuffer": "1.0.1",
-        "xtend": "4.0.1"
-      }
-    },
-    "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
-    },
-    "strict-uri-encode": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
-      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
-      "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": "1.0.3",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "5.1.1"
-      }
-    },
-    "stringstream": {
-      "version": "0.0.5",
-      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
-      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
-      "dev": true
-    },
-    "strip-ansi": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-      "dev": true,
-      "requires": {
-        "ansi-regex": "2.1.1"
-      }
-    },
-    "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.1"
-      }
-    },
-    "strip-eof": {
-      "version": "1.0.0",
-      "resolved": "https://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.19.0",
-      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz",
-      "integrity": "sha512-9mx9sC9nX1dgP96MZOODpGC6l1RzQBITI2D5WJhu+wnbrSYVKLGuy14XJSLVQih/0GFrPpjelt+s//VcZQ2Evw==",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0",
-        "schema-utils": "0.3.0"
-      }
-    },
-    "supports-color": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-      "dev": true
-    },
-    "svgo": {
-      "version": "0.7.2",
-      "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
-      "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
-      "dev": true,
-      "requires": {
-        "coa": "1.0.4",
-        "colors": "1.1.2",
-        "csso": "2.3.2",
-        "js-yaml": "3.7.0",
-        "mkdirp": "0.5.1",
-        "sax": "1.2.4",
-        "whet.extend": "0.9.9"
-      },
-      "dependencies": {
-        "colors": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
-          "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
-          "dev": true
-        }
-      }
-    },
-    "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": "4.0.2",
-      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
-      "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
-      "dev": true,
-      "requires": {
-        "ajv": "5.2.3",
-        "ajv-keywords": "2.1.0",
-        "chalk": "2.1.0",
-        "lodash": "4.17.4",
-        "slice-ansi": "1.0.0",
-        "string-width": "2.1.1"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
-          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.4.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "taffydb": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
-      "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
-      "dev": true
-    },
-    "tapable": {
-      "version": "0.2.8",
-      "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
-      "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
-      "dev": true
-    },
-    "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": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
-      "dev": true
-    },
-    "through2": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
-      "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
-      "dev": true,
-      "requires": {
-        "readable-stream": "2.3.3",
-        "xtend": "4.0.1"
-      }
-    },
-    "thunky": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz",
-      "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=",
-      "dev": true
-    },
-    "time-stamp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz",
-      "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=",
-      "dev": true
-    },
-    "timers-browserify": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz",
-      "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==",
-      "dev": true,
-      "requires": {
-        "setimmediate": "1.0.5"
-      }
-    },
-    "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=",
-      "dev": true
-    },
-    "toposort": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz",
-      "integrity": "sha1-wxdI5V0hDv/AD9zcfW5o19e7nOw=",
-      "dev": true
-    },
-    "tough-cookie": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
-      "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
-      "dev": true,
-      "requires": {
-        "punycode": "1.4.1"
-      }
-    },
-    "tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
-      "dev": true
-    },
-    "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.26",
-      "resolved": "https://registry.npmjs.org/triplesec/-/triplesec-3.0.26.tgz",
-      "integrity": "sha1-3/K7R1ikIzcuc5o5fYmR8Fl9CsE=",
-      "requires": {
-        "iced-error": "0.0.12",
-        "iced-lock": "1.1.0",
-        "iced-runtime": "1.0.3",
-        "more-entropy": "0.0.7",
-        "progress": "1.1.8"
-      }
-    },
-    "tryit": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
-      "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
-      "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.1.1"
-      }
-    },
-    "tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true,
-      "optional": true
-    },
-    "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-is": {
-      "version": "1.6.15",
-      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
-      "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
-      "dev": true,
-      "requires": {
-        "media-typer": "0.3.0",
-        "mime-types": "2.1.17"
-      }
-    },
-    "typedarray": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
-      "dev": true
-    },
-    "uglify-js": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.3.tgz",
-      "integrity": "sha512-5ZUOgufCHjN2mBBLfz63UtWTP6va2sSzBpNCM+/iqI6RnPzEhANmB0EKiKBYdQbc3v7KeomXJ2DJx0Xq9gvUvA==",
-      "dev": true,
-      "requires": {
-        "commander": "2.11.0",
-        "source-map": "0.5.7"
-      }
-    },
-    "uglify-to-browserify": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
-      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
-      "dev": true,
-      "optional": true
-    },
-    "uglifyjs-webpack-plugin": {
-      "version": "0.4.6",
-      "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
-      "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
-      "dev": true,
-      "requires": {
-        "source-map": "0.5.7",
-        "uglify-js": "2.8.29",
-        "webpack-sources": "1.0.1"
-      },
-      "dependencies": {
-        "camelcase": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
-          "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
-          "dev": true
-        },
-        "uglify-js": {
-          "version": "2.8.29",
-          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
-          "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
-          "dev": true,
-          "requires": {
-            "source-map": "0.5.7",
-            "uglify-to-browserify": "1.0.2",
-            "yargs": "3.10.0"
-          }
-        },
-        "yargs": {
-          "version": "3.10.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
-          "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
-          "dev": true,
-          "requires": {
-            "camelcase": "1.2.1",
-            "cliui": "2.1.0",
-            "decamelize": "1.2.0",
-            "window-size": "0.1.0"
-          }
-        }
-      }
-    },
-    "uint64be": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz",
-      "integrity": "sha1-H3FUIC8qG4rzU4cd2mUb80zpPpU="
-    },
-    "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.2.3",
-      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz",
-      "integrity": "sha1-gGmSYzZl1eX8tNsfs6hi62jp5to=",
-      "dev": true
-    },
-    "uniq": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
-      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
-      "dev": true
-    },
-    "uniqid": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz",
-      "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=",
-      "dev": true,
-      "requires": {
-        "macaddress": "0.2.8"
-      }
-    },
-    "uniqs": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
-      "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
-      "dev": true
-    },
-    "unixify": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/unixify/-/unixify-0.2.1.tgz",
-      "integrity": "sha1-SGQwPCbsyuEWDZHQRvZUc/Aivtw=",
-      "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
-    },
-    "upper-case": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
-      "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
-      "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-loader": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz",
-      "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0",
-        "mime": "1.4.1",
-        "schema-utils": "0.3.0"
-      }
-    },
-    "url-parse": {
-      "version": "1.1.9",
-      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.9.tgz",
-      "integrity": "sha1-xn8dd11R8KGJEd17P/rSe7nlvRk=",
-      "dev": true,
-      "requires": {
-        "querystringify": "1.0.0",
-        "requires-port": "1.0.0"
-      },
-      "dependencies": {
-        "querystringify": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz",
-          "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=",
-          "dev": true
-        }
-      }
-    },
-    "util": {
-      "version": "0.10.3",
-      "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
-      "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
-      "dev": true,
-      "requires": {
-        "inherits": "2.0.1"
-      },
-      "dependencies": {
-        "inherits": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
-          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
-          "dev": true
-        }
-      }
-    },
-    "util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-      "dev": true
-    },
-    "utila": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
-      "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
-      "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.1.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
-      "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
-      "dev": true
-    },
-    "val-loader": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/val-loader/-/val-loader-1.0.2.tgz",
-      "integrity": "sha1-eQkZgJOzfLoKlr9PbSnelw0JnT0=",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0"
-      }
-    },
-    "valid-data-url": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-0.1.4.tgz",
-      "integrity": "sha512-p3bCVl3Vrz42TV37a1OjagyLLd6qQAXBDWarIazuo7NQzCt8Kw8ZZwSAbUVPGlz5ubgbgJmgT0KRjLeCFNrfoQ==",
-      "dev": true
-    },
-    "validate-npm-package-license": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
-      "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
-      "dev": true,
-      "requires": {
-        "spdx-correct": "1.0.2",
-        "spdx-expression-parse": "1.0.4"
-      }
-    },
-    "validator": {
-      "version": "5.7.0",
-      "resolved": "https://registry.npmjs.org/validator/-/validator-5.7.0.tgz",
-      "integrity": "sha1-eoelgUa2laxIYHEUHAxJ1n2gXlw=",
-      "dev": true
-    },
-    "vary": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
-      "dev": true
-    },
-    "vendors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz",
-      "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=",
-      "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.3.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"
-      }
-    },
-    "watchpack": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
-      "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=",
-      "dev": true,
-      "requires": {
-        "async": "2.5.0",
-        "chokidar": "1.7.0",
-        "graceful-fs": "4.1.11"
-      }
-    },
-    "wbuf": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz",
-      "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=",
-      "dev": true,
-      "requires": {
-        "minimalistic-assert": "1.0.0"
-      }
-    },
-    "web-resource-inliner": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.2.0.tgz",
-      "integrity": "sha512-NvLvZzKvnNAB3LXG5c12WwUx5ZA7ZfNMYq82GnbhFyBLuu3jtamW4tQ40M02XiQzkFsyDuWG6Y2TOq9yywaxlg==",
-      "dev": true,
-      "requires": {
-        "async": "2.5.0",
-        "chalk": "1.1.3",
-        "datauri": "1.0.5",
-        "htmlparser2": "3.9.2",
-        "lodash.unescape": "4.0.1",
-        "request": "2.83.0",
-        "valid-data-url": "0.1.4",
-        "xtend": "4.0.1"
-      },
-      "dependencies": {
-        "domhandler": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
-          "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
-          "dev": true,
-          "requires": {
-            "domelementtype": "1.3.0"
-          }
-        },
-        "htmlparser2": {
-          "version": "3.9.2",
-          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
-          "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
-          "dev": true,
-          "requires": {
-            "domelementtype": "1.3.0",
-            "domhandler": "2.4.1",
-            "domutils": "1.5.1",
-            "entities": "1.1.1",
-            "inherits": "2.0.3",
-            "readable-stream": "2.3.3"
-          }
-        }
-      }
-    },
-    "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": "3.6.0",
-      "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.6.0.tgz",
-      "integrity": "sha512-OsHT3D0W0KmPPh60tC7asNnOmST6bKTiR90UyEdT9QYoaJ4OYN4Gg7WK1k3VxHK07ZoiYWPsKvlS/gAjwL/vRA==",
-      "dev": true,
-      "requires": {
-        "acorn": "5.1.2",
-        "acorn-dynamic-import": "2.0.2",
-        "ajv": "5.2.3",
-        "ajv-keywords": "2.1.0",
-        "async": "2.5.0",
-        "enhanced-resolve": "3.4.1",
-        "escope": "3.6.0",
-        "interpret": "1.0.4",
-        "json-loader": "0.5.7",
-        "json5": "0.5.1",
-        "loader-runner": "2.3.0",
-        "loader-utils": "1.1.0",
-        "memory-fs": "0.4.1",
-        "mkdirp": "0.5.1",
-        "node-libs-browser": "2.0.0",
-        "source-map": "0.5.7",
-        "supports-color": "4.4.0",
-        "tapable": "0.2.8",
-        "uglifyjs-webpack-plugin": "0.4.6",
-        "watchpack": "1.4.0",
-        "webpack-sources": "1.0.1",
-        "yargs": "8.0.2"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz",
-          "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==",
-          "dev": true
-        },
-        "escope": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
-          "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
-          "dev": true,
-          "requires": {
-            "es6-map": "0.1.5",
-            "es6-weak-map": "2.0.2",
-            "esrecurse": "4.2.0",
-            "estraverse": "4.2.0"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
-      }
-    },
-    "webpack-dev-middleware": {
-      "version": "1.12.0",
-      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz",
-      "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=",
-      "dev": true,
-      "requires": {
-        "memory-fs": "0.4.1",
-        "mime": "1.4.1",
-        "path-is-absolute": "1.0.1",
-        "range-parser": "1.2.0",
-        "time-stamp": "2.0.0"
-      }
-    },
-    "webpack-dev-server": {
-      "version": "2.9.1",
-      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.1.tgz",
-      "integrity": "sha512-qFKs4Wg6JI6FkAQ6WFqeDCCxXEBLsDHkqJB3f9tmlqx8C68Y9vQWwcaMT4Q9H8WF32Q6QUNmgK4qQkdHfXvj/g==",
-      "dev": true,
-      "requires": {
-        "ansi-html": "0.0.7",
-        "array-includes": "3.0.3",
-        "bonjour": "3.5.0",
-        "chokidar": "1.7.0",
-        "compression": "1.7.1",
-        "connect-history-api-fallback": "1.3.0",
-        "del": "3.0.0",
-        "express": "4.16.1",
-        "html-entities": "1.2.1",
-        "http-proxy-middleware": "0.17.4",
-        "internal-ip": "1.2.0",
-        "ip": "1.1.5",
-        "loglevel": "1.5.0",
-        "opn": "5.1.0",
-        "portfinder": "1.0.13",
-        "selfsigned": "1.10.1",
-        "serve-index": "1.9.1",
-        "sockjs": "0.3.18",
-        "sockjs-client": "1.1.4",
-        "spdy": "3.4.7",
-        "strip-ansi": "3.0.1",
-        "supports-color": "4.4.0",
-        "webpack-dev-middleware": "1.12.0",
-        "yargs": "6.6.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
-        },
-        "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.2",
-            "strip-ansi": "3.0.1",
-            "wrap-ansi": "2.1.0"
-          }
-        },
-        "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.2.0",
-            "pify": "3.0.0",
-            "rimraf": "2.2.8"
-          }
-        },
-        "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.2",
-            "glob": "7.0.6",
-            "object-assign": "4.1.1",
-            "pify": "2.3.0",
-            "pinkie-promise": "2.0.1"
-          },
-          "dependencies": {
-            "pify": {
-              "version": "2.3.0",
-              "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-              "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "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.1"
-          }
-        },
-        "os-locale": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
-          "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
-          "dev": true,
-          "requires": {
-            "lcid": "1.0.0"
-          }
-        },
-        "pify": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
-          "dev": true
-        },
-        "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.1.0",
-            "is-fullwidth-code-point": "1.0.0",
-            "strip-ansi": "3.0.1"
-          }
-        },
-        "supports-color": {
-          "version": "4.4.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
-          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "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
-        },
-        "yargs": {
-          "version": "6.6.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
-          "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
-          "dev": true,
-          "requires": {
-            "camelcase": "3.0.0",
-            "cliui": "3.2.0",
-            "decamelize": "1.2.0",
-            "get-caller-file": "1.0.2",
-            "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": "4.2.1"
-          }
-        },
-        "yargs-parser": {
-          "version": "4.2.1",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
-          "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
-          "dev": true,
-          "requires": {
-            "camelcase": "3.0.0"
-          }
-        }
-      }
-    },
-    "webpack-node-externals": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.6.0.tgz",
-      "integrity": "sha1-Iyxi7GCSsQBjWj0p2DwXRxKN+b0=",
-      "dev": true
-    },
-    "webpack-sources": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz",
-      "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==",
-      "dev": true,
-      "requires": {
-        "source-list-map": "2.0.0",
-        "source-map": "0.5.7"
-      }
-    },
-    "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.8",
-        "websocket-extensions": "0.1.2"
-      }
-    },
-    "websocket-extensions": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.2.tgz",
-      "integrity": "sha1-Dhh4HeYpoYMIzhSBZQ9n/6JpOl0=",
-      "dev": true
-    },
-    "whatwg-encoding": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz",
-      "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=",
-      "dev": true,
-      "requires": {
-        "iconv-lite": "0.4.13"
-      },
-      "dependencies": {
-        "iconv-lite": {
-          "version": "0.4.13",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
-          "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=",
-          "dev": true
-        }
-      }
-    },
-    "whatwg-url": {
-      "version": "4.8.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz",
-      "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=",
-      "dev": true,
-      "requires": {
-        "tr46": "0.0.3",
-        "webidl-conversions": "3.0.1"
-      },
-      "dependencies": {
-        "webidl-conversions": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-          "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
-          "dev": true
-        }
-      }
-    },
-    "whet.extend": {
-      "version": "0.9.9",
-      "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
-      "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=",
-      "dev": true
-    },
-    "which": {
-      "version": "1.2.14",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
-      "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
-      "dev": true,
-      "requires": {
-        "isexe": "2.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
-    },
-    "window-size": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
-      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
-      "dev": true
-    },
-    "wordwrap": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
-    },
-    "worker-loader": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.0.0.tgz",
-      "integrity": "sha512-dUwgs4Rdi1qG3VciM1+EPgAoO8m9USpCXxE3xmpWrnHJSMKGkzpCUNeYLjBRgYcSkf2A5xnXpR450Wqtu+pq0w==",
-      "dev": true,
-      "requires": {
-        "loader-utils": "1.1.0",
-        "schema-utils": "0.3.0"
-      }
-    },
-    "wrap-ansi": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
-      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
-      "dev": true,
-      "requires": {
-        "string-width": "1.0.2",
-        "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.1"
-          }
-        },
-        "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.1.0",
-            "is-fullwidth-code-point": "1.0.0",
-            "strip-ansi": "3.0.1"
-          }
-        }
-      }
-    },
-    "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"
-      }
-    },
-    "xml-char-classes": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz",
-      "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=",
-      "dev": true
-    },
-    "xml-name-validator": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
-      "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=",
-      "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.24",
-      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.24.tgz",
-      "integrity": "sha1-Gt4WLhzFI8jTn8fQavwW6iFvKfs="
-    },
-    "xtend": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
-      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
-      "dev": true
-    },
-    "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": "8.0.2",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
-      "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
-      "dev": true,
-      "requires": {
-        "camelcase": "4.1.0",
-        "cliui": "3.2.0",
-        "decamelize": "1.2.0",
-        "get-caller-file": "1.0.2",
-        "os-locale": "2.1.0",
-        "read-pkg-up": "2.0.0",
-        "require-directory": "2.1.1",
-        "require-main-filename": "1.0.1",
-        "set-blocking": "2.0.0",
-        "string-width": "2.1.1",
-        "which-module": "2.0.0",
-        "y18n": "3.2.1",
-        "yargs-parser": "7.0.0"
-      },
-      "dependencies": {
-        "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": "3.2.0",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
-          "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
-          "dev": true,
-          "requires": {
-            "string-width": "1.0.2",
-            "strip-ansi": "3.0.1",
-            "wrap-ansi": "2.1.0"
-          },
-          "dependencies": {
-            "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.1.0",
-                "is-fullwidth-code-point": "1.0.0",
-                "strip-ansi": "3.0.1"
-              }
-            }
-          }
-        },
-        "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.1"
-          }
-        },
-        "load-json-file": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
-          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "4.1.11",
-            "parse-json": "2.2.0",
-            "pify": "2.3.0",
-            "strip-bom": "3.0.0"
-          }
-        },
-        "path-type": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
-          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
-          "dev": true,
-          "requires": {
-            "pify": "2.3.0"
-          }
-        },
-        "read-pkg": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
-          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
-          "dev": true,
-          "requires": {
-            "load-json-file": "2.0.0",
-            "normalize-package-data": "2.4.0",
-            "path-type": "2.0.0"
-          }
-        },
-        "read-pkg-up": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
-          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
-          "dev": true,
-          "requires": {
-            "find-up": "2.1.0",
-            "read-pkg": "2.0.0"
-          }
-        },
-        "strip-bom": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
-          "dev": true
-        }
-      }
-    },
-    "yargs-parser": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
-      "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
-      "dev": true,
-      "requires": {
-        "camelcase": "4.1.0"
-      },
-      "dependencies": {
-        "camelcase": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
-          "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
-          "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="
-    }
-  }
-}
+{
+  "name": "cyberchef",
+  "version": "7.4.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "HTML_CodeSniffer": {
+      "version": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
+      "dev": true
+    },
+    "JSONSelect": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
+      "integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
+    },
+    "abab": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
+      "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=",
+      "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.4",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+      "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+      "dev": true,
+      "requires": {
+        "mime-types": "2.1.17",
+        "negotiator": "0.6.1"
+      }
+    },
+    "access-sniff": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/access-sniff/-/access-sniff-3.0.1.tgz",
+      "integrity": "sha1-IJ4W63DAlaA79/yCnsrLfHeS9e4=",
+      "dev": true,
+      "requires": {
+        "HTML_CodeSniffer": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
+        "axios": "0.9.1",
+        "bluebird": "3.5.0",
+        "chalk": "1.1.3",
+        "commander": "2.11.0",
+        "glob": "7.1.2",
+        "jsdom": "9.12.0",
+        "mkdirp": "0.5.1",
+        "phantomjs-prebuilt": "2.1.15",
+        "rc": "1.2.1",
+        "underscore": "1.8.3",
+        "unixify": "0.2.1",
+        "validator": "5.7.0"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "underscore": {
+          "version": "1.8.3",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+          "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=",
+          "dev": true
+        }
+      }
+    },
+    "acorn": {
+      "version": "4.0.13",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+      "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
+      "dev": true
+    },
+    "acorn-dynamic-import": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
+      "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
+      "dev": true,
+      "requires": {
+        "acorn": "4.0.13"
+      }
+    },
+    "acorn-globals": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
+      "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
+      "dev": true,
+      "requires": {
+        "acorn": "4.0.13"
+      }
+    },
+    "acorn-jsx": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+      "dev": true,
+      "requires": {
+        "acorn": "3.3.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+          "dev": true
+        }
+      }
+    },
+    "ajv": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz",
+      "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=",
+      "dev": true,
+      "requires": {
+        "co": "4.6.0",
+        "fast-deep-equal": "1.0.0",
+        "json-schema-traverse": "0.3.1",
+        "json-stable-stringify": "1.0.1"
+      }
+    },
+    "ajv-keywords": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz",
+      "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=",
+      "dev": true
+    },
+    "align-text": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2",
+        "longest": "1.0.1",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "alphanum-sort": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+      "dev": true
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+    },
+    "ansi-escapes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
+      "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==",
+      "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=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+      "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+      "dev": true,
+      "requires": {
+        "micromatch": "2.3.11",
+        "normalize-path": "2.1.1"
+      }
+    },
+    "argparse": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+      "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
+    "arr-diff": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "1.1.0"
+      }
+    },
+    "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
+    },
+    "array-equal": {
+      "version": "1.0.0",
+      "resolved": "https://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.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz",
+      "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=",
+      "dev": true
+    },
+    "array-includes": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
+      "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "es-abstract": "1.10.0"
+      }
+    },
+    "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.3"
+      }
+    },
+    "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.2.1",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+      "dev": true,
+      "optional": true
+    },
+    "asn1": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+      "dev": true
+    },
+    "asn1.js": {
+      "version": "4.9.2",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz",
+      "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "inherits": "2.0.3",
+        "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"
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "async": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
+      "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.4"
+      }
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "6.7.7",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
+      "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
+      "dev": true,
+      "requires": {
+        "browserslist": "1.7.7",
+        "caniuse-db": "1.0.30000741",
+        "normalize-range": "0.1.2",
+        "num2fraction": "1.2.2",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      },
+      "dependencies": {
+        "browserslist": {
+          "version": "1.7.7",
+          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+          "dev": true,
+          "requires": {
+            "caniuse-db": "1.0.30000741",
+            "electron-to-chromium": "1.3.24"
+          }
+        }
+      }
+    },
+    "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.6.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.9.1.tgz",
+      "integrity": "sha1-lWCLFkR+4psDNYmFTD/H7iwGv24=",
+      "dev": true,
+      "requires": {
+        "follow-redirects": "0.0.7"
+      }
+    },
+    "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=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "esutils": "2.0.2",
+        "js-tokens": "3.0.2"
+      }
+    },
+    "babel-core": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
+      "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "babel-generator": "6.26.0",
+        "babel-helpers": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-register": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "babylon": "6.18.0",
+        "convert-source-map": "1.5.1",
+        "debug": "2.6.9",
+        "json5": "0.5.1",
+        "lodash": "4.17.4",
+        "minimatch": "3.0.4",
+        "path-is-absolute": "1.0.1",
+        "private": "0.1.7",
+        "slash": "1.0.0",
+        "source-map": "0.5.7"
+      }
+    },
+    "babel-generator": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
+      "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
+      "dev": true,
+      "requires": {
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "detect-indent": "4.0.0",
+        "jsesc": "1.3.0",
+        "lodash": "4.17.4",
+        "source-map": "0.5.7",
+        "trim-right": "1.0.1"
+      }
+    },
+    "babel-helper-bindify-decorators": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz",
+      "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-builder-binary-assignment-operator-visitor": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+      "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+      "dev": true,
+      "requires": {
+        "babel-helper-explode-assignable-expression": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-call-delegate": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+      "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+      "dev": true,
+      "requires": {
+        "babel-helper-hoist-variables": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-define-map": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+      "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.4"
+      }
+    },
+    "babel-helper-explode-assignable-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+      "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-explode-class": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz",
+      "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=",
+      "dev": true,
+      "requires": {
+        "babel-helper-bindify-decorators": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+      "dev": true,
+      "requires": {
+        "babel-helper-get-function-arity": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-get-function-arity": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-hoist-variables": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+      "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-optimise-call-expression": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+      "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-regex": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+      "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.4"
+      }
+    },
+    "babel-helper-remap-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-replace-supers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+      "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+      "dev": true,
+      "requires": {
+        "babel-helper-optimise-call-expression": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helpers": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+      "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-loader": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz",
+      "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "1.0.0",
+        "loader-utils": "1.1.0",
+        "mkdirp": "0.5.1"
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-check-es2015-constants": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+      "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-syntax-async-functions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+      "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+      "dev": true
+    },
+    "babel-plugin-syntax-async-generators": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
+      "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
+      "dev": true
+    },
+    "babel-plugin-syntax-class-constructor-call": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
+      "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=",
+      "dev": true
+    },
+    "babel-plugin-syntax-class-properties": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
+      "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
+      "dev": true
+    },
+    "babel-plugin-syntax-decorators": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
+      "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
+      "dev": true
+    },
+    "babel-plugin-syntax-do-expressions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
+      "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=",
+      "dev": true
+    },
+    "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-syntax-exponentiation-operator": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+      "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+      "dev": true
+    },
+    "babel-plugin-syntax-export-extensions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
+      "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=",
+      "dev": true
+    },
+    "babel-plugin-syntax-function-bind": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
+      "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=",
+      "dev": true
+    },
+    "babel-plugin-syntax-object-rest-spread": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+      "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+      "dev": true
+    },
+    "babel-plugin-syntax-trailing-function-commas": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+      "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+      "dev": true
+    },
+    "babel-plugin-transform-async-generator-functions": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz",
+      "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=",
+      "dev": true,
+      "requires": {
+        "babel-helper-remap-async-to-generator": "6.24.1",
+        "babel-plugin-syntax-async-generators": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+      "dev": true,
+      "requires": {
+        "babel-helper-remap-async-to-generator": "6.24.1",
+        "babel-plugin-syntax-async-functions": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-class-constructor-call": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz",
+      "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-class-constructor-call": "6.18.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-class-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz",
+      "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-plugin-syntax-class-properties": "6.13.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-decorators": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz",
+      "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=",
+      "dev": true,
+      "requires": {
+        "babel-helper-explode-class": "6.24.1",
+        "babel-plugin-syntax-decorators": "6.13.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-do-expressions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz",
+      "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-do-expressions": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-arrow-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+      "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-block-scoped-functions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+      "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-block-scoping": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+      "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0",
+        "lodash": "4.17.4"
+      }
+    },
+    "babel-plugin-transform-es2015-classes": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+      "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+      "dev": true,
+      "requires": {
+        "babel-helper-define-map": "6.26.0",
+        "babel-helper-function-name": "6.24.1",
+        "babel-helper-optimise-call-expression": "6.24.1",
+        "babel-helper-replace-supers": "6.24.1",
+        "babel-messages": "6.23.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-computed-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+      "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-destructuring": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+      "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-duplicate-keys": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+      "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-for-of": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+      "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+      "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+      "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-amd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+      "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-commonjs": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
+      "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-strict-mode": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-systemjs": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+      "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+      "dev": true,
+      "requires": {
+        "babel-helper-hoist-variables": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-umd": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+      "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-object-super": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+      "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+      "dev": true,
+      "requires": {
+        "babel-helper-replace-supers": "6.24.1",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-parameters": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+      "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+      "dev": true,
+      "requires": {
+        "babel-helper-call-delegate": "6.24.1",
+        "babel-helper-get-function-arity": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-shorthand-properties": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+      "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-spread": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+      "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-sticky-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+      "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+      "dev": true,
+      "requires": {
+        "babel-helper-regex": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-template-literals": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+      "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-typeof-symbol": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+      "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-unicode-regex": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+      "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+      "dev": true,
+      "requires": {
+        "babel-helper-regex": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "regexpu-core": "2.0.0"
+      }
+    },
+    "babel-plugin-transform-exponentiation-operator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+      "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+      "dev": true,
+      "requires": {
+        "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
+        "babel-plugin-syntax-exponentiation-operator": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-export-extensions": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz",
+      "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-export-extensions": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-function-bind": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz",
+      "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-function-bind": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-object-rest-spread": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
+      "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-object-rest-spread": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-regenerator": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+      "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "0.10.1"
+      }
+    },
+    "babel-plugin-transform-runtime": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz",
+      "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-strict-mode": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-polyfill": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+      "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.1",
+        "regenerator-runtime": "0.10.5"
+      }
+    },
+    "babel-preset-env": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz",
+      "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==",
+      "dev": true,
+      "requires": {
+        "babel-plugin-check-es2015-constants": "6.22.0",
+        "babel-plugin-syntax-trailing-function-commas": "6.22.0",
+        "babel-plugin-transform-async-to-generator": "6.24.1",
+        "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoping": "6.26.0",
+        "babel-plugin-transform-es2015-classes": "6.24.1",
+        "babel-plugin-transform-es2015-computed-properties": "6.24.1",
+        "babel-plugin-transform-es2015-destructuring": "6.23.0",
+        "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
+        "babel-plugin-transform-es2015-for-of": "6.23.0",
+        "babel-plugin-transform-es2015-function-name": "6.24.1",
+        "babel-plugin-transform-es2015-literals": "6.22.0",
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+        "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
+        "babel-plugin-transform-es2015-modules-umd": "6.24.1",
+        "babel-plugin-transform-es2015-object-super": "6.24.1",
+        "babel-plugin-transform-es2015-parameters": "6.24.1",
+        "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
+        "babel-plugin-transform-es2015-spread": "6.22.0",
+        "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
+        "babel-plugin-transform-es2015-template-literals": "6.22.0",
+        "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
+        "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
+        "babel-plugin-transform-exponentiation-operator": "6.24.1",
+        "babel-plugin-transform-regenerator": "6.26.0",
+        "browserslist": "2.5.1",
+        "invariant": "2.2.2",
+        "semver": "5.4.1"
+      }
+    },
+    "babel-preset-es2015": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz",
+      "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-check-es2015-constants": "6.22.0",
+        "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
+        "babel-plugin-transform-es2015-block-scoping": "6.26.0",
+        "babel-plugin-transform-es2015-classes": "6.24.1",
+        "babel-plugin-transform-es2015-computed-properties": "6.24.1",
+        "babel-plugin-transform-es2015-destructuring": "6.23.0",
+        "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
+        "babel-plugin-transform-es2015-for-of": "6.23.0",
+        "babel-plugin-transform-es2015-function-name": "6.24.1",
+        "babel-plugin-transform-es2015-literals": "6.22.0",
+        "babel-plugin-transform-es2015-modules-amd": "6.24.1",
+        "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
+        "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
+        "babel-plugin-transform-es2015-modules-umd": "6.24.1",
+        "babel-plugin-transform-es2015-object-super": "6.24.1",
+        "babel-plugin-transform-es2015-parameters": "6.24.1",
+        "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
+        "babel-plugin-transform-es2015-spread": "6.22.0",
+        "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
+        "babel-plugin-transform-es2015-template-literals": "6.22.0",
+        "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
+        "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
+        "babel-plugin-transform-regenerator": "6.26.0"
+      }
+    },
+    "babel-preset-stage-0": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz",
+      "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-do-expressions": "6.22.0",
+        "babel-plugin-transform-function-bind": "6.22.0",
+        "babel-preset-stage-1": "6.24.1"
+      }
+    },
+    "babel-preset-stage-1": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz",
+      "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-class-constructor-call": "6.24.1",
+        "babel-plugin-transform-export-extensions": "6.22.0",
+        "babel-preset-stage-2": "6.24.1"
+      }
+    },
+    "babel-preset-stage-2": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz",
+      "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-dynamic-import": "6.18.0",
+        "babel-plugin-transform-class-properties": "6.24.1",
+        "babel-plugin-transform-decorators": "6.24.1",
+        "babel-preset-stage-3": "6.24.1"
+      }
+    },
+    "babel-preset-stage-3": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz",
+      "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-trailing-function-commas": "6.22.0",
+        "babel-plugin-transform-async-generator-functions": "6.24.1",
+        "babel-plugin-transform-async-to-generator": "6.24.1",
+        "babel-plugin-transform-exponentiation-operator": "6.24.1",
+        "babel-plugin-transform-object-rest-spread": "6.26.0"
+      }
+    },
+    "babel-register": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+      "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+      "dev": true,
+      "requires": {
+        "babel-core": "6.26.0",
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.1",
+        "home-or-tmp": "2.0.0",
+        "lodash": "4.17.4",
+        "mkdirp": "0.5.1",
+        "source-map-support": "0.4.18"
+      }
+    },
+    "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=",
+      "dev": true,
+      "requires": {
+        "core-js": "2.5.1",
+        "regenerator-runtime": "0.11.0"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
+          "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==",
+          "dev": true
+        }
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "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=",
+      "dev": true,
+      "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.9",
+        "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=",
+      "dev": true,
+      "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==",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base64-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
+      "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
+      "dev": true
+    },
+    "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.1",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "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
+    },
+    "bignumber.js": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-5.0.0.tgz",
+      "integrity": "sha512-KWTu6ZMVk9sxlDJQh2YH1UOnfDP8O8TpxUxgQG/vKASoSnEjK9aVuOueFaPcQEYQ5fyNXNTOYwYw3099RYebWg=="
+    },
+    "binary-extensions": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+      "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+      "dev": true
+    },
+    "bluebird": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
+      "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=",
+      "dev": true
+    },
+    "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-parser": {
+      "version": "1.18.2",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+      "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+      "dev": true,
+      "requires": {
+        "bytes": "3.0.0",
+        "content-type": "1.0.4",
+        "debug": "2.6.9",
+        "depd": "1.1.1",
+        "http-errors": "1.6.2",
+        "iconv-lite": "0.4.19",
+        "on-finished": "2.3.0",
+        "qs": "6.5.1",
+        "raw-body": "2.3.2",
+        "type-is": "1.6.15"
+      }
+    },
+    "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.1",
+        "deep-equal": "1.0.1",
+        "dns-equal": "1.0.0",
+        "dns-txt": "2.0.2",
+        "multicast-dns": "6.2.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
+    },
+    "boom": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+      "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+      "dev": true,
+      "requires": {
+        "hoek": "4.2.0"
+      }
+    },
+    "bootstrap": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.3.7.tgz",
+      "integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E="
+    },
+    "bootstrap-colorpicker": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/bootstrap-colorpicker/-/bootstrap-colorpicker-2.5.2.tgz",
+      "integrity": "sha512-krzBno9AMUwI2+IDwMvjnpqpa2f8womW0CCKmEcxGzVkolCFrt22jjMjzx1NZqB8C1DUdNgZP4LfyCsgpHRiYA==",
+      "requires": {
+        "jquery": "3.2.1"
+      }
+    },
+    "bootstrap-switch": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/bootstrap-switch/-/bootstrap-switch-3.3.4.tgz",
+      "integrity": "sha1-cOCusqh3wNx2aZHeEI4hcPwpov8="
+    },
+    "brace-expansion": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+      "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+      "dev": true,
+      "requires": {
+        "expand-range": "1.8.2",
+        "preserve": "0.2.0",
+        "repeat-element": "1.1.2"
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browserify-aes": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz",
+      "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "1.0.3",
+        "cipher-base": "1.0.4",
+        "create-hash": "1.1.3",
+        "evp_bytestokey": "1.0.3",
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
+      "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "1.1.1",
+        "browserify-des": "1.0.0",
+        "evp_bytestokey": "1.0.3"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
+      "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "des.js": "1.0.0",
+        "inherits": "2.0.3"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "randombytes": "2.0.5"
+      }
+    },
+    "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.11.8",
+        "browserify-rsa": "4.0.1",
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "elliptic": "6.4.0",
+        "inherits": "2.0.3",
+        "parse-asn1": "5.1.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.6"
+      }
+    },
+    "browserslist": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.5.1.tgz",
+      "integrity": "sha512-jAvM2ku7YDJ+leAq3bFH1DE0Ylw+F+EQDq4GkqZfgPEqpWYw9ofQH85uKSB9r3Tv7XDbfqVtE+sdvKJW7IlPJA==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "1.0.30000751",
+        "electron-to-chromium": "1.3.24"
+      }
+    },
+    "buffer": {
+      "version": "4.9.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+      "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+      "dev": true,
+      "requires": {
+        "base64-js": "1.2.1",
+        "ieee754": "1.1.8",
+        "isarray": "1.0.0"
+      }
+    },
+    "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": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+      "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="
+    },
+    "caller-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+      "dev": true,
+      "requires": {
+        "callsites": "0.2.0"
+      }
+    },
+    "callsites": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "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.3.2",
+        "upper-case": "1.1.3"
+      }
+    },
+    "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": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "2.1.1",
+        "map-obj": "1.0.1"
+      }
+    },
+    "caniuse-api": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
+      "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
+      "dev": true,
+      "requires": {
+        "browserslist": "1.7.7",
+        "caniuse-db": "1.0.30000741",
+        "lodash.memoize": "4.1.2",
+        "lodash.uniq": "4.5.0"
+      },
+      "dependencies": {
+        "browserslist": {
+          "version": "1.7.7",
+          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+          "dev": true,
+          "requires": {
+            "caniuse-db": "1.0.30000741",
+            "electron-to-chromium": "1.3.24"
+          }
+        }
+      }
+    },
+    "caniuse-db": {
+      "version": "1.0.30000741",
+      "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000741.tgz",
+      "integrity": "sha1-C+WREdQiHyH2ErUO5dZ4caLEp6U=",
+      "dev": true
+    },
+    "caniuse-lite": {
+      "version": "1.0.30000751",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000751.tgz",
+      "integrity": "sha1-KYrTQYLKQ1l1e0qTr8aBt7kX41g=",
+      "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"
+      }
+    },
+    "center-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+      "dev": true,
+      "requires": {
+        "align-text": "0.1.4",
+        "lazy-cache": "1.0.4"
+      }
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "chokidar": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+      "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+      "dev": true,
+      "requires": {
+        "anymatch": "1.3.2",
+        "async-each": "1.0.1",
+        "fsevents": "1.1.3",
+        "glob-parent": "2.0.0",
+        "inherits": "2.0.3",
+        "is-binary-path": "1.0.1",
+        "is-glob": "2.0.1",
+        "path-is-absolute": "1.0.1",
+        "readdirp": "2.1.0"
+      }
+    },
+    "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.3",
+        "safe-buffer": "5.1.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="
+    },
+    "clap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
+      "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3"
+      }
+    },
+    "clean-css": {
+      "version": "4.1.9",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.9.tgz",
+      "integrity": "sha1-Nc7ornaHpJuYA09w3gDE7dOCYwE=",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7"
+      }
+    },
+    "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": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+      "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+      "dev": true,
+      "requires": {
+        "center-align": "0.1.3",
+        "right-align": "0.1.3",
+        "wordwrap": "0.0.2"
+      },
+      "dependencies": {
+        "wordwrap": {
+          "version": "0.0.2",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+          "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+          "dev": true
+        }
+      }
+    },
+    "clone": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz",
+      "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=",
+      "dev": true
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "coa": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
+      "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
+      "dev": true,
+      "requires": {
+        "q": "1.5.0"
+      }
+    },
+    "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
+    },
+    "coffee-script": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.10.0.tgz",
+      "integrity": "sha1-EpOLz5vhlI+gBvkuDEyegXBRCMA=",
+      "dev": true
+    },
+    "color": {
+      "version": "0.11.4",
+      "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
+      "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
+      "dev": true,
+      "requires": {
+        "clone": "1.0.2",
+        "color-convert": "1.9.0",
+        "color-string": "0.3.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
+      "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+      "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
+    },
+    "color-string": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
+      "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "colormin": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
+      "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
+      "dev": true,
+      "requires": {
+        "color": "0.11.4",
+        "css-color-names": "0.0.4",
+        "has": "1.0.1"
+      }
+    },
+    "colors": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
+      "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
+    },
+    "combined-stream": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+      "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+      "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+      "dev": true
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "compressible": {
+      "version": "2.0.12",
+      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.12.tgz",
+      "integrity": "sha1-xZpcmdt2dn6YdlAOJx72OzSTvWY=",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.30.0"
+      }
+    },
+    "compression": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.1.tgz",
+      "integrity": "sha1-7/JgPvwuIs+G810uuTWJ+YdTc9s=",
+      "dev": true,
+      "requires": {
+        "accepts": "1.3.4",
+        "bytes": "3.0.0",
+        "compressible": "2.0.12",
+        "debug": "2.6.9",
+        "on-headers": "1.0.1",
+        "safe-buffer": "5.1.1",
+        "vary": "1.1.2"
+      }
+    },
+    "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.0",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+      "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3",
+        "typedarray": "0.0.6"
+      }
+    },
+    "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
+    },
+    "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"
+      }
+    },
+    "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
+    },
+    "content-type-parser": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz",
+      "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ=",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+      "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
+      "dev": true
+    },
+    "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
+    },
+    "core-js": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
+      "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=",
+      "dev": true
+    },
+    "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": "2.2.2",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
+      "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
+      "dev": true,
+      "requires": {
+        "is-directory": "0.3.1",
+        "js-yaml": "3.7.0",
+        "minimist": "1.2.0",
+        "object-assign": "4.1.1",
+        "os-homedir": "1.0.2",
+        "parse-json": "2.2.0",
+        "require-from-string": "1.2.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
+      "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "elliptic": "6.4.0"
+      }
+    },
+    "create-hash": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
+      "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "inherits": "2.0.3",
+        "ripemd160": "2.0.1",
+        "sha.js": "2.4.9"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
+      "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "create-hash": "1.1.3",
+        "inherits": "2.0.3",
+        "ripemd160": "2.0.1",
+        "safe-buffer": "5.1.1",
+        "sha.js": "2.4.9"
+      }
+    },
+    "cross-spawn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.1",
+        "shebang-command": "1.2.0",
+        "which": "1.2.14"
+      }
+    },
+    "cryptiles": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+      "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+      "dev": true,
+      "requires": {
+        "boom": "5.2.0"
+      },
+      "dependencies": {
+        "boom": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+          "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+          "dev": true,
+          "requires": {
+            "hoek": "4.2.0"
+          }
+        }
+      }
+    },
+    "crypto-api": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/crypto-api/-/crypto-api-0.7.5.tgz",
+      "integrity": "sha1-TCc3K8s85mnSKNV7NZG8YRjFKdU="
+    },
+    "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.4",
+        "create-ecdh": "4.0.0",
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "diffie-hellman": "5.0.2",
+        "inherits": "2.0.3",
+        "pbkdf2": "3.0.14",
+        "public-encrypt": "4.0.0",
+        "randombytes": "2.0.5",
+        "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-color-names": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+      "dev": true
+    },
+    "css-loader": {
+      "version": "0.28.7",
+      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.7.tgz",
+      "integrity": "sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "6.26.0",
+        "css-selector-tokenizer": "0.7.0",
+        "cssnano": "3.10.0",
+        "icss-utils": "2.1.0",
+        "loader-utils": "1.1.0",
+        "lodash.camelcase": "4.3.0",
+        "object-assign": "4.1.1",
+        "postcss": "5.2.17",
+        "postcss-modules-extract-imports": "1.1.0",
+        "postcss-modules-local-by-default": "1.2.0",
+        "postcss-modules-scope": "1.1.0",
+        "postcss-modules-values": "1.3.0",
+        "postcss-value-parser": "3.3.0",
+        "source-list-map": "2.0.0"
+      }
+    },
+    "css-select": {
+      "version": "1.2.0",
+      "resolved": "https://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.0",
+        "domutils": "1.5.1",
+        "nth-check": "1.0.1"
+      }
+    },
+    "css-selector-tokenizer": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
+      "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
+      "dev": true,
+      "requires": {
+        "cssesc": "0.1.0",
+        "fastparse": "1.1.1",
+        "regexpu-core": "1.0.0"
+      },
+      "dependencies": {
+        "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.3.3",
+            "regjsgen": "0.2.0",
+            "regjsparser": "0.1.5"
+          }
+        }
+      }
+    },
+    "css-what": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
+      "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=",
+      "dev": true
+    },
+    "cssesc": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
+      "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
+      "dev": true
+    },
+    "cssnano": {
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
+      "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
+      "dev": true,
+      "requires": {
+        "autoprefixer": "6.7.7",
+        "decamelize": "1.2.0",
+        "defined": "1.0.0",
+        "has": "1.0.1",
+        "object-assign": "4.1.1",
+        "postcss": "5.2.17",
+        "postcss-calc": "5.3.1",
+        "postcss-colormin": "2.2.2",
+        "postcss-convert-values": "2.6.1",
+        "postcss-discard-comments": "2.0.4",
+        "postcss-discard-duplicates": "2.1.0",
+        "postcss-discard-empty": "2.1.0",
+        "postcss-discard-overridden": "0.1.1",
+        "postcss-discard-unused": "2.2.3",
+        "postcss-filter-plugins": "2.0.2",
+        "postcss-merge-idents": "2.1.7",
+        "postcss-merge-longhand": "2.0.2",
+        "postcss-merge-rules": "2.1.2",
+        "postcss-minify-font-values": "1.0.5",
+        "postcss-minify-gradients": "1.0.5",
+        "postcss-minify-params": "1.2.2",
+        "postcss-minify-selectors": "2.1.1",
+        "postcss-normalize-charset": "1.1.1",
+        "postcss-normalize-url": "3.0.8",
+        "postcss-ordered-values": "2.2.3",
+        "postcss-reduce-idents": "2.4.0",
+        "postcss-reduce-initial": "1.0.1",
+        "postcss-reduce-transforms": "1.0.4",
+        "postcss-svgo": "2.1.6",
+        "postcss-unique-selectors": "2.0.2",
+        "postcss-value-parser": "3.3.0",
+        "postcss-zindex": "2.2.0"
+      }
+    },
+    "csso": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
+      "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
+      "dev": true,
+      "requires": {
+        "clap": "1.2.3",
+        "source-map": "0.5.7"
+      }
+    },
+    "cssom": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
+      "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=",
+      "dev": true
+    },
+    "cssstyle": {
+      "version": "0.2.37",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
+      "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
+      "dev": true,
+      "requires": {
+        "cssom": "0.3.2"
+      }
+    },
+    "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.2"
+      }
+    },
+    "d": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+      "dev": true,
+      "requires": {
+        "es5-ext": "0.10.37"
+      }
+    },
+    "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"
+      }
+    },
+    "datauri": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/datauri/-/datauri-1.0.5.tgz",
+      "integrity": "sha1-0JddGrbI8uDOPKQ7qkU5vhLSiaA=",
+      "dev": true,
+      "requires": {
+        "image-size": "0.3.5",
+        "mimer": "0.2.1",
+        "semver": "5.4.1"
+      },
+      "dependencies": {
+        "image-size": {
+          "version": "0.3.5",
+          "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.3.5.tgz",
+          "integrity": "sha1-gyQOqy+1sAsEqrjHSwRx6cunrYw=",
+          "dev": true
+        }
+      }
+    },
+    "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.7.0"
+      }
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "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
+    },
+    "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.4.2",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+      "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
+      "dev": true
+    },
+    "deep-for-each": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/deep-for-each/-/deep-for-each-1.0.6.tgz",
+      "integrity": "sha1-r6DOJJxYSSqXIFOUeKGNN+GxC64=",
+      "dev": true,
+      "requires": {
+        "is-plain-object": "2.0.4"
+      }
+    },
+    "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="
+    },
+    "define-properties": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+      "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+      "dev": true,
+      "requires": {
+        "foreach": "2.0.5",
+        "object-keys": "1.0.11"
+      }
+    },
+    "defined": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+      "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+      "dev": true
+    },
+    "del": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+      "dev": true,
+      "requires": {
+        "globby": "5.0.0",
+        "is-path-cwd": "1.0.0",
+        "is-path-in-cwd": "1.0.0",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "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
+    },
+    "depd": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+      "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+      "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.3",
+        "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-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "detect-node": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz",
+      "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
+      "dev": true
+    },
+    "diff": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
+      "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA=="
+    },
+    "diffie-hellman": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
+      "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "miller-rabin": "4.0.1",
+        "randombytes": "2.0.5"
+      }
+    },
+    "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.2.2",
+      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.2.2.tgz",
+      "integrity": "sha512-kN+DjfGF7dJGUL7nWRktL9Z18t1rWP3aQlyZdY8XlpvU3Nc6GeFTQApftcjtWKxAZfiggZSGrCEoszNgvnpwDg==",
+      "dev": true,
+      "requires": {
+        "ip": "1.1.5",
+        "safe-buffer": "5.1.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.1.1"
+      }
+    },
+    "doctrine": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
+      "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=",
+      "dev": true,
+      "requires": {
+        "esutils": "2.0.2",
+        "isarray": "1.0.0"
+      }
+    },
+    "dom-converter": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz",
+      "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=",
+      "dev": true,
+      "requires": {
+        "utila": "0.3.3"
+      },
+      "dependencies": {
+        "utila": {
+          "version": "0.3.3",
+          "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
+          "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
+          "dev": true
+        }
+      }
+    },
+    "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.3",
+        "entities": "1.1.1"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+          "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+          "dev": true
+        }
+      }
+    },
+    "domain-browser": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
+      "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=",
+      "dev": true
+    },
+    "domelementtype": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+      "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+      "dev": true
+    },
+    "domhandler": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz",
+      "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.3.0"
+      }
+    },
+    "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.1.0",
+        "domelementtype": "1.3.0"
+      }
+    },
+    "duplexify": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz",
+      "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "1.4.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3",
+        "stream-shift": "1.0.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.1",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "jsbn": "0.1.1"
+      },
+      "dependencies": {
+        "jsbn": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "electron-to-chromium": {
+      "version": "1.3.24",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz",
+      "integrity": "sha1-m3uIuwXOufoBahd4M8wt3jiPIbY=",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
+      "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "brorand": "1.1.0",
+        "hash.js": "1.1.3",
+        "hmac-drbg": "1.0.1",
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0",
+        "minimalistic-crypto-utils": "1.0.1"
+      }
+    },
+    "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.1",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
+      "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
+      "dev": true
+    },
+    "end-of-stream": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
+      "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
+      "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "memory-fs": "0.4.1",
+        "object-assign": "4.1.1",
+        "tapable": "0.2.8"
+      }
+    },
+    "entities": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+      "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
+      "dev": true
+    },
+    "errno": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz",
+      "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=",
+      "dev": true,
+      "requires": {
+        "prr": "0.0.0"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz",
+      "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==",
+      "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.1.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+      "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+      "dev": true,
+      "requires": {
+        "is-callable": "1.1.3",
+        "is-date-object": "1.0.1",
+        "is-symbol": "1.0.1"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.37",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz",
+      "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "es6-map": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+      "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37",
+        "es6-iterator": "2.0.3",
+        "es6-set": "0.1.5",
+        "es6-symbol": "3.1.1",
+        "event-emitter": "0.3.5"
+      }
+    },
+    "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.1.0",
+        "es6-promise-polyfill": "1.2.0"
+      }
+    },
+    "es6-promise": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.0.5.tgz",
+      "integrity": "sha1-eILzCt3lskDM+n99eMVIMwlRrkI="
+    },
+    "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": "5.0.0",
+      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+      "requires": {
+        "es6-promise": "4.0.5"
+      }
+    },
+    "es6-set": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+      "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37",
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1",
+        "event-emitter": "0.3.5"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37"
+      }
+    },
+    "es6-weak-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37",
+        "es6-iterator": "2.0.3",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "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=",
+      "dev": true
+    },
+    "escodegen": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
+      "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
+      "requires": {
+        "esprima": "3.1.3",
+        "estraverse": "4.2.0",
+        "esutils": "2.0.2",
+        "optionator": "0.8.2",
+        "source-map": "0.5.7"
+      },
+      "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": "4.8.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.8.0.tgz",
+      "integrity": "sha1-Ip7w41Tg5h2DfHqA/fuoJeGZgV4=",
+      "dev": true,
+      "requires": {
+        "ajv": "5.2.3",
+        "babel-code-frame": "6.26.0",
+        "chalk": "2.1.0",
+        "concat-stream": "1.6.0",
+        "cross-spawn": "5.1.0",
+        "debug": "3.1.0",
+        "doctrine": "2.0.0",
+        "eslint-scope": "3.7.1",
+        "espree": "3.5.1",
+        "esquery": "1.0.0",
+        "estraverse": "4.2.0",
+        "esutils": "2.0.2",
+        "file-entry-cache": "2.0.0",
+        "functional-red-black-tree": "1.0.1",
+        "glob": "7.1.2",
+        "globals": "9.18.0",
+        "ignore": "3.3.5",
+        "imurmurhash": "0.1.4",
+        "inquirer": "3.3.0",
+        "is-resolvable": "1.0.0",
+        "js-yaml": "3.10.0",
+        "json-stable-stringify": "1.0.1",
+        "levn": "0.3.0",
+        "lodash": "4.17.4",
+        "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",
+        "require-uncached": "1.0.3",
+        "semver": "5.4.1",
+        "strip-ansi": "4.0.0",
+        "strip-json-comments": "2.0.1",
+        "table": "4.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.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "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"
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "js-yaml": {
+          "version": "3.10.0",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+          "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+          "dev": true,
+          "requires": {
+            "argparse": "1.0.9",
+            "esprima": "4.0.0"
+          }
+        },
+        "progress": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+          "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+          "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": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "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.2.0",
+        "estraverse": "4.2.0"
+      }
+    },
+    "esmangle": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esmangle/-/esmangle-1.0.1.tgz",
+      "integrity": "sha1-2bs3uPjq+/Tm1O1reqKVarvTxMI=",
+      "requires": {
+        "escodegen": "1.3.3",
+        "escope": "1.0.3",
+        "esprima": "1.1.1",
+        "esshorten": "1.1.1",
+        "estraverse": "1.5.1",
+        "esutils": "1.0.0",
+        "optionator": "0.3.0",
+        "source-map": "0.1.43"
+      },
+      "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.1",
+            "esutils": "1.0.0",
+            "source-map": "0.1.43"
+          }
+        },
+        "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.2",
+            "type-check": "0.3.2"
+          }
+        },
+        "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.3",
+            "fast-levenshtein": "1.0.7",
+            "levn": "0.2.5",
+            "prelude-ls": "1.1.2",
+            "type-check": "0.3.2",
+            "wordwrap": "0.0.3"
+          }
+        },
+        "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": "1.0.1"
+          }
+        },
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
+        }
+      }
+    },
+    "espree": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz",
+      "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=",
+      "dev": true,
+      "requires": {
+        "acorn": "5.1.2",
+        "acorn-jsx": "3.0.1"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz",
+          "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==",
+          "dev": true
+        }
+      }
+    },
+    "esprima": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
+    },
+    "esquery": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
+      "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
+      "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "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.3",
+        "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
+    },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.37"
+      }
+    },
+    "eventemitter2": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+      "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
+      "dev": true
+    },
+    "eventemitter3": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
+      "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
+      "dev": true
+    },
+    "events": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
+      "dev": true
+    },
+    "eventsource": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
+      "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
+      "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.7.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "5.1.0",
+        "get-stream": "3.0.0",
+        "is-stream": "1.1.0",
+        "npm-run-path": "2.0.2",
+        "p-finally": "1.0.0",
+        "signal-exit": "3.0.2",
+        "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": "0.1.5",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+      "dev": true,
+      "requires": {
+        "is-posix-bracket": "0.1.1"
+      }
+    },
+    "expand-range": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+      "dev": true,
+      "requires": {
+        "fill-range": "2.2.3"
+      }
+    },
+    "exports-loader": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.6.4.tgz",
+      "integrity": "sha1-1w/GEhl1s1/BKDDPUnVL4nQPyIY=",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0",
+        "source-map": "0.5.7"
+      }
+    },
+    "express": {
+      "version": "4.16.2",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
+      "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
+      "dev": true,
+      "requires": {
+        "accepts": "1.3.4",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.18.2",
+        "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.1",
+        "encodeurl": "1.0.1",
+        "escape-html": "1.0.3",
+        "etag": "1.8.1",
+        "finalhandler": "1.1.0",
+        "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.2",
+        "qs": "6.5.1",
+        "range-parser": "1.2.0",
+        "safe-buffer": "5.1.1",
+        "send": "0.16.1",
+        "serve-static": "1.13.1",
+        "setprototypeof": "1.1.0",
+        "statuses": "1.3.1",
+        "type-is": "1.6.15",
+        "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.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+      "dev": true
+    },
+    "external-editor": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz",
+      "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==",
+      "dev": true,
+      "requires": {
+        "iconv-lite": "0.4.19",
+        "jschardet": "1.5.1",
+        "tmp": "0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "extract-text-webpack-plugin": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz",
+      "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==",
+      "dev": true,
+      "requires": {
+        "async": "2.5.0",
+        "loader-utils": "1.1.0",
+        "schema-utils": "0.3.0",
+        "webpack-sources": "1.0.1"
+      }
+    },
+    "extract-zip": {
+      "version": "1.6.5",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz",
+      "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.0",
+        "debug": "2.2.0",
+        "mkdirp": "0.5.0",
+        "yauzl": "2.4.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+          "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+          "dev": true,
+          "requires": {
+            "ms": "0.7.1"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+          "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "0.7.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+          "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
+          "dev": true
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+      "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
+      "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.1",
+      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
+      "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
+      "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.7.0"
+      }
+    },
+    "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"
+      }
+    },
+    "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.3.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "file-loader": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.6.tgz",
+      "integrity": "sha512-873ztuL+/hfvXbLDJ262PGO6XjERnybJu2gW1/5j8HUfxSiFJI9Hj/DhZ50ZGRUxBvuNiazb/cM2rh9pqrxP6Q==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0",
+        "schema-utils": "0.3.0"
+      }
+    },
+    "file-saver": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-1.3.3.tgz",
+      "integrity": "sha1-zdTETTqiZOrC9o7BZbx5HDSvEjI="
+    },
+    "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
+    },
+    "filename-regex": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+      "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+      "dev": true,
+      "requires": {
+        "is-number": "2.1.0",
+        "isobject": "2.1.0",
+        "randomatic": "1.1.7",
+        "repeat-element": "1.1.2",
+        "repeat-string": "1.6.1"
+      },
+      "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"
+          }
+        }
+      }
+    },
+    "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"
+      }
+    },
+    "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.1.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.15"
+      },
+      "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.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        }
+      }
+    },
+    "flat-cache": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+      "dev": true,
+      "requires": {
+        "circular-json": "0.3.3",
+        "del": "2.2.2",
+        "graceful-fs": "4.1.11",
+        "write": "0.2.1"
+      }
+    },
+    "flatten": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
+      "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
+      "dev": true
+    },
+    "follow-redirects": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.7.tgz",
+      "integrity": "sha1-NLkLqyqRGqNHVx2pDyK9NuzYqRk=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "stream-consume": "0.1.0"
+      }
+    },
+    "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": "0.1.5",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2"
+      }
+    },
+    "foreach": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+      "dev": true
+    },
+    "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.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+      "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+      "dev": true,
+      "requires": {
+        "asynckit": "0.4.0",
+        "combined-stream": "1.0.5",
+        "mime-types": "2.1.17"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true
+    },
+    "fs-extra": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+      "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "jsonfile": "2.4.0",
+        "klaw": "1.3.1"
+      }
+    },
+    "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.1.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz",
+      "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "2.8.0",
+        "node-pre-gyp": "0.6.39"
+      },
+      "dependencies": {
+        "abbrev": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ajv": {
+          "version": "4.11.8",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "co": "4.6.0",
+            "json-stable-stringify": "1.0.1"
+          }
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "aproba": {
+          "version": "1.1.1",
+          "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.2.9"
+          }
+        },
+        "asn1": {
+          "version": "0.2.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "assert-plus": {
+          "version": "0.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "asynckit": {
+          "version": "0.4.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "aws-sign2": {
+          "version": "0.6.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "aws4": {
+          "version": "1.6.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "balanced-match": {
+          "version": "0.4.2",
+          "bundled": true,
+          "dev": true
+        },
+        "bcrypt-pbkdf": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "tweetnacl": "0.14.5"
+          }
+        },
+        "block-stream": {
+          "version": "0.0.9",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.3"
+          }
+        },
+        "boom": {
+          "version": "2.10.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        },
+        "brace-expansion": {
+          "version": "1.1.7",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "balanced-match": "0.4.2",
+            "concat-map": "0.0.1"
+          }
+        },
+        "buffer-shims": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "caseless": {
+          "version": "0.12.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "co": {
+          "version": "4.6.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "combined-stream": {
+          "version": "1.0.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "delayed-stream": "1.0.0"
+          }
+        },
+        "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
+        },
+        "cryptiles": {
+          "version": "2.0.5",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "boom": "2.10.1"
+          }
+        },
+        "dashdash": {
+          "version": "1.14.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "1.0.0"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "debug": {
+          "version": "2.6.8",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.4.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "delayed-stream": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "detect-libc": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ecc-jsbn": {
+          "version": "0.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "jsbn": "0.1.1"
+          }
+        },
+        "extend": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "extsprintf": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "forever-agent": {
+          "version": "0.6.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "form-data": {
+          "version": "2.1.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.5",
+            "mime-types": "2.1.15"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "fstream": {
+          "version": "1.0.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "inherits": "2.0.3",
+            "mkdirp": "0.5.1",
+            "rimraf": "2.6.1"
+          }
+        },
+        "fstream-ignore": {
+          "version": "1.0.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fstream": "1.0.11",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4"
+          }
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aproba": "1.1.1",
+            "console-control-strings": "1.1.0",
+            "has-unicode": "2.0.1",
+            "object-assign": "4.1.1",
+            "signal-exit": "3.0.2",
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "wide-align": "1.1.2"
+          }
+        },
+        "getpass": {
+          "version": "0.1.7",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "1.0.0"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "graceful-fs": {
+          "version": "4.1.11",
+          "bundled": true,
+          "dev": true
+        },
+        "har-schema": {
+          "version": "1.0.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "har-validator": {
+          "version": "4.2.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ajv": "4.11.8",
+            "har-schema": "1.0.5"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "hawk": {
+          "version": "3.1.3",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "boom": "2.10.1",
+            "cryptiles": "2.0.5",
+            "hoek": "2.16.3",
+            "sntp": "1.0.9"
+          }
+        },
+        "hoek": {
+          "version": "2.16.3",
+          "bundled": true,
+          "dev": true
+        },
+        "http-signature": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "0.2.0",
+            "jsprim": "1.4.0",
+            "sshpk": "1.13.0"
+          }
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "once": "1.4.0",
+            "wrappy": "1.0.2"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "ini": {
+          "version": "1.3.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "is-typedarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "isstream": {
+          "version": "0.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "jodid25519": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "jsbn": "0.1.1"
+          }
+        },
+        "jsbn": {
+          "version": "0.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "json-schema": {
+          "version": "0.2.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "json-stable-stringify": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "jsonify": "0.0.0"
+          }
+        },
+        "json-stringify-safe": {
+          "version": "5.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "jsonify": {
+          "version": "0.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "jsprim": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "1.0.0",
+            "extsprintf": "1.0.2",
+            "json-schema": "0.2.3",
+            "verror": "1.3.6"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "mime-db": {
+          "version": "1.27.0",
+          "bundled": true,
+          "dev": true
+        },
+        "mime-types": {
+          "version": "2.1.15",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "mime-db": "1.27.0"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.7"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": true,
+          "dev": true
+        },
+        "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
+        },
+        "node-pre-gyp": {
+          "version": "0.6.39",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "detect-libc": "1.0.2",
+            "hawk": "3.1.3",
+            "mkdirp": "0.5.1",
+            "nopt": "4.0.1",
+            "npmlog": "4.1.0",
+            "rc": "1.2.1",
+            "request": "2.81.0",
+            "rimraf": "2.6.1",
+            "semver": "5.3.0",
+            "tar": "2.2.1",
+            "tar-pack": "3.4.0"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "abbrev": "1.1.0",
+            "osenv": "0.1.4"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "1.1.4",
+            "console-control-strings": "1.1.0",
+            "gauge": "2.7.4",
+            "set-blocking": "2.0.0"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "oauth-sign": {
+          "version": "0.8.2",
+          "bundled": true,
+          "dev": true,
+          "optional": 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.0.2"
+          }
+        },
+        "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.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "os-homedir": "1.0.2",
+            "os-tmpdir": "1.0.2"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "performance-now": {
+          "version": "0.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "process-nextick-args": {
+          "version": "1.0.7",
+          "bundled": true,
+          "dev": true
+        },
+        "punycode": {
+          "version": "1.4.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "qs": {
+          "version": "6.4.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "rc": {
+          "version": "1.2.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "deep-extend": "0.4.2",
+            "ini": "1.3.4",
+            "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.2.9",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "buffer-shims": "1.0.0",
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "1.0.7",
+            "string_decoder": "1.0.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "request": {
+          "version": "2.81.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aws-sign2": "0.6.0",
+            "aws4": "1.6.0",
+            "caseless": "0.12.0",
+            "combined-stream": "1.0.5",
+            "extend": "3.0.1",
+            "forever-agent": "0.6.1",
+            "form-data": "2.1.4",
+            "har-validator": "4.2.1",
+            "hawk": "3.1.3",
+            "http-signature": "1.1.1",
+            "is-typedarray": "1.0.0",
+            "isstream": "0.1.2",
+            "json-stringify-safe": "5.0.1",
+            "mime-types": "2.1.15",
+            "oauth-sign": "0.8.2",
+            "performance-now": "0.2.0",
+            "qs": "6.4.0",
+            "safe-buffer": "5.0.1",
+            "stringstream": "0.0.5",
+            "tough-cookie": "2.3.2",
+            "tunnel-agent": "0.6.0",
+            "uuid": "3.0.1"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "glob": "7.1.2"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "semver": {
+          "version": "5.3.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
+        },
+        "sntp": {
+          "version": "1.0.9",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        },
+        "sshpk": {
+          "version": "1.13.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "asn1": "0.2.3",
+            "assert-plus": "1.0.0",
+            "bcrypt-pbkdf": "1.0.1",
+            "dashdash": "1.14.1",
+            "ecc-jsbn": "0.1.1",
+            "getpass": "0.1.7",
+            "jodid25519": "1.0.2",
+            "jsbn": "0.1.1",
+            "tweetnacl": "0.14.5"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.0.1"
+          }
+        },
+        "stringstream": {
+          "version": "0.0.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "2.1.1"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "tar": {
+          "version": "2.2.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "block-stream": "0.0.9",
+            "fstream": "1.0.11",
+            "inherits": "2.0.3"
+          }
+        },
+        "tar-pack": {
+          "version": "3.4.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "2.6.8",
+            "fstream": "1.0.11",
+            "fstream-ignore": "1.0.5",
+            "once": "1.4.0",
+            "readable-stream": "2.2.9",
+            "rimraf": "2.6.1",
+            "tar": "2.2.1",
+            "uid-number": "0.0.6"
+          }
+        },
+        "tough-cookie": {
+          "version": "2.3.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "punycode": "1.4.1"
+          }
+        },
+        "tunnel-agent": {
+          "version": "0.6.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safe-buffer": "5.0.1"
+          }
+        },
+        "tweetnacl": {
+          "version": "0.14.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "uid-number": {
+          "version": "0.0.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "uuid": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "verror": {
+          "version": "1.3.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "extsprintf": "1.0.2"
+          }
+        },
+        "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
+        }
+      }
+    },
+    "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
+    },
+    "get-caller-file": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+      "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
+      "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": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "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.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.6",
+        "inherits": "2.0.3",
+        "minimatch": "3.0.4",
+        "once": "1.4.0",
+        "path-is-absolute": "1.0.1"
+      }
+    },
+    "glob-base": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+      "dev": true,
+      "requires": {
+        "glob-parent": "2.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-parent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+      "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+      "dev": true,
+      "requires": {
+        "is-glob": "2.0.1"
+      }
+    },
+    "globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+      "dev": true
+    },
+    "globby": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+      "dev": true,
+      "requires": {
+        "array-union": "1.0.2",
+        "arrify": "1.0.1",
+        "glob": "7.0.6",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "google-code-prettify": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/google-code-prettify/-/google-code-prettify-1.0.5.tgz",
+      "integrity": "sha1-n0d/Ik2/piNy5e+AOn4VdBBAAIQ="
+    },
+    "graceful-fs": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+      "dev": true
+    },
+    "grunt": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.1.tgz",
+      "integrity": "sha1-6HeHZOlEsY8yuw8QuQeEdcnftWs=",
+      "dev": true,
+      "requires": {
+        "coffee-script": "1.10.0",
+        "dateformat": "1.0.12",
+        "eventemitter2": "0.4.14",
+        "exit": "0.1.2",
+        "findup-sync": "0.3.0",
+        "glob": "7.0.6",
+        "grunt-cli": "1.2.0",
+        "grunt-known-options": "1.1.0",
+        "grunt-legacy-log": "1.0.0",
+        "grunt-legacy-util": "1.0.0",
+        "iconv-lite": "0.4.19",
+        "js-yaml": "3.5.5",
+        "minimatch": "3.0.4",
+        "nopt": "3.0.6",
+        "path-is-absolute": "1.0.1",
+        "rimraf": "2.2.8"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "2.7.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+          "dev": true
+        },
+        "grunt-cli": {
+          "version": "1.2.0",
+          "resolved": "https://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.7"
+          }
+        },
+        "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.9",
+            "esprima": "2.7.3"
+          }
+        }
+      }
+    },
+    "grunt-accessibility": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-accessibility/-/grunt-accessibility-5.0.0.tgz",
+      "integrity": "sha1-/uK+5WHjPOl8lfk/7ogEPfFFokk=",
+      "dev": true,
+      "requires": {
+        "access-sniff": "3.0.1"
+      }
+    },
+    "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"
+      }
+    },
+    "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.5.2",
+        "indent-string": "2.1.0",
+        "pad-stream": "1.2.0"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-contrib-clean": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-1.1.0.tgz",
+      "integrity": "sha1-Vkq/LQN4qYOhW54/MO51tzjEBjg=",
+      "dev": true,
+      "requires": {
+        "async": "1.5.2",
+        "rimraf": "2.6.2"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "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.6"
+          }
+        }
+      }
+    },
+    "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.3",
+        "file-sync-cmp": "0.1.1"
+      }
+    },
+    "grunt-eslint": {
+      "version": "20.1.0",
+      "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-20.1.0.tgz",
+      "integrity": "sha512-VZlDOLrB2KKefDDcx/wR8rEEz7smDwDKVblmooa+itdt/2jWw3ee2AiZB5Ap4s4AoRY0pbHRjZ3HHwY8uKR9Rw==",
+      "dev": true,
+      "requires": {
+        "chalk": "2.1.0",
+        "eslint": "4.8.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.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-execute": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.2.2.tgz",
+      "integrity": "sha1-TpRf5XlZzA3neZCDtrQq7ZYWNQo=",
+      "dev": true
+    },
+    "grunt-jsdoc": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.2.0.tgz",
+      "integrity": "sha512-3/HzvzcG7gxlm4YefR5ELbsUB/bIFCeX3CbUeAANKGMfNUZ2tDQ+Pp0YRb/VWHjyu+v8wG6n1PD8yIjubjEDeg==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "3.0.1",
+        "jsdoc": "3.5.5"
+      },
+      "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.1.1",
+            "which": "1.2.14"
+          }
+        }
+      }
+    },
+    "grunt-known-options": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz",
+      "integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=",
+      "dev": true
+    },
+    "grunt-legacy-log": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz",
+      "integrity": "sha1-+4bxgJhHvAfcR4Q/ns1srLYt8tU=",
+      "dev": true,
+      "requires": {
+        "colors": "1.1.2",
+        "grunt-legacy-log-utils": "1.0.0",
+        "hooker": "0.2.3",
+        "lodash": "3.10.1",
+        "underscore.string": "3.2.3"
+      },
+      "dependencies": {
+        "colors": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+          "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+          "dev": true
+        },
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-legacy-log-utils": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz",
+      "integrity": "sha1-p7ji0Ps1taUPSvmG/BEnSevJbz0=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "lodash": "4.3.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
+          "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-legacy-util": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz",
+      "integrity": "sha1-OGqnjcbtUJhsKxiVcmWxtIq7m4Y=",
+      "dev": true,
+      "requires": {
+        "async": "1.5.2",
+        "exit": "0.1.2",
+        "getobject": "0.1.0",
+        "hooker": "0.2.3",
+        "lodash": "4.3.0",
+        "underscore.string": "3.2.3",
+        "which": "1.2.14"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.3.0.tgz",
+          "integrity": "sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ=",
+          "dev": true
+        }
+      }
+    },
+    "grunt-webpack": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/grunt-webpack/-/grunt-webpack-3.0.2.tgz",
+      "integrity": "sha512-ghSkdCdvbF1SpI46qDT9FYqw5ZP5sSYbEQU/DwzoJE1K42xizAZ5Rv3kzpaRdJT4yvu8/6fO5+wne3/y0n74QA==",
+      "dev": true,
+      "requires": {
+        "deep-for-each": "1.0.6",
+        "lodash": "4.17.4"
+      }
+    },
+    "handle-thing": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz",
+      "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=",
+      "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.0.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+      "dev": true,
+      "requires": {
+        "ajv": "5.2.3",
+        "har-schema": "2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
+      "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
+      "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=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+      "dev": true
+    },
+    "hash-base": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+      "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      }
+    },
+    "hash.js": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+      "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "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.1.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "hawk": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+      "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+      "dev": true,
+      "requires": {
+        "boom": "4.3.1",
+        "cryptiles": "3.1.2",
+        "hoek": "4.2.0",
+        "sntp": "2.0.2"
+      }
+    },
+    "he": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+      "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+      "dev": true
+    },
+    "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.1.3",
+        "minimalistic-assert": "1.0.0",
+        "minimalistic-crypto-utils": "1.0.1"
+      }
+    },
+    "hoek": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+      "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==",
+      "dev": true
+    },
+    "home-or-tmp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+      "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+      "dev": true,
+      "requires": {
+        "os-homedir": "1.0.2",
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "hooker": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+      "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+      "dev": true
+    },
+    "hosted-git-info": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+      "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
+      "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.3",
+        "obuf": "1.1.1",
+        "readable-stream": "2.3.3",
+        "wbuf": "1.7.2"
+      }
+    },
+    "html-comment-regex": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
+      "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
+      "dev": true
+    },
+    "html-encoding-sniffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz",
+      "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=",
+      "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.5",
+      "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.5.tgz",
+      "integrity": "sha512-g+1+NBycQI0fGnggd52JM8TRUweG7+9W2wrtjGitMAqc4G7maweAHvVAAjz9veHseIH3tYKE2lk2USGSoewIrQ==",
+      "dev": true,
+      "requires": {
+        "camel-case": "3.0.0",
+        "clean-css": "4.1.9",
+        "commander": "2.11.0",
+        "he": "1.1.1",
+        "ncname": "1.0.0",
+        "param-case": "2.1.1",
+        "relateurl": "0.2.7",
+        "uglify-js": "3.1.3"
+      }
+    },
+    "html-webpack-plugin": {
+      "version": "2.30.1",
+      "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz",
+      "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.0",
+        "html-minifier": "3.5.5",
+        "loader-utils": "0.2.17",
+        "lodash": "4.17.4",
+        "pretty-error": "2.1.1",
+        "toposort": "1.0.6"
+      },
+      "dependencies": {
+        "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.2.0",
+            "emojis-list": "2.1.0",
+            "json5": "0.5.1",
+            "object-assign": "4.1.1"
+          }
+        }
+      }
+    },
+    "htmlparser2": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
+      "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.3.0",
+        "domhandler": "2.1.0",
+        "domutils": "1.1.6",
+        "readable-stream": "1.0.34"
+      },
+      "dependencies": {
+        "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.3.0"
+          }
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.0.34",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "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
+        }
+      }
+    },
+    "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.2",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+      "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+      "dev": true,
+      "requires": {
+        "depd": "1.1.1",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.0.3",
+        "statuses": "1.3.1"
+      },
+      "dependencies": {
+        "setprototypeof": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+          "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+          "dev": true
+        }
+      }
+    },
+    "http-parser-js": {
+      "version": "0.4.9",
+      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz",
+      "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=",
+      "dev": true
+    },
+    "http-proxy": {
+      "version": "1.16.2",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
+      "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "1.2.0",
+        "requires-port": "1.0.0"
+      }
+    },
+    "http-proxy-middleware": {
+      "version": "0.17.4",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz",
+      "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=",
+      "dev": true,
+      "requires": {
+        "http-proxy": "1.16.2",
+        "is-glob": "3.1.0",
+        "lodash": "4.17.4",
+        "micromatch": "2.3.11"
+      },
+      "dependencies": {
+        "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-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.1"
+          }
+        }
+      }
+    },
+    "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.4.1",
+        "sshpk": "1.13.1"
+      }
+    },
+    "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
+    },
+    "iced-error": {
+      "version": "0.0.12",
+      "resolved": "https://registry.npmjs.org/iced-error/-/iced-error-0.0.12.tgz",
+      "integrity": "sha1-4KhhRigXzwzpdLE/ymEtOg1dEL4="
+    },
+    "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.3"
+      }
+    },
+    "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.19",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+      "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
+      "dev": true
+    },
+    "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": "2.1.0",
+      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz",
+      "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
+      "dev": true,
+      "requires": {
+        "postcss": "6.0.12"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.12",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
+          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.1.0",
+            "source-map": "0.5.7",
+            "supports-color": "4.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "ieee754": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
+      "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "3.3.5",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
+      "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==",
+      "dev": true
+    },
+    "image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+      "dev": true,
+      "optional": true
+    },
+    "import-local": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-0.1.1.tgz",
+      "integrity": "sha1-sReVcqrNwRxqkQCftDDbyrX2aKg=",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "2.0.0",
+        "resolve-cwd": "2.0.0"
+      }
+    },
+    "imports-loader": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.7.1.tgz",
+      "integrity": "sha1-8gS180cCoywdt9SNidXoZ6BEElM=",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0",
+        "source-map": "0.5.7"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "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.1"
+      }
+    },
+    "indexes-of": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+      "dev": true
+    },
+    "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.4.0",
+        "wrappy": "1.0.2"
+      }
+    },
+    "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.4",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+      "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+      "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.20.1",
+        "sanitize-html": "1.15.0"
+      }
+    },
+    "inquirer": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "3.0.0",
+        "chalk": "2.1.0",
+        "cli-cursor": "2.1.0",
+        "cli-width": "2.2.0",
+        "external-editor": "2.0.5",
+        "figures": "2.0.0",
+        "lodash": "4.17.4",
+        "mute-stream": "0.0.7",
+        "run-async": "2.3.0",
+        "rx-lite": "4.0.8",
+        "rx-lite-aggregates": "4.0.8",
+        "string-width": "2.1.1",
+        "strip-ansi": "4.0.0",
+        "through": "2.3.8"
+      },
+      "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.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "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": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "internal-ip": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz",
+      "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=",
+      "dev": true,
+      "requires": {
+        "meow": "3.7.0"
+      }
+    },
+    "interpret": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+      "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+      "dev": true
+    },
+    "invariant": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
+      "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+      "dev": true,
+      "requires": {
+        "loose-envify": "1.3.1"
+      }
+    },
+    "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
+    },
+    "ipaddr.js": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
+      "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=",
+      "dev": true
+    },
+    "is-absolute-url": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+      "dev": true
+    },
+    "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.11.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": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "1.1.1"
+      }
+    },
+    "is-callable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
+      "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
+      "dev": true
+    },
+    "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-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-dotfile": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+      "dev": true
+    },
+    "is-equal-shallow": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+      "dev": true,
+      "requires": {
+        "is-primitive": "2.0.0"
+      }
+    },
+    "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": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+      "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.1"
+      }
+    },
+    "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-glob": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "is-number": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.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.0",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+      "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "1.0.0"
+      }
+    },
+    "is-path-inside": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
+      "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "1.0.2"
+      }
+    },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true
+    },
+    "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-posix-bracket": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+      "dev": true
+    },
+    "is-primitive": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+      "dev": true
+    },
+    "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-resolvable": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
+      "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
+      "dev": true,
+      "requires": {
+        "tryit": "1.0.3"
+      }
+    },
+    "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-svg": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
+      "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
+      "dev": true,
+      "requires": {
+        "html-comment-regex": "1.1.1"
+      }
+    },
+    "is-symbol": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
+      "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
+      "dev": true
+    },
+    "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-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "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
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "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
+    },
+    "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.10",
+        "escodegen": "0.0.21",
+        "esprima": "1.0.4",
+        "jison-lex": "0.2.1",
+        "lex-parser": "0.1.4",
+        "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.4",
+            "estraverse": "0.0.4",
+            "source-map": "0.5.7"
+          }
+        },
+        "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.4",
+        "nomnom": "1.5.2"
+      }
+    },
+    "jquery": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
+      "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c="
+    },
+    "js-base64": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
+      "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==",
+      "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-sha3": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz",
+      "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA=="
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
+      "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.9",
+        "esprima": "2.7.3"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "2.7.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+          "dev": true
+        }
+      }
+    },
+    "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.2"
+      }
+    },
+    "jsbn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+      "integrity": "sha1-sBMHyym2GKHtJux56RH4A8TaAEA="
+    },
+    "jschardet": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz",
+      "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==",
+      "dev": true
+    },
+    "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.11"
+          }
+        },
+        "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.3.0",
+      "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.3.0.tgz",
+      "integrity": "sha1-Lqrv2eyo2LeIRTlKHM6diJa+++E=",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.4"
+      }
+    },
+    "jsdom": {
+      "version": "9.12.0",
+      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz",
+      "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=",
+      "dev": true,
+      "requires": {
+        "abab": "1.0.4",
+        "acorn": "4.0.13",
+        "acorn-globals": "3.1.0",
+        "array-equal": "1.0.0",
+        "content-type-parser": "1.0.1",
+        "cssom": "0.3.2",
+        "cssstyle": "0.2.37",
+        "escodegen": "1.9.0",
+        "html-encoding-sniffer": "1.0.1",
+        "nwmatcher": "1.4.3",
+        "parse5": "1.5.1",
+        "request": "2.83.0",
+        "sax": "1.2.4",
+        "symbol-tree": "3.2.2",
+        "tough-cookie": "2.3.3",
+        "webidl-conversions": "4.0.2",
+        "whatwg-encoding": "1.0.1",
+        "whatwg-url": "4.8.0",
+        "xml-name-validator": "2.0.1"
+      }
+    },
+    "jsesc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+      "dev": true
+    },
+    "json-loader": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
+      "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
+      "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.3.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+      "dev": true
+    },
+    "json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "requires": {
+        "jsonify": "0.0.0"
+      }
+    },
+    "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": "0.5.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+      "dev": true
+    },
+    "jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "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="
+        }
+      }
+    },
+    "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"
+      }
+    },
+    "jsrsasign": {
+      "version": "8.0.4",
+      "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.4.tgz",
+      "integrity": "sha1-P3uCOIRPEmtJanVW7J9LUR+V+GE="
+    },
+    "kbpgp": {
+      "version": "2.0.76",
+      "resolved": "https://registry.npmjs.org/kbpgp/-/kbpgp-2.0.76.tgz",
+      "integrity": "sha1-qKtufM8279812BNdfJb/bpSLMAI=",
+      "requires": {
+        "bn": "1.0.1",
+        "bzip-deflate": "1.0.0",
+        "deep-equal": "1.0.1",
+        "iced-error": "0.0.12",
+        "iced-lock": "1.1.0",
+        "iced-runtime": "1.0.3",
+        "keybase-ecurve": "1.0.0",
+        "keybase-nacl": "1.0.10",
+        "minimist": "1.2.0",
+        "pgp-utils": "0.0.34",
+        "purepack": "1.0.4",
+        "triplesec": "3.0.26",
+        "tweetnacl": "0.13.3"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+        },
+        "tweetnacl": {
+          "version": "0.13.3",
+          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz",
+          "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y="
+        }
+      }
+    },
+    "kew": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+      "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+      "dev": true
+    },
+    "killable": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz",
+      "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=",
+      "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.1"
+      }
+    },
+    "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.3",
+        "tweetnacl": "0.13.3",
+        "uint64be": "1.0.1"
+      },
+      "dependencies": {
+        "tweetnacl": {
+          "version": "0.13.3",
+          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.13.3.tgz",
+          "integrity": "sha1-1ii1bzvMPVrnS6nUwacE3vWrS1Y="
+        }
+      }
+    },
+    "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.6"
+      }
+    },
+    "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.11"
+      }
+    },
+    "lazy-cache": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+      "dev": true
+    },
+    "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"
+      }
+    },
+    "less": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz",
+      "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==",
+      "dev": true,
+      "requires": {
+        "errno": "0.1.4",
+        "graceful-fs": "4.1.11",
+        "image-size": "0.5.5",
+        "mime": "1.4.1",
+        "mkdirp": "0.5.1",
+        "promise": "7.3.1",
+        "request": "2.81.0",
+        "source-map": "0.5.7"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "co": "4.6.0",
+            "json-stable-stringify": "1.0.1"
+          }
+        },
+        "assert-plus": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+          "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+          "dev": true,
+          "optional": true
+        },
+        "aws-sign2": {
+          "version": "0.6.0",
+          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+          "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+          "dev": true,
+          "optional": true
+        },
+        "boom": {
+          "version": "2.10.1",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+          "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+          "dev": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        },
+        "cryptiles": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+          "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "boom": "2.10.1"
+          }
+        },
+        "form-data": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+          "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.5",
+            "mime-types": "2.1.17"
+          }
+        },
+        "har-schema": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+          "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+          "dev": true,
+          "optional": true
+        },
+        "har-validator": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+          "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ajv": "4.11.8",
+            "har-schema": "1.0.5"
+          }
+        },
+        "hawk": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+          "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "boom": "2.10.1",
+            "cryptiles": "2.0.5",
+            "hoek": "2.16.3",
+            "sntp": "1.0.9"
+          }
+        },
+        "hoek": {
+          "version": "2.16.3",
+          "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+          "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+          "dev": true
+        },
+        "http-signature": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+          "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "0.2.0",
+            "jsprim": "1.4.1",
+            "sshpk": "1.13.1"
+          }
+        },
+        "performance-now": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+          "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+          "dev": true,
+          "optional": true
+        },
+        "qs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+          "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+          "dev": true,
+          "optional": true
+        },
+        "request": {
+          "version": "2.81.0",
+          "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+          "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aws-sign2": "0.6.0",
+            "aws4": "1.6.0",
+            "caseless": "0.12.0",
+            "combined-stream": "1.0.5",
+            "extend": "3.0.1",
+            "forever-agent": "0.6.1",
+            "form-data": "2.1.4",
+            "har-validator": "4.2.1",
+            "hawk": "3.1.3",
+            "http-signature": "1.1.1",
+            "is-typedarray": "1.0.0",
+            "isstream": "0.1.2",
+            "json-stringify-safe": "5.0.1",
+            "mime-types": "2.1.17",
+            "oauth-sign": "0.8.2",
+            "performance-now": "0.2.0",
+            "qs": "6.4.0",
+            "safe-buffer": "5.1.1",
+            "stringstream": "0.0.5",
+            "tough-cookie": "2.3.3",
+            "tunnel-agent": "0.6.0",
+            "uuid": "3.1.0"
+          }
+        },
+        "sntp": {
+          "version": "1.0.9",
+          "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+          "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        }
+      }
+    },
+    "less-loader": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.0.5.tgz",
+      "integrity": "sha1-rhVadAbKxqzSk9eFWH/P8PR4xN0=",
+      "dev": true,
+      "requires": {
+        "clone": "2.1.1",
+        "loader-utils": "1.1.0",
+        "pify": "2.3.0"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
+          "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
+          "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="
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "parse-json": "2.2.0",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "strip-bom": "2.0.0"
+      }
+    },
+    "loader-runner": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
+      "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
+      "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.2.0",
+        "emojis-list": "2.1.0",
+        "json5": "0.5.1"
+      }
+    },
+    "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.4",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+    },
+    "lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+      "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.memoize": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+      "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
+    },
+    "lodash.uniq": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+      "dev": true
+    },
+    "loglevel": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.0.tgz",
+      "integrity": "sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ="
+    },
+    "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.6.0"
+      }
+    },
+    "longest": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+      "dev": true
+    },
+    "loose-envify": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+      "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
+      "dev": true,
+      "requires": {
+        "js-tokens": "3.0.2"
+      }
+    },
+    "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.2"
+      }
+    },
+    "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.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+      "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+      "dev": true,
+      "requires": {
+        "pseudomap": "1.0.2",
+        "yallist": "2.1.2"
+      }
+    },
+    "macaddress": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
+      "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=",
+      "dev": true
+    },
+    "make-dir": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz",
+      "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==",
+      "dev": true,
+      "requires": {
+        "pify": "3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "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
+    },
+    "marked": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz",
+      "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=",
+      "dev": true
+    },
+    "math-expression-evaluator": {
+      "version": "1.2.17",
+      "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
+      "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
+      "dev": true
+    },
+    "md5.js": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+      "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+      "dev": true,
+      "requires": {
+        "hash-base": "3.0.4",
+        "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "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.3",
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "mem": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+      "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "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.4",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "dev": true,
+      "requires": {
+        "camelcase-keys": "2.1.0",
+        "decamelize": "1.2.0",
+        "loud-rejection": "1.6.0",
+        "map-obj": "1.0.1",
+        "minimist": "1.2.0",
+        "normalize-package-data": "2.4.0",
+        "object-assign": "4.1.1",
+        "read-pkg-up": "1.0.1",
+        "redent": "1.0.0",
+        "trim-newlines": "1.0.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "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": "2.3.11",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+      "dev": true,
+      "requires": {
+        "arr-diff": "2.0.0",
+        "array-unique": "0.2.1",
+        "braces": "1.8.5",
+        "expand-brackets": "0.1.5",
+        "extglob": "0.3.2",
+        "filename-regex": "2.0.1",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1",
+        "kind-of": "3.2.2",
+        "normalize-path": "2.1.1",
+        "object.omit": "2.0.1",
+        "parse-glob": "3.0.4",
+        "regex-cache": "0.4.4"
+      }
+    },
+    "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.11.8",
+        "brorand": "1.1.0"
+      }
+    },
+    "mime": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+      "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.30.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+      "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.17",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+      "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.30.0"
+      }
+    },
+    "mimer": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/mimer/-/mimer-0.2.1.tgz",
+      "integrity": "sha1-xjxaF/6GQj9RYahdVcPtUYm6r/w=",
+      "dev": true
+    },
+    "mimic-fn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
+      "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
+      "dev": true
+    },
+    "minimalistic-assert": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
+      "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
+      "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.8"
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+      "dev": true
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "moment": {
+      "version": "2.20.1",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz",
+      "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg=="
+    },
+    "moment-timezone": {
+      "version": "0.5.14",
+      "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz",
+      "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=",
+      "requires": {
+        "moment": "2.20.1"
+      }
+    },
+    "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": "1.0.3"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "multicast-dns": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.1.tgz",
+      "integrity": "sha512-uV3/ckdsffHx9IrGQrx613mturMdMqQ06WTq+C09NsStJ9iNG6RcUWgPKs1Rfjy+idZT6tfQoXEusGNnEZhT3w==",
+      "dev": true,
+      "requires": {
+        "dns-packet": "1.2.2",
+        "thunky": "0.1.0"
+      }
+    },
+    "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
+    },
+    "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.8.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
+      "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=",
+      "dev": true,
+      "optional": true
+    },
+    "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
+    },
+    "ncname": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz",
+      "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=",
+      "dev": true,
+      "requires": {
+        "xml-char-classes": "1.0.0"
+      }
+    },
+    "negotiator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+      "dev": true
+    },
+    "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.4"
+      }
+    },
+    "node-forge": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
+      "integrity": "sha1-naYR6giYL0uUIGs760zJZl8gwwA="
+    },
+    "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.4.1",
+        "browserify-zlib": "0.2.0",
+        "buffer": "4.9.1",
+        "console-browserify": "1.1.0",
+        "constants-browserify": "1.0.0",
+        "crypto-browserify": "3.12.0",
+        "domain-browser": "1.1.7",
+        "events": "1.1.1",
+        "https-browserify": "1.0.0",
+        "os-browserify": "0.3.0",
+        "path-browserify": "0.0.0",
+        "process": "0.11.10",
+        "punycode": "1.4.1",
+        "querystring-es3": "0.2.1",
+        "readable-stream": "2.3.3",
+        "stream-browserify": "2.0.1",
+        "stream-http": "2.7.2",
+        "string_decoder": "1.0.3",
+        "timers-browserify": "2.0.4",
+        "tty-browserify": "0.0.0",
+        "url": "0.11.0",
+        "util": "0.10.3",
+        "vm-browserify": "0.0.4"
+      }
+    },
+    "node-md6": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/node-md6/-/node-md6-0.1.0.tgz",
+      "integrity": "sha1-9WH0WyszY1K4KXbFHMoRR9U5N/U="
+    },
+    "nomnom": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz",
+      "integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=",
+      "requires": {
+        "colors": "0.5.1",
+        "underscore": "1.1.7"
+      },
+      "dependencies": {
+        "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.1.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.5.0",
+        "is-builtin-module": "1.0.0",
+        "semver": "5.4.1",
+        "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.1.0"
+      }
+    },
+    "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
+    },
+    "normalize-url": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
+      "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "prepend-http": "1.0.4",
+        "query-string": "4.3.4",
+        "sort-keys": "1.1.2"
+      }
+    },
+    "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.1"
+      }
+    },
+    "nth-check": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
+      "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
+      "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.3",
+      "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz",
+      "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw=="
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+      "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-keys": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+      "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
+      "dev": true
+    },
+    "object.omit": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+      "dev": true,
+      "requires": {
+        "for-own": "0.1.5",
+        "is-extendable": "0.1.1"
+      }
+    },
+    "obuf": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz",
+      "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=",
+      "dev": true
+    },
+    "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.0.2"
+      }
+    },
+    "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.1.0"
+      }
+    },
+    "opn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz",
+      "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==",
+      "dev": true,
+      "requires": {
+        "is-wsl": "1.1.0"
+      }
+    },
+    "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.6",
+        "levn": "0.3.0",
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2",
+        "wordwrap": "1.0.0"
+      }
+    },
+    "original": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz",
+      "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=",
+      "dev": true,
+      "requires": {
+        "url-parse": "1.0.5"
+      },
+      "dependencies": {
+        "url-parse": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz",
+          "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=",
+          "dev": true,
+          "requires": {
+            "querystringify": "0.0.4",
+            "requires-port": "1.0.0"
+          }
+        }
+      }
+    },
+    "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": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+      "dev": true
+    },
+    "os-locale": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+      "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+      "dev": true,
+      "requires": {
+        "execa": "0.7.0",
+        "lcid": "1.0.0",
+        "mem": "1.1.0"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "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-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
+    "p-limit": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
+      "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
+      "dev": true
+    },
+    "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
+    },
+    "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.7.0",
+        "pumpify": "1.3.5",
+        "repeating": "2.0.1",
+        "split2": "1.1.1",
+        "through2": "2.0.3"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "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.3.2"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
+      "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+      "dev": true,
+      "requires": {
+        "asn1.js": "4.9.2",
+        "browserify-aes": "1.1.1",
+        "create-hash": "1.1.3",
+        "evp_bytestokey": "1.0.3",
+        "pbkdf2": "3.0.14"
+      }
+    },
+    "parse-glob": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+      "dev": true,
+      "requires": {
+        "glob-base": "0.3.0",
+        "is-dotfile": "1.0.3",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.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.3.1"
+      }
+    },
+    "parse5": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
+      "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=",
+      "dev": true
+    },
+    "parseurl": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+      "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-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": "https://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-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.11",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "pbkdf2": {
+      "version": "3.0.14",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
+      "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
+      "dev": true,
+      "requires": {
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "ripemd160": "2.0.1",
+        "safe-buffer": "5.1.1",
+        "sha.js": "2.4.9"
+      }
+    },
+    "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.12",
+        "iced-runtime": "1.0.3"
+      }
+    },
+    "phantomjs-prebuilt": {
+      "version": "2.1.15",
+      "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.15.tgz",
+      "integrity": "sha1-IPhugtM0nFBZF1J3RbekEeCLOQM=",
+      "dev": true,
+      "requires": {
+        "es6-promise": "4.0.5",
+        "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.14"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+          "dev": true,
+          "requires": {
+            "co": "4.6.0",
+            "json-stable-stringify": "1.0.1"
+          }
+        },
+        "assert-plus": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+          "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+          "dev": true
+        },
+        "aws-sign2": {
+          "version": "0.6.0",
+          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+          "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+          "dev": true
+        },
+        "boom": {
+          "version": "2.10.1",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+          "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+          "dev": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        },
+        "cryptiles": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+          "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+          "dev": true,
+          "requires": {
+            "boom": "2.10.1"
+          }
+        },
+        "form-data": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+          "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+          "dev": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.5",
+            "mime-types": "2.1.17"
+          }
+        },
+        "har-schema": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+          "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+          "dev": true
+        },
+        "har-validator": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+          "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+          "dev": true,
+          "requires": {
+            "ajv": "4.11.8",
+            "har-schema": "1.0.5"
+          }
+        },
+        "hawk": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+          "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+          "dev": true,
+          "requires": {
+            "boom": "2.10.1",
+            "cryptiles": "2.0.5",
+            "hoek": "2.16.3",
+            "sntp": "1.0.9"
+          }
+        },
+        "hoek": {
+          "version": "2.16.3",
+          "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+          "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+          "dev": true
+        },
+        "http-signature": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+          "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+          "dev": true,
+          "requires": {
+            "assert-plus": "0.2.0",
+            "jsprim": "1.4.1",
+            "sshpk": "1.13.1"
+          }
+        },
+        "performance-now": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+          "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+          "dev": true
+        },
+        "qs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+          "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+          "dev": true
+        },
+        "request": {
+          "version": "2.81.0",
+          "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+          "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+          "dev": true,
+          "requires": {
+            "aws-sign2": "0.6.0",
+            "aws4": "1.6.0",
+            "caseless": "0.12.0",
+            "combined-stream": "1.0.5",
+            "extend": "3.0.1",
+            "forever-agent": "0.6.1",
+            "form-data": "2.1.4",
+            "har-validator": "4.2.1",
+            "hawk": "3.1.3",
+            "http-signature": "1.1.1",
+            "is-typedarray": "1.0.0",
+            "isstream": "0.1.2",
+            "json-stringify-safe": "5.0.1",
+            "mime-types": "2.1.17",
+            "oauth-sign": "0.8.2",
+            "performance-now": "0.2.0",
+            "qs": "6.4.0",
+            "safe-buffer": "5.1.1",
+            "stringstream": "0.0.5",
+            "tough-cookie": "2.3.3",
+            "tunnel-agent": "0.6.0",
+            "uuid": "3.1.0"
+          }
+        },
+        "sntp": {
+          "version": "1.0.9",
+          "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+          "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+          "dev": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        }
+      }
+    },
+    "pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "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.4"
+      }
+    },
+    "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"
+      }
+    },
+    "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
+    },
+    "portfinder": {
+      "version": "1.0.13",
+      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz",
+      "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=",
+      "dev": true,
+      "requires": {
+        "async": "1.5.2",
+        "debug": "2.6.9",
+        "mkdirp": "0.5.1"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "postcss": {
+      "version": "5.2.17",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz",
+      "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "js-base64": "2.3.2",
+        "source-map": "0.5.7",
+        "supports-color": "3.2.3"
+      },
+      "dependencies": {
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "1.0.0"
+          }
+        }
+      }
+    },
+    "postcss-calc": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
+      "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17",
+        "postcss-message-helpers": "2.0.0",
+        "reduce-css-calc": "1.3.0"
+      }
+    },
+    "postcss-colormin": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
+      "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
+      "dev": true,
+      "requires": {
+        "colormin": "1.1.2",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-convert-values": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz",
+      "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-css-variables": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/postcss-css-variables/-/postcss-css-variables-0.8.0.tgz",
+      "integrity": "sha512-ilcsJMhq09HOsQ2RzXm+fPQNEwMN3kLab6IYpcL5EH8E1EKvBrWQRsiWONWqjWPAKHFMWkEvJTHJJzP9m1E0yQ==",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5",
+        "extend": "3.0.1",
+        "postcss": "6.0.12"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.12",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
+          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.1.0",
+            "source-map": "0.5.7",
+            "supports-color": "4.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "postcss-discard-comments": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
+      "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17"
+      }
+    },
+    "postcss-discard-duplicates": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz",
+      "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17"
+      }
+    },
+    "postcss-discard-empty": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
+      "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17"
+      }
+    },
+    "postcss-discard-overridden": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
+      "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17"
+      }
+    },
+    "postcss-discard-unused": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
+      "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17",
+        "uniqs": "2.0.0"
+      }
+    },
+    "postcss-filter-plugins": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz",
+      "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17",
+        "uniqid": "4.1.1"
+      }
+    },
+    "postcss-import": {
+      "version": "11.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.0.0.tgz",
+      "integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=",
+      "dev": true,
+      "requires": {
+        "postcss": "6.0.12",
+        "postcss-value-parser": "3.3.0",
+        "read-cache": "1.0.0",
+        "resolve": "1.1.7"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.12",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
+          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.1.0",
+            "source-map": "0.5.7",
+            "supports-color": "4.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "postcss-load-config": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
+      "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "2.2.2",
+        "object-assign": "4.1.1",
+        "postcss-load-options": "1.2.0",
+        "postcss-load-plugins": "2.3.0"
+      }
+    },
+    "postcss-load-options": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
+      "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "2.2.2",
+        "object-assign": "4.1.1"
+      }
+    },
+    "postcss-load-plugins": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
+      "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "2.2.2",
+        "object-assign": "4.1.1"
+      }
+    },
+    "postcss-loader": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.9.tgz",
+      "integrity": "sha512-sgoXPtmgVT3aBAhU47Kig8oPF+mbXl8Unjvtz1Qj1q2D2EvSVJW2mKJNzxv5y/LvA9xWwuvdysvhc7Zn80UWWw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0",
+        "postcss": "6.0.14",
+        "postcss-load-config": "1.2.0",
+        "schema-utils": "0.3.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.14",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz",
+          "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.3.0",
+            "source-map": "0.6.1",
+            "supports-color": "4.5.0"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "postcss-merge-idents": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz",
+      "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=",
+      "dev": true,
+      "requires": {
+        "has": "1.0.1",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-merge-longhand": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz",
+      "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17"
+      }
+    },
+    "postcss-merge-rules": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz",
+      "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=",
+      "dev": true,
+      "requires": {
+        "browserslist": "1.7.7",
+        "caniuse-api": "1.6.1",
+        "postcss": "5.2.17",
+        "postcss-selector-parser": "2.2.3",
+        "vendors": "1.0.1"
+      },
+      "dependencies": {
+        "browserslist": {
+          "version": "1.7.7",
+          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+          "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+          "dev": true,
+          "requires": {
+            "caniuse-db": "1.0.30000741",
+            "electron-to-chromium": "1.3.24"
+          }
+        }
+      }
+    },
+    "postcss-message-helpers": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz",
+      "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=",
+      "dev": true
+    },
+    "postcss-minify-font-values": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz",
+      "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-minify-gradients": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
+      "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-minify-params": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz",
+      "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "1.0.2",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0",
+        "uniqs": "2.0.0"
+      }
+    },
+    "postcss-minify-selectors": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz",
+      "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "1.0.2",
+        "has": "1.0.1",
+        "postcss": "5.2.17",
+        "postcss-selector-parser": "2.2.3"
+      }
+    },
+    "postcss-modules-extract-imports": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz",
+      "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=",
+      "dev": true,
+      "requires": {
+        "postcss": "6.0.12"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.12",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
+          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.1.0",
+            "source-map": "0.5.7",
+            "supports-color": "4.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "postcss-modules-local-by-default": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
+      "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "0.7.0",
+        "postcss": "6.0.12"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.12",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
+          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.1.0",
+            "source-map": "0.5.7",
+            "supports-color": "4.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "postcss-modules-scope": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
+      "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "0.7.0",
+        "postcss": "6.0.12"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.12",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
+          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.1.0",
+            "source-map": "0.5.7",
+            "supports-color": "4.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "postcss-modules-values": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
+      "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
+      "dev": true,
+      "requires": {
+        "icss-replace-symbols": "1.1.0",
+        "postcss": "6.0.12"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "postcss": {
+          "version": "6.0.12",
+          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
+          "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+          "dev": true,
+          "requires": {
+            "chalk": "2.1.0",
+            "source-map": "0.5.7",
+            "supports-color": "4.4.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "postcss-normalize-charset": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz",
+      "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17"
+      }
+    },
+    "postcss-normalize-url": {
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz",
+      "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=",
+      "dev": true,
+      "requires": {
+        "is-absolute-url": "2.1.0",
+        "normalize-url": "1.9.1",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-ordered-values": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz",
+      "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-reduce-idents": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz",
+      "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-reduce-initial": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz",
+      "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
+      "dev": true,
+      "requires": {
+        "postcss": "5.2.17"
+      }
+    },
+    "postcss-reduce-transforms": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz",
+      "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=",
+      "dev": true,
+      "requires": {
+        "has": "1.0.1",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "postcss-selector-parser": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
+      "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
+      "dev": true,
+      "requires": {
+        "flatten": "1.0.2",
+        "indexes-of": "1.0.1",
+        "uniq": "1.0.1"
+      }
+    },
+    "postcss-svgo": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz",
+      "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=",
+      "dev": true,
+      "requires": {
+        "is-svg": "2.1.0",
+        "postcss": "5.2.17",
+        "postcss-value-parser": "3.3.0",
+        "svgo": "0.7.2"
+      }
+    },
+    "postcss-unique-selectors": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz",
+      "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=",
+      "dev": true,
+      "requires": {
+        "alphanum-sort": "1.0.2",
+        "postcss": "5.2.17",
+        "uniqs": "2.0.0"
+      }
+    },
+    "postcss-value-parser": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+      "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
+      "dev": true
+    },
+    "postcss-zindex": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz",
+      "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=",
+      "dev": true,
+      "requires": {
+        "has": "1.0.1",
+        "postcss": "5.2.17",
+        "uniqs": "2.0.0"
+      }
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
+    },
+    "prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true
+    },
+    "preserve": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+      "dev": true
+    },
+    "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.0"
+      }
+    },
+    "private": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz",
+      "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=",
+      "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": "1.0.7",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+      "dev": true
+    },
+    "progress": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+      "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74="
+    },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "asap": "2.0.6"
+      }
+    },
+    "proxy-addr": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
+      "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
+      "dev": true,
+      "requires": {
+        "forwarded": "0.1.2",
+        "ipaddr.js": "1.5.2"
+      }
+    },
+    "prr": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
+      "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=",
+      "dev": true
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
+      "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "browserify-rsa": "4.0.1",
+        "create-hash": "1.1.3",
+        "parse-asn1": "5.1.0",
+        "randombytes": "2.0.5"
+      }
+    },
+    "pump": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz",
+      "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "1.4.0",
+        "once": "1.4.0"
+      }
+    },
+    "pumpify": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz",
+      "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=",
+      "dev": true,
+      "requires": {
+        "duplexify": "3.5.1",
+        "inherits": "2.0.3",
+        "pump": "1.0.2"
+      }
+    },
+    "punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+      "dev": true
+    },
+    "purepack": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/purepack/-/purepack-1.0.4.tgz",
+      "integrity": "sha1-CGKC/ZOShfWGZLqam7oxzbFlzNI="
+    },
+    "q": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
+      "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+      "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+      "dev": true
+    },
+    "query-string": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+      "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+      "dev": true,
+      "requires": {
+        "object-assign": "4.1.1",
+        "strict-uri-encode": "1.1.0"
+      }
+    },
+    "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": "0.0.4",
+      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz",
+      "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=",
+      "dev": true
+    },
+    "randomatic": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+      "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "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.2.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.6"
+              }
+            }
+          }
+        },
+        "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.6"
+          }
+        }
+      }
+    },
+    "randombytes": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
+      "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz",
+      "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==",
+      "dev": true,
+      "requires": {
+        "randombytes": "2.0.5",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "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": "2.3.2",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+      "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+      "dev": true,
+      "requires": {
+        "bytes": "3.0.0",
+        "http-errors": "1.6.2",
+        "iconv-lite": "0.4.19",
+        "unpipe": "1.0.0"
+      }
+    },
+    "rc": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
+      "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
+      "dev": true,
+      "requires": {
+        "deep-extend": "0.4.2",
+        "ini": "1.3.4",
+        "minimist": "1.2.0",
+        "strip-json-comments": "2.0.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "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"
+      }
+    },
+    "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.1.0",
+        "normalize-package-data": "2.4.0",
+        "path-type": "1.1.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.1.2",
+        "read-pkg": "1.1.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.1.0",
+            "pinkie-promise": "2.0.1"
+          }
+        },
+        "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.1"
+          }
+        }
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+      "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+      "dev": true,
+      "requires": {
+        "core-util-is": "1.0.2",
+        "inherits": "2.0.3",
+        "isarray": "1.0.0",
+        "process-nextick-args": "1.0.7",
+        "safe-buffer": "5.1.1",
+        "string_decoder": "1.0.3",
+        "util-deprecate": "1.0.2"
+      }
+    },
+    "readdirp": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+      "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "minimatch": "3.0.4",
+        "readable-stream": "2.3.3",
+        "set-immediate-shim": "1.0.1"
+      }
+    },
+    "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"
+      }
+    },
+    "reduce-css-calc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
+      "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "0.4.2",
+        "math-expression-evaluator": "1.2.17",
+        "reduce-function-call": "1.0.2"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "0.4.2",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+          "dev": true
+        }
+      }
+    },
+    "reduce-function-call": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
+      "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "0.4.2"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "0.4.2",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+          "dev": true
+        }
+      }
+    },
+    "regenerate": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
+      "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
+      "dev": true
+    },
+    "regenerator-runtime": {
+      "version": "0.10.5",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+      "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+      "dev": true
+    },
+    "regenerator-transform": {
+      "version": "0.10.1",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+      "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "private": "0.1.7"
+      }
+    },
+    "regex-cache": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+      "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+      "dev": true,
+      "requires": {
+        "is-equal-shallow": "0.1.3"
+      }
+    },
+    "regexpu-core": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+      "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+      "dev": true,
+      "requires": {
+        "regenerate": "1.3.3",
+        "regjsgen": "0.2.0",
+        "regjsparser": "0.1.5"
+      }
+    },
+    "regjsgen": {
+      "version": "0.2.0",
+      "resolved": "https://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"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://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.1",
+      "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz",
+      "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=",
+      "dev": true,
+      "requires": {
+        "css-select": "1.2.0",
+        "dom-converter": "0.1.4",
+        "htmlparser2": "3.3.0",
+        "strip-ansi": "3.0.1",
+        "utila": "0.3.3"
+      },
+      "dependencies": {
+        "utila": {
+          "version": "0.3.3",
+          "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz",
+          "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=",
+          "dev": true
+        }
+      }
+    },
+    "repeat-element": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+      "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.2"
+      }
+    },
+    "request": {
+      "version": "2.83.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+      "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "0.7.0",
+        "aws4": "1.6.0",
+        "caseless": "0.12.0",
+        "combined-stream": "1.0.5",
+        "extend": "3.0.1",
+        "forever-agent": "0.6.1",
+        "form-data": "2.3.1",
+        "har-validator": "5.0.3",
+        "hawk": "6.0.2",
+        "http-signature": "1.2.0",
+        "is-typedarray": "1.0.0",
+        "isstream": "0.1.2",
+        "json-stringify-safe": "5.0.1",
+        "mime-types": "2.1.17",
+        "oauth-sign": "0.8.2",
+        "performance-now": "2.1.0",
+        "qs": "6.5.1",
+        "safe-buffer": "5.1.1",
+        "stringstream": "0.0.5",
+        "tough-cookie": "2.3.3",
+        "tunnel-agent": "0.6.0",
+        "uuid": "3.1.0"
+      }
+    },
+    "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"
+      }
+    },
+    "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": "1.2.1",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+      "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+      "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
+    },
+    "require-uncached": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+      "dev": true,
+      "requires": {
+        "caller-path": "0.1.0",
+        "resolve-from": "1.0.1"
+      }
+    },
+    "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.1.7",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+      "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+      "dev": true
+    },
+    "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": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "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.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "right-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+      "dev": true,
+      "requires": {
+        "align-text": "0.1.4"
+      }
+    },
+    "rimraf": {
+      "version": "2.2.8",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
+      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
+      "dev": true
+    },
+    "ripemd160": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
+      "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+      "dev": true,
+      "requires": {
+        "hash-base": "2.0.2",
+        "inherits": "2.0.3"
+      }
+    },
+    "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"
+      }
+    },
+    "rx-lite": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+      "dev": true
+    },
+    "rx-lite-aggregates": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+      "dev": true,
+      "requires": {
+        "rx-lite": "4.0.8"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+      "dev": true
+    },
+    "sanitize-html": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.15.0.tgz",
+      "integrity": "sha512-1jWLToWx8ZV53Z1Jg+2fHl8dNFsxvQt2Cmrk4o/z1+MUdB5EXSU0QVuzlGGhfp7cQrYbEEfMO/TUWHfkBUqujQ==",
+      "dev": true,
+      "requires": {
+        "htmlparser2": "3.9.2",
+        "lodash.escaperegexp": "4.1.2",
+        "srcset": "1.0.0",
+        "xtend": "4.0.1"
+      },
+      "dependencies": {
+        "domhandler": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
+          "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0"
+          }
+        },
+        "htmlparser2": {
+          "version": "3.9.2",
+          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
+          "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0",
+            "domhandler": "2.4.1",
+            "domutils": "1.5.1",
+            "entities": "1.1.1",
+            "inherits": "2.0.3",
+            "readable-stream": "2.3.3"
+          }
+        }
+      }
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+      "dev": true
+    },
+    "schema-utils": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
+      "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=",
+      "dev": true,
+      "requires": {
+        "ajv": "5.2.3"
+      }
+    },
+    "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.1",
+      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.1.tgz",
+      "integrity": "sha1-v4y3uDJWxFUeMTR8YxF3jbme7FI=",
+      "dev": true,
+      "requires": {
+        "node-forge": "0.6.33"
+      },
+      "dependencies": {
+        "node-forge": {
+          "version": "0.6.33",
+          "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.33.tgz",
+          "integrity": "sha1-RjgRh59XPUUVWtap9D3ClujoXrw=",
+          "dev": true
+        }
+      }
+    },
+    "semver": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+      "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
+      "dev": true
+    },
+    "send": {
+      "version": "0.16.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+      "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "depd": "1.1.1",
+        "destroy": "1.0.4",
+        "encodeurl": "1.0.1",
+        "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.3.1"
+      }
+    },
+    "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.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+      "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
+      "dev": true,
+      "requires": {
+        "encodeurl": "1.0.1",
+        "escape-html": "1.0.3",
+        "parseurl": "1.3.2",
+        "send": "0.16.1"
+      }
+    },
+    "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-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true
+    },
+    "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.9",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz",
+      "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "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.5.3",
+      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.5.3.tgz",
+      "integrity": "sha1-xUmCuZbHbvDB5rWfvcWCX1txMRM=",
+      "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
+    },
+    "sladex-blowfish": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/sladex-blowfish/-/sladex-blowfish-0.8.1.tgz",
+      "integrity": "sha1-y431Dra7sJgchCjGzl6B8H5kZrE="
+    },
+    "slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+      "dev": true
+    },
+    "slice-ansi": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "2.0.0"
+      }
+    },
+    "sntp": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz",
+      "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=",
+      "dev": true,
+      "requires": {
+        "hoek": "4.2.0"
+      }
+    },
+    "sockjs": {
+      "version": "0.3.18",
+      "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz",
+      "integrity": "sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc=",
+      "dev": true,
+      "requires": {
+        "faye-websocket": "0.10.0",
+        "uuid": "2.0.3"
+      },
+      "dependencies": {
+        "uuid": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
+          "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
+          "dev": true
+        }
+      }
+    },
+    "sockjs-client": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz",
+      "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "eventsource": "0.1.6",
+        "faye-websocket": "0.11.1",
+        "inherits": "2.0.3",
+        "json3": "3.3.2",
+        "url-parse": "1.2.0"
+      },
+      "dependencies": {
+        "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.7.0"
+          }
+        }
+      }
+    },
+    "sort-keys": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+      "dev": true,
+      "requires": {
+        "is-plain-obj": "1.1.0"
+      }
+    },
+    "sortablejs": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.7.0.tgz",
+      "integrity": "sha1-gKKyNwq9Vo4c7IwnETHvMKkE+ig="
+    },
+    "source-list-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
+      "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+    },
+    "source-map-support": {
+      "version": "0.4.18",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7"
+      }
+    },
+    "spdx-correct": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+      "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+      "dev": true,
+      "requires": {
+        "spdx-license-ids": "1.2.2"
+      }
+    },
+    "spdx-expression-parse": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+      "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
+      "dev": true
+    },
+    "spdx-license-ids": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+      "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
+      "dev": true
+    },
+    "spdy": {
+      "version": "3.4.7",
+      "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz",
+      "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "handle-thing": "1.2.5",
+        "http-deceiver": "1.2.7",
+        "safe-buffer": "5.1.1",
+        "select-hose": "2.0.0",
+        "spdy-transport": "2.0.20"
+      }
+    },
+    "spdy-transport": {
+      "version": "2.0.20",
+      "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz",
+      "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "detect-node": "2.0.3",
+        "hpack.js": "2.1.6",
+        "obuf": "1.1.1",
+        "readable-stream": "2.3.3",
+        "safe-buffer": "5.1.1",
+        "wbuf": "1.7.2"
+      }
+    },
+    "split.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.3.5.tgz",
+      "integrity": "sha1-YuLOZtLPkcx3SqXwdJ/yUTgDn1A="
+    },
+    "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.3"
+      }
+    },
+    "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.3",
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "sshpk": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+      "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+      "dev": true,
+      "requires": {
+        "asn1": "0.2.3",
+        "assert-plus": "1.0.0",
+        "bcrypt-pbkdf": "1.0.1",
+        "dashdash": "1.14.1",
+        "ecc-jsbn": "0.1.1",
+        "getpass": "0.1.7",
+        "jsbn": "0.1.1",
+        "tweetnacl": "0.14.5"
+      },
+      "dependencies": {
+        "jsbn": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+          "dev": true,
+          "optional": 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.9.0"
+      }
+    },
+    "statuses": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+      "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+      "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.3",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "stream-consume": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz",
+      "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=",
+      "dev": true
+    },
+    "stream-http": {
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz",
+      "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "3.0.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3",
+        "to-arraybuffer": "1.0.1",
+        "xtend": "4.0.1"
+      }
+    },
+    "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
+    },
+    "strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "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": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "stringstream": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+      "dev": true
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "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.1"
+      }
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://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.19.1",
+      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz",
+      "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0",
+        "schema-utils": "0.3.0"
+      }
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
+    },
+    "svgo": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
+      "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
+      "dev": true,
+      "requires": {
+        "coa": "1.0.4",
+        "colors": "1.1.2",
+        "csso": "2.3.2",
+        "js-yaml": "3.7.0",
+        "mkdirp": "0.5.1",
+        "sax": "1.2.4",
+        "whet.extend": "0.9.9"
+      },
+      "dependencies": {
+        "colors": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+          "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+          "dev": true
+        }
+      }
+    },
+    "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": "4.0.2",
+      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+      "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.2.3",
+        "ajv-keywords": "2.1.0",
+        "chalk": "2.1.0",
+        "lodash": "4.17.4",
+        "slice-ansi": "1.0.0",
+        "string-width": "2.1.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
+          "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "taffydb": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+      "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+      "dev": true
+    },
+    "tapable": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
+      "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
+      "dev": true
+    },
+    "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": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+      "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.3",
+        "xtend": "4.0.1"
+      }
+    },
+    "thunky": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz",
+      "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=",
+      "dev": true
+    },
+    "time-stamp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz",
+      "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=",
+      "dev": true
+    },
+    "timers-browserify": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz",
+      "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==",
+      "dev": true,
+      "requires": {
+        "setimmediate": "1.0.5"
+      }
+    },
+    "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=",
+      "dev": true
+    },
+    "toposort": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz",
+      "integrity": "sha1-wxdI5V0hDv/AD9zcfW5o19e7nOw=",
+      "dev": true
+    },
+    "tough-cookie": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+      "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      }
+    },
+    "tr46": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
+      "dev": true
+    },
+    "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.26",
+      "resolved": "https://registry.npmjs.org/triplesec/-/triplesec-3.0.26.tgz",
+      "integrity": "sha1-3/K7R1ikIzcuc5o5fYmR8Fl9CsE=",
+      "requires": {
+        "iced-error": "0.0.12",
+        "iced-lock": "1.1.0",
+        "iced-runtime": "1.0.3",
+        "more-entropy": "0.0.7",
+        "progress": "1.1.8"
+      }
+    },
+    "tryit": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
+      "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
+      "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.1.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true,
+      "optional": true
+    },
+    "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-is": {
+      "version": "1.6.15",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
+      "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+      "dev": true,
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "2.1.17"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "uglify-js": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.3.tgz",
+      "integrity": "sha512-5ZUOgufCHjN2mBBLfz63UtWTP6va2sSzBpNCM+/iqI6RnPzEhANmB0EKiKBYdQbc3v7KeomXJ2DJx0Xq9gvUvA==",
+      "dev": true,
+      "requires": {
+        "commander": "2.11.0",
+        "source-map": "0.5.7"
+      }
+    },
+    "uglify-to-browserify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+      "dev": true,
+      "optional": true
+    },
+    "uglifyjs-webpack-plugin": {
+      "version": "0.4.6",
+      "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
+      "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7",
+        "uglify-js": "2.8.29",
+        "webpack-sources": "1.0.1"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+          "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+          "dev": true
+        },
+        "uglify-js": {
+          "version": "2.8.29",
+          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+          "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+          "dev": true,
+          "requires": {
+            "source-map": "0.5.7",
+            "uglify-to-browserify": "1.0.2",
+            "yargs": "3.10.0"
+          }
+        },
+        "yargs": {
+          "version": "3.10.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+          "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+          "dev": true,
+          "requires": {
+            "camelcase": "1.2.1",
+            "cliui": "2.1.0",
+            "decamelize": "1.2.0",
+            "window-size": "0.1.0"
+          }
+        }
+      }
+    },
+    "uint64be": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/uint64be/-/uint64be-1.0.1.tgz",
+      "integrity": "sha1-H3FUIC8qG4rzU4cd2mUb80zpPpU="
+    },
+    "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.2.3",
+      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.2.3.tgz",
+      "integrity": "sha1-gGmSYzZl1eX8tNsfs6hi62jp5to=",
+      "dev": true
+    },
+    "uniq": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+      "dev": true
+    },
+    "uniqid": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz",
+      "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=",
+      "dev": true,
+      "requires": {
+        "macaddress": "0.2.8"
+      }
+    },
+    "uniqs": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+      "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
+      "dev": true
+    },
+    "unixify": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/unixify/-/unixify-0.2.1.tgz",
+      "integrity": "sha1-SGQwPCbsyuEWDZHQRvZUc/Aivtw=",
+      "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
+    },
+    "upper-case": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+      "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
+      "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-loader": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz",
+      "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0",
+        "mime": "1.4.1",
+        "schema-utils": "0.3.0"
+      }
+    },
+    "url-parse": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz",
+      "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==",
+      "dev": true,
+      "requires": {
+        "querystringify": "1.0.0",
+        "requires-port": "1.0.0"
+      },
+      "dependencies": {
+        "querystringify": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz",
+          "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=",
+          "dev": true
+        }
+      }
+    },
+    "utf8": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+      "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ=="
+    },
+    "util": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+      "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.1"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "utila": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+      "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
+      "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.1.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+      "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+      "dev": true
+    },
+    "val-loader": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/val-loader/-/val-loader-1.1.0.tgz",
+      "integrity": "sha512-8m62XF42FcfrBBl02rtDY9hQhDcDczrEcr60/aSMxlzJiXAcbAimRPvsDoDa5QcGAusOgOmVTpFtK5EbfZdDwA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0"
+      }
+    },
+    "valid-data-url": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-0.1.4.tgz",
+      "integrity": "sha512-p3bCVl3Vrz42TV37a1OjagyLLd6qQAXBDWarIazuo7NQzCt8Kw8ZZwSAbUVPGlz5ubgbgJmgT0KRjLeCFNrfoQ==",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+      "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "1.0.2",
+        "spdx-expression-parse": "1.0.4"
+      }
+    },
+    "validator": {
+      "version": "5.7.0",
+      "resolved": "https://registry.npmjs.org/validator/-/validator-5.7.0.tgz",
+      "integrity": "sha1-eoelgUa2laxIYHEUHAxJ1n2gXlw=",
+      "dev": true
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true
+    },
+    "vendors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz",
+      "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=",
+      "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.3.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"
+      }
+    },
+    "watchpack": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
+      "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=",
+      "dev": true,
+      "requires": {
+        "async": "2.5.0",
+        "chokidar": "1.7.0",
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "wbuf": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz",
+      "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=",
+      "dev": true,
+      "requires": {
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "web-resource-inliner": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.2.0.tgz",
+      "integrity": "sha512-NvLvZzKvnNAB3LXG5c12WwUx5ZA7ZfNMYq82GnbhFyBLuu3jtamW4tQ40M02XiQzkFsyDuWG6Y2TOq9yywaxlg==",
+      "dev": true,
+      "requires": {
+        "async": "2.5.0",
+        "chalk": "1.1.3",
+        "datauri": "1.0.5",
+        "htmlparser2": "3.9.2",
+        "lodash.unescape": "4.0.1",
+        "request": "2.83.0",
+        "valid-data-url": "0.1.4",
+        "xtend": "4.0.1"
+      },
+      "dependencies": {
+        "domhandler": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
+          "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0"
+          }
+        },
+        "htmlparser2": {
+          "version": "3.9.2",
+          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
+          "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0",
+            "domhandler": "2.4.1",
+            "domutils": "1.5.1",
+            "entities": "1.1.1",
+            "inherits": "2.0.3",
+            "readable-stream": "2.3.3"
+          }
+        }
+      }
+    },
+    "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": "3.10.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz",
+      "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==",
+      "dev": true,
+      "requires": {
+        "acorn": "5.2.1",
+        "acorn-dynamic-import": "2.0.2",
+        "ajv": "5.2.3",
+        "ajv-keywords": "2.1.0",
+        "async": "2.5.0",
+        "enhanced-resolve": "3.4.1",
+        "escope": "3.6.0",
+        "interpret": "1.1.0",
+        "json-loader": "0.5.7",
+        "json5": "0.5.1",
+        "loader-runner": "2.3.0",
+        "loader-utils": "1.1.0",
+        "memory-fs": "0.4.1",
+        "mkdirp": "0.5.1",
+        "node-libs-browser": "2.1.0",
+        "source-map": "0.5.7",
+        "supports-color": "4.5.0",
+        "tapable": "0.2.8",
+        "uglifyjs-webpack-plugin": "0.4.6",
+        "watchpack": "1.4.0",
+        "webpack-sources": "1.0.1",
+        "yargs": "8.0.2"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.2.1",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz",
+          "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==",
+          "dev": true
+        },
+        "escope": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+          "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+          "dev": true,
+          "requires": {
+            "es6-map": "0.1.5",
+            "es6-weak-map": "2.0.2",
+            "esrecurse": "4.2.0",
+            "estraverse": "4.2.0"
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "webpack-dev-middleware": {
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz",
+      "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==",
+      "dev": true,
+      "requires": {
+        "memory-fs": "0.4.1",
+        "mime": "1.6.0",
+        "path-is-absolute": "1.0.1",
+        "range-parser": "1.2.0",
+        "time-stamp": "2.0.0"
+      },
+      "dependencies": {
+        "mime": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+          "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-dev-server": {
+      "version": "2.9.7",
+      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.7.tgz",
+      "integrity": "sha512-Pu7uoQFgQj5RE5wmlfkpYSzihMKxulwEuO2xCsaMnAnyRSApwoVi3B8WCm9XbigyWTHaIMzYGkB90Vr6leAeTQ==",
+      "dev": true,
+      "requires": {
+        "ansi-html": "0.0.7",
+        "array-includes": "3.0.3",
+        "bonjour": "3.5.0",
+        "chokidar": "1.7.0",
+        "compression": "1.7.1",
+        "connect-history-api-fallback": "1.5.0",
+        "debug": "3.1.0",
+        "del": "3.0.0",
+        "express": "4.16.2",
+        "html-entities": "1.2.1",
+        "http-proxy-middleware": "0.17.4",
+        "import-local": "0.1.1",
+        "internal-ip": "1.2.0",
+        "ip": "1.1.5",
+        "killable": "1.0.0",
+        "loglevel": "1.6.0",
+        "opn": "5.1.0",
+        "portfinder": "1.0.13",
+        "selfsigned": "1.10.1",
+        "serve-index": "1.9.1",
+        "sockjs": "0.3.18",
+        "sockjs-client": "1.1.4",
+        "spdy": "3.4.7",
+        "strip-ansi": "3.0.1",
+        "supports-color": "4.5.0",
+        "webpack-dev-middleware": "1.12.2",
+        "yargs": "6.6.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
+        },
+        "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.2",
+            "strip-ansi": "3.0.1",
+            "wrap-ansi": "2.1.0"
+          }
+        },
+        "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"
+          }
+        },
+        "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.2.0",
+            "pify": "3.0.0",
+            "rimraf": "2.2.8"
+          }
+        },
+        "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.2",
+            "glob": "7.0.6",
+            "object-assign": "4.1.1",
+            "pify": "2.3.0",
+            "pinkie-promise": "2.0.1"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "2.3.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+              "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+              "dev": true
+            }
+          }
+        },
+        "has-flag": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+          "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.1"
+          }
+        },
+        "os-locale": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+          "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+          "dev": true,
+          "requires": {
+            "lcid": "1.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "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.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "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
+        },
+        "yargs": {
+          "version": "6.6.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
+          "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
+          "dev": true,
+          "requires": {
+            "camelcase": "3.0.0",
+            "cliui": "3.2.0",
+            "decamelize": "1.2.0",
+            "get-caller-file": "1.0.2",
+            "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": "4.2.1"
+          }
+        },
+        "yargs-parser": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
+          "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
+          "dev": true,
+          "requires": {
+            "camelcase": "3.0.0"
+          }
+        }
+      }
+    },
+    "webpack-node-externals": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.6.0.tgz",
+      "integrity": "sha1-Iyxi7GCSsQBjWj0p2DwXRxKN+b0=",
+      "dev": true
+    },
+    "webpack-sources": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz",
+      "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "2.0.0",
+        "source-map": "0.5.7"
+      }
+    },
+    "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.9",
+        "websocket-extensions": "0.1.3"
+      }
+    },
+    "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
+    },
+    "whatwg-encoding": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz",
+      "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=",
+      "dev": true,
+      "requires": {
+        "iconv-lite": "0.4.13"
+      },
+      "dependencies": {
+        "iconv-lite": {
+          "version": "0.4.13",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
+          "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=",
+          "dev": true
+        }
+      }
+    },
+    "whatwg-url": {
+      "version": "4.8.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz",
+      "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=",
+      "dev": true,
+      "requires": {
+        "tr46": "0.0.3",
+        "webidl-conversions": "3.0.1"
+      },
+      "dependencies": {
+        "webidl-conversions": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+          "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
+          "dev": true
+        }
+      }
+    },
+    "whet.extend": {
+      "version": "0.9.9",
+      "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
+      "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=",
+      "dev": true
+    },
+    "which": {
+      "version": "1.2.14",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
+      "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
+      "dev": true,
+      "requires": {
+        "isexe": "2.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
+    },
+    "window-size": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+      "dev": true
+    },
+    "wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
+    },
+    "worker-loader": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-1.1.0.tgz",
+      "integrity": "sha512-W91q8Wi1JxbzFQZuLJlFK4x8UuWjKgeOX9IMMyng007K0UkP6I8lOejckoCWY61QmnJq2x9qZ/Viru+uF8g6nA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.1.0",
+        "schema-utils": "0.3.0"
+      }
+    },
+    "wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "dev": true,
+      "requires": {
+        "string-width": "1.0.2",
+        "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.1"
+          }
+        },
+        "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.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        }
+      }
+    },
+    "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"
+      }
+    },
+    "xml-char-classes": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz",
+      "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=",
+      "dev": true
+    },
+    "xml-name-validator": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
+      "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=",
+      "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=="
+    },
+    "xtend": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "dev": true
+    },
+    "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": "8.0.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
+      "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
+      "dev": true,
+      "requires": {
+        "camelcase": "4.1.0",
+        "cliui": "3.2.0",
+        "decamelize": "1.2.0",
+        "get-caller-file": "1.0.2",
+        "os-locale": "2.1.0",
+        "read-pkg-up": "2.0.0",
+        "require-directory": "2.1.1",
+        "require-main-filename": "1.0.1",
+        "set-blocking": "2.0.0",
+        "string-width": "2.1.1",
+        "which-module": "2.0.0",
+        "y18n": "3.2.1",
+        "yargs-parser": "7.0.0"
+      },
+      "dependencies": {
+        "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": "3.2.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+          "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+          "dev": true,
+          "requires": {
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "wrap-ansi": "2.1.0"
+          },
+          "dependencies": {
+            "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.1.0",
+                "is-fullwidth-code-point": "1.0.0",
+                "strip-ansi": "3.0.1"
+              }
+            }
+          }
+        },
+        "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.1"
+          }
+        },
+        "load-json-file": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "parse-json": "2.2.0",
+            "pify": "2.3.0",
+            "strip-bom": "3.0.0"
+          }
+        },
+        "path-type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+          "dev": true,
+          "requires": {
+            "pify": "2.3.0"
+          }
+        },
+        "read-pkg": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "2.0.0",
+            "normalize-package-data": "2.4.0",
+            "path-type": "2.0.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+          "dev": true,
+          "requires": {
+            "find-up": "2.1.0",
+            "read-pkg": "2.0.0"
+          }
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+      "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+      "dev": true,
+      "requires": {
+        "camelcase": "4.1.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+          "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+          "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="
+    }
+  }
+}

+ 122 - 112
package.json

@@ -1,112 +1,122 @@
-{
-  "name": "cyberchef",
-  "version": "6.4.0",
-  "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
-  "author": "n1474335 <n1474335@gmail.com>",
-  "homepage": "https://gchq.github.io/CyberChef",
-  "copyright": "Crown copyright 2016",
-  "license": "Apache-2.0",
-  "keywords": [
-    "cipher",
-    "cypher",
-    "encode",
-    "decode",
-    "encrypt",
-    "decrypt",
-    "base64",
-    "xor",
-    "charset",
-    "hex",
-    "encoding",
-    "format",
-    "cybersecurity",
-    "data manipulation",
-    "data analysis"
-  ],
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/gchq/CyberChef/"
-  },
-  "main": "build/node/CyberChef.js",
-  "bugs": "https://github.com/gchq/CyberChef/issues",
-  "devDependencies": {
-    "babel-core": "^6.26.0",
-    "babel-loader": "^7.1.2",
-    "babel-plugin-transform-runtime": "^6.23.0",
-    "babel-polyfill": "^6.26.0",
-    "babel-preset-env": "^1.6.0",
-    "babel-preset-es2015": "^6.24.1",
-    "babel-preset-stage-0": "^6.24.1",
-    "css-loader": "^0.28.7",
-    "exports-loader": "^0.6.4",
-    "extract-text-webpack-plugin": "^3.0.1",
-    "file-loader": "^1.1.4",
-    "grunt": ">=1.0.1",
-    "grunt-accessibility": "~5.0.0",
-    "grunt-chmod": "~1.1.1",
-    "grunt-concurrent": "^2.3.1",
-    "grunt-contrib-clean": "~1.1.0",
-    "grunt-contrib-copy": "~1.0.0",
-    "grunt-eslint": "^20.1.0",
-    "grunt-exec": "~3.0.0",
-    "grunt-execute": "^0.2.2",
-    "grunt-jsdoc": "^2.2.0",
-    "grunt-webpack": "^3.0.2",
-    "html-webpack-plugin": "^2.30.1",
-    "imports-loader": "^0.7.1",
-    "ink-docstrap": "^1.3.0",
-    "jsdoc-babel": "^0.3.0",
-    "less": "^2.7.2",
-    "less-loader": "^4.0.5",
-    "postcss-css-variables": "^0.8.0",
-    "postcss-import": "^11.0.0",
-    "postcss-loader": "^2.0.6",
-    "style-loader": "^0.19.0",
-    "url-loader": "^0.6.2",
-    "val-loader": "^1.0.2",
-    "web-resource-inliner": "^4.2.0",
-    "webpack": "^3.6.0",
-    "webpack-dev-server": "^2.9.1",
-    "webpack-node-externals": "^1.6.0",
-    "worker-loader": "^1.0.0"
-  },
-  "dependencies": {
-    "bootstrap": "^3.3.7",
-    "bootstrap-colorpicker": "^2.5.2",
-    "bootstrap-switch": "^3.3.4",
-    "crypto-api": "^0.7.5",
-    "crypto-js": "^3.1.9-1",
-    "diff": "^3.3.1",
-    "es6-promisify": "^5.0.0",
-    "escodegen": "^1.9.0",
-    "esmangle": "^1.0.1",
-    "esprima": "^4.0.0",
-    "exif-parser": "^0.1.12",
-    "google-code-prettify": "^1.0.5",
-    "jquery": "^3.2.1",
-    "js-crc": "^0.2.0",
-    "js-sha3": "^0.6.1",
-    "jsbn": "^1.1.0",
-    "jsonpath": "^0.2.12",
-    "jsrsasign": "8.0.4",
-    "kbpgp": "^2.0.76",
-    "lodash": "^4.17.4",
-    "moment": "^2.18.1",
-    "moment-timezone": "^0.5.13",
-    "node-md6": "^0.1.0",
-    "otp": "^0.1.3",
-    "sladex-blowfish": "^0.8.1",
-    "sortablejs": "^1.6.1",
-    "split.js": "^1.3.5",
-    "vkbeautify": "^0.99.3",
-    "xmldom": "^0.1.27",
-    "xpath": "0.0.24",
-    "zlibjs": "^0.3.1"
-  },
-  "scripts": {
-    "start": "grunt dev",
-    "build": "grunt prod",
-    "test": "grunt test",
-    "docs": "grunt docs"
-  }
-}
+{
+  "name": "cyberchef",
+  "version": "7.4.0",
+  "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
+  "author": "n1474335 <n1474335@gmail.com>",
+  "homepage": "https://gchq.github.io/CyberChef",
+  "copyright": "Crown copyright 2016",
+  "license": "Apache-2.0",
+  "keywords": [
+    "cipher",
+    "cypher",
+    "encode",
+    "decode",
+    "encrypt",
+    "decrypt",
+    "base64",
+    "xor",
+    "charset",
+    "hex",
+    "encoding",
+    "format",
+    "cybersecurity",
+    "data manipulation",
+    "data analysis"
+  ],
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/gchq/CyberChef/"
+  },
+  "main": "build/node/CyberChef.js",
+  "bugs": "https://github.com/gchq/CyberChef/issues",
+  "devDependencies": {
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-preset-env": "^1.6.1",
+    "babel-plugin-transform-runtime": "^6.23.0",
+    "babel-polyfill": "^6.26.0",
+    "babel-preset-env": "^1.6.0",
+    "babel-preset-es2015": "^6.24.1",
+    "babel-preset-stage-0": "^6.24.1",
+    "css-loader": "^0.28.7",
+    "exports-loader": "^0.6.4",
+    "extract-text-webpack-plugin": "^3.0.2",
+    "file-loader": "^1.1.6",
+    "grunt": ">=1.0.1",
+    "grunt-accessibility": "~5.0.0",
+    "grunt-chmod": "~1.1.1",
+    "grunt-concurrent": "^2.3.1",
+    "grunt-contrib-clean": "~1.1.0",
+    "grunt-contrib-copy": "~1.0.0",
+    "grunt-eslint": "^20.1.0",
+    "grunt-exec": "~3.0.0",
+    "grunt-execute": "^0.2.2",
+    "grunt-jsdoc": "^2.2.0",
+    "grunt-webpack": "^3.0.2",
+    "html-webpack-plugin": "^2.30.1",
+    "imports-loader": "^0.7.1",
+    "ink-docstrap": "^1.3.2",
+    "jsdoc-babel": "^0.3.0",
+    "less": "^2.7.3",
+    "less-loader": "^4.0.5",
+    "postcss-css-variables": "^0.8.0",
+    "postcss-import": "^11.0.0",
+    "postcss-loader": "^2.0.9",
+    "style-loader": "^0.19.1",
+    "url-loader": "^0.6.2",
+    "val-loader": "^1.1.0",
+    "web-resource-inliner": "^4.2.0",
+    "webpack": "^3.10.0",
+    "webpack-dev-server": "^2.9.7",
+    "webpack-node-externals": "^1.6.0",
+    "worker-loader": "^1.1.0"
+  },
+  "dependencies": {
+    "babel-polyfill": "^6.26.0",
+    "bignumber.js": "^5.0.0",
+    "bootstrap": "^3.3.7",
+    "bootstrap-colorpicker": "^2.5.2",
+    "bootstrap-switch": "^3.3.4",
+    "crypto-api": "^0.7.5",
+    "crypto-js": "^3.1.9-1",
+    "diff": "^3.4.0",
+    "diff": "^3.3.1",
+    "es6-promisify": "^5.0.0",
+    "escodegen": "^1.9.0",
+    "esmangle": "^1.0.1",
+    "esprima": "^4.0.0",
+    "exif-parser": "^0.1.12",
+    "file-saver": "^1.3.3",
+    "google-code-prettify": "^1.0.5",
+    "jquery": "^3.2.1",
+    "js-crc": "^0.2.0",
+    "js-sha3": "^0.7.0",
+    "jsbn": "^1.1.0",
+    "jsonpath": "^1.0.0",
+    "jsrsasign": "8.0.4",
+    "kbpgp": "^2.0.76",
+    "lodash": "^4.17.4",
+    "loglevel": "^1.6.0",
+    "loglevel-message-prefix": "^3.0.0",
+    "moment": "^2.20.1",
+    "moment-timezone": "^0.5.14",
+    "node-forge": "^0.7.1",
+    "node-md6": "^0.1.0",
+    "nwmatcher": "^1.4.3",
+    "otp": "^0.1.3",
+    "sladex-blowfish": "^0.8.1",
+    "sortablejs": "^1.7.0",
+    "split.js": "^1.3.5",
+    "utf8": "^3.0.0",
+    "vkbeautify": "^0.99.3",
+    "xmldom": "^0.1.27",
+    "xpath": "0.0.27",
+    "zlibjs": "^0.3.1"
+  },
+  "scripts": {
+    "start": "grunt dev",
+    "build": "grunt prod",
+    "test": "grunt test",
+    "docs": "grunt docs"
+  }
+}

+ 22 - 10
src/core/Chef.js

@@ -19,7 +19,7 @@ const Chef = function() {
 /**
 /**
  * Runs the recipe over the input.
  * Runs the recipe over the input.
  *
  *
- * @param {string} inputText - The input data as a string
+ * @param {string|ArrayBuffer} input - The input data as a string or ArrayBuffer
  * @param {Object[]} recipeConfig - The recipe configuration object
  * @param {Object[]} recipeConfig - The recipe configuration object
  * @param {Object} options - The options object storing various user choices
  * @param {Object} options - The options object storing various user choices
  * @param {boolean} options.attempHighlight - Whether or not to attempt highlighting
  * @param {boolean} options.attempHighlight - Whether or not to attempt highlighting
@@ -33,11 +33,13 @@ const Chef = function() {
  * @returns {number} response.duration - The number of ms it took to execute 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)
  * @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(),
+Chef.prototype.bake = async function(input, recipeConfig, options, progress, step) {
+    log.debug("Chef baking");
+    const startTime  = new Date().getTime(),
         recipe     = new Recipe(recipeConfig),
         recipe     = new Recipe(recipeConfig),
         containsFc = recipe.containsFlowControl(),
         containsFc = recipe.containsFlowControl(),
-        error      = false;
+        notUTF8    = options && options.hasOwnProperty("treatAsUtf8") && !options.treatAsUtf8;
+    let error      = false;
 
 
     if (containsFc && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
     if (containsFc && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
 
 
@@ -62,22 +64,30 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress,
 
 
     // If starting from scratch, load data
     // If starting from scratch, load data
     if (progress === 0) {
     if (progress === 0) {
-        this.dish.set(inputText, Dish.STRING);
+        const type = input instanceof ArrayBuffer ? Dish.ARRAY_BUFFER : Dish.STRING;
+        this.dish.set(input, type);
     }
     }
 
 
     try {
     try {
         progress = await recipe.execute(this.dish, progress);
         progress = await recipe.execute(this.dish, progress);
     } catch (err) {
     } 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;
+        log.error(err);
+        error = {
+            displayStr: err.displayStr,
+        };
         progress = err.progress;
         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;
+
     return {
     return {
         result: this.dish.type === Dish.HTML ?
         result: this.dish.type === Dish.HTML ?
-            this.dish.get(Dish.HTML) :
-            this.dish.get(Dish.STRING),
+            this.dish.get(Dish.HTML, notUTF8) :
+            this.dish.get(returnType, notUTF8),
         type: Dish.enumLookup(this.dish.type),
         type: Dish.enumLookup(this.dish.type),
         progress: progress,
         progress: progress,
         duration: new Date().getTime() - startTime,
         duration: new Date().getTime() - startTime,
@@ -104,6 +114,8 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress,
  * @returns {number} The time it took to run the silent bake in milliseconds.
  * @returns {number} The time it took to run the silent bake in milliseconds.
 */
 */
 Chef.prototype.silentBake = function(recipeConfig) {
 Chef.prototype.silentBake = function(recipeConfig) {
+    log.debug("Running silent bake");
+
     let startTime = new Date().getTime(),
     let startTime = new Date().getTime(),
         recipe    = new Recipe(recipeConfig),
         recipe    = new Recipe(recipeConfig),
         dish      = new Dish("", Dish.STRING);
         dish      = new Dish("", Dish.STRING);

+ 16 - 2
src/core/ChefWorker.js

@@ -11,6 +11,15 @@ import Chef from "./Chef.js";
 import OperationConfig from "./config/MetaConfig.js";
 import OperationConfig from "./config/MetaConfig.js";
 import OpModules from "./config/modules/Default.js";
 import OpModules from "./config/modules/Default.js";
 
 
+// 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
 // Set up Chef instance
 self.chef = new Chef();
 self.chef = new Chef();
@@ -42,6 +51,8 @@ self.postMessage({
 self.addEventListener("message", function(e) {
 self.addEventListener("message", function(e) {
     // Handle message
     // Handle message
     const r = e.data;
     const r = e.data;
+    log.debug("ChefWorker receiving command '" + r.action + "'");
+
     switch (r.action) {
     switch (r.action) {
         case "bake":
         case "bake":
             bake(r.data);
             bake(r.data);
@@ -61,6 +72,9 @@ self.addEventListener("message", function(e) {
                 r.data.pos
                 r.data.pos
             );
             );
             break;
             break;
+        case "setLogLevel":
+            log.setLevel(r.data, false);
+            break;
         default:
         default:
             break;
             break;
     }
     }
@@ -86,7 +100,7 @@ async function bake(data) {
         );
         );
 
 
         self.postMessage({
         self.postMessage({
-            action: "bakeSuccess",
+            action: "bakeComplete",
             data: response
             data: response
         });
         });
     } catch (err) {
     } catch (err) {
@@ -121,7 +135,7 @@ function loadRequiredModules(recipeConfig) {
         let module = self.OperationConfig[op.op].module;
         let module = self.OperationConfig[op.op].module;
 
 
         if (!OpModules.hasOwnProperty(module)) {
         if (!OpModules.hasOwnProperty(module)) {
-            console.log("Loading module " + module);
+            log.info("Loading module " + module);
             self.sendStatusMessage("Loading module " + module);
             self.sendStatusMessage("Loading module " + module);
             self.importScripts(self.docURL + "/" + module + ".js");
             self.importScripts(self.docURL + "/" + module + ".js");
         }
         }

+ 99 - 31
src/core/Dish.js

@@ -1,19 +1,21 @@
 import Utils from "./Utils.js";
 import Utils from "./Utils.js";
+import BigNumber from "bignumber.js";
 
 
 /**
 /**
  * The data being operated on by each operation.
  * The data being operated on by each operation.
  *
  *
  * @author n1474335 [n1474335@gmail.com]
  * @author n1474335 [n1474335@gmail.com]
+ * @author Matt C [matt@artemisbot.uk]
  * @copyright Crown Copyright 2016
  * @copyright Crown Copyright 2016
  * @license Apache-2.0
  * @license Apache-2.0
  *
  *
  * @class
  * @class
- * @param {byteArray|string|number} value - The value of the input data.
+ * @param {byteArray|string|number|ArrayBuffer|BigNumber} value - The value of the input data.
  * @param {number} type - The data type of value, see Dish enums.
  * @param {number} type - The data type of value, see Dish enums.
  */
  */
 const Dish = function(value, type) {
 const Dish = function(value, type) {
-    this.value = value || typeof value == "string" ? value : null;
-    this.type  = type || Dish.BYTE_ARRAY;
+    this.value = value || typeof value === "string" ? value : null;
+    this.type = type || Dish.BYTE_ARRAY;
 };
 };
 
 
 
 
@@ -41,6 +43,18 @@ Dish.NUMBER = 2;
  * @enum
  * @enum
  */
  */
 Dish.HTML = 3;
 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;
 
 
 
 
 /**
 /**
@@ -51,19 +65,22 @@ Dish.HTML = 3;
  * @returns {number} The data type enum value.
  * @returns {number} The data type enum value.
  */
  */
 Dish.typeEnum = function(typeStr) {
 Dish.typeEnum = function(typeStr) {
-    switch (typeStr) {
-        case "byteArray":
-        case "Byte array":
+    switch (typeStr.toLowerCase()) {
+        case "bytearray":
+        case "byte array":
             return Dish.BYTE_ARRAY;
             return Dish.BYTE_ARRAY;
         case "string":
         case "string":
-        case "String":
             return Dish.STRING;
             return Dish.STRING;
         case "number":
         case "number":
-        case "Number":
             return Dish.NUMBER;
             return Dish.NUMBER;
         case "html":
         case "html":
-        case "HTML":
             return Dish.HTML;
             return Dish.HTML;
+        case "arraybuffer":
+        case "array buffer":
+            return Dish.ARRAY_BUFFER;
+        case "bignumber":
+        case "big number":
+            return Dish.BIG_NUMBER;
         default:
         default:
             throw "Invalid data type string. No matching enum.";
             throw "Invalid data type string. No matching enum.";
     }
     }
@@ -74,8 +91,8 @@ Dish.typeEnum = function(typeStr) {
  * Returns the data type string for the given type enum.
  * Returns the data type string for the given type enum.
  *
  *
  * @static
  * @static
- * @param {string} typeEnum - The enum value of the data type.
- * @returns {number} The data type as a string.
+ * @param {number} typeEnum - The enum value of the data type.
+ * @returns {string} The data type as a string.
  */
  */
 Dish.enumLookup = function(typeEnum) {
 Dish.enumLookup = function(typeEnum) {
     switch (typeEnum) {
     switch (typeEnum) {
@@ -87,6 +104,10 @@ Dish.enumLookup = function(typeEnum) {
             return "number";
             return "number";
         case Dish.HTML:
         case Dish.HTML:
             return "html";
             return "html";
+        case Dish.ARRAY_BUFFER:
+            return "ArrayBuffer";
+        case Dish.BIG_NUMBER:
+            return "BigNumber";
         default:
         default:
             throw "Invalid data type enum. No matching type.";
             throw "Invalid data type enum. No matching type.";
     }
     }
@@ -96,12 +117,13 @@ Dish.enumLookup = function(typeEnum) {
 /**
 /**
  * Sets the data value and type and then validates them.
  * Sets the data value and type and then validates them.
  *
  *
- * @param {byteArray|string|number} value - The value of the input data.
+ * @param {byteArray|string|number|ArrayBuffer|BigNumber} value - The value of the input data.
  * @param {number} type - The data type of value, see Dish enums.
  * @param {number} type - The data type of value, see Dish enums.
  */
  */
 Dish.prototype.set = function(value, type) {
 Dish.prototype.set = function(value, type) {
+    log.debug("Dish type: " + Dish.enumLookup(type));
     this.value = value;
     this.value = value;
-    this.type  = type;
+    this.type = type;
 
 
     if (!this.valid()) {
     if (!this.valid()) {
         const sample = Utils.truncate(JSON.stringify(this.value), 13);
         const sample = Utils.truncate(JSON.stringify(this.value), 13);
@@ -114,11 +136,12 @@ Dish.prototype.set = function(value, type) {
  * Returns the value of the data in the type format specified.
  * Returns the value of the data in the type format specified.
  *
  *
  * @param {number} type - The data type of value, see Dish enums.
  * @param {number} type - The data type of value, see Dish enums.
- * @returns {byteArray|string|number} The value of the output data.
+ * @param {boolean} [notUTF8] - Do not treat strings as UTF8.
+ * @returns {byteArray|string|number|ArrayBuffer|BigNumber} The value of the output data.
  */
  */
-Dish.prototype.get = function(type) {
+Dish.prototype.get = function(type, notUTF8) {
     if (this.type !== type) {
     if (this.type !== type) {
-        this.translate(type);
+        this.translate(type, notUTF8);
     }
     }
     return this.value;
     return this.value;
 };
 };
@@ -128,37 +151,59 @@ Dish.prototype.get = function(type) {
  * Translates the data to the given type format.
  * Translates the data to the given type format.
  *
  *
  * @param {number} toType - The data type of value, see Dish enums.
  * @param {number} toType - The data type of value, see Dish enums.
+ * @param {boolean} [notUTF8] - Do not treat strings as UTF8.
  */
  */
-Dish.prototype.translate = function(toType) {
+Dish.prototype.translate = function(toType, notUTF8) {
+    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
     // Convert data to intermediate byteArray type
     switch (this.type) {
     switch (this.type) {
         case Dish.STRING:
         case Dish.STRING:
             this.value = this.value ? Utils.strToByteArray(this.value) : [];
             this.value = this.value ? Utils.strToByteArray(this.value) : [];
-            this.type = Dish.BYTE_ARRAY;
             break;
             break;
         case Dish.NUMBER:
         case Dish.NUMBER:
             this.value = typeof this.value == "number" ? Utils.strToByteArray(this.value.toString()) : [];
             this.value = typeof this.value == "number" ? Utils.strToByteArray(this.value.toString()) : [];
-            this.type = Dish.BYTE_ARRAY;
             break;
             break;
         case Dish.HTML:
         case Dish.HTML:
             this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
             this.value = this.value ? Utils.strToByteArray(Utils.unescapeHtml(Utils.stripHtmlTags(this.value, true))) : [];
-            this.type = Dish.BYTE_ARRAY;
+            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 = this.value instanceof BigNumber ? Utils.strToByteArray(this.value.toString()) : [];
             break;
             break;
         default:
         default:
             break;
             break;
     }
     }
 
 
+    this.type = Dish.BYTE_ARRAY;
+
     // Convert from byteArray to toType
     // Convert from byteArray to toType
     switch (toType) {
     switch (toType) {
         case Dish.STRING:
         case Dish.STRING:
         case Dish.HTML:
         case Dish.HTML:
-            this.value = this.value ? Utils.byteArrayToUtf8(this.value) : "";
+            this.value = this.value ? byteArrayToStr(this.value) : "";
             this.type = Dish.STRING;
             this.type = Dish.STRING;
             break;
             break;
         case Dish.NUMBER:
         case Dish.NUMBER:
-            this.value = this.value ? parseFloat(Utils.byteArrayToUtf8(this.value)) : 0;
+            this.value = this.value ? parseFloat(byteArrayToStr(this.value)) : 0;
             this.type = Dish.NUMBER;
             this.type = Dish.NUMBER;
             break;
             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;
         default:
         default:
             break;
             break;
     }
     }
@@ -180,7 +225,7 @@ Dish.prototype.valid = function() {
 
 
             // Check that every value is a number between 0 - 255
             // Check that every value is a number between 0 - 255
             for (let i = 0; i < this.value.length; i++) {
             for (let i = 0; i < this.value.length; i++) {
-                if (typeof this.value[i] != "number" ||
+                if (typeof this.value[i] !== "number" ||
                     this.value[i] < 0 ||
                     this.value[i] < 0 ||
                     this.value[i] > 255) {
                     this.value[i] > 255) {
                     return false;
                     return false;
@@ -189,18 +234,41 @@ Dish.prototype.valid = function() {
             return true;
             return true;
         case Dish.STRING:
         case Dish.STRING:
         case Dish.HTML:
         case Dish.HTML:
-            if (typeof this.value == "string") {
-                return true;
-            }
-            return false;
+            return typeof this.value === "string";
         case Dish.NUMBER:
         case Dish.NUMBER:
-            if (typeof this.value == "number") {
-                return true;
-            }
-            return false;
+            return typeof this.value === "number";
+        case Dish.ARRAY_BUFFER:
+            return this.value instanceof ArrayBuffer;
+        case Dish.BIG_NUMBER:
+            return this.value instanceof BigNumber;
         default:
         default:
             return false;
             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}
+*/
+Dish.prototype.size = function() {
+    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;
+        default:
+            return -1;
+    }
+};
+
+
 export default Dish;
 export default Dish;

+ 44 - 20
src/core/FlowControl.js

@@ -56,6 +56,7 @@ const FlowControl = {
 
 
         // Run recipe over each tranche
         // Run recipe over each tranche
         for (i = 0; i < inputs.length; i++) {
         for (i = 0; i < inputs.length; i++) {
+            log.debug(`Entering tranche ${i + 1} of ${inputs.length}`);
             const dish = new Dish(inputs[i], inputType);
             const dish = new Dish(inputs[i], inputType);
             try {
             try {
                 progress = await recipe.execute(dish, 0);
                 progress = await recipe.execute(dish, 0);
@@ -169,20 +170,19 @@ const FlowControl = {
      * @returns {Object} The updated state of the recipe.
      * @returns {Object} The updated state of the recipe.
      */
      */
     runJump: function(state) {
     runJump: function(state) {
-        let ings     = state.opList[state.progress].getIngValues(),
-            jumpNum  = ings[0],
-            maxJumps = ings[1];
+        const ings     = state.opList[state.progress].getIngValues(),
+            label = ings[0],
+            maxJumps = ings[1],
+            jmpIndex = FlowControl._getLabelIndex(label, state);
 
 
-        if (jumpNum < 0) {
-            jumpNum--;
-        }
-
-        if (state.numJumps >= maxJumps) {
+        if (state.numJumps >= maxJumps || jmpIndex === -1) {
+            log.debug("Maximum jumps reached or label cannot be found");
             return state;
             return state;
         }
         }
 
 
-        state.progress += jumpNum;
+        state.progress = jmpIndex;
         state.numJumps++;
         state.numJumps++;
+        log.debug(`Jumping to label '${label}' at position ${jmpIndex} (jumps = ${state.numJumps})`);
         return state;
         return state;
     },
     },
 
 
@@ -198,23 +198,26 @@ const FlowControl = {
      * @returns {Object} The updated state of the recipe.
      * @returns {Object} The updated state of the recipe.
      */
      */
     runCondJump: function(state) {
     runCondJump: function(state) {
-        let ings     = state.opList[state.progress].getIngValues(),
+        const ings     = state.opList[state.progress].getIngValues(),
             dish     = state.dish,
             dish     = state.dish,
             regexStr = ings[0],
             regexStr = ings[0],
-            jumpNum  = ings[1],
-            maxJumps = ings[2];
-
-        if (jumpNum < 0) {
-            jumpNum--;
-        }
+            invert   = ings[1],
+            label    = ings[2],
+            maxJumps = ings[3],
+            jmpIndex = FlowControl._getLabelIndex(label, state);
 
 
-        if (state.numJumps >= maxJumps) {
+        if (state.numJumps >= maxJumps || jmpIndex === -1) {
+            log.debug("Maximum jumps reached or label cannot be found");
             return state;
             return state;
         }
         }
 
 
-        if (regexStr !== "" && dish.get(Dish.STRING).search(regexStr) > -1) {
-            state.progress += jumpNum;
-            state.numJumps++;
+        if (regexStr !== "") {
+            let strMatch = dish.get(Dish.STRING).search(regexStr) > -1;
+            if (!invert && strMatch || invert && !strMatch) {
+                state.progress = jmpIndex;
+                state.numJumps++;
+                log.debug(`Jumping to label '${label}' at position ${jmpIndex} (jumps = ${state.numJumps})`);
+            }
         }
         }
 
 
         return state;
         return state;
@@ -249,6 +252,27 @@ const FlowControl = {
         return state;
         return state;
     },
     },
 
 
+
+    /**
+     * Returns the index of a label.
+     *
+     * @private
+     * @param {Object} state
+     * @param {string} name
+     * @returns {number}
+     */
+    _getLabelIndex: function(name, state) {
+        for (let o = 0; o < state.opList.length; o++) {
+            let operation = state.opList[o];
+            if (operation.name === "Label"){
+                let ings = operation.getIngValues();
+                if (name === ings[0]) {
+                    return o;
+                }
+            }
+        }
+        return -1;
+    },
 };
 };
 
 
 export default FlowControl;
 export default FlowControl;

+ 6 - 0
src/core/Recipe.js

@@ -146,18 +146,23 @@ Recipe.prototype.lastOpIndex = function(startIndex) {
 Recipe.prototype.execute = async function(dish, startFrom) {
 Recipe.prototype.execute = async function(dish, startFrom) {
     startFrom = startFrom || 0;
     startFrom = startFrom || 0;
     let op, input, output, numJumps = 0, numRegisters = 0;
     let op, input, output, numJumps = 0, numRegisters = 0;
+    log.debug(`[*] Executing recipe of ${this.opList.length} operations, starting at ${startFrom}`);
 
 
     for (let i = startFrom; i < this.opList.length; i++) {
     for (let i = startFrom; i < this.opList.length; i++) {
         op = this.opList[i];
         op = this.opList[i];
+        log.debug(`[${i}] ${op.name} ${JSON.stringify(op.getIngValues())}`);
         if (op.isDisabled()) {
         if (op.isDisabled()) {
+            log.debug("Operation is disabled, skipping");
             continue;
             continue;
         }
         }
         if (op.isBreakpoint()) {
         if (op.isBreakpoint()) {
+            log.debug("Pausing at breakpoint");
             return i;
             return i;
         }
         }
 
 
         try {
         try {
             input = dish.get(op.inputType);
             input = dish.get(op.inputType);
+            log.debug("Executing operation");
 
 
             if (op.isFlowControl()) {
             if (op.isFlowControl()) {
                 // Package up the current state
                 // Package up the current state
@@ -193,6 +198,7 @@ Recipe.prototype.execute = async function(dish, startFrom) {
         }
         }
     }
     }
 
 
+    log.debug("Recipe complete");
     return this.opList.length;
     return this.opList.length;
 };
 };
 
 

+ 130 - 138
src/core/Utils.js

@@ -1,4 +1,4 @@
-import CryptoJS from "crypto-js";
+import utf8 from "utf8";
 
 
 
 
 /**
 /**
@@ -64,58 +64,6 @@ const Utils = {
     },
     },
 
 
 
 
-    /**
-     * Adds leading zeros to strings
-     *
-     * @param {string} str - String to add leading characters to.
-     * @param {number} max - Maximum width of the string.
-     * @param {char} [chr='0'] - The character to pad with.
-     * @returns {string}
-     *
-     * @example
-     * // returns "0a"
-     * Utils.padLeft("a", 2);
-     *
-     * // returns "000a"
-     * Utils.padLeft("a", 4);
-     *
-     * // returns "xxxa"
-     * Utils.padLeft("a", 4, "x");
-     *
-     * // returns "bcabchello"
-     * Utils.padLeft("hello", 10, "abc");
-     */
-    padLeft: function(str, max, chr) {
-        chr = chr || "0";
-        let startIndex = chr.length - (max - str.length);
-        startIndex = startIndex < 0 ? 0 : startIndex;
-        return str.length < max ?
-            Utils.padLeft(chr.slice(startIndex, chr.length) + str, max, chr) : str;
-    },
-
-
-    /**
-     * Adds trailing spaces to strings.
-     *
-     * @param {string} str - String to add trailing characters to.
-     * @param {number} max - Maximum width of the string.
-     * @param {char} [chr='0'] - The character to pad with.
-     * @returns {string}
-     *
-     * @example
-     * // returns "a   "
-     * Utils.padRight("a", 4);
-     *
-     * // returns "axxx"
-     * Utils.padRight("a", 4, "x");
-     */
-    padRight: function(str, max, chr) {
-        chr = chr || " ";
-        return str.length < max ?
-            Utils.padRight(str + chr.slice(0, max-str.length), max, chr) : str;
-    },
-
-
     /**
     /**
      * Adds trailing bytes to a byteArray.
      * Adds trailing bytes to a byteArray.
      *
      *
@@ -152,14 +100,6 @@ const Utils = {
     },
     },
 
 
 
 
-    /**
-     * @alias Utils.padLeft
-     */
-    pad: function(str, max, chr) {
-        return Utils.padLeft(str, max, chr);
-    },
-
-
     /**
     /**
      * Truncates a long string to max length and adds suffix.
      * Truncates a long string to max length and adds suffix.
      *
      *
@@ -201,7 +141,7 @@ const Utils = {
     hex: function(c, length) {
     hex: function(c, length) {
         c = typeof c == "string" ? Utils.ord(c) : c;
         c = typeof c == "string" ? Utils.ord(c) : c;
         length = length || 2;
         length = length || 2;
-        return Utils.pad(c.toString(16), length);
+        return c.toString(16).padStart(length, "0");
     },
     },
 
 
 
 
@@ -222,7 +162,7 @@ const Utils = {
     bin: function(c, length) {
     bin: function(c, length) {
         c = typeof c == "string" ? Utils.ord(c) : c;
         c = typeof c == "string" ? Utils.ord(c) : c;
         length = length || 8;
         length = length || 8;
-        return Utils.pad(c.toString(2), length);
+        return c.toString(2).padStart(length, "0");
     },
     },
 
 
 
 
@@ -261,7 +201,7 @@ const Utils = {
      * Utils.parseEscapedChars("\\n");
      * Utils.parseEscapedChars("\\n");
      */
      */
     parseEscapedChars: function(str) {
     parseEscapedChars: function(str) {
-        return str.replace(/(\\)?\\([nrtbf]|x[\da-f]{2})/g, function(m, a, b) {
+        return str.replace(/(\\)?\\([nrtbf]|x[\da-fA-F]{2})/g, function(m, a, b) {
             if (a === "\\") return "\\"+b;
             if (a === "\\") return "\\"+b;
             switch (b[0]) {
             switch (b[0]) {
                 case "n":
                 case "n":
@@ -340,6 +280,72 @@ const Utils = {
     },
     },
 
 
 
 
+    /**
+     * Coverts data of varying types to a byteArray.
+     * Accepts hex, Base64, UTF8 and Latin1 strings.
+     *
+     * @param {string} str
+     * @param {string} type - One of "Hex", "Base64", "UTF8" or "Latin1"
+     * @returns {byteArray}
+     *
+     * @example
+     * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
+     * Utils.convertToByteArray("Привет", "utf8");
+     *
+     * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
+     * Utils.convertToByteArray("d097d0b4d180d0b0d0b2d181d182d0b2d183d0b9d182d0b5", "hex");
+     *
+     * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
+     * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
+     */
+    convertToByteArray: function(str, type) {
+        switch (type.toLowerCase()) {
+            case "hex":
+                return Utils.fromHex(str);
+            case "base64":
+                return Utils.fromBase64(str, null, "byteArray");
+            case "utf8":
+                return Utils.strToUtf8ByteArray(str);
+            case "latin1":
+            default:
+                return Utils.strToByteArray(str);
+        }
+    },
+
+
+    /**
+     * Coverts data of varying types to a byte string.
+     * Accepts hex, Base64, UTF8 and Latin1 strings.
+     *
+     * @param {string} str
+     * @param {string} type - One of "Hex", "Base64", "UTF8" or "Latin1"
+     * @returns {string}
+     *
+     * @example
+     * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
+     * Utils.convertToByteArray("Привет", "utf8");
+     *
+     * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
+     * Utils.convertToByteArray("d097d0b4d180d0b0d0b2d181d182d0b2d183d0b9d182d0b5", "hex");
+     *
+     * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130]
+     * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64");
+     */
+    convertToByteString: function(str, type) {
+        switch (type.toLowerCase()) {
+            case "hex":
+                return Utils.byteArrayToChars(Utils.fromHex(str));
+            case "base64":
+                return Utils.byteArrayToChars(Utils.fromBase64(str, null, "byteArray"));
+            case "utf8":
+                return utf8.encode(str);
+            case "latin1":
+            default:
+                return str;
+        }
+    },
+
+
     /**
     /**
      * Converts a string to a byte array.
      * Converts a string to a byte array.
      * Treats the string as UTF-8 if any values are over 255.
      * Treats the string as UTF-8 if any values are over 255.
@@ -381,17 +387,17 @@ const Utils = {
      * Utils.strToUtf8ByteArray("你好");
      * Utils.strToUtf8ByteArray("你好");
      */
      */
     strToUtf8ByteArray: function(str) {
     strToUtf8ByteArray: function(str) {
-        let wordArray = CryptoJS.enc.Utf8.parse(str),
-            byteArray = Utils.wordArrayToByteArray(wordArray);
+        const utf8Str = utf8.encode(str);
 
 
-        if (str.length !== wordArray.sigBytes) {
+        if (str.length !== utf8Str.length) {
             if (ENVIRONMENT_IS_WORKER()) {
             if (ENVIRONMENT_IS_WORKER()) {
                 self.setOption("attemptHighlight", false);
                 self.setOption("attemptHighlight", false);
             } else if (ENVIRONMENT_IS_WEB()) {
             } else if (ENVIRONMENT_IS_WEB()) {
                 window.app.options.attemptHighlight = false;
                 window.app.options.attemptHighlight = false;
             }
             }
         }
         }
-        return byteArray;
+
+        return Utils.strToByteArray(utf8Str);
     },
     },
 
 
 
 
@@ -443,26 +449,21 @@ const Utils = {
      * Utils.byteArrayToUtf8([228,189,160,229,165,189]);
      * Utils.byteArrayToUtf8([228,189,160,229,165,189]);
      */
      */
     byteArrayToUtf8: function(byteArray) {
     byteArrayToUtf8: function(byteArray) {
+        const str = Utils.byteArrayToChars(byteArray);
         try {
         try {
-            // Try to output data as UTF-8 string
-            const words = [];
-            for (let i = 0; i < byteArray.length; i++) {
-                words[i >>> 2] |= byteArray[i] << (24 - (i % 4) * 8);
-            }
-            let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
-                str = CryptoJS.enc.Utf8.stringify(wordArray);
+            const utf8Str = utf8.decode(str);
 
 
-            if (str.length !== wordArray.sigBytes) {
+            if (str.length !== utf8Str.length) {
                 if (ENVIRONMENT_IS_WORKER()) {
                 if (ENVIRONMENT_IS_WORKER()) {
                     self.setOption("attemptHighlight", false);
                     self.setOption("attemptHighlight", false);
                 } else if (ENVIRONMENT_IS_WEB()) {
                 } else if (ENVIRONMENT_IS_WEB()) {
                     window.app.options.attemptHighlight = false;
                     window.app.options.attemptHighlight = false;
                 }
                 }
             }
             }
-            return str;
+            return utf8Str;
         } catch (err) {
         } catch (err) {
             // If it fails, treat it as ANSI
             // If it fails, treat it as ANSI
-            return Utils.byteArrayToChars(byteArray);
+            return str;
         }
         }
     },
     },
 
 
@@ -470,7 +471,7 @@ const Utils = {
     /**
     /**
      * Converts a charcode array to a string.
      * Converts a charcode array to a string.
      *
      *
-     * @param {byteArray} byteArray
+     * @param {byteArray|Uint8Array} byteArray
      * @returns {string}
      * @returns {string}
      *
      *
      * @example
      * @example
@@ -491,33 +492,25 @@ const Utils = {
 
 
 
 
     /**
     /**
-     * Converts a CryptoJS.lib.WordArray to a byteArray.
+     * Converts an ArrayBuffer to a string.
      *
      *
-     * @param {CryptoJS.lib.WordArray} wordArray
-     * @returns {byteArray}
+     * @param {ArrayBuffer} arrayBuffer
+     * @returns {string}
      *
      *
      * @example
      * @example
-     * // returns [84, 101, 115, 116]
-     * Utils.wordArrayToByteArray(CryptoJS.enc.Hex.parse("54657374"));
+     * // returns "hello"
+     * Utils.arrayBufferToStr(Uint8Array.from([104,101,108,108,111]).buffer);
      */
      */
-    wordArrayToByteArray: function(wordArray) {
-        if (wordArray.sigBytes <= 0) return [];
-
-        let words = wordArray.words,
-            byteArray = [];
-
-        for (let i = 0; i < wordArray.sigBytes; i++) {
-            byteArray.push((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff);
-        }
-
-        return byteArray;
+    arrayBufferToStr: function(arrayBuffer) {
+        const byteArray = Array.prototype.slice.call(new Uint8Array(arrayBuffer));
+        return Utils.byteArrayToUtf8(byteArray);
     },
     },
 
 
 
 
     /**
     /**
      * Base64's the input byte array using the given alphabet, returning a string.
      * Base64's the input byte array using the given alphabet, returning a string.
      *
      *
-     * @param {byteArray|string} data
+     * @param {byteArray|Uint8Array|string} data
      * @param {string} [alphabet]
      * @param {string} [alphabet]
      * @returns {string}
      * @returns {string}
      *
      *
@@ -636,7 +629,7 @@ const Utils = {
     /**
     /**
      * Convert a byte array into a hex string.
      * Convert a byte array into a hex string.
      *
      *
-     * @param {byteArray} data
+     * @param {Uint8Array|byteArray} data
      * @param {string} [delim=" "]
      * @param {string} [delim=" "]
      * @param {number} [padding=2]
      * @param {number} [padding=2]
      * @returns {string}
      * @returns {string}
@@ -656,7 +649,7 @@ const Utils = {
         let output = "";
         let output = "";
 
 
         for (let i = 0; i < data.length; i++) {
         for (let i = 0; i < data.length; i++) {
-            output += Utils.pad(data[i].toString(16), padding) + delim;
+            output += data[i].toString(16).padStart(padding, "0") + delim;
         }
         }
 
 
         // Add \x or 0x to beginning
         // Add \x or 0x to beginning
@@ -859,7 +852,7 @@ const Utils = {
      *
      *
      * fragment      = *( pchar / "/" / "?" )
      * fragment      = *( pchar / "/" / "?" )
      * query         = *( pchar / "/" / "?" )
      * query         = *( pchar / "/" / "?" )
-     * pchar         = unreserved / pct-encoded / sub-delims / ":" / "@" 
+     * pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
      * unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
      * unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
      * pct-encoded   = "%" HEXDIG HEXDIG
      * pct-encoded   = "%" HEXDIG HEXDIG
      * sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
      * sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
@@ -1248,21 +1241,6 @@ const Utils = {
         "None":          /\s+/g // Included here to remove whitespace when there shouldn't be any
         "None":          /\s+/g // Included here to remove whitespace when there shouldn't be any
     },
     },
 
 
-
-    /**
-     * A mapping of string formats to their classes in the CryptoJS library.
-     * @constant
-     */
-    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,
-    },
-
 };
 };
 
 
 export default Utils;
 export default Utils;
@@ -1376,29 +1354,43 @@ String.prototype.count = function(chr) {
 };
 };
 
 
 
 
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Library overrides ///////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse
- * the hex string.
- *
- * @param {string} hexStr
- * @returns {CryptoJS.lib.WordArray}
+/*
+ * Polyfills
  */
  */
-CryptoJS.enc.Hex.parse = function (hexStr) {
-    // Remove whitespace
-    hexStr = hexStr.replace(/\s/g, "");
-
-    // Shortcut
-    const hexStrLength = hexStr.length;
-
-    // Convert
-    const words = [];
-    for (let i = 0; i < hexStrLength; i += 2) {
-        words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
-    }
 
 
-    return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2);
-};
+// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
+if (!String.prototype.padStart) {
+    String.prototype.padStart = function padStart(targetLength, padString) {
+        targetLength = targetLength>>0; //floor if number or convert non-number to 0;
+        padString = String((typeof padString !== "undefined" ? padString : " "));
+        if (this.length > targetLength) {
+            return String(this);
+        } else {
+            targetLength = targetLength-this.length;
+            if (targetLength > padString.length) {
+                padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
+            }
+            return padString.slice(0, targetLength) + String(this);
+        }
+    };
+}
+
+
+// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
+if (!String.prototype.padEnd) {
+    String.prototype.padEnd = function padEnd(targetLength, padString) {
+        targetLength = targetLength>>0; //floor if number or convert non-number to 0;
+        padString = String((typeof padString !== "undefined" ? padString : " "));
+        if (this.length > targetLength) {
+            return String(this);
+        } else {
+            targetLength = targetLength-this.length;
+            if (targetLength > padString.length) {
+                padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
+            }
+            return String(this) + padString.slice(0, targetLength);
+        }
+    };
+}

+ 16 - 3
src/core/config/Categories.js

@@ -79,8 +79,8 @@ const Categories = [
             "DES Decrypt",
             "DES Decrypt",
             "Triple DES Encrypt",
             "Triple DES Encrypt",
             "Triple DES Decrypt",
             "Triple DES Decrypt",
-            "Rabbit Encrypt",
-            "Rabbit Decrypt",
+            "RC2 Encrypt",
+            "RC2 Decrypt",
             "RC4",
             "RC4",
             "RC4 Drop",
             "RC4 Drop",
             "ROT13",
             "ROT13",
@@ -99,6 +99,7 @@ const Categories = [
             "Substitute",
             "Substitute",
             "Derive PBKDF2 key",
             "Derive PBKDF2 key",
             "Derive EVP key",
             "Derive EVP key",
+            "Pseudo-Random Number Generator",
         ]
         ]
     },
     },
     {
     {
@@ -113,7 +114,7 @@ const Categories = [
         ]
         ]
     },
     },
     {
     {
-        name: "Logical operations",
+        name: "Arithmetic / Logic",
         ops: [
         ops: [
             "XOR",
             "XOR",
             "XOR Brute Force",
             "XOR Brute Force",
@@ -122,6 +123,13 @@ const Categories = [
             "AND",
             "AND",
             "ADD",
             "ADD",
             "SUB",
             "SUB",
+            "Sum",
+            "Subtract",
+            "Multiply",
+            "Divide",
+            "Mean",
+            "Median",
+            "Standard Deviation",
             "Bit shift left",
             "Bit shift left",
             "Bit shift right",
             "Bit shift right",
             "Rotate left",
             "Rotate left",
@@ -191,6 +199,7 @@ const Categories = [
             "Parse colour code",
             "Parse colour code",
             "Escape string",
             "Escape string",
             "Unescape string",
             "Unescape string",
+            "Pseudo-Random Number Generator",
         ]
         ]
     },
     },
     {
     {
@@ -288,6 +297,7 @@ const Categories = [
             "XPath expression",
             "XPath expression",
             "JPath expression",
             "JPath expression",
             "CSS selector",
             "CSS selector",
+            "PHP Deserialize",
             "Microsoft Script Decoder",
             "Microsoft Script Decoder",
             "Strip HTML tags",
             "Strip HTML tags",
             "Diff",
             "Diff",
@@ -301,9 +311,11 @@ const Categories = [
         ops: [
         ops: [
             "Entropy",
             "Entropy",
             "Frequency distribution",
             "Frequency distribution",
+            "Chi Square",
             "Detect File Type",
             "Detect File Type",
             "Scan for Embedded Files",
             "Scan for Embedded Files",
             "Disassemble x86",
             "Disassemble x86",
+            "Pseudo-Random Number Generator",
             "Generate UUID",
             "Generate UUID",
             "Generate TOTP",
             "Generate TOTP",
             "Generate HOTP",
             "Generate HOTP",
@@ -319,6 +331,7 @@ const Categories = [
             "Fork",
             "Fork",
             "Merge",
             "Merge",
             "Register",
             "Register",
+            "Label",
             "Jump",
             "Jump",
             "Conditional Jump",
             "Conditional Jump",
             "Return",
             "Return",

+ 3998 - 3930
src/core/config/OperationConfig.js

@@ -1,3930 +1,3998 @@
-import Base from "../operations/Base.js";
-import Base58 from "../operations/Base58.js";
-import Base64 from "../operations/Base64.js";
-import BCD from "../operations/BCD.js";
-import BitwiseOp from "../operations/BitwiseOp.js";
-import ByteRepr from "../operations/ByteRepr.js";
-import CharEnc from "../operations/CharEnc.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 Diff from "../operations/Diff.js";
-import Endian from "../operations/Endian.js";
-import Entropy from "../operations/Entropy.js";
-import Extract from "../operations/Extract.js";
-import Filetime from "../operations/Filetime.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 PGP from "../operations/PGP.js";
-import PublicKey from "../operations/PublicKey.js";
-import Punycode from "../operations/Punycode.js";
-import Rotate from "../operations/Rotate.js";
-import SeqUtils from "../operations/SeqUtils.js";
-import Shellcode from "../operations/Shellcode.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";
-
-
-/**
- * Type definition for an OpConf.
- *
- * @typedef {Object} OpConf
- * @property {string} module - The module to which the operation belongs
- * @property {html} description - A description of the operation with optional HTML tags
- * @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": {
-        module: "Default",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "Split delimiter",
-                type: "binaryShortString",
-                value: "\\n"
-            },
-            {
-                name: "Merge delimiter",
-                type: "binaryShortString",
-                value: "\\n"
-            },
-            {
-                name: "Ignore errors",
-                type: "boolean",
-                value: false
-            }
-        ]
-    },
-    "Merge": {
-        module: "Default",
-        description: "Consolidate all branches back into a single trunk. The opposite of Fork.",
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: []
-    },
-    "Register": {
-        module: "Default",
-        description: "Extract data from the input and store it in registers which can then be passed into subsequent operations as arguments. Regular expression capture groups are used to select the data to extract.<br><br>To use registers in arguments, refer to them using the notation <code>$Rn</code> where n is the register number, starting at 0.<br><br>For example:<br>Input: <code>Test</code><br>Extractor: <code>(.*)</code><br>Argument: <code>$R0</code> becomes <code>Test</code><br><br>Registers can be escaped in arguments using a backslash. e.g. <code>\\$R0</code> would become <code>$R0</code> rather than <code>Test</code>.",
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "Extractor",
-                type: "binaryString",
-                value: "([\\s\\S]*)"
-            },
-            {
-                name: "Case insensitive",
-                type: "boolean",
-                value: true
-            },
-            {
-                name: "Multiline matching",
-                type: "boolean",
-                value: false
-            },
-        ]
-    },
-    "Jump": {
-        module: "Default",
-        description: "Jump forwards or backwards over the specified number of operations.",
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "Number of operations to jump over",
-                type: "number",
-                value: 0
-            },
-            {
-                name: "Maximum jumps (if jumping backwards)",
-                type: "number",
-                value: 10
-            }
-        ]
-    },
-    "Conditional Jump": {
-        module: "Default",
-        description: "Conditionally jump forwards or backwards over the specified number of operations based on whether the data matches the specified regular expression.",
-        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: 0
-            },
-            {
-                name: "Maximum jumps (if jumping backwards)",
-                type: "number",
-                value: 10
-            }
-        ]
-    },
-    "Return": {
-        module: "Default",
-        description: "End execution of operations at this point in the recipe.",
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: []
-    },
-    "Comment": {
-        module: "Default",
-        description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.",
-        inputType: "string",
-        outputType: "string",
-        flowControl: true,
-        args: [
-            {
-                name: "",
-                type: "text",
-                value: ""
-            }
-        ]
-    },
-    "From Base64": {
-        module: "Default",
-        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>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base64.ALPHABET_OPTIONS
-            },
-            {
-                name: "Remove non-alphabet chars",
-                type: "boolean",
-                value: Base64.REMOVE_NON_ALPH_CHARS
-            }
-        ]
-    },
-    "To Base64": {
-        module: "Default",
-        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>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base64.ALPHABET_OPTIONS
-            },
-        ]
-    },
-    "From Base58": {
-        module: "Default",
-        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).",
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base58.ALPHABET_OPTIONS
-            },
-            {
-                name: "Remove non-alphabet chars",
-                type: "boolean",
-                value: Base58.REMOVE_NON_ALPH_CHARS
-            }
-        ]
-    },
-    "To Base58": {
-        module: "Default",
-        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).",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Alphabet",
-                type: "editableOption",
-                value: Base58.ALPHABET_OPTIONS
-            },
-        ]
-    },
-    "From Base32": {
-        module: "Default",
-        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.",
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Alphabet",
-                type: "binaryString",
-                value: Base64.BASE32_ALPHABET
-            },
-            {
-                name: "Remove non-alphabet chars",
-                type: "boolean",
-                value: Base64.REMOVE_NON_ALPH_CHARS
-            }
-        ]
-    },
-    "To Base32": {
-        module: "Default",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Alphabet",
-                type: "binaryString",
-                value: Base64.BASE32_ALPHABET
-            }
-        ]
-    },
-    "Show Base64 offsets": {
-        module: "Default",
-        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.",
-        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
-            }
-        ]
-    },
-    "Disassemble x86": {
-        module: "Shellcode",
-        description: "Disassembly is the process of translating machine language into assembly language.<br><br>This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.<br><br>Input should be in hexadecimal.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Bit mode",
-                type: "option",
-                value: Shellcode.MODE
-            },
-            {
-                name: "Compatibility",
-                type: "option",
-                value: Shellcode.COMPATIBILITY
-            },
-            {
-                name: "Code Segment (CS)",
-                type: "number",
-                value: 16
-            },
-            {
-                name: "Offset (IP)",
-                type: "number",
-                value: 0
-            },
-            {
-                name: "Show instruction hex",
-                type: "boolean",
-                value: true
-            },
-            {
-                name: "Show instruction position",
-                type: "boolean",
-                value: true
-            }
-        ]
-    },
-    "XOR": {
-        module: "Default",
-        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>",
-        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": {
-        module: "Default",
-        description: "Enumerate all possible XOR solutions. Current maximum key length is 2 due to browser performance.<br><br>Optionally enter a string that you expect to find in the plaintext to filter results (crib).",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Key length",
-                type: "number",
-                value: BitwiseOp.XOR_BRUTE_KEY_LENGTH
-            },
-            {
-                name: "Sample length",
-                type: "number",
-                value: BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH
-            },
-            {
-                name: "Sample offset",
-                type: "number",
-                value: BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET
-            },
-            {
-                name: "Scheme",
-                type: "option",
-                value: BitwiseOp.XOR_SCHEME
-            },
-            {
-                name: "Null preserving",
-                type: "boolean",
-                value: BitwiseOp.XOR_PRESERVE_NULLS
-            },
-            {
-                name: "Print key",
-                type: "boolean",
-                value: BitwiseOp.XOR_BRUTE_PRINT_KEY
-            },
-            {
-                name: "Output as hex",
-                type: "boolean",
-                value: BitwiseOp.XOR_BRUTE_OUTPUT_HEX
-            },
-            {
-                name: "Crib (known plaintext string)",
-                type: "binaryString",
-                value: ""
-            }
-        ]
-    },
-    "NOT": {
-        module: "Default",
-        description: "Returns the inverse of each byte.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: []
-    },
-    "AND": {
-        module: "Default",
-        description: "AND the input with the given key.<br>e.g. <code>fe023da5</code>",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "OR": {
-        module: "Default",
-        description: "OR the input with the given key.<br>e.g. <code>fe023da5</code>",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "ADD": {
-        module: "Default",
-        description: "ADD the input with the given key (e.g. <code>fe023da5</code>), MOD 255",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "SUB": {
-        module: "Default",
-        description: "SUB the input with the given key (e.g. <code>fe023da5</code>), MOD 255",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Key",
-                type: "toggleString",
-                value: "",
-                toggleValues: BitwiseOp.KEY_FORMAT
-            }
-        ]
-    },
-    "From Hex": {
-        module: "Default",
-        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>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.HEX_DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Hex": {
-        module: "Default",
-        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>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.HEX_DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Octal": {
-        module: "Default",
-        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>",
-        highlight: false,
-        highlightReverse: false,
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Octal": {
-        module: "Default",
-        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>",
-        highlight: false,
-        highlightReverse: false,
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Charcode": {
-        module: "Default",
-        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>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            },
-            {
-                name: "Base",
-                type: "number",
-                value: ByteRepr.CHARCODE_BASE
-            }
-        ]
-    },
-
-    "To Charcode": {
-        module: "Default",
-        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>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            },
-            {
-                name: "Base",
-                type: "number",
-                value: ByteRepr.CHARCODE_BASE
-            }
-        ]
-    },
-    "From Binary": {
-        module: "Default",
-        description: "Converts a binary string back into its raw form.<br><br>e.g. <code>01001000 01101001</code> becomes <code>Hi</code>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.BIN_DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Binary": {
-        module: "Default",
-        description: "Displays the input data as a binary string.<br><br>e.g. <code>Hi</code> becomes <code>01001000 01101001</code>",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.BIN_DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Decimal": {
-        module: "Default",
-        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>",
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "To Decimal": {
-        module: "Default",
-        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>",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: ByteRepr.DELIM_OPTIONS
-            }
-        ]
-    },
-    "From Hexdump": {
-        module: "Default",
-        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.",
-        highlight: "func",
-        highlightReverse: "func",
-        inputType: "string",
-        outputType: "byteArray",
-        args: []
-    },
-    "To Hexdump": {
-        module: "Default",
-        description: "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.",
-        highlight: "func",
-        highlightReverse: "func",
-        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": {
-        module: "Default",
-        description: "Converts a number to decimal from a given numerical base.",
-        inputType: "string",
-        outputType: "number",
-        args: [
-            {
-                name: "Radix",
-                type: "number",
-                value: Base.DEFAULT_RADIX
-            }
-        ]
-    },
-    "To Base": {
-        module: "Default",
-        description: "Converts a decimal number to a given numerical base.",
-        inputType: "number",
-        outputType: "string",
-        args: [
-            {
-                name: "Radix",
-                type: "number",
-                value: Base.DEFAULT_RADIX
-            }
-        ]
-    },
-    "From HTML Entity": {
-        module: "Default",
-        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 &
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "To HTML Entity": {
-        module: "Default",
-        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 &
-        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": {
-        module: "Default",
-        description: "Removes all HTML tags from the input.",
-        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": {
-        module: "Default",
-        description: "Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "URL Encode": {
-        module: "Default",
-        description: "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.<br><br>e.g. <code>=</code> becomes <code>%3d</code>",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Encode all special chars",
-                type: "boolean",
-                value: URL_.ENCODE_ALL
-            }
-        ]
-    },
-    "Parse URI": {
-        module: "Default",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Unescape Unicode Characters": {
-        module: "Default",
-        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>",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Prefix",
-                type: "option",
-                value: Unicode.PREFIXES
-            }
-        ]
-    },
-    "From Quoted Printable": {
-        module: "Default",
-        description: "Converts QP-encoded text back to standard text.",
-        inputType: "string",
-        outputType: "byteArray",
-        args: []
-    },
-    "To Quoted Printable": {
-        module: "Default",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "From Punycode": {
-        module: "Encodings",
-        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>",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Internationalised domain name",
-                type: "boolean",
-                value: Punycode.IDN
-            }
-        ]
-    },
-    "To Punycode": {
-        module: "Encodings",
-        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>",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Internationalised domain name",
-                type: "boolean",
-                value: Punycode.IDN
-            }
-        ]
-    },
-    "From Hex Content": {
-        module: "Default",
-        description: "Translates hexadecimal bytes in text back to raw bytes.<br><br>e.g. <code>foo|3d|bar</code> becomes <code>foo=bar</code>.",
-        inputType: "string",
-        outputType: "byteArray",
-        args: []
-    },
-    "To Hex Content": {
-        module: "Default",
-        description: "Converts special characters in a string to hexadecimal.<br><br>e.g. <code>foo=bar</code> becomes <code>foo|3d|bar</code>.",
-        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": {
-        module: "JSBN",
-        description: "Convert an IP address from one format to another, e.g. <code>172.20.23.54</code> to <code>ac141736</code>",
-        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": {
-        module: "JSBN",
-        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.",
-        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": {
-        module: "JSBN",
-        description: "Groups a list of IP addresses into subnets. Supports both IPv4 and IPv6 addresses.",
-        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": {
-        module: "JSBN",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse IPv4 header": {
-        module: "JSBN",
-        description: "Given an IPv4 header, this operations parses and displays each field in an easily readable format.",
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Input format",
-                type: "option",
-                value: IP.IP_HEADER_FORMAT
-            }
-        ]
-    },
-    "Encode text": {
-        module: "CharEnc",
-        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"),
-        inputType: "string",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Encoding",
-                type: "option",
-                value: Object.keys(CharEnc.IO_FORMAT),
-            },
-        ]
-    },
-    "Decode text": {
-        module: "CharEnc",
-        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"),
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Encoding",
-                type: "option",
-                value: Object.keys(CharEnc.IO_FORMAT),
-            },
-        ]
-    },
-    "AES Decrypt": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key",
-                type: "string",
-                value: ""
-            }
-        ]
-    },
-    "Vigenère Decode": {
-        module: "Ciphers",
-        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.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key",
-                type: "string",
-                value: ""
-            }
-        ]
-    },
-    "Bifid Cipher Encode": {
-        module: "Ciphers",
-        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.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Keyword",
-                type: "string",
-                value: ""
-            }
-        ]
-    },
-    "Bifid Cipher Decode": {
-        module: "Ciphers",
-        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.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Keyword",
-                type: "string",
-                value: ""
-            }
-        ]
-    },
-    "Affine Cipher Encode": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        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": {
-        module: "Ciphers",
-        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.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Rotate right": {
-        module: "Default",
-        description: "Rotates each byte to the right by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Amount",
-                type: "number",
-                value: Rotate.ROTATE_AMOUNT
-            },
-            {
-                name: "Carry through",
-                type: "boolean",
-                value: Rotate.ROTATE_CARRY
-            }
-        ]
-    },
-    "Rotate left": {
-        module: "Default",
-        description: "Rotates each byte to the left by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Amount",
-                type: "number",
-                value: Rotate.ROTATE_AMOUNT
-            },
-            {
-                name: "Carry through",
-                type: "boolean",
-                value: Rotate.ROTATE_CARRY
-            }
-        ]
-    },
-    "ROT13": {
-        module: "Default",
-        description: "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).",
-        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": {
-        module: "Default",
-        description: "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Amount",
-                type: "number",
-                value: Rotate.ROT47_AMOUNT
-            },
-        ]
-    },
-    "Strip HTTP headers": {
-        module: "HTTP",
-        description: "Removes HTTP headers from a request or response by looking for the first instance of a double newline.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse User Agent": {
-        module: "HTTP",
-        description: "Attempts to identify and categorise information contained in a user-agent string.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Format MAC addresses": {
-        module: "Default",
-        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.",
-        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": {
-        module: "Default",
-        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.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Offset",
-                type: "number",
-                value: NetBIOS.OFFSET
-            }
-        ]
-    },
-    "Decode NetBIOS Name": {
-        module: "Default",
-        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.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Offset",
-                type: "number",
-                value: NetBIOS.OFFSET
-            }
-        ]
-    },
-    "Offset checker": {
-        module: "Default",
-        description: "Compares multiple inputs (separated by the specified delimiter) and highlights matching characters which appear at the same position in all samples.",
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Sample delimiter",
-                type: "binaryString",
-                value: StrUtils.OFF_CHK_SAMPLE_DELIMITER
-            }
-        ]
-    },
-    "Remove whitespace": {
-        module: "Default",
-        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.",
-        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": {
-        module: "Default",
-        description: "Removes all null bytes (<code>0x00</code>) from the input.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: []
-    },
-    "Drop bytes": {
-        module: "Default",
-        description: "Cuts the specified number of bytes out of the data.",
-        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": {
-        module: "Default",
-        description: "Takes a slice of the specified number of bytes from the data.",
-        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": {
-        module: "Default",
-        description: "Add the specified number of the specified character to the beginning or end of each line",
-        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": {
-        module: "Default",
-        description: "Reverses the input string.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "By",
-                type: "option",
-                value: SeqUtils.REVERSE_BY
-            }
-        ]
-    },
-    "Sort": {
-        module: "Default",
-        description: "Alphabetically sorts strings separated by the specified delimiter.<br><br>The IP address option supports IPv4 only.",
-        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": {
-        module: "Default",
-        description: "Removes duplicate strings from the input.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: SeqUtils.DELIMITER_OPTIONS
-            }
-        ]
-    },
-    "Count occurrences": {
-        module: "Default",
-        description: "Counts the number of times the provided string occurs in the input.",
-        inputType: "string",
-        outputType: "number",
-        args: [
-            {
-                name: "Search string",
-                type: "toggleString",
-                value: "",
-                toggleValues: SeqUtils.SEARCH_TYPE
-            }
-        ]
-    },
-    "Add line numbers": {
-        module: "Default",
-        description: "Adds line numbers to the output.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Remove line numbers": {
-        module: "Default",
-        description: "Removes line numbers from the output if they can be trivially detected.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Find / Replace": {
-        module: "Default",
-        description: "Replaces all occurrences of the first string with the second.<br><br> Includes support for regular expressions (regex), simple strings and extended strings (which support \\n, \\r, \\t, \\b, \\f and escaped hex bytes using \\x notation, e.g. \\x00 for a null byte).",
-        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": {
-        module: "Default",
-        description: "Converts the input string to upper case, optionally limiting scope to only the first character in each word, sentence or paragraph.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Scope",
-                type: "option",
-                value: StrUtils.CASE_SCOPE
-            }
-        ]
-    },
-    "To Lower case": {
-        module: "Default",
-        description: "Converts every character in the input to lower case.",
-        highlight: true,
-        highlightReverse: true,
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Split": {
-        module: "Default",
-        description: "Splits a string into sections around a given delimiter.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Split delimiter",
-                type: "binaryShortString",
-                value: StrUtils.SPLIT_DELIM
-            },
-            {
-                name: "Join delimiter",
-                type: "option",
-                value: StrUtils.DELIMITER_OPTIONS
-            }
-        ]
-    },
-    "Filter": {
-        module: "Default",
-        description: "Splits up the input using the specified delimiter and then filters each branch based on a regular expression.",
-        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": {
-        module: "Default",
-        description: "Extracts all strings from the input.",
-        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": {
-        module: "Default",
-        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!",
-        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": {
-        module: "Default",
-        description: "Extracts all email addresses from the input.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract MAC addresses": {
-        module: "Default",
-        description: "Extracts all Media Access Control (MAC) addresses from the input.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract URLs": {
-        module: "Default",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract domains": {
-        module: "Default",
-        description: "Extracts domain names.<br>Note that this will not include paths. Use <strong>Extract URLs</strong> to find entire URLs.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Extract file paths": {
-        module: "Default",
-        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.",
-        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": {
-        module: "Default",
-        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",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Display total",
-                type: "boolean",
-                value: Extract.DISPLAY_TOTAL
-            }
-        ]
-    },
-    "Regular expression": {
-        module: "Default",
-        description: "Define your own regular expression (regex) to search the input data with, optionally choosing from a list of pre-defined patterns.",
-        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": {
-        module: "Code",
-        description: "Extract information from an XML document with an XPath query",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "XPath",
-                type: "string",
-                value: Code.XPATH_INITIAL
-            },
-            {
-                name: "Result delimiter",
-                type: "binaryShortString",
-                value: Code.XPATH_DELIMITER
-            }
-        ]
-    },
-    "JPath expression": {
-        module: "Code",
-        description: "Extract information from a JSON object with a JPath query.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Query",
-                type: "string",
-                value: Code.JPATH_INITIAL
-            },
-            {
-                name: "Result delimiter",
-                type: "binaryShortString",
-                value: Code.JPATH_DELIMITER
-            }
-        ]
-    },
-    "CSS selector": {
-        module: "Code",
-        description: "Extract information from an HTML document with a CSS selector",
-        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": {
-        module: "Default",
-        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><br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).",
-        inputType: "number",
-        outputType: "string",
-        args: [
-            {
-                name: "Units",
-                type: "option",
-                value: DateTime.UNITS
-            }
-        ]
-    },
-    "To UNIX Timestamp": {
-        module: "Default",
-        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><br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).",
-        inputType: "string",
-        outputType: "number",
-        args: [
-            {
-                name: "Units",
-                type: "option",
-                value: DateTime.UNITS
-            },
-            {
-                name: "Treat as UTC",
-                type: "boolean",
-                value: DateTime.TREAT_AS_UTC
-            }
-        ]
-    },
-    "Windows Filetime to UNIX Timestamp": {
-        module: "JSBN",
-        description: "Converts a Windows Filetime value to a UNIX timestamp.<br><br>A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.<br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).<br><br>This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Output units",
-                type: "option",
-                value: Filetime.UNITS
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: Filetime.FILETIME_FORMATS
-            }
-        ]
-    },
-    "UNIX Timestamp to Windows Filetime": {
-        module: "JSBN",
-        description: "Converts a UNIX timestamp to a Windows Filetime value.<br><br>A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.<br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).<br><br>This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Input units",
-                type: "option",
-                value: Filetime.UNITS
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: Filetime.FILETIME_FORMATS
-            }
-        ]
-    },
-    "Translate DateTime Format": {
-        module: "Default",
-        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.",
-        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": {
-        module: "Default",
-        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.",
-        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": {
-        module: "Default",
-        description: "Converts a unit of distance to another format.",
-        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": {
-        module: "Default",
-        description: "Converts a unit of area to another format.",
-        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": {
-        module: "Default",
-        description: "Converts a unit of mass to another format.",
-        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": {
-        module: "Default",
-        description: "Converts a unit of speed to another format.",
-        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": {
-        module: "Default",
-        description: "Converts a unit of data to another format.",
-        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": {
-        module: "Compression",
-        description: "Compresses data using the deflate algorithm with no headers.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Compression type",
-                type: "option",
-                value: Compress.COMPRESSION_TYPE
-            }
-        ]
-    },
-    "Raw Inflate": {
-        module: "Compression",
-        description: "Decompresses data which has been compressed using the deflate algorithm with no headers.",
-        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": {
-        module: "Compression",
-        description: "Compresses data using the deflate algorithm adding zlib headers.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Compression type",
-                type: "option",
-                value: Compress.COMPRESSION_TYPE
-            }
-        ]
-    },
-    "Zlib Inflate": {
-        module: "Compression",
-        description: "Decompresses data which has been compressed using the deflate algorithm with zlib headers.",
-        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": {
-        module: "Compression",
-        description: "Compresses data using the deflate algorithm with gzip headers.",
-        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": {
-        module: "Compression",
-        description: "Decompresses data which has been compressed using the deflate algorithm with gzip headers.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: []
-    },
-    "Zip": {
-        module: "Compression",
-        description: "Compresses data using the PKZIP algorithm with the given filename.<br><br>No support for multiple files at this time.",
-        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": {
-        module: "Compression",
-        description: "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.",
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-            {
-                name: "Password",
-                type: "binaryString",
-                value: ""
-            },
-            {
-                name: "Verify result",
-                type: "boolean",
-                value: Compress.PKUNZIP_VERIFY
-            }
-        ]
-    },
-    "Bzip2 Decompress": {
-        module: "Compression",
-        description: "Decompresses data using the Bzip2 algorithm.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Generic Code Beautify": {
-        module: "Code",
-        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>",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "JavaScript Parser": {
-        module: "Code",
-        description: "Returns an Abstract Syntax Tree for valid JavaScript code.",
-        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": {
-        module: "Code",
-        description: "Parses and pretty prints valid JavaScript code. Also works with JavaScript Object Notation (JSON).",
-        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": {
-        module: "Code",
-        description: "Compresses JavaScript code.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "XML Beautify": {
-        module: "Code",
-        description: "Indents and prettifies eXtensible Markup Language (XML) code.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "JSON Beautify": {
-        module: "Code",
-        description: "Indents and prettifies JavaScript Object Notation (JSON) code.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "CSS Beautify": {
-        module: "Code",
-        description: "Indents and prettifies Cascading Style Sheets (CSS) code.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "SQL Beautify": {
-        module: "Code",
-        description: "Indents and prettifies Structured Query Language (SQL) code.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Indent string",
-                type: "binaryShortString",
-                value: Code.BEAUTIFY_INDENT
-            }
-        ]
-    },
-    "XML Minify": {
-        module: "Code",
-        description: "Compresses eXtensible Markup Language (XML) code.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Preserve comments",
-                type: "boolean",
-                value: Code.PRESERVE_COMMENTS
-            }
-        ]
-    },
-    "JSON Minify": {
-        module: "Code",
-        description: "Compresses JavaScript Object Notation (JSON) code.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "CSS Minify": {
-        module: "Code",
-        description: "Compresses Cascading Style Sheets (CSS) code.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Preserve comments",
-                type: "boolean",
-                value: Code.PRESERVE_COMMENTS
-            }
-        ]
-    },
-    "SQL Minify": {
-        module: "Code",
-        description: "Compresses Structured Query Language (SQL) code.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Analyse hash": {
-        module: "Hashing",
-        description: "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "MD2": {
-        module: "Hashing",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "MD4": {
-        module: "Hashing",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "MD5": {
-        module: "Hashing",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "MD6": {
-        module: "Hashing",
-        description: "The MD6 (Message-Digest 6) algorithm is a cryptographic hash function. It uses a Merkle tree-like structure to allow for immense parallel computation of hashes for very long inputs.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Size",
-                type: "number",
-                value: Hash.MD6_SIZE
-            },
-            {
-                name: "Levels",
-                type: "number",
-                value: Hash.MD6_LEVELS
-            },
-            {
-                name: "Key",
-                type: "string",
-                value: ""
-            }
-        ]
-    },
-    "SHA0": {
-        module: "Hashing",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA1": {
-        module: "Hashing",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "SHA2": {
-        module: "Hashing",
-        description: "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.<br><br><ul><li>SHA-512 operates on 64-bit words.</li><li>SHA-256 operates on 32-bit words.</li><li>SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.</li><li>SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.</li><li>SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.</li></ul>",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Size",
-                type: "option",
-                value: Hash.SHA2_SIZE
-            }
-        ]
-    },
-    "SHA3": {
-        module: "Hashing",
-        description: "The SHA-3 (Secure Hash Algorithm 3) hash functions were released by NIST on August 5, 2015. Although part of the same series of standards, SHA-3 is internally quite different from the MD5-like structure of SHA-1 and SHA-2.<br><br>SHA-3 is a subset of the broader cryptographic primitive family Keccak designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Size",
-                type: "option",
-                value: Hash.SHA3_SIZE
-            }
-        ]
-    },
-    "Keccak": {
-        module: "Hashing",
-        description: "The Keccak hash algorithm was designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún. It was selected as the winner of the SHA-3 design competition.<br><br>This version of the algorithm is Keccak[c=2d] and differs from the SHA-3 specification.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Size",
-                type: "option",
-                value: Hash.KECCAK_SIZE
-            }
-        ]
-    },
-    "Shake": {
-        module: "Hashing",
-        description: "Shake is an Extendable Output Function (XOF) of the SHA-3 hash algorithm, part of the Keccak family, allowing for variable output length/size.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Capacity",
-                type: "option",
-                value: Hash.SHAKE_CAPACITY
-            },
-            {
-                name: "Size",
-                type: "number",
-                value: Hash.SHAKE_SIZE
-            }
-        ]
-
-    },
-    "RIPEMD": {
-        module: "Hashing",
-        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>",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Size",
-                type: "option",
-                value: Hash.RIPEMD_SIZE
-            }
-        ]
-    },
-    "HAS-160": {
-        module: "Hashing",
-        description: "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.<br><br>HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.<br><br>The message digest algorithm consists of 80 rounds.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Whirlpool": {
-        module: "Hashing",
-        description: "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Variant",
-                type: "option",
-                value: Hash.WHIRLPOOL_VARIANT
-            }
-        ]
-    },
-    "Snefru": {
-        module: "Hashing",
-        description: "Snefru is a cryptographic hash function invented by Ralph Merkle in 1990 while working at Xerox PARC. The function supports 128-bit and 256-bit output. It was named after the Egyptian Pharaoh Sneferu, continuing the tradition of the Khufu and Khafre block ciphers.<br><br>The original design of Snefru was shown to be insecure by Eli Biham and Adi Shamir who were able to use differential cryptanalysis to find hash collisions. The design was then modified by increasing the number of iterations of the main pass of the algorithm from two to eight.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Rounds",
-                type: "option",
-                value: Hash.SNEFRU_ROUNDS
-            },
-            {
-                name: "Size",
-                type: "option",
-                value: Hash.SNEFRU_SIZE
-            }
-        ]
-    },
-    "HMAC": {
-        module: "Hashing",
-        description: "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Password",
-                type: "binaryString",
-                value: ""
-            },
-            {
-                name: "Hashing function",
-                type: "option",
-                value: Hash.HMAC_FUNCTIONS
-            },
-        ]
-    },
-    "Fletcher-8 Checksum": {
-        module: "Hashing",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Fletcher-16 Checksum": {
-        module: "Hashing",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Fletcher-32 Checksum": {
-        module: "Hashing",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Fletcher-64 Checksum": {
-        module: "Hashing",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Adler-32 Checksum": {
-        module: "Hashing",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "CRC-32 Checksum": {
-        module: "Hashing",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "CRC-16 Checksum": {
-        module: "Hashing",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Generate all hashes": {
-        module: "Hashing",
-        description: "Generates all available hashes and checksums for the input.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Entropy": {
-        module: "Default",
-        description: "Calculates the Shannon entropy of the input data which gives an idea of its randomness. 8 is the maximum.",
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-            {
-                name: "Chunk size",
-                type: "number",
-                value: Entropy.CHUNK_SIZE
-            }
-        ]
-    },
-    "Frequency distribution": {
-        module: "Default",
-        description: "Displays the distribution of bytes in the data as a graph.",
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-            {
-                name: "Show 0%'s",
-                type: "boolean",
-                value: Entropy.FREQ_ZEROS
-            }
-        ]
-    },
-    "Numberwang": {
-        module: "Default",
-        description: "Based on the popular gameshow by Mitchell and Webb.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse X.509 certificate": {
-        module: "PublicKey",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Input format",
-                type: "option",
-                value: PublicKey.X509_INPUT_FORMAT
-            }
-        ]
-    },
-    "PEM to Hex": {
-        module: "PublicKey",
-        description: "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Hex to PEM": {
-        module: "PublicKey",
-        description: "Converts a hexadecimal DER (Distinguished Encoding Rules) string into PEM (Privacy Enhanced Mail) format.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Header string",
-                type: "string",
-                value: PublicKey.PEM_HEADER_STRING
-            }
-        ]
-    },
-    "Hex to Object Identifier": {
-        module: "PublicKey",
-        description: "Converts a hexadecimal string into an object identifier (OID).",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Object Identifier to Hex": {
-        module: "PublicKey",
-        description: "Converts an object identifier (OID) into a hexadecimal string.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Parse ASN.1 hex string": {
-        module: "PublicKey",
-        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.",
-        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": {
-        module: "Default",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Scan for Embedded Files": {
-        module: "Default",
-        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.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Ignore common byte sequences",
-                type: "boolean",
-                value: FileType.IGNORE_COMMON_BYTE_SEQUENCES
-            }
-        ]
-    },
-    "Expand alphabet range": {
-        module: "Default",
-        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>.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "binaryString",
-                value: ""
-            }
-        ]
-    },
-    "Diff": {
-        module: "Diff",
-        description: "Compares two inputs (separated by the specified delimiter) and highlights the differences between them.",
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Sample delimiter",
-                type: "binaryString",
-                value: Diff.DIFF_SAMPLE_DELIMITER
-            },
-            {
-                name: "Diff by",
-                type: "option",
-                value: Diff.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": {
-        module: "Default",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Swap endianness": {
-        module: "Default",
-        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.",
-        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
-            }
-        ]
-    },
-    "Microsoft Script Decoder": {
-        module: "Default",
-        description: "Decodes Microsoft Encoded Script files that have been encoded with Microsoft's custom encoding. These are often VBS (Visual Basic Script) files that are encoded and renamed with a '.vbe' extention or JS (JScript) files renamed with a '.jse' extention.<br><br><b>Sample</b><br><br>Encoded:<br><code>#@~^RQAAAA==-mD~sX|:/TP{~J:+dYbxL~@!F@*@!+@*@!&amp;@*eEI@#@&amp;@#@&amp;.jm.raY 214Wv:zms/obI0xEAAA==^#~@</code><br><br>Decoded:<br><code>var my_msg = &#34;Testing <1><2><3>!&#34;;\n\nVScript.Echo(my_msg);</code>",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Syntax highlighter": {
-        module: "Code",
-        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.",
-        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
-            }
-        ]
-    },
-    "TCP/IP Checksum": {
-        module: "Hashing",
-        description: "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: []
-    },
-    "Parse colour code": {
-        module: "Default",
-        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>",
-        inputType: "string",
-        outputType: "html",
-        args: []
-    },
-    "Generate UUID": {
-        module: "Default",
-        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.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Substitute": {
-        module: "Ciphers",
-        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>.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Plaintext",
-                type: "binaryString",
-                value: Cipher.SUBS_PLAINTEXT
-            },
-            {
-                name: "Ciphertext",
-                type: "binaryString",
-                value: Cipher.SUBS_CIPHERTEXT
-            }
-        ]
-    },
-    "Escape string": {
-        module: "Default",
-        description: "Escapes special characters in a string so that they do not cause conflicts. For example, <code>Don't stop me now</code> becomes <code>Don\\'t stop me now</code>.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "Unescape string": {
-        module: "Default",
-        description: "Unescapes characters in a string that have been escaped. For example, <code>Don\\'t stop me now</code> becomes <code>Don't stop me now</code>.",
-        inputType: "string",
-        outputType: "string",
-        args: []
-    },
-    "To Morse Code": {
-        module: "Default",
-        description: "Translates alphanumeric characters into International Morse Code.<br><br>Ignores non-Morse characters.<br><br>e.g. <code>SOS</code> becomes <code>... --- ...</code>",
-        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": {
-        module: "Default",
-        description: "Translates Morse Code into (upper case) alphanumeric characters.",
-        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": {
-        module: "Compression",
-        description: "Packs the input into a tarball.<br><br>No support for multiple files at this time.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: [
-            {
-                name: "Filename",
-                type: "string",
-                value: Compress.TAR_FILENAME
-            }
-        ]
-    },
-    "Untar": {
-        module: "Compression",
-        description: "Unpacks a tarball and displays it per file.",
-        inputType: "byteArray",
-        outputType: "html",
-        args: [
-        ]
-    },
-    "Head": {
-        module: "Default",
-        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"),
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: StrUtils.DELIMITER_OPTIONS
-            },
-            {
-                name: "Number",
-                type: "number",
-                value: 10,
-            },
-        ]
-    },
-    "Tail": {
-        module: "Default",
-        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"),
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Delimiter",
-                type: "option",
-                value: StrUtils.DELIMITER_OPTIONS
-            },
-            {
-                name: "Number",
-                type: "number",
-                value: 10,
-            },
-        ]
-    },
-    "To Snake case": {
-        module: "Code",
-        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"),
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Attempt to be context aware",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "To Camel case": {
-        module: "Code",
-        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"),
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Attempt to be context aware",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "To Kebab case": {
-        module: "Code",
-        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"),
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Attempt to be context aware",
-                type: "boolean",
-                value: false,
-            },
-        ]
-    },
-    "Extract EXIF": {
-        module: "Image",
-        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"),
-        inputType: "byteArray",
-        outputType: "string",
-        args: [],
-    },
-    "Render Image": {
-        module: "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>",
-        inputType: "string",
-        outputType: "html",
-        args: [
-            {
-                name: "Input format",
-                type: "option",
-                value: Image.INPUT_FORMAT
-            }
-        ]
-    },
-    "Remove EXIF": {
-        module: "Image",
-        description: [
-            "Removes EXIF data from a JPEG image.",
-            "<br><br>",
-            "EXIF data embedded in photos usually contains information about the image file itself as well as the device used to create it.",
-        ].join("\n"),
-        inputType: "byteArray",
-        outputType: "byteArray",
-        args: []
-    },
-    "HTTP request": {
-        module: "HTTP",
-        description: [
-            "Makes an HTTP request and returns the response.",
-            "<br><br>",
-            "This operation supports different HTTP verbs like GET, POST, PUT, etc.",
-            "<br><br>",
-            "You can add headers line by line in the format <code>Key: Value</code>",
-            "<br><br>",
-            "The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.",
-        ].join("\n"),
-        inputType: "string",
-        outputType: "string",
-        manualBake: true,
-        args: [
-            {
-                name: "Method",
-                type: "option",
-                value: HTTP.METHODS,
-            },
-            {
-                name: "URL",
-                type: "string",
-                value: "",
-            },
-            {
-                name: "Headers",
-                type: "text",
-                value: "",
-            },
-            {
-                name: "Mode",
-                type: "option",
-                value: HTTP.MODE,
-            },
-            {
-                name: "Show response metadata",
-                type: "boolean",
-                value: false,
-            }
-        ]
-    },
-    "From BCD": {
-        module: "Default",
-        description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.",
-        inputType: "string",
-        outputType: "number",
-        args: [
-            {
-                name: "Scheme",
-                type: "option",
-                value: BCD.ENCODING_SCHEME
-            },
-            {
-                name: "Packed",
-                type: "boolean",
-                value: true
-            },
-            {
-                name: "Signed",
-                type: "boolean",
-                value: false
-            },
-            {
-                name: "Input format",
-                type: "option",
-                value: BCD.FORMAT
-            }
-        ]
-
-    },
-    "To BCD": {
-        module: "Default",
-        description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign",
-        inputType: "number",
-        outputType: "string",
-        args: [
-            {
-                name: "Scheme",
-                type: "option",
-                value: BCD.ENCODING_SCHEME
-            },
-            {
-                name: "Packed",
-                type: "boolean",
-                value: true
-            },
-            {
-                name: "Signed",
-                type: "boolean",
-                value: false
-            },
-            {
-                name: "Output format",
-                type: "option",
-                value: BCD.FORMAT
-            }
-        ]
-
-    },
-    "Bit shift left": {
-        module: "Default",
-        description: "Shifts the bits in each byte towards the left by the specified amount.",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        highlight: true,
-        highlightReverse: true,
-        args: [
-            {
-                name: "Amount",
-                type: "number",
-                value: 1
-            },
-        ]
-    },
-    "Bit shift right": {
-        module: "Default",
-        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).",
-        inputType: "byteArray",
-        outputType: "byteArray",
-        highlight: true,
-        highlightReverse: true,
-        args: [
-            {
-                name: "Amount",
-                type: "number",
-                value: 1
-            },
-            {
-                name: "Type",
-                type: "option",
-                value: BitwiseOp.BIT_SHIFT_TYPE
-            }
-        ]
-    },
-    "Generate TOTP": {
-        module: "Default",
-        description: "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.<br><br>Enter the secret as the input or leave it blank for a random secret to be generated. T0 and T1 are in seconds.",
-        inputType: "byteArray",
-        outputType: "string",
-        args: [
-            {
-                name: "Name",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Key size",
-                type: "number",
-                value: 32
-            },
-            {
-                name: "Code length",
-                type: "number",
-                value: 6
-            },
-            {
-                name: "Epoch offset (T0)",
-                type: "number",
-                value: 0
-            },
-            {
-                name: "Interval (T1)",
-                type: "number",
-                value: 30
-            }
-        ]
-    },
-    "Generate HOTP": {
-        module: "Default",
-        description: "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems.<br><br>Enter the secret as the input or leave it blank for a random secret to be generated.",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Name",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Key size",
-                type: "number",
-                value: 32
-            },
-            {
-                name: "Code length",
-                type: "number",
-                value: 6
-            },
-            {
-                name: "Counter",
-                type: "number",
-                value: 0
-            }
-        ]
-    },
-    "Generate PGP Key Pair": {
-        module: "PGP",
-        manualBake: true,
-        description: "",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Key type",
-                type: "option",
-                value: PGP.KEY_TYPES
-            },
-            {
-                name: "Key size",
-                type: "option",
-                value: PGP.KEY_SIZES
-            },
-            {
-                name: "Password (optional)",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Name (optional)",
-                type: "string",
-                value: ""
-            },
-            {
-                name: "Email (optional)",
-                type: "string",
-                value: ""
-            },
-        ]
-    },
-    "PGP Encrypt": {
-        module: "PGP",
-        manualBake: true,
-        description: "",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Public key",
-                type: "text",
-                value: ""
-            },
-        ]
-    },
-    "PGP Decrypt": {
-        module: "PGP",
-        manualBake: true,
-        description: "",
-        inputType: "string",
-        outputType: "string",
-        args: [
-            {
-                name: "Private key",
-                type: "text",
-                value: ""
-            },
-        ]
-    },
-};
-
-
-/**
- * Exports the OperationConfig JSON object in val-loader format so that it can be loaded
- * into the app without also importing all the dependencies.
- *
- * See https://github.com/webpack-contrib/val-loader
- *
- * @returns {Object}
- */
-function valExport() {
-    return {
-        code: "module.exports = " + JSON.stringify(OperationConfig) + ";"
-    };
-}
-
-export default valExport;
-
-export { OperationConfig };
+import Arithmetic from "../operations/Arithmetic.js";
+import Base from "../operations/Base.js";
+import Base58 from "../operations/Base58.js";
+import Base64 from "../operations/Base64.js";
+import BCD from "../operations/BCD.js";
+import BitwiseOp from "../operations/BitwiseOp.js";
+import ByteRepr from "../operations/ByteRepr.js";
+import CharEnc from "../operations/CharEnc.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 Diff from "../operations/Diff.js";
+import Endian from "../operations/Endian.js";
+import Entropy from "../operations/Entropy.js";
+import Extract from "../operations/Extract.js";
+import Filetime from "../operations/Filetime.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 PHP from "../operations/PHP.js";
+import PGP from "../operations/PGP.js";
+import PublicKey from "../operations/PublicKey.js";
+import Punycode from "../operations/Punycode.js";
+import Rotate from "../operations/Rotate.js";
+import SeqUtils from "../operations/SeqUtils.js";
+import Shellcode from "../operations/Shellcode.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";
+
+
+/**
+ * Type definition for an OpConf.
+ *
+ * @typedef {Object} OpConf
+ * @property {string} module - The module to which the operation belongs
+ * @property {html} description - A description of the operation with optional HTML tags
+ * @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": {
+        module: "Default",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: [
+            {
+                name: "Split delimiter",
+                type: "binaryShortString",
+                value: "\\n"
+            },
+            {
+                name: "Merge delimiter",
+                type: "binaryShortString",
+                value: "\\n"
+            },
+            {
+                name: "Ignore errors",
+                type: "boolean",
+                value: false
+            }
+        ]
+    },
+    "Merge": {
+        module: "Default",
+        description: "Consolidate all branches back into a single trunk. The opposite of Fork.",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: []
+    },
+    "Register": {
+        module: "Default",
+        description: "Extract data from the input and store it in registers which can then be passed into subsequent operations as arguments. Regular expression capture groups are used to select the data to extract.<br><br>To use registers in arguments, refer to them using the notation <code>$Rn</code> where n is the register number, starting at 0.<br><br>For example:<br>Input: <code>Test</code><br>Extractor: <code>(.*)</code><br>Argument: <code>$R0</code> becomes <code>Test</code><br><br>Registers can be escaped in arguments using a backslash. e.g. <code>\\$R0</code> would become <code>$R0</code> rather than <code>Test</code>.",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: [
+            {
+                name: "Extractor",
+                type: "binaryString",
+                value: "([\\s\\S]*)"
+            },
+            {
+                name: "Case insensitive",
+                type: "boolean",
+                value: true
+            },
+            {
+                name: "Multiline matching",
+                type: "boolean",
+                value: false
+            },
+        ]
+    },
+    "Jump": {
+        module: "Default",
+        description: "Jump forwards or backwards to the specified Label",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: [
+            {
+                name: "Label name",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Maximum jumps (if jumping backwards)",
+                type: "number",
+                value: 10
+            }
+        ]
+    },
+    "Conditional Jump": {
+        module: "Default",
+        description: "Conditionally jump forwards or backwards to the specified Label  based on whether the data matches the specified regular expression.",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: [
+            {
+                name: "Match (regex)",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Invert match",
+                type: "boolean",
+                value: false
+            },
+            {
+                name: "Label name",
+                type: "shortString",
+                value: ""
+            },
+            {
+                name: "Maximum jumps (if jumping backwards)",
+                type: "number",
+                value: 10
+            }
+        ]
+    },
+    "Label": {
+        module: "Default",
+        description: "Provides a location for conditional and fixed jumps to redirect execution to.",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: [
+            {
+                name: "Name",
+                type: "shortString",
+                value: ""
+            }
+        ]
+    },
+    "Return": {
+        module: "Default",
+        description: "End execution of operations at this point in the recipe.",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: []
+    },
+    "Comment": {
+        module: "Default",
+        description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.",
+        inputType: "string",
+        outputType: "string",
+        flowControl: true,
+        args: [
+            {
+                name: "",
+                type: "text",
+                value: ""
+            }
+        ]
+    },
+    "From Base64": {
+        module: "Default",
+        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>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Alphabet",
+                type: "editableOption",
+                value: Base64.ALPHABET_OPTIONS
+            },
+            {
+                name: "Remove non-alphabet chars",
+                type: "boolean",
+                value: Base64.REMOVE_NON_ALPH_CHARS
+            }
+        ]
+    },
+    "To Base64": {
+        module: "Default",
+        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>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "ArrayBuffer",
+        outputType: "string",
+        args: [
+            {
+                name: "Alphabet",
+                type: "editableOption",
+                value: Base64.ALPHABET_OPTIONS
+            },
+        ]
+    },
+    "From Base58": {
+        module: "Default",
+        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).",
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Alphabet",
+                type: "editableOption",
+                value: Base58.ALPHABET_OPTIONS
+            },
+            {
+                name: "Remove non-alphabet chars",
+                type: "boolean",
+                value: Base58.REMOVE_NON_ALPH_CHARS
+            }
+        ]
+    },
+    "To Base58": {
+        module: "Default",
+        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).",
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Alphabet",
+                type: "editableOption",
+                value: Base58.ALPHABET_OPTIONS
+            },
+        ]
+    },
+    "From Base32": {
+        module: "Default",
+        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.",
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Alphabet",
+                type: "binaryString",
+                value: Base64.BASE32_ALPHABET
+            },
+            {
+                name: "Remove non-alphabet chars",
+                type: "boolean",
+                value: Base64.REMOVE_NON_ALPH_CHARS
+            }
+        ]
+    },
+    "To Base32": {
+        module: "Default",
+        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.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Alphabet",
+                type: "binaryString",
+                value: Base64.BASE32_ALPHABET
+            }
+        ]
+    },
+    "Show Base64 offsets": {
+        module: "Default",
+        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.",
+        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
+            }
+        ]
+    },
+    "Disassemble x86": {
+        module: "Shellcode",
+        description: "Disassembly is the process of translating machine language into assembly language.<br><br>This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.<br><br>Input should be in hexadecimal.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Bit mode",
+                type: "option",
+                value: Shellcode.MODE
+            },
+            {
+                name: "Compatibility",
+                type: "option",
+                value: Shellcode.COMPATIBILITY
+            },
+            {
+                name: "Code Segment (CS)",
+                type: "number",
+                value: 16
+            },
+            {
+                name: "Offset (IP)",
+                type: "number",
+                value: 0
+            },
+            {
+                name: "Show instruction hex",
+                type: "boolean",
+                value: true
+            },
+            {
+                name: "Show instruction position",
+                type: "boolean",
+                value: true
+            }
+        ]
+    },
+    "XOR": {
+        module: "Default",
+        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>",
+        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": {
+        module: "Default",
+        description: "Enumerate all possible XOR solutions. Current maximum key length is 2 due to browser performance.<br><br>Optionally enter a string that you expect to find in the plaintext to filter results (crib).",
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Key length",
+                type: "number",
+                value: BitwiseOp.XOR_BRUTE_KEY_LENGTH
+            },
+            {
+                name: "Sample length",
+                type: "number",
+                value: BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH
+            },
+            {
+                name: "Sample offset",
+                type: "number",
+                value: BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET
+            },
+            {
+                name: "Scheme",
+                type: "option",
+                value: BitwiseOp.XOR_SCHEME
+            },
+            {
+                name: "Null preserving",
+                type: "boolean",
+                value: BitwiseOp.XOR_PRESERVE_NULLS
+            },
+            {
+                name: "Print key",
+                type: "boolean",
+                value: BitwiseOp.XOR_BRUTE_PRINT_KEY
+            },
+            {
+                name: "Output as hex",
+                type: "boolean",
+                value: BitwiseOp.XOR_BRUTE_OUTPUT_HEX
+            },
+            {
+                name: "Crib (known plaintext string)",
+                type: "binaryString",
+                value: ""
+            }
+        ]
+    },
+    "NOT": {
+        module: "Default",
+        description: "Returns the inverse of each byte.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: []
+    },
+    "AND": {
+        module: "Default",
+        description: "AND the input with the given key.<br>e.g. <code>fe023da5</code>",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: BitwiseOp.KEY_FORMAT
+            }
+        ]
+    },
+    "OR": {
+        module: "Default",
+        description: "OR the input with the given key.<br>e.g. <code>fe023da5</code>",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: BitwiseOp.KEY_FORMAT
+            }
+        ]
+    },
+    "ADD": {
+        module: "Default",
+        description: "ADD the input with the given key (e.g. <code>fe023da5</code>), MOD 255",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: BitwiseOp.KEY_FORMAT
+            }
+        ]
+    },
+    "SUB": {
+        module: "Default",
+        description: "SUB the input with the given key (e.g. <code>fe023da5</code>), MOD 255",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: BitwiseOp.KEY_FORMAT
+            }
+        ]
+    },
+    "Sum": {
+        module: "Default",
+        description: "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>18.5</code>",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: Arithmetic.DELIM_OPTIONS
+            }
+        ]
+    },
+    "Subtract": {
+        module: "Default",
+        description: "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>1.5</code>",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: Arithmetic.DELIM_OPTIONS
+            }
+        ]
+    },
+    "Multiply": {
+        module: "Default",
+        description: "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>40</code>",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: Arithmetic.DELIM_OPTIONS
+            }
+        ]
+    },
+    "Divide": {
+        module: "Default",
+        description: "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>2.5</code>",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: Arithmetic.DELIM_OPTIONS
+            }
+        ]
+    },
+    "Mean": {
+        module: "Default",
+        description: "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5 .5</code> becomes <code>4.75</code>",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: Arithmetic.DELIM_OPTIONS
+            }
+        ]
+    },
+    "Median": {
+        module: "Default",
+        description: "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 1 .5</code> becomes <code>4.5</code>",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: Arithmetic.DELIM_OPTIONS
+            }
+        ]
+    },
+    "Standard Deviation": {
+        module: "Default",
+        description: "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.<br><br>e.g. <code>0x0a 8 .5</code> becomes <code>4.089281382128433</code>",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: Arithmetic.DELIM_OPTIONS
+            }
+        ]
+    },
+    "From Hex": {
+        module: "Default",
+        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>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.HEX_DELIM_OPTIONS
+            }
+        ]
+    },
+    "To Hex": {
+        module: "Default",
+        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>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "ArrayBuffer",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.HEX_DELIM_OPTIONS
+            }
+        ]
+    },
+    "From Octal": {
+        module: "Default",
+        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>",
+        highlight: false,
+        highlightReverse: false,
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.DELIM_OPTIONS
+            }
+        ]
+    },
+    "To Octal": {
+        module: "Default",
+        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>",
+        highlight: false,
+        highlightReverse: false,
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.DELIM_OPTIONS
+            }
+        ]
+    },
+    "From Charcode": {
+        module: "Default",
+        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>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.DELIM_OPTIONS
+            },
+            {
+                name: "Base",
+                type: "number",
+                value: ByteRepr.CHARCODE_BASE
+            }
+        ]
+    },
+
+    "To Charcode": {
+        module: "Default",
+        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>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.DELIM_OPTIONS
+            },
+            {
+                name: "Base",
+                type: "number",
+                value: ByteRepr.CHARCODE_BASE
+            }
+        ]
+    },
+    "From Binary": {
+        module: "Default",
+        description: "Converts a binary string back into its raw form.<br><br>e.g. <code>01001000 01101001</code> becomes <code>Hi</code>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.BIN_DELIM_OPTIONS
+            }
+        ]
+    },
+    "To Binary": {
+        module: "Default",
+        description: "Displays the input data as a binary string.<br><br>e.g. <code>Hi</code> becomes <code>01001000 01101001</code>",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.BIN_DELIM_OPTIONS
+            }
+        ]
+    },
+    "From Decimal": {
+        module: "Default",
+        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>",
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.DELIM_OPTIONS
+            }
+        ]
+    },
+    "To Decimal": {
+        module: "Default",
+        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>",
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: ByteRepr.DELIM_OPTIONS
+            }
+        ]
+    },
+    "From Hexdump": {
+        module: "Default",
+        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.",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "string",
+        outputType: "byteArray",
+        args: []
+    },
+    "To Hexdump": {
+        module: "Default",
+        description: "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.",
+        highlight: "func",
+        highlightReverse: "func",
+        inputType: "ArrayBuffer",
+        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": {
+        module: "Default",
+        description: "Converts a number to decimal from a given numerical base.",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Radix",
+                type: "number",
+                value: Base.DEFAULT_RADIX
+            }
+        ]
+    },
+    "To Base": {
+        module: "Default",
+        description: "Converts a decimal number to a given numerical base.",
+        inputType: "BigNumber",
+        outputType: "string",
+        args: [
+            {
+                name: "Radix",
+                type: "number",
+                value: Base.DEFAULT_RADIX
+            }
+        ]
+    },
+    "From HTML Entity": {
+        module: "Default",
+        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 &
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "To HTML Entity": {
+        module: "Default",
+        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 &
+        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": {
+        module: "Default",
+        description: "Removes all HTML tags from the input.",
+        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": {
+        module: "URL",
+        description: "Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "URL Encode": {
+        module: "URL",
+        description: "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.<br><br>e.g. <code>=</code> becomes <code>%3d</code>",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Encode all special chars",
+                type: "boolean",
+                value: URL_.ENCODE_ALL
+            }
+        ]
+    },
+    "Parse URI": {
+        module: "URL",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Unescape Unicode Characters": {
+        module: "Default",
+        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>",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Prefix",
+                type: "option",
+                value: Unicode.PREFIXES
+            }
+        ]
+    },
+    "From Quoted Printable": {
+        module: "Default",
+        description: "Converts QP-encoded text back to standard text.",
+        inputType: "string",
+        outputType: "byteArray",
+        args: []
+    },
+    "To Quoted Printable": {
+        module: "Default",
+        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.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "From Punycode": {
+        module: "Encodings",
+        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>",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Internationalised domain name",
+                type: "boolean",
+                value: Punycode.IDN
+            }
+        ]
+    },
+    "To Punycode": {
+        module: "Encodings",
+        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>",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Internationalised domain name",
+                type: "boolean",
+                value: Punycode.IDN
+            }
+        ]
+    },
+    "From Hex Content": {
+        module: "Default",
+        description: "Translates hexadecimal bytes in text back to raw bytes.<br><br>e.g. <code>foo|3d|bar</code> becomes <code>foo=bar</code>.",
+        inputType: "string",
+        outputType: "byteArray",
+        args: []
+    },
+    "To Hex Content": {
+        module: "Default",
+        description: "Converts special characters in a string to hexadecimal.<br><br>e.g. <code>foo=bar</code> becomes <code>foo|3d|bar</code>.",
+        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": {
+        module: "JSBN",
+        description: "Convert an IP address from one format to another, e.g. <code>172.20.23.54</code> to <code>ac141736</code>",
+        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": {
+        module: "JSBN",
+        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.",
+        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": {
+        module: "JSBN",
+        description: "Groups a list of IP addresses into subnets. Supports both IPv4 and IPv6 addresses.",
+        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": {
+        module: "JSBN",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Parse IPv4 header": {
+        module: "JSBN",
+        description: "Given an IPv4 header, this operations parses and displays each field in an easily readable format.",
+        inputType: "string",
+        outputType: "html",
+        args: [
+            {
+                name: "Input format",
+                type: "option",
+                value: IP.IP_HEADER_FORMAT
+            }
+        ]
+    },
+    "Encode text": {
+        module: "CharEnc",
+        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"),
+        inputType: "string",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Encoding",
+                type: "option",
+                value: Object.keys(CharEnc.IO_FORMAT),
+            },
+        ]
+    },
+    "Decode text": {
+        module: "CharEnc",
+        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"),
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Encoding",
+                type: "option",
+                value: Object.keys(CharEnc.IO_FORMAT),
+            },
+        ]
+    },
+    "AES Decrypt": {
+        module: "Ciphers",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.AES_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+            {
+                name: "GCM Tag",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+        ]
+    },
+    "AES Encrypt": {
+        module: "Ciphers",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.AES_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+        ]
+    },
+    "DES Decrypt": {
+        module: "Ciphers",
+        description: "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.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.DES_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+        ]
+    },
+    "DES Encrypt": {
+        module: "Ciphers",
+        description: "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.<br><br><b>Key:</b> DES uses a key length of 8 bytes (64 bits).<br>Triple DES uses a key length of 24 bytes (192 bits).<br><br>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.DES_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+        ]
+    },
+    "Triple DES Decrypt": {
+        module: "Ciphers",
+        description: "Triple DES applies DES three times to each block to increase key size.<br><br><b>Key:</b> Triple DES uses a key length of 24 bytes (192 bits).<br>DES uses a key length of 8 bytes (64 bits).<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.DES_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+        ]
+    },
+    "Triple DES Encrypt": {
+        module: "Ciphers",
+        description: "Triple DES applies DES three times to each block to increase key size.<br><br><b>Key:</b> Triple DES uses a key length of 24 bytes (192 bits).<br>DES uses a key length of 8 bytes (64 bits).<br><br>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.<br><br><b>Padding:</b> In CBC and ECB mode, PKCS#7 padding will be used.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.DES_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+        ]
+    },
+    "Blowfish Decrypt": {
+        module: "Ciphers",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.BLOWFISH_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.BLOWFISH_OUTPUT_TYPES
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+        ]
+    },
+    "Blowfish Encrypt": {
+        module: "Ciphers",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: Cipher.BLOWFISH_MODES
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.BLOWFISH_OUTPUT_TYPES
+            },
+        ]
+    },
+    "RC4": {
+        module: "Ciphers",
+        description: "RC4 (also known as ARC4) is a widely-used stream cipher designed by Ron Rivest. 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.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Passphrase",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.RC4_KEY_FORMAT
+            },
+            {
+                name: "Input format",
+                type: "option",
+                value: Cipher.CJS_IO_FORMAT
+            },
+            {
+                name: "Output format",
+                type: "option",
+                value: Cipher.CJS_IO_FORMAT
+            },
+        ]
+    },
+    "RC4 Drop": {
+        module: "Ciphers",
+        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.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Passphrase",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.RC4_KEY_FORMAT
+            },
+            {
+                name: "Input format",
+                type: "option",
+                value: Cipher.CJS_IO_FORMAT
+            },
+            {
+                name: "Output format",
+                type: "option",
+                value: Cipher.CJS_IO_FORMAT
+            },
+            {
+                name: "Number of bytes to drop",
+                type: "number",
+                value: Cipher.RC4DROP_BYTES
+            },
+        ]
+    },
+    "RC2 Decrypt": {
+        module: "Ciphers",
+        description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.<br><br><b>Key:</b> RC2 uses a variable size key.<br><br><b>IV:</b> To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.<br><br><b>Padding:</b> In both CBC and ECB mode, PKCS#7 padding will be used.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+        ]
+    },
+    "RC2 Encrypt": {
+        module: "Ciphers",
+        description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.<br><br><b>Key:</b> RC2 uses a variable size key.<br><br>You can generate a password-based key using one of the KDF operations.<br><br><b>IV:</b> To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.<br><br><b>Padding:</b> In both CBC and ECB mode, PKCS#7 padding will be used.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "IV",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+            {
+                name: "Input",
+                type: "option",
+                value: Cipher.IO_FORMAT3
+            },
+            {
+                name: "Output",
+                type: "option",
+                value: Cipher.IO_FORMAT4
+            },
+        ]
+    },
+    "Pseudo-Random Number Generator": {
+        module: "Ciphers",
+        description: "A cryptographically-secure pseudo-random number generator (PRNG).<br><br>This operation uses the browser's built-in <code>crypto.getRandomValues()</code> method if available. If this cannot be found, it falls back to a Fortuna-based PRNG algorithm.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Number of bytes",
+                type: "number",
+                value: Cipher.PRNG_BYTES
+            },
+            {
+                name: "Output as",
+                type: "option",
+                value: Cipher.PRNG_OUTPUT
+            }
+        ]
+    },
+    "Derive PBKDF2 key": {
+        module: "Ciphers",
+        description: "PBKDF2 is a password-based key derivation function. It is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's RFC 2898.<br><br>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>If you leave the salt argument empty, a random salt will be generated.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Passphrase",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT2
+            },
+            {
+                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",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+        ]
+    },
+    "Derive EVP key": {
+        module: "Ciphers",
+        description: "EVP is a password-based key derivation function (PBKDF) 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>If you leave the salt argument empty, a random salt will be generated.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Passphrase",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT2
+            },
+            {
+                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",
+                type: "toggleString",
+                value: "",
+                toggleValues: Cipher.IO_FORMAT1
+            },
+        ]
+    },
+    "Vigenère Encode": {
+        module: "Ciphers",
+        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.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "string",
+                value: ""
+            }
+        ]
+    },
+    "Vigenère Decode": {
+        module: "Ciphers",
+        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.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key",
+                type: "string",
+                value: ""
+            }
+        ]
+    },
+    "Bifid Cipher Encode": {
+        module: "Ciphers",
+        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.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Keyword",
+                type: "string",
+                value: ""
+            }
+        ]
+    },
+    "Bifid Cipher Decode": {
+        module: "Ciphers",
+        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.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Keyword",
+                type: "string",
+                value: ""
+            }
+        ]
+    },
+    "Affine Cipher Encode": {
+        module: "Ciphers",
+        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.",
+        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": {
+        module: "Ciphers",
+        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.",
+        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": {
+        module: "Ciphers",
+        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.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Rotate right": {
+        module: "Default",
+        description: "Rotates each byte to the right by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Amount",
+                type: "number",
+                value: Rotate.ROTATE_AMOUNT
+            },
+            {
+                name: "Carry through",
+                type: "boolean",
+                value: Rotate.ROTATE_CARRY
+            }
+        ]
+    },
+    "Rotate left": {
+        module: "Default",
+        description: "Rotates each byte to the left by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Amount",
+                type: "number",
+                value: Rotate.ROTATE_AMOUNT
+            },
+            {
+                name: "Carry through",
+                type: "boolean",
+                value: Rotate.ROTATE_CARRY
+            }
+        ]
+    },
+    "ROT13": {
+        module: "Default",
+        description: "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).",
+        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": {
+        module: "Default",
+        description: "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Amount",
+                type: "number",
+                value: Rotate.ROT47_AMOUNT
+            },
+        ]
+    },
+    "Strip HTTP headers": {
+        module: "HTTP",
+        description: "Removes HTTP headers from a request or response by looking for the first instance of a double newline.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Parse User Agent": {
+        module: "HTTP",
+        description: "Attempts to identify and categorise information contained in a user-agent string.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Format MAC addresses": {
+        module: "Default",
+        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.",
+        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": {
+        module: "Default",
+        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.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Offset",
+                type: "number",
+                value: NetBIOS.OFFSET
+            }
+        ]
+    },
+    "Decode NetBIOS Name": {
+        module: "Default",
+        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.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Offset",
+                type: "number",
+                value: NetBIOS.OFFSET
+            }
+        ]
+    },
+    "Offset checker": {
+        module: "Default",
+        description: "Compares multiple inputs (separated by the specified delimiter) and highlights matching characters which appear at the same position in all samples.",
+        inputType: "string",
+        outputType: "html",
+        args: [
+            {
+                name: "Sample delimiter",
+                type: "binaryString",
+                value: StrUtils.OFF_CHK_SAMPLE_DELIMITER
+            }
+        ]
+    },
+    "Remove whitespace": {
+        module: "Default",
+        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.",
+        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": {
+        module: "Default",
+        description: "Removes all null bytes (<code>0x00</code>) from the input.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: []
+    },
+    "Drop bytes": {
+        module: "Default",
+        description: "Cuts a slice of the specified number of bytes out of the data.",
+        inputType: "ArrayBuffer",
+        outputType: "ArrayBuffer",
+        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": {
+        module: "Default",
+        description: "Takes a slice of the specified number of bytes from the data.",
+        inputType: "ArrayBuffer",
+        outputType: "ArrayBuffer",
+        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": {
+        module: "Default",
+        description: "Add the specified number of the specified character to the beginning or end of each line",
+        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": {
+        module: "Default",
+        description: "Reverses the input string.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "By",
+                type: "option",
+                value: SeqUtils.REVERSE_BY
+            }
+        ]
+    },
+    "Sort": {
+        module: "Default",
+        description: "Alphabetically sorts strings separated by the specified delimiter.<br><br>The IP address option supports IPv4 only.",
+        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": {
+        module: "Default",
+        description: "Removes duplicate strings from the input.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: SeqUtils.DELIMITER_OPTIONS
+            }
+        ]
+    },
+    "Count occurrences": {
+        module: "Default",
+        description: "Counts the number of times the provided string occurs in the input.",
+        inputType: "string",
+        outputType: "number",
+        args: [
+            {
+                name: "Search string",
+                type: "toggleString",
+                value: "",
+                toggleValues: SeqUtils.SEARCH_TYPE
+            }
+        ]
+    },
+    "Add line numbers": {
+        module: "Default",
+        description: "Adds line numbers to the output.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Remove line numbers": {
+        module: "Default",
+        description: "Removes line numbers from the output if they can be trivially detected.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Find / Replace": {
+        module: "Default",
+        description: "Replaces all occurrences of the first string with the second.<br><br> Includes support for regular expressions (regex), simple strings and extended strings (which support \\n, \\r, \\t, \\b, \\f and escaped hex bytes using \\x notation, e.g. \\x00 for a null byte).",
+        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": {
+        module: "Default",
+        description: "Converts the input string to upper case, optionally limiting scope to only the first character in each word, sentence or paragraph.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Scope",
+                type: "option",
+                value: StrUtils.CASE_SCOPE
+            }
+        ]
+    },
+    "To Lower case": {
+        module: "Default",
+        description: "Converts every character in the input to lower case.",
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Split": {
+        module: "Default",
+        description: "Splits a string into sections around a given delimiter.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Split delimiter",
+                type: "binaryShortString",
+                value: StrUtils.SPLIT_DELIM
+            },
+            {
+                name: "Join delimiter",
+                type: "option",
+                value: StrUtils.DELIMITER_OPTIONS
+            }
+        ]
+    },
+    "Filter": {
+        module: "Default",
+        description: "Splits up the input using the specified delimiter and then filters each branch based on a regular expression.",
+        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": {
+        module: "Default",
+        description: "Extracts all strings from the input.",
+        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": {
+        module: "Default",
+        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!",
+        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": {
+        module: "Default",
+        description: "Extracts all email addresses from the input.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Display total",
+                type: "boolean",
+                value: Extract.DISPLAY_TOTAL
+            }
+        ]
+    },
+    "Extract MAC addresses": {
+        module: "Default",
+        description: "Extracts all Media Access Control (MAC) addresses from the input.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Display total",
+                type: "boolean",
+                value: Extract.DISPLAY_TOTAL
+            }
+        ]
+    },
+    "Extract URLs": {
+        module: "Default",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Display total",
+                type: "boolean",
+                value: Extract.DISPLAY_TOTAL
+            }
+        ]
+    },
+    "Extract domains": {
+        module: "Default",
+        description: "Extracts domain names.<br>Note that this will not include paths. Use <strong>Extract URLs</strong> to find entire URLs.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Display total",
+                type: "boolean",
+                value: Extract.DISPLAY_TOTAL
+            }
+        ]
+    },
+    "Extract file paths": {
+        module: "Default",
+        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.",
+        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": {
+        module: "Default",
+        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",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Display total",
+                type: "boolean",
+                value: Extract.DISPLAY_TOTAL
+            }
+        ]
+    },
+    "Regular expression": {
+        module: "Default",
+        description: "Define your own regular expression (regex) to search the input data with, optionally choosing from a list of pre-defined patterns.",
+        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": {
+        module: "Code",
+        description: "Extract information from an XML document with an XPath query",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "XPath",
+                type: "string",
+                value: Code.XPATH_INITIAL
+            },
+            {
+                name: "Result delimiter",
+                type: "binaryShortString",
+                value: Code.XPATH_DELIMITER
+            }
+        ]
+    },
+    "JPath expression": {
+        module: "Code",
+        description: "Extract information from a JSON object with a JPath query.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Query",
+                type: "string",
+                value: Code.JPATH_INITIAL
+            },
+            {
+                name: "Result delimiter",
+                type: "binaryShortString",
+                value: Code.JPATH_DELIMITER
+            }
+        ]
+    },
+    "CSS selector": {
+        module: "Code",
+        description: "Extract information from an HTML document with a CSS selector",
+        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": {
+        module: "Default",
+        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><br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).",
+        inputType: "number",
+        outputType: "string",
+        args: [
+            {
+                name: "Units",
+                type: "option",
+                value: DateTime.UNITS
+            }
+        ]
+    },
+    "To UNIX Timestamp": {
+        module: "Default",
+        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><br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).",
+        inputType: "string",
+        outputType: "number",
+        args: [
+            {
+                name: "Units",
+                type: "option",
+                value: DateTime.UNITS
+            },
+            {
+                name: "Treat as UTC",
+                type: "boolean",
+                value: DateTime.TREAT_AS_UTC
+            }
+        ]
+    },
+    "Windows Filetime to UNIX Timestamp": {
+        module: "JSBN",
+        description: "Converts a Windows Filetime value to a UNIX timestamp.<br><br>A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.<br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).<br><br>This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Output units",
+                type: "option",
+                value: Filetime.UNITS
+            },
+            {
+                name: "Input format",
+                type: "option",
+                value: Filetime.FILETIME_FORMATS
+            }
+        ]
+    },
+    "UNIX Timestamp to Windows Filetime": {
+        module: "JSBN",
+        description: "Converts a UNIX timestamp to a Windows Filetime value.<br><br>A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.<br><br>A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).<br><br>This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Input units",
+                type: "option",
+                value: Filetime.UNITS
+            },
+            {
+                name: "Output format",
+                type: "option",
+                value: Filetime.FILETIME_FORMATS
+            }
+        ]
+    },
+    "Translate DateTime Format": {
+        module: "Default",
+        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.",
+        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": {
+        module: "Default",
+        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.",
+        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": {
+        module: "Default",
+        description: "Converts a unit of distance to another format.",
+        inputType: "BigNumber",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Input units",
+                type: "option",
+                value: Convert.DISTANCE_UNITS
+            },
+            {
+                name: "Output units",
+                type: "option",
+                value: Convert.DISTANCE_UNITS
+            }
+        ]
+    },
+    "Convert area": {
+        module: "Default",
+        description: "Converts a unit of area to another format.",
+        inputType: "BigNumber",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Input units",
+                type: "option",
+                value: Convert.AREA_UNITS
+            },
+            {
+                name: "Output units",
+                type: "option",
+                value: Convert.AREA_UNITS
+            }
+        ]
+    },
+    "Convert mass": {
+        module: "Default",
+        description: "Converts a unit of mass to another format.",
+        inputType: "BigNumber",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Input units",
+                type: "option",
+                value: Convert.MASS_UNITS
+            },
+            {
+                name: "Output units",
+                type: "option",
+                value: Convert.MASS_UNITS
+            }
+        ]
+    },
+    "Convert speed": {
+        module: "Default",
+        description: "Converts a unit of speed to another format.",
+        inputType: "BigNumber",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Input units",
+                type: "option",
+                value: Convert.SPEED_UNITS
+            },
+            {
+                name: "Output units",
+                type: "option",
+                value: Convert.SPEED_UNITS
+            }
+        ]
+    },
+    "Convert data units": {
+        module: "Default",
+        description: "Converts a unit of data to another format.",
+        inputType: "BigNumber",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Input units",
+                type: "option",
+                value: Convert.DATA_UNITS
+            },
+            {
+                name: "Output units",
+                type: "option",
+                value: Convert.DATA_UNITS
+            }
+        ]
+    },
+    "Raw Deflate": {
+        module: "Compression",
+        description: "Compresses data using the deflate algorithm with no headers.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Compression type",
+                type: "option",
+                value: Compress.COMPRESSION_TYPE
+            }
+        ]
+    },
+    "Raw Inflate": {
+        module: "Compression",
+        description: "Decompresses data which has been compressed using the deflate algorithm with no headers.",
+        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": {
+        module: "Compression",
+        description: "Compresses data using the deflate algorithm adding zlib headers.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Compression type",
+                type: "option",
+                value: Compress.COMPRESSION_TYPE
+            }
+        ]
+    },
+    "Zlib Inflate": {
+        module: "Compression",
+        description: "Decompresses data which has been compressed using the deflate algorithm with zlib headers.",
+        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": {
+        module: "Compression",
+        description: "Compresses data using the deflate algorithm with gzip headers.",
+        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": {
+        module: "Compression",
+        description: "Decompresses data which has been compressed using the deflate algorithm with gzip headers.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: []
+    },
+    "Zip": {
+        module: "Compression",
+        description: "Compresses data using the PKZIP algorithm with the given filename.<br><br>No support for multiple files at this time.",
+        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": {
+        module: "Compression",
+        description: "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.",
+        inputType: "byteArray",
+        outputType: "html",
+        args: [
+            {
+                name: "Password",
+                type: "binaryString",
+                value: ""
+            },
+            {
+                name: "Verify result",
+                type: "boolean",
+                value: Compress.PKUNZIP_VERIFY
+            }
+        ]
+    },
+    "Bzip2 Decompress": {
+        module: "Compression",
+        description: "Decompresses data using the Bzip2 algorithm.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "Generic Code Beautify": {
+        module: "Code",
+        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>",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "JavaScript Parser": {
+        module: "Code",
+        description: "Returns an Abstract Syntax Tree for valid JavaScript code.",
+        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": {
+        module: "Code",
+        description: "Parses and pretty prints valid JavaScript code. Also works with JavaScript Object Notation (JSON).",
+        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": {
+        module: "Code",
+        description: "Compresses JavaScript code.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "XML Beautify": {
+        module: "Code",
+        description: "Indents and prettifies eXtensible Markup Language (XML) code.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Indent string",
+                type: "binaryShortString",
+                value: Code.BEAUTIFY_INDENT
+            }
+        ]
+    },
+    "JSON Beautify": {
+        module: "Code",
+        description: "Indents and prettifies JavaScript Object Notation (JSON) code.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Indent string",
+                type: "binaryShortString",
+                value: Code.BEAUTIFY_INDENT
+            }
+        ]
+    },
+    "CSS Beautify": {
+        module: "Code",
+        description: "Indents and prettifies Cascading Style Sheets (CSS) code.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Indent string",
+                type: "binaryShortString",
+                value: Code.BEAUTIFY_INDENT
+            }
+        ]
+    },
+    "SQL Beautify": {
+        module: "Code",
+        description: "Indents and prettifies Structured Query Language (SQL) code.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Indent string",
+                type: "binaryShortString",
+                value: Code.BEAUTIFY_INDENT
+            }
+        ]
+    },
+    "XML Minify": {
+        module: "Code",
+        description: "Compresses eXtensible Markup Language (XML) code.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Preserve comments",
+                type: "boolean",
+                value: Code.PRESERVE_COMMENTS
+            }
+        ]
+    },
+    "JSON Minify": {
+        module: "Code",
+        description: "Compresses JavaScript Object Notation (JSON) code.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "CSS Minify": {
+        module: "Code",
+        description: "Compresses Cascading Style Sheets (CSS) code.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Preserve comments",
+                type: "boolean",
+                value: Code.PRESERVE_COMMENTS
+            }
+        ]
+    },
+    "SQL Minify": {
+        module: "Code",
+        description: "Compresses Structured Query Language (SQL) code.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Analyse hash": {
+        module: "Hashing",
+        description: "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "MD2": {
+        module: "Hashing",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "MD4": {
+        module: "Hashing",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "MD5": {
+        module: "Hashing",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "MD6": {
+        module: "Hashing",
+        description: "The MD6 (Message-Digest 6) algorithm is a cryptographic hash function. It uses a Merkle tree-like structure to allow for immense parallel computation of hashes for very long inputs.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Size",
+                type: "number",
+                value: Hash.MD6_SIZE
+            },
+            {
+                name: "Levels",
+                type: "number",
+                value: Hash.MD6_LEVELS
+            },
+            {
+                name: "Key",
+                type: "string",
+                value: ""
+            }
+        ]
+    },
+    "SHA0": {
+        module: "Hashing",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "SHA1": {
+        module: "Hashing",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "SHA2": {
+        module: "Hashing",
+        description: "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.<br><br><ul><li>SHA-512 operates on 64-bit words.</li><li>SHA-256 operates on 32-bit words.</li><li>SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.</li><li>SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.</li><li>SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.</li></ul>",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Size",
+                type: "option",
+                value: Hash.SHA2_SIZE
+            }
+        ]
+    },
+    "SHA3": {
+        module: "Hashing",
+        description: "The SHA-3 (Secure Hash Algorithm 3) hash functions were released by NIST on August 5, 2015. Although part of the same series of standards, SHA-3 is internally quite different from the MD5-like structure of SHA-1 and SHA-2.<br><br>SHA-3 is a subset of the broader cryptographic primitive family Keccak designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Size",
+                type: "option",
+                value: Hash.SHA3_SIZE
+            }
+        ]
+    },
+    "Keccak": {
+        module: "Hashing",
+        description: "The Keccak hash algorithm was designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún. It was selected as the winner of the SHA-3 design competition.<br><br>This version of the algorithm is Keccak[c=2d] and differs from the SHA-3 specification.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Size",
+                type: "option",
+                value: Hash.KECCAK_SIZE
+            }
+        ]
+    },
+    "Shake": {
+        module: "Hashing",
+        description: "Shake is an Extendable Output Function (XOF) of the SHA-3 hash algorithm, part of the Keccak family, allowing for variable output length/size.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Capacity",
+                type: "option",
+                value: Hash.SHAKE_CAPACITY
+            },
+            {
+                name: "Size",
+                type: "number",
+                value: Hash.SHAKE_SIZE
+            }
+        ]
+
+    },
+    "RIPEMD": {
+        module: "Hashing",
+        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>",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Size",
+                type: "option",
+                value: Hash.RIPEMD_SIZE
+            }
+        ]
+    },
+    "HAS-160": {
+        module: "Hashing",
+        description: "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.<br><br>HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.<br><br>The message digest algorithm consists of 80 rounds.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Whirlpool": {
+        module: "Hashing",
+        description: "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Variant",
+                type: "option",
+                value: Hash.WHIRLPOOL_VARIANT
+            }
+        ]
+    },
+    "Snefru": {
+        module: "Hashing",
+        description: "Snefru is a cryptographic hash function invented by Ralph Merkle in 1990 while working at Xerox PARC. The function supports 128-bit and 256-bit output. It was named after the Egyptian Pharaoh Sneferu, continuing the tradition of the Khufu and Khafre block ciphers.<br><br>The original design of Snefru was shown to be insecure by Eli Biham and Adi Shamir who were able to use differential cryptanalysis to find hash collisions. The design was then modified by increasing the number of iterations of the main pass of the algorithm from two to eight.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Rounds",
+                type: "option",
+                value: Hash.SNEFRU_ROUNDS
+            },
+            {
+                name: "Size",
+                type: "option",
+                value: Hash.SNEFRU_SIZE
+            }
+        ]
+    },
+    "HMAC": {
+        module: "Hashing",
+        description: "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Password",
+                type: "binaryString",
+                value: ""
+            },
+            {
+                name: "Hashing function",
+                type: "option",
+                value: Hash.HMAC_FUNCTIONS
+            },
+        ]
+    },
+    "Fletcher-8 Checksum": {
+        module: "Hashing",
+        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.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "Fletcher-16 Checksum": {
+        module: "Hashing",
+        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.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "Fletcher-32 Checksum": {
+        module: "Hashing",
+        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.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "Fletcher-64 Checksum": {
+        module: "Hashing",
+        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.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "Adler-32 Checksum": {
+        module: "Hashing",
+        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.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "CRC-32 Checksum": {
+        module: "Hashing",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "CRC-16 Checksum": {
+        module: "Hashing",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Generate all hashes": {
+        module: "Hashing",
+        description: "Generates all available hashes and checksums for the input.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Entropy": {
+        module: "Default",
+        description: "Calculates the Shannon entropy of the input data which gives an idea of its randomness. 8 is the maximum.",
+        inputType: "byteArray",
+        outputType: "html",
+        args: [
+            {
+                name: "Chunk size",
+                type: "number",
+                value: Entropy.CHUNK_SIZE
+            }
+        ]
+    },
+    "Frequency distribution": {
+        module: "Default",
+        description: "Displays the distribution of bytes in the data as a graph.",
+        inputType: "ArrayBuffer",
+        outputType: "html",
+        args: [
+            {
+                name: "Show 0%'s",
+                type: "boolean",
+                value: Entropy.FREQ_ZEROS
+            }
+        ]
+    },
+    "Chi Square": {
+        module: "Default",
+        description: "Calculates the Chi Square distribution of values.",
+        inputType: "ArrayBuffer",
+        outputType: "number",
+        args: []
+    },
+    "Numberwang": {
+        module: "Default",
+        description: "Based on the popular gameshow by Mitchell and Webb.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Parse X.509 certificate": {
+        module: "PublicKey",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Input format",
+                type: "option",
+                value: PublicKey.X509_INPUT_FORMAT
+            }
+        ]
+    },
+    "PEM to Hex": {
+        module: "PublicKey",
+        description: "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Hex to PEM": {
+        module: "PublicKey",
+        description: "Converts a hexadecimal DER (Distinguished Encoding Rules) string into PEM (Privacy Enhanced Mail) format.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Header string",
+                type: "string",
+                value: PublicKey.PEM_HEADER_STRING
+            }
+        ]
+    },
+    "Hex to Object Identifier": {
+        module: "PublicKey",
+        description: "Converts a hexadecimal string into an object identifier (OID).",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Object Identifier to Hex": {
+        module: "PublicKey",
+        description: "Converts an object identifier (OID) into a hexadecimal string.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Parse ASN.1 hex string": {
+        module: "PublicKey",
+        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.",
+        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": {
+        module: "Default",
+        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.",
+        inputType: "ArrayBuffer",
+        outputType: "string",
+        args: []
+    },
+    "Scan for Embedded Files": {
+        module: "Default",
+        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.",
+        inputType: "ArrayBuffer",
+        outputType: "string",
+        args: [
+            {
+                name: "Ignore common byte sequences",
+                type: "boolean",
+                value: FileType.IGNORE_COMMON_BYTE_SEQUENCES
+            }
+        ]
+    },
+    "Expand alphabet range": {
+        module: "Default",
+        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>.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "binaryString",
+                value: ""
+            }
+        ]
+    },
+    "Diff": {
+        module: "Diff",
+        description: "Compares two inputs (separated by the specified delimiter) and highlights the differences between them.",
+        inputType: "string",
+        outputType: "html",
+        args: [
+            {
+                name: "Sample delimiter",
+                type: "binaryString",
+                value: Diff.DIFF_SAMPLE_DELIMITER
+            },
+            {
+                name: "Diff by",
+                type: "option",
+                value: Diff.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": {
+        module: "Default",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Swap endianness": {
+        module: "Default",
+        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.",
+        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
+            }
+        ]
+    },
+    "Microsoft Script Decoder": {
+        module: "Default",
+        description: "Decodes Microsoft Encoded Script files that have been encoded with Microsoft's custom encoding. These are often VBS (Visual Basic Script) files that are encoded and renamed with a '.vbe' extention or JS (JScript) files renamed with a '.jse' extention.<br><br><b>Sample</b><br><br>Encoded:<br><code>#@~^RQAAAA==-mD~sX|:/TP{~J:+dYbxL~@!F@*@!+@*@!&amp;@*eEI@#@&amp;@#@&amp;.jm.raY 214Wv:zms/obI0xEAAA==^#~@</code><br><br>Decoded:<br><code>var my_msg = &#34;Testing <1><2><3>!&#34;;\n\nVScript.Echo(my_msg);</code>",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Syntax highlighter": {
+        module: "Code",
+        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.",
+        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
+            }
+        ]
+    },
+    "TCP/IP Checksum": {
+        module: "Hashing",
+        description: "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: []
+    },
+    "Parse colour code": {
+        module: "Default",
+        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>",
+        inputType: "string",
+        outputType: "html",
+        args: []
+    },
+    "Generate UUID": {
+        module: "Default",
+        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.",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Substitute": {
+        module: "Ciphers",
+        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>.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Plaintext",
+                type: "binaryString",
+                value: Cipher.SUBS_PLAINTEXT
+            },
+            {
+                name: "Ciphertext",
+                type: "binaryString",
+                value: Cipher.SUBS_CIPHERTEXT
+            }
+        ]
+    },
+    "Escape string": {
+        module: "Default",
+        description: "Escapes special characters in a string so that they do not cause conflicts. For example, <code>Don't stop me now</code> becomes <code>Don\\'t stop me now</code>.<br><br>Supports the following escape sequences:<ul><li><code>\\n</code> (Line feed/newline)</li><li><code>\\r</code> (Carriage return)</li><li><code>\\t</code> (Horizontal tab)</li><li><code>\\b</code> (Backspace)</li><li><code>\\f</code> (Form feed)</li><li><code>\\xnn</code> (Hex, where n is 0-f)</li><li><code>\\\\</code> (Backslash)</li><li><code>\\'</code> (Single quote)</li><li><code>\\&quot;</code> (Double quote)</li></ul>",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "Unescape string": {
+        module: "Default",
+        description: "Unescapes characters in a string that have been escaped. For example, <code>Don\\'t stop me now</code> becomes <code>Don't stop me now</code>.<br><br>Supports the following escape sequences:<ul><li><code>\\n</code> (Line feed/newline)</li><li><code>\\r</code> (Carriage return)</li><li><code>\\t</code> (Horizontal tab)</li><li><code>\\b</code> (Backspace)</li><li><code>\\f</code> (Form feed)</li><li><code>\\xnn</code> (Hex, where n is 0-f)</li><li><code>\\\\</code> (Backslash)</li><li><code>\\'</code> (Single quote)</li><li><code>\\&quot;</code> (Double quote)</li></ul>",
+        inputType: "string",
+        outputType: "string",
+        args: []
+    },
+    "To Morse Code": {
+        module: "Default",
+        description: "Translates alphanumeric characters into International Morse Code.<br><br>Ignores non-Morse characters.<br><br>e.g. <code>SOS</code> becomes <code>... --- ...</code>",
+        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": {
+        module: "Default",
+        description: "Translates Morse Code into (upper case) alphanumeric characters.",
+        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": {
+        module: "Compression",
+        description: "Packs the input into a tarball.<br><br>No support for multiple files at this time.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: [
+            {
+                name: "Filename",
+                type: "string",
+                value: Compress.TAR_FILENAME
+            }
+        ]
+    },
+    "Untar": {
+        module: "Compression",
+        description: "Unpacks a tarball and displays it per file.",
+        inputType: "byteArray",
+        outputType: "html",
+        args: [
+        ]
+    },
+    "Head": {
+        module: "Default",
+        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"),
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: StrUtils.DELIMITER_OPTIONS
+            },
+            {
+                name: "Number",
+                type: "number",
+                value: 10,
+            },
+        ]
+    },
+    "Tail": {
+        module: "Default",
+        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"),
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Delimiter",
+                type: "option",
+                value: StrUtils.DELIMITER_OPTIONS
+            },
+            {
+                name: "Number",
+                type: "number",
+                value: 10,
+            },
+        ]
+    },
+    "To Snake case": {
+        module: "Code",
+        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"),
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Attempt to be context aware",
+                type: "boolean",
+                value: false,
+            },
+        ]
+    },
+    "To Camel case": {
+        module: "Code",
+        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"),
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Attempt to be context aware",
+                type: "boolean",
+                value: false,
+            },
+        ]
+    },
+    "To Kebab case": {
+        module: "Code",
+        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"),
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Attempt to be context aware",
+                type: "boolean",
+                value: false,
+            },
+        ]
+    },
+    "Extract EXIF": {
+        module: "Image",
+        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"),
+        inputType: "ArrayBuffer",
+        outputType: "string",
+        args: [],
+    },
+    "Render Image": {
+        module: "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>",
+        inputType: "string",
+        outputType: "html",
+        args: [
+            {
+                name: "Input format",
+                type: "option",
+                value: Image.INPUT_FORMAT
+            }
+        ]
+    },
+    "Remove EXIF": {
+        module: "Image",
+        description: [
+            "Removes EXIF data from a JPEG image.",
+            "<br><br>",
+            "EXIF data embedded in photos usually contains information about the image file itself as well as the device used to create it.",
+        ].join("\n"),
+        inputType: "byteArray",
+        outputType: "byteArray",
+        args: []
+    },
+    "HTTP request": {
+        module: "HTTP",
+        description: [
+            "Makes an HTTP request and returns the response.",
+            "<br><br>",
+            "This operation supports different HTTP verbs like GET, POST, PUT, etc.",
+            "<br><br>",
+            "You can add headers line by line in the format <code>Key: Value</code>",
+            "<br><br>",
+            "The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.",
+        ].join("\n"),
+        inputType: "string",
+        outputType: "string",
+        manualBake: true,
+        args: [
+            {
+                name: "Method",
+                type: "option",
+                value: HTTP.METHODS,
+            },
+            {
+                name: "URL",
+                type: "string",
+                value: "",
+            },
+            {
+                name: "Headers",
+                type: "text",
+                value: "",
+            },
+            {
+                name: "Mode",
+                type: "option",
+                value: HTTP.MODE,
+            },
+            {
+                name: "Show response metadata",
+                type: "boolean",
+                value: false,
+            }
+        ]
+    },
+    "From BCD": {
+        module: "Default",
+        description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.",
+        inputType: "string",
+        outputType: "BigNumber",
+        args: [
+            {
+                name: "Scheme",
+                type: "option",
+                value: BCD.ENCODING_SCHEME
+            },
+            {
+                name: "Packed",
+                type: "boolean",
+                value: true
+            },
+            {
+                name: "Signed",
+                type: "boolean",
+                value: false
+            },
+            {
+                name: "Input format",
+                type: "option",
+                value: BCD.FORMAT
+            }
+        ]
+
+    },
+    "To BCD": {
+        module: "Default",
+        description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign",
+        inputType: "BigNumber",
+        outputType: "string",
+        args: [
+            {
+                name: "Scheme",
+                type: "option",
+                value: BCD.ENCODING_SCHEME
+            },
+            {
+                name: "Packed",
+                type: "boolean",
+                value: true
+            },
+            {
+                name: "Signed",
+                type: "boolean",
+                value: false
+            },
+            {
+                name: "Output format",
+                type: "option",
+                value: BCD.FORMAT
+            }
+        ]
+
+    },
+    "Bit shift left": {
+        module: "Default",
+        description: "Shifts the bits in each byte towards the left by the specified amount.",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        highlight: true,
+        highlightReverse: true,
+        args: [
+            {
+                name: "Amount",
+                type: "number",
+                value: 1
+            },
+        ]
+    },
+    "Bit shift right": {
+        module: "Default",
+        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).",
+        inputType: "byteArray",
+        outputType: "byteArray",
+        highlight: true,
+        highlightReverse: true,
+        args: [
+            {
+                name: "Amount",
+                type: "number",
+                value: 1
+            },
+            {
+                name: "Type",
+                type: "option",
+                value: BitwiseOp.BIT_SHIFT_TYPE
+            }
+        ]
+    },
+    "Generate TOTP": {
+        module: "Default",
+        description: "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.<br><br>Enter the secret as the input or leave it blank for a random secret to be generated. T0 and T1 are in seconds.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Name",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Key size",
+                type: "number",
+                value: 32
+            },
+            {
+                name: "Code length",
+                type: "number",
+                value: 6
+            },
+            {
+                name: "Epoch offset (T0)",
+                type: "number",
+                value: 0
+            },
+            {
+                name: "Interval (T1)",
+                type: "number",
+                value: 30
+            }
+        ]
+    },
+    "Generate HOTP": {
+        module: "Default",
+        description: "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems.<br><br>Enter the secret as the input or leave it blank for a random secret to be generated.",
+        inputType: "byteArray",
+        outputType: "string",
+        args: [
+            {
+                name: "Name",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Key size",
+                type: "number",
+                value: 32
+            },
+            {
+                name: "Code length",
+                type: "number",
+                value: 6
+            },
+            {
+                name: "Counter",
+                type: "number",
+                value: 0
+            }
+        ]
+    },
+    "PHP Deserialize": {
+        module: "Default",
+        description: "Deserializes PHP serialized data, outputting keyed arrays as JSON.<br><br>This function does not support <code>object</code> tags.<br><br>Example:<br><code>a:2:{s:1:&quot;a&quot;;i:10;i:0;a:1:{s:2:&quot;ab&quot;;b:1;}}</code><br>becomes<br><code>{&quot;a&quot;: 10,0: {&quot;ab&quot;: true}}</code><br><br><u>Output valid JSON:</u> JSON doesn't support integers as keys, whereas PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes.",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Output valid JSON",
+                type: "boolean",
+                value: PHP.OUTPUT_VALID_JSON
+            }
+        ]
+    },
+    "Generate PGP Key Pair": {
+        module: "PGP",
+        manualBake: true,
+        description: "",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Key type",
+                type: "option",
+                value: PGP.KEY_TYPES
+            },
+            {
+                name: "Key size",
+                type: "option",
+                value: PGP.KEY_SIZES
+            },
+            {
+                name: "Password (optional)",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Name (optional)",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Email (optional)",
+                type: "string",
+                value: ""
+            },
+        ]
+    },
+    "PGP Encrypt": {
+        module: "PGP",
+        manualBake: true,
+        description: "",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Public key",
+                type: "text",
+                value: ""
+            },
+        ]
+    },
+    "PGP Decrypt": {
+        module: "PGP",
+        manualBake: true,
+        description: "",
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Private key",
+                type: "text",
+                value: ""
+            },
+        ]
+    },
+};
+
+
+/**
+ * Exports the OperationConfig JSON object in val-loader format so that it can be loaded
+ * into the app without also importing all the dependencies.
+ *
+ * See https://github.com/webpack-contrib/val-loader
+ *
+ * @returns {Object}
+ */
+function valExport() {
+    return {
+        code: "module.exports = " + JSON.stringify(OperationConfig) + ";"
+    };
+}
+
+export default valExport;
+
+export { OperationConfig };

+ 0 - 1
src/core/config/modules/CharEnc.js

@@ -6,7 +6,6 @@ import CharEnc from "../../operations/CharEnc.js";
  *
  *
  * Libraries:
  * Libraries:
  *  - cptable
  *  - cptable
- *  - CryptoJS
  *
  *
  * @author n1474335 [n1474335@gmail.com]
  * @author n1474335 [n1474335@gmail.com]
  * @copyright Crown Copyright 2017
  * @copyright Crown Copyright 2017

+ 4 - 2
src/core/config/modules/Ciphers.js

@@ -7,6 +7,7 @@ import Cipher from "../../operations/Cipher.js";
  * Libraries:
  * Libraries:
  *  - CryptoJS
  *  - CryptoJS
  *  - Blowfish
  *  - Blowfish
+ *  - Forge
  *
  *
  * @author n1474335 [n1474335@gmail.com]
  * @author n1474335 [n1474335@gmail.com]
  * @copyright Crown Copyright 2017
  * @copyright Crown Copyright 2017
@@ -23,12 +24,12 @@ OpModules.Ciphers = {
     "DES Decrypt":          Cipher.runDesDec,
     "DES Decrypt":          Cipher.runDesDec,
     "Triple DES Encrypt":   Cipher.runTripleDesEnc,
     "Triple DES Encrypt":   Cipher.runTripleDesEnc,
     "Triple DES Decrypt":   Cipher.runTripleDesDec,
     "Triple DES Decrypt":   Cipher.runTripleDesDec,
-    "Rabbit Encrypt":       Cipher.runRabbitEnc,
-    "Rabbit Decrypt":       Cipher.runRabbitDec,
     "Derive PBKDF2 key":    Cipher.runPbkdf2,
     "Derive PBKDF2 key":    Cipher.runPbkdf2,
     "Derive EVP key":       Cipher.runEvpkdf,
     "Derive EVP key":       Cipher.runEvpkdf,
     "RC4":                  Cipher.runRc4,
     "RC4":                  Cipher.runRc4,
     "RC4 Drop":             Cipher.runRc4drop,
     "RC4 Drop":             Cipher.runRc4drop,
+    "RC2 Encrypt":          Cipher.runRc2Enc,
+    "RC2 Decrypt":          Cipher.runRc2Dec,
     "Vigenère Encode":      Cipher.runVigenereEnc,
     "Vigenère Encode":      Cipher.runVigenereEnc,
     "Vigenère Decode":      Cipher.runVigenereDec,
     "Vigenère Decode":      Cipher.runVigenereDec,
     "Bifid Cipher Encode":  Cipher.runBifidEnc,
     "Bifid Cipher Encode":  Cipher.runBifidEnc,
@@ -37,6 +38,7 @@ OpModules.Ciphers = {
     "Affine Cipher Decode": Cipher.runAffineDec,
     "Affine Cipher Decode": Cipher.runAffineDec,
     "Atbash Cipher":        Cipher.runAtbash,
     "Atbash Cipher":        Cipher.runAtbash,
     "Substitute":           Cipher.runSubstitute,
     "Substitute":           Cipher.runSubstitute,
+    "Pseudo-Random Number Generator": Cipher.runPRNG,
 };
 };
 
 
 export default OpModules;
 export default OpModules;

+ 13 - 6
src/core/config/modules/Default.js

@@ -1,4 +1,5 @@
 import FlowControl from "../../FlowControl.js";
 import FlowControl from "../../FlowControl.js";
+import Arithmetic from "../../operations/Arithmetic.js";
 import Base from "../../operations/Base.js";
 import Base from "../../operations/Base.js";
 import Base58 from "../../operations/Base58.js";
 import Base58 from "../../operations/Base58.js";
 import Base64 from "../../operations/Base64.js";
 import Base64 from "../../operations/Base64.js";
@@ -20,16 +21,15 @@ import NetBIOS from "../../operations/NetBIOS.js";
 import Numberwang from "../../operations/Numberwang.js";
 import Numberwang from "../../operations/Numberwang.js";
 import OS from "../../operations/OS.js";
 import OS from "../../operations/OS.js";
 import OTP from "../../operations/OTP.js";
 import OTP from "../../operations/OTP.js";
+import PHP from "../../operations/PHP.js";
 import QuotedPrintable from "../../operations/QuotedPrintable.js";
 import QuotedPrintable from "../../operations/QuotedPrintable.js";
 import Rotate from "../../operations/Rotate.js";
 import Rotate from "../../operations/Rotate.js";
 import SeqUtils from "../../operations/SeqUtils.js";
 import SeqUtils from "../../operations/SeqUtils.js";
 import StrUtils from "../../operations/StrUtils.js";
 import StrUtils from "../../operations/StrUtils.js";
 import Tidy from "../../operations/Tidy.js";
 import Tidy from "../../operations/Tidy.js";
 import Unicode from "../../operations/Unicode.js";
 import Unicode from "../../operations/Unicode.js";
-import URL_ from "../../operations/URL.js";
 import UUID from "../../operations/UUID.js";
 import UUID from "../../operations/UUID.js";
 
 
-
 /**
 /**
  * Default module.
  * Default module.
  *
  *
@@ -38,8 +38,8 @@ import UUID from "../../operations/UUID.js";
  *
  *
  * Libraries:
  * Libraries:
  *  - Utils.js
  *  - Utils.js
- *    - CryptoJS
  *  - otp
  *  - otp
+ *  - crypto
  *
  *
  * @author n1474335 [n1474335@gmail.com]
  * @author n1474335 [n1474335@gmail.com]
  * @copyright Crown Copyright 2017
  * @copyright Crown Copyright 2017
@@ -77,9 +77,6 @@ OpModules.Default = {
     "From HTML Entity":     HTML.runFromEntity,
     "From HTML Entity":     HTML.runFromEntity,
     "Strip HTML tags":      HTML.runStripTags,
     "Strip HTML tags":      HTML.runStripTags,
     "Parse colour code":    HTML.runParseColourCode,
     "Parse colour code":    HTML.runParseColourCode,
-    "URL Encode":           URL_.runTo,
-    "URL Decode":           URL_.runFrom,
-    "Parse URI":            URL_.runParse,
     "Unescape Unicode Characters": Unicode.runUnescape,
     "Unescape Unicode Characters": Unicode.runUnescape,
     "To Quoted Printable":  QuotedPrintable.runTo,
     "To Quoted Printable":  QuotedPrintable.runTo,
     "From Quoted Printable": QuotedPrintable.runFrom,
     "From Quoted Printable": QuotedPrintable.runFrom,
@@ -146,6 +143,7 @@ OpModules.Default = {
     "Microsoft Script Decoder": MS.runDecodeScript,
     "Microsoft Script Decoder": MS.runDecodeScript,
     "Entropy":              Entropy.runEntropy,
     "Entropy":              Entropy.runEntropy,
     "Frequency distribution": Entropy.runFreqDistrib,
     "Frequency distribution": Entropy.runFreqDistrib,
+    "Chi Square":           Entropy.runChiSq,
     "Detect File Type":     FileType.runDetect,
     "Detect File Type":     FileType.runDetect,
     "Scan for Embedded Files": FileType.runScanForEmbeddedFiles,
     "Scan for Embedded Files": FileType.runScanForEmbeddedFiles,
     "Generate UUID":        UUID.runGenerateV4,
     "Generate UUID":        UUID.runGenerateV4,
@@ -155,10 +153,19 @@ OpModules.Default = {
     "Fork":                 FlowControl.runFork,
     "Fork":                 FlowControl.runFork,
     "Merge":                FlowControl.runMerge,
     "Merge":                FlowControl.runMerge,
     "Register":             FlowControl.runRegister,
     "Register":             FlowControl.runRegister,
+    "Label":                FlowControl.runComment,
     "Jump":                 FlowControl.runJump,
     "Jump":                 FlowControl.runJump,
     "Conditional Jump":     FlowControl.runCondJump,
     "Conditional Jump":     FlowControl.runCondJump,
     "Return":               FlowControl.runReturn,
     "Return":               FlowControl.runReturn,
     "Comment":              FlowControl.runComment,
     "Comment":              FlowControl.runComment,
+    "PHP Deserialize":      PHP.runDeserialize,
+    "Sum":                  Arithmetic.runSum,
+    "Subtract":             Arithmetic.runSub,
+    "Multiply":             Arithmetic.runMulti,
+    "Divide":               Arithmetic.runDiv,
+    "Mean":                 Arithmetic.runMean,
+    "Median":               Arithmetic.runMedian,
+    "Standard Deviation":   Arithmetic.runStdDev,
 
 
 
 
     /*
     /*

+ 3 - 1
src/core/config/modules/OpModules.js

@@ -19,6 +19,7 @@ import ImageModule from "./Image.js";
 import JSBNModule from "./JSBN.js";
 import JSBNModule from "./JSBN.js";
 import PublicKeyModule from "./PublicKey.js";
 import PublicKeyModule from "./PublicKey.js";
 import ShellcodeModule from "./Shellcode.js";
 import ShellcodeModule from "./Shellcode.js";
+import URLModule from "./URL.js";
 
 
 Object.assign(
 Object.assign(
     OpModules,
     OpModules,
@@ -33,7 +34,8 @@ Object.assign(
     ImageModule,
     ImageModule,
     JSBNModule,
     JSBNModule,
     PublicKeyModule,
     PublicKeyModule,
-    ShellcodeModule
+    ShellcodeModule,
+    URLModule
 );
 );
 
 
 export default OpModules;
 export default OpModules;

+ 23 - 0
src/core/config/modules/URL.js

@@ -0,0 +1,23 @@
+import URL_ from "../../operations/URL.js";
+
+
+/**
+ * URL module.
+ *
+ * Libraries:
+ *  - Utils.js
+ *  - url
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+let OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.URL = {
+    "URL Encode": URL_.runTo,
+    "URL Decode": URL_.runFrom,
+    "Parse URI":  URL_.runParse,
+};
+
+export default OpModules;

+ 253 - 0
src/core/operations/Arithmetic.js

@@ -0,0 +1,253 @@
+import Utils from "../Utils.js";
+import BigNumber from "bignumber.js";
+
+
+/**
+ * Math operations on numbers.
+ *
+ * @author bwhitn [brian.m.whitney@outlook.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const Arithmetic = {
+
+    /**
+     * @constant
+     * @default
+     */
+    DELIM_OPTIONS: ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"],
+
+
+    /**
+     * Splits a string based on a delimiter and calculates the sum of numbers.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {BigNumber}
+     */
+    runSum: function(input, args) {
+        const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0]));
+        return val instanceof BigNumber ? val : new BigNumber(NaN);
+    },
+
+
+    /**
+     * Splits a string based on a delimiter and subtracts all the numbers.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {BigNumber}
+     */
+    runSub: function(input, args) {
+        let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0]));
+        return val instanceof BigNumber ? val : new BigNumber(NaN);
+    },
+
+
+    /**
+     * Splits a string based on a delimiter and multiplies the numbers.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {BigNumber}
+     */
+    runMulti: function(input, args) {
+        let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0]));
+        return val instanceof BigNumber ? val : new BigNumber(NaN);
+    },
+
+
+    /**
+     * Splits a string based on a delimiter and divides the numbers.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {BigNumber}
+     */
+    runDiv: function(input, args) {
+        let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0]));
+        return val instanceof BigNumber ? val : new BigNumber(NaN);
+    },
+
+
+    /**
+     * Splits a string based on a delimiter and computes the mean (average).
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {BigNumber}
+     */
+    runMean: function(input, args) {
+        let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0]));
+        return val instanceof BigNumber ? val : new BigNumber(NaN);
+    },
+
+
+    /**
+     * Splits a string based on a delimiter and finds the median.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {BigNumber}
+     */
+    runMedian: function(input, args) {
+        let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0]));
+        return val instanceof BigNumber ? val : new BigNumber(NaN);
+    },
+
+
+    /**
+     * splits a string based on a delimiter and computes the standard deviation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {BigNumber}
+     */
+    runStdDev: function(input, args) {
+        let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0]));
+        return val instanceof BigNumber ? val : new BigNumber(NaN);
+    },
+
+
+    /**
+     * Converts a string array to a number array.
+     *
+     * @private
+     * @param {string[]} input
+     * @param {string} delim
+     * @returns {BigNumber[]}
+     */
+    _createNumArray: function(input, delim) {
+        delim = Utils.charRep[delim || "Space"];
+        let splitNumbers = input.split(delim),
+            numbers = [],
+            num;
+
+        for (let i = 0; i < splitNumbers.length; i++) {
+            try {
+                num = BigNumber(splitNumbers[i].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.
+     *
+     * @private
+     * @param {BigNumber[]} data
+     * @returns {BigNumber}
+     */
+    _sum: function(data) {
+        if (data.length > 0) {
+            return data.reduce((acc, curr) => acc.plus(curr));
+        }
+    },
+
+
+    /**
+     * Subtracts an array of numbers and returns the value.
+     *
+     * @private
+     * @param {BigNumber[]} data
+     * @returns {BigNumber}
+     */
+    _sub: function(data) {
+        if (data.length > 0) {
+            return data.reduce((acc, curr) => acc.minus(curr));
+        }
+    },
+
+
+    /**
+     * Multiplies an array of numbers and returns the value.
+     *
+     * @private
+     * @param {BigNumber[]} data
+     * @returns {BigNumber}
+     */
+    _multi: function(data) {
+        if (data.length > 0) {
+            return data.reduce((acc, curr) => acc.times(curr));
+        }
+    },
+
+
+    /**
+     * Divides an array of numbers and returns the value.
+     *
+     * @private
+     * @param {BigNumber[]} data
+     * @returns {BigNumber}
+     */
+    _div: function(data) {
+        if (data.length > 0) {
+            return data.reduce((acc, curr) => acc.div(curr));
+        }
+    },
+
+
+    /**
+     * Computes mean of a number array and returns the value.
+     *
+     * @private
+     * @param {BigNumber[]} data
+     * @returns {BigNumber}
+     */
+    _mean: function(data) {
+        if (data.length > 0) {
+            return Arithmetic._sum(data).div(data.length);
+        }
+    },
+
+
+    /**
+     * Computes median of a number array and returns the value.
+     *
+     * @private
+     * @param {BigNumber[]} data
+     * @returns {BigNumber}
+     */
+    _median: function (data) {
+        if ((data.length % 2) === 0 && data.length > 0) {
+            let first, second;
+            data.sort(function(a, b){
+                return a.minus(b);
+            });
+            first = data[Math.floor(data.length / 2)];
+            second = data[Math.floor(data.length / 2) - 1];
+            return Arithmetic._mean([first, second]);
+        } else {
+            return data[Math.floor(data.length / 2)];
+        }
+    },
+
+
+    /**
+     * Computes standard deviation of a number array and returns the value.
+     *
+     * @private
+     * @param {BigNumber[]} data
+     * @returns {BigNumber}
+     */
+    _stdDev: function (data) {
+        if (data.length > 0) {
+            let avg = Arithmetic._mean(data);
+            let devSum = new BigNumber(0);
+            for (let i = 0; i < data.length; i++) {
+                devSum = devSum.plus(data[i].minus(avg).pow(2));
+            }
+            return devSum.div(data.length).sqrt();
+        }
+    },
+};
+
+export default Arithmetic;

+ 9 - 8
src/core/operations/BCD.js

@@ -1,4 +1,5 @@
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
+import BigNumber from "bignumber.js";
 
 
 
 
 /**
 /**
@@ -61,14 +62,14 @@ const BCD = {
     /**
     /**
      * To BCD operation.
      * To BCD operation.
      *
      *
-     * @param {number} input
+     * @param {BigNumber} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runToBCD: function(input, args) {
     runToBCD: function(input, args) {
-        if (isNaN(input))
+        if (input.isNaN())
             return "Invalid input";
             return "Invalid input";
-        if (Math.floor(input) !== input)
+        if (!input.floor().equals(input))
             return "Fractional values are not supported by BCD";
             return "Fractional values are not supported by BCD";
 
 
         const encoding = BCD.ENCODING_LOOKUP[args[0]],
         const encoding = BCD.ENCODING_LOOKUP[args[0]],
@@ -77,7 +78,7 @@ const BCD = {
             outputFormat = args[3];
             outputFormat = args[3];
 
 
         // Split input number up into separate digits
         // Split input number up into separate digits
-        const digits = input.toString().split("");
+        const digits = input.toFixed().split("");
 
 
         if (digits[0] === "-" || digits[0] === "+") {
         if (digits[0] === "-" || digits[0] === "+") {
             digits.shift();
             digits.shift();
@@ -134,11 +135,11 @@ const BCD = {
         switch (outputFormat) {
         switch (outputFormat) {
             case "Nibbles":
             case "Nibbles":
                 return nibbles.map(n => {
                 return nibbles.map(n => {
-                    return Utils.padLeft(n.toString(2), 4);
+                    return n.toString(2).padStart(4, "0");
                 }).join(" ");
                 }).join(" ");
             case "Bytes":
             case "Bytes":
                 return bytes.map(b => {
                 return bytes.map(b => {
-                    return Utils.padLeft(b.toString(2), 8);
+                    return b.toString(2).padStart(8, "0");
                 }).join(" ");
                 }).join(" ");
             case "Raw":
             case "Raw":
             default:
             default:
@@ -152,7 +153,7 @@ const BCD = {
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {number}
+     * @returns {BigNumber}
      */
      */
     runFromBCD: function(input, args) {
     runFromBCD: function(input, args) {
         const encoding = BCD.ENCODING_LOOKUP[args[0]],
         const encoding = BCD.ENCODING_LOOKUP[args[0]],
@@ -206,7 +207,7 @@ const BCD = {
             output += val.toString();
             output += val.toString();
         });
         });
 
 
-        return parseInt(output, 10);
+        return new BigNumber(output);
     },
     },
 
 
 };
 };

+ 7 - 5
src/core/operations/Base.js

@@ -1,3 +1,5 @@
+import BigNumber from "bignumber.js";
+
 /**
 /**
  * Numerical base operations.
  * Numerical base operations.
  *
  *
@@ -18,7 +20,7 @@ const Base = {
     /**
     /**
      * To Base operation.
      * To Base operation.
      *
      *
-     * @param {number} input
+     * @param {BigNumber} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
@@ -39,7 +41,7 @@ const Base = {
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {number}
+     * @returns {BigNumber}
      */
      */
     runFrom: function(input, args) {
     runFrom: function(input, args) {
         const radix = args[0] || Base.DEFAULT_RADIX;
         const radix = args[0] || Base.DEFAULT_RADIX;
@@ -48,14 +50,14 @@ const Base = {
         }
         }
 
 
         let number = input.replace(/\s/g, "").split("."),
         let number = input.replace(/\s/g, "").split("."),
-            result = parseInt(number[0], radix) || 0;
+            result = new BigNumber(number[0], radix) || 0;
 
 
         if (number.length === 1) return result;
         if (number.length === 1) return result;
 
 
         // Fractional part
         // Fractional part
         for (let i = 0; i < number[1].length; i++) {
         for (let i = 0; i < number[1].length; i++) {
-            const digit = parseInt(number[1][i], radix);
-            result += digit / Math.pow(radix, i+1);
+            const digit = new BigNumber(number[1][i], radix);
+            result += digit.div(Math.pow(radix, i+1));
         }
         }
 
 
         return result;
         return result;

+ 2 - 2
src/core/operations/Base64.js

@@ -40,13 +40,13 @@ const Base64 = {
     /**
     /**
      * To Base64 operation.
      * To Base64 operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runTo: function(input, args) {
     runTo: function(input, args) {
         const alphabet = args[0] || Base64.ALPHABET;
         const alphabet = args[0] || Base64.ALPHABET;
-        return Utils.toBase64(input, alphabet);
+        return Utils.toBase64(new Uint8Array(input), alphabet);
     },
     },
 
 
 
 

+ 6 - 12
src/core/operations/BitwiseOp.js

@@ -67,7 +67,7 @@ const BitwiseOp = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    KEY_FORMAT: ["Hex", "Base64", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1"],
+    KEY_FORMAT: ["Hex", "Base64", "UTF8", "Latin1"],
 
 
     /**
     /**
      * XOR operation.
      * XOR operation.
@@ -77,12 +77,10 @@ const BitwiseOp = {
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
     runXor: function (input, args) {
     runXor: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || ""),
+        const key = Utils.convertToByteArray(args[0].string || "", args[0].option),
             scheme = args[1],
             scheme = args[1],
             nullPreserving = args[2];
             nullPreserving = args[2];
 
 
-        key = Utils.wordArrayToByteArray(key);
-
         return BitwiseOp._bitOp(input, key, BitwiseOp._xor, nullPreserving, scheme);
         return BitwiseOp._bitOp(input, key, BitwiseOp._xor, nullPreserving, scheme);
     },
     },
 
 
@@ -200,8 +198,7 @@ const BitwiseOp = {
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
     runAnd: function (input, args) {
     runAnd: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
+        const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
 
 
         return BitwiseOp._bitOp(input, key, BitwiseOp._and);
         return BitwiseOp._bitOp(input, key, BitwiseOp._and);
     },
     },
@@ -215,8 +212,7 @@ const BitwiseOp = {
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
     runOr: function (input, args) {
     runOr: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
+        const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
 
 
         return BitwiseOp._bitOp(input, key, BitwiseOp._or);
         return BitwiseOp._bitOp(input, key, BitwiseOp._or);
     },
     },
@@ -230,8 +226,7 @@ const BitwiseOp = {
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
     runAdd: function (input, args) {
     runAdd: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
+        const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
 
 
         return BitwiseOp._bitOp(input, key, BitwiseOp._add);
         return BitwiseOp._bitOp(input, key, BitwiseOp._add);
     },
     },
@@ -245,8 +240,7 @@ const BitwiseOp = {
      * @returns {byteArray}
      * @returns {byteArray}
      */
      */
     runSub: function (input, args) {
     runSub: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || "");
-        key = Utils.wordArrayToByteArray(key);
+        const key = Utils.convertToByteArray(args[0].string || "", args[0].option);
 
 
         return BitwiseOp._bitOp(input, key, BitwiseOp._sub);
         return BitwiseOp._bitOp(input, key, BitwiseOp._sub);
     },
     },

+ 4 - 4
src/core/operations/ByteRepr.js

@@ -31,13 +31,13 @@ const ByteRepr = {
     /**
     /**
      * To Hex operation.
      * To Hex operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runToHex: function(input, args) {
     runToHex: function(input, args) {
         const delim = Utils.charRep[args[0] || "Space"];
         const delim = Utils.charRep[args[0] || "Space"];
-        return Utils.toHex(input, delim, 2);
+        return Utils.toHex(new Uint8Array(input), delim, 2);
     },
     },
 
 
 
 
@@ -186,7 +186,7 @@ const ByteRepr = {
         // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
         // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
         if (delim === "0x" || delim === "\\x") {
         if (delim === "0x" || delim === "\\x") {
             pos[0].start += 2;
             pos[0].start += 2;
-            pos[0].end   += 2;
+            pos[0].end += 2;
         }
         }
         return pos;
         return pos;
     },
     },
@@ -266,7 +266,7 @@ const ByteRepr = {
             padding = 8;
             padding = 8;
 
 
         for (let i = 0; i < input.length; i++) {
         for (let i = 0; i < input.length; i++) {
-            output += Utils.pad(input[i].toString(2), padding) + delim;
+            output += input[i].toString(2).padStart(padding, "0") + delim;
         }
         }
 
 
         if (delim.length) {
         if (delim.length) {

+ 373 - 173
src/core/operations/Cipher.js

@@ -1,6 +1,8 @@
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
 import CryptoJS from "crypto-js";
 import CryptoJS from "crypto-js";
+import forge from "imports-loader?jQuery=>null!node-forge/dist/forge.min.js";
 import {blowfish as Blowfish} from "sladex-blowfish";
 import {blowfish as Blowfish} from "sladex-blowfish";
+import BigNumber from "bignumber.js";
 
 
 
 
 /**
 /**
@@ -18,156 +20,121 @@ const Cipher = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    IO_FORMAT1: ["Hex", "Base64", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1"],
+    IO_FORMAT1: ["Hex", "UTF8", "Latin1", "Base64"],
     /**
     /**
-     * @constant
-     * @default
-     */
-    IO_FORMAT2: ["UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1", "Hex", "Base64"],
+    * @constant
+    * @default
+    */
+    IO_FORMAT2: ["UTF8", "Latin1", "Hex", "Base64"],
     /**
     /**
-     * @constant
-     * @default
-     */
-    IO_FORMAT3: ["Hex", "Base64", "UTF16", "UTF16LE", "UTF16BE", "Latin1"],
+    * @constant
+    * @default
+    */
+    IO_FORMAT3: ["Raw", "Hex"],
     /**
     /**
-     * @constant
-     * @default
-     */
-    IO_FORMAT4: ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"],
+    * @constant
+    * @default
+    */
+    IO_FORMAT4: ["Hex", "Raw"],
     /**
     /**
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    MODES: ["CBC", "CFB", "CTR", "OFB", "ECB"],
-    /**
-     * @constant
-     * @default
-     */
-    PADDING: ["Pkcs7", "Iso97971", "AnsiX923", "Iso10126", "ZeroPadding", "NoPadding"],
-    /**
-     * @constant
-     * @default
-     */
-    RESULT_TYPE: ["Show all", "Ciphertext", "Key", "IV", "Salt"],
-
+    AES_MODES: ["CBC", "CFB", "OFB", "CTR", "GCM", "ECB"],
 
 
     /**
     /**
-     * Runs encryption operations using the CryptoJS framework.
+     * AES Encrypt operation.
      *
      *
-     * @private
-     * @param {function} algo - The CryptoJS algorithm to use
-     * @param {byteArray} input
-     * @param {function} args
+     * @param {string} input
+     * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    _enc: function (algo, input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || ""),
-            iv = Utils.format[args[1].option].parse(args[1].string || ""),
-            salt = Utils.format[args[2].option].parse(args[2].string || ""),
-            mode = CryptoJS.mode[args[3]],
-            padding = CryptoJS.pad[args[4]],
-            resultOption = args[5].toLowerCase(),
-            outputFormat = args[6];
-
-        if (iv.sigBytes === 0) {
-            // Use passphrase rather than key. Need to convert it to a string.
-            key = key.toString(CryptoJS.enc.Latin1);
+    runAesEnc: function (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) {
+            return `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`;
         }
         }
 
 
-        const encrypted = algo.encrypt(input, key, {
-            salt: salt.sigBytes > 0 ? salt : false,
-            iv: iv.sigBytes > 0 ? iv : null,
-            mode: mode,
-            padding: padding
-        });
+        input = Utils.convertToByteString(input, inputType);
 
 
-        let result = "";
-        if (resultOption === "show all") {
-            result += "Key:  " + encrypted.key.toString(Utils.format[outputFormat]);
-            result += "\nIV:   " + encrypted.iv.toString(Utils.format[outputFormat]);
-            if (encrypted.salt) result += "\nSalt: " + encrypted.salt.toString(Utils.format[outputFormat]);
-            result += "\n\nCiphertext: " + encrypted.ciphertext.toString(Utils.format[outputFormat]);
+        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 {
         } else {
-            result = encrypted[resultOption].toString(Utils.format[outputFormat]);
+            if (mode === "GCM") {
+                return cipher.output.getBytes() + "\n\n" +
+                    "Tag: " + cipher.mode.tag.getBytes();
+            }
+            return cipher.output.getBytes();
         }
         }
-
-        return result;
     },
     },
 
 
 
 
     /**
     /**
-     * Runs decryption operations using the CryptoJS framework.
+     * AES Decrypt operation.
      *
      *
-     * @private
-     * @param {function} algo - The CryptoJS algorithm to use
-     * @param {byteArray} input
-     * @param {function} args
+     * @param {string} input
+     * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    _dec: function (algo, input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string || ""),
-            iv = Utils.format[args[1].option].parse(args[1].string || ""),
-            salt = Utils.format[args[2].option].parse(args[2].string || ""),
-            mode = CryptoJS.mode[args[3]],
-            padding = CryptoJS.pad[args[4]],
-            inputFormat = args[5],
-            outputFormat = args[6];
-
-        // The ZeroPadding option causes a crash when the input length is 0
-        if (!input.length) {
-            return "No input";
+    runAesDec: function (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) {
+            return `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`;
         }
         }
 
 
-        const ciphertext = Utils.format[inputFormat].parse(input);
+        input = Utils.convertToByteString(input, inputType);
 
 
-        if (iv.sigBytes === 0) {
-            // Use passphrase rather than key. Need to convert it to a string.
-            key = key.toString(CryptoJS.enc.Latin1);
-        }
-
-        const decrypted = algo.decrypt({
-            ciphertext: ciphertext,
-            salt: salt.sigBytes > 0 ? salt : false
-        }, key, {
-            iv: iv.sigBytes > 0 ? iv : null,
-            mode: mode,
-            padding: padding
+        const decipher = forge.cipher.createDecipher("AES-" + mode, key);
+        decipher.start({
+            iv: iv,
+            tag: gcmTag
         });
         });
+        decipher.update(forge.util.createBuffer(input));
+        const result = decipher.finish();
 
 
-        let result;
-        try {
-            result = decrypted.toString(Utils.format[outputFormat]);
-        } catch (err) {
-            result = "Decrypt error: " + err.message;
+        if (result) {
+            return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
+        } else {
+            return "Unable to decrypt input with these parameters.";
         }
         }
-
-        return result;
-    },
-
-
-    /**
-     * AES Encrypt operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runAesEnc: function (input, args) {
-        return Cipher._enc(CryptoJS.AES, input, args);
     },
     },
 
 
 
 
     /**
     /**
-     * AES Decrypt operation.
-     *
-     * @param {string} input
-     * @param {Object[]} args
-     * @returns {string}
+     * @constant
+     * @default
      */
      */
-    runAesDec: function (input, args) {
-        return Cipher._dec(CryptoJS.AES, input, args);
-    },
-
+    DES_MODES: ["CBC", "CFB", "OFB", "CTR", "ECB"],
 
 
     /**
     /**
      * DES Encrypt operation.
      * DES Encrypt operation.
@@ -177,7 +144,27 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runDesEnc: function (input, args) {
     runDesEnc: function (input, args) {
-        return Cipher._enc(CryptoJS.DES, input, args);
+        const key = Utils.convertToByteString(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 (key.length !== 8) {
+            return `Invalid key length: ${key.length} bytes
+
+DES uses a key length of 8 bytes (64 bits).
+Triple DES uses a key length of 24 bytes (192 bits).`;
+        }
+
+        input = Utils.convertToByteString(input, inputType);
+
+        const cipher = forge.cipher.createCipher("DES-" + mode, key);
+        cipher.start({iv: iv});
+        cipher.update(forge.util.createBuffer(input));
+        cipher.finish();
+
+        return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes();
     },
     },
 
 
 
 
@@ -189,7 +176,31 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runDesDec: function (input, args) {
     runDesDec: function (input, args) {
-        return Cipher._dec(CryptoJS.DES, input, args);
+        const key = Utils.convertToByteString(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 (key.length !== 8) {
+            return `Invalid key length: ${key.length} bytes
+
+DES uses a key length of 8 bytes (64 bits).
+Triple DES uses a key length of 24 bytes (192 bits).`;
+        }
+
+        input = Utils.convertToByteString(input, inputType);
+
+        const decipher = forge.cipher.createDecipher("DES-" + mode, key);
+        decipher.start({iv: iv});
+        decipher.update(forge.util.createBuffer(input));
+        const result = decipher.finish();
+
+        if (result) {
+            return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
+        } else {
+            return "Unable to decrypt input with these parameters.";
+        }
     },
     },
 
 
 
 
@@ -201,7 +212,27 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runTripleDesEnc: function (input, args) {
     runTripleDesEnc: function (input, args) {
-        return Cipher._enc(CryptoJS.TripleDES, input, args);
+        const key = Utils.convertToByteString(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 (key.length !== 24) {
+            return `Invalid key length: ${key.length} bytes
+
+Triple DES uses a key length of 24 bytes (192 bits).
+DES uses a key length of 8 bytes (64 bits).`;
+        }
+
+        input = Utils.convertToByteString(input, inputType);
+
+        const cipher = forge.cipher.createCipher("3DES-" + mode, key);
+        cipher.start({iv: iv});
+        cipher.update(forge.util.createBuffer(input));
+        cipher.finish();
+
+        return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes();
     },
     },
 
 
 
 
@@ -213,31 +244,79 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runTripleDesDec: function (input, args) {
     runTripleDesDec: function (input, args) {
-        return Cipher._dec(CryptoJS.TripleDES, input, args);
+        const key = Utils.convertToByteString(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 (key.length !== 24) {
+            return `Invalid key length: ${key.length} bytes
+
+Triple DES uses a key length of 24 bytes (192 bits).
+DES uses a key length of 8 bytes (64 bits).`;
+        }
+
+        input = Utils.convertToByteString(input, inputType);
+
+        const decipher = forge.cipher.createDecipher("3DES-" + mode, key);
+        decipher.start({iv: iv});
+        decipher.update(forge.util.createBuffer(input));
+        const result = decipher.finish();
+
+        if (result) {
+            return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
+        } else {
+            return "Unable to decrypt input with these parameters.";
+        }
     },
     },
 
 
 
 
     /**
     /**
-     * Rabbit Encrypt operation.
+     * RC2 Encrypt operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runRabbitEnc: function (input, args) {
-        return Cipher._enc(CryptoJS.Rabbit, input, args);
+    runRc2Enc: function (input, args) {
+        const key = Utils.convertToByteString(args[0].string, args[0].option),
+            iv = Utils.convertToByteString(args[1].string, args[1].option),
+            inputType = args[2],
+            outputType = args[3],
+            cipher = forge.rc2.createEncryptionCipher(key);
+
+        input = Utils.convertToByteString(input, inputType);
+
+        cipher.start(iv || null);
+        cipher.update(forge.util.createBuffer(input));
+        cipher.finish();
+
+        return outputType === "Hex" ? cipher.output.toHex() : cipher.output.getBytes();
     },
     },
 
 
 
 
     /**
     /**
-     * Rabbit Decrypt operation.
+     * RC2 Decrypt operation.
      *
      *
      * @param {string} input
      * @param {string} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
-    runRabbitDec: function (input, args) {
-        return Cipher._dec(CryptoJS.Rabbit, input, args);
+    runRc2Dec: function (input, args) {
+        const key = Utils.convertToByteString(args[0].string, args[0].option),
+            iv = Utils.convertToByteString(args[1].string, args[1].option),
+            inputType = args[2],
+            outputType = args[3],
+            decipher = forge.rc2.createDecryptionCipher(key);
+
+        input = Utils.convertToByteString(input, inputType);
+
+        decipher.start(iv || null);
+        decipher.update(forge.util.createBuffer(input));
+        decipher.finish();
+
+        return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
     },
     },
 
 
 
 
@@ -245,12 +324,29 @@ const Cipher = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    BLOWFISH_MODES: ["ECB", "CBC", "PCBC", "CFB", "OFB", "CTR"],
+    BLOWFISH_MODES: ["CBC", "PCBC", "CFB", "OFB", "CTR", "ECB"],
     /**
     /**
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    BLOWFISH_OUTPUT_TYPES: ["Base64", "Hex", "String", "Raw"],
+    BLOWFISH_OUTPUT_TYPES: ["Hex", "Base64", "Raw"],
+
+    /**
+     * Lookup table for Blowfish output types.
+     *
+     * @private
+     */
+    _BLOWFISH_OUTPUT_TYPE_LOOKUP: {
+        Base64: 0, Hex: 1, String: 2, Raw: 3
+    },
+    /**
+     * Lookup table for Blowfish modes.
+     *
+     * @private
+     */
+    _BLOWFISH_MODE_LOOKUP: {
+        ECB: 0, CBC: 1, PCBC: 2, CFB: 3, OFB: 4, CTR: 5
+    },
 
 
     /**
     /**
      * Blowfish Encrypt operation.
      * Blowfish Encrypt operation.
@@ -260,19 +356,24 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runBlowfishEnc: function (input, args) {
     runBlowfishEnc: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
-            mode = args[1],
-            outputFormat = args[2];
+        const key = Utils.convertToByteString(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 (key.length === 0) return "Enter a key";
         if (key.length === 0) return "Enter a key";
 
 
-        let encHex = Blowfish.encrypt(input, key, {
-                outputType: 1,
-                cipherMode: Cipher.BLOWFISH_MODES.indexOf(mode)
-            }),
-            enc = CryptoJS.enc.Hex.parse(encHex);
+        input = Utils.convertToByteString(input, inputType);
 
 
-        return enc.toString(Utils.format[outputFormat]);
+        Blowfish.setIV(Utils.toBase64(iv), 0);
+
+        const enc = Blowfish.encrypt(input, key, {
+            outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[outputType],
+            cipherMode: Cipher._BLOWFISH_MODE_LOOKUP[mode]
+        });
+
+        return outputType === "Raw" ? Utils.byteArrayToChars(enc) : enc   ;
     },
     },
 
 
 
 
@@ -284,18 +385,24 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runBlowfishDec: function (input, args) {
     runBlowfishDec: function (input, args) {
-        let key = Utils.format[args[0].option].parse(args[0].string).toString(Utils.format.Latin1),
-            mode = args[1],
-            inputFormat = args[2];
+        const key = Utils.convertToByteString(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 (key.length === 0) return "Enter a key";
         if (key.length === 0) return "Enter a key";
 
 
-        input = Utils.format[inputFormat].parse(input);
+        input = inputType === "Raw" ? Utils.strToByteArray(input) : input;
 
 
-        return Blowfish.decrypt(input.toString(CryptoJS.enc.Base64), key, {
-            outputType: 0, // This actually means inputType. The library is weird.
-            cipherMode: Cipher.BLOWFISH_MODES.indexOf(mode)
+        Blowfish.setIV(Utils.toBase64(iv), 0);
+
+        const result = Blowfish.decrypt(input, key, {
+            outputType: Cipher._BLOWFISH_OUTPUT_TYPE_LOOKUP[inputType], // This actually means inputType. The library is weird.
+            cipherMode: Cipher._BLOWFISH_MODE_LOOKUP[mode]
         });
         });
+
+        return outputType === "Hex" ? Utils.toHexFast(Utils.strToByteArray(result)) : result;
     },
     },
 
 
 
 
@@ -303,7 +410,7 @@ const Cipher = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    KDF_KEY_SIZE: 256,
+    KDF_KEY_SIZE: 128,
     /**
     /**
      * @constant
      * @constant
      * @default
      * @default
@@ -313,7 +420,7 @@ const Cipher = {
      * @constant
      * @constant
      * @default
      * @default
      */
      */
-    HASHERS: ["MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "RIPEMD160"],
+    HASHERS: ["SHA1", "SHA256", "SHA384", "SHA512", "MD5"],
 
 
     /**
     /**
      * Derive PBKDF2 key operation.
      * Derive PBKDF2 key operation.
@@ -323,20 +430,15 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runPbkdf2: function (input, args) {
     runPbkdf2: function (input, args) {
-        let keySize = args[0] / 32,
-            iterations = args[1],
-            hasher = args[2],
-            salt = CryptoJS.enc.Hex.parse(args[3] || ""),
-            inputFormat = args[4],
-            outputFormat = args[5],
-            passphrase = Utils.format[inputFormat].parse(input),
-            key = CryptoJS.PBKDF2(passphrase, salt, {
-                keySize: keySize,
-                hasher: CryptoJS.algo[hasher],
-                iterations: iterations,
-            });
-
-        return key.toString(Utils.format[outputFormat]);
+        const passphrase = Utils.convertToByteString(args[0].string, args[0].option),
+            keySize = args[1],
+            iterations = args[2],
+            hasher = args[3],
+            salt = Utils.convertToByteString(args[4].string, args[4].option) ||
+                forge.random.getBytesSync(keySize),
+            derivedKey = forge.pkcs5.pbkdf2(passphrase, salt, iterations, keySize / 8, hasher.toLowerCase());
+
+        return forge.util.bytesToHex(derivedKey);
     },
     },
 
 
 
 
@@ -348,23 +450,33 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runEvpkdf: function (input, args) {
     runEvpkdf: function (input, args) {
-        let keySize = args[0] / 32,
-            iterations = args[1],
-            hasher = args[2],
-            salt = CryptoJS.enc.Hex.parse(args[3] || ""),
-            inputFormat = args[4],
-            outputFormat = args[5],
-            passphrase = Utils.format[inputFormat].parse(input),
+        const passphrase = Utils.convertToByteString(args[0].string, args[0].option),
+            keySize = args[1] / 32,
+            iterations = args[2],
+            hasher = args[3],
+            salt = Utils.convertToByteString(args[4].string, args[4].option),
             key = CryptoJS.EvpKDF(passphrase, salt, {
             key = CryptoJS.EvpKDF(passphrase, salt, {
                 keySize: keySize,
                 keySize: keySize,
                 hasher: CryptoJS.algo[hasher],
                 hasher: CryptoJS.algo[hasher],
                 iterations: iterations,
                 iterations: iterations,
             });
             });
 
 
-        return key.toString(Utils.format[outputFormat]);
+        return key.toString(CryptoJS.enc.Hex);
     },
     },
 
 
 
 
+    /**
+     * @constant
+     * @default
+     */
+    RC4_KEY_FORMAT: ["UTF8", "UTF16", "UTF16LE", "UTF16BE", "Latin1", "Hex", "Base64"],
+    /**
+     * @constant
+     * @default
+     */
+    CJS_IO_FORMAT: ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"],
+
+
     /**
     /**
      * RC4 operation.
      * RC4 operation.
      *
      *
@@ -373,11 +485,11 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runRc4: function (input, args) {
     runRc4: function (input, args) {
-        let message = Utils.format[args[1]].parse(input),
-            passphrase = Utils.format[args[0].option].parse(args[0].string),
+        let message = Cipher._format[args[1]].parse(input),
+            passphrase = Cipher._format[args[0].option].parse(args[0].string),
             encrypted = CryptoJS.RC4.encrypt(message, passphrase);
             encrypted = CryptoJS.RC4.encrypt(message, passphrase);
 
 
-        return encrypted.ciphertext.toString(Utils.format[args[2]]);
+        return encrypted.ciphertext.toString(Cipher._format[args[2]]);
     },
     },
 
 
 
 
@@ -395,12 +507,59 @@ const Cipher = {
      * @returns {string}
      * @returns {string}
      */
      */
     runRc4drop: function (input, args) {
     runRc4drop: function (input, args) {
-        let message = Utils.format[args[1]].parse(input),
-            passphrase = Utils.format[args[0].option].parse(args[0].string),
+        let message = Cipher._format[args[1]].parse(input),
+            passphrase = Cipher._format[args[0].option].parse(args[0].string),
             drop = args[3],
             drop = args[3],
             encrypted = CryptoJS.RC4Drop.encrypt(message, passphrase, { drop: drop });
             encrypted = CryptoJS.RC4Drop.encrypt(message, passphrase, { drop: drop });
 
 
-        return encrypted.ciphertext.toString(Utils.format[args[2]]);
+        return encrypted.ciphertext.toString(Cipher._format[args[2]]);
+    },
+
+
+    /**
+     * @constant
+     * @default
+     */
+    PRNG_BYTES: 32,
+    PRNG_OUTPUT: ["Hex", "Integer", "Byte array", "Raw"],
+
+    /**
+     * Pseudo-Random Number Generator operation.
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runPRNG: function(input, args) {
+        const numBytes = args[0],
+            outputAs = args[1];
+
+        let bytes;
+
+        if (ENVIRONMENT_IS_WORKER() && self.crypto) {
+            bytes = self.crypto.getRandomValues(new Uint8Array(numBytes));
+            bytes = Utils.arrayBufferToStr(bytes.buffer);
+        } else {
+            bytes = forge.random.getBytesSync(numBytes);
+        }
+
+        let value = new BigNumber(0),
+            i;
+
+        switch (outputAs) {
+            case "Hex":
+                return forge.util.bytesToHex(bytes);
+            case "Integer":
+                for (i = bytes.length - 1; i >= 0; i--) {
+                    value = value.mul(256).plus(bytes.charCodeAt(i));
+                }
+                return value.toFixed();
+            case "Byte array":
+                return JSON.stringify(Utils.strToCharcode(bytes));
+            case "Raw":
+            default:
+                return bytes;
+        }
     },
     },
 
 
 
 
@@ -783,6 +942,23 @@ const Cipher = {
         return output;
         return output;
     },
     },
 
 
+
+    /**
+     * A mapping of string formats to their classes in the CryptoJS library.
+     *
+     * @private
+     * @constant
+     */
+    _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,
+    },
+
 };
 };
 
 
 export default Cipher;
 export default Cipher;
@@ -827,3 +1003,27 @@ CryptoJS.kdf.OpenSSL.execute = function (password, keySize, ivSize, salt) {
     // Return params
     // Return params
     return CryptoJS.lib.CipherParams.create({ key: key, iv: iv, salt: salt });
     return CryptoJS.lib.CipherParams.create({ key: key, iv: iv, salt: salt });
 };
 };
+
+
+/**
+ * Override for the CryptoJS Hex encoding parser to remove whitespace before attempting to parse
+ * the hex string.
+ *
+ * @param {string} hexStr
+ * @returns {CryptoJS.lib.WordArray}
+ */
+CryptoJS.enc.Hex.parse = function (hexStr) {
+    // Remove whitespace
+    hexStr = hexStr.replace(/\s/g, "");
+
+    // Shortcut
+    const hexStrLength = hexStr.length;
+
+    // Convert
+    const words = [];
+    for (let i = 0; i < hexStrLength; i += 2) {
+        words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
+    }
+
+    return new CryptoJS.lib.WordArray.init(words, hexStrLength / 2);
+};

+ 16 - 15
src/core/operations/Code.js

@@ -2,9 +2,10 @@ import {camelCase, kebabCase, snakeCase} from "lodash";
 
 
 import Utils from "../Utils.js";
 import Utils from "../Utils.js";
 import vkbeautify from "vkbeautify";
 import vkbeautify from "vkbeautify";
-import {DOMParser as dom} from "xmldom";
+import {DOMParser} from "xmldom";
 import xpath from "xpath";
 import xpath from "xpath";
 import jpath from "jsonpath";
 import jpath from "jsonpath";
+import nwmatcher from "nwmatcher";
 import prettyPrintOne from "imports-loader?window=>global!exports-loader?prettyPrintOne!google-code-prettify/bin/prettify.min.js";
 import prettyPrintOne from "imports-loader?window=>global!exports-loader?prettyPrintOne!google-code-prettify/bin/prettify.min.js";
 
 
 
 
@@ -336,7 +337,7 @@ const Code = {
 
 
         let doc;
         let doc;
         try {
         try {
-            doc = new dom().parseFromString(input);
+            doc = new DOMParser().parseFromString(input, "application/xml");
         } catch (err) {
         } catch (err) {
             return "Invalid input XML.";
             return "Invalid input XML.";
         }
         }
@@ -423,7 +424,7 @@ const Code = {
         let query = args[0],
         let query = args[0],
             delimiter = args[1],
             delimiter = args[1],
             parser = new DOMParser(),
             parser = new DOMParser(),
-            html,
+            dom,
             result;
             result;
 
 
         if (!query.length || !input.length) {
         if (!query.length || !input.length) {
@@ -431,32 +432,32 @@ const Code = {
         }
         }
 
 
         try {
         try {
-            html = parser.parseFromString(input, "text/html");
+            dom = parser.parseFromString(input);
         } catch (err) {
         } catch (err) {
             return "Invalid input HTML.";
             return "Invalid input HTML.";
         }
         }
 
 
         try {
         try {
-            result = html.querySelectorAll(query);
+            const matcher = nwmatcher({document: dom});
+            result = matcher.select(query, dom);
         } catch (err) {
         } catch (err) {
             return "Invalid CSS Selector. Details:\n" + err.message;
             return "Invalid CSS Selector. Details:\n" + err.message;
         }
         }
 
 
         const nodeToString = function(node) {
         const nodeToString = function(node) {
+            return node.toString();
+            /* xmldom does not return the outerHTML value.
             switch (node.nodeType) {
             switch (node.nodeType) {
-                case Node.ELEMENT_NODE: return node.outerHTML;
-                case Node.ATTRIBUTE_NODE: return node.value;
-                case Node.COMMENT_NODE: return node.data;
-                case Node.TEXT_NODE: return node.wholeText;
-                case Node.DOCUMENT_NODE: return node.outerHTML;
+                case node.ELEMENT_NODE: return node.outerHTML;
+                case node.ATTRIBUTE_NODE: return node.value;
+                case node.TEXT_NODE: return node.wholeText;
+                case node.COMMENT_NODE: return node.data;
+                case node.DOCUMENT_NODE: return node.outerHTML;
                 default: throw new Error("Unknown Node Type: " + node.nodeType);
                 default: throw new Error("Unknown Node Type: " + node.nodeType);
-            }
+            }*/
         };
         };
 
 
-        return Array.apply(null, Array(result.length))
-            .map(function(_, i) {
-                return result[i];
-            })
+        return result
             .map(nodeToString)
             .map(nodeToString)
             .join(delimiter);
             .join(delimiter);
     },
     },

+ 3 - 3
src/core/operations/Compress.js

@@ -418,9 +418,9 @@ const Compress = {
             }
             }
         };
         };
 
 
-        const fileSize = Utils.padLeft(input.length.toString(8), 11, "0");
+        const fileSize = input.length.toString(8).padStart(11, "0");
         const currentUnixTimestamp = Math.floor(Date.now() / 1000);
         const currentUnixTimestamp = Math.floor(Date.now() / 1000);
-        const lastModTime = Utils.padLeft(currentUnixTimestamp.toString(8), 11, "0");
+        const lastModTime = currentUnixTimestamp.toString(8).padStart(11, "0");
 
 
         const file = {
         const file = {
             fileName: Utils.padBytesRight(args[0], 100),
             fileName: Utils.padBytesRight(args[0], 100),
@@ -452,7 +452,7 @@ const Compress = {
                 }
                 }
             });
             });
         }
         }
-        checksum = Utils.padBytesRight(Utils.padLeft(checksum.toString(8), 7, "0"), 8);
+        checksum = Utils.padBytesRight(checksum.toString(8).padStart(7, "0"), 8);
         file.checksum = checksum;
         file.checksum = checksum;
 
 
         const tarball = new Tarball();
         const tarball = new Tarball();

+ 20 - 21
src/core/operations/Convert.js

@@ -60,17 +60,16 @@ const Convert = {
     /**
     /**
      * Convert distance operation.
      * Convert distance operation.
      *
      *
-     * @param {number} input
+     * @param {BigNumber} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {number}
+     * @returns {BigNumber}
      */
      */
     runDistance: function (input, args) {
     runDistance: function (input, args) {
         let inputUnits = args[0],
         let inputUnits = args[0],
             outputUnits = args[1];
             outputUnits = args[1];
 
 
-        input = input * Convert.DISTANCE_FACTOR[inputUnits];
-        return input / Convert.DISTANCE_FACTOR[outputUnits];
-        // TODO Remove rounding errors (e.g. 1.000000000001)
+        input = input.mul(Convert.DISTANCE_FACTOR[inputUnits]);
+        return input.div(Convert.DISTANCE_FACTOR[outputUnits]);
     },
     },
 
 
 
 
@@ -141,16 +140,16 @@ const Convert = {
     /**
     /**
      * Convert data units operation.
      * Convert data units operation.
      *
      *
-     * @param {number} input
+     * @param {BigNumber} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {number}
+     * @returns {BigNumber}
      */
      */
     runDataSize: function (input, args) {
     runDataSize: function (input, args) {
         let inputUnits = args[0],
         let inputUnits = args[0],
             outputUnits = args[1];
             outputUnits = args[1];
 
 
-        input = input * Convert.DATA_FACTOR[inputUnits];
-        return input / Convert.DATA_FACTOR[outputUnits];
+        input = input.mul(Convert.DATA_FACTOR[inputUnits]);
+        return input.div(Convert.DATA_FACTOR[outputUnits]);
     },
     },
 
 
 
 
@@ -221,16 +220,16 @@ const Convert = {
     /**
     /**
      * Convert area operation.
      * Convert area operation.
      *
      *
-     * @param {number} input
+     * @param {BigNumber} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {number}
+     * @returns {BigNumber}
      */
      */
     runArea: function (input, args) {
     runArea: function (input, args) {
         let inputUnits = args[0],
         let inputUnits = args[0],
             outputUnits = args[1];
             outputUnits = args[1];
 
 
-        input = input * Convert.AREA_FACTOR[inputUnits];
-        return input / Convert.AREA_FACTOR[outputUnits];
+        input = input.mul(Convert.AREA_FACTOR[inputUnits]);
+        return input.div(Convert.AREA_FACTOR[outputUnits]);
     },
     },
 
 
 
 
@@ -332,16 +331,16 @@ const Convert = {
     /**
     /**
      * Convert mass operation.
      * Convert mass operation.
      *
      *
-     * @param {number} input
+     * @param {BigNumber} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {number}
+     * @returns {BigNumber}
      */
      */
     runMass: function (input, args) {
     runMass: function (input, args) {
         let inputUnits = args[0],
         let inputUnits = args[0],
             outputUnits = args[1];
             outputUnits = args[1];
 
 
-        input = input * Convert.MASS_FACTOR[inputUnits];
-        return input / Convert.MASS_FACTOR[outputUnits];
+        input = input.mul(Convert.MASS_FACTOR[inputUnits]);
+        return input.div(Convert.MASS_FACTOR[outputUnits]);
     },
     },
 
 
 
 
@@ -397,16 +396,16 @@ const Convert = {
     /**
     /**
      * Convert speed operation.
      * Convert speed operation.
      *
      *
-     * @param {number} input
+     * @param {BigNumber} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {number}
+     * @returns {BigNumber}
      */
      */
     runSpeed: function (input, args) {
     runSpeed: function (input, args) {
         let inputUnits = args[0],
         let inputUnits = args[0],
             outputUnits = args[1];
             outputUnits = args[1];
 
 
-        input = input * Convert.SPEED_FACTOR[inputUnits];
-        return input / Convert.SPEED_FACTOR[outputUnits];
+        input = input.mul(Convert.SPEED_FACTOR[inputUnits]);
+        return input.div(Convert.SPEED_FACTOR[outputUnits]);
     },
     },
 
 
 };
 };

+ 32 - 5
src/core/operations/Entropy.js

@@ -81,22 +81,23 @@ const Entropy = {
     /**
     /**
      * Frequency distribution operation.
      * Frequency distribution operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {html}
      * @returns {html}
      */
      */
     runFreqDistrib: function (input, args) {
     runFreqDistrib: function (input, args) {
-        if (!input.length) return "No data";
+        const data = new Uint8Array(input);
+        if (!data.length) return "No data";
 
 
         let distrib = new Array(256).fill(0),
         let distrib = new Array(256).fill(0),
             percentages = new Array(256),
             percentages = new Array(256),
-            len = input.length,
+            len = data.length,
             showZeroes = args[0],
             showZeroes = args[0],
             i;
             i;
 
 
         // Count bytes
         // Count bytes
         for (i = 0; i < len; i++) {
         for (i = 0; i < len; i++) {
-            distrib[input[i]]++;
+            distrib[data[i]]++;
         }
         }
 
 
         // Calculate percentages
         // Calculate percentages
@@ -126,7 +127,7 @@ const Entropy = {
         for (i = 0; i < 256; i++) {
         for (i = 0; i < 256; i++) {
             if (distrib[i] || showZeroes) {
             if (distrib[i] || showZeroes) {
                 output += " " + Utils.hex(i, 2) + "    (" +
                 output += " " + Utils.hex(i, 2) + "    (" +
-                        Utils.padRight(percentages[i].toFixed(2).replace(".00", "") + "%)", 8) +
+                        (percentages[i].toFixed(2).replace(".00", "") + "%)").padEnd(8, " ") +
                         Array(Math.ceil(percentages[i])+1).join("|") + "\n";
                         Array(Math.ceil(percentages[i])+1).join("|") + "\n";
             }
             }
         }
         }
@@ -135,6 +136,32 @@ const Entropy = {
     },
     },
 
 
 
 
+    /**
+     * Chi Square operation.
+     *
+     * @param {ArrayBuffer} data
+     * @param {Object[]} args
+     * @returns {number}
+     */
+    runChiSq: function(input, args) {
+        const data = new Uint8Array(input);
+        let distArray = new Array(256).fill(0),
+            total = 0;
+
+        for (let i = 0; i < data.length; i++) {
+            distArray[data[i]]++;
+        }
+
+        for (let i = 0; i < distArray.length; i++) {
+            if (distArray[i] > 0) {
+                total += Math.pow(distArray[i] - data.length / 256, 2) / (data.length / 256);
+            }
+        }
+
+        return total;
+    },
+
+
     /**
     /**
      * Calculates the Shannon entropy for a given chunk of data.
      * Calculates the Shannon entropy for a given chunk of data.
      *
      *

+ 10 - 8
src/core/operations/FileType.js

@@ -15,12 +15,13 @@ const FileType = {
     /**
     /**
      * Detect File Type operation.
      * Detect File Type operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runDetect: function(input, args) {
     runDetect: function(input, args) {
-        const type = FileType.magicType(input);
+        const data = new Uint8Array(input),
+            type = FileType.magicType(data);
 
 
         if (!type) {
         if (!type) {
             return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?";
             return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?";
@@ -46,20 +47,21 @@ const FileType = {
     /**
     /**
      * Scan for Embedded Files operation.
      * Scan for Embedded Files operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runScanForEmbeddedFiles: function(input, args) {
     runScanForEmbeddedFiles: function(input, args) {
         let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n",
         let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n",
             type,
             type,
-            ignoreCommon = args[0],
-            commonExts = ["ico", "ttf", ""],
             numFound = 0,
             numFound = 0,
             numCommonFound = 0;
             numCommonFound = 0;
+        const ignoreCommon = args[0],
+            commonExts = ["ico", "ttf", ""],
+            data = new Uint8Array(input);
 
 
-        for (let i = 0; i < input.length; i++) {
-            type = FileType.magicType(input.slice(i));
+        for (let i = 0; i < data.length; i++) {
+            type = FileType.magicType(data.slice(i));
             if (type) {
             if (type) {
                 if (ignoreCommon && commonExts.indexOf(type.ext) > -1) {
                 if (ignoreCommon && commonExts.indexOf(type.ext) > -1) {
                     numCommonFound++;
                     numCommonFound++;
@@ -96,7 +98,7 @@ const FileType = {
      * Given a buffer, detects magic byte sequences at specific positions and returns the
      * Given a buffer, detects magic byte sequences at specific positions and returns the
      * extension and mime type.
      * extension and mime type.
      *
      *
-     * @param {byteArray} buf
+     * @param {Uint8Array} buf
      * @returns {Object} type
      * @returns {Object} type
      * @returns {string} type.ext - File extension
      * @returns {string} type.ext - File extension
      * @returns {string} type.mime - Mime type
      * @returns {string} type.mime - Mime type

+ 3 - 3
src/core/operations/HTML.js

@@ -215,9 +215,9 @@ const HTML = {
         k = k.toFixed(2);
         k = k.toFixed(2);
 
 
         let hex = "#" +
         let hex = "#" +
-                Utils.padLeft(Math.round(r).toString(16), 2) +
-                Utils.padLeft(Math.round(g).toString(16), 2) +
-                Utils.padLeft(Math.round(b).toString(16), 2),
+                Math.round(r).toString(16).padStart(2, "0") +
+                Math.round(g).toString(16).padStart(2, "0") +
+                Math.round(b).toString(16).padStart(2, "0"),
             rgb  = "rgb(" + r + ", " + g + ", " + b + ")",
             rgb  = "rgb(" + r + ", " + g + ", " + b + ")",
             rgba = "rgba(" + r + ", " + g + ", " + b + ", " + a + ")",
             rgba = "rgba(" + r + ", " + g + ", " + b + ", " + a + ")",
             hsl  = "hsl(" + h + ", " + s + "%, " + l + "%)",
             hsl  = "hsl(" + h + ", " + s + "%, " + l + "%)",

+ 26 - 10
src/core/operations/Hash.js

@@ -16,6 +16,22 @@ import Checksum from "./Checksum.js";
  */
  */
 const Hash = {
 const Hash = {
 
 
+    /**
+     * Generic hash function.
+     *
+     * @param {string} name
+     * @param {string} input
+     * @returns {string}
+     */
+    runHash: function(name, input) {
+        const hasher = CryptoApi.hasher(name);
+        hasher.state.message = input;
+        hasher.state.length += input.length;
+        hasher.process();
+        return hasher.finalize().stringify("hex");
+    },
+
+
     /**
     /**
      * MD2 operation.
      * MD2 operation.
      *
      *
@@ -24,7 +40,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runMD2: function (input, args) {
     runMD2: function (input, args) {
-        return CryptoApi.hash("md2", input, {}).stringify("hex");
+        return Hash.runHash("md2", input);
     },
     },
 
 
 
 
@@ -36,7 +52,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runMD4: function (input, args) {
     runMD4: function (input, args) {
-        return CryptoApi.hash("md4", input, {}).stringify("hex");
+        return Hash.runHash("md4", input);
     },
     },
 
 
 
 
@@ -48,7 +64,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runMD5: function (input, args) {
     runMD5: function (input, args) {
-        return CryptoApi.hash("md5", input, {}).stringify("hex");
+        return Hash.runHash("md5", input);
     },
     },
 
 
 
 
@@ -92,7 +108,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runSHA0: function (input, args) {
     runSHA0: function (input, args) {
-        return CryptoApi.hash("sha0", input, {}).stringify("hex");
+        return Hash.runHash("sha0", input);
     },
     },
 
 
 
 
@@ -104,7 +120,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runSHA1: function (input, args) {
     runSHA1: function (input, args) {
-        return CryptoApi.hash("sha1", input, {}).stringify("hex");
+        return Hash.runHash("sha1", input);
     },
     },
 
 
 
 
@@ -123,7 +139,7 @@ const Hash = {
      */
      */
     runSHA2: function (input, args) {
     runSHA2: function (input, args) {
         const size = args[0];
         const size = args[0];
-        return CryptoApi.hash("sha" + size, input, {}).stringify("hex");
+        return Hash.runHash("sha" + size, input);
     },
     },
 
 
 
 
@@ -259,7 +275,7 @@ const Hash = {
      */
      */
     runRIPEMD: function (input, args) {
     runRIPEMD: function (input, args) {
         const size = args[0];
         const size = args[0];
-        return CryptoApi.hash("ripemd" + size, input, {}).stringify("hex");
+        return Hash.runHash("ripemd" + size, input);
     },
     },
 
 
 
 
@@ -271,7 +287,7 @@ const Hash = {
      * @returns {string}
      * @returns {string}
      */
      */
     runHAS: function (input, args) {
     runHAS: function (input, args) {
-        return CryptoApi.hash("has160", input, {}).stringify("hex");
+        return Hash.runHash("has160", input);
     },
     },
 
 
 
 
@@ -290,7 +306,7 @@ const Hash = {
      */
      */
     runWhirlpool: function (input, args) {
     runWhirlpool: function (input, args) {
         const variant = args[0].toLowerCase();
         const variant = args[0].toLowerCase();
-        return CryptoApi.hash(variant, input, {}).stringify("hex");
+        return Hash.runHash(variant, input);
     },
     },
 
 
 
 
@@ -315,7 +331,7 @@ const Hash = {
     runSnefru: function (input, args) {
     runSnefru: function (input, args) {
         const rounds = args[0],
         const rounds = args[0],
             size = args[1];
             size = args[1];
-        return CryptoApi.hash(`snefru-${rounds}-${size}`, input, {}).stringify("hex");
+        return Hash.runHash(`snefru-${rounds}-${size}`, input);
     },
     },
 
 
 
 

+ 7 - 6
src/core/operations/Hexdump.js

@@ -31,18 +31,19 @@ const Hexdump = {
     /**
     /**
      * To Hexdump operation.
      * To Hexdump operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runTo: function(input, args) {
     runTo: function(input, args) {
+        const data = new Uint8Array(input);
         const length = args[0] || Hexdump.WIDTH;
         const length = args[0] || Hexdump.WIDTH;
         const upperCase = args[1];
         const upperCase = args[1];
         const includeFinalLength = args[2];
         const includeFinalLength = args[2];
 
 
         let output = "", padding = 2;
         let output = "", padding = 2;
-        for (let i = 0; i < input.length; i += length) {
-            const buff = input.slice(i, i+length);
+        for (let i = 0; i < data.length; i += length) {
+            const buff = data.slice(i, i+length);
             let hexa = "";
             let hexa = "";
             for (let j = 0; j < buff.length; j++) {
             for (let j = 0; j < buff.length; j++) {
                 hexa += Utils.hex(buff[j], padding) + " ";
                 hexa += Utils.hex(buff[j], padding) + " ";
@@ -56,10 +57,10 @@ const Hexdump = {
             }
             }
 
 
             output += lineNo + "  " +
             output += lineNo + "  " +
-                Utils.padRight(hexa, (length*(padding+1))) +
-                " |" + Utils.padRight(Utils.printable(Utils.byteArrayToChars(buff)), buff.length) + "|\n";
+                hexa.padEnd(length*(padding+1), " ") +
+                " |" + Utils.printable(Utils.byteArrayToChars(buff)).padEnd(buff.length, " ") + "|\n";
 
 
-            if (includeFinalLength && i+buff.length === input.length) {
+            if (includeFinalLength && i+buff.length === data.length) {
                 output += Utils.hex(i+buff.length, 8) + "\n";
                 output += Utils.hex(i+buff.length, 8) + "\n";
             }
             }
         }
         }

+ 3 - 4
src/core/operations/Image.js

@@ -20,14 +20,13 @@ const Image = {
      *
      *
      * Extracts EXIF data from a byteArray, representing a JPG or a TIFF image.
      * Extracts EXIF data from a byteArray, representing a JPG or a TIFF image.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
      * @returns {string}
      * @returns {string}
      */
      */
     runExtractEXIF(input, args) {
     runExtractEXIF(input, args) {
         try {
         try {
-            const bytes = Uint8Array.from(input);
-            const parser = ExifParser.create(bytes.buffer);
+            const parser = ExifParser.create(input);
             const result = parser.parse();
             const result = parser.parse();
 
 
             let lines = [];
             let lines = [];
@@ -53,7 +52,7 @@ const Image = {
      * @author David Moodie [davidmoodie12@gmail.com]
      * @author David Moodie [davidmoodie12@gmail.com]
      * @param {byteArray} input
      * @param {byteArray} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {string}
+     * @returns {byteArray}
      */
      */
     runRemoveEXIF(input, args) {
     runRemoveEXIF(input, args) {
         // Do nothing if input is empty
         // Do nothing if input is empty

+ 1 - 1
src/core/operations/MS.js

@@ -1,5 +1,5 @@
 /**
 /**
- * Microsoft operations. 
+ * Microsoft operations.
  *
  *
  * @author bmwhitn [brian.m.whitney@outlook.com]
  * @author bmwhitn [brian.m.whitney@outlook.com]
  * @copyright Crown Copyright 2017
  * @copyright Crown Copyright 2017

+ 17 - 6
src/core/operations/NetBIOS.js

@@ -26,9 +26,14 @@ const NetBIOS = {
         let output = [],
         let output = [],
             offset = args[0];
             offset = args[0];
 
 
-        for (let i = 0; i < input.length; i++) {
-            output.push((input[i] >> 4) + offset);
-            output.push((input[i] & 0xf) + offset);
+        if (input.length <= 16) {
+            let len = input.length;
+            input.length = 16;
+            input.fill(32, len, 16);
+            for (let i = 0; i < input.length; i++) {
+                output.push((input[i] >> 4) + offset);
+                output.push((input[i] & 0xf) + offset);
+            }
         }
         }
 
 
         return output;
         return output;
@@ -46,9 +51,15 @@ const NetBIOS = {
         let output = [],
         let output = [],
             offset = args[0];
             offset = args[0];
 
 
-        for (let i = 0; i < input.length; i += 2) {
-            output.push(((input[i] - offset) << 4) |
-                        ((input[i + 1] - offset) & 0xf));
+        if (input.length <= 32 && (input.length % 2) === 0) {
+            for (let i = 0; i < input.length; i += 2) {
+                output.push((((input[i] & 0xff) - offset) << 4) |
+                            (((input[i + 1] & 0xff) - offset) & 0xf));
+            }
+            for (let i = output.length - 1; i > 0; i--) {
+                if (output[i] === 32) output.splice(i, i);
+                else break;
+            }
         }
         }
 
 
         return output;
         return output;

+ 62 - 6
src/core/operations/Numberwang.js

@@ -14,16 +14,72 @@ const Numberwang = {
      * @returns {string}
      * @returns {string}
      */
      */
     run: function(input, args) {
     run: function(input, args) {
-        if (!input) return "Let's play Wangernumb!";
-        const match = input.match(/\d+/);
-        if (match) {
-            return match[0] + "! That's Numberwang!";
+        let output;
+        if (!input) {
+            output = "Let's play Wangernumb!";
         } else {
         } else {
-            // That's a bad miss!
-            return "Sorry, that's not Numberwang. Let's rotate the board!";
+            const match = input.match(/(f0rty-s1x|shinty-six|filth-hundred and neeb|-?√?\d+(\.\d+)?i?([a-z]?)%?)/i);
+            if (match) {
+                if (match[3]) output = match[0] + "! That's AlphaNumericWang!";
+                else output = match[0] + "! That's Numberwang!";
+            } else {
+                // That's a bad miss!
+                output = "Sorry, that's not Numberwang. Let's rotate the board!";
+            }
         }
         }
+
+        const rand = Math.floor(Math.random() * Numberwang._didYouKnow.length);
+        return output + "\n\nDid you know: " + Numberwang._didYouKnow[rand];
     },
     },
 
 
+
+    /**
+     * Taken from http://numberwang.wikia.com/wiki/Numberwang_Wikia
+     *
+     * @private
+     * @constant
+     */
+    _didYouKnow: [
+        "Numberwang, contrary to popular belief, is a fruit and not a vegetable.",
+        "Robert Webb once got WordWang while presenting an episode of Numberwang.",
+        "The 6705th digit of pi is Numberwang.",
+        "Numberwang was invented on a Sevenday.",
+        "Contrary to popular belief, Albert Einstein always got good grades in Numberwang at school. He once scored ^4$ on a test.",
+        "680 asteroids have been named after Numberwang.",
+        "Archimedes is most famous for proclaiming \"That's Numberwang!\" during an epiphany about water displacement he had while taking a bath.",
+        "Numberwang Day is celebrated in Japan on every day of the year apart from June 6.",
+        "Biologists recently discovered Numberwang within a strand of human DNA.",
+        "Numbernot is a special type of non-Numberwang number. It is divisible by 3 and the letter \"y\".",
+        "Julie once got 612.04 Numberwangs in a single episode of Emmerdale.",
+        "In India, it is traditional to shout out \"Numberwang!\" instead of checkmate during games of chess.",
+        "There is a rule on Countdown which states that if you get Numberwang in the numbers round, you automatically win. It has only ever been invoked twice.",
+        "\"Numberwang\" was the third-most common baby name for a brief period in 1722.",
+        "\"The Lion King\" was loosely based on Numberwang.",
+        "\"A Numberwang a day keeps the doctor away\" is how Donny Cosy, the oldest man in the world, explained how he was in such good health at the age of 136.",
+        "The \"number lock\" button on a keyboard is based on the popular round of the same name in \"Numberwang\".",
+        "Cambridge became the first university to offer a course in Numberwang in 1567.",
+        "Schrödinger's Numberwang is a number that has been confusing dentists for centuries.",
+        "\"Harry Potter and the Numberwang of Numberwang\" was rejected by publishers -41 times before it became a bestseller.",
+        "\"Numberwang\" is the longest-running British game show in history; it has aired 226 seasons, each containing 19 episodes, which makes a grand total of 132 episodes.",
+        "The triple Numberwang bonus was discovered by archaeologist Thomas Jefferson in Somerset.",
+        "Numberwang is illegal in parts of Czechoslovakia.",
+        "Numberwang was discovered in India in the 12th century.",
+        "Numberwang has the chemical formula Zn4SO2(HgEs)3.",
+        "The first pack of cards ever created featured two \"Numberwang\" cards instead of jokers.",
+        "Julius Caesar was killed by an overdose of Numberwang.",
+        "The most Numberwang musical note is G#.",
+        "In 1934, the forty-third Google Doodle promoted the upcoming television show \"Numberwang on Ice\".",
+        "A recent psychology study found that toddlers were 17% faster at identifying numbers which were Numberwang.",
+        "There are 700 ways to commit a foul in the television show \"Numberwang\". All 700 of these fouls were committed by Julie in one single episode in 1473.",
+        "Astronomers suspect God is Numberwang.",
+        "Numberwang is the official beverage of Canada.",
+        "In the pilot episode of \"The Price is Right\", if a contestant got the value of an item exactly right they were told \"That's Numberwang!\" and immediately won ₹5.7032.",
+        "The first person to get three Numberwangs in a row was Madonna.",
+        "\"Numberwang\" has the code U+46402 in Unicode.",
+        "The musical note \"Numberwang\" is between D# and E♮.",
+        "Numberwang was first played on the moon in 1834.",
+    ],
+
 };
 };
 
 
 export default Numberwang;
 export default Numberwang;

+ 1 - 0
src/core/operations/OTP.js

@@ -1,6 +1,7 @@
 import otp from "otp";
 import otp from "otp";
 import Base64 from "./Base64.js";
 import Base64 from "./Base64.js";
 
 
+
 /**
 /**
  * One-Time Password operations.
  * One-Time Password operations.
  *
  *

+ 160 - 0
src/core/operations/PHP.js

@@ -0,0 +1,160 @@
+/**
+ * PHP operations.
+ *
+ * @author Jarmo van Lenthe [github.com/jarmovanlenthe]
+ * @copyright Jarmo van Lenthe
+ * @license Apache-2.0
+ *
+ * @namespace
+ */
+const PHP = {
+
+    /**
+     * @constant
+     * @default
+     */
+    OUTPUT_VALID_JSON: true,
+
+    /**
+     * PHP Deserialize operation.
+     *
+     * This Javascript implementation is based on the Python implementation by
+     * Armin Ronacher (2016), who released it under the 3-Clause BSD license.
+     * See: https://github.com/mitsuhiko/phpserialize/
+     *
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runDeserialize: function (input, args) {
+        /**
+         * Recursive method for deserializing.
+         * @returns {*}
+         */
+        function handleInput() {
+            /**
+             * Read `length` characters from the input, shifting them out the input.
+             * @param length
+             * @returns {string}
+             */
+            function read(length) {
+                let result = "";
+                for (let idx = 0; idx < length; idx++) {
+                    let char = inputPart.shift();
+                    if (char === undefined) {
+                        throw "End of input reached before end of script";
+                    }
+                    result += char;
+                }
+                return result;
+            }
+
+            /**
+             * Read characters from the input until `until` is found.
+             * @param until
+             * @returns {string}
+             */
+            function readUntil(until) {
+                let result = "";
+                for (;;) {
+                    let char = read(1);
+                    if (char === until) {
+                        break;
+                    } else {
+                        result += char;
+                    }
+                }
+                return result;
+
+            }
+
+            /**
+             * Read characters from the input that must be equal to `expect`
+             * @param expect
+             * @returns {string}
+             */
+            function expect(expect) {
+                let result = read(expect.length);
+                if (result !== expect) {
+                    throw "Unexpected input found";
+                }
+                return result;
+            }
+
+            /**
+             * Helper function to handle deserialized arrays.
+             * @returns {Array}
+             */
+            function handleArray() {
+                let items = parseInt(readUntil(":"), 10) * 2;
+                expect("{");
+                let result = [];
+                let isKey = true;
+                let lastItem = null;
+                for (let idx = 0; idx < items; idx++) {
+                    let item = handleInput();
+                    if (isKey) {
+                        lastItem = item;
+                        isKey = false;
+                    } else {
+                        let numberCheck = lastItem.match(/[0-9]+/);
+                        if (args[0] && numberCheck && numberCheck[0].length === lastItem.length) {
+                            result.push("\"" + lastItem + "\": " + item);
+                        } else {
+                            result.push(lastItem + ": " + item);
+                        }
+                        isKey = true;
+                    }
+                }
+                expect("}");
+                return result;
+            }
+
+
+            let kind = read(1).toLowerCase();
+
+            switch (kind) {
+                case "n":
+                    expect(";");
+                    return "";
+
+                case "i":
+                case "d":
+                case "b": {
+                    expect(":");
+                    let data = readUntil(";");
+                    if (kind === "b") {
+                        return (parseInt(data, 10) !== 0);
+                    }
+                    return data;
+                }
+
+                case "a":
+                    expect(":");
+                    return "{" + handleArray() + "}";
+
+                case "s": {
+                    expect(":");
+                    let length = readUntil(":");
+                    expect("\"");
+                    let value = read(length);
+                    expect("\";");
+                    if (args[0]) {
+                        return "\"" + value.replace(/"/g, "\\\"") + "\"";
+                    } else {
+                        return "\"" + value + "\"";
+                    }
+                }
+
+                default:
+                    throw "Unknown type: " + kind;
+            }
+        }
+
+        let inputPart = input.split("");
+        return handleInput();
+    }
+
+};
+
+export default PHP;

+ 4 - 5
src/core/operations/PublicKey.js

@@ -121,8 +121,7 @@ const PublicKey = {
         // Format Public Key fields
         // Format Public Key fields
         for (let i = 0; i < pkFields.length; i++) {
         for (let i = 0; i < pkFields.length; i++) {
             pkStr += "  " + pkFields[i].key + ":" +
             pkStr += "  " + pkFields[i].key + ":" +
-                Utils.padLeft(
-                    pkFields[i].value + "\n",
+                (pkFields[i].value + "\n").padStart(
                     18 - (pkFields[i].key.length + 3) + pkFields[i].value.length + 1,
                     18 - (pkFields[i].key.length + 3) + pkFields[i].value.length + 1,
                     " "
                     " "
                 );
                 );
@@ -286,9 +285,9 @@ ${extensions}`;
 
 
             key = fields[i].split("=")[0];
             key = fields[i].split("=")[0];
             value = fields[i].split("=")[1];
             value = fields[i].split("=")[1];
-            str = Utils.padRight(key, maxKeyLen) + " = " + value + "\n";
+            str = key.padEnd(maxKeyLen, " ") + " = " + value + "\n";
 
 
-            output += Utils.padLeft(str, indent + str.length, " ");
+            output += str.padStart(indent + str.length, " ");
         }
         }
 
 
         return output.slice(0, -1);
         return output.slice(0, -1);
@@ -314,7 +313,7 @@ ${extensions}`;
             if (i === 0) {
             if (i === 0) {
                 output += str;
                 output += str;
             } else {
             } else {
-                output += Utils.padLeft(str, indent + str.length, " ");
+                output += str.padStart(indent + str.length, " ");
             }
             }
         }
         }
 
 

+ 2 - 2
src/core/operations/SeqUtils.js

@@ -158,7 +158,7 @@ const SeqUtils = {
             width = lines.length.toString().length;
             width = lines.length.toString().length;
 
 
         for (let n = 0; n < lines.length; n++) {
         for (let n = 0; n < lines.length; n++) {
-            output += Utils.pad((n+1).toString(), width, " ") + " " + lines[n] + "\n";
+            output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n";
         }
         }
         return output.slice(0, output.length-1);
         return output.slice(0, output.length-1);
     },
     },
@@ -249,7 +249,7 @@ const SeqUtils = {
             }
             }
         }
         }
 
 
-        return 0;
+        return a.localeCompare(b);
     },
     },
 
 
 };
 };

+ 28 - 23
src/core/operations/Tidy.js

@@ -1,6 +1,3 @@
-import Utils from "../Utils.js";
-
-
 /**
 /**
  * Tidy operations.
  * Tidy operations.
  *
  *
@@ -104,32 +101,39 @@ const Tidy = {
     /**
     /**
      * Drop bytes operation.
      * Drop bytes operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {byteArray}
+     * @returns {ArrayBuffer}
      */
      */
     runDropBytes: function(input, args) {
     runDropBytes: function(input, args) {
-        let start = args[0],
+        const start = args[0],
             length = args[1],
             length = args[1],
             applyToEachLine = args[2];
             applyToEachLine = args[2];
 
 
         if (start < 0 || length < 0)
         if (start < 0 || length < 0)
             throw "Error: Invalid value";
             throw "Error: Invalid value";
 
 
-        if (!applyToEachLine)
-            return input.slice(0, start).concat(input.slice(start+length, input.length));
+        if (!applyToEachLine) {
+            const left = input.slice(0, start),
+                right = input.slice(start + length, input.byteLength);
+            let result = new Uint8Array(left.byteLength + right.byteLength);
+            result.set(new Uint8Array(left), 0);
+            result.set(new Uint8Array(right), left.byteLength);
+            return result.buffer;
+        }
 
 
         // Split input into lines
         // Split input into lines
+        const data = new Uint8Array(input);
         let lines = [],
         let lines = [],
             line = [],
             line = [],
             i;
             i;
 
 
-        for (i = 0; i < input.length; i++) {
-            if (input[i] === 0x0a) {
+        for (i = 0; i < data.length; i++) {
+            if (data[i] === 0x0a) {
                 lines.push(line);
                 lines.push(line);
                 line = [];
                 line = [];
             } else {
             } else {
-                line.push(input[i]);
+                line.push(data[i]);
             }
             }
         }
         }
         lines.push(line);
         lines.push(line);
@@ -139,7 +143,7 @@ const Tidy = {
             output = output.concat(lines[i].slice(0, start).concat(lines[i].slice(start+length, lines[i].length)));
             output = output.concat(lines[i].slice(0, start).concat(lines[i].slice(start+length, lines[i].length)));
             output.push(0x0a);
             output.push(0x0a);
         }
         }
-        return output.slice(0, output.length-1);
+        return new Uint8Array(output.slice(0, output.length-1)).buffer;
     },
     },
 
 
 
 
@@ -157,12 +161,12 @@ const Tidy = {
     /**
     /**
      * Take bytes operation.
      * Take bytes operation.
      *
      *
-     * @param {byteArray} input
+     * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @param {Object[]} args
-     * @returns {byteArray}
+     * @returns {ArrayBuffer}
      */
      */
     runTakeBytes: function(input, args) {
     runTakeBytes: function(input, args) {
-        let start = args[0],
+        const start = args[0],
             length = args[1],
             length = args[1],
             applyToEachLine = args[2];
             applyToEachLine = args[2];
 
 
@@ -173,16 +177,17 @@ const Tidy = {
             return input.slice(start, start+length);
             return input.slice(start, start+length);
 
 
         // Split input into lines
         // Split input into lines
+        const data = new Uint8Array(input);
         let lines = [],
         let lines = [],
-            line = [];
-        let i;
+            line = [],
+            i;
 
 
-        for (i = 0; i < input.length; i++) {
-            if (input[i] === 0x0a) {
+        for (i = 0; i < data.length; i++) {
+            if (data[i] === 0x0a) {
                 lines.push(line);
                 lines.push(line);
                 line = [];
                 line = [];
             } else {
             } else {
-                line.push(input[i]);
+                line.push(data[i]);
             }
             }
         }
         }
         lines.push(line);
         lines.push(line);
@@ -192,7 +197,7 @@ const Tidy = {
             output = output.concat(lines[i].slice(start, start+length));
             output = output.concat(lines[i].slice(start, start+length));
             output.push(0x0a);
             output.push(0x0a);
         }
         }
-        return output.slice(0, output.length-1);
+        return new Uint8Array(output.slice(0, output.length-1)).buffer;
     },
     },
 
 
 
 
@@ -229,11 +234,11 @@ const Tidy = {
 
 
         if (position === "Start") {
         if (position === "Start") {
             for (i = 0; i < lines.length; i++) {
             for (i = 0; i < lines.length; i++) {
-                output += Utils.padLeft(lines[i], lines[i].length+len, chr) + "\n";
+                output += lines[i].padStart(lines[i].length+len, chr) + "\n";
             }
             }
         } else if (position === "End") {
         } else if (position === "End") {
             for (i = 0; i < lines.length; i++) {
             for (i = 0; i < lines.length; i++) {
-                output += Utils.padRight(lines[i], lines[i].length+len, chr) + "\n";
+                output += lines[i].padEnd(lines[i].length+len, chr) + "\n";
             }
             }
         }
         }
 
 

+ 27 - 47
src/core/operations/URL.js

@@ -1,5 +1,5 @@
 /* globals unescape */
 /* globals unescape */
-import Utils from "../Utils.js";
+import url from "url";
 
 
 
 
 /**
 /**
@@ -58,56 +58,36 @@ const URL_ = {
      * @returns {string}
      * @returns {string}
      */
      */
     runParse: function(input, args) {
     runParse: function(input, args) {
-        if (!document) {
-            throw "This operation only works in a browser.";
-        }
-
-        const a = document.createElement("a");
-
-        // Overwrite base href which will be the current CyberChef URL to reduce confusion.
-        a.href = "http://example.com/";
-        a.href = input;
-
-        if (a.protocol) {
-            let output = "";
-            if (a.hostname !== window.location.hostname) {
-                output = "Protocol:\t" + a.protocol + "\n";
-                if (a.hostname) output += "Hostname:\t" + a.hostname + "\n";
-                if (a.port) output += "Port:\t\t" + a.port + "\n";
-            }
-
-            if (a.pathname && a.pathname !== window.location.pathname) {
-                let pathname = a.pathname;
-                if (pathname.indexOf(window.location.pathname) === 0)
-                    pathname = pathname.replace(window.location.pathname, "");
-                if (pathname)
-                    output += "Path name:\t" + pathname + "\n";
-            }
-
-            if (a.hash && a.hash !== window.location.hash) {
-                output += "Hash:\t\t" + a.hash + "\n";
-            }
-
-            if (a.search && a.search !== window.location.search) {
-                output += "Arguments:\n";
-                const args_ = (a.search.slice(1, a.search.length)).split("&");
-                let splitArgs = [], padding = 0, i;
-                for (i = 0; i < args_.length; i++) {
-                    splitArgs.push(args_[i].split("="));
-                    padding = (splitArgs[i][0].length > padding) ? splitArgs[i][0].length : padding;
-                }
-                for (i = 0; i < splitArgs.length; i++) {
-                    output += "\t" + Utils.padRight(splitArgs[i][0], padding);
-                    if (splitArgs[i].length > 1 && splitArgs[i][1].length)
-                        output += " = " + splitArgs[i][1] + "\n";
-                    else output += "\n";
+        const uri = url.parse(input, true);
+
+        let output = "";
+
+        if (uri.protocol) output += "Protocol:\t" + uri.protocol + "\n";
+        if (uri.auth) output += "Auth:\t\t" + uri.auth + "\n";
+        if (uri.hostname) output += "Hostname:\t" + uri.hostname + "\n";
+        if (uri.port) output += "Port:\t\t" + uri.port + "\n";
+        if (uri.pathname) output += "Path name:\t" + uri.pathname + "\n";
+        if (uri.query) {
+            let keys = Object.keys(uri.query),
+                padding = 0;
+
+            keys.forEach(k => {
+                padding = (k.length > padding) ? k.length : padding;
+            });
+
+            output += "Arguments:\n";
+            for (let key in uri.query) {
+                output += "\t" + key.padEnd(padding, " ");
+                if (uri.query[key].length) {
+                    output += " = " + uri.query[key] + "\n";
+                } else {
+                    output += "\n";
                 }
                 }
             }
             }
-
-            return output;
         }
         }
+        if (uri.hash) output += "Hash:\t\t" + uri.hash + "\n";
 
 
-        return "Invalid URI";
+        return output;
     },
     },
 
 
 
 

+ 14 - 19
src/core/operations/UUID.js

@@ -1,3 +1,6 @@
+import crypto from "crypto";
+
+
 /**
 /**
  * UUID operations.
  * UUID operations.
  *
  *
@@ -17,25 +20,17 @@ const UUID = {
      * @returns {string}
      * @returns {string}
      */
      */
     runGenerateV4: function(input, args) {
     runGenerateV4: function(input, args) {
-        if (window && typeof(window.crypto) !== "undefined" && typeof(window.crypto.getRandomValues) !== "undefined") {
-            let buf = new Uint32Array(4),
-                i = 0;
-            window.crypto.getRandomValues(buf);
-            return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
-                let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf,
-                    v = c === "x" ? r : (r & 0x3 | 0x8);
-                i++;
-                return v.toString(16);
-            });
-        } else {
-            return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
-                let r = Math.random() * 16 | 0,
-                    v = c === "x" ? r : (r & 0x3 | 0x8);
-                return v.toString(16);
-            });
-        }
-    },
-
+        const buf = new Uint32Array(4).map(() => {
+            return crypto.randomBytes(4).readUInt32BE(0, true);
+        });
+        let i = 0;
+        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
+            let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf,
+                v = c === "x" ? r : (r & 0x3 | 0x8);
+            i++;
+            return v.toString(16);
+        });
+    }
 };
 };
 
 
 export default UUID;
 export default UUID;

+ 9 - 5
src/web/App.js

@@ -49,9 +49,11 @@ App.prototype.setup = function() {
     this.manager.setup();
     this.manager.setup();
     this.resetLayout();
     this.resetLayout();
     this.setCompileMessage();
     this.setCompileMessage();
-    this.loadURIParams();
 
 
+    log.debug("App loaded");
     this.appLoaded = true;
     this.appLoaded = true;
+
+    this.loadURIParams();
     this.loaded();
     this.loaded();
 };
 };
 
 
@@ -88,9 +90,10 @@ App.prototype.loaded = function() {
  * An error handler for displaying the error to the user.
  * An error handler for displaying the error to the user.
  *
  *
  * @param {Error} err
  * @param {Error} err
+ * @param {boolean} [logToConsole=false]
  */
  */
-App.prototype.handleError = function(err) {
-    console.error(err);
+App.prototype.handleError = function(err, logToConsole) {
+    if (logToConsole) log.error(err);
     const msg = err.displayStr || err.toString();
     const msg = err.displayStr || err.toString();
     this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors);
     this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors);
 };
 };
@@ -128,6 +131,7 @@ App.prototype.autoBake = function() {
     if (this.autoBakePause) return false;
     if (this.autoBakePause) return false;
 
 
     if (this.autoBake_ && !this.baking) {
     if (this.autoBake_ && !this.baking) {
+        log.debug("Auto-baking");
         this.bake();
         this.bake();
     } else {
     } else {
         this.manager.controls.showStaleIndicator();
         this.manager.controls.showStaleIndicator();
@@ -528,7 +532,7 @@ App.prototype.setCompileMessage = function() {
 
 
 /**
 /**
  * Determines whether the browser supports Local Storage and if it is accessible.
  * Determines whether the browser supports Local Storage and if it is accessible.
- * 
+ *
  * @returns {boolean}
  * @returns {boolean}
  */
  */
 App.prototype.isLocalStorageAvailable = function() {
 App.prototype.isLocalStorageAvailable = function() {
@@ -568,7 +572,7 @@ App.prototype.isLocalStorageAvailable = function() {
 App.prototype.alert = function(str, style, timeout, silent) {
 App.prototype.alert = function(str, style, timeout, silent) {
     const time = new Date();
     const time = new Date();
 
 
-    console.log("[" + time.toLocaleString() + "] " + str);
+    log.info("[" + time.toLocaleString() + "] " + str);
     if (silent) return;
     if (silent) return;
 
 
     style = style || "danger";
     style = style || "danger";

+ 217 - 0
src/web/BindingsWaiter.js

@@ -0,0 +1,217 @@
+/**
+ * Waiter to handle keybindings to CyberChef functions (i.e. Bake, Step, Save, Load etc.)
+ *
+ * @author Matt C [matt@artemisbot.uk]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ *
+ * @constructor
+ * @param {App} app - The main view object for CyberChef.
+ * @param {Manager} manager - The CyberChef event manager.
+ */
+const BindingsWaiter = function (app, manager) {
+    this.app = app;
+    this.manager = manager;
+};
+
+
+/**
+ * Handler for all keydown events
+ * Checks whether valid keyboard shortcut has been instated
+ *
+ * @fires Manager#statechange
+ * @param {event} e
+ */
+BindingsWaiter.prototype.parseInput = function(e) {
+    const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey;
+
+    if (e.ctrlKey && modKey) {
+        let elem;
+        switch (e.code) {
+            case "KeyF": // Focus search
+                e.preventDefault();
+                document.getElementById("search").focus();
+                break;
+            case "KeyI": // Focus input
+                e.preventDefault();
+                document.getElementById("input-text").focus();
+                break;
+            case "KeyO": // Focus output
+                e.preventDefault();
+                document.getElementById("output-text").focus();
+                break;
+            case "Period": // Focus next operation
+                e.preventDefault();
+                try {
+                    elem = document.activeElement.closest(".operation") || document.querySelector("#rec-list .operation");
+                    if (elem.parentNode.lastChild === elem) {
+                        // If operation is last in recipe, loop around to the top operation's first argument
+                        elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus();
+                    } else {
+                        // Focus first argument of next operation
+                        elem.nextSibling.querySelectorAll(".arg")[0].focus();
+                    }
+                } catch (e) {
+                    // do nothing, just don't throw an error
+                }
+                break;
+            case "KeyB": // Set breakpoint
+                e.preventDefault();
+                try {
+                    elem = document.activeElement.closest(".operation").querySelectorAll(".breakpoint")[0];
+                    if (elem.getAttribute("break") === "false") {
+                        elem.setAttribute("break", "true"); // add break point if not already enabled
+                        elem.classList.add("breakpoint-selected");
+                    } else {
+                        elem.setAttribute("break", "false"); // remove break point if already enabled
+                        elem.classList.remove("breakpoint-selected");
+                    }
+                    window.dispatchEvent(this.manager.statechange);
+                } catch (e) {
+                    // do nothing, just don't throw an error
+                }
+                break;
+            case "KeyD": // Disable operation
+                e.preventDefault();
+                try {
+                    elem = document.activeElement.closest(".operation").querySelectorAll(".disable-icon")[0];
+                    if (elem.getAttribute("disabled") === "false") {
+                        elem.setAttribute("disabled", "true"); // disable operation if enabled
+                        elem.classList.add("disable-elem-selected");
+                        elem.parentNode.parentNode.classList.add("disabled");
+                    } else {
+                        elem.setAttribute("disabled", "false"); // enable operation if disabled
+                        elem.classList.remove("disable-elem-selected");
+                        elem.parentNode.parentNode.classList.remove("disabled");
+                    }
+                    this.app.progress = 0;
+                    window.dispatchEvent(this.manager.statechange);
+                } catch (e) {
+                    // do nothing, just don't throw an error
+                }
+                break;
+            case "Space": // Bake
+                e.preventDefault();
+                this.app.bake();
+                break;
+            case "Quote": // Step through
+                e.preventDefault();
+                this.app.bake(true);
+                break;
+            case "KeyC": // Clear recipe
+                e.preventDefault();
+                this.manager.recipe.clearRecipe();
+                break;
+            case "KeyS": // Save output to file
+                e.preventDefault();
+                this.manager.output.saveClick();
+                break;
+            case "KeyL": // Load recipe
+                e.preventDefault();
+                this.manager.controls.loadClick();
+                break;
+            case "KeyM": // Switch input and output
+                e.preventDefault();
+                this.manager.output.switchClick();
+                break;
+            default:
+                if (e.code.match(/Digit[0-9]/g)) { // Select nth operation
+                    e.preventDefault();
+                    try {
+                        // Select the first argument of the operation corresponding to the number pressed
+                        document.querySelector(`li:nth-child(${e.code.substr(-1)}) .arg`).focus();
+                    } catch (e) {
+                        // do nothing, just don't throw an error
+                    }
+                }
+                break;
+        }
+    }
+};
+
+
+/**
+ * Updates keybinding list when metaKey option is toggled
+ *
+ */
+BindingsWaiter.prototype.updateKeybList = function() {
+    let modWinLin = "Alt";
+    let modMac = "Opt";
+    if (this.app.options.useMetaKey) {
+        modWinLin = "Win";
+        modMac = "Cmd";
+    }
+    document.getElementById("keybList").innerHTML = `
+    <tr>
+        <td><b>Command</b></td>
+        <td><b>Shortcut (Win/Linux)</b></td>
+        <td><b>Shortcut (Mac)</b></td>
+    </tr>
+    <tr>
+        <td>Place cursor in search field</td>
+        <td>Ctrl+${modWinLin}+f</td>
+        <td>Ctrl+${modMac}+f</td>
+    <tr>
+        <td>Place cursor in input box</td>
+        <td>Ctrl+${modWinLin}+i</td>
+        <td>Ctrl+${modMac}+i</td>
+    </tr>
+    <tr>
+        <td>Place cursor in output box</td>
+        <td>Ctrl+${modWinLin}+o</td>
+        <td>Ctrl+${modMac}+o</td>
+    </tr>
+    <tr>
+        <td>Place cursor in first argument field of the next operation in the recipe</td>
+        <td>Ctrl+${modWinLin}+.</td>
+        <td>Ctrl+${modMac}+.</td>
+    </tr>
+    <tr>
+        <td>Place cursor in first argument field of the nth operation in the recipe</td>
+        <td>Ctrl+${modWinLin}+[1-9]</td>
+        <td>Ctrl+${modMac}+[1-9]</td>
+    </tr>
+    <tr>
+        <td>Disable current operation</td>
+        <td>Ctrl+${modWinLin}+d</td>
+        <td>Ctrl+${modMac}+d</td>
+    </tr>
+    <tr>
+        <td>Set/clear breakpoint</td>
+        <td>Ctrl+${modWinLin}+b</td>
+        <td>Ctrl+${modMac}+b</td>
+    </tr>
+    <tr>
+        <td>Bake</td>
+        <td>Ctrl+${modWinLin}+Space</td>
+        <td>Ctrl+${modMac}+Space</td>
+    </tr>
+    <tr>
+        <td>Step</td>
+        <td>Ctrl+${modWinLin}+'</td>
+        <td>Ctrl+${modMac}+'</td>
+    </tr>
+    <tr>
+        <td>Clear recipe</td>
+        <td>Ctrl+${modWinLin}+c</td>
+        <td>Ctrl+${modMac}+c</td>
+    </tr>
+    <tr>
+        <td>Save to file</td>
+        <td>Ctrl+${modWinLin}+s</td>
+        <td>Ctrl+${modMac}+s</td>
+    </tr>
+    <tr>
+        <td>Load recipe</td>
+        <td>Ctrl+${modWinLin}+l</td>
+        <td>Ctrl+${modMac}+l</td>
+    </tr>
+    <tr>
+        <td>Move output to input</td>
+        <td>Ctrl+${modWinLin}+m</td>
+        <td>Ctrl+${modMac}+m</td>
+    </tr>
+    `;
+};
+
+export default BindingsWaiter;

+ 4 - 7
src/web/HighlighterWaiter.js

@@ -1,6 +1,3 @@
-import Utils from "../core/Utils.js";
-
-
 /**
 /**
  * Waiter to handle events related to highlighting in CyberChef.
  * Waiter to handle events related to highlighting in CyberChef.
  *
  *
@@ -312,9 +309,9 @@ HighlighterWaiter.prototype.outputHtmlMousemove = function(e) {
 HighlighterWaiter.prototype.selectionInfo = function(start, end) {
 HighlighterWaiter.prototype.selectionInfo = function(start, end) {
     const len = end.toString().length;
     const len = end.toString().length;
     const width = len < 2 ? 2 : len;
     const width = len < 2 ? 2 : len;
-    const startStr = Utils.pad(start.toString(), width, " ").replace(/ /g, "&nbsp;");
-    const endStr   = Utils.pad(end.toString(), width, " ").replace(/ /g, "&nbsp;");
-    const lenStr   = Utils.pad((end-start).toString(), width, " ").replace(/ /g, "&nbsp;");
+    const startStr = start.toString().padStart(width, " ").replace(/ /g, "&nbsp;");
+    const endStr = end.toString().padStart(width, " ").replace(/ /g, "&nbsp;");
+    const lenStr = (end-start).toString().padStart(width, " ").replace(/ /g, "&nbsp;");
 
 
     return "start: " + startStr + "<br>end: " + endStr + "<br>length: " + lenStr;
     return "start: " + startStr + "<br>end: " + endStr + "<br>length: " + lenStr;
 };
 };
@@ -402,7 +399,7 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
 
 
     // Check if there is a carriage return in the output dish as this will not
     // Check if there is a carriage return in the output dish as this will not
     // be displayed by the HTML textarea and will mess up highlighting offsets.
     // be displayed by the HTML textarea and will mess up highlighting offsets.
-    if (!this.app.dishStr || this.app.dishStr.indexOf("\r") >= 0) return false;
+    if (this.manager.output.containsCR()) return false;
 
 
     const startPlaceholder = "[startHighlight]";
     const startPlaceholder = "[startHighlight]";
     const startPlaceholderRegex = /\[startHighlight\]/g;
     const startPlaceholderRegex = /\[startHighlight\]/g;

+ 138 - 57
src/web/InputWaiter.js

@@ -1,4 +1,4 @@
-import Utils from "../core/Utils.js";
+import LoaderWorker from "worker-loader?inline&fallback=false!./LoaderWorker.js";
 
 
 
 
 /**
 /**
@@ -33,6 +33,9 @@ const InputWaiter = function(app, manager) {
         144, //Num
         144, //Num
         145, //Scroll
         145, //Scroll
     ];
     ];
+
+    this.loaderWorker = null;
+    this.fileBuffer = null;
 };
 };
 
 
 
 
@@ -42,20 +45,52 @@ const InputWaiter = function(app, manager) {
  * @returns {string}
  * @returns {string}
  */
  */
 InputWaiter.prototype.get = function() {
 InputWaiter.prototype.get = function() {
-    return document.getElementById("input-text").value;
+    return this.fileBuffer || document.getElementById("input-text").value;
 };
 };
 
 
 
 
 /**
 /**
- * Sets the input in the input textarea.
+ * Sets the input in the input area.
  *
  *
- * @param {string} input
+ * @param {string|File} input
  *
  *
  * @fires Manager#statechange
  * @fires Manager#statechange
  */
  */
 InputWaiter.prototype.set = function(input) {
 InputWaiter.prototype.set = function(input) {
-    document.getElementById("input-text").value = input;
-    window.dispatchEvent(this.manager.statechange);
+    const inputText = document.getElementById("input-text");
+    if (input instanceof File) {
+        this.setFile(input);
+        inputText.value = "";
+        this.setInputInfo(input.size, null);
+    } else {
+        inputText.value = input;
+        window.dispatchEvent(this.manager.statechange);
+        const lines = input.length < (this.app.options.ioDisplayThreshold * 1024) ?
+            input.count("\n") + 1 : null;
+        this.setInputInfo(input.length, lines);
+    }
+};
+
+
+/**
+ * Shows file details.
+ *
+ * @param {File} file
+ */
+InputWaiter.prototype.setFile = function(file) {
+    // Display file overlay in input area with details
+    const fileOverlay = document.getElementById("input-file"),
+        fileName = document.getElementById("input-file-name"),
+        fileSize = document.getElementById("input-file-size"),
+        fileType = document.getElementById("input-file-type"),
+        fileLoaded = document.getElementById("input-file-loaded");
+
+    this.fileBuffer = new ArrayBuffer();
+    fileOverlay.style.display = "block";
+    fileName.textContent = file.name;
+    fileSize.textContent = file.size.toLocaleString() + " bytes";
+    fileType.textContent = file.type || "unknown";
+    fileLoaded.textContent = "0%";
 };
 };
 
 
 
 
@@ -69,22 +104,29 @@ InputWaiter.prototype.setInputInfo = function(length, lines) {
     let width = length.toString().length;
     let width = length.toString().length;
     width = width < 2 ? 2 : width;
     width = width < 2 ? 2 : width;
 
 
-    const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, "&nbsp;");
-    const linesStr  = Utils.pad(lines.toString(), width, " ").replace(/ /g, "&nbsp;");
+    const lengthStr = length.toString().padStart(width, " ").replace(/ /g, "&nbsp;");
+    let msg = "length: " + lengthStr;
+
+    if (typeof lines === "number") {
+        const linesStr = lines.toString().padStart(width, " ").replace(/ /g, "&nbsp;");
+        msg += "<br>lines: " + linesStr;
+    }
 
 
-    document.getElementById("input-info").innerHTML = "length: " + lengthStr + "<br>lines: " + linesStr;
+    document.getElementById("input-info").innerHTML = msg;
 };
 };
 
 
 
 
 /**
 /**
- * Handler for input scroll events.
- * Scrolls the highlighter pane to match the input textarea position and updates history state.
+ * Handler for input change events.
  *
  *
  * @param {event} e
  * @param {event} e
  *
  *
  * @fires Manager#statechange
  * @fires Manager#statechange
  */
  */
 InputWaiter.prototype.inputChange = function(e) {
 InputWaiter.prototype.inputChange = function(e) {
+    // Ignore this function if the input is a File
+    if (this.fileBuffer) return;
+
     // Remove highlighting from input and output panes as the offsets might be different now
     // Remove highlighting from input and output panes as the offsets might be different now
     this.manager.highlighter.removeHighlights();
     this.manager.highlighter.removeHighlights();
 
 
@@ -93,18 +135,47 @@ InputWaiter.prototype.inputChange = function(e) {
 
 
     // Update the input metadata info
     // Update the input metadata info
     const inputText = this.get();
     const inputText = this.get();
-    const lines = inputText.count("\n") + 1;
+    const lines = inputText.length < (this.app.options.ioDisplayThreshold * 1024) ?
+        inputText.count("\n") + 1 : null;
 
 
     this.setInputInfo(inputText.length, lines);
     this.setInputInfo(inputText.length, lines);
 
 
-
-    if (this.badKeys.indexOf(e.keyCode) < 0) {
+    if (e && this.badKeys.indexOf(e.keyCode) < 0) {
         // Fire the statechange event as the input has been modified
         // Fire the statechange event as the input has been modified
         window.dispatchEvent(this.manager.statechange);
         window.dispatchEvent(this.manager.statechange);
     }
     }
 };
 };
 
 
 
 
+/**
+ * Handler for input paste events.
+ * Checks that the size of the input is below the display limit, otherwise treats it as a file/blob.
+ *
+ * @param {event} e
+ */
+InputWaiter.prototype.inputPaste = function(e) {
+    const pastedData = e.clipboardData.getData("Text");
+
+    if (pastedData.length < (this.app.options.ioDisplayThreshold * 1024)) {
+        this.inputChange(e);
+    } else {
+        e.preventDefault();
+        e.stopPropagation();
+
+        const file = new File([pastedData], "PastedData", {
+            type: "text/plain",
+            lastModified: Date.now()
+        });
+
+        this.loaderWorker = new LoaderWorker();
+        this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this));
+        this.loaderWorker.postMessage({"file": file});
+        this.set(file);
+        return false;
+    }
+};
+
+
 /**
 /**
  * Handler for input dragover events.
  * Handler for input dragover events.
  * Gives the user a visual cue to show that items can be dropped here.
  * Gives the user a visual cue to show that items can be dropped here.
@@ -118,7 +189,7 @@ InputWaiter.prototype.inputDragover = function(e) {
 
 
     e.stopPropagation();
     e.stopPropagation();
     e.preventDefault();
     e.preventDefault();
-    e.target.classList.add("dropping-file");
+    e.target.closest("#input-text,#input-file").classList.add("dropping-file");
 };
 };
 
 
 
 
@@ -131,7 +202,8 @@ InputWaiter.prototype.inputDragover = function(e) {
 InputWaiter.prototype.inputDragleave = function(e) {
 InputWaiter.prototype.inputDragleave = function(e) {
     e.stopPropagation();
     e.stopPropagation();
     e.preventDefault();
     e.preventDefault();
-    e.target.classList.remove("dropping-file");
+    document.getElementById("input-text").classList.remove("dropping-file");
+    document.getElementById("input-file").classList.remove("dropping-file");
 };
 };
 
 
 
 
@@ -149,55 +221,62 @@ InputWaiter.prototype.inputDrop = function(e) {
     e.stopPropagation();
     e.stopPropagation();
     e.preventDefault();
     e.preventDefault();
 
 
-    const el = e.target;
     const file = e.dataTransfer.files[0];
     const file = e.dataTransfer.files[0];
     const text = e.dataTransfer.getData("Text");
     const text = e.dataTransfer.getData("Text");
-    const reader = new FileReader();
-    let inputCharcode = "";
-    let offset = 0;
-    const CHUNK_SIZE = 20480; // 20KB
-
-    const setInput = function() {
-        const recipeConfig = this.app.getRecipeConfig();
-        if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
-            recipeConfig.unshift({op: "From Hex", args: ["Space"]});
-            this.app.setRecipeConfig(recipeConfig);
-        }
-
-        this.set(inputCharcode);
-
-        el.classList.remove("loadingFile");
-    }.bind(this);
-
-    const seek = function() {
-        if (offset >= file.size) {
-            setInput();
-            return;
-        }
-        el.value = "Processing... " + Math.round(offset / file.size * 100) + "%";
-        const slice = file.slice(offset, offset + CHUNK_SIZE);
-        reader.readAsArrayBuffer(slice);
-    };
-
-    reader.onload = function(e) {
-        const data = new Uint8Array(reader.result);
-        inputCharcode += Utils.toHexFast(data);
-        offset += CHUNK_SIZE;
-        seek();
-    };
-
-
-    el.classList.remove("dropping-file");
 
 
-    if (file) {
-        el.classList.add("loadingFile");
-        seek();
-    } else if (text) {
+    document.getElementById("input-text").classList.remove("dropping-file");
+    document.getElementById("input-file").classList.remove("dropping-file");
+
+    if (text) {
+        this.closeFile();
         this.set(text);
         this.set(text);
+        return;
+    }
+
+    if (file) {
+        this.closeFile();
+        this.loaderWorker = new LoaderWorker();
+        this.loaderWorker.addEventListener("message", this.handleLoaderMessage.bind(this));
+        this.loaderWorker.postMessage({"file": file});
+        this.set(file);
+    }
+};
+
+
+/**
+ * Handler for messages sent back by the LoaderWorker.
+ *
+ * @param {MessageEvent} e
+ */
+InputWaiter.prototype.handleLoaderMessage = function(e) {
+    const r = e.data;
+    if (r.hasOwnProperty("progress")) {
+        const fileLoaded = document.getElementById("input-file-loaded");
+        fileLoaded.textContent = r.progress + "%";
+    }
+
+    if (r.hasOwnProperty("error")) {
+        this.app.alert(r.error, "danger", 10000);
+    }
+
+    if (r.hasOwnProperty("fileBuffer")) {
+        log.debug("Input file loaded");
+        this.fileBuffer = r.fileBuffer;
+        window.dispatchEvent(this.manager.statechange);
     }
     }
 };
 };
 
 
 
 
+/**
+ * Handler for file close events.
+ */
+InputWaiter.prototype.closeFile = function() {
+    if (this.loaderWorker) this.loaderWorker.terminate();
+    this.fileBuffer = null;
+    document.getElementById("input-file").style.display = "none";
+};
+
+
 /**
 /**
  * Handler for clear IO events.
  * Handler for clear IO events.
  * Resets the input, output and info areas.
  * Resets the input, output and info areas.
@@ -205,6 +284,8 @@ InputWaiter.prototype.inputDrop = function(e) {
  * @fires Manager#statechange
  * @fires Manager#statechange
  */
  */
 InputWaiter.prototype.clearIoClick = function() {
 InputWaiter.prototype.clearIoClick = function() {
+    this.closeFile();
+    this.manager.output.closeFile();
     this.manager.highlighter.removeHighlights();
     this.manager.highlighter.removeHighlights();
     document.getElementById("input-text").value = "";
     document.getElementById("input-text").value = "";
     document.getElementById("output-text").value = "";
     document.getElementById("output-text").value = "";

+ 54 - 0
src/web/LoaderWorker.js

@@ -0,0 +1,54 @@
+/**
+ * Web Worker to load large amounts of data without locking up the UI.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+
+
+/**
+ * Respond to message from parent thread.
+ */
+self.addEventListener("message", function(e) {
+    const r = e.data;
+    if (r.hasOwnProperty("file")) {
+        self.loadFile(r.file);
+    }
+});
+
+
+/**
+ * Loads a file object into an ArrayBuffer, then transfers it back to the parent thread.
+ *
+ * @param {File} file
+ */
+self.loadFile = function(file) {
+    const reader = new FileReader();
+    let data = new Uint8Array(file.size);
+    let offset = 0;
+    const CHUNK_SIZE = 10485760; // 10MiB
+
+    const seek = function() {
+        if (offset >= file.size) {
+            self.postMessage({"progress": 100});
+            self.postMessage({"fileBuffer": data.buffer}, [data.buffer]);
+            return;
+        }
+        self.postMessage({"progress": Math.round(offset / file.size * 100)});
+        const slice = file.slice(offset, offset + CHUNK_SIZE);
+        reader.readAsArrayBuffer(slice);
+    };
+
+    reader.onload = function(e) {
+        data.set(new Uint8Array(reader.result), offset);
+        offset += CHUNK_SIZE;
+        seek();
+    };
+
+    reader.onerror = function(e) {
+        self.postMessage({"error": file.error.message});
+    };
+
+    seek();
+};

+ 18 - 6
src/web/Manager.js

@@ -8,6 +8,7 @@ import OutputWaiter from "./OutputWaiter.js";
 import OptionsWaiter from "./OptionsWaiter.js";
 import OptionsWaiter from "./OptionsWaiter.js";
 import HighlighterWaiter from "./HighlighterWaiter.js";
 import HighlighterWaiter from "./HighlighterWaiter.js";
 import SeasonalWaiter from "./SeasonalWaiter.js";
 import SeasonalWaiter from "./SeasonalWaiter.js";
+import BindingsWaiter from "./BindingsWaiter.js";
 
 
 
 
 /**
 /**
@@ -57,9 +58,10 @@ const Manager = function(app) {
     this.ops         = new OperationsWaiter(this.app, this);
     this.ops         = new OperationsWaiter(this.app, this);
     this.input       = new InputWaiter(this.app, this);
     this.input       = new InputWaiter(this.app, this);
     this.output      = new OutputWaiter(this.app, this);
     this.output      = new OutputWaiter(this.app, this);
-    this.options     = new OptionsWaiter(this.app);
+    this.options     = new OptionsWaiter(this.app, this);
     this.highlighter = new HighlighterWaiter(this.app, this);
     this.highlighter = new HighlighterWaiter(this.app, this);
     this.seasonal    = new SeasonalWaiter(this.app, this);
     this.seasonal    = new SeasonalWaiter(this.app, this);
+    this.bindings    = new BindingsWaiter(this.app, this);
 
 
     // Object to store dynamic handlers to fire on elements that may not exist yet
     // Object to store dynamic handlers to fire on elements that may not exist yet
     this.dynamicHandlers = {};
     this.dynamicHandlers = {};
@@ -75,6 +77,7 @@ Manager.prototype.setup = function() {
     this.worker.registerChefWorker();
     this.worker.registerChefWorker();
     this.recipe.initialiseOperationDragNDrop();
     this.recipe.initialiseOperationDragNDrop();
     this.controls.autoBakeChange();
     this.controls.autoBakeChange();
+    this.bindings.updateKeybList();
     this.seasonal.load();
     this.seasonal.load();
 };
 };
 
 
@@ -116,7 +119,7 @@ Manager.prototype.initialiseEventListeners = function() {
     this.addDynamicListener(".op-list .op-icon", "mouseover", this.ops.opIconMouseover, this.ops);
     this.addDynamicListener(".op-list .op-icon", "mouseover", this.ops.opIconMouseover, this.ops);
     this.addDynamicListener(".op-list .op-icon", "mouseleave", this.ops.opIconMouseleave, this.ops);
     this.addDynamicListener(".op-list .op-icon", "mouseleave", this.ops.opIconMouseleave, this.ops);
     this.addDynamicListener(".op-list", "oplistcreate", this.ops.opListCreate, this.ops);
     this.addDynamicListener(".op-list", "oplistcreate", this.ops.opListCreate, this.ops);
-    this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd.bind(this.recipe));
+    this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd, this.recipe);
 
 
     // Recipe
     // Recipe
     this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe);
     this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe);
@@ -129,19 +132,22 @@ Manager.prototype.initialiseEventListeners = function() {
     this.addDynamicListener("#rec-list", "operationremove", this.recipe.opRemove.bind(this.recipe));
     this.addDynamicListener("#rec-list", "operationremove", this.recipe.opRemove.bind(this.recipe));
 
 
     // Input
     // Input
-    this.addMultiEventListener("#input-text", "keyup paste", this.input.inputChange, this.input);
+    this.addMultiEventListener("#input-text", "keyup", this.input.inputChange, this.input);
+    this.addMultiEventListener("#input-text", "paste", this.input.inputPaste, this.input);
     document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app));
     document.getElementById("reset-layout").addEventListener("click", this.app.resetLayout.bind(this.app));
     document.getElementById("clr-io").addEventListener("click", this.input.clearIoClick.bind(this.input));
     document.getElementById("clr-io").addEventListener("click", this.input.clearIoClick.bind(this.input));
-    document.getElementById("input-text").addEventListener("dragover", this.input.inputDragover.bind(this.input));
-    document.getElementById("input-text").addEventListener("dragleave", this.input.inputDragleave.bind(this.input));
-    document.getElementById("input-text").addEventListener("drop", this.input.inputDrop.bind(this.input));
+    this.addListeners("#input-text,#input-file", "dragover", this.input.inputDragover, this.input);
+    this.addListeners("#input-text,#input-file", "dragleave", this.input.inputDragleave, this.input);
+    this.addListeners("#input-text,#input-file", "drop", this.input.inputDrop, this.input);
     document.getElementById("input-text").addEventListener("scroll", this.highlighter.inputScroll.bind(this.highlighter));
     document.getElementById("input-text").addEventListener("scroll", this.highlighter.inputScroll.bind(this.highlighter));
     document.getElementById("input-text").addEventListener("mouseup", this.highlighter.inputMouseup.bind(this.highlighter));
     document.getElementById("input-text").addEventListener("mouseup", this.highlighter.inputMouseup.bind(this.highlighter));
     document.getElementById("input-text").addEventListener("mousemove", this.highlighter.inputMousemove.bind(this.highlighter));
     document.getElementById("input-text").addEventListener("mousemove", this.highlighter.inputMousemove.bind(this.highlighter));
     this.addMultiEventListener("#input-text", "mousedown dblclick select",  this.highlighter.inputMousedown, this.highlighter);
     this.addMultiEventListener("#input-text", "mousedown dblclick select",  this.highlighter.inputMousedown, this.highlighter);
+    document.querySelector("#input-file .close").addEventListener("click", this.input.clearIoClick.bind(this.input));
 
 
     // Output
     // Output
     document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output));
     document.getElementById("save-to-file").addEventListener("click", this.output.saveClick.bind(this.output));
+    document.getElementById("copy-output").addEventListener("click", this.output.copyClick.bind(this.output));
     document.getElementById("switch").addEventListener("click", this.output.switchClick.bind(this.output));
     document.getElementById("switch").addEventListener("click", this.output.switchClick.bind(this.output));
     document.getElementById("undo-switch").addEventListener("click", this.output.undoSwitchClick.bind(this.output));
     document.getElementById("undo-switch").addEventListener("click", this.output.undoSwitchClick.bind(this.output));
     document.getElementById("maximise-output").addEventListener("click", this.output.maximiseOutputClick.bind(this.output));
     document.getElementById("maximise-output").addEventListener("click", this.output.maximiseOutputClick.bind(this.output));
@@ -153,18 +159,24 @@ Manager.prototype.initialiseEventListeners = function() {
     this.addMultiEventListener("#output-text", "mousedown dblclick select",  this.highlighter.outputMousedown, this.highlighter);
     this.addMultiEventListener("#output-text", "mousedown dblclick select",  this.highlighter.outputMousedown, this.highlighter);
     this.addMultiEventListener("#output-html", "mousedown dblclick select",  this.highlighter.outputHtmlMousedown, this.highlighter);
     this.addMultiEventListener("#output-html", "mousedown dblclick select",  this.highlighter.outputHtmlMousedown, this.highlighter);
     this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output);
     this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output);
+    this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output);
+    this.addDynamicListener("#output-file-slice", "click", this.output.displayFileSlice, this.output);
+    document.getElementById("show-file-overlay").addEventListener("click", this.output.showFileOverlayClick.bind(this.output));
 
 
     // Options
     // Options
     document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options));
     document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options));
     document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options));
     document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.switchChange.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.switchChange.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.setWordWrap.bind(this.options));
     $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox", this.options.setWordWrap.bind(this.options));
+    $(document).on("switchChange.bootstrapSwitch", ".option-item input:checkbox#useMetaKey", this.bindings.updateKeybList.bind(this.bindings));
     this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options);
     this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options);
     this.addDynamicListener(".option-item select", "change", this.options.selectChange, this.options);
     document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options));
     document.getElementById("theme").addEventListener("change", this.options.themeChange.bind(this.options));
+    document.getElementById("logLevel").addEventListener("change", this.options.logLevelChange.bind(this.options));
 
 
     // Misc
     // Misc
+    window.addEventListener("keydown", this.bindings.parseInput.bind(this.bindings));
     document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
     document.getElementById("alert-close").addEventListener("click", this.app.alertCloseClick.bind(this.app));
 };
 };
 
 

+ 21 - 2
src/web/OptionsWaiter.js

@@ -8,8 +8,9 @@
  * @constructor
  * @constructor
  * @param {App} app - The main view object for CyberChef.
  * @param {App} app - The main view object for CyberChef.
  */
  */
-const OptionsWaiter = function(app) {
+const OptionsWaiter = function(app, manager) {
     this.app = app;
     this.app = app;
+    this.manager = manager;
 };
 };
 
 
 
 
@@ -86,6 +87,7 @@ OptionsWaiter.prototype.switchChange = function(e, state) {
     const el = e.target;
     const el = e.target;
     const option = el.getAttribute("option");
     const option = el.getAttribute("option");
 
 
+    log.debug(`Setting ${option} to ${state}`);
     this.app.options[option] = state;
     this.app.options[option] = state;
 
 
     if (this.app.isLocalStorageAvailable())
     if (this.app.isLocalStorageAvailable())
@@ -102,8 +104,10 @@ OptionsWaiter.prototype.switchChange = function(e, state) {
 OptionsWaiter.prototype.numberChange = function(e) {
 OptionsWaiter.prototype.numberChange = function(e) {
     const el = e.target;
     const el = e.target;
     const option = el.getAttribute("option");
     const option = el.getAttribute("option");
+    const val = parseInt(el.value, 10);
 
 
-    this.app.options[option] = parseInt(el.value, 10);
+    log.debug(`Setting ${option} to ${val}`);
+    this.app.options[option] = val;
 
 
     if (this.app.isLocalStorageAvailable())
     if (this.app.isLocalStorageAvailable())
         localStorage.setItem("options", JSON.stringify(this.app.options));
         localStorage.setItem("options", JSON.stringify(this.app.options));
@@ -120,6 +124,7 @@ OptionsWaiter.prototype.selectChange = function(e) {
     const el = e.target;
     const el = e.target;
     const option = el.getAttribute("option");
     const option = el.getAttribute("option");
 
 
+    log.debug(`Setting ${option} to ${el.value}`);
     this.app.options[option] = el.value;
     this.app.options[option] = el.value;
 
 
     if (this.app.isLocalStorageAvailable())
     if (this.app.isLocalStorageAvailable())
@@ -149,6 +154,8 @@ OptionsWaiter.prototype.setWordWrap = function() {
 
 
 /**
 /**
  * Changes the theme by setting the class of the <html> element.
  * Changes the theme by setting the class of the <html> element.
+ *
+ * @param {Event} e
  */
  */
 OptionsWaiter.prototype.themeChange = function (e) {
 OptionsWaiter.prototype.themeChange = function (e) {
     const themeClass = e.target.value;
     const themeClass = e.target.value;
@@ -156,4 +163,16 @@ OptionsWaiter.prototype.themeChange = function (e) {
     document.querySelector(":root").className = themeClass;
     document.querySelector(":root").className = themeClass;
 };
 };
 
 
+
+/**
+ * Changes the console logging level.
+ *
+ * @param {Event} e
+ */
+OptionsWaiter.prototype.logLevelChange = function (e) {
+    const level = e.target.value;
+    log.setLevel(level, false);
+    this.manager.worker.setLogLevel();
+};
+
 export default OptionsWaiter;
 export default OptionsWaiter;

+ 211 - 49
src/web/OutputWaiter.js

@@ -1,4 +1,5 @@
 import Utils from "../core/Utils.js";
 import Utils from "../core/Utils.js";
+import FileSaver from "file-saver";
 
 
 
 
 /**
 /**
@@ -15,6 +16,9 @@ import Utils from "../core/Utils.js";
 const OutputWaiter = function(app, manager) {
 const OutputWaiter = function(app, manager) {
     this.app = app;
     this.app = app;
     this.manager = manager;
     this.manager = manager;
+
+    this.dishBuffer = null;
+    this.dishStr = null;
 };
 };
 
 
 
 
@@ -31,47 +35,151 @@ OutputWaiter.prototype.get = function() {
 /**
 /**
  * Sets the output in the output textarea.
  * Sets the output in the output textarea.
  *
  *
- * @param {string} dataStr - The output string/HTML
+ * @param {string|ArrayBuffer} data - The output string/HTML/ArrayBuffer
  * @param {string} type - The data type of the output
  * @param {string} type - The data type of the output
  * @param {number} duration - The length of time (ms) it took to generate the output
  * @param {number} duration - The length of time (ms) it took to generate the output
+ * @param {boolean} [preserveBuffer=false] - Whether to preserve the dishBuffer
  */
  */
-OutputWaiter.prototype.set = function(dataStr, type, duration) {
+OutputWaiter.prototype.set = function(data, type, duration, preserveBuffer) {
+    log.debug("Output type: " + type);
     const outputText = document.getElementById("output-text");
     const outputText = document.getElementById("output-text");
     const outputHtml = document.getElementById("output-html");
     const outputHtml = document.getElementById("output-html");
+    const outputFile = document.getElementById("output-file");
     const outputHighlighter = document.getElementById("output-highlighter");
     const outputHighlighter = document.getElementById("output-highlighter");
     const inputHighlighter = document.getElementById("input-highlighter");
     const inputHighlighter = document.getElementById("input-highlighter");
+    let scriptElements, lines, length;
 
 
-    if (type === "html") {
-        outputText.style.display = "none";
-        outputHtml.style.display = "block";
-        outputHighlighter.display = "none";
-        inputHighlighter.display = "none";
-
-        outputText.value = "";
-        outputHtml.innerHTML = dataStr;
-
-        // Execute script sections
-        const scriptElements = outputHtml.querySelectorAll("script");
-        for (let i = 0; i < scriptElements.length; i++) {
-            try {
-                eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval
-            } catch (err) {
-                console.error(err);
-            }
-        }
-    } else {
-        outputText.style.display = "block";
-        outputHtml.style.display = "none";
-        outputHighlighter.display = "block";
-        inputHighlighter.display = "block";
+    if (!preserveBuffer) {
+        this.closeFile();
+        document.getElementById("show-file-overlay").style.display = "none";
+    }
 
 
-        outputText.value = Utils.printable(dataStr, true);
-        outputHtml.innerHTML = "";
+    switch (type) {
+        case "html":
+            outputText.style.display = "none";
+            outputHtml.style.display = "block";
+            outputFile.style.display = "none";
+            outputHighlighter.display = "none";
+            inputHighlighter.display = "none";
+
+            outputText.value = "";
+            outputHtml.innerHTML = data;
+            this.dishStr = Utils.stripHtmlTags(data, true);
+            length = data.length;
+            lines = this.dishStr.count("\n") + 1;
+
+            // Execute script sections
+            scriptElements = outputHtml.querySelectorAll("script");
+            for (let i = 0; i < scriptElements.length; i++) {
+                try {
+                    eval(scriptElements[i].innerHTML); // eslint-disable-line no-eval
+                } catch (err) {
+                    log.error(err);
+                }
+            }
+            break;
+        case "ArrayBuffer":
+            outputText.style.display = "block";
+            outputHtml.style.display = "none";
+            outputHighlighter.display = "none";
+            inputHighlighter.display = "none";
+
+            outputText.value = "";
+            outputHtml.innerHTML = "";
+            this.dishStr = "";
+            length = data.byteLength;
+
+            this.setFile(data);
+            break;
+        case "string":
+        default:
+            outputText.style.display = "block";
+            outputHtml.style.display = "none";
+            outputFile.style.display = "none";
+            outputHighlighter.display = "block";
+            inputHighlighter.display = "block";
+
+            outputText.value = Utils.printable(data, true);
+            outputHtml.innerHTML = "";
+
+            lines = data.count("\n") + 1;
+            length = data.length;
+            this.dishStr = data;
+            break;
     }
     }
 
 
     this.manager.highlighter.removeHighlights();
     this.manager.highlighter.removeHighlights();
-    const lines = dataStr.count("\n") + 1;
-    this.setOutputInfo(dataStr.length, lines, duration);
+    this.setOutputInfo(length, lines, duration);
+};
+
+
+/**
+ * Shows file details.
+ *
+ * @param {ArrayBuffer} buf
+ */
+OutputWaiter.prototype.setFile = function(buf) {
+    this.dishBuffer = buf;
+    const file = new File([buf], "output.dat");
+
+    // Display file overlay in output area with details
+    const fileOverlay = document.getElementById("output-file"),
+        fileSize = document.getElementById("output-file-size");
+
+    fileOverlay.style.display = "block";
+    fileSize.textContent = file.size.toLocaleString() + " bytes";
+};
+
+
+/**
+ * Removes the output file and nulls its memory.
+ */
+OutputWaiter.prototype.closeFile = function() {
+    this.dishBuffer = null;
+    document.getElementById("output-file").style.display = "none";
+};
+
+
+/**
+ * Handler for file download events.
+ */
+OutputWaiter.prototype.downloadFile = function() {
+    this.filename = window.prompt("Please enter a filename:", this.filename || "download.dat");
+    const file = new File([this.dishBuffer], this.filename);
+
+    if (this.filename) FileSaver.saveAs(file, this.filename, false);
+};
+
+
+/**
+ * Handler for file slice display events.
+ */
+OutputWaiter.prototype.displayFileSlice = function() {
+    const startTime = new Date().getTime(),
+        showFileOverlay = document.getElementById("show-file-overlay"),
+        sliceFromEl = document.getElementById("output-file-slice-from"),
+        sliceToEl = document.getElementById("output-file-slice-to"),
+        sliceFrom = parseInt(sliceFromEl.value, 10),
+        sliceTo = parseInt(sliceToEl.value, 10),
+        str = Utils.arrayBufferToStr(this.dishBuffer.slice(sliceFrom, sliceTo));
+
+    showFileOverlay.style.display = "block";
+    this.set(str, "string", new Date().getTime() - startTime, true);
+};
+
+
+/**
+ * Handler for show file overlay events.
+ *
+ * @param {Event} e
+ */
+OutputWaiter.prototype.showFileOverlayClick = function(e) {
+    const outputFile = document.getElementById("output-file"),
+        showFileOverlay = e.target;
+
+    outputFile.style.display = "block";
+    showFileOverlay.style.display = "none";
+    this.setOutputInfo(this.dishBuffer.byteLength, null, 0);
 };
 };
 
 
 
 
@@ -86,13 +194,17 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) {
     let width = length.toString().length;
     let width = length.toString().length;
     width = width < 4 ? 4 : width;
     width = width < 4 ? 4 : width;
 
 
-    const lengthStr = Utils.pad(length.toString(), width, " ").replace(/ /g, "&nbsp;");
-    const linesStr  = Utils.pad(lines.toString(), width, " ").replace(/ /g, "&nbsp;");
-    const timeStr   = Utils.pad(duration.toString() + "ms", width, " ").replace(/ /g, "&nbsp;");
+    const lengthStr = length.toString().padStart(width, " ").replace(/ /g, "&nbsp;");
+    const timeStr = (duration.toString() + "ms").padStart(width, " ").replace(/ /g, "&nbsp;");
+
+    let msg = "time: " + timeStr + "<br>length: " + lengthStr;
+
+    if (typeof lines === "number") {
+        const linesStr = lines.toString().padStart(width, " ").replace(/ /g, "&nbsp;");
+        msg += "<br>lines: " + linesStr;
+    }
 
 
-    document.getElementById("output-info").innerHTML = "time: " + timeStr +
-        "<br>length: " + lengthStr +
-        "<br>lines: " + linesStr;
+    document.getElementById("output-info").innerHTML = msg;
     document.getElementById("input-selection-info").innerHTML = "";
     document.getElementById("input-selection-info").innerHTML = "";
     document.getElementById("output-selection-info").innerHTML = "";
     document.getElementById("output-selection-info").innerHTML = "";
 };
 };
@@ -105,17 +217,20 @@ OutputWaiter.prototype.setOutputInfo = function(length, lines, duration) {
 OutputWaiter.prototype.adjustWidth = function() {
 OutputWaiter.prototype.adjustWidth = function() {
     const output         = document.getElementById("output");
     const output         = document.getElementById("output");
     const saveToFile     = document.getElementById("save-to-file");
     const saveToFile     = document.getElementById("save-to-file");
+    const copyOutput     = document.getElementById("copy-output");
     const switchIO       = document.getElementById("switch");
     const switchIO       = document.getElementById("switch");
     const undoSwitch     = document.getElementById("undo-switch");
     const undoSwitch     = document.getElementById("undo-switch");
     const maximiseOutput = document.getElementById("maximise-output");
     const maximiseOutput = document.getElementById("maximise-output");
 
 
     if (output.clientWidth < 680) {
     if (output.clientWidth < 680) {
         saveToFile.childNodes[1].nodeValue = "";
         saveToFile.childNodes[1].nodeValue = "";
+        copyOutput.childNodes[1].nodeValue = "";
         switchIO.childNodes[1].nodeValue = "";
         switchIO.childNodes[1].nodeValue = "";
         undoSwitch.childNodes[1].nodeValue = "";
         undoSwitch.childNodes[1].nodeValue = "";
         maximiseOutput.childNodes[1].nodeValue = "";
         maximiseOutput.childNodes[1].nodeValue = "";
     } else {
     } else {
         saveToFile.childNodes[1].nodeValue = " Save to file";
         saveToFile.childNodes[1].nodeValue = " Save to file";
+        copyOutput.childNodes[1].nodeValue = " Copy output";
         switchIO.childNodes[1].nodeValue = " Move output to input";
         switchIO.childNodes[1].nodeValue = " Move output to input";
         undoSwitch.childNodes[1].nodeValue = " Undo";
         undoSwitch.childNodes[1].nodeValue = " Undo";
         maximiseOutput.childNodes[1].nodeValue =
         maximiseOutput.childNodes[1].nodeValue =
@@ -126,24 +241,51 @@ OutputWaiter.prototype.adjustWidth = function() {
 
 
 /**
 /**
  * Handler for save click events.
  * Handler for save click events.
- * Saves the current output to a file, downloaded as a URL octet stream.
+ * Saves the current output to a file.
  */
  */
 OutputWaiter.prototype.saveClick = function() {
 OutputWaiter.prototype.saveClick = function() {
-    const data = Utils.toBase64(this.app.dishStr);
-    const filename = window.prompt("Please enter a filename:", "download.dat");
+    if (!this.dishBuffer) {
+        this.dishBuffer = new Uint8Array(Utils.strToCharcode(this.dishStr)).buffer;
+    }
+    this.downloadFile();
+};
 
 
-    if (filename) {
-        const el = document.createElement("a");
-        el.setAttribute("href", "data:application/octet-stream;base64;charset=utf-8," + data);
-        el.setAttribute("download", filename);
 
 
-        // Firefox requires that the element be added to the DOM before it can be clicked
-        el.style.display = "none";
-        document.body.appendChild(el);
+/**
+ * Handler for copy click events.
+ * Copies the output to the clipboard.
+ */
+OutputWaiter.prototype.copyClick = function() {
+    // Create invisible textarea to populate with the raw dishStr (not the printable version that
+    // contains dots instead of the actual bytes)
+    const textarea = document.createElement("textarea");
+    textarea.style.position = "fixed";
+    textarea.style.top = 0;
+    textarea.style.left = 0;
+    textarea.style.width = 0;
+    textarea.style.height = 0;
+    textarea.style.border = "none";
+
+    textarea.value = this.dishStr;
+    document.body.appendChild(textarea);
+
+    // Select and copy the contents of this textarea
+    let success = false;
+    try {
+        textarea.select();
+        success = this.dishStr && document.execCommand("copy");
+    } catch (err) {
+        success = false;
+    }
 
 
-        el.click();
-        el.remove();
+    if (success) {
+        this.app.alert("Copied raw output successfully.", "success", 2000);
+    } else {
+        this.app.alert("Sorry, the output could not be copied.", "danger", 2000);
     }
     }
+
+    // Clean up
+    document.body.removeChild(textarea);
 };
 };
 
 
 
 
@@ -154,7 +296,17 @@ OutputWaiter.prototype.saveClick = function() {
 OutputWaiter.prototype.switchClick = function() {
 OutputWaiter.prototype.switchClick = function() {
     this.switchOrigData = this.manager.input.get();
     this.switchOrigData = this.manager.input.get();
     document.getElementById("undo-switch").disabled = false;
     document.getElementById("undo-switch").disabled = false;
-    this.app.setInput(this.app.dishStr);
+    if (this.dishBuffer) {
+        this.manager.input.setFile(new File([this.dishBuffer], "output.dat"));
+        this.manager.input.handleLoaderMessage({
+            data: {
+                progress: 100,
+                fileBuffer: this.dishBuffer
+            }
+        });
+    } else {
+        this.app.setInput(this.dishStr);
+    }
 };
 };
 
 
 
 
@@ -169,7 +321,7 @@ OutputWaiter.prototype.undoSwitchClick = function() {
 
 
 /**
 /**
  * Handler for file switch click events.
  * Handler for file switch click events.
- * Moves a files data for items created via Utils.displayFilesAsHTML to the input.
+ * Moves a file's data for items created via Utils.displayFilesAsHTML to the input.
  */
  */
 OutputWaiter.prototype.fileSwitch = function(e) {
 OutputWaiter.prototype.fileSwitch = function(e) {
     e.preventDefault();
     e.preventDefault();
@@ -241,4 +393,14 @@ OutputWaiter.prototype.setStatusMsg = function(msg) {
     el.textContent = msg;
     el.textContent = msg;
 };
 };
 
 
+
+/**
+ * Returns true if the output contains carriage returns
+ *
+ * @returns {boolean}
+ */
+OutputWaiter.prototype.containsCR = function() {
+    return this.dishStr.indexOf("\r") >= 0;
+};
+
 export default OutputWaiter;
 export default OutputWaiter;

+ 4 - 2
src/web/RecipeWaiter.js

@@ -253,7 +253,7 @@ RecipeWaiter.prototype.breakpointClick = function(e) {
  */
  */
 RecipeWaiter.prototype.operationDblclick = function(e) {
 RecipeWaiter.prototype.operationDblclick = function(e) {
     e.target.remove();
     e.target.remove();
-    window.dispatchEvent(this.manager.statechange);
+    this.opRemove(e);
 };
 };
 
 
 
 
@@ -266,7 +266,7 @@ RecipeWaiter.prototype.operationDblclick = function(e) {
  */
  */
 RecipeWaiter.prototype.operationChildDblclick = function(e) {
 RecipeWaiter.prototype.operationChildDblclick = function(e) {
     e.target.parentNode.remove();
     e.target.parentNode.remove();
-    window.dispatchEvent(this.manager.statechange);
+    this.opRemove(e);
 };
 };
 
 
 
 
@@ -421,6 +421,7 @@ RecipeWaiter.prototype.dropdownToggleClick = function(e) {
  * @param {event} e
  * @param {event} e
  */
  */
 RecipeWaiter.prototype.opAdd = function(e) {
 RecipeWaiter.prototype.opAdd = function(e) {
+    log.debug(`'${e.target.querySelector(".arg-title").textContent}' added to recipe`);
     window.dispatchEvent(this.manager.statechange);
     window.dispatchEvent(this.manager.statechange);
 };
 };
 
 
@@ -433,6 +434,7 @@ RecipeWaiter.prototype.opAdd = function(e) {
  * @param {event} e
  * @param {event} e
  */
  */
 RecipeWaiter.prototype.opRemove = function(e) {
 RecipeWaiter.prototype.opRemove = function(e) {
+    log.debug("Operation removed from recipe");
     window.dispatchEvent(this.manager.statechange);
     window.dispatchEvent(this.manager.statechange);
 };
 };
 
 

+ 25 - 5
src/web/WorkerWaiter.js

@@ -1,4 +1,3 @@
-import Utils from "../core/Utils.js";
 import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker.js";
 import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker.js";
 
 
 /**
 /**
@@ -22,8 +21,10 @@ const WorkerWaiter = function(app, manager) {
  * Sets up the ChefWorker and associated listeners.
  * Sets up the ChefWorker and associated listeners.
  */
  */
 WorkerWaiter.prototype.registerChefWorker = function() {
 WorkerWaiter.prototype.registerChefWorker = function() {
+    log.debug("Registering new ChefWorker");
     this.chefWorker = new ChefWorker();
     this.chefWorker = new ChefWorker();
     this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this));
     this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this));
+    this.setLogLevel();
 
 
     let docURL = document.location.href.split(/[#?]/)[0];
     let docURL = document.location.href.split(/[#?]/)[0];
     const index = docURL.lastIndexOf("/");
     const index = docURL.lastIndexOf("/");
@@ -41,8 +42,10 @@ WorkerWaiter.prototype.registerChefWorker = function() {
  */
  */
 WorkerWaiter.prototype.handleChefMessage = function(e) {
 WorkerWaiter.prototype.handleChefMessage = function(e) {
     const r = e.data;
     const r = e.data;
+    log.debug("Receiving '" + r.action + "' from ChefWorker");
+
     switch (r.action) {
     switch (r.action) {
-        case "bakeSuccess":
+        case "bakeComplete":
             this.bakingComplete(r.data);
             this.bakingComplete(r.data);
             break;
             break;
         case "bakeError":
         case "bakeError":
@@ -53,12 +56,14 @@ WorkerWaiter.prototype.handleChefMessage = function(e) {
             break;
             break;
         case "workerLoaded":
         case "workerLoaded":
             this.app.workerLoaded = true;
             this.app.workerLoaded = true;
+            log.debug("ChefWorker loaded");
             this.app.loaded();
             this.app.loaded();
             break;
             break;
         case "statusMessage":
         case "statusMessage":
             this.manager.output.setStatusMsg(r.data);
             this.manager.output.setStatusMsg(r.data);
             break;
             break;
         case "optionUpdate":
         case "optionUpdate":
+            log.debug(`Setting ${r.data.option} to ${r.data.value}`);
             this.app.options[r.data.option] = r.data.value;
             this.app.options[r.data.option] = r.data.value;
             break;
             break;
         case "setRegisters":
         case "setRegisters":
@@ -68,7 +73,7 @@ WorkerWaiter.prototype.handleChefMessage = function(e) {
             this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction);
             this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction);
             break;
             break;
         default:
         default:
-            console.error("Unrecognised message from ChefWorker", e);
+            log.error("Unrecognised message from ChefWorker", e);
             break;
             break;
     }
     }
 };
 };
@@ -111,10 +116,10 @@ WorkerWaiter.prototype.bakingComplete = function(response) {
         this.app.handleError(response.error);
         this.app.handleError(response.error);
     }
     }
 
 
-    this.app.dishStr  = response.type === "html" ? Utils.stripHtmlTags(response.result, true) : response.result;
     this.app.progress = response.progress;
     this.app.progress = response.progress;
     this.manager.recipe.updateBreakpointIndicator(response.progress);
     this.manager.recipe.updateBreakpointIndicator(response.progress);
     this.manager.output.set(response.result, response.type, response.duration);
     this.manager.output.set(response.result, response.type, response.duration);
+    log.debug("--- Bake complete ---");
 };
 };
 
 
 
 
@@ -147,7 +152,7 @@ WorkerWaiter.prototype.bake = function(input, recipeConfig, options, progress, s
  * Asks the ChefWorker to run a silent bake, forcing the browser to load and cache all the relevant
  * Asks the ChefWorker to run a silent bake, forcing the browser to load and cache all the relevant
  * JavaScript code needed to do a real bake.
  * JavaScript code needed to do a real bake.
  *
  *
- * @param {Objectp[]} [recipeConfig]
+ * @param {Object[]} [recipeConfig]
  */
  */
 WorkerWaiter.prototype.silentBake = function(recipeConfig) {
 WorkerWaiter.prototype.silentBake = function(recipeConfig) {
     this.chefWorker.postMessage({
     this.chefWorker.postMessage({
@@ -180,4 +185,19 @@ WorkerWaiter.prototype.highlight = function(recipeConfig, direction, pos) {
 };
 };
 
 
 
 
+/**
+ * Sets the console log level in the worker.
+ *
+ * @param {string} level
+ */
+WorkerWaiter.prototype.setLogLevel = function(level) {
+    if (!this.chefWorker) return;
+
+    this.chefWorker.postMessage({
+        action: "setLogLevel",
+        data: log.getLevel()
+    });
+};
+
+
 export default WorkerWaiter;
 export default WorkerWaiter;

+ 104 - 34
src/web/html/index.html

@@ -1,17 +1,17 @@
 <!-- htmlmin:ignore --><!--
 <!-- htmlmin:ignore --><!--
     CyberChef - The Cyber Swiss Army Knife
     CyberChef - The Cyber Swiss Army Knife
-    
+
     @copyright Crown Copyright 2016
     @copyright Crown Copyright 2016
     @license Apache-2.0
     @license Apache-2.0
-    
+
       Copyright 2016 Crown Copyright
       Copyright 2016 Crown Copyright
-    
+
     Licensed under the Apache License, Version 2.0 (the "License");
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
     You may obtain a copy of the License at
-    
+
         http://www.apache.org/licenses/LICENSE-2.0
         http://www.apache.org/licenses/LICENSE-2.0
-    
+
     Unless required by applicable law or agreed to in writing, software
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,7 +24,7 @@
     <head>
     <head>
         <meta charset="UTF-8">
         <meta charset="UTF-8">
         <title>CyberChef</title>
         <title>CyberChef</title>
-        
+
         <meta name="copyright" content="Crown Copyright 2016" />
         <meta name="copyright" content="Crown Copyright 2016" />
         <meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
         <meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
         <meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip,  md5, sha1, aes, des, blowfish, xor" />
         <meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip,  md5, sha1, aes, des, blowfish, xor" />
@@ -59,6 +59,9 @@
                 "for i in range(additional): Pylon()",
                 "for i in range(additional): Pylon()",
                 "(creating unresolved tension...",
                 "(creating unresolved tension...",
                 "Symlinking emacs and vim to ed...",
                 "Symlinking emacs and vim to ed...",
+                "Training branch predictor...",
+                "Timing cache hits...",
+                "Speculatively executing recipes..."
             ];
             ];
 
 
             // Shuffle array using Durstenfeld algorithm
             // Shuffle array using Durstenfeld algorithm
@@ -115,7 +118,7 @@
                     <span id="notice">
                     <span id="notice">
                         <script type="text/javascript">
                         <script type="text/javascript">
                             // Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
                             // Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
-                            if (navigator.userAgent && navigator.userAgent.match(/MSIE \d\d?\./)) {
+                            if (navigator.userAgent && navigator.userAgent.match(/Trident/)) {
                                 document.write("Internet Explorer is not supported, please use Firefox or Chrome instead");
                                 document.write("Internet Explorer is not supported, please use Firefox or Chrome instead");
                                 alert("Internet Explorer is not supported, please use Firefox or Chrome instead");
                                 alert("Internet Explorer is not supported, please use Firefox or Chrome instead");
                             }
                             }
@@ -135,11 +138,11 @@
                     <ul id="search-results" class="op-list"></ul>
                     <ul id="search-results" class="op-list"></ul>
                     <div id="categories" class="panel-group no-select"></div>
                     <div id="categories" class="panel-group no-select"></div>
                 </div>
                 </div>
-                
+
                 <div id="recipe" class="split split-horizontal no-select">
                 <div id="recipe" class="split split-horizontal no-select">
                     <div class="title no-select">Recipe</div>
                     <div class="title no-select">Recipe</div>
                     <ul id="rec-list" class="list-area no-select"></ul>
                     <ul id="rec-list" class="list-area no-select"></ul>
-                    
+
                     <div id="controls" class="no-select">
                     <div id="controls" class="no-select">
                         <div id="operational-controls">
                         <div id="operational-controls">
                             <div id="bake-group">
                             <div id="bake-group">
@@ -152,13 +155,13 @@
                                     <div>Auto Bake</div>
                                     <div>Auto Bake</div>
                                 </label>
                                 </label>
                             </div>
                             </div>
-                            
+
                             <div class="btn-group" style="padding-top: 10px;">
                             <div class="btn-group" style="padding-top: 10px;">
                                 <button type="button" class="btn btn-default" id="step"><img aria-hidden="true" src="<%- require('../static/images/step-16x16.png') %>" alt="Footstep Icon"/> Step through</button>
                                 <button type="button" class="btn btn-default" id="step"><img aria-hidden="true" src="<%- require('../static/images/step-16x16.png') %>" alt="Footstep Icon"/> Step through</button>
                                 <button type="button" class="btn btn-default" id="clr-breaks"><img aria-hidden="true" src="<%- require('../static/images/erase-16x16.png') %>" alt="Eraser Icon"/> Clear breakpoints</button>
                                 <button type="button" class="btn btn-default" id="clr-breaks"><img aria-hidden="true" src="<%- require('../static/images/erase-16x16.png') %>" alt="Eraser Icon"/> Clear breakpoints</button>
                             </div>
                             </div>
                         </div>
                         </div>
-                        
+
                         <div class="btn-group-vertical" id="extra-controls">
                         <div class="btn-group-vertical" id="extra-controls">
                             <button type="button" class="btn btn-default" id="save"><img aria-hidden="true" src="<%- require('../static/images/save-16x16.png') %>" alt="Save Icon"/> Save recipe</button>
                             <button type="button" class="btn btn-default" id="save"><img aria-hidden="true" src="<%- require('../static/images/save-16x16.png') %>" alt="Save Icon"/> Save recipe</button>
                             <button type="button" class="btn btn-default" id="load"><img aria-hidden="true" src="<%- require('../static/images/open_yellow-16x16.png') %>" alt="Open Icon"/> Load recipe</button>
                             <button type="button" class="btn btn-default" id="load"><img aria-hidden="true" src="<%- require('../static/images/open_yellow-16x16.png') %>" alt="Open Icon"/> Load recipe</button>
@@ -166,7 +169,7 @@
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
-                
+
                 <div class="split split-horizontal" id="IO">
                 <div class="split split-horizontal" id="IO">
                     <div id="input" class="split no-select">
                     <div id="input" class="split no-select">
                         <div class="title no-select">
                         <div class="title no-select">
@@ -181,14 +184,29 @@
                         <div class="textarea-wrapper no-select">
                         <div class="textarea-wrapper no-select">
                             <div id="input-highlighter" class="no-select"></div>
                             <div id="input-highlighter" class="no-select"></div>
                             <textarea id="input-text"></textarea>
                             <textarea id="input-text"></textarea>
+                            <div id="input-file">
+                                <div style="position: relative; height: 100%;">
+                                    <div class="card">
+                                        <img aria-hidden="true" src="<%- require('../static/images/file-128x128.png') %>" alt="File icon"/>
+                                        <div class="card-body">
+                                            <button type="button" class="close" id="input-file-close">&times;</button>
+                                            Name: <span id="input-file-name"></span><br>
+                                            Size: <span id="input-file-size"></span><br>
+                                            Type: <span id="input-file-type"></span><br>
+                                            Loaded: <span id="input-file-loaded"></span>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div id="output" class="split">
                     <div id="output" class="split">
                         <div class="title no-select">
                         <div class="title no-select">
                             <label for="output-text">Output</label>
                             <label for="output-text">Output</label>
                             <div class="btn-group io-btn-group">
                             <div class="btn-group io-btn-group">
                                 <button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
                                 <button type="button" class="btn btn-default btn-sm" id="save-to-file" title="Save to file"><img aria-hidden="true" src="<%- require('../static/images/save_as-16x16.png') %>" alt="Save Icon"/> Save to file</button>
+                                <button type="button" class="btn btn-default btn-sm" id="copy-output" title="Copy output"><img aria-hidden="true" src="<%- require('../static/images/copy-16x16.png') %>" alt="Copy Icon"/> Copy raw output</button>
                                 <button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
                                 <button type="button" class="btn btn-default btn-sm" id="switch" title="Move output to input"><img aria-hidden="true" src="<%- require('../static/images/switch-16x16.png') %>" alt="Switch Icon"/> Move output to input</button>
                                 <button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img aria-hidden="true" src="<%- require('../static/images/undo-16x16.png') %>" alt="Undo Icon"/> Undo</button>
                                 <button type="button" class="btn btn-default btn-sm" id="undo-switch" title="Undo move" disabled="disabled"><img aria-hidden="true" src="<%- require('../static/images/undo-16x16.png') %>" alt="Undo Icon"/> Undo</button>
                                 <button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img aria-hidden="true" src="<%- require('../static/images/maximise-16x16.png') %>" alt="Maximise Icon"/> Max</button>
                                 <button type="button" class="btn btn-default btn-sm" id="maximise-output" title="Maximise"><img aria-hidden="true" src="<%- require('../static/images/maximise-16x16.png') %>" alt="Maximise Icon"/> Max</button>
@@ -201,6 +219,26 @@
                             <div id="output-highlighter" class="no-select"></div>
                             <div id="output-highlighter" class="no-select"></div>
                             <div id="output-html"></div>
                             <div id="output-html"></div>
                             <textarea id="output-text" readonly="readonly"></textarea>
                             <textarea id="output-text" readonly="readonly"></textarea>
+                            <img id="show-file-overlay" aria-hidden="true" src="<%- require('../static/images/file-32x32.png') %>" alt="Show file overlay" title="Show file overlay"/>
+                            <div id="output-file">
+                                <div style="position: relative; height: 100%;">
+                                    <div class="card">
+                                        <img aria-hidden="true" src="<%- require('../static/images/file-128x128.png') %>" alt="File icon"/>
+                                        <div class="card-body">
+                                            Size: <span id="output-file-size"></span><br>
+                                            <button id="output-file-download" type="button" class="btn btn-primary">Download</button>
+                                            <div class="input-group">
+                                                <span class="input-group-btn">
+                                                    <button id="output-file-slice" type="button" class="btn btn-default" title="View slice">&#x1f50d;</button>
+                                                </span>
+                                                <input type="number" class="form-control" id="output-file-slice-from" placeholder="From" value="0" step="1024" min="0">
+                                                <div class="input-group-addon">to</div>
+                                                <input type="number" class="form-control" id="output-file-slice-to" placeholder="To" value="1024" step="1024" min="0">
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
                             <div id="output-loader">
                             <div id="output-loader">
                                 <div class="loader"></div>
                                 <div class="loader"></div>
                                 <div class="loading-msg"></div>
                                 <div class="loading-msg"></div>
@@ -210,7 +248,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="save-modal" tabindex="-1" role="dialog">
         <div class="modal" id="save-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -261,7 +299,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="load-modal" tabindex="-1" role="dialog">
         <div class="modal" id="load-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -287,7 +325,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="options-modal" tabindex="-1" role="dialog">
         <div class="modal" id="options-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -307,27 +345,46 @@
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
                             <input type="checkbox" option="updateUrl" id="updateUrl" checked />
                             <input type="checkbox" option="updateUrl" id="updateUrl" checked />
-                            <label for="updateUrl"> Update the URL when the input or recipe changes </label>
+                            <label for="updateUrl"> Update the URL when the input or recipe changes</label>
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
                             <input type="checkbox" option="showHighlighter" id="showHighlighter" checked />
                             <input type="checkbox" option="showHighlighter" id="showHighlighter" checked />
-                            <label for="showHighlighter"> Highlight selected bytes in output and input (when possible) </label>
+                            <label for="showHighlighter"> Highlight selected bytes in output and input (when possible)</label>
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
                             <input type="checkbox" option="treatAsUtf8" id="treatAsUtf8" checked />
                             <input type="checkbox" option="treatAsUtf8" id="treatAsUtf8" checked />
-                            <label for="treatAsUtf8"> Treat output as UTF-8 if possible </label>
+                            <label for="treatAsUtf8"> Treat output as UTF-8 if possible</label>
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
                             <input type="checkbox" option="wordWrap" id="wordWrap" checked />
                             <input type="checkbox" option="wordWrap" id="wordWrap" checked />
-                            <label for="wordWrap"> Word wrap the input and output </label>
+                            <label for="wordWrap"> Word wrap the input and output</label>
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
                             <input type="checkbox" option="showErrors" id="showErrors" checked />
                             <input type="checkbox" option="showErrors" id="showErrors" checked />
-                            <label for="showErrors"> Operation error reporting (recommended) </label>
+                            <label for="showErrors"> Operation error reporting (recommended)</label>
+                        </div>
+                        <div class="option-item">
+                            <input type="checkbox" option="useMetaKey" id="useMetaKey" />
+                            <label for="useMetaKey"> Use meta key for keybindings (Windows ⊞/Command ⌘)</label>
                         </div>
                         </div>
                         <div class="option-item">
                         <div class="option-item">
                             <input type="number" option="errorTimeout" id="errorTimeout" />
                             <input type="number" option="errorTimeout" id="errorTimeout" />
-                            <label for="errorTimeout"> Operation error timeout in ms (0 for never) </label>
+                            <label for="errorTimeout"> Operation error timeout in ms (0 for never)</label>
+                        </div>
+                        <div class="option-item">
+                            <input type="number" option="ioDisplayThreshold" id="ioDisplayThreshold" />
+                            <label for="ioDisplayThreshold"> Size threshold for treating the input and output as a file (KiB)</label>
+                        </div>
+                        <div class="option-item">
+                            <select option="logLevel" id="logLevel">
+                                <option value="silent">Silent</option>
+                                <option value="error">Error</option>
+                                <option value="warn">Warn</option>
+                                <option value="info">Info</option>
+                                <option value="debug">Debug</option>
+                                <option value="trace">Trace</option>
+                            </select>
+                            <label for="logLevel"> Console logging level</label>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="modal-footer">
                     <div class="modal-footer">
@@ -337,7 +394,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="favourites-modal" tabindex="-1" role="dialog">
         <div class="modal" id="favourites-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -364,7 +421,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="support-modal" tabindex="-1" role="dialog">
         <div class="modal" id="support-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -380,6 +437,11 @@
                         </p>
                         </p>
                         <p>&copy; Crown Copyright 2016.</p>
                         <p>&copy; Crown Copyright 2016.</p>
                         <p>Released under the Apache Licence, Version 2.0.</p>
                         <p>Released under the Apache Licence, Version 2.0.</p>
+                        <p>
+                            <a href="https://gitter.im/gchq/CyberChef">
+                                <img src="<%- require('../static/images/gitter-badge.svg') %>">
+                            </a>
+                        </p>
                         <br>
                         <br>
                         <br>
                         <br>
                         <div>
                         <div>
@@ -396,6 +458,10 @@
                                     <img aria-hidden="true" src="<%- require('../static/images/speech-16x16.png') %>" alt="Speech Balloon Icon"/>
                                     <img aria-hidden="true" src="<%- require('../static/images/speech-16x16.png') %>" alt="Speech Balloon Icon"/>
                                     About
                                     About
                                 </a></li>
                                 </a></li>
+                                <li role="presentation"><a href="#keybindings" aria-controls="messages" role="tab" data-toggle="tab">
+                                    <img aria-hidden="true" src="<%- require('../static/images/code-16x16.png') %>" alt="List Icon"/>
+                                    Keybindings
+                                </a></li>
                             </ul>
                             </ul>
                             <div class="tab-content">
                             <div class="tab-content">
                                 <div role="tabpanel" class="tab-pane active" id="faqs">
                                 <div role="tabpanel" class="tab-pane active" id="faqs">
@@ -414,7 +480,7 @@
                                             <li><a href="#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw">Convert data from a hexdump, then decompress</a></li>
                                             <li><a href="#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw">Convert data from a hexdump, then decompress</a></li>
                                             <li><a href="#recipe=RC4(%7B'option':'UTF8','string':'secret'%7D,'Hex','Hex')Disassemble_x86('64','Full%20x86%20architecture',16,0,true,true)&input=MjFkZGQyNTQwMTYwZWU2NWZlMDc3NzEwM2YyYTM5ZmJlNWJjYjZhYTBhYWJkNDE0ZjkwYzZjYWY1MzEyNzU0YWY3NzRiNzZiM2JiY2QxOTNjYjNkZGZkYmM1YTI2NTMzYTY4NmI1OWI4ZmVkNGQzODBkNDc0NDIwMWFlYzIwNDA1MDcxMzhlMmZlMmIzOTUwNDQ2ZGIzMWQyYmM2MjliZTRkM2YyZWIwMDQzYzI5M2Q3YTVkMjk2MmMwMGZlNmRhMzAwNzJkOGM1YTZiNGZlN2Q4NTlhMDQwZWVhZjI5OTczMzYzMDJmNWEwZWMxOQ">Decrypt and disassemble shellcode</a></li>
                                             <li><a href="#recipe=RC4(%7B'option':'UTF8','string':'secret'%7D,'Hex','Hex')Disassemble_x86('64','Full%20x86%20architecture',16,0,true,true)&input=MjFkZGQyNTQwMTYwZWU2NWZlMDc3NzEwM2YyYTM5ZmJlNWJjYjZhYTBhYWJkNDE0ZjkwYzZjYWY1MzEyNzU0YWY3NzRiNzZiM2JiY2QxOTNjYjNkZGZkYmM1YTI2NTMzYTY4NmI1OWI4ZmVkNGQzODBkNDc0NDIwMWFlYzIwNDA1MDcxMzhlMmZlMmIzOTUwNDQ2ZGIzMWQyYmM2MjliZTRkM2YyZWIwMDQzYzI5M2Q3YTVkMjk2MmMwMGZlNmRhMzAwNzJkOGM1YTZiNGZlN2Q4NTlhMDQwZWVhZjI5OTczMzYzMDJmNWEwZWMxOQ">Decrypt and disassemble shellcode</a></li>
                                             <li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA">Display multiple timestamps as full dates</a></li>
                                             <li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA">Display multiple timestamps as full dates</a></li>
-                                            <li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA">Carry out different operations on data of different types</a></li>
+                                            <li><a href="#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">Carry out different operations on data of different types</a></li>
                                             <li><a href="#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">Use parts of the input as arguments to operations</a></li>
                                             <li><a href="#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">Use parts of the input as arguments to operations</a></li>
                                         </ul>
                                         </ul>
                                     </div>
                                     </div>
@@ -424,8 +490,9 @@
                                         </a>
                                         </a>
                                     </blockquote>
                                     </blockquote>
                                     <div class="collapse" id="faq-load-files">
                                     <div class="collapse" id="faq-load-files">
-                                        <p>Yes! Just drag your file over the input box and drop it. The contents of the file will be converted into hexadecimal and the 'From Hex' operation will be added to the beginning of the recipe (if it's not already there). This is so that special characters like carriage returns aren't removed by your browser.</p>
-                                        <p>Please note that loading large files is likely to cause a crash. There's not a lot that can be done about this - browsers just aren't very good at handling and displaying large amounts of data.</p>
+                                        <p>Yes! Just drag your file over the input box and drop it.</p>
+                                        <p>CyberChef can handle files up to around 500MB (depending on your browser), however some of the operations may take a very long time to run over this much data.</p>
+                                        <p>If the output is larger than a certain threshold (default 1MiB), it will be presented to you as a file available for download. Slices of the file can be viewed in the output if you need to inspect them.</p>
                                     </div>
                                     </div>
                                     <blockquote>
                                     <blockquote>
                                         <a data-toggle="collapse" data-target="#faq-fork">
                                         <a data-toggle="collapse" data-target="#faq-fork">
@@ -449,28 +516,31 @@
                                 <div role="tabpanel" class="tab-pane" id="about" style="padding: 20px;">
                                 <div role="tabpanel" class="tab-pane" id="about" style="padding: 20px;">
                                     <h5><strong>What</strong></h5>
                                     <h5><strong>What</strong></h5>
                                     <p>A simple, intuitive web app for analysing and decoding data without having to deal with complex tools or programming languages. CyberChef encourages both technical and non-technical people to explore data formats, encryption and compression.</p><br>
                                     <p>A simple, intuitive web app for analysing and decoding data without having to deal with complex tools or programming languages. CyberChef encourages both technical and non-technical people to explore data formats, encryption and compression.</p><br>
-                                    
+
                                     <h5><strong>Why</strong></h5>
                                     <h5><strong>Why</strong></h5>
                                     <p>Digital data comes in all shapes, sizes and formats in the modern world – CyberChef helps to make sense of this data all on one easy-to-use platform.</p><br>
                                     <p>Digital data comes in all shapes, sizes and formats in the modern world – CyberChef helps to make sense of this data all on one easy-to-use platform.</p><br>
 
 
-                                    
+
                                     <h5><strong>How</strong></h5>
                                     <h5><strong>How</strong></h5>
                                     <p>The interface is designed with simplicity at its heart. Complex techniques are now as trivial as drag-and-drop. Simple functions can be combined to build up a "recipe", potentially resulting in complex analysis, which can be shared with other users and used with their input.</p>
                                     <p>The interface is designed with simplicity at its heart. Complex techniques are now as trivial as drag-and-drop. Simple functions can be combined to build up a "recipe", potentially resulting in complex analysis, which can be shared with other users and used with their input.</p>
                                     <p>For those comfortable writing code, CyberChef is a quick and efficient way to prototype solutions to a problem which can then be scripted once proven to work.</p><br>
                                     <p>For those comfortable writing code, CyberChef is a quick and efficient way to prototype solutions to a problem which can then be scripted once proven to work.</p><br>
 
 
-                                    
+
                                     <h5><strong>Who</strong></h5>
                                     <h5><strong>Who</strong></h5>
                                     <p>It is expected that CyberChef will be useful for cybersecurity and antivirus companies. It should also appeal to the academic world and any individuals or companies involved in the analysis of digital data, be that software developers, analysts, mathematicians or casual puzzle solvers.</p><br>
                                     <p>It is expected that CyberChef will be useful for cybersecurity and antivirus companies. It should also appeal to the academic world and any individuals or companies involved in the analysis of digital data, be that software developers, analysts, mathematicians or casual puzzle solvers.</p><br>
 
 
-                                    
+
                                     <h5><strong>Aim</strong></h5>
                                     <h5><strong>Aim</strong></h5>
                                     <p>It is hoped that by releasing CyberChef through <a href="https://github.com/gchq/CyberChef">GitHub</a>, contributions can be added which can be rolled out into future versions of the tool.</p><br>
                                     <p>It is hoped that by releasing CyberChef through <a href="https://github.com/gchq/CyberChef">GitHub</a>, contributions can be added which can be rolled out into future versions of the tool.</p><br>
 
 
 
 
                                     <br>
                                     <br>
-                                    <p>There are around 150 useful operations in CyberChef for anyone working on anything vaguely Internet-related, whether you just want to convert a timestamp to a different format, decompress gzipped data, create a SHA3 hash, or parse an X.509 certificate to find out who issued it.</p>
+                                    <p>There are around 200 useful operations in CyberChef for anyone working on anything vaguely Internet-related, whether you just want to convert a timestamp to a different format, decompress gzipped data, create a SHA3 hash, or parse an X.509 certificate to find out who issued it.</p>
                                     <p>It’s the Cyber Swiss Army Knife.</p>
                                     <p>It’s the Cyber Swiss Army Knife.</p>
                                 </div>
                                 </div>
+                                <div role="tabpanel" class="tab-pane" id="keybindings" style="padding: 20px;">
+                                    <table class="table table-condensed table-bordered table-hover" id="keybList"></table>
+                                </div>
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
@@ -483,7 +553,7 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
         <div class="modal" id="confirm-modal" tabindex="-1" role="dialog">
         <div class="modal" id="confirm-modal" tabindex="-1" role="dialog">
             <div class="modal-dialog modal-lg">
             <div class="modal-dialog modal-lg">
                 <div class="modal-content">
                 <div class="modal-content">
@@ -504,6 +574,6 @@
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
-        
+
     </body>
     </body>
 </html>
 </html>

+ 11 - 11
src/web/index.js

@@ -38,14 +38,17 @@ function main() {
     ];
     ];
 
 
     const defaultOptions = {
     const defaultOptions = {
-        updateUrl:         true,
-        showHighlighter:   true,
-        treatAsUtf8:       true,
-        wordWrap:          true,
-        showErrors:        true,
-        errorTimeout:      4000,
-        attemptHighlight:  true,
-        theme:             "classic",
+        updateUrl:           true,
+        showHighlighter:     true,
+        treatAsUtf8:         true,
+        wordWrap:            true,
+        showErrors:          true,
+        errorTimeout:        4000,
+        attemptHighlight:    true,
+        theme:               "classic",
+        useMetaKey:          false,
+        ioDisplayThreshold:  512,
+        logLevel:            "info"
     };
     };
 
 
     document.removeEventListener("DOMContentLoaded", main, false);
     document.removeEventListener("DOMContentLoaded", main, false);
@@ -53,9 +56,6 @@ function main() {
     window.app.setup();
     window.app.setup();
 }
 }
 
 
-// Fix issues with browsers that don't support console.log()
-window.console = console || {log: function() {}, error: function() {}};
-
 window.compileTime = moment.tz(COMPILE_TIME, "DD/MM/YYYY HH:mm:ss z", "UTC").valueOf();
 window.compileTime = moment.tz(COMPILE_TIME, "DD/MM/YYYY HH:mm:ss z", "UTC").valueOf();
 window.compileMessage = COMPILE_MSG;
 window.compileMessage = COMPILE_MSG;
 
 

BIN
src/web/static/images/copy-16x16.png


BIN
src/web/static/images/file-128x128.png


BIN
src/web/static/images/file-32x32.png


+ 1 - 0
src/web/static/images/fork_me.png


+ 53 - 0
src/web/stylesheets/components/_pane.css

@@ -28,3 +28,56 @@
     margin: 0;
     margin: 0;
     padding: 0;
     padding: 0;
 }
 }
+
+.card {
+    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
+    transition: 0.3s;
+    width: 400px;
+    height: 150px;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    font-family: var(--primary-font-family);
+    color: var(--primary-font-colour);
+    line-height: 30px;
+    background-color: var(--primary-background-colour);
+}
+
+.card:hover {
+    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
+}
+
+.card>img {
+    float: left;
+    width: 128px;
+    height: 128px;
+    margin-left: 10px;
+    margin-top: 11px;
+}
+
+.card-body .close {
+    position: absolute;
+    right: 10px;
+    top: 10px;
+}
+
+.card-body {
+    float: left;
+    padding: 16px;
+    width: 250px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    user-select: text;
+}
+
+.card-body>.btn {
+    margin-bottom: 15px;
+    margin-top: 5px;
+}
+
+.card input[type=number] {
+    padding-right: 6px;
+    padding-left: 6px;
+}

+ 22 - 1
src/web/stylesheets/layout/_io.css

@@ -39,7 +39,7 @@
 }
 }
 
 
 .textarea-wrapper textarea,
 .textarea-wrapper textarea,
-.textarea-wrapper div {
+.textarea-wrapper>div {
     font-family: var(--fixed-width-font-family);
     font-family: var(--fixed-width-font-family);
     font-size: var(--fixed-width-font-size);
     font-size: var(--fixed-width-font-size);
     color: var(--fixed-width-font-colour);
     color: var(--fixed-width-font-colour);
@@ -77,6 +77,25 @@
     transition: all 0.5s ease;
     transition: all 0.5s ease;
 }
 }
 
 
+#input-file,
+#output-file {
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    background-color: var(--title-background-colour);
+    display: none;
+}
+
+#show-file-overlay {
+    position: absolute;
+    right: 15px;
+    top: 15px;
+    cursor: pointer;
+    display: none;
+}
+
 .io-btn-group {
 .io-btn-group {
     float: right;
     float: right;
     margin-top: -4px;
     margin-top: -4px;
@@ -92,6 +111,8 @@
     font-family: var(--fixed-width-font-family);
     font-family: var(--fixed-width-font-family);
     font-weight: normal;
     font-weight: normal;
     font-size: 8pt;
     font-size: 8pt;
+    display: flex;
+    align-items: center;
 }
 }
 
 
 #input-info {
 #input-info {

+ 11 - 1
src/web/stylesheets/utils/_overrides.css

@@ -64,7 +64,8 @@ a:focus {
 .alert,
 .alert,
 .modal-content,
 .modal-content,
 .tooltip-inner,
 .tooltip-inner,
-.dropdown-menu {
+.dropdown-menu,
+.input-group-addon {
     border-radius: 0 !important;
     border-radius: 0 !important;
 }
 }
 
 
@@ -187,6 +188,15 @@ optgroup {
     color: var(--primary-font-colour);
     color: var(--primary-font-colour);
 }
 }
 
 
+.input-group-addon:not(:first-child):not(:last-child) {
+    border-left: 0;
+    border-right: 0;
+}
+
+.input-group-btn:first-child>.btn {
+    border-right: 0;
+}
+
 
 
 /* Bootstrap-switch */
 /* Bootstrap-switch */
 
 

+ 5 - 0
test/index.js

@@ -1,3 +1,5 @@
+/* eslint no-console: 0 */
+
 /**
 /**
  * TestRunner.js
  * TestRunner.js
  *
  *
@@ -25,6 +27,9 @@ import "./tests/operations/Hash.js";
 import "./tests/operations/Image.js";
 import "./tests/operations/Image.js";
 import "./tests/operations/MorseCode.js";
 import "./tests/operations/MorseCode.js";
 import "./tests/operations/MS.js";
 import "./tests/operations/MS.js";
+import "./tests/operations/PHP.js";
+import "./tests/operations/NetBIOS.js";
+import "./tests/operations/OTP.js";
 import "./tests/operations/StrUtils.js";
 import "./tests/operations/StrUtils.js";
 import "./tests/operations/SeqUtils.js";
 import "./tests/operations/SeqUtils.js";
 
 

+ 1298 - 0
test/tests/operations/Cipher.js

@@ -2,6 +2,7 @@
  * Cipher tests.
  * Cipher tests.
  *
  *
  * @author Matt C [matt@artemisbot.uk]
  * @author Matt C [matt@artemisbot.uk]
+ * @author n1474335 [n1474335@gmail.com]
  *
  *
  * @copyright Crown Copyright 2017
  * @copyright Crown Copyright 2017
  * @license Apache-2.0
  * @license Apache-2.0
@@ -75,4 +76,1301 @@ TestRegister.addTests([
             }
             }
         ],
         ],
     },
     },
+
+    /**
+     * Ciphers
+     *
+     * The following expectedOutputs were generated using the following command format:
+     * > openssl enc -aes-128-cbc -in test.txt -out test.enc -K "00112233445566778899aabbccddeeff" -iv "00112233445566778899aabbccddeeff"
+     * > xxd -p test.enc | tr -d '\n' | xclip -selection clipboard
+     *
+     * All random data blocks (binary input, keys and IVs) were generated from /dev/urandom using dd:
+     * > dd if=/dev/urandom of=key.txt bs=16 count=1
+     */
+    {
+        name: "AES Encrypt: no key",
+        input: "",
+        expectedOutput: `Invalid key length: 0 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`,
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-CBC, no IV, ASCII",
+        input: "The quick brown fox jumps over the lazy dog.",
+        expectedOutput: "2ef6c3fdb1314b5c2c326a2087fe1a82d5e73bf605ec8431d73e847187fc1c8fbbe969c177df1ecdf8c13f2f505f9498",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-CBC with IV, ASCII",
+        input: "The quick brown fox jumps over the lazy dog.",
+        expectedOutput: "4fa077d50cc71a57393e7b542c4e3aea0fb75383b97083f2f568ffc13c0e7a47502ec6d9f25744a061a3a5e55fe95e8d",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "CBC", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-CFB, ASCII",
+        input: "The quick brown fox jumps over the lazy dog.",
+        expectedOutput: "369e1c9e5a85b0520f3e61eecc37759246ad0a02cae7a99a3d250ae39cad4743385375cf63720d52ae8cdfb9",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "CFB", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-OFB, ASCII",
+        input: "The quick brown fox jumps over the lazy dog.",
+        expectedOutput: "369e1c9e5a85b0520f3e61eecc37759288cb378c5fa9c675bd6c4ede0ae6a925eaebc8e0a6162d2a000ddc0f",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "OFB", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-CTR, ASCII",
+        input: "The quick brown fox jumps over the lazy dog.",
+        expectedOutput: "369e1c9e5a85b0520f3e61eecc37759206f6f1ba63527af96fae3b15a921844df2e542902a4f0525dbb4146b",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "CTR", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-ECB, ASCII",
+        input: "The quick brown fox jumps over the lazy dog.",
+        expectedOutput: "2ef6c3fdb1314b5c2c326a2087fe1a8238c5a5db7dff38f6f4eb75b2e55cab3d8d6113eb8d3517223b4545fcdb4c5a48",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": ""},
+                    "ECB", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-GCM, ASCII",
+        input: "The quick brown fox jumps over the lazy dog.",
+        expectedOutput: `d0bcace0fa3a214b0ac3cbb4ac2caaf97b965f172f66d2a4ec6304a15a4072f1b28a6f9b80473f86bfa47b2c
+
+Tag: 16a3e732a605cc9ca29108f742ca0743`,
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": ""},
+                    "GCM", "Raw", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-CBC, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "bf2ccb148e5df181a46f39764047e24fc94cc46bbe6c8d160fc25a977e4b630883e9e04d3eeae3ccbb2d57a4c22e61909f2b6d7b24940abe95d356ce986294270d0513e0ffe7a9928fa6669e1aaae4379310281dc27c0bb9e254684b2ecd7f5f944c8218f3bc680570399a508dfe4b65",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-CFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "17211941bb2fa43d54d9fa59072436422a55be7a2be164cf5ec4e50e7a0035094ab684dab8d45a4515ae95c4136ded98898f74d4ecc4ac57ae682a985031ecb7518ddea6c8d816349801aa22ff0b6ac1784d169060efcd9fb77d564477038eb09bb4e1ce",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-OFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "17211941bb2fa43d54d9fa5907243642bfd805201c130c8600566720cf87562011f0872598f1e69cfe541bb864de7ed68201e0a34284157b581984dab3fe2cb0f20cb80d0046740df3e149ec4c92c0e81f2dc439a6f3a05c5ef505eae6308b301c673cfa",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "OFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-CTR, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "17211941bb2fa43d54d9fa5907243642baf08c837003bf24d7b81a911ce41bd31de8a92f6dc6d11135b70c73ea167c3fc4ea78234f58652d25e23245dbcb895bf4165092d0515ae8f14230f8a34b06957f24ba4b24db741490e7edcd6e5310945cc159fc",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CTR", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-GCM, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: `fa17fcbf5e8763322c1b0c8562e1512ed9d702ef70c1643572b9de3e34ae6b535e6c1b992432aa6d06fb6f80c861262aef66e7c26035afe77bd3861261e4e092b523f058f8ebef2143db21bc16d02f7a011efb07419300cb41c3b884d1d8d6a766b8963c
+
+Tag: fa6bbb34c8cde65a3d7b93fb094fc84f`,
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "GCM", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-128-ECB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "869c057637a58cc3363bcc4bcfa62702abf85dff44300eb9fdcfb9d845772c8acb557c8d540baae2489c6758abef83d81b74239bef87c6c944c1b00ca160882bc15be9a6a3de4e6a50a2eab8b635c634027ed7eae4c1d2f08477c38b7dc24f6915da235bc3051f3a50736b14db8863e4",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "ECB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-192-CBC, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "1aec90cd7f629ef68243881f3e2b793a548cbcdad69631995a6bd0c8aea1e948d8a5f3f2b7e7f9b77da77434c92a6257a9f57e937b883f4400511b990888a0b1d27c0a4b7f298e6f50b563135edc9fa7d8eceb6bc8163e6153a20cf07aa1e705bc5cb3a37b0452b4019cef8000d7c1b7",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-192-CFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "fc370a6c013b3c05430fbce810cb97d39cb0a587320a4c1b57d0c0d08e93cb0d1221abba9df09b4b1332ce923b289f92000e6b4f7fbc55dfdab9179081d8c36ef4a0e3d3a49f1564715c5d3e88f8bf6d3dd77944f22f99a03b5535a3cd47bc44d4a9665c",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-192-OFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "fc370a6c013b3c05430fbce810cb97d33605d11b2531c8833bc3e818003bbd7dd58b2a38d10d44d25d11bd96228b264a4d2aad1d0a7af2cfad0e70c1ade305433e95cb0ee693447f6877a59a4be5c070d19afba23ff10caf5ecfa7a9c2877b8df23d61f2",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "OFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-192-CTR, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "fc370a6c013b3c05430fbce810cb97d340525303ae59c5e9b73ad5ff3e65ce3abf00431e0a292d990f732a397de589420827beb1c28623c56972eb2ddf0cf3f82e3c30e155df7f64a530419c28fc51a9091c73df78e73958bee1d1acd8676c9c0f1915ca",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CTR", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-192-GCM, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: `ed22946f96964d300b45f5ce2d9601ba87682da1a603c90e6d4f7738729b0602f613ee392c9bfc7792594474f1213fb99185851f02ece4df0e93995e49f97aa4d0a337d7a80d83e4219dae5a3d36658f8659cdd5ed7c32707f98656fab7fb43f7a61e37c
+
+Tag: be17cb31edb77f648b9d1032b235b33d`,
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "GCM", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-192-ECB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "56ef533db50a3b33951a76acede52b7d54fbae7fb07da20daa3e2731e5721ee4c13ab15ac80748c14dece982310530ad65480512a4cf70201473fb7bc3480446bc86b1ff9b4517c4c1f656bc236fab1aca276ae5af25f5871b671823f3cb3e426da059dd83a13f125bd6cfe600c331b0",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "ECB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-256-CBC, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "bc60a7613559e23e8a7be8e98a1459003fdb036f33368d8a30156c51464b49472705a4ddae05da96956ce058bb180dd301c5fd58bf6a2ded0d7dd4da85fd5ba43a4297691532bf7f4cd92bfcfd3704faf2f9bd5425049b34433ba90fb85c80646e6cb09ee4e4059e7cd753a2fef8bbad",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-256-CFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "5dc73709da5cb0ac914ae4bcb621fd75169eac5ff13a2dde573f6380ff812e8ddb58f0e9afaec1ff0d6d2af0659e10c05b714ec97481a15f4a7aeb4c6ea84112ce897459b54ed9e77a794f023f2bef1901f013cf435432fca5fb59e2be781916247d2334",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-256-OFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "5dc73709da5cb0ac914ae4bcb621fd75b6e1f909b88733f784b1df8a52dc200440a1076415d009a7c12cac1e8ab76bdc290e6634cd5bf8a416fda8dcfd7910e55fe9d1148cd85d7a59adad39ab089e111d8f8da246e2e874cf5d9ab7552af6308320a5ab",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "OFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-256-CTR, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "5dc73709da5cb0ac914ae4bcb621fd7591356d4169898c986a90b193f4d1f0d5cba1d10b2bfc5aee8a48dce9dba174cecf56f92dddf7eb306d78360000eea7bcb50f696d84a3757a822800ed68f9edf118dc61406bacf64f022717d8cb6010049bf75d7e",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CTR", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-256-GCM, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: `e3f1b236eaf3b9df69df8133a1b417fa42b242d8ad49e4d2f3469aca7e2a41737e4f2c8a0d212143287088fad51743577dc6dfa8ed328ca90113cbeb9b137926b2168cc037bdc371777e6ee02b9d9c017b6054fd83d43b4885fbe9c044a8574f1491a893
+
+Tag: 23ddbd3ee4de33f98a9ea9a170bdf268`,
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "GCM", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Encrypt: AES-256-ECB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "7e8521ba3f356ef692a51841807e141464aadc07bbc0ef2b628b8745bae356d245682a220688afca7be987b60cb120681ed42680ee93a67065619a3beaac11111a6cd88a6afa9e367722cb57df343f8548f2d691b295184da4ed5f3b763aaa8558502cb348ab58e81986337096e90caa",
+        recipeConfig: [
+            {
+                "op": "AES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "ECB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Encrypt: no key",
+        input: "",
+        expectedOutput: `Invalid key length: 0 bytes
+
+DES uses a key length of 8 bytes (64 bits).
+Triple DES uses a key length of 24 bytes (192 bits).`,
+        recipeConfig: [
+            {
+                "op": "DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Encrypt: DES-CBC, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "6500defb824b0eb8ccbf1fa9689c6f5bcc65247d93ecb0e573232824bca82dd41e2361f8fd82ef187de9f3b74f7ba3ca2b4e735f3ca6304fb8dd1675933c576424b1ea72b3219bdab62fce56d49c820d5ac02a4702a6d688e90b0933de97da21e4829e5cf85caae8",
+        recipeConfig: [
+            {
+                "op": "DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Encrypt: DES-CFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "09015087e15b09374bc9edba80ce41e6809e332fc1e988858749fb2f4ebbd6483a6fce01a43271280c07c90e13d517729acac45beef7d088339eb7e084bbbb7459fc8bb592d2ca76b90066dc79b1fbc5e016208e1d02c6e48ab675530f8040e53e1a138b",
+        recipeConfig: [
+            {
+                "op": "DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "CFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Encrypt: DES-OFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "09015087e15b09374d8879bac14dbad851dd08fb131353a8c510acc4570e97720dd159465f1c7da3cac4a50521e1c1ab87e8cf5b0aa0c1d2eaa8a1ed914a26c13b2b0a76a368f08812fc7fa4b7c047f27df0c35e5f53b8a20e2ffc10e55d388cae8070db",
+        recipeConfig: [
+            {
+                "op": "DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "OFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Encrypt: DES-CTR, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "09015087e15b0937ab0ae5a84d66e520893690a6ea066382bf1330e8876cb3aa82ccc634f8f0d458bbe0257df6f4637cdac89f311168ba91208a21ba4bdd13c4b1a92cb93b33364b5b94a5d3d7fba68f6eed5807d9f5afeb7fbffcd94792131d264004ae",
+        recipeConfig: [
+            {
+                "op": "DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "CTR", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Encrypt: DES-ECB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "8dea4c6a35d5f6a419232159a0b039798d0a0b20fd1e559b1d04f8eb1120e8bca6ed5b3a4bc2b23d3b62312e6085d9e837677569fe79a65eba7cb4a2969e099fc1bd649e9c8aeb2c4c519e085db6974819257c20fde70acabc976308cc41635038c91acf5eefff1e",
+        recipeConfig: [
+            {
+                "op": "DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "ECB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Encrypt: no key",
+        input: "",
+        expectedOutput: `Invalid key length: 0 bytes
+
+Triple DES uses a key length of 24 bytes (192 bits).
+DES uses a key length of 8 bytes (64 bits).`,
+        recipeConfig: [
+            {
+                "op": "Triple DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Encrypt: DES-EDE3-CBC, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "f826c9116ea932eb7027a810b5ce21109c4ef2563c9f3ba5e2518f72484e88f8d3f6ff3f334f64bb6bb9ff91b70f6f29c037b10dee5fe16d7f0f41c9a7ecdd83f113a1dd66ab70783ee458c2366bf5fbc016f7c168c43c11d607692a3280e3750a6154a86b62c48d",
+        recipeConfig: [
+            {
+                "op": "Triple DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Encrypt: DES-EDE3-CFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "874d32cd7bdae52c3690875e265a2fac7ced685e5ec4436a6bb5a5c18be185f4526683a5bc7ae86f00523034fb725ab4c8285a6967ccca1b76f6331718c26e12ea67fc924071f81ce0035a9dd31705bcd6467991cae5504d70424e6339459db5b33cbc8a",
+        recipeConfig: [
+            {
+                "op": "Triple DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "CFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Encrypt: DES-EDE3-OFB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "874d32cd7bdae52c8f61672860f715d14819c0270320a8ad71083b38bd8954bbada3c77af641590b00a678524d748668fe3dfa83f71835c411cdbdd8e73a70656324b7faaba16e1d8dba260d8f965fe7a91110134c19076f1eeb46393038c22c559fe490",
+        recipeConfig: [
+            {
+                "op": "Triple DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "OFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Encrypt: DES-EDE3-CTR, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "874d32cd7bdae52c254687e2d7e7093b077af2ec70878f99315f52a21ded5fb10c80a47e6271384335ac47376c758f675484fd7b8be9568aaec643f0d15cffdf3fe54ef3a1b2da50d5d8c7994d7a4a94e0a13a4d437443f0f1f39e93dd13ff06a80c66e4",
+        recipeConfig: [
+            {
+                "op": "Triple DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "CTR", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Encrypt: DES-EDE3-ECB Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "aa81f23d1b3abebd68ac560e051a711c2923843beecddb0f7fe4113bd1874e73cccf3a2a494bb011e154ca2737b4d0eb5978a10316361074ed368d85d5aff5c8555ea101b0a468e58780a74c7830c561674c183c972a2b48931adf789cb16df304e169500f8c95ad",
+        recipeConfig: [
+            {
+                "op": "Triple DES Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "ECB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: no key",
+        input: "",
+        expectedOutput: `Invalid key length: 0 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`,
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Hex", "Raw",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-CBC, no IV, ASCII",
+        input: "2ef6c3fdb1314b5c2c326a2087fe1a82d5e73bf605ec8431d73e847187fc1c8fbbe969c177df1ecdf8c13f2f505f9498",
+        expectedOutput: "The quick brown fox jumps over the lazy dog.",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Hex", "Raw",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-CBC with IV, ASCII",
+        input: "4fa077d50cc71a57393e7b542c4e3aea0fb75383b97083f2f568ffc13c0e7a47502ec6d9f25744a061a3a5e55fe95e8d",
+        expectedOutput: "The quick brown fox jumps over the lazy dog.",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "CBC", "Hex", "Raw",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-CFB, ASCII",
+        input: "369e1c9e5a85b0520f3e61eecc37759246ad0a02cae7a99a3d250ae39cad4743385375cf63720d52ae8cdfb9",
+        expectedOutput: "The quick brown fox jumps over the lazy dog.",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "CFB", "Hex", "Raw",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-OFB, ASCII",
+        input: "369e1c9e5a85b0520f3e61eecc37759288cb378c5fa9c675bd6c4ede0ae6a925eaebc8e0a6162d2a000ddc0f",
+        expectedOutput: "The quick brown fox jumps over the lazy dog.",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "OFB", "Hex", "Raw",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-CTR, ASCII",
+        input: "369e1c9e5a85b0520f3e61eecc37759206f6f1ba63527af96fae3b15a921844df2e542902a4f0525dbb4146b",
+        expectedOutput: "The quick brown fox jumps over the lazy dog.",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    "CTR", "Hex", "Raw",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-ECB, ASCII",
+        input: "2ef6c3fdb1314b5c2c326a2087fe1a8238c5a5db7dff38f6f4eb75b2e55cab3d8d6113eb8d3517223b4545fcdb4c5a48",
+        expectedOutput: "The quick brown fox jumps over the lazy dog.",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": ""},
+                    "ECB", "Hex", "Raw",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-GCM, ASCII",
+        input: "d0bcace0fa3a214b0ac3cbb4ac2caaf97b965f172f66d2a4ec6304a15a4072f1b28a6f9b80473f86bfa47b2c",
+        expectedOutput: "The quick brown fox jumps over the lazy dog.",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
+                    {"option": "Hex", "string": ""},
+                    "GCM", "Hex", "Raw",
+                    {"option": "Hex", "string": "16a3e732a605cc9ca29108f742ca0743"}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-CBC, Binary",
+        input: "bf2ccb148e5df181a46f39764047e24fc94cc46bbe6c8d160fc25a977e4b630883e9e04d3eeae3ccbb2d57a4c22e61909f2b6d7b24940abe95d356ce986294270d0513e0ffe7a9928fa6669e1aaae4379310281dc27c0bb9e254684b2ecd7f5f944c8218f3bc680570399a508dfe4b65",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CBC", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-CFB, Binary",
+        input: "17211941bb2fa43d54d9fa59072436422a55be7a2be164cf5ec4e50e7a0035094ab684dab8d45a4515ae95c4136ded98898f74d4ecc4ac57ae682a985031ecb7518ddea6c8d816349801aa22ff0b6ac1784d169060efcd9fb77d564477038eb09bb4e1ce",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CFB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-OFB, Binary",
+        input: "17211941bb2fa43d54d9fa5907243642bfd805201c130c8600566720cf87562011f0872598f1e69cfe541bb864de7ed68201e0a34284157b581984dab3fe2cb0f20cb80d0046740df3e149ec4c92c0e81f2dc439a6f3a05c5ef505eae6308b301c673cfa",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "OFB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-CTR, Binary",
+        input: "17211941bb2fa43d54d9fa5907243642baf08c837003bf24d7b81a911ce41bd31de8a92f6dc6d11135b70c73ea167c3fc4ea78234f58652d25e23245dbcb895bf4165092d0515ae8f14230f8a34b06957f24ba4b24db741490e7edcd6e5310945cc159fc",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CTR", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-GCM, Binary",
+        input: "fa17fcbf5e8763322c1b0c8562e1512ed9d702ef70c1643572b9de3e34ae6b535e6c1b992432aa6d06fb6f80c861262aef66e7c26035afe77bd3861261e4e092b523f058f8ebef2143db21bc16d02f7a011efb07419300cb41c3b884d1d8d6a766b8963c",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "GCM", "Hex", "Hex",
+                    {"option": "Hex", "string": "fa6bbb34c8cde65a3d7b93fb094fc84f"}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-128-ECB, Binary",
+        input: "869c057637a58cc3363bcc4bcfa62702abf85dff44300eb9fdcfb9d845772c8acb557c8d540baae2489c6758abef83d81b74239bef87c6c944c1b00ca160882bc15be9a6a3de4e6a50a2eab8b635c634027ed7eae4c1d2f08477c38b7dc24f6915da235bc3051f3a50736b14db8863e4",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "ECB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-192-CBC, Binary",
+        input: "1aec90cd7f629ef68243881f3e2b793a548cbcdad69631995a6bd0c8aea1e948d8a5f3f2b7e7f9b77da77434c92a6257a9f57e937b883f4400511b990888a0b1d27c0a4b7f298e6f50b563135edc9fa7d8eceb6bc8163e6153a20cf07aa1e705bc5cb3a37b0452b4019cef8000d7c1b7",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CBC", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-192-CFB, Binary",
+        input: "fc370a6c013b3c05430fbce810cb97d39cb0a587320a4c1b57d0c0d08e93cb0d1221abba9df09b4b1332ce923b289f92000e6b4f7fbc55dfdab9179081d8c36ef4a0e3d3a49f1564715c5d3e88f8bf6d3dd77944f22f99a03b5535a3cd47bc44d4a9665c",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CFB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-192-OFB, Binary",
+        input: "fc370a6c013b3c05430fbce810cb97d33605d11b2531c8833bc3e818003bbd7dd58b2a38d10d44d25d11bd96228b264a4d2aad1d0a7af2cfad0e70c1ade305433e95cb0ee693447f6877a59a4be5c070d19afba23ff10caf5ecfa7a9c2877b8df23d61f2",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "OFB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-192-CTR, Binary",
+        input: "fc370a6c013b3c05430fbce810cb97d340525303ae59c5e9b73ad5ff3e65ce3abf00431e0a292d990f732a397de589420827beb1c28623c56972eb2ddf0cf3f82e3c30e155df7f64a530419c28fc51a9091c73df78e73958bee1d1acd8676c9c0f1915ca",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CTR", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-192-GCM, Binary",
+        input: "ed22946f96964d300b45f5ce2d9601ba87682da1a603c90e6d4f7738729b0602f613ee392c9bfc7792594474f1213fb99185851f02ece4df0e93995e49f97aa4d0a337d7a80d83e4219dae5a3d36658f8659cdd5ed7c32707f98656fab7fb43f7a61e37c",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "GCM", "Hex", "Hex",
+                    {"option": "Hex", "string": "be17cb31edb77f648b9d1032b235b33d"}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-192-ECB, Binary",
+        input: "56ef533db50a3b33951a76acede52b7d54fbae7fb07da20daa3e2731e5721ee4c13ab15ac80748c14dece982310530ad65480512a4cf70201473fb7bc3480446bc86b1ff9b4517c4c1f656bc236fab1aca276ae5af25f5871b671823f3cb3e426da059dd83a13f125bd6cfe600c331b0",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "ECB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-256-CBC, Binary",
+        input: "bc60a7613559e23e8a7be8e98a1459003fdb036f33368d8a30156c51464b49472705a4ddae05da96956ce058bb180dd301c5fd58bf6a2ded0d7dd4da85fd5ba43a4297691532bf7f4cd92bfcfd3704faf2f9bd5425049b34433ba90fb85c80646e6cb09ee4e4059e7cd753a2fef8bbad",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CBC", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-256-CFB, Binary",
+        input: "5dc73709da5cb0ac914ae4bcb621fd75169eac5ff13a2dde573f6380ff812e8ddb58f0e9afaec1ff0d6d2af0659e10c05b714ec97481a15f4a7aeb4c6ea84112ce897459b54ed9e77a794f023f2bef1901f013cf435432fca5fb59e2be781916247d2334",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CFB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-256-OFB, Binary",
+        input: "5dc73709da5cb0ac914ae4bcb621fd75b6e1f909b88733f784b1df8a52dc200440a1076415d009a7c12cac1e8ab76bdc290e6634cd5bf8a416fda8dcfd7910e55fe9d1148cd85d7a59adad39ab089e111d8f8da246e2e874cf5d9ab7552af6308320a5ab",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "OFB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-256-CTR, Binary",
+        input: "5dc73709da5cb0ac914ae4bcb621fd7591356d4169898c986a90b193f4d1f0d5cba1d10b2bfc5aee8a48dce9dba174cecf56f92dddf7eb306d78360000eea7bcb50f696d84a3757a822800ed68f9edf118dc61406bacf64f022717d8cb6010049bf75d7e",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "CTR", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-256-GCM, Binary",
+        input: "e3f1b236eaf3b9df69df8133a1b417fa42b242d8ad49e4d2f3469aca7e2a41737e4f2c8a0d212143287088fad51743577dc6dfa8ed328ca90113cbeb9b137926b2168cc037bdc371777e6ee02b9d9c017b6054fd83d43b4885fbe9c044a8574f1491a893",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "GCM", "Hex", "Hex",
+                    {"option": "Hex", "string": "23ddbd3ee4de33f98a9ea9a170bdf268"}
+                ]
+            }
+        ],
+    },
+    {
+        name: "AES Decrypt: AES-256-ECB, Binary",
+        input: "7e8521ba3f356ef692a51841807e141464aadc07bbc0ef2b628b8745bae356d245682a220688afca7be987b60cb120681ed42680ee93a67065619a3beaac11111a6cd88a6afa9e367722cb57df343f8548f2d691b295184da4ed5f3b763aaa8558502cb348ab58e81986337096e90caa",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "AES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
+                    {"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
+                    "ECB", "Hex", "Hex",
+                    {"option": "Hex", "string": ""}
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Decrypt: no key",
+        input: "",
+        expectedOutput: `Invalid key length: 0 bytes
+
+DES uses a key length of 8 bytes (64 bits).
+Triple DES uses a key length of 24 bytes (192 bits).`,
+        recipeConfig: [
+            {
+                "op": "DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Decrypt: DES-CBC, Binary",
+        input: "6500defb824b0eb8ccbf1fa9689c6f5bcc65247d93ecb0e573232824bca82dd41e2361f8fd82ef187de9f3b74f7ba3ca2b4e735f3ca6304fb8dd1675933c576424b1ea72b3219bdab62fce56d49c820d5ac02a4702a6d688e90b0933de97da21e4829e5cf85caae8",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Decrypt: DES-CFB, Binary",
+        input: "09015087e15b09374bc9edba80ce41e6809e332fc1e988858749fb2f4ebbd6483a6fce01a43271280c07c90e13d517729acac45beef7d088339eb7e084bbbb7459fc8bb592d2ca76b90066dc79b1fbc5e016208e1d02c6e48ab675530f8040e53e1a138b",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "CFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Decrypt: DES-OFB, Binary",
+        input: "09015087e15b09374d8879bac14dbad851dd08fb131353a8c510acc4570e97720dd159465f1c7da3cac4a50521e1c1ab87e8cf5b0aa0c1d2eaa8a1ed914a26c13b2b0a76a368f08812fc7fa4b7c047f27df0c35e5f53b8a20e2ffc10e55d388cae8070db",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "OFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Decrypt: DES-CTR, Binary",
+        input: "09015087e15b0937ab0ae5a84d66e520893690a6ea066382bf1330e8876cb3aa82ccc634f8f0d458bbe0257df6f4637cdac89f311168ba91208a21ba4bdd13c4b1a92cb93b33364b5b94a5d3d7fba68f6eed5807d9f5afeb7fbffcd94792131d264004ae",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "CTR", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "DES Decrypt: DES-ECB, Binary",
+        input: "8dea4c6a35d5f6a419232159a0b039798d0a0b20fd1e559b1d04f8eb1120e8bca6ed5b3a4bc2b23d3b62312e6085d9e837677569fe79a65eba7cb4a2969e099fc1bd649e9c8aeb2c4c519e085db6974819257c20fde70acabc976308cc41635038c91acf5eefff1e",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "58345efb0a64e87e"},
+                    {"option": "Hex", "string": "533ed1378bfd929e"},
+                    "ECB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Decrypt: no key",
+        input: "",
+        expectedOutput: `Invalid key length: 0 bytes
+
+Triple DES uses a key length of 24 bytes (192 bits).
+DES uses a key length of 8 bytes (64 bits).`,
+        recipeConfig: [
+            {
+                "op": "Triple DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Decrypt: DES-EDE3-CBC, Binary",
+        input: "f826c9116ea932eb7027a810b5ce21109c4ef2563c9f3ba5e2518f72484e88f8d3f6ff3f334f64bb6bb9ff91b70f6f29c037b10dee5fe16d7f0f41c9a7ecdd83f113a1dd66ab70783ee458c2366bf5fbc016f7c168c43c11d607692a3280e3750a6154a86b62c48d",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "Triple DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "CBC", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Decrypt: DES-EDE3-CFB, Binary",
+        input: "874d32cd7bdae52c3690875e265a2fac7ced685e5ec4436a6bb5a5c18be185f4526683a5bc7ae86f00523034fb725ab4c8285a6967ccca1b76f6331718c26e12ea67fc924071f81ce0035a9dd31705bcd6467991cae5504d70424e6339459db5b33cbc8a",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "Triple DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "CFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Decrypt: DES-EDE3-OFB, Binary",
+        input: "874d32cd7bdae52c8f61672860f715d14819c0270320a8ad71083b38bd8954bbada3c77af641590b00a678524d748668fe3dfa83f71835c411cdbdd8e73a70656324b7faaba16e1d8dba260d8f965fe7a91110134c19076f1eeb46393038c22c559fe490",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "Triple DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "OFB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Decrypt: DES-EDE3-CTR, Binary",
+        input: "874d32cd7bdae52c254687e2d7e7093b077af2ec70878f99315f52a21ded5fb10c80a47e6271384335ac47376c758f675484fd7b8be9568aaec643f0d15cffdf3fe54ef3a1b2da50d5d8c7994d7a4a94e0a13a4d437443f0f1f39e93dd13ff06a80c66e4",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "Triple DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "CTR", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "Triple DES Decrypt: DES-EDE3-ECB, Binary",
+        input: "aa81f23d1b3abebd68ac560e051a711c2923843beecddb0f7fe4113bd1874e73cccf3a2a494bb011e154ca2737b4d0eb5978a10316361074ed368d85d5aff5c8555ea101b0a468e58780a74c7830c561674c183c972a2b48931adf789cb16df304e169500f8c95ad",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "Triple DES Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "190da55fb54b9e7dd6de05f43bf3347ef203cd34a5829b23"},
+                    {"option": "Hex", "string": "14f67ac044a84da6"},
+                    "ECB", "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "RC2 Encrypt: no key",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "d3644d898b51a544f690b506c3fd0caeb7a1e6097f7ea28f69b909a4d8805c9a05f4cade8b281d3f044fa069374efb90e94723622c86afc17caee394ffbee0abe627de299208460eb981c9d56f9df885091c6c89e2ee173264b2820b8e67675214e6545a05dc0d3f",
+        recipeConfig: [
+            {
+                "op": "RC2 Encrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "RC2 Encrypt: RC2-CBC, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "d25e5bc6c9311ef196d6f21cc4b0274b29fcca366aba5256406e02bf4ae628398f84e7d72ad92025ede76df4752d1510fe9c3492efb1dcf0be2cd41d619e10b9dd5a2304c2efbd3598d3b87f1a21f326d45e65537563436cfb6e4a41ec3733182ddc058f96f74a6c",
+        recipeConfig: [
+            {
+                "op": "RC2 Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "eb970554bb213430f4bb4e5988a6a218"},
+                    {"option": "Hex", "string": "ae817c784a097e0c"},
+                    "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "RC2 Encrypt: RC2-ECB, Binary",
+        input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        expectedOutput: "a160bf23b2a85eaa43d26753e51aaa899f162ec0da7280fffd41b705c5309c7fef2bbb56bf261cab4eadd3a5c69e0a67d45e426d1097187cc9a959b4d979a9d40df26f3dc8d030453fe27701438b78d3ce044330b4b5dca7832537ecf40b914f1b1dc16d4e6d7229",
+        recipeConfig: [
+            {
+                "op": "RC2 Encrypt",
+                "args": [
+                    {"option": "Hex", "string": "eb970554bb213430f4bb4e5988a6a218"},
+                    {"option": "Hex", "string": ""},
+                    "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "RC2 Decrypt: no key",
+        input: "d3644d898b51a544f690b506c3fd0caeb7a1e6097f7ea28f69b909a4d8805c9a05f4cade8b281d3f044fa069374efb90e94723622c86afc17caee394ffbee0abe627de299208460eb981c9d56f9df885091c6c89e2ee173264b2820b8e67675214e6545a05dc0d3f",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "RC2 Decrypt",
+                "args": [
+                    {"option": "Hex", "string": ""},
+                    {"option": "Hex", "string": ""},
+                    "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "RC2 Decrypt: RC2-CBC, Binary",
+        input: "d25e5bc6c9311ef196d6f21cc4b0274b29fcca366aba5256406e02bf4ae628398f84e7d72ad92025ede76df4752d1510fe9c3492efb1dcf0be2cd41d619e10b9dd5a2304c2efbd3598d3b87f1a21f326d45e65537563436cfb6e4a41ec3733182ddc058f96f74a6c",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "RC2 Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "eb970554bb213430f4bb4e5988a6a218"},
+                    {"option": "Hex", "string": "ae817c784a097e0c"},
+                    "Hex", "Hex"
+                ]
+            }
+        ],
+    },
+    {
+        name: "RC2 Decrypt: RC2-ECB, Binary",
+        input: "a160bf23b2a85eaa43d26753e51aaa899f162ec0da7280fffd41b705c5309c7fef2bbb56bf261cab4eadd3a5c69e0a67d45e426d1097187cc9a959b4d979a9d40df26f3dc8d030453fe27701438b78d3ce044330b4b5dca7832537ecf40b914f1b1dc16d4e6d7229",
+        expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
+        recipeConfig: [
+            {
+                "op": "RC2 Decrypt",
+                "args": [
+                    {"option": "Hex", "string": "eb970554bb213430f4bb4e5988a6a218"},
+                    {"option": "Hex", "string": ""},
+                    "Hex", "Hex"
+                ]
+            }
+        ],
+    },
 ]);
 ]);

+ 22 - 0
test/tests/operations/Code.js

@@ -310,4 +310,26 @@ TestRegister.addTests([
             }
             }
         ],
         ],
     },
     },
+    {
+        name: "CSS selector",
+        input: '<div id="test">\n<p class="a">hello</p>\n<p>world</p>\n<p class="a">again</p>\n</div>',
+        expectedOutput: '<p class="a">hello</p>\n<p class="a">again</p>',
+        recipeConfig: [
+            {
+                "op": "CSS selector",
+                "args": ["#test p.a", "\\n"]
+            }
+        ]
+    },
+    {
+        name: "XPath expression",
+        input: '<div id="test">\n<p class="a">hello</p>\n<p>world</p>\n<p class="a">again</p>\n</div>',
+        expectedOutput: '<p class="a">hello</p>\n<p class="a">again</p>',
+        recipeConfig: [
+            {
+                "op": "XPath expression",
+                "args": ["/div/p[@class=\"a\"]", "\\n"]
+            }
+        ]
+    }
 ]);
 ]);

+ 27 - 11
test/tests/operations/FlowControl.js

@@ -37,7 +37,7 @@ TestRegister.addTests([
     },
     },
     {
     {
         name: "Fork, (expect) Error, Merge",
         name: "Fork, (expect) Error, Merge",
-        input: "1\n2\na\n4",
+        input: "1.1\n2.5\na\n3.4",
         expectedError: true,
         expectedError: true,
         recipeConfig: [
         recipeConfig: [
             {
             {
@@ -45,8 +45,8 @@ TestRegister.addTests([
                 args: ["\n", "\n", false],
                 args: ["\n", "\n", false],
             },
             },
             {
             {
-                op: "To Base",
-                args: [16],
+                op: "Object Identifier to Hex",
+                args: [],
             },
             },
             {
             {
                 op: "Merge",
                 op: "Merge",
@@ -60,14 +60,15 @@ TestRegister.addTests([
         expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n",
         expectedOutput: "U29tZSBkYXRhIHdpdGggYSAxIGluIGl0\n53 6f 6d 65 20 64 61 74 61 20 77 69 74 68 20 61 20 32 20 69 6e 20 69 74\n",
         recipeConfig: [
         recipeConfig: [
             {"op": "Fork", "args": ["\\n", "\\n", false]},
             {"op": "Fork", "args": ["\\n", "\\n", false]},
-            {"op": "Conditional Jump", "args": ["1", "2", "10"]},
+            {"op": "Conditional Jump", "args": ["1", false, "skipReturn", "10"]},
             {"op": "To Hex", "args": ["Space"]},
             {"op": "To Hex", "args": ["Space"]},
             {"op": "Return", "args": []},
             {"op": "Return", "args": []},
+            {"op": "Label", "args": ["skipReturn"]},
             {"op": "To Base64", "args": ["A-Za-z0-9+/="]}
             {"op": "To Base64", "args": ["A-Za-z0-9+/="]}
         ]
         ]
     },
     },
     {
     {
-        name: "Jump: skips 0",
+        name: "Jump: Empty Label",
         input: [
         input: [
             "should be changed",
             "should be changed",
         ].join("\n"),
         ].join("\n"),
@@ -77,7 +78,7 @@ TestRegister.addTests([
         recipeConfig: [
         recipeConfig: [
             {
             {
                 op: "Jump",
                 op: "Jump",
-                args: [0, 10],
+                args: ["", 10],
             },
             },
             {
             {
                 op: "Find / Replace",
                 op: "Find / Replace",
@@ -105,7 +106,7 @@ TestRegister.addTests([
         recipeConfig: [
         recipeConfig: [
             {
             {
                 op: "Jump",
                 op: "Jump",
-                args: [1, 10],
+                args: ["skipReplace", 10],
             },
             },
             {
             {
                 op: "Find / Replace",
                 op: "Find / Replace",
@@ -120,6 +121,10 @@ TestRegister.addTests([
                     true,
                     true,
                 ],
                 ],
             },
             },
+            {
+                op: "Label",
+                args: ["skipReplace"]
+            },
         ],
         ],
     },
     },
     {
     {
@@ -137,7 +142,7 @@ TestRegister.addTests([
         recipeConfig: [
         recipeConfig: [
             {
             {
                 op: "Conditional Jump",
                 op: "Conditional Jump",
-                args: ["match", 0, 0],
+                args: ["match", false, "", 0],
             },
             },
             {
             {
                 op: "Find / Replace",
                 op: "Find / Replace",
@@ -212,7 +217,7 @@ TestRegister.addTests([
         recipeConfig: [
         recipeConfig: [
             {
             {
                 op: "Conditional Jump",
                 op: "Conditional Jump",
-                args: ["match", 1, 10],
+                args: ["match", false, "skip match", 10],
             },
             },
             {
             {
                 op: "Find / Replace",
                 op: "Find / Replace",
@@ -227,6 +232,9 @@ TestRegister.addTests([
                     true,
                     true,
                 ],
                 ],
             },
             },
+            {
+                op: "Label", args: ["skip match"],
+            },
             {
             {
                 op: "Find / Replace",
                 op: "Find / Replace",
                 args: [
                 args: [
@@ -251,9 +259,13 @@ TestRegister.addTests([
             "replaced",
             "replaced",
         ].join("\n"),
         ].join("\n"),
         recipeConfig: [
         recipeConfig: [
+            {
+                op: "Label",
+                args: ["back to the beginning"],
+            },
             {
             {
                 op: "Jump",
                 op: "Jump",
-                args: [1],
+                args: ["skip replace"],
             },
             },
             {
             {
                 op: "Find / Replace",
                 op: "Find / Replace",
@@ -268,9 +280,13 @@ TestRegister.addTests([
                     true,
                     true,
                 ],
                 ],
             },
             },
+            {
+                op: "Label",
+                args: ["skip replace"],
+            },
             {
             {
                 op: "Conditional Jump",
                 op: "Conditional Jump",
-                args: ["match", -2, 10],
+                args: ["match", false, "back to the beginning", 10],
             },
             },
         ],
         ],
     },
     },

+ 34 - 0
test/tests/operations/NetBIOS.js

@@ -0,0 +1,34 @@
+/**
+ * NetBIOS tests.
+ *
+ * @author bwhitn [brian.m.whitney@outlook.com]
+ *
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+import TestRegister from "../../TestRegister.js";
+
+TestRegister.addTests([
+    {
+        name: "Encode NetBIOS name",
+        input: "The NetBIOS name",
+        expectedOutput: "FEGIGFCAEOGFHEECEJEPFDCAGOGBGNGF",
+        recipeConfig: [
+            {
+                op: "Encode NetBIOS Name",
+                args: [65],
+            },
+        ],
+    },
+    {
+        name: "Decode NetBIOS Name",
+        input: "FEGIGFCAEOGFHEECEJEPFDCAGOGBGNGF",
+        expectedOutput: "The NetBIOS name",
+        recipeConfig: [
+            {
+                op: "Decode NetBIOS Name",
+                args: [65],
+            },
+        ],
+    },
+]);

+ 23 - 0
test/tests/operations/OTP.js

@@ -0,0 +1,23 @@
+/**
+ * OTP HOTP tests.
+ *
+ * @author bwhitn [brian.m.whitney@outlook.com]
+ *
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+import TestRegister from "../../TestRegister.js";
+
+TestRegister.addTests([
+    {
+        name: "Generate HOTP",
+        input: "12345678901234567890",
+        expectedOutput: "URI: otpauth://hotp/OTPAuthentication?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ\n\nPassword: 755224",
+        recipeConfig: [
+            {
+                op: "Generate HOTP",
+                args: ["", 32, 6, 0],
+            },
+        ],
+    },
+]);

+ 68 - 0
test/tests/operations/PHP.js

@@ -0,0 +1,68 @@
+/**
+ * PHP tests.
+ *
+ * @author Jarmo van Lenthe
+ *
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+
+import TestRegister from "../../TestRegister.js";
+
+TestRegister.addTests([
+    {
+        name: "PHP Deserialize empty array",
+        input: "a:0:{}",
+        expectedOutput: "{}",
+        recipeConfig: [
+            {
+                op: "PHP Deserialize",
+                args: [true],
+            },
+        ],
+    },
+    {
+        name: "PHP Deserialize integer",
+        input: "i:10;",
+        expectedOutput: "10",
+        recipeConfig: [
+            {
+                op: "PHP Deserialize",
+                args: [true],
+            },
+        ],
+    },
+    {
+        name: "PHP Deserialize string",
+        input: "s:17:\"PHP Serialization\";",
+        expectedOutput: "\"PHP Serialization\"",
+        recipeConfig: [
+            {
+                op: "PHP Deserialize",
+                args: [true],
+            },
+        ],
+    },
+    {
+        name: "PHP Deserialize array (JSON)",
+        input: "a:2:{s:1:\"a\";i:10;i:0;a:1:{s:2:\"ab\";b:1;}}",
+        expectedOutput: "{\"a\": 10,\"0\": {\"ab\": true}}",
+        recipeConfig: [
+            {
+                op: "PHP Deserialize",
+                args: [true],
+            },
+        ],
+    },
+    {
+        name: "PHP Deserialize array (non-JSON)",
+        input: "a:2:{s:1:\"a\";i:10;i:0;a:1:{s:2:\"ab\";b:1;}}",
+        expectedOutput: "{\"a\": 10,0: {\"ab\": true}}",
+        recipeConfig: [
+            {
+                op: "PHP Deserialize",
+                args: [false],
+            },
+        ],
+    },
+]);

+ 2 - 2
test/tests/operations/SeqUtils.js

@@ -10,8 +10,8 @@ import TestRegister from "../../TestRegister.js";
 TestRegister.addTests([
 TestRegister.addTests([
     {
     {
         name: "SeqUtils - Numeric sort photos",
         name: "SeqUtils - Numeric sort photos",
-        input: "Photo-1.jpg\nPhoto-4.jpg\nPhoto-2.jpg\nPhoto-3.jpg\n",
-        expectedOutput: "Photo-1.jpg\nPhoto-2.jpg\nPhoto-3.jpg\nPhoto-4.jpg\n",
+        input: "Photo-1.jpg\nPhoto-4.jpg\nPhoto-2.jpg\nPhoto-3.jpg",
+        expectedOutput: "Photo-1.jpg\nPhoto-2.jpg\nPhoto-3.jpg\nPhoto-4.jpg",
         recipeConfig: [
         recipeConfig: [
             {
             {
                 "op": "Sort",
                 "op": "Sort",

+ 2 - 1
webpack.config.js

@@ -35,7 +35,8 @@ module.exports = {
         new webpack.ProvidePlugin({
         new webpack.ProvidePlugin({
             $: "jquery",
             $: "jquery",
             jQuery: "jquery",
             jQuery: "jquery",
-            moment: "moment-timezone"
+            moment: "moment-timezone",
+            log: "loglevel"
         }),
         }),
         new webpack.BannerPlugin({
         new webpack.BannerPlugin({
             banner: banner,
             banner: banner,