From da34cabe0465e35fbd6da61740ec3fec192a826c Mon Sep 17 00:00:00 2001
From: hawkspar <quentin.chevalier@polytechnique.edu>
Date: Wed, 10 Oct 2018 00:33:10 +0200
Subject: [PATCH] Passage en typescript

---
 .gitignore                               |    2 +-
 README.md                                |    2 +-
 configfile_doc.json                      |   10 +-
 package-lock.json                        | 2813 +++++++++++++++++++++-
 package.json                             |   14 +-
 src/graphql/typeDefs/actions.graphql     |    1 -
 src/ldap/{admins.js => admins.ts}        |  129 +-
 src/ldap/{basics.js => basics.ts}        |   92 +-
 src/ldap/config.js                       |   25 -
 ldap_config.json => src/ldap/config.json |   26 +-
 src/ldap/config.ts                       |   16 +
 src/ldap/{users.js => users.ts}          |  148 +-
 src/ldap/{utilities.js => utilities.ts}  |   94 +-
 tsconfig.json                            |    1 +
 14 files changed, 3043 insertions(+), 330 deletions(-)
 rename src/ldap/{admins.js => admins.ts} (80%)
 rename src/ldap/{basics.js => basics.ts} (65%)
 delete mode 100644 src/ldap/config.js
 rename ldap_config.json => src/ldap/config.json (79%)
 create mode 100644 src/ldap/config.ts
 rename src/ldap/{users.js => users.ts} (79%)
 rename src/ldap/{utilities.js => utilities.ts} (74%)

diff --git a/.gitignore b/.gitignore
index 72d9f2b..1459baf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,6 +71,6 @@ doc/
 build/
 
 # Config files
-ldap_connexion_config.json
+connexion_config.json
 sigma-back.service
 .env
\ No newline at end of file
diff --git a/README.md b/README.md
index abeabee..d8c43fe 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@ On peut donc le configurer via des fichiers ou des variables d'environnement.
 
 ### Configuration LDAP
 
-L'API de Sigma nécessite de se connecter au LDAP Frankiz, à la fois pour obtenir des données et pour l'authentification des utilisateurs. Cela est fait à l'aide de la librairie [ldapjs](http://ldapjs.org) pour faire les requêtes au LDAP et [passportJS](http://www.passportjs.org/) pour l'auth.
+L'API de Sigma nécessite de se connecter au LDAP Frankiz, à la fois pour obtenir des données et pour l'authentification des utilisateurs. Cela est fait à l'aide de la librairie [ldapjs](http://ldapjs.org) pour faire les requêtes au LDAP et [passportJS](http://www.passportjs.org/) pour l'authentification.
 
 * La configuration LDAP de base se situe dans [ldap_config.json](ldap_config.json).
 * Elle est importée dans l'application depuis [src/ldap/config.js](src/ldap/config.js).
diff --git a/configfile_doc.json b/configfile_doc.json
index ef667bd..ca587bd 100644
--- a/configfile_doc.json
+++ b/configfile_doc.json
@@ -1,11 +1,11 @@
 {
     "comment": "Ce fichier sert à configurer JSDoc et permet la génération automatique de documentation facilement",
-    "plugins": ["plugins/markdown", "plugins/summarize"],
+    "plugins": ["plugins/markdown", "plugins/summarize", "node_modules/jsdoc-babel"],
     "recurseDepth": 5,
     "source": {
         "include": ["./src","./db","./knexfile.js","./README.md"],
         "exclude": ["./db/migrations","./db/seeds"],
-        "includePattern": ".+\\.js(doc|x)?$",
+        "includePattern": ".+\\.(js|ts)(doc|x)?$",
         "excludePattern": "(^|\\/|\\\\)_"
     },
     "sourceType": "module",
@@ -22,5 +22,11 @@
     "templates": {
         "cleverLinks": true,
         "monospaceLinks": true
+    },
+    "babel": {
+      "extensions": ["ts", "tsx"],
+      "babelrc": false,
+      "presets": [["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/typescript"],
+      "plugins": ["@babel/proposal-class-properties", "@babel/proposal-object-rest-spread"]
     }
 }
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 46f8381..ecfe764 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,66 +19,2154 @@
       "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.0.tgz",
       "integrity": "sha512-QAZIFrfVRkjvMkUHIQKZXZ3La0V5t12w5PWrhihYEabHwzIZV/txQd/kSYHgYPXC4s5OURxsXZop9f0BzI2QIQ=="
     },
+    "@babel/cli": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/cli/-/cli-7.0.0-beta.40.tgz",
+      "integrity": "sha512-7f2pWUlklOYn5USkVPlDw1yX71WsgP8EG7CTn17j4ydtGnYtD+nptTMM4J3EaRgILOgfesVkSOV+lIOnUVOAlg==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^1.6.1",
+        "commander": "^2.8.1",
+        "convert-source-map": "^1.1.0",
+        "fs-readdir-recursive": "^1.0.0",
+        "glob": "^7.0.0",
+        "lodash": "^4.2.0",
+        "output-file-sync": "^2.0.0",
+        "slash": "^1.0.0",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+          "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "micromatch": "^2.1.5",
+            "normalize-path": "^2.0.0"
+          }
+        },
+        "arr-diff": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+          "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "arr-flatten": "^1.0.1"
+          }
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+          "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+          "dev": true,
+          "optional": true
+        },
+        "braces": {
+          "version": "1.8.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+          "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "expand-range": "^1.8.1",
+            "preserve": "^0.2.0",
+            "repeat-element": "^1.1.2"
+          }
+        },
+        "chokidar": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+          "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "anymatch": "^1.3.0",
+            "async-each": "^1.0.0",
+            "fsevents": "^1.0.0",
+            "glob-parent": "^2.0.0",
+            "inherits": "^2.0.1",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^2.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.0.0"
+          }
+        },
+        "expand-brackets": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+          "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-posix-bracket": "^0.1.0"
+          }
+        },
+        "extglob": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+          "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-extglob": "^1.0.0"
+          }
+        },
+        "glob-parent": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+          "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-glob": "^2.0.0"
+          }
+        },
+        "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-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"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        },
+        "micromatch": {
+          "version": "2.3.11",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+          "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "arr-diff": "^2.0.0",
+            "array-unique": "^0.2.1",
+            "braces": "^1.8.2",
+            "expand-brackets": "^0.1.4",
+            "extglob": "^0.3.1",
+            "filename-regex": "^2.0.0",
+            "is-extglob": "^1.0.0",
+            "is-glob": "^2.0.1",
+            "kind-of": "^3.0.2",
+            "normalize-path": "^2.0.1",
+            "object.omit": "^2.0.0",
+            "parse-glob": "^3.0.4",
+            "regex-cache": "^0.4.2"
+          }
+        }
+      }
+    },
     "@babel/code-frame": {
       "version": "7.0.0-beta.44",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz",
       "integrity": "sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g==",
       "dev": true,
       "requires": {
-        "@babel/highlight": "7.0.0-beta.44"
+        "@babel/highlight": "7.0.0-beta.44"
+      }
+    },
+    "@babel/core": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/core/-/core-7.0.0-beta.40.tgz",
+      "integrity": "sha512-jJMjn/EMg89xDGv7uq4BoFg+fHEchSeqNc9YUMnGuAi/FWKBkSsDbhh2y5euw4qaGOFD2jw1le0rvCu5gPUc6Q==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "7.0.0-beta.40",
+        "@babel/generator": "7.0.0-beta.40",
+        "@babel/helpers": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "babylon": "7.0.0-beta.40",
+        "convert-source-map": "^1.1.0",
+        "debug": "^3.0.1",
+        "json5": "^0.5.0",
+        "lodash": "^4.2.0",
+        "micromatch": "^2.3.11",
+        "resolve": "^1.3.2",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.2.0",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/traverse": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
+            "globals": "^11.1.0",
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "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.0.1"
+          }
+        },
+        "array-unique": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+          "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+          "dev": true
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        },
+        "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.1",
+            "preserve": "^0.2.0",
+            "repeat-element": "^1.1.2"
+          }
+        },
+        "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.0"
+          }
+        },
+        "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"
+          }
+        },
+        "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-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"
+          }
+        },
+        "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"
+          }
+        },
+        "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.2",
+            "expand-brackets": "^0.1.4",
+            "extglob": "^0.3.1",
+            "filename-regex": "^2.0.0",
+            "is-extglob": "^1.0.0",
+            "is-glob": "^2.0.1",
+            "kind-of": "^3.0.2",
+            "normalize-path": "^2.0.1",
+            "object.omit": "^2.0.0",
+            "parse-glob": "^3.0.4",
+            "regex-cache": "^0.4.2"
+          }
+        }
+      }
+    },
+    "@babel/generator": {
+      "version": "7.0.0-beta.44",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz",
+      "integrity": "sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "7.0.0-beta.44",
+        "jsesc": "^2.5.1",
+        "lodash": "^4.2.0",
+        "source-map": "^0.5.0",
+        "trim-right": "^1.0.1"
+      }
+    },
+    "@babel/helper-annotate-as-pure": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0-beta.40.tgz",
+      "integrity": "sha512-bJd92d70QTlcqCO9WiE8C94r7NwVzJx1V6Yz7rYi4IQ53P0jbh9jjKL2zl8YoU2S8M/KX1jpu+yIgXbx+LOruQ==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.0.0-beta.40.tgz",
+      "integrity": "sha512-rMfjqkQrfHsA3ppMc2MsICoMqXH1b0BD77fTr4Kf+aUzEt5GSx5ZP5aNYlCqaPzhafg3znEEg/LVeq2EyGY8JQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-explode-assignable-expression": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@babel/helper-call-delegate": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.0.0-beta.40.tgz",
+      "integrity": "sha512-kfLlTpTayyCwj3/Rq4zDaK85GVPzRIR433QLhuNb0qjJfMQgLit2UEfBHUPPMRvKlb0FelrlXGTxXfsHLmfgzw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.2.0",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/traverse": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
+            "globals": "^11.1.0",
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-define-map": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.0.0-beta.40.tgz",
+      "integrity": "sha512-hDg3sFSAxYQ/CSXzIBzGeNRD4yp89MkC3wkwvGBH80LXobL6csEdQpzCPhwpL0K8RNB07awRnck1OtPqjeCpgA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-explode-assignable-expression": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.0.0-beta.40.tgz",
+      "integrity": "sha512-EUbu+uVNtHVp9emICjYO5wYodqWnSTx/s4Hfk++7IdnPTQi7UA9F/tPXf1GS8BLazlWc9tDwQ2aHFQLheHEXHw==",
+      "dev": true,
+      "requires": {
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.2.0",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/traverse": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
+            "globals": "^11.1.0",
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.0.0-beta.44",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz",
+      "integrity": "sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "7.0.0-beta.44",
+        "@babel/template": "7.0.0-beta.44",
+        "@babel/types": "7.0.0-beta.44"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.0.0-beta.44",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz",
+      "integrity": "sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "7.0.0-beta.44"
+      }
+    },
+    "@babel/helper-hoist-variables": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0-beta.40.tgz",
+      "integrity": "sha512-ghnJxUUEmqK8mssF7Y7R5jNzF5xDu4hmWQ1aZghZtLNJSymmj3HrXCLl5m1dBYpq9gGk7TlZK8stIvIJsCGmTQ==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@babel/helper-module-imports": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0-beta.40.tgz",
+      "integrity": "sha512-QFOskAKWbqJSBbGIl/Y1igJI4mW0A+wD5NFqsgDJj85KSvj/dHM4wNGIeqCi85nN9aMa4DgTBBrzUK4zSMsN2Q==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
+      },
+      "dependencies": {
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@babel/helper-module-transforms": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1H7cBk7kUWJpTepPH77TIRGwKILRGpu1yXmz1OjOruR6y2z0qfbp7ZzzZ3/xg6NlLDENLArEyO2+J0mO+VyQsg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "7.0.0-beta.40",
+        "@babel/helper-simple-access": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-optimise-call-expression": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0-beta.40.tgz",
+      "integrity": "sha512-2f4ZKEkvdnKiTUA/Nhju+oEoRcyHcpf6lFuQI5cxbo1Toxqa8E9HBO5tiOWwlIwuak7RZPYSnxnrJQy/0d4YUw==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@babel/helper-regex": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-75zi8hZSdWLT7upmEyAemfN0hJ7522svItPGbIj4Pi2T/C5vbgNFXLy8o/iOCX4FzB+yVKhz0zWC3SzN9hyigA==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.2.0"
+      }
+    },
+    "@babel/helper-remap-async-to-generator": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-RISz7EebAqaf4ofdG9LdVNfeqhK+JlFYJxvqCGMcS+Pyz84dA41MxgtjrRQdT85be1lZLI2OArvD7zDrj1psag==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "7.0.0-beta.40",
+        "@babel/helper-wrap-function": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.2.0",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/traverse": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
+            "globals": "^11.1.0",
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-replace-supers": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.0.0-beta.40.tgz",
+      "integrity": "sha512-Nu/5wpUV3rG35RzOq/upZlm61cP0lSAtmNkJLFfO5k2zOGCiHRczD1Y/xKqYOMl5f2iZmYw9fANi1jE4odMIIQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-optimise-call-expression": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.2.0",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/traverse": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
+            "globals": "^11.1.0",
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-simple-access": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.0.0-beta.40.tgz",
+      "integrity": "sha512-hEKOIXUZFOiyqUPiGydGc+Jr0s8mVCFrD1OtAw2BDkXf1BaR+PxVEVcBAWcJVLOjqrr7oVZL9SENjR4B/Y+yEw==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40",
+        "lodash": "^4.2.0"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.0.0-beta.44",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz",
+      "integrity": "sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "7.0.0-beta.44"
+      }
+    },
+    "@babel/helper-wrap-function": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.0.0-beta.40.tgz",
+      "integrity": "sha512-VBXE/uGQuZC9IaYufa3eCoT5ZqcCPv21Uhs/vo4ZqNRDX5QemYEkgDj5SmV2p73bhC66jDwUHaQHKQIiW7ExxA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.2.0",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/traverse": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
+            "globals": "^11.1.0",
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helpers": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/helpers/-/helpers-7.0.0-beta.40.tgz",
+      "integrity": "sha512-NK/mM/I16inThgXmKPxoqrg+N6OCLt+e9Zsmy8TJ93/zMx4Eddd679I231YwDP2J1Z12UgkfWCLbbvauU5TLlQ==",
+      "dev": true,
+      "requires": {
+        "@babel/template": "7.0.0-beta.40",
+        "@babel/traverse": "7.0.0-beta.40",
+        "@babel/types": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.40.tgz",
+          "integrity": "sha512-c91BQcXyTq/5aFV4afgOionxZS1dxWt8OghEx5Q52SKssdGRFSiMKnk9tGkev1pYULPJBqjSDZU2Pcuc58ffZw==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.2.0",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/traverse": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.40.tgz",
+          "integrity": "sha512-h96SQorjvdSuxQ6hHFIuAa3oxnad1TA5bU1Zz88+XqzwmM5QM0/k2D+heXGGy/76gT5ajl7xYLKGiPA/KTyVhQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/generator": "7.0.0-beta.40",
+            "@babel/helper-function-name": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "debug": "^3.0.1",
+            "globals": "^11.1.0",
+            "invariant": "^2.2.0",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.0.0-beta.44",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz",
+      "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.0",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.0"
+      }
+    },
+    "@babel/plugin-proposal-async-generator-functions": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.0.0-beta.40.tgz",
+      "integrity": "sha512-DU9JstbqQRAPhbW3Pk0yrEJA8GIiIDdylrnIuPI9x01jAwijxJfRwi6FbUAZUbS+3mzAAM5ALXUJkF1i1R5qbQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-remap-async-to-generator": "7.0.0-beta.40",
+        "@babel/plugin-syntax-async-generators": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-proposal-class-properties": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-Sg9dQw/4TpYKdTO5wx+AxxICXEraBbdhDUFl9tJfJYgz4grJm+UR2xMXbBO6fGRyBlFLMqQQQcY7Olk5iN6qNA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/plugin-syntax-class-properties": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/plugin-proposal-object-rest-spread": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0-beta.40.tgz",
+      "integrity": "sha512-nsQEWEvBgDcxYPBhmeIHqIXVVkPLQJBTD/bAdCMFhVe0vQdOR/px5E+rMsbP+9CywqV3AJ7PngYadnPgiuu4sg==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-proposal-optional-catch-binding": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0-beta.40.tgz",
+      "integrity": "sha512-GKKY7LDS3Z2iAVsM0KP745LAML8jKUdFqD+rGLa6F4Q9pEqDh3pjbL8eqiWLv/g/phpuCdvjaj+4wmUHi/E5eg==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-proposal-unicode-property-regex": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-BJlgIZcqodpkgNLOsKtkprA3zeXhg0O9Hru+IIaDVhcrZnkIIMVsdIG6gY5cKCAnpKFVN4kloQRTB61qYdKueA==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-regex": "7.0.0-beta.40",
+        "regexpu-core": "^4.1.3"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        },
+        "regexpu-core": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.2.0.tgz",
+          "integrity": "sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw==",
+          "dev": true,
+          "requires": {
+            "regenerate": "^1.4.0",
+            "regenerate-unicode-properties": "^7.0.0",
+            "regjsgen": "^0.4.0",
+            "regjsparser": "^0.3.0",
+            "unicode-match-property-ecmascript": "^1.0.4",
+            "unicode-match-property-value-ecmascript": "^1.0.2"
+          }
+        },
+        "regjsgen": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz",
+          "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==",
+          "dev": true
+        },
+        "regjsparser": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz",
+          "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==",
+          "dev": true,
+          "requires": {
+            "jsesc": "~0.5.0"
+          }
+        }
+      }
+    },
+    "@babel/plugin-syntax-async-generators": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0-beta.40.tgz",
+      "integrity": "sha512-UczObsgk1A4DaSMqTj59iETtmtuiXdBMs/1WBpy6LvLtf8AdjO/bZ2IbvrwKR5gEp8xJxBgzNq2sfK8RUsQBsQ==",
+      "dev": true
+    },
+    "@babel/plugin-syntax-class-properties": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-JQUvaacmUpzXDU6BVE1l7hMES6AOJLAyGuEapTop3hD1BDvKwLOIrzwZxawBmp3GOA02S3m4VdUyIfWS5DATjw==",
+      "dev": true
+    },
+    "@babel/plugin-syntax-object-rest-spread": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0-beta.40.tgz",
+      "integrity": "sha512-LY96LEXC+qxuiOcoqrkrsyEUaD95gS7AQE7nZJ/lZBGG14h4cJhc+T0FYdJpVKqhqNuEqVHsJV9xfCYHI4Ksug==",
+      "dev": true
+    },
+    "@babel/plugin-syntax-optional-catch-binding": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0-beta.40.tgz",
+      "integrity": "sha512-YP2Zqhi6r5mnp6LALz19pvF7szhEzBFybw4KqGFj6OwGmfF1nrvCG3h6cOTRhIKSwkfM7IlqGZm+GBhbYRYxGA==",
+      "dev": true
+    },
+    "@babel/plugin-syntax-typescript": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.0.0-beta.40.tgz",
+      "integrity": "sha512-o4xi4GbvyV5sG6vLMahVMQbx2qQYpuaC4KCZrwTko/Pd/1ZTO3cSezTgWeTQpCksjt3ngkuqbvvREWwles1GEg==",
+      "dev": true
+    },
+    "@babel/plugin-transform-arrow-functions": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0-beta.40.tgz",
+      "integrity": "sha512-B6wh62BErLWS3XInOUHhLcqBSK1QGdBph8E2K82EEFgJdQvphy30QXb0vwLUr8YU1efYyZXTsRA0JZ12jcm30Q==",
+      "dev": true
+    },
+    "@babel/plugin-transform-async-to-generator": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-4yTmjiZQw0S6dpnJqj0os0hom2czOAFKPhAuPplDay2zyqzDjbNt3zHFadIRTU4ekTonMb6ghTbMO1vlKcLMiQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-imports": "7.0.0-beta.40",
+        "@babel/helper-remap-async-to-generator": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0-beta.40.tgz",
+      "integrity": "sha512-GC64FqQfGJ5Wt3i0zSMcwRxmnZwgrx8fVLCeONNNm3BlK7Ui5Usuc7WubygM3bDq47UiHfeKo8ih54pr/POsFw==",
+      "dev": true
+    },
+    "@babel/plugin-transform-block-scoping": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0-beta.40.tgz",
+      "integrity": "sha512-8QpOK9lXdzrq1QIrP3Hfx/BmGPaCKjBORd2QSjdghPNNRlQFZmO2l3kb0I6yC7w75U1M5q26KvUbAcPrE68E4w==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.2.0"
+      }
+    },
+    "@babel/plugin-transform-classes": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.0.0-beta.40.tgz",
+      "integrity": "sha512-yjViyoOYJtt2vLDai8jluxl9quOtq/Xq4GTjT9uzy+mOfUTE77dcJySMGkWHE52Mu3n0TSI09ENBFYykpvXXDw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "7.0.0-beta.40",
+        "@babel/helper-define-map": "7.0.0-beta.40",
+        "@babel/helper-function-name": "7.0.0-beta.40",
+        "@babel/helper-optimise-call-expression": "7.0.0-beta.40",
+        "@babel/helper-replace-supers": "7.0.0-beta.40",
+        "globals": "^11.1.0"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/plugin-transform-computed-properties": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1VBpE+6YN4bj72MtbQoIwXZxoI5VfPLutQ5uhOx/tIrjf1KbLKsFR0epPPGx4nZ13u++lUR8CjUFUHGJ6RJirA==",
+      "dev": true
+    },
+    "@babel/plugin-transform-destructuring": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0-beta.40.tgz",
+      "integrity": "sha512-/FJq+WUAw4R5kg+2XWkmk0rDJqVs76rNNSIPpxeE0SiJvp8tvou7y8u0D1IhoO29ZgC+53jbdL+MkVN7mrH/iQ==",
+      "dev": true
+    },
+    "@babel/plugin-transform-dotall-regex": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-5npi7X6QGNWWfXxVBMQl+fEAn0LceNNFT139yaGRkyWZtUXmueFLgXKsa9dY2DhuEis29KuZrwGcmGSQWnEmtg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-regex": "7.0.0-beta.40",
+        "regexpu-core": "^4.1.3"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        },
+        "regexpu-core": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.2.0.tgz",
+          "integrity": "sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw==",
+          "dev": true,
+          "requires": {
+            "regenerate": "^1.4.0",
+            "regenerate-unicode-properties": "^7.0.0",
+            "regjsgen": "^0.4.0",
+            "regjsparser": "^0.3.0",
+            "unicode-match-property-ecmascript": "^1.0.4",
+            "unicode-match-property-value-ecmascript": "^1.0.2"
+          }
+        },
+        "regjsgen": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz",
+          "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==",
+          "dev": true
+        },
+        "regjsparser": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz",
+          "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==",
+          "dev": true,
+          "requires": {
+            "jsesc": "~0.5.0"
+          }
+        }
       }
     },
-    "@babel/generator": {
-      "version": "7.0.0-beta.44",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz",
-      "integrity": "sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ==",
+    "@babel/plugin-transform-duplicate-keys": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0-beta.40.tgz",
+      "integrity": "sha512-rxEyRbU/iEGR99oBMoer5QeGWLMhT3Kq4a8B03DFLCBpGLv3XirpSGC/Ys1YhUKAmEio4jIcVVI8dRBbcVeyDw==",
+      "dev": true
+    },
+    "@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-nh9qIA4P1wQczihazVOvTpkl2EBfoSMfkM6/21p8NBY4GxZJcEwT1O1nke/+RLludUekHqXHGH+9ekfEfLwKRQ==",
       "dev": true,
       "requires": {
-        "@babel/types": "7.0.0-beta.44",
-        "jsesc": "^2.5.1",
-        "lodash": "^4.2.0",
-        "source-map": "^0.5.0",
-        "trim-right": "^1.0.1"
+        "@babel/helper-builder-binary-assignment-operator-visitor": "7.0.0-beta.40"
       }
     },
-    "@babel/helper-function-name": {
-      "version": "7.0.0-beta.44",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz",
-      "integrity": "sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg==",
+    "@babel/plugin-transform-for-of": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0-beta.40.tgz",
+      "integrity": "sha512-ArDbLAGMzI++G5Ut8HIbLvnAxZNOC5tFzMXiud51JJTHRaeFB7AwX+duY9x/Hu/KypISXjels3BYVYCV/EH+ow==",
+      "dev": true
+    },
+    "@babel/plugin-transform-function-name": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.0.0-beta.40.tgz",
+      "integrity": "sha512-wvpswFciLQ2eAnHAs6/NSWymPg88LhHH87BljjXDxNnyGBzckip/iEa051Dz6lDumVUUjXLukw3D2fv5NBitVA==",
       "dev": true,
       "requires": {
-        "@babel/helper-get-function-arity": "7.0.0-beta.44",
-        "@babel/template": "7.0.0-beta.44",
-        "@babel/types": "7.0.0-beta.44"
+        "@babel/helper-function-name": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.40.tgz",
+          "integrity": "sha512-eVXQSbu/RimU6OKcK2/gDJVTFcxXJI4sHbIqw2mhwMZeQ2as/8AhS9DGkEDoHMBBNJZ5B0US63lF56x+KDcxiA==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.40.tgz",
+          "integrity": "sha512-cK9BVLtOfisSISTTHXKGvBc2OBh65tjEk4PgXhsSnnH0i8RP2v+5RCxoSlh2y/i+l2fxQqKqv++Qo5RMiwmRCA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "7.0.0-beta.40",
+            "@babel/template": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.40.tgz",
+          "integrity": "sha512-mOhhTrzieV6VO7odgzFGFapiwRK0ei8RZRhfzHhb6cpX3QM8XXuCLXWjN8qBB7JReDdUR80V3LFfFrGUYevhNg==",
+          "dev": true,
+          "requires": {
+            "chalk": "^2.0.0",
+            "esutils": "^2.0.2",
+            "js-tokens": "^3.0.0"
+          }
+        },
+        "@babel/template": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.40.tgz",
+          "integrity": "sha512-RlQiVB7eL7fxsKN6JvnCCwEwEL28CBYalXSgWWULuFlEHjtMoXBqQanSie3bNyhrANJx67sb+Sd/vuGivoMwLQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "7.0.0-beta.40",
+            "@babel/types": "7.0.0-beta.40",
+            "babylon": "7.0.0-beta.40",
+            "lodash": "^4.2.0"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "babylon": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.40.tgz",
+          "integrity": "sha512-AVxF2EcxvGD5hhOuLTOLAXBb0VhwWpEX0HyHdAI2zU+AAP4qEwtQj8voz1JR3uclGai0rfcE+dCTHnNMOnimFg==",
+          "dev": true
+        }
       }
     },
-    "@babel/helper-get-function-arity": {
-      "version": "7.0.0-beta.44",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz",
-      "integrity": "sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw==",
+    "@babel/plugin-transform-literals": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0-beta.40.tgz",
+      "integrity": "sha512-p7VlTod2r7srx0uKVrKqMJR1f6iyvDAnlLdTEDGrLHpP9pXXvIc/bP8xZTxVPn+IziSFh6FvOzHXXLMtnRKnow==",
+      "dev": true
+    },
+    "@babel/plugin-transform-modules-amd": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.0.0-beta.40.tgz",
+      "integrity": "sha512-o/XTve9C+M9203MVxGRBOXNx4f9DZGiPLbwPPeDobdtw3NKHUCymFNbh9xxMJy0MPMEe8JldxbVwGy2f8DY/3w==",
       "dev": true,
       "requires": {
-        "@babel/types": "7.0.0-beta.44"
+        "@babel/helper-module-transforms": "7.0.0-beta.40"
       }
     },
-    "@babel/helper-split-export-declaration": {
-      "version": "7.0.0-beta.44",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz",
-      "integrity": "sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA==",
+    "@babel/plugin-transform-modules-commonjs": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1kRhaQP3K9kRiJhhLpP7J5NsMV+SiKWSsli6TUR6uxbuHHNAleRtlsZ76JgCRMaufBgPMLxq5pp7yibUhwTn8w==",
       "dev": true,
       "requires": {
-        "@babel/types": "7.0.0-beta.44"
+        "@babel/helper-module-transforms": "7.0.0-beta.40",
+        "@babel/helper-simple-access": "7.0.0-beta.40"
       }
     },
-    "@babel/highlight": {
-      "version": "7.0.0-beta.44",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz",
-      "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==",
+    "@babel/plugin-transform-modules-systemjs": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0-beta.40.tgz",
+      "integrity": "sha512-q5IpFXNlzrK2ObpHkH5jzTCqRVzoNzmH8RoE8ZHQvLLiaIT346u8ynNv/BH1ltA49SPUPWyYpA+Z7OqCM4d3NA==",
       "dev": true,
       "requires": {
-        "chalk": "^2.0.0",
-        "esutils": "^2.0.2",
-        "js-tokens": "^3.0.0"
+        "@babel/helper-hoist-variables": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-transform-modules-umd": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.0.0-beta.40.tgz",
+      "integrity": "sha512-LHKqJFwo7x/CeEwjLyUE99SlG/kbTl8LS1DQ26fWctVnW5JuPt3hwYrggnmo1L/g/dal7EP2IL56+UezDMpJUQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-module-transforms": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-transform-new-target": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0-beta.40.tgz",
+      "integrity": "sha512-t4ivwZVGrVf1bhLgHcgaLhFH4loZhV5WmEKKNPEe7QnGikJBibrLmggOM1w5s6BMsHj03+j0rxUmcKLmGlC/fg==",
+      "dev": true
+    },
+    "@babel/plugin-transform-object-super": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.0.0-beta.40.tgz",
+      "integrity": "sha512-a9kXy4amuvAz7eFuntXiyjg0eKXej1FH++xQg37ugh24zozD0cmfr3pvRbYOGlmbmOeZWJnlq+O6X8BSfLSycw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-replace-supers": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-transform-parameters": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.0.0-beta.40.tgz",
+      "integrity": "sha512-JShFDeKEzwwTB+pHcUuLdX9zPi98sRekvtdCEOt8UoF5pzW02k1XdsVOckp/PzcEdoGAgZiiI1PFkJZ+xanfPg==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-call-delegate": "7.0.0-beta.40",
+        "@babel/helper-get-function-arity": "7.0.0-beta.40"
+      },
+      "dependencies": {
+        "@babel/helper-get-function-arity": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.40.tgz",
+          "integrity": "sha512-MwquaPznI4cUoZEgHC/XGkddOXtqKqD4DvZDOyJK2LR9Qi6TbMbAhc6IaFoRX7CRTFCmtGeu8gdXW2dBotBBTA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "7.0.0-beta.40"
+          }
+        },
+        "@babel/types": {
+          "version": "7.0.0-beta.40",
+          "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.40.tgz",
+          "integrity": "sha512-uXCGCzTgMZxcSUzutCPtZmXbVC+cvENgS2e0tRuhn+Y1hZnMb8IHP0Trq7Q2MB/eFmG5pKrAeTIUfQIe5kA4Tg==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.2.0",
+            "to-fast-properties": "^2.0.0"
+          }
+        }
+      }
+    },
+    "@babel/plugin-transform-regenerator": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0-beta.40.tgz",
+      "integrity": "sha512-hFj52wAXbEpXwwfKsMol5Y967D3L8tz46Jin9n/gYPgcNWugvsw6d7g+HknBJ8FzaUESrDruFRkGPXgD+FyjvQ==",
+      "dev": true,
+      "requires": {
+        "regenerator-transform": "^0.12.3"
+      },
+      "dependencies": {
+        "regenerator-transform": {
+          "version": "0.12.4",
+          "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.12.4.tgz",
+          "integrity": "sha512-p2I0fY+TbSLD2/VFTFb/ypEHxs3e3AjU0DzttdPqk2bSmDhfSh5E54b86Yc6XhUa5KykK1tgbvZ4Nr82oCJWkQ==",
+          "dev": true,
+          "requires": {
+            "private": "^0.1.6"
+          }
+        }
+      }
+    },
+    "@babel/plugin-transform-shorthand-properties": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0-beta.40.tgz",
+      "integrity": "sha512-1leHn9ST0PKFHwH7klJqGA76YPoqs3cR5zeJK6YGZETeX89YiAVtR+5JTSGhfI/1RR0Vcg9Tl1LnPpf7LmYlng==",
+      "dev": true
+    },
+    "@babel/plugin-transform-spread": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0-beta.40.tgz",
+      "integrity": "sha512-RPrIpV+h8OqoqyMic7CNeM8TdSDk7ec+T6jM97vMb9XQQrRInAUWlwWvG6d36v72xobFtHoPA28VN/0aVsbQDg==",
+      "dev": true
+    },
+    "@babel/plugin-transform-sticky-regex": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-dJPUaV2D5SwSXypaDFRJd+LIhabeaWhZ3McmNo0COn+lBINJ9iL7mYuPxnqwhM/KoBNv+vYIoFFZzT/I27K6AQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-regex": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-transform-template-literals": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0-beta.40.tgz",
+      "integrity": "sha512-ScGHntym1y5FweT751OJxGW4rydxdLA9BwkHfJ5o6RcCoq+LRubDeGu2HeuX4SMEvAw0MnZeSk8vw5TwIOzEIQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-transform-typeof-symbol": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0-beta.40.tgz",
+      "integrity": "sha512-y+mXC0tIlTZj04ZD9326grEIvFjI/IeLSIVVKMIf8nSodLDCgipuM6zXhxqXVvjcTrvvUKuxPrvPeSuht0eeMg==",
+      "dev": true
+    },
+    "@babel/plugin-transform-typescript": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.0.0-beta.40.tgz",
+      "integrity": "sha512-7MLJ5DU6j8B76yYrfhQvV4LKXOX5AQz4Z+SlZy7tUEiARilztqE1vBymju5FGBNCsWaE27lkHSaSXhtIBCjn6g==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-syntax-typescript": "7.0.0-beta.40"
+      }
+    },
+    "@babel/plugin-transform-unicode-regex": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0-beta.40.tgz",
+      "integrity": "sha512-+eProDq93qiYnXOy+LDSMoKF2lEQVQ+r6DF3ZZXJV5QJ3f2+vwpSqGIQy61sSkVMEaoNtYL/Jy+G8HrWFw9p3w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-regex": "7.0.0-beta.40",
+        "regexpu-core": "^4.1.3"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        },
+        "regexpu-core": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.2.0.tgz",
+          "integrity": "sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw==",
+          "dev": true,
+          "requires": {
+            "regenerate": "^1.4.0",
+            "regenerate-unicode-properties": "^7.0.0",
+            "regjsgen": "^0.4.0",
+            "regjsparser": "^0.3.0",
+            "unicode-match-property-ecmascript": "^1.0.4",
+            "unicode-match-property-value-ecmascript": "^1.0.2"
+          }
+        },
+        "regjsgen": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.4.0.tgz",
+          "integrity": "sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA==",
+          "dev": true
+        },
+        "regjsparser": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.3.0.tgz",
+          "integrity": "sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA==",
+          "dev": true,
+          "requires": {
+            "jsesc": "~0.5.0"
+          }
+        }
+      }
+    },
+    "@babel/preset-env": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/preset-env/-/preset-env-7.0.0-beta.40.tgz",
+      "integrity": "sha512-IBnkVmaM/K2pHB8RR0tC5oHrPdS4y0RZXrGc+lmfDuj4tgyCAmDBuQ1EWVaLOpWw8fXPwXfX70Vdp65L2df+RQ==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-proposal-async-generator-functions": "7.0.0-beta.40",
+        "@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.40",
+        "@babel/plugin-proposal-optional-catch-binding": "7.0.0-beta.40",
+        "@babel/plugin-proposal-unicode-property-regex": "7.0.0-beta.40",
+        "@babel/plugin-syntax-async-generators": "7.0.0-beta.40",
+        "@babel/plugin-syntax-object-rest-spread": "7.0.0-beta.40",
+        "@babel/plugin-syntax-optional-catch-binding": "7.0.0-beta.40",
+        "@babel/plugin-transform-arrow-functions": "7.0.0-beta.40",
+        "@babel/plugin-transform-async-to-generator": "7.0.0-beta.40",
+        "@babel/plugin-transform-block-scoped-functions": "7.0.0-beta.40",
+        "@babel/plugin-transform-block-scoping": "7.0.0-beta.40",
+        "@babel/plugin-transform-classes": "7.0.0-beta.40",
+        "@babel/plugin-transform-computed-properties": "7.0.0-beta.40",
+        "@babel/plugin-transform-destructuring": "7.0.0-beta.40",
+        "@babel/plugin-transform-dotall-regex": "7.0.0-beta.40",
+        "@babel/plugin-transform-duplicate-keys": "7.0.0-beta.40",
+        "@babel/plugin-transform-exponentiation-operator": "7.0.0-beta.40",
+        "@babel/plugin-transform-for-of": "7.0.0-beta.40",
+        "@babel/plugin-transform-function-name": "7.0.0-beta.40",
+        "@babel/plugin-transform-literals": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-amd": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-commonjs": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-systemjs": "7.0.0-beta.40",
+        "@babel/plugin-transform-modules-umd": "7.0.0-beta.40",
+        "@babel/plugin-transform-new-target": "7.0.0-beta.40",
+        "@babel/plugin-transform-object-super": "7.0.0-beta.40",
+        "@babel/plugin-transform-parameters": "7.0.0-beta.40",
+        "@babel/plugin-transform-regenerator": "7.0.0-beta.40",
+        "@babel/plugin-transform-shorthand-properties": "7.0.0-beta.40",
+        "@babel/plugin-transform-spread": "7.0.0-beta.40",
+        "@babel/plugin-transform-sticky-regex": "7.0.0-beta.40",
+        "@babel/plugin-transform-template-literals": "7.0.0-beta.40",
+        "@babel/plugin-transform-typeof-symbol": "7.0.0-beta.40",
+        "@babel/plugin-transform-unicode-regex": "7.0.0-beta.40",
+        "browserslist": "^3.0.0",
+        "invariant": "^2.2.2",
+        "semver": "^5.3.0"
+      }
+    },
+    "@babel/preset-typescript": {
+      "version": "7.0.0-beta.40",
+      "resolved": "http://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.0.0-beta.40.tgz",
+      "integrity": "sha512-G74AcsTo4QPTn6RhZGxG2TapvbeA7SZ7+1dNtn2FZRD5LisJiC33AlBal6MMl3hqBL61xJVcAkNadbtC6PoC1Q==",
+      "dev": true,
+      "requires": {
+        "@babel/plugin-transform-typescript": "7.0.0-beta.40"
       }
     },
     "@babel/runtime": {
@@ -809,6 +2897,15 @@
         "string-width": "^2.0.0"
       }
     },
+    "ansi-escape-sequences": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.0.0.tgz",
+      "integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0"
+      }
+    },
     "ansi-escapes": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
@@ -1197,6 +3294,16 @@
         "sprintf-js": "~1.0.2"
       }
     },
+    "argv-tools": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/argv-tools/-/argv-tools-0.1.1.tgz",
+      "integrity": "sha512-Cc0dBvx4dvrjjKpyDA6w8RlNAw8Su30NvZbWl/Tv9ZALEVlLVkWQiHMi84Q0xNfpVuSaiQbYkdmWK8g1PLGhKw==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "find-replace": "^2.0.1"
+      }
+    },
     "arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -1212,6 +3319,15 @@
       "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
       "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
     },
+    "array-back": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+      "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+      "dev": true,
+      "requires": {
+        "typical": "^2.6.1"
+      }
+    },
     "array-differ": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
@@ -2548,7 +4664,7 @@
     },
     "browserify-rsa": {
       "version": "4.0.1",
-      "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
       "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
       "dev": true,
       "requires": {
@@ -2580,9 +4696,19 @@
         "pako": "~1.0.5"
       }
     },
+    "browserslist": {
+      "version": "3.2.8",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+      "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30000844",
+        "electron-to-chromium": "^1.3.47"
+      }
+    },
     "buffer": {
       "version": "4.9.1",
-      "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
       "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
       "dev": true,
       "requires": {
@@ -2709,6 +4835,17 @@
         "unset-value": "^1.0.0"
       }
     },
+    "cache-point": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-0.4.1.tgz",
+      "integrity": "sha512-4TgWfe9SF+bUy5cCql8gWHqKNrviufNwSYxLjf2utB0pY4+bdcuFwMmY1hDB+67Gz/L1vmhFNhePAjJTFBtV+Q==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "fs-then-native": "^2.0.0",
+        "mkdirp2": "^1.0.3"
+      }
+    },
     "cacheable-request": {
       "version": "2.1.4",
       "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
@@ -2769,6 +4906,12 @@
       "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
       "dev": true
     },
+    "caniuse-lite": {
+      "version": "1.0.30000890",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000890.tgz",
+      "integrity": "sha512-4NI3s4Y6ROm+SgZN5sLUG4k7nVWQnedis3c/RWkynV5G6cHSY7+a8fwFyn2yoBDE3E6VswhTNNwR3PvzGqlTkg==",
+      "dev": true
+    },
     "capture-stack-trace": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
@@ -3107,6 +5250,16 @@
       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
       "dev": true
     },
+    "collect-all": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.3.tgz",
+      "integrity": "sha512-0y0rBgoX8IzIjBAUnO73SEtSb4Mhk3IoceWJq5zZSxb9mWORhWH8xLYo4EDSOE1jRBk1LhmfjqWFFt10h/+MEA==",
+      "dev": true,
+      "requires": {
+        "stream-connect": "^1.0.2",
+        "stream-via": "^1.0.4"
+      }
+    },
     "collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -3134,11 +5287,55 @@
       "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz",
       "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ=="
     },
+    "command-line-args": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.0.2.tgz",
+      "integrity": "sha512-/qPcbL8zpqg53x4rAaqMFlRV4opN3pbla7I7k9x8kyOBMQoGT6WltjN6sXZuxOXw6DgdK7Ad+ijYS5gjcr7vlA==",
+      "dev": true,
+      "requires": {
+        "argv-tools": "^0.1.1",
+        "array-back": "^2.0.0",
+        "find-replace": "^2.0.1",
+        "lodash.camelcase": "^4.3.0",
+        "typical": "^2.6.1"
+      }
+    },
+    "command-line-tool": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz",
+      "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==",
+      "dev": true,
+      "requires": {
+        "ansi-escape-sequences": "^4.0.0",
+        "array-back": "^2.0.0",
+        "command-line-args": "^5.0.0",
+        "command-line-usage": "^4.1.0",
+        "typical": "^2.6.1"
+      }
+    },
+    "command-line-usage": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
+      "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
+      "dev": true,
+      "requires": {
+        "ansi-escape-sequences": "^4.0.0",
+        "array-back": "^2.0.0",
+        "table-layout": "^0.4.2",
+        "typical": "^2.6.1"
+      }
+    },
     "commander": {
       "version": "2.17.1",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
       "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
     },
+    "common-sequence": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-1.0.2.tgz",
+      "integrity": "sha1-MOB/P49vf5s97oVPILLTnu4Ibeg=",
+      "dev": true
+    },
     "common-tags": {
       "version": "1.8.0",
       "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
@@ -3163,7 +5360,7 @@
       "dependencies": {
         "minimist": {
           "version": "1.2.0",
-          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
           "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
         }
       }
@@ -3188,6 +5385,23 @@
         "typedarray": "^0.0.6"
       }
     },
+    "config-master": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz",
+      "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=",
+      "dev": true,
+      "requires": {
+        "walk-back": "^2.0.1"
+      },
+      "dependencies": {
+        "walk-back": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz",
+          "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=",
+          "dev": true
+        }
+      }
+    },
     "configstore": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
@@ -3734,6 +5948,26 @@
         "path-type": "^3.0.0"
       }
     },
+    "dmd": {
+      "version": "3.0.12",
+      "resolved": "https://registry.npmjs.org/dmd/-/dmd-3.0.12.tgz",
+      "integrity": "sha512-79w644JdsB2TthYpVl2bDurX7i9Abaegg2E7X46Ajc135aASTMXxrHzJ9mOa5X5nbmnXwlBYiF68K+1baX+BzQ==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "cache-point": "^0.4.1",
+        "common-sequence": "^1.0.2",
+        "file-set": "^2.0.0",
+        "handlebars": "^4.0.11",
+        "marked": "^0.3.16",
+        "object-get": "^2.1.0",
+        "reduce-flatten": "^1.0.1",
+        "reduce-unique": "^1.0.0",
+        "reduce-without": "^1.0.1",
+        "test-value": "^3.0.0",
+        "walk-back": "^3.0.0"
+      }
+    },
     "doctrine": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
@@ -3783,12 +6017,20 @@
       "integrity": "sha512-FlWbnhgjtwD+uNLUGHbMykMOYQaTivdHEmYwAKFjn6GKe/CqY0fNae93ZHTd20snh9ZLr8mTzIL9m0APQ1pjQg=="
     },
     "dtrace-provider": {
-      "version": "0.8.6",
-      "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.6.tgz",
-      "integrity": "sha1-QooiOv4DQl0s1tY0f99AxmkDVj0=",
+      "version": "0.8.7",
+      "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz",
+      "integrity": "sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ=",
       "optional": true,
       "requires": {
-        "nan": "^2.3.3"
+        "nan": "^2.10.0"
+      },
+      "dependencies": {
+        "nan": {
+          "version": "2.11.1",
+          "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
+          "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==",
+          "optional": true
+        }
       }
     },
     "duplexer": {
@@ -3839,6 +6081,12 @@
       "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==",
       "dev": true
     },
+    "electron-to-chromium": {
+      "version": "1.3.75",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.75.tgz",
+      "integrity": "sha512-nLo03Qpw++8R6BxDZL/B1c8SQvUe/htdgc5LWYHe5YotV2jVvRUMP5AlOmxOsyeOzgMiXrNln2mC05Ixz6vuUQ==",
+      "dev": true
+    },
     "elegant-spinner": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
@@ -4714,6 +6962,32 @@
         "schema-utils": "^0.4.5"
       }
     },
+    "file-set": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz",
+      "integrity": "sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "glob": "^7.1.3"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.3",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+          "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        }
+      }
+    },
     "filename-regex": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
@@ -4775,6 +7049,16 @@
         "pkg-dir": "^2.0.0"
       }
     },
+    "find-replace": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-2.0.1.tgz",
+      "integrity": "sha512-LzDo3Fpa30FLIBsh6DCDnMN1KW2g4QKkqKmejlImgWY67dDFPX/x9Kh/op/GK522DchQXEvDi/wD48HKW49XOQ==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "test-value": "^3.0.0"
+      }
+    },
     "find-up": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
@@ -4916,6 +7200,18 @@
       "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
       "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
     },
+    "fs-readdir-recursive": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+      "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
+      "dev": true
+    },
+    "fs-then-native": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz",
+      "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=",
+      "dev": true
+    },
     "fs-write-stream-atomic": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -4973,14 +7269,12 @@
         "balanced-match": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -5000,8 +7294,7 @@
         "concat-map": {
           "version": "0.0.1",
           "bundled": true,
-          "dev": true,
-          "optional": true
+          "dev": true
         },
         "console-control-strings": {
           "version": "1.1.0",
@@ -5149,7 +7442,6 @@
           "version": "3.0.4",
           "bundled": true,
           "dev": true,
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -5828,6 +8120,46 @@
         "lodash": "^4.17.2"
       }
     },
+    "handlebars": {
+      "version": "4.0.12",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz",
+      "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==",
+      "dev": true,
+      "requires": {
+        "async": "^2.5.0",
+        "optimist": "^0.6.1",
+        "source-map": "^0.6.1",
+        "uglify-js": "^3.1.4"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.1",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+          "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+          "dev": true,
+          "requires": {
+            "lodash": "^4.17.10"
+          }
+        },
+        "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
+        },
+        "uglify-js": {
+          "version": "3.4.9",
+          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
+          "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "commander": "~2.17.1",
+            "source-map": "~0.6.1"
+          }
+        }
+      }
+    },
     "has": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
@@ -6825,6 +9157,61 @@
         }
       }
     },
+    "jsdoc-api": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-4.0.3.tgz",
+      "integrity": "sha512-dfYq9JgB+XahY0XfSEw93PmXmocjwYcvJ5aMuQUJ/OdDRGWamf2SSOk3W06Bsj8qdjp/UdefzqpP/mpwsvHuvA==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "cache-point": "^0.4.1",
+        "collect-all": "^1.0.3",
+        "file-set": "^2.0.0",
+        "fs-then-native": "^2.0.0",
+        "jsdoc": "~3.5.5",
+        "object-to-spawn-args": "^1.1.1",
+        "temp-path": "^1.0.0",
+        "walk-back": "^3.0.0"
+      }
+    },
+    "jsdoc-babel": {
+      "version": "0.4.0-alpha.0",
+      "resolved": "https://registry.npmjs.org/jsdoc-babel/-/jsdoc-babel-0.4.0-alpha.0.tgz",
+      "integrity": "sha1-wUJ7XLTU+D1Fymf52uMrkSz7B0k=",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.13.1"
+      }
+    },
+    "jsdoc-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-3.0.1.tgz",
+      "integrity": "sha512-btZLp4wYl90vcAfgk4hoGQbO17iBVrhh3LJRMKZNtZgniO3F8H2CjxXld0owBIB1XxN+j3bAcWZnZKMnSj3iMA==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "lodash.omit": "^4.5.0",
+        "lodash.pick": "^4.4.0",
+        "reduce-extract": "^1.0.0",
+        "sort-array": "^2.0.0",
+        "test-value": "^3.0.0"
+      }
+    },
+    "jsdoc-to-markdown": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-4.0.1.tgz",
+      "integrity": "sha512-LHJRoLoLyDdxNcColgkLoB/rFG5iRP+PNJjMILI0x+95IdEAtyjSt0wJ6ZlKxRpkhBYtQXTQQ119hMqPIUZzTQ==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "command-line-tool": "^0.8.0",
+        "config-master": "^3.1.0",
+        "dmd": "^3.0.10",
+        "jsdoc-api": "^4.0.1",
+        "jsdoc-parse": "^3.0.1",
+        "walk-back": "^3.0.0"
+      }
+    },
     "jsesc": {
       "version": "2.5.1",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz",
@@ -7596,6 +9983,12 @@
       "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz",
       "integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q=="
     },
+    "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.debounce": {
       "version": "4.0.8",
       "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -7632,11 +10025,29 @@
       "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
       "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
     },
+    "lodash.omit": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
+      "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=",
+      "dev": true
+    },
     "lodash.once": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
       "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
     },
+    "lodash.padend": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
+      "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
+      "dev": true
+    },
+    "lodash.pick": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
+      "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
+      "dev": true
+    },
     "lodash.set": {
       "version": "4.3.2",
       "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
@@ -8042,10 +10453,16 @@
         "minimist": "0.0.8"
       }
     },
+    "mkdirp2": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.4.tgz",
+      "integrity": "sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw==",
+      "dev": true
+    },
     "moment": {
-      "version": "2.21.0",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.21.0.tgz",
-      "integrity": "sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ==",
+      "version": "2.22.2",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz",
+      "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=",
       "optional": true
     },
     "morgan": {
@@ -8145,6 +10562,7 @@
       "version": "2.9.2",
       "resolved": "https://registry.npmjs.org/nan/-/nan-2.9.2.tgz",
       "integrity": "sha512-ltW65co7f3PQWBDbqVvaU1WtFJUsNW7sWWm4HINhbMQIyVyzIeyZ8toX5TC5eeooE6piZoaEh4cZkueSKG3KYw==",
+      "dev": true,
       "optional": true
     },
     "nanomatch": {
@@ -8408,6 +10826,12 @@
         }
       }
     },
+    "object-get": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.0.tgz",
+      "integrity": "sha1-ciu9tgA576R8rTxtws5RqFwCxa4=",
+      "dev": true
+    },
     "object-hash": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.0.tgz",
@@ -8424,6 +10848,12 @@
       "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz",
       "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk="
     },
+    "object-to-spawn-args": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz",
+      "integrity": "sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U=",
+      "dev": true
+    },
     "object-visit": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -8520,6 +10950,24 @@
         "mimic-fn": "^1.0.0"
       }
     },
+    "optimist": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+      "dev": true,
+      "requires": {
+        "minimist": "~0.0.1",
+        "wordwrap": "~0.0.2"
+      },
+      "dependencies": {
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+          "dev": true
+        }
+      }
+    },
     "optionator": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
@@ -8635,6 +11083,17 @@
       "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
       "dev": true
     },
+    "output-file-sync": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz",
+      "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "is-plain-obj": "^1.1.0",
+        "mkdirp": "^0.5.1"
+      }
+    },
     "p-cancelable": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
@@ -8878,6 +11337,15 @@
       "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
       "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
     },
+    "path": {
+      "version": "0.12.7",
+      "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+      "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=",
+      "requires": {
+        "process": "^0.11.1",
+        "util": "^0.10.3"
+      }
+    },
     "path-browserify": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
@@ -9155,8 +11623,7 @@
     "process": {
       "version": "0.11.10",
       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
-      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
-      "dev": true
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
     },
     "process-nextick-args": {
       "version": "2.0.0",
@@ -9508,6 +11975,17 @@
         }
       }
     },
+    "react": {
+      "version": "16.5.2",
+      "resolved": "https://registry.npmjs.org/react/-/react-16.5.2.tgz",
+      "integrity": "sha512-FDCSVd3DjVTmbEAjUNX6FgfAmQ+ypJfHUsqUJOYNCBUp1h8lqmtC+0mXJ+JjsWx4KAVTkk1vKd1hLQPvEviSuw==",
+      "requires": {
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.1",
+        "prop-types": "^15.6.2",
+        "schedule": "^0.5.0"
+      }
+    },
     "react-event-listener": {
       "version": "0.6.3",
       "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.3.tgz",
@@ -9552,7 +12030,7 @@
     },
     "react-redux": {
       "version": "5.0.7",
-      "resolved": "http://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz",
+      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.7.tgz",
       "integrity": "sha512-5VI8EV5hdgNgyjfmWzBbdrqUkrVRKlyTKk1sGH3jzM2M2Mhj/seQgPXaz6gVAj2lz/nz688AdTqMO18Lr24Zhg==",
       "requires": {
         "hoist-non-react-statics": "^2.5.0",
@@ -9689,6 +12167,78 @@
         "symbol-observable": "^1.0.4"
       }
     },
+    "reduce-extract": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",
+      "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=",
+      "dev": true,
+      "requires": {
+        "test-value": "^1.0.1"
+      },
+      "dependencies": {
+        "array-back": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+          "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+          "dev": true,
+          "requires": {
+            "typical": "^2.6.0"
+          }
+        },
+        "test-value": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz",
+          "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=",
+          "dev": true,
+          "requires": {
+            "array-back": "^1.0.2",
+            "typical": "^2.4.2"
+          }
+        }
+      }
+    },
+    "reduce-flatten": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
+      "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
+      "dev": true
+    },
+    "reduce-unique": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-1.0.0.tgz",
+      "integrity": "sha1-flhrz4ek4ytter2Cd/rWzeyfSAM=",
+      "dev": true
+    },
+    "reduce-without": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz",
+      "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=",
+      "dev": true,
+      "requires": {
+        "test-value": "^2.0.0"
+      },
+      "dependencies": {
+        "array-back": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+          "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+          "dev": true,
+          "requires": {
+            "typical": "^2.6.0"
+          }
+        },
+        "test-value": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
+          "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
+          "dev": true,
+          "requires": {
+            "array-back": "^1.0.3",
+            "typical": "^2.6.0"
+          }
+        }
+      }
+    },
     "redux": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.0.tgz",
@@ -9709,6 +12259,15 @@
       "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
       "dev": true
     },
+    "regenerate-unicode-properties": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz",
+      "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.4.0"
+      }
+    },
     "regenerator-runtime": {
       "version": "0.11.1",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
@@ -10032,9 +12591,9 @@
       "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
     },
     "safe-json-stringify": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.1.0.tgz",
-      "integrity": "sha512-EzBtUaFH9bHYPc69wqjp0efJI/DPNHdFbGE3uIMn4sVbO0zx8vZ8cG4WKxQfOpUOKsQyGBiT2mTqnCw+6nLswA==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz",
+      "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==",
       "optional": true
     },
     "safe-regex": {
@@ -10050,6 +12609,14 @@
       "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
+    "schedule": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/schedule/-/schedule-0.5.0.tgz",
+      "integrity": "sha512-HUcJicG5Ou8xfR//c2rPT0lPIRR09vVvN81T9fqfVgBmhERUbDEQoYKjpBxbueJnCPpSu2ujXzOnRQt6x9o/jw==",
+      "requires": {
+        "object-assign": "^4.1.1"
+      }
+    },
     "schema-utils": {
       "version": "0.4.5",
       "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz",
@@ -10379,6 +12946,28 @@
         }
       }
     },
+    "sort-array": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-2.0.0.tgz",
+      "integrity": "sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI=",
+      "dev": true,
+      "requires": {
+        "array-back": "^1.0.4",
+        "object-get": "^2.1.0",
+        "typical": "^2.6.0"
+      },
+      "dependencies": {
+        "array-back": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+          "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+          "dev": true,
+          "requires": {
+            "typical": "^2.6.0"
+          }
+        }
+      }
+    },
     "sort-keys": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
@@ -10531,6 +13120,26 @@
         "duplexer": "~0.1.1"
       }
     },
+    "stream-connect": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz",
+      "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=",
+      "dev": true,
+      "requires": {
+        "array-back": "^1.0.2"
+      },
+      "dependencies": {
+        "array-back": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+          "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+          "dev": true,
+          "requires": {
+            "typical": "^2.6.0"
+          }
+        }
+      }
+    },
     "stream-each": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
@@ -10584,6 +13193,12 @@
       "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
       "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
     },
+    "stream-via": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz",
+      "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==",
+      "dev": true
+    },
     "streamsearch": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
@@ -10754,6 +13369,19 @@
         }
       }
     },
+    "table-layout": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.4.tgz",
+      "integrity": "sha512-uNaR3SRMJwfdp9OUr36eyEi6LLsbcTqTO/hfTsNviKsNeyMBPICJCC7QXRF3+07bAP6FRwA8rczJPBqXDc0CkQ==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "deep-extend": "~0.6.0",
+        "lodash.padend": "^4.6.1",
+        "typical": "^2.6.1",
+        "wordwrapjs": "^3.0.0"
+      }
+    },
     "taffydb": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
@@ -10789,6 +13417,12 @@
         }
       }
     },
+    "temp-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz",
+      "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=",
+      "dev": true
+    },
     "term-size": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
@@ -10798,6 +13432,16 @@
         "execa": "^0.7.0"
       }
     },
+    "test-value": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz",
+      "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
+      "dev": true,
+      "requires": {
+        "array-back": "^2.0.0",
+        "typical": "^2.6.1"
+      }
+    },
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -11001,9 +13645,15 @@
       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
     },
     "typescript": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.3.tgz",
-      "integrity": "sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.1.tgz",
+      "integrity": "sha512-Veu0w4dTc/9wlWNf2jeRInNodKlcdLgemvPsrNpfu5Pq39sgfFjvIIgTsvUHCoLBnMhPoUA+tFxsXjU6VexVRQ==",
+      "dev": true
+    },
+    "typical": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+      "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
       "dev": true
     },
     "ua-parser-js": {
@@ -11123,6 +13773,34 @@
         }
       }
     },
+    "unicode-canonical-property-names-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+      "dev": true
+    },
+    "unicode-match-property-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+      "dev": true,
+      "requires": {
+        "unicode-canonical-property-names-ecmascript": "^1.0.4",
+        "unicode-property-aliases-ecmascript": "^1.0.4"
+      }
+    },
+    "unicode-match-property-value-ecmascript": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz",
+      "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==",
+      "dev": true
+    },
+    "unicode-property-aliases-ecmascript": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz",
+      "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==",
+      "dev": true
+    },
     "union-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
@@ -11353,7 +14031,6 @@
       "version": "0.10.4",
       "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
       "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
-      "dev": true,
       "requires": {
         "inherits": "2.0.3"
       }
@@ -11495,6 +14172,12 @@
       "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
       "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
     },
+    "walk-back": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.0.tgz",
+      "integrity": "sha1-I1h4ejXakQMtrV6S+AsSNw2HlcU=",
+      "dev": true
+    },
     "warning": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.2.tgz",
@@ -11972,6 +14655,16 @@
       "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
       "dev": true
     },
+    "wordwrapjs": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
+      "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
+      "dev": true,
+      "requires": {
+        "reduce-flatten": "^1.0.1",
+        "typical": "^2.6.1"
+      }
+    },
     "worker-farm": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
diff --git a/package.json b/package.json
index 2953270..dd51450 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
     "dev": "webpack --mode development",
     "watch": "webpack --watch --mode development",
     "start": "nodemon --watch build build/bundle.js",
-    "doc": "jsdoc -c configfile_doc.json",
+    "doc": "jsdoc --configure configfile_doc.json",
     "lint": "eslint src/"
   },
   "repository": {
@@ -43,8 +43,10 @@
     "morgan": "^1.9.1",
     "passport": "^0.4.0",
     "passport-ldapauth": "^2.0.0",
+    "path": "^0.12.7",
     "pg": "^7.4.3",
     "pug": "^2.0.3",
+    "react": "^16.5.2",
     "serve-favicon": "^2.5.0",
     "url-loader": "^0.6.2"
   },
@@ -55,6 +57,12 @@
     "@types/knex": "^0.14.24",
     "@types/node": "^10.10.3",
     "@types/passport": "^0.4.6",
+    "@babel/cli": "^7.0.0-beta.40",
+    "@babel/core": "^7.0.0-beta.40",
+    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.40",
+    "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.40",
+    "@babel/preset-env": "^7.0.0-beta.40",
+    "@babel/preset-typescript": "^7.0.0-beta.40",
     "babel-eslint": "^8.2.6",
     "eslint": "^4.19.1",
     "eslint-config-standard": "^11.0.0",
@@ -64,9 +72,11 @@
     "eslint-plugin-promise": "^3.8.0",
     "eslint-plugin-standard": "^3.1.0",
     "jsdoc": "^3.5.5",
+    "jsdoc-babel": "^0.4.0-alpha.0",
+    "jsdoc-to-markdown": "^4.0.1",
     "nodemon": "^1.18.4",
     "ts-loader": "^4.5.0",
-    "typescript": "^3.0.3",
+    "typescript": "^3.1.1",
     "webpack": "^4.19.1",
     "webpack-cli": "^2.1.5",
     "webpack-graphql-loader": "^1.0.0",
diff --git a/src/graphql/typeDefs/actions.graphql b/src/graphql/typeDefs/actions.graphql
index fc1a0e5..82964a6 100644
--- a/src/graphql/typeDefs/actions.graphql
+++ b/src/graphql/typeDefs/actions.graphql
@@ -54,7 +54,6 @@ type Query {
     # Viewer Queries
     
     test : String
-
 }
 
 type Mutation {
diff --git a/src/ldap/admins.js b/src/ldap/admins.ts
similarity index 80%
rename from src/ldap/admins.js
rename to src/ldap/admins.ts
index a9ca438..7a9bf8a 100644
--- a/src/ldap/admins.js
+++ b/src/ldap/admins.ts
@@ -4,25 +4,35 @@
  * @author hawkspar
  */
 
-import LDAP from './basics.js';
-import Tests from './utilities.js';
-import User from './users.js';
-// Essentiels pour le fichier de config
-import path from 'path';
-import fs from 'fs';
+import {config} from './config';
+import {LDAP} from './basics';
+import {Tests} from './utilities';
+import { Open, User, userData, groupData } from './users';
 
-// Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement
-var configPath = path.resolve('./','ldap_config.json');
-var config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
+/**
+ * @interface userFullData
+ * @desc Interface avec toutes les données d'un utilisateur. Etend {@link userData}.
+ * @var {string} password - Mot de passe généré en amont
+ * @arg {string} readPerm - Permissions spéciales BR
+ * @var {string} writePerm - Permissions spéciales BR
+ * @var {string[]} forlifes - Alias BR (attention le filtre .fkz n'est plus fonctionnel)
+ * @var {string[]} groupsIsAdmin - Liste des gid dont le pax est admin ; supposé sous-liste de groups
+ */
+export interface userFullData extends userData {
+    password: string,
+    readPerm: string,
+    writePerm: string,
+    forlifes: string[],
+    groupsIsAdmin: string[]
+}
 
 export class Admin extends User {
     /**
      * @class Cette classe est la classe de l'administrateur d'un groupe qui lui permet de rajouter des membres, en supprimer, idem pour des admins,
      * ou éditer, voir supprimer le groupe.
      * @summary Ce constructeur appelle simplement le constructeur de sa classe mère.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.bind}.
     */
-    constructor(user) { super(user); }
+    constructor() { super(); }
     
     //------------------------------------------------------------------------------------------------------------------------
     // Fonctions de relation TBT
@@ -35,12 +45,12 @@ export class Admin extends User {
      * @arg {string} uid - Identifiant du futur membre
      * @arg {string} gid - Identifiant du groupe
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async addGroupMember(uid, gid) {
+    static async addGroupMember(uid: string, gid: string) {
         try {
             // Vérifie que l'utilisateur est pas déjà membre pour groupes
-            let lm = await this.getMembers(gid);
+            let lm = await Open.getMembers(gid);
             if (!lm.includes(uid)) {
                 let vals = {};
                 vals[config.groups.member] = uid;
@@ -55,7 +65,7 @@ export class Admin extends User {
         }
         try {
             // Vérifie que l'utilisateur est pas déjà membre pour users
-            let lg = await this.getGroups(uid);
+            let lg = await Open.getGroups(uid);
             if (!lg.includes(gid)) {
                 let vals2 = {};
                 vals2[config.users.groups] = gid;
@@ -77,12 +87,12 @@ export class Admin extends User {
      * @arg {string} uid - Identifiant de l'ex-membre
      * @arg {string} gid - Identifiant du groupe
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async delGroupMember(uid, gid) {
+    static async delGroupMember(uid: string, gid: string) {
         try {
             // Vérifie que l'utilisateur est pas déjà viré pour groupes
-            let lm = await this.getMembers(gid);
+            let lm = await Open.getMembers(gid);
             if (lm.includes(uid)) {
                 // Supprime tous les utilisateurs
                 if (!await LDAP.change(config.key_id+gid+config.dn_groups, "del", config.group.member)) {
@@ -102,7 +112,7 @@ export class Admin extends User {
             throw "Erreur pour obtenir une liste de membres d'un groupe pour supprimer un membre du groupe.";
         }
         try {
-            let lg = await this.getGroups(uid);
+            let lg = await Open.getGroups(uid);
             // Vérifie que l'utilisateur est pas déjà viré pour users
             if (lg.includes(gid)) {
                 // Supprime tous les groupes
@@ -132,13 +142,13 @@ export class Admin extends User {
      * @arg {string} uid - Identifiant du futur membre
      * @arg {string} gid - Identifiant du groupe
      * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async addGroupAdmin(uid, gid){
+    static async addGroupAdmin(uid: string, gid: string){
         // Ajoute le membre au groupe avant d'en faire un admin
-        if (!await this.addGroupMember(uid,gid)) { throw "Erreur lors de l'ajout du futur admin en tant que membre."; }
+        if (!await Admin.addGroupMember(uid,gid)) { throw "Erreur lors de l'ajout du futur admin en tant que membre."; }
         try {
-            let la = await this.getAdmins(gid);
+            let la = await Open.getAdmins(gid);
             if (!la.includes(uid)) {
                 // Finalement modification, uniquement dans groups
                 let vals = {};
@@ -160,20 +170,20 @@ export class Admin extends User {
      * @arg {string} uid - Identifiant du futur membre
      * @arg {string} gid - Identifiant du groupe
      * @return {boolean} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async delGroupAdmin(uid, gid) {
+    static async delGroupAdmin(uid: string, gid: string) {
         // Peut paraître absurde mais permet de s'assurer que le membre est bien présent et que ses champs sont comme il faut
-        if (!(await this.delGroupMember(uid, gid)&&this.addGroupMember(uid,gid))) { throw "Erreur dans l'éjection/réadmission du futur admin."; }
+        if (!(await Admin.delGroupMember(uid, gid)&&Admin.addGroupMember(uid,gid))) { throw "Erreur dans l'éjection/réadmission du futur admin."; }
         try {
             // Vérifie que l'utilisateur est bien admin (comme dans delGroupMember)
-            let la = await this.getAdmins(gid);
+            let la = await Open.getAdmins(gid);
             if (la.includes(uid)) {
                 // Supprime tous les administrateurs
                 if (!await LDAP.change(config.key_id+gid+config.dn_groups, "del", config.group.admin)) { throw "Erreur dans la suppression de tous les admins pour en supprimer un."; }
                 // Les rajoute un par un, sauf pour le supprimé
                 la.forEach(id => {
-                    if (id!=uid) { this.addGroupAdmin(id, gid).then(res => {
+                    if (id!=uid) { Admin.addGroupAdmin(id, gid).then(res => {
                         if (!res) { throw "Erreur dans le réajout d'un des autres admins."; }
                     }); }
                 });
@@ -188,19 +198,19 @@ export class Admin extends User {
     //------------------------------------------------------------------------------------------------------------------------
     // Fonction d'édition TBT
     //------------------------------------------------------------------------------------------------------------------------
-    
+
     /**
      * @summary Fonction qui édite un groupe existant dans le LDAP. Très similaire à {@link User.addGroup}
      * @desc Appelle {@link LDAP.add} bien sûr, mais aussi {@link Admin.addGroupMember} et {@link Admin.addGroupAdmin} en godmode pour gérer les groupes du nouvel utilisateur.
      * @arg {string} gid - Identifiant du groupe à modifier
-     * @arg {Object} data - Dictionnaire des informations utilisateurs au même format que pour {@link User.addGroup} avec tous les champs optionnels.
+     * @arg {groupData} data - Dictionnaire des informations utilisateurs au même format que pour {@link User.addGroup} avec tous les champs optionnels.
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async editGroup(gid, data) {
+    static async editGroup(gid: string, data: groupData) {
         try {
             // Récupération des anciennes données
-            let profil = await this.peekGroup(gid);
+            let profil = await Open.peekGroup(gid);
             // Reecriture de profil avec les bons champs
             Object.keys(profil).forEach(keyLDAP => {
                 Object.keys(config.group).forEach(keyAlias => {
@@ -213,7 +223,7 @@ export class Admin extends User {
                 profil[key]=data[key];
             });
             // Modification propre
-            if (!await this.delGroup(gid)&&await this.addGroup(profil)) { throw "Erreur de la destruction/recréation du groupe pour le modifier."; }
+            if (!await Admin.delGroup(gid)&&await User.addGroup(profil)) { throw "Erreur de la destruction/recréation du groupe pour le modifier."; }
             return true;
         }
         catch(err) {
@@ -231,12 +241,12 @@ export class Admin extends User {
      * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Admin.delGroupMember} et {@link Admin.delGroupAdmin} pour gérer les groupes de l'utilisateur sortant.
      * @arg {string} gid - gid de la victime
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async delGroup(gid) {
+    static async delGroup(gid) {
         try {
             // Gestion des membres et administrateurs d'abord
-            let profil = await this.constructor.peekGroup(gid);
+            let profil = await Open.peekGroup(gid);
             // Ordre important
             profil[config.group['admin']].forEach( id => {
                 this.delGroupAdmin( id, gid).then(res => { if (!res) { throw "Erreur lors de la suppression d'un admin d'un groupe en cours de suppression."; } });
@@ -257,11 +267,10 @@ export class Admin extends User {
 export class Supervisor extends Admin {
     /**
      * @class Cette classe est la classe du super administrateur qui créé et supprime des membres.
-     * @summary Bête appel au constructeur de la classe mère.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.bind}.
+     * @summary Constructeur vide.
      * @author hawkspar
      */
-    constructor(user) { super(user); }
+    constructor(user) { super(); }
 
     //------------------------------------------------------------------------------------------------------------------------
     // Fonctions de création TBT
@@ -270,27 +279,11 @@ export class Supervisor extends Admin {
     /**
      * @summary Fonction qui créé un nouvel utilisateur dans le LDAP.
      * @desc Appelle {@link LDAP.add} bien sûr, mais aussi {@link User.addGroupMember} et {@link Admin.addGroupAdmin} pour gérer les groupes du nouvel utilisateur.
-     * @arg {Object} data - Dictionnaire des informations utilisateurs. Des erreurs peuvent apparaître si tous les champs ne sont pas remplis.
-     * @arg {string} data[givenName] - Prénom
-     * @arg {string} data[lastName] - Nom
-     * @arg {string} data[nickname] [] - Surnom
-     * @arg {string} data[birthdate] - Date d'anniversaire au format annee-mois-jour
-     * @arg {string} data[password] - Mot de passe (doit être généré en amont)
-     * @arg {string} data[promotion] - Simple année d'entrée école (pas d'X)
-     * @arg {string} data[mail] - Courriel supposé valide
-     * @arg {string} data[phone] - String du numéro de portable
-     * @arg {string} data[photo] - Photo jpeg directement en bytestring
-     * @arg {string} data[room] - Pour l'instant juste le numéro de casert ou rien, à terme l'adresse complète
-     * @arg {string} data[readPerm] [] - Permissions spéciales BR sous la forme "*truc,"
-     * @arg {string} data[writePerm] [] - Permissions spéciales BR sous la forme "*truc,"
-     * @arg {string[]} data[forlifes] [] - Liste d'alias spéciaux BR (attention le filtre .fkz n'est plus fonctionnel)
-     * @arg {string[]} data[ips] - Liste des ips connus de la personne
-     * @arg {string[]} data[groups] [] - Liste des gid dont le pax est membre (doit contenir "on_platal" si il y a lieu)
-     * @arg {string[]} data[groupsIsAdmin] [] - Liste des gid dont le pax est admin ; supposé sous-liste du précédent
+     * @arg {userFullData} data - Dictionnaire des informations utilisateurs. Des erreurs peuvent apparaître si tous les champs ne sont pas remplis.
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async addUser(data) {
+    static async addUser(data: userFullData) {
         // Calcul d'un dictionnaire d'ajout
         let vals = {};
 
@@ -378,12 +371,12 @@ export class Supervisor extends Admin {
 
         // Utilisation des fonctions adaptées pour assurer la cohérence de l'ensemble
         data['groupsIsMember'].forEach(gid => {
-            this.addGroupMember(vals[config.key_id], gid).then(res => {
+            Admin.addGroupMember(vals[config.key_id], gid).then(res => {
                 if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe."; }
             });
         });
         data['groupsIsAdmin'].forEach(gid => { 
-            this.addGroupAdmin( vals[config.key_id], gid).then(res => {
+            Admin.addGroupAdmin( vals[config.key_id], gid).then(res => {
                 if (!res) { throw "Erreur lors de l'ajout du nouvel utilisateur à un groupe en tant qu'admin."; }
             });
         });
@@ -401,23 +394,23 @@ export class Supervisor extends Admin {
      * Appelle {@link LDAP.clear} bien sûr, mais aussi {@link Admin.delGroupMember} et {@link Admin.delGroupAdmin} pour gérer les groupes de l'utilisateur sortant.
      * @arg {string} uid - uid de la victime
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async delUser(uid) {
+    static async delUser(uid: string) {
         try {
             // Gestion des groupes d'abord
-            let profil = await this.peekUser(uid);
+            let profil = await Open.peekUser(uid);
             profil[config.user['groups']].forEach(gid => {
-                if (this.isGroupAdmin(gid)) {
-                    if (!this.delGroupAdmin(uid, gid)) { throw "Erreur lors de la suppression des droits d'admin de l'utilisateur."; }
+                if (Open.isGroupAdmin(uid,gid)) {
+                    if (!Admin.delGroupAdmin(uid, gid)) { throw "Erreur lors de la suppression des droits d'admin de l'utilisateur."; }
                 }
-                if (!this.delGroupMember(uid, gid)) { throw "Erreur lors de la suppression de l'appartenace à un groupe de l'utilisateur."; }
+                if (!Admin.delGroupMember(uid, gid)) { throw "Erreur lors de la suppression de l'appartenace à un groupe de l'utilisateur."; }
             });
         }
         catch(err) {
             throw "Erreur lors de l'obtention des informations de l'utilisateur à supprimer.";
         }
         // Elimination
-        if (!this.LDAP.clear(config.key_id+"="+uid+","+config.dn_users)) { throw "Erreur lors de la suppression de l'utilisateur."; }
+        if (!LDAP.clear(config.key_id+"="+uid+","+config.dn_users)) { throw "Erreur lors de la suppression de l'utilisateur."; }
     }
 }
\ No newline at end of file
diff --git a/src/ldap/basics.js b/src/ldap/basics.ts
similarity index 65%
rename from src/ldap/basics.js
rename to src/ldap/basics.ts
index 80b6fe1..0ed8982 100644
--- a/src/ldap/basics.js
+++ b/src/ldap/basics.ts
@@ -7,22 +7,17 @@
  * @author hawkspar
  */
 
-import ldap  from 'ldapjs';
+import ldap from 'ldapjs';
 // Toutes les entrées utilisateur sont escapées par sécurité
 import ldapEscape from 'ldap-escape';
-// Essentiels pour le fichier de config
-import path from 'path';
-import fs from 'fs';
+// Fichier de config du ldap
+import {config, credentialsConfig} from './config';
 
 // Important ; permet de vérifier que l'utilisateur reste connecté.
-var ensureLoggedin =  require('connect-ensure-login').ensureLoggedIn;
-
-// Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement
-var configPath = path.resolve('./','ldap_config.json');
-var config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
+//var ensureLoggedin =  require('connect-ensure-login').ensureLoggedIn; //hawkspar->manifold : est-ce encore utile ? je ne crois pas
 
 // Connection au serveur LDAP avec des temps de timeout arbitraires
-var client = ldap.createClient({ url: config.ldap.server});
+var client = ldap.createClient({ url: config.server});
 
 //------------------------------------------------------------------------------------------------------------------------
 // Fonctions de base agissant sur le LDAP
@@ -36,19 +31,18 @@ export class LDAP {
     constructor() {}
 
     /**
-     * @summary Fonction qui sert à s'identifier sur le LDAP. Ne renvoie rien.
+     * @summary Fonction qui sert à s'identifier sur le LDAP.
      * @desc Assez important en terme de sécurité, de gestion de conflit, et de droit d'accès. Méthode ldapjs 
      * (voir [`Client API`](http://ldapjs.org/client.html) méthode bind).
-     * @arg {Object} user - Utilisateur de la forme suivante :
-     * @arg {string} user[uid] - User identifier
-     * @arg {string} user[password] - Mot de passe
+     * @arg {string} dn - Nom de domaine ; identifiant de l'utilisateur cherchant à se connecter
+     * @arg {string} password - Mot de passe de l'utilisateur cherchant à se connecter
      * @returns {Promise(boolean)} `true` si l'opération s'est bien déroulée, `false` sinon.
      * @static @async
      */
-    static async bind(user) {
+    static async bind(dn: string, password: string) {
         return new Promise((resolve, reject) => {
             // Escape DN as everywhere in this file, but password is taken as is
-            client.bind(ldapEscape.dn("${txt}", { txt: user["dn"]}), user["password"], res => {
+            client.bind(dn, password, res => {
                 // Gestion erreur
                 try { res; }
                 catch(err) {
@@ -62,27 +56,35 @@ export class LDAP {
     }
 
     /**
-     * @summary Fonction qui sert à se déconnecter du LDAP. Ne renvoie rien.
-     * @desc Assez important en terme de sécurité, de gestion de conflit, et de droit d'accès. Fait appel à {@link LDAP.bind}
+     * @summary Fonction qui sert à s'identifier sur le LDAP avec plein pouvoirs.
+     * @desc Appelle {@link bind} avec un utilisateur tout puissant.
      * @returns {Promise(boolean)} `true` si l'opération s'est bien déroulée, `false` sinon.
      * @static @async
      */
-    static async unbind() { return this.bind({"uid":"", "password":""}); }
+    static async adminBind() { return this.bind(credentialsConfig.dn, credentialsConfig.password); }
+
+    /**
+     * @summary Fonction qui sert à se déconnecter du LDAP.
+     * @desc Assez important en terme de sécurité, de gestion de conflit, et de droit d'accès.
+     * Fait appel à {@link LDAP.bind} avec deux champs vides.
+     * @returns {Promise(boolean)} `true` si l'opération s'est bien déroulée, `false` sinon.
+     * @static @async
+     */
+    static async unbind() { return this.bind("", ""); }
 
     /**
      * @summary Fonction qui interroge le LDAP selon un protocole spécifié en argument et renvoit les valeurs trouvées.
-     * @desc Cette fonction utilise ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode search). Il faut l'appeler suivant un schéma
-     * `rechercher(...).then((res) => { truc avec res });`. Cette fonction fait une demande au LDAP qu'elle filtre selon un schéma prédéfini dans `dic`
-     * et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
+     * @desc Cette fonction utilise ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode search). Cette fonction fait une demande au LDAP
+     * qu'elle filtre selon un schéma prédéfini dans `filter` et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
      * @arg {string} dn - DN de l'emplacement de la requête
      * @arg {string} filter ["(objectClass=*)"] - Filtre logique de la recherche (format [`RFC2254`](https://tools.ietf.org/search/rfc2254)) déjà passé au ldapEscape
-     * @arg {string} filter_dic[key] - Vraie valeur pertinente de la recherche
      * @arg {string[]} attributes - Liste des attributs qui figureront dans le résultat final ; peut aussi être un seul élément
-     * @return {Promise(Object[])} Résultats de la recherche ; soit une liste de valeurs d'attributs, 
+     * @return {(Promise(Array.<Object>)|Promise(Array.Object.<string, Object>))} Résultats de la recherche ; soit une liste de valeurs d'attributs, 
      * soit une liste de dictionnaires si on veut plus d'un attribut (les clés du dictionnaire sont celles du LDAP)
      * @static @async
      */
-    static async search(dn, attributes, filter="(objectClass=*)") {
+    static async search(dn: string, attributes: string[], filter="(objectClass=*)") {
+        this.adminBind();
         return new Promise((resolve, reject) => {
             let vals=[];
             // Interrogation LDAP selon configuration fournie en argument
@@ -112,7 +114,10 @@ export class LDAP {
                     // Si la recherche renvoie une erreur, on renvoit
                     res.on('error', resErr => { reject(resErr); });
                     // Si la recherche est finie on se déconnecte et on renvoit la liste
-                    res.on('end', res => { resolve(vals); });
+                    res.on('end', res => {
+                        this.unbind();
+                        resolve(vals);
+                    });
                 }
             });
         });
@@ -121,18 +126,17 @@ export class LDAP {
     //TBT
     /**
      * @summary Fonction qui permet de modifier un élément sur le LDAP. Gestion intelligente de l'appartenance à un binet.
-     * @desc Cette fonction utilise une Promise pour être asynchrone ; elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs
-     * (voir [`Client API`](http://ldapjs.org/client.html) méthode modify). Il faut l'appeler suivant un schéma `LDAP.modifier(...).then((res) => { truc avec res });`.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.connecter}
+     * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode modify).
      * @arg {string} dn - DN de l'endroit à modifier
      * @arg {string} op - Operation à réaliser sur le LDAP. Trois opération sont possibles ; "add", qui rajoute des attributs et qui peut créer des doublons,
      * "del" qui en supprime, et "replace" qui remplace du contenu par un autre. 
-     * @arg {Object} mod - Dictionnaire contenant les attributs à modifier et les nouvelles valeurs des attributs. Une nouvelle valeur vide ("") est équivalent à la suppression
-     * de cet attribut.
+     * @arg {Object.<string, string>} mod - Dictionnaire contenant les attributs à modifier et les nouvelles valeurs des attributs.
+     * @arg {Object} mod[key] - Nouvelle valeur de l'attribut key. Une nouvelle valeur vide ("") est équivalent à la suppression de cet attribut.
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, `false` sinon.
      * @static @async
      */
-    static async change(dn, op, mod) {
+    static async change(dn: string, op: string, mod) {
+        this.adminBind();
         return new Promise((resolve, reject) => {
             // Modification LDAP selon configuration en argument (pourrait prendre une liste de Changes)
             client.modify(ldapEscape.dn("${txt}", {txt: dn}), new ldap.Change({
@@ -143,6 +147,7 @@ export class LDAP {
                 reject(err);
                 throw "Erreur lors d'une opération de modification sur le LDAP.";
             });
+            this.unbind();
             resolve(true);
         });
     }
@@ -150,23 +155,22 @@ export class LDAP {
     //TBT
     /**
      * @summary Fonction qui permet de rajouter un élément sur le LDAP.
-     * @desc Cette fonction appelle {@link LDAP.connecter} pour authentifier l'utilisateur puis rompts la connexion. Cette fonction utilise une Promise pour être asynchrone ;
-     * elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode add).
-     * Il faut l'appeler suivant un schéma `LDAP.ajouter(...).then((res) => { truc avec res });`.
-     * @arg {Object} user - Utilisateur de la forme nécessaire au {@linkoperationsLDAP. connecterLDAP}
+     * @desc  Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode add).
      * @arg {string} dn - Adresse du parent
-     * @arg {Object} vals - Dictionnaire contenant les valeurs à créer
-     * @arg {string} vals[key] - Nouvelle valeur pour le champ key
+     * @arg {Object.<string, string>} vals - Dictionnaire contenant les valeurs à créer
+     * @arg {Object} vals[key] - Nouvelle valeur pour le champ key
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon.
      * @static @async
      */
-    static async add(dn, vals) {
+    static async add(dn: string, vals) {
+        this.adminBind();
         return new Promise((resolve, reject) => {
             // Ajout LDAP selon la configuration en argument
             client.add(ldapEscape.dn(config.key_id+"="+vals[config.key_id]+",${txt}", { txt: dn}), vals, err => {
                 reject(err);
                 throw "Erreur lors d'une opération d'ajout sur le LDAP.";
             });
+            this.unbind();
             resolve(true);
         });
     }
@@ -174,23 +178,21 @@ export class LDAP {
     //TBT
     /**
      * @summary Fonction qui permet de supprimer une feuille du LDAP.
-     * @desc Cette fonction appelle {@link LDAP.connecter} pour authentifier l'utilisateur puis rompts la connexion. Cette fonction utilise une Promise pour être asynchrone ;
-     * elle renvoit la promesse d'une réponse puis traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode del).
-     * Il faut l'appeler suivant un schéma `LDAP.supprimer(...).then((res) => { truc avec res });`. Cette fonction fait une demande au LDAP qu'elle filtre selon un
-     * schéma prédéfini dans `dic` et à chaque résultat (event SearchEntry) le met dans une liste, et renvoit la liste à l'issue (event end).
+     * @desc Cette fonction traite la demande avec ldapjs (voir [`Client API`](http://ldapjs.org/client.html) méthode del).
      * Elle est différente de modify avec "del" car elle affecte directement une feuille et pas un attribut.
-     * @arg {Object} user - Utilisateur de la forme nécessaire au {@link LDAP.connecter}
      * @arg {string} dn - Adresse de la cible
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
      * @static @async
      */
-    static async clear(dn) {
+    static async clear(dn: string) {
+        this.adminBind();
         return new Promise((resolve, reject) => {
             // Suppression LDAP
             client.del(ldapEscape.dn("${txt}", {txt: dn}), err => {
                 reject(err);
                 throw "Erreur lors d'une opération de suppression sur le LDAP.";
             });
+            this.unbind();
             resolve(true);
         });
     }
diff --git a/src/ldap/config.js b/src/ldap/config.js
deleted file mode 100644
index f27fbc9..0000000
--- a/src/ldap/config.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @file Importe la configuration du LDAP au sein de l'application, et remplace certaines valeurs en fonction des variables d'environnement.
- * @author manifold
- */
-
-const fs = require('fs');
-const path = require('path');
-const colors = require('colors');
-// Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement
-const configPath = path.resolve('./', 'ldap_config.json');
-const credsPath = path.resolve('./', 'ldap_connexion_config.json');
-console.log(colors.cyan("Loading LDAP config file from %s"), configPath);
-console.log(colors.cyan("Loading LDAP credentials from %s"), credsPath);
-const ldapConfig = JSON.parse(fs.readFileSync(configPath));
-const credentialsConfig = JSON.parse(fs.readFileSync(credsPath));
-
-// Override config server from environment
-if (process.env.LDAP_URI != null) {
-    ldapConfig.ldap.server = process.env.LDAP_URI;
-}
-
-module.exports = {
-    ldapConfig,
-    credentialsConfig
-};
\ No newline at end of file
diff --git a/ldap_config.json b/src/ldap/config.json
similarity index 79%
rename from ldap_config.json
rename to src/ldap/config.json
index 1eaee9c..d043e83 100644
--- a/ldap_config.json
+++ b/src/ldap/config.json
@@ -1,10 +1,6 @@
 {
 	"comment_1": "Tout ce fichier sert à protéger les vrais champs du LDAP dans les scripts dans src/ldap. Les champs ci-dessous contiennent le nécessaire à une première connexion par exemple.",
-	"ldap": {
-		"server": "ldap://frankiz.eleves.polytechnique.fr:389",
-		"searchBase": "ou=eleves,dc=frankiz,dc=net",
-		"searchFilter": "(uid={{username}})"
-	},
+	"server": "ldap://frankiz.eleves.polytechnique.fr:389",
 	
 	"comment_2": "Noms de domaines dans LDAP ; le niv d'après est en uid=, voir Wikipedia",
 	"dn_groups":"ou=groups,dc=frankiz,dc=net",
@@ -15,7 +11,7 @@
 	"user": {
 		"direct_input": ["givenName","lastName","birthdate", "promotion", "mail","phone","photo","adress"],
 		"multiple_input": ["ips","forlifes"],
-		"profil": ["jpegPhoto","displayName","givenName", "sn", "brBirthdate", "brPromo","telephoneNumber","mail","brRoom","brIP","brMemberOf","brNewsReadAccess","brNewsPostAccess","brAlias"],
+		"profil": ["jpegPhoto","displayName","givenName", "sn", "brBirthdate", "brPromo","telephoneNumber","mail","brRoom","brIP","brMemberOf"],
 		"photo": "jpegPhoto",
 		"givenName": "givenName",
 		"lastName": "sn",
@@ -26,7 +22,7 @@
 		"phone": "telephoneNumber",
 		"mail": "mail",
 		"adress": "brRoom",
-		"ips": "brIP",
+		"ip": "brIP",
 		"id": "uidNumber",
 		"sport": "brMemberOf",
 		"password": "userPassword",
@@ -39,7 +35,7 @@
 		"login": "loginShell",
 		"groups": "brMemberOf",
 		"school": "brMemberOf",
-		"studies": "brMemberOf",
+		"course": "brMemberOf",
 		"cleanFullName": "gecos",
 		"class": "objectClass"
 	},
@@ -60,19 +56,5 @@
 		"readPerm": "brNewsReadAccess",
 		"writePerm": "brNewsPostAccess"
 	},
-	"comment_5": "Placeholders pour certaines fonctions dans LDAP",
-	"am": {
-		"key_gr": "restrictedMemberUid",
-		"key_u": "brMemberOf"
-	},
-	"aa": {
-		"key_gr": "memberUid"
-	},
-	"sm": {
-		"attributs": ["restrictedMemberUid", "brMemberOf"]
-	},
-	"sa": {
-		"attributs": "memberUid"
-	},
 	"sessionSecret":"ozyNMHdT,WFTu|t"
 }
\ No newline at end of file
diff --git a/src/ldap/config.ts b/src/ldap/config.ts
new file mode 100644
index 0000000..38368e8
--- /dev/null
+++ b/src/ldap/config.ts
@@ -0,0 +1,16 @@
+/**
+ * @file Importe la configuration du LDAP au sein de l'application, et remplace certaines valeurs en fonction des variables d'environnement.
+ * @author manifold
+ */
+
+import fs from 'fs';
+import colors from 'colors';
+// Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement
+console.log(colors.cyan("Loading LDAP config file from config.json"));
+console.log(colors.cyan("Loading LDAP credentials from connexion_config.json"));
+export const config = JSON.parse(fs.readFileSync('config.json').toString());
+export const credentialsConfig = JSON.parse(fs.readFileSync('connexion_config.json').toString());
+// Override config server from environment
+if (process.env.LDAP_URI != null) {
+    config.ldap.server = process.env.LDAP_URI;
+}
\ No newline at end of file
diff --git a/src/ldap/users.js b/src/ldap/users.ts
similarity index 79%
rename from src/ldap/users.js
rename to src/ldap/users.ts
index 736161a..26552b6 100644
--- a/src/ldap/users.js
+++ b/src/ldap/users.ts
@@ -4,16 +4,53 @@
  * @author hawkspar
  */
 
-import LDAP from './basics.js';
-import {SmartSearch, Tests} from './utilities.js';
-import {Admin, SuperAdmin} from './admins.js';
-// Essentiels pour le fichier de config
-import path from 'path';
-import fs from 'fs';
+import {config} from './config';
+import {LDAP} from './basics';
+import {searchUserFields, SmartSearch, Tests} from './utilities.js';
+import {Admin, Supervisor} from './admins.js';
 
-// Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement
-var configPath = path.resolve('./','ldap_config.json');
-var config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
+/**
+ * @interface groupData
+ * @var {string} name - Nom du groupe
+ * @var {string} ns - Statut du groupe ; 'binet' ou 'free', càd ouvert à tous
+ * @var {string[]} members - Liste des membres du groupe
+ * @var {string[]} admins - Liste des admins du groupe ; supposée être une sous-liste de la précédente
+ */
+export interface groupData {
+    name:string,
+    ns: string,
+    members:string[],
+    admins: string[]
+}
+
+/**
+ * @interface userData
+ * @desc Interface avec toutes les données extractables pour un utilisateur.
+ * @var {string} givenName - Prénom
+ * @var {string} lastName - Nom
+ * @var {string} nickname - Surnom
+ * @var {string} photo - Bytestring de la photo de l'utilisateur
+ * @var {string} birthdate - Date d'anniversaire
+ * @var {string} promotion - Année(s) de promo
+ * @var {string} phone - Numéro(s) de téléphone
+ * @var {string} mail - Adresse(s) courriel
+ * @var {string} ip - Adresse(s) ip
+ * @var {string} adress - Adresse(s)
+ * @var {string} groups - Un ou plusieurs groupes dont l'utilisateur est membre (inclus section sportive, binet, PA...)
+ */
+export interface userData {
+    givenName: string,
+    lastName: string,
+    nickname: string,
+    photo: string,
+    birthdate: string,
+    promotion: string,
+    phone: string,
+    mail: string,
+    ip: string,
+    adress: string,
+    groups: string,
+}
 
 //------------------------------------------------------------------------------------------------------------------------
 // Classes à exporter TBT
@@ -36,7 +73,7 @@ export class Open {
      * @return {Promise(string[])} Liste des uid de groupes (noms flat des groupes) où l'id fourni est membre
      * @static @async
      */
-    static async getGroups(uid) {
+    static async getGroups(uid: string) {
         try {
             return LDAP.search(config.key_id+uid+config.dn_users, config.user.groups)[0];
         }
@@ -52,7 +89,7 @@ export class Open {
      * @return {Promise(String[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
      * @static @async
      */
-    static async getMembers(gid) {
+    static async getMembers(gid: string) {
         try {
             return LDAP.search(config.key_id+gid+config.dn_users, config.group.member)[0];
         }
@@ -68,7 +105,7 @@ export class Open {
      * @return {Promise(string[])} Liste des uid des membres où l'id fournie est membre (noms flat des groupes)
      * @static @async
      */
-    static async getAdmins(gid) {
+    static async getAdmins(gid: string) {
         try {
             return LDAP.search(config.key_id+gid+config.dn_users, config.group.admin)[0];
         }
@@ -85,7 +122,7 @@ export class Open {
      * @returns {Promise(boolean)} True si l'utilisateur est membre
      * @static @async
      */
-    static async isGroupMember(uid, gid) {
+    static async isGroupMember(uid: string, gid: string) {
         try {
             let lg = await this.getGroups(uid);
             let lm = await this.getMembers(gid);
@@ -106,7 +143,7 @@ export class Open {
      * @returns {Promise(boolean)} True si l'utilisateur est administrateur
      * @static @async
      */
-    static async isGroupAdmin(uid, gid) {
+    static async isGroupAdmin(uid: string, gid: string) {
         try {
             let la = await this.getAdmins(gid);
             if (la.includes(uid)) {
@@ -122,11 +159,11 @@ export class Open {
      * @summary Fonction qui renvoit toutes les infos relatives à un utilisateur particulier.
      * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis.
      * @arg {string} uid - Identifiant de l'utilisateur
-     * @return {Promise(Object[])} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet de l'utilisateur ;
+     * @return {Promise(userData)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet de l'utilisateur ;
      * voir `ldap_config.json`(..\..\ldap_config.json) pour les clés exactes.
-     * @static
+     * @static @async
      */
-    static peekUser(uid) {
+    static async peekUser(uid: string) {
         try {
             return LDAP.search(config.key_id+uid+config.dn_users, config.user.profil);
         }
@@ -139,13 +176,21 @@ export class Open {
      * @summary Fonction qui renvoit toutes les infos relatives à un groupe particulier.
      * @desc Cette fonction utilise {@link LDAP.search} avec des attributs prédéfinis.
      * @arg {string} gid - Identifiant du groupe
-     * @return {Promise(Object[])} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet du groupe ;
+     * @return {Promise(groupData)} Informations recueillies ; renvoie une liste de dictionnaire avec le profil complet du groupe ;
      * voir `ldap_config.json`(..\..\ldap_config.json) pour les clés exactes.
-     * @static
+     * @static @async
      */
-    static peekGroup(gid) {
+    static async peekGroup(gid: string) {
         try {
-            return LDAP.search(config.key_id+gid+config.dn_groups, config.group.profil);
+            let groupData = await LDAP.search(config.key_id+gid+config.dn_groups, config.group.profil);
+            let outGroupData={}
+            // Rename output
+            for (var uncleanKey in groupData) {
+                for (var cleanKey in config.group) {
+                    if (uncleanKey==config.group.cleanKey) { outGroupData[cleanKey] = groupData[uncleanKey]; }
+                }
+            }
+            return outGroupData;
         }
         catch(err) {
             throw "Erreur lors d'une recherche d'informations sur un groupe.";
@@ -163,7 +208,7 @@ export class Open {
      * @return {Promise(string[])} Liste des gid dont le nom ressemble à l'input.
      * @static @async
     */
-    static async findGroups(input) {
+    static async findGroups(input: string) {
         try {
             // Trucs intelligents faits dans ./utilities
             return SmartSearch.groups(input, [config.key_id, config.group.type]);
@@ -171,25 +216,17 @@ export class Open {
         catch(err) {
             throw "Erreur lors de la recherche approximative d'un groupe.";
         }
-        /**
-        let gidtyList = [];
-        gList.forEach(g => {
-            // Si le groupe est du bon type on rajoute son gid
-            if (g[config.group.type]==type) { gidtyList.push(g[config.key_id]); }
-        });
-        return gidtyList;
-        */
     }
 
     /**
-     * @summary Fonction qui retrouve les uid des paxs validant les critères de recherche. Autre étape vers vrai TOL (Trombino On Line). Doit être préféré à repliquerTOL
+     * @summary Fonction qui retrouve les uid des paxs validant les critères de recherche. Autre étape vers vrai TOL (Trombino On Line). Doit être préféré à repliquer TOL
      * car moins gourmande envers le LDAP (utiliser {@link peekUser} au cas par cas après pour obtenir les vraies infos).
      * @desc Cette fonction utilise {@link SmartSearch.users}.
-     * @arg {Object} data - Dictionnaire contenant les données nécessaires à {@link SmartSearch.groups}
+     * @arg {searchUserFields} data - Dictionnaire contenant les données nécessaires à {@link SmartSearch.groups}
      * @return {Promise(string[])} gids des profils qui "match" les critères proposés.
      * @static @async
      */
-    static async findUsers(data) {
+    static async findUsers(data: searchUserFields) {
         try {
             return SmartSearch.users(data, config.key_id);
         }
@@ -204,19 +241,9 @@ export class User extends Open {
      * @class Cette classe est la classe de l'utilisateur connecté qui peut déjà créer un groupe et changer son profil.
      * Techniquement, c'est la première classe qui a vraiment besoin de méthodes dynamiques dans l'arborescence, puisque c'est à partir du niveau User
      * qu'on peut commencer à vouloir tracer les actions de l'utilisateur. 
-     * @summary Ce constructeur appelle simplement {@link LDAP.bind}.
-     * @arg {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.bind}.
-     * @async
+     * @summary Constructeur vide.
     */
-    constructor(user) {
-        super();
-        try {
-            LDAP.bind(user);
-        }
-        catch(err) {
-            throw "Erreur lors de la connexion à un compte utilisateur.";
-        }
-    }
+    constructor() { super(); }
 
     //------------------------------------------------------------------------------------------------------------------------
     // Fonction de création TBT
@@ -227,15 +254,11 @@ export class User extends Open {
      * @desc Cette fonction fait une utilisation massive d'eval pour anonymiser son code ; c'est mal et cela suppose que beaucoup de soins ont été pris lors de
      * l'escape de ses paramètres. Appelle {@link LDAP.add} et {@link LDAP.change}, mais aussi {@link Admin.addMemberGroup} et {@link Admin.addAdminGroup}
      * pour gérer les groupes du nouvel utilisateur. Attention une manip FOIREUSE est cachée dedans.
-     * @arg {Object} data - Dictionnaire des informations utilisateurs (voir détail des champs dans config.json)
-     * @arg {string} data[name] - Nom du groupe
-     * @arg {string} data[ns] - Statut du groupe ; 'binet' ou 'free', càd ouvert à tous
-     * @arg {string[]} data[members] - Liste des membres du groupe
-     * @arg {string[]} data[admins] - Liste des admins du groupe ; supposée être une sous-liste de la précédente
+     * @arg {groupData} data - Dictionnaire des informations utilisateurs (voir détail des champs dans config.json)
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async addGroup(data) {
+    static async addGroup(data: groupData) {
         // Calcul d'un dictionnaire d'ajout
         let vals = {};
 
@@ -321,17 +344,18 @@ export class User extends Open {
     /**
      * @summary Fonction qui édite un utilisateur existant dans le LDAP. Très similaire à {@link creerUtilisateur}
      * @desc Appelle simplement {@link creerUtilisateur} et {@link supprimerUtilisateur} en godmode, plus {@link renseignerSurUtilisateur} pour les champs non fournis.
-     * Ce choix a pour conséquence que l'ordre du dictionnaire de correspondance dans ldap_config est important. Une version "nerfée" de cette fonction est envisageable ; elle donne bcp de pouvoir à l'utilisateur.
+     * Ce choix a pour conséquence que l'ordre du dictionnaire de correspondance dans ldap_config est important.
+     * Une version "nerfée" de cette fonction est envisageable ; elle donne bcp de pouvoir à l'utilisateur.
      * @arg {string} uid - Utilisateur à modifier (le plus souvent le même, mais root possible)
-     * @arg {Object} data - Dictionnaire des informations utilisateurs au même format que pour {@link creerUtilisateur} avec tous les champs optionnels ;
+     * @arg {userData} data - Dictionnaire des informations utilisateurs au même format que pour {@link creerUtilisateur} avec tous les champs optionnels ;
      * Attention toutes les clés de cette entrée seront modifiées dans le LDAP ; les nouveaux résultats écrasant les précédents, sauf 'readPerm','writePerm','forlifes','ips','groups' et 'groupsIsAdmin'
      * qui sont censurés pour cette fonction)
      * @return {Promise(boolean)} `true` si la modification s'est bien déroulée, false sinon
-     * @async
+     * @async @static
      */
-    async editUser(uid, data) {
+    static async editUser(uid, data) {
         // Récupération des anciennes données
-        let profil = await this.peekUser(uid);
+        let profil = await Open.peekUser(uid);
         // Reecriture de profil avec les bons champs
         Object.keys(profil).forEach(keyLDAP => {
             Object.keys(config.user).forEach(keyAlias => {
@@ -341,10 +365,10 @@ export class User extends Open {
         });
         // Régénération du champ manquant dans profil
         try {
-            let lg = await this.getGroups(uid);
+            let lg = await Open.getGroups(uid);
             profil['groupsIsAdmin']=[];
             lg.forEach(gid => {
-                this.isGroupAdmin(uid, gid).then(res => {
+                Open.isGroupAdmin(uid, gid).then(res => {
                     if (res) { profil['groupsIsAdmin'].push(gid); }
                 });
             });
@@ -356,10 +380,8 @@ export class User extends Open {
             // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
             // TBM : rajouter god passwd. Moche mais bonne façon de faire
             // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-            // Passage en godmode
-            var god = SuperAdmin({"uid":"", "password":""});
-            // Modification propre par effet de bord
-            if (!(await god.delUser(uid) && await god.createUser(profil))) {
+            // Passage en godmode,modification propre par effet de bord
+            if (!(await Supervisor.delUser(uid) && await Supervisor.addUser(profil))) {
                 throw "Erreur dans la destruction/création du compte.";
             } else {
                 return true;
diff --git a/src/ldap/utilities.js b/src/ldap/utilities.ts
similarity index 74%
rename from src/ldap/utilities.js
rename to src/ldap/utilities.ts
index abcedac..80cb325 100644
--- a/src/ldap/utilities.js
+++ b/src/ldap/utilities.ts
@@ -4,14 +4,41 @@
  * @author hawkspar
  */
 
-import LDAP from './basics.js';
-// Essentiels pour le fichier de config
-import path from 'path';
-import fs from 'fs';
+import {config} from './config';
+import {LDAP} from './basics.js';
 
-// Point central ; tous les champs de la BDD sont 'cachés' dans config.json et pas visibles directement
-var configPath = path.resolve('./','ldap_config.json');
-var config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
+/**
+ * @interface searchUserFields
+ * @desc Interface permettant la recherche d'un utilisateur avec des champs incomplets. Plusieurs valeurs sont possibles pour le même champ.
+ * Aucun de ces champs n'est obligatoire, mais certains de ces champs doivent être exacts pour obtenir un bon résultat.
+ * @var {string|Array.string} givenName - Prénom(s)
+ * @var {string|Array.string} lastName - Nom(s)
+ * @var {string|Array.string} nickname - Surnom(s)
+ * @var {string|Array.string} nationality - Nationalité(s) (à implémenter)
+ * @var {string|Array.string} promotion - Année(s) de promo
+ * @var {string|Array.string} phone - Numéro(s) de téléphone
+ * @var {string|Array.string} mail - Adresse(s) courriel
+ * @var {string|Array.string} ip - Adresse(s) ip
+ * @var {string|Array.string} adress - Adresse(s)
+ * @var {string} school - Ecole d'appartenance (instable, doit être exact)
+ * @var {string|Array.string} groups - Un ou plusieurs groupes dont l'utilisateur est membre (doit être exact).
+ * @var {string} course - PA ou autre. Doit être exact.
+ */
+export interface searchUserFields {
+    givenName: string,
+    lastName: string,
+    nickname: string,
+    nationality: string,
+    promotion: string,
+    phone: string,
+    mail: string,
+    ip: string,
+    adress: string,
+    school: string,
+    groups: string,
+    studies: string,
+    sport: string
+}
 
 //------------------------------------------------------------------------------------------------------------------------
 // Fonctions de recherche
@@ -38,7 +65,7 @@ export class SmartSearch {
      * @return {Promise(string[])} Liste des uid de groupes dont le nom ressemble à l'input
      * @static @async
      */
-    static async groups(input, return_attributes) {
+    static async groups(input: string, return_attributes: string[]) {
         // Construction du filtre custom
         let filter= "(|("+config.key_id+"="+ input+")" +    // On cherche la valeur exacte
                     "(|("+config.key_id+"=*"+input+")" +    // La valeur finale avec des trucs avant ; wildcard *
@@ -59,31 +86,19 @@ export class SmartSearch {
      * @desc Cette fonction utilise {@link LDAP.search} mais avec un filtre généré à la volée. Accepte des champs exacts ou incomplets pour la plupart des champs
      * mais pas approximatifs et ne gère pas l'auto-complete. MEF Timeout pour des recherches trop vagues. Elle utilise LDAPEscape pour éviter les injections.
      * Utiliser trouverGroupesParTypes pour chaque champ relié à groups.
-     * @arg {Object} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse
+     * @arg {searchUserFields} data - Dictionnaire contenant les données nécessaires à la recherche. Les valeurs sont celles entrées par l'utilisateur et sont par hypothèse
      * comme des sous-parties compactes des valeurs renvoyées. Tous les champs ci-dessous peuvent être indifféremment des listes (par exempl pour chercher un membre
      * de plusieurs groupes) ou des éléments isolés. Si un champ n'est pas pertinent, le mettre à '' ou undefined.
-     * @arg {string} data[givenName] - Prénom 
-     * @arg {string} data[lastName] - Nom
-     * @arg {string} data[nickname] - Surnom
-     * @arg {string} data[nationality] - Nationalité (non implémentée pour l'instant, pas de format spécifique)
-     * @arg {string} data[promotion] - String de l'année de promo
-     * @arg {string} data[phone] - String du numéro de portable
-     * @arg {string} data[mail] - Adresse mail
-     * @arg {string} data[ips] - Une ou des adresses ip
-     * @arg {string} data[school] - Ecole d'appartenance (pour l'instant instable). Doit être exact.
-     * @arg {string} data[groups] - Un ou plusieurs groupes (pas de différence entre membre simple et admin). Doit être exact.
-     * @arg {string} data[studies] - PA ou autre. Doit être exact.
-     * @arg {string} data[sport] - Section sportive ou autre Doit être exact.
-     * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final
+     * @arg {string[]} return_attributes - Liste d'attributs à renvoyer dans le résultat final.
      * @return {Promise(Object[])} Liste de dictionnaires de profils en cohérence avec l'input avec pour clés les attributs des profils.
      * @static @async
      */
-    static async users(data, return_attributes) {
+    static async users(data: searchUserFields, return_attributes: string[]) {
         let filter="";
         // Iteration pour chaque champ, alourdissement du filtre selon des trucs prédéfinis dans config encore
         for (var key in data) {
-            if ((data[key]!= undefined) & (data[key] != '')) {                    // Si il y a qque chose à chercher pour ce filtre
-                if (!Array.isArray(data[key])) { data[key]=[data[key]]; }        // Gestion d'une liste de valeurs à rechercher
+            if ((data[key]!= undefined) && (data[key] != '')) {                    // Si il y a qque chose à chercher pour ce filtre
+                if (!Array.isArray(data[key])) { data[key]=[data[key]]; }          // Gestion d'une liste de valeurs à rechercher
                 // Iteration pour chaque valeur fournie par l'utilisateur
                 data[key].forEach(val => {
                     // Traduction en language LDAP
@@ -96,7 +111,7 @@ export class SmartSearch {
                 });
             }
         }
-        // Appel rechercheLDAP avec filtre de l'espace 
+        // Appel avec filtre de l'espace 
         try {
             return LDAP.search(config.dn_users, return_attributes, filter);
         }
@@ -119,16 +134,16 @@ export class Tests {
      * @param {string} value - Valeur de l'attribut (le plus souvent un identifiant) à tester à cette itération
      * @param {string} attribute - Attribut à tester
      * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
-     * @param {function} changeValue - Fonction qui prend uniquement en argument l'id courant et 
+     * @param {(string, int) => string} changeValue - Fonction qui prend uniquement en argument l'id courant et 
      * le nombre d'itérations et qui renvoit la prochaine valeur de l'attribut 
      * @param {int} n [0] - Nombre d'itérations (à initialiser à 0)
      * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
      * @static @async
      */
-    static async ensureUnique(value, attribute, dn, changeValue, n=0) {
+    static async ensureUnique(value: string, attribute: string, dn: string, changeValue: (string, int) => string, n=0) {
         // Recherche d'autres occurences de l'id
         try {
-            return LDAP.search(dn, config.key_id, "("+attribute+"="+value+")").then(matches => {
+            return LDAP.search(dn, config.key_id, "("+attribute+"="+value+")").then(function (matches: string[]) {
                 if (!matches) { throw ""; }
                 // On renvoit la valeur si elle est bien unique
                 else if (matches.length==0) { return value; }
@@ -150,13 +165,13 @@ export class Tests {
      * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
      * @static @async
      */
-    static async generateUid(givenName, lastName, promotion) {
+    static async generateUid(givenName: string, lastName: string, promotion: string) {
         try {
             // normalize et lowerCase standardisent le format
-            return this.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), config.key_id, config.dn_users, (id,n) => {
-                if (n==1) { id+='.'+promotion; }    // Si prénom.nom existe déjà, on rajoute la promo
-                else if (n==2) { id+='.'+n-1; }     // Puis si prénom.nom.promo existe déjà on passe à nom.prenom.promo .1
-                else if (n>2) { id+=n; }           // Ensuite on continue .123, .1234, etc...
+            return this.ensureUnique((givenName+'.'+lastName).toLowerCase().normalize('UFD'), config.key_id, config.dn_users, (id: string, n: number) => {
+                if (n==1) { id+='.'+promotion; }                // Si prénom.nom existe déjà, on rajoute la promo
+                else if (n==2) { id+='.'+(n-1).toString(); }    // Puis si prénom.nom.promo existe déjà on passe à nom.prenom.promo .1
+                else if (n>2) { id+=n; }                        // Ensuite on continue .123, .1234, etc...
                 return id;
             });
         }
@@ -172,12 +187,12 @@ export class Tests {
      * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
      * @static @async
      */
-    static async generateReadableId(name) {
+    static async generateReadableId(name: string) {
         try {
             // normalize et lowerCase standardisent le format
-            return this.ensureUnique(name.toLowerCase().normalize('UFD'), config.key_id, config.dn_groups, (id,n) => {
-                if (n==1) { id+='.'+n; }    // Si nom existe déjà, on essaie nom.1
-                else if (n>1) { id+=n; }   // Ensuite on continue .12, .123, etc...
+            return this.ensureUnique(name.toLowerCase().normalize('UFD'), config.key_id, config.dn_groups, (id: string, n: number) => {
+                if (n==1) { id+='.'+n.toString(); }   // Si nom existe déjà, on essaie nom.1
+                else if (n>1) { id+=n.toString(); }   // Ensuite on continue .12, .123, etc...
                 return id;
             });
         }
@@ -188,13 +203,12 @@ export class Tests {
 
     /**
      * @summary Cette fonction teste une valeur dummy (0) pour un identifiant numérique puis le fait évoluer aléatoirement (entre 1 et 100 000) jusqu'à ce qu'il soit unique.
-     * @param {Object} user - Utilisateur de la forme nécessaire à {@link LDAP.bind}.
      * @param {string} attribut - Intitulé exact de l'id concerné
      * @param {string} dn - *Domain Name* dans lequel l'attribut doit être unique
      * @return {Promise(string)} Valeur unique dans le domaine spécifié de l'attribut spécifié
      * @static @async
      */
-    static async generateId(attribut, dn) {
+    static async generateId(attribut: string, dn: string) {
         try {
             return this.ensureUnique("0", attribut, dn, (id,n) => { return Math.floor((Math.random() * 100000) + 1).toString(); });
         }
diff --git a/tsconfig.json b/tsconfig.json
index c4d630a..f0c7fcb 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -8,6 +8,7 @@
         "sourceMap": true,
         "outDir": "build",
         "resolveJsonModule": true,
+        "allowSyntheticDefaultImports": true
     },
     "include": [
         "src/**/*",
-- 
GitLab