diff --git a/package-lock.json b/package-lock.json
index 5ae0403acf6a7859d9ad83665015b983a737aa07..f0d14e50073f1417b524c846e1c761b8344562d5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -352,6 +352,21 @@
         "any-observable": "^0.3.0"
       }
     },
+    "@sindresorhus/is": {
+      "version": "0.14.0",
+      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+      "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+      "dev": true
+    },
+    "@szmarczak/http-timer": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+      "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+      "dev": true,
+      "requires": {
+        "defer-to-connect": "^1.0.1"
+      }
+    },
     "@types/babel-types": {
       "version": "7.0.7",
       "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz",
@@ -518,6 +533,49 @@
       "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
       "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
     },
+    "ansi-align": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+      "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+      "dev": true,
+      "requires": {
+        "string-width": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
     "ansi-escapes": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
@@ -587,17 +645,20 @@
     "arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "optional": true
     },
     "arr-flatten": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
-      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "optional": true
     },
     "arr-union": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
-      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "optional": true
     },
     "array-find-index": {
       "version": "1.0.2",
@@ -607,7 +668,8 @@
     "array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "optional": true
     },
     "asap": {
       "version": "2.0.6",
@@ -630,7 +692,8 @@
     "assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
-      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "optional": true
     },
     "async": {
       "version": "3.2.0",
@@ -657,7 +720,8 @@
     "atob": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
-      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "optional": true
     },
     "aws-sign2": {
       "version": "0.7.0",
@@ -710,6 +774,7 @@
       "version": "0.11.2",
       "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
       "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "optional": true,
       "requires": {
         "cache-base": "^1.0.1",
         "class-utils": "^0.3.5",
@@ -724,6 +789,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
           "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^1.0.0"
           }
@@ -732,6 +798,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
           "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -740,6 +807,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
           "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -748,6 +816,7 @@
           "version": "1.0.2",
           "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
           "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "optional": true,
           "requires": {
             "is-accessor-descriptor": "^1.0.0",
             "is-data-descriptor": "^1.0.0",
@@ -793,6 +862,117 @@
       "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
       "dev": true
     },
+    "boxen": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
+      "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
+      "dev": true,
+      "requires": {
+        "ansi-align": "^3.0.0",
+        "camelcase": "^5.3.1",
+        "chalk": "^3.0.0",
+        "cli-boxes": "^2.2.0",
+        "string-width": "^4.1.0",
+        "term-size": "^2.1.0",
+        "type-fest": "^0.8.1",
+        "widest-line": "^3.1.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -806,6 +986,7 @@
       "version": "2.3.2",
       "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
       "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "optional": true,
       "requires": {
         "arr-flatten": "^1.1.0",
         "array-unique": "^0.3.2",
@@ -823,6 +1004,7 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
           "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "optional": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
@@ -850,6 +1032,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
       "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "optional": true,
       "requires": {
         "collection-visit": "^1.0.0",
         "component-emitter": "^1.2.1",
@@ -862,6 +1045,38 @@
         "unset-value": "^1.0.0"
       }
     },
+    "cacheable-request": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+      "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+      "dev": true,
+      "requires": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^3.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^4.1.0",
+        "responselike": "^1.0.2"
+      },
+      "dependencies": {
+        "get-stream": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+          "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "lowercase-keys": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+          "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+          "dev": true
+        }
+      }
+    },
     "cachedir": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
@@ -950,6 +1165,7 @@
       "version": "0.3.6",
       "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
       "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "optional": true,
       "requires": {
         "arr-union": "^3.1.0",
         "define-property": "^0.2.5",
@@ -961,6 +1177,7 @@
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
           "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
@@ -982,6 +1199,12 @@
         }
       }
     },
+    "cli-boxes": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
+      "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+      "dev": true
+    },
     "cli-cursor": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
@@ -1055,6 +1278,15 @@
         "wrap-ansi": "^2.0.0"
       }
     },
+    "clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+      "dev": true,
+      "requires": {
+        "mimic-response": "^1.0.0"
+      }
+    },
     "code-point-at": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -1064,6 +1296,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
       "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "optional": true,
       "requires": {
         "map-visit": "^1.0.0",
         "object-visit": "^1.0.0"
@@ -1111,7 +1344,8 @@
     "component-emitter": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
-      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+      "optional": true
     },
     "compressible": {
       "version": "2.0.18",
@@ -1152,6 +1386,37 @@
         "typedarray": "^0.0.6"
       }
     },
+    "configstore": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
+      "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
+      "dev": true,
+      "requires": {
+        "dot-prop": "^5.2.0",
+        "graceful-fs": "^4.1.2",
+        "make-dir": "^3.0.0",
+        "unique-string": "^2.0.0",
+        "write-file-atomic": "^3.0.0",
+        "xdg-basedir": "^4.0.0"
+      },
+      "dependencies": {
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
     "connect": {
       "version": "3.6.6",
       "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
@@ -1200,7 +1465,8 @@
     "copy-descriptor": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
-      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "optional": true
     },
     "copyfiles": {
       "version": "2.2.0",
@@ -1343,6 +1609,12 @@
         "which": "^1.2.9"
       }
     },
+    "crypto-random-string": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+      "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+      "dev": true
+    },
     "currently-unhandled": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -1547,7 +1819,29 @@
     "decode-uri-component": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
-      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "optional": true
+    },
+    "decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "dev": true,
+      "requires": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "dev": true
+    },
+    "defer-to-connect": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+      "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+      "dev": true
     },
     "define-properties": {
       "version": "1.1.3",
@@ -1561,6 +1855,7 @@
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
       "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "optional": true,
       "requires": {
         "is-descriptor": "^1.0.2",
         "isobject": "^3.0.1"
@@ -1570,6 +1865,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
           "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -1578,6 +1874,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
           "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -1586,6 +1883,7 @@
           "version": "1.0.2",
           "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
           "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "optional": true,
           "requires": {
             "is-accessor-descriptor": "^1.0.0",
             "is-data-descriptor": "^1.0.0",
@@ -1619,6 +1917,21 @@
       "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
       "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
     },
+    "dot-prop": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+      "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+      "dev": true,
+      "requires": {
+        "is-obj": "^2.0.0"
+      }
+    },
+    "duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+      "dev": true
+    },
     "ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -1704,6 +2017,12 @@
         "is-symbol": "^1.0.2"
       }
     },
+    "escape-goat": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
+      "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==",
+      "dev": true
+    },
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -1779,6 +2098,7 @@
       "version": "2.1.4",
       "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
       "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "optional": true,
       "requires": {
         "debug": "^2.3.3",
         "define-property": "^0.2.5",
@@ -1793,6 +2113,7 @@
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
           "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
@@ -1801,6 +2122,7 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
           "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "optional": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
@@ -1816,6 +2138,7 @@
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
       "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "optional": true,
       "requires": {
         "assign-symbols": "^1.0.0",
         "is-extendable": "^1.0.1"
@@ -1825,6 +2148,7 @@
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
           "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "optional": true,
           "requires": {
             "is-plain-object": "^2.0.4"
           }
@@ -1835,6 +2159,7 @@
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
       "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "optional": true,
       "requires": {
         "array-unique": "^0.3.2",
         "define-property": "^1.0.0",
@@ -1850,6 +2175,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
           "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^1.0.0"
           }
@@ -1858,6 +2184,7 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
           "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "optional": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
@@ -1866,6 +2193,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
           "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -1874,6 +2202,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
           "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -1882,6 +2211,7 @@
           "version": "1.0.2",
           "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
           "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "optional": true,
           "requires": {
             "is-accessor-descriptor": "^1.0.0",
             "is-data-descriptor": "^1.0.0",
@@ -1963,6 +2293,7 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
       "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "optional": true,
       "requires": {
         "extend-shallow": "^2.0.1",
         "is-number": "^3.0.0",
@@ -1974,6 +2305,7 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
           "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "optional": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
@@ -2006,7 +2338,8 @@
     "for-in": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "optional": true
     },
     "forever-agent": {
       "version": "0.6.1",
@@ -2027,6 +2360,7 @@
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
       "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "optional": true,
       "requires": {
         "map-cache": "^0.2.2"
       }
@@ -2083,7 +2417,8 @@
         },
         "ansi-regex": {
           "version": "2.1.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -2120,7 +2455,8 @@
         },
         "code-point-at": {
           "version": "1.1.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
@@ -2129,7 +2465,8 @@
         },
         "console-control-strings": {
           "version": "1.1.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -2232,7 +2569,8 @@
         },
         "inherits": {
           "version": "2.0.4",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
@@ -2242,6 +2580,7 @@
         "is-fullwidth-code-point": {
           "version": "1.0.0",
           "bundled": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -2254,17 +2593,20 @@
         "minimatch": {
           "version": "3.0.4",
           "bundled": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
         },
         "minimist": {
           "version": "0.0.8",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.9.0",
           "bundled": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -2281,6 +2623,7 @@
         "mkdirp": {
           "version": "0.5.1",
           "bundled": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -2361,7 +2704,8 @@
         },
         "number-is-nan": {
           "version": "1.0.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -2371,6 +2715,7 @@
         "once": {
           "version": "1.4.0",
           "bundled": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -2446,7 +2791,8 @@
         },
         "safe-buffer": {
           "version": "5.1.2",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -2476,6 +2822,7 @@
         "string-width": {
           "version": "1.0.2",
           "bundled": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -2493,6 +2840,7 @@
         "strip-ansi": {
           "version": "3.0.1",
           "bundled": true,
+          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -2531,11 +2879,13 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "yallist": {
           "version": "3.1.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         }
       }
     },
@@ -2605,7 +2955,8 @@
     "get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
-      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "optional": true
     },
     "getos": {
       "version": "3.1.4",
@@ -2682,6 +3033,25 @@
         "minimatch": "~3.0.2"
       }
     },
+    "got": {
+      "version": "9.6.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+      "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+      "dev": true,
+      "requires": {
+        "@sindresorhus/is": "^0.14.0",
+        "@szmarczak/http-timer": "^1.1.2",
+        "cacheable-request": "^6.0.0",
+        "decompress-response": "^3.3.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^4.1.0",
+        "lowercase-keys": "^1.0.1",
+        "mimic-response": "^1.0.1",
+        "p-cancelable": "^1.0.0",
+        "to-readable-stream": "^1.0.0",
+        "url-parse-lax": "^3.0.0"
+      }
+    },
     "graceful-fs": {
       "version": "4.1.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
@@ -2736,6 +3106,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
       "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "optional": true,
       "requires": {
         "get-value": "^2.0.6",
         "has-values": "^1.0.0",
@@ -2746,6 +3117,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
       "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "optional": true,
       "requires": {
         "is-number": "^3.0.0",
         "kind-of": "^4.0.0"
@@ -2755,17 +3127,30 @@
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
           "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
         }
       }
     },
-    "hosted-git-info": {
+    "has-yarn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
+      "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
+      "dev": true
+    },
+    "hosted-git-info": {
       "version": "2.7.1",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
       "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w=="
     },
+    "http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+      "dev": true
+    },
     "http-errors": {
       "version": "1.6.3",
       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
@@ -2794,6 +3179,24 @@
         "sshpk": "^1.7.0"
       }
     },
+    "ignore-by-default": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+      "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
+      "dev": true
+    },
+    "import-lazy": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+      "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+      "dev": true
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
     "in-publish": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
@@ -2841,6 +3244,7 @@
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
       "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "optional": true,
       "requires": {
         "kind-of": "^3.0.2"
       },
@@ -2849,6 +3253,7 @@
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
           "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
@@ -2892,6 +3297,7 @@
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
       "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "optional": true,
       "requires": {
         "kind-of": "^3.0.2"
       },
@@ -2900,6 +3306,7 @@
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
           "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
@@ -2915,6 +3322,7 @@
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
       "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "optional": true,
       "requires": {
         "is-accessor-descriptor": "^0.1.6",
         "is-data-descriptor": "^0.1.4",
@@ -2924,7 +3332,8 @@
         "kind-of": {
           "version": "5.1.0",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
-          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "optional": true
         }
       }
     },
@@ -2947,7 +3356,8 @@
     "is-extendable": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
-      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "optional": true
     },
     "is-extglob": {
       "version": "2.1.1",
@@ -2971,7 +3381,6 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
       "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
-      "optional": true,
       "requires": {
         "is-extglob": "^2.1.1"
       }
@@ -2986,10 +3395,17 @@
         "is-path-inside": "^1.0.0"
       }
     },
+    "is-npm": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
+      "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
+      "dev": true
+    },
     "is-number": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
       "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "optional": true,
       "requires": {
         "kind-of": "^3.0.2"
       },
@@ -2998,12 +3414,19 @@
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
           "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
         }
       }
     },
+    "is-obj": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+      "dev": true
+    },
     "is-observable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
@@ -3026,6 +3449,7 @@
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
       "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "optional": true,
       "requires": {
         "isobject": "^3.0.1"
       }
@@ -3070,7 +3494,14 @@
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
-      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "optional": true
+    },
+    "is-yarn-global": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
+      "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
+      "dev": true
     },
     "isarray": {
       "version": "1.0.0",
@@ -3085,7 +3516,8 @@
     "isobject": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "optional": true
     },
     "isstream": {
       "version": "0.1.2",
@@ -3117,6 +3549,12 @@
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
       "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
     },
+    "json-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+      "dev": true
+    },
     "json-parse-better-errors": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -3181,10 +3619,29 @@
         "promise": "^7.0.1"
       }
     },
+    "keyv": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+      "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+      "dev": true,
+      "requires": {
+        "json-buffer": "3.0.0"
+      }
+    },
     "kind-of": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
-      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "optional": true
+    },
+    "latest-version": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+      "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+      "dev": true,
+      "requires": {
+        "package-json": "^6.3.0"
+      }
     },
     "lazy-ass": {
       "version": "1.6.0",
@@ -3481,6 +3938,12 @@
         "signal-exit": "^3.0.0"
       }
     },
+    "lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+      "dev": true
+    },
     "lru-cache": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@@ -3514,7 +3977,8 @@
     "map-cache": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
-      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "optional": true
     },
     "map-obj": {
       "version": "1.0.1",
@@ -3525,6 +3989,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
       "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "optional": true,
       "requires": {
         "object-visit": "^1.0.0"
       }
@@ -3568,6 +4033,7 @@
       "version": "3.1.10",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
       "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "optional": true,
       "requires": {
         "arr-diff": "^4.0.0",
         "array-unique": "^0.3.2",
@@ -3608,6 +4074,12 @@
       "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
       "dev": true
     },
+    "mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+      "dev": true
+    },
     "minimatch": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -3625,6 +4097,7 @@
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
       "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+      "optional": true,
       "requires": {
         "for-in": "^1.0.2",
         "is-extendable": "^1.0.1"
@@ -3634,6 +4107,7 @@
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
           "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "optional": true,
           "requires": {
             "is-plain-object": "^2.0.4"
           }
@@ -3668,6 +4142,7 @@
       "version": "1.2.13",
       "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
       "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "optional": true,
       "requires": {
         "arr-diff": "^4.0.0",
         "array-unique": "^0.3.2",
@@ -3766,6 +4241,146 @@
         }
       }
     },
+    "nodemon": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz",
+      "integrity": "sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^3.2.2",
+        "debug": "^3.2.6",
+        "ignore-by-default": "^1.0.1",
+        "minimatch": "^3.0.4",
+        "pstree.remy": "^1.1.7",
+        "semver": "^5.7.1",
+        "supports-color": "^5.5.0",
+        "touch": "^3.1.0",
+        "undefsafe": "^2.0.3",
+        "update-notifier": "^4.1.0"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+          "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+          "dev": true,
+          "requires": {
+            "normalize-path": "^3.0.0",
+            "picomatch": "^2.0.4"
+          }
+        },
+        "binary-extensions": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
+          "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
+          "dev": true
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chokidar": {
+          "version": "3.4.3",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
+          "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
+          "dev": true,
+          "requires": {
+            "anymatch": "~3.1.1",
+            "braces": "~3.0.2",
+            "fsevents": "~2.1.2",
+            "glob-parent": "~5.1.0",
+            "is-binary-path": "~2.1.0",
+            "is-glob": "~4.0.1",
+            "normalize-path": "~3.0.0",
+            "readdirp": "~3.5.0"
+          }
+        },
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "fsevents": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+          "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+          "dev": true,
+          "optional": true
+        },
+        "glob-parent": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+          "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        },
+        "is-binary-path": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+          "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+          "dev": true,
+          "requires": {
+            "binary-extensions": "^2.0.0"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "readdirp": {
+          "version": "3.5.0",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+          "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+          "dev": true,
+          "requires": {
+            "picomatch": "^2.2.1"
+          }
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
     "noms": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz",
@@ -3830,8 +4445,13 @@
     "normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "optional": true
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+    },
+    "normalize-url": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+      "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+      "dev": true
     },
     "normalize.css": {
       "version": "8.0.1",
@@ -3925,6 +4545,16 @@
         "path-key": "^2.0.0"
       }
     },
+    "npm-watch": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/npm-watch/-/npm-watch-0.7.0.tgz",
+      "integrity": "sha512-AN2scNyMljMGkn0mIkaRRk19I7Vx0qTK6GmsIcDblX5YRbSsoJORTAtrceICSx7Om9q48NWcwm/R0t6E7F4Ocg==",
+      "dev": true,
+      "requires": {
+        "nodemon": "^2.0.3",
+        "through2": "^2.0.0"
+      }
+    },
     "npmlog": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
@@ -3955,6 +4585,7 @@
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
       "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "optional": true,
       "requires": {
         "copy-descriptor": "^0.1.0",
         "define-property": "^0.2.5",
@@ -3965,6 +4596,7 @@
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
           "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
@@ -3973,6 +4605,7 @@
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
           "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
@@ -3993,6 +4626,7 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
       "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "optional": true,
       "requires": {
         "isobject": "^3.0.0"
       }
@@ -4012,6 +4646,7 @@
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
       "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "optional": true,
       "requires": {
         "isobject": "^3.0.1"
       }
@@ -4076,6 +4711,12 @@
       "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=",
       "dev": true
     },
+    "p-cancelable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+      "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+      "dev": true
+    },
     "p-finally": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
@@ -4109,6 +4750,26 @@
       "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
       "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
     },
+    "package-json": {
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
+      "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
+      "dev": true,
+      "requires": {
+        "got": "^9.6.0",
+        "registry-auth-token": "^4.0.0",
+        "registry-url": "^5.0.0",
+        "semver": "^6.2.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
     "parse-json": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
@@ -4125,7 +4786,8 @@
     "pascalcase": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
-      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "optional": true
     },
     "path-dirname": {
       "version": "1.0.2",
@@ -4183,6 +4845,12 @@
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
     },
+    "picomatch": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+      "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+      "dev": true
+    },
     "pidtree": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz",
@@ -4209,7 +4877,14 @@
     "posix-character-classes": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
-      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "optional": true
+    },
+    "prepend-http": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+      "dev": true
     },
     "pretty-bytes": {
       "version": "5.3.0",
@@ -4240,6 +4915,12 @@
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
       "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
     },
+    "pstree.remy": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+      "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+      "dev": true
+    },
     "pug": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
@@ -4404,6 +5085,15 @@
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
       "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
     },
+    "pupa": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz",
+      "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==",
+      "dev": true,
+      "requires": {
+        "escape-goat": "^2.0.0"
+      }
+    },
     "pushstate-server": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/pushstate-server/-/pushstate-server-3.1.0.tgz",
@@ -4445,6 +5135,26 @@
       "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
       "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
     },
+    "rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+      "dev": true,
+      "requires": {
+        "deep-extend": "^0.6.0",
+        "ini": "~1.3.0",
+        "minimist": "^1.2.0",
+        "strip-json-comments": "~2.0.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.5",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+          "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+          "dev": true
+        }
+      }
+    },
     "read-pkg": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
@@ -4507,11 +5217,30 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
       "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "optional": true,
       "requires": {
         "extend-shallow": "^3.0.2",
         "safe-regex": "^1.1.0"
       }
     },
+    "registry-auth-token": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.0.tgz",
+      "integrity": "sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w==",
+      "dev": true,
+      "requires": {
+        "rc": "^1.2.8"
+      }
+    },
+    "registry-url": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
+      "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+      "dev": true,
+      "requires": {
+        "rc": "^1.2.8"
+      }
+    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -4521,7 +5250,8 @@
     "repeat-element": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
-      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "optional": true
     },
     "repeat-string": {
       "version": "1.6.1",
@@ -4593,7 +5323,17 @@
     "resolve-url": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
-      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "optional": true
+    },
+    "responselike": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+      "dev": true,
+      "requires": {
+        "lowercase-keys": "^1.0.0"
+      }
     },
     "restore-cursor": {
       "version": "1.0.1",
@@ -4608,7 +5348,8 @@
     "ret": {
       "version": "0.1.15",
       "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
-      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "optional": true
     },
     "right-align": {
       "version": "0.1.3",
@@ -4644,6 +5385,7 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
       "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "optional": true,
       "requires": {
         "ret": "~0.1.10"
       }
@@ -4688,6 +5430,23 @@
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
       "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw=="
     },
+    "semver-diff": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
+      "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
+      "dev": true,
+      "requires": {
+        "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
     "send": {
       "version": "0.16.2",
       "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
@@ -4740,6 +5499,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
       "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+      "optional": true,
       "requires": {
         "extend-shallow": "^2.0.1",
         "is-extendable": "^0.1.1",
@@ -4751,6 +5511,7 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
           "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "optional": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
@@ -4800,6 +5561,7 @@
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
       "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "optional": true,
       "requires": {
         "base": "^0.11.1",
         "debug": "^2.2.0",
@@ -4815,6 +5577,7 @@
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
           "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
@@ -4823,6 +5586,7 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
           "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "optional": true,
           "requires": {
             "is-extendable": "^0.1.0"
           }
@@ -4833,6 +5597,7 @@
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
       "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "optional": true,
       "requires": {
         "define-property": "^1.0.0",
         "isobject": "^3.0.0",
@@ -4843,6 +5608,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
           "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^1.0.0"
           }
@@ -4851,6 +5617,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
           "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -4859,6 +5626,7 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
           "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "optional": true,
           "requires": {
             "kind-of": "^6.0.0"
           }
@@ -4867,6 +5635,7 @@
           "version": "1.0.2",
           "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
           "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "optional": true,
           "requires": {
             "is-accessor-descriptor": "^1.0.0",
             "is-data-descriptor": "^1.0.0",
@@ -4879,6 +5648,7 @@
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
       "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "optional": true,
       "requires": {
         "kind-of": "^3.2.0"
       },
@@ -4887,6 +5657,7 @@
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
           "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
@@ -4902,6 +5673,7 @@
       "version": "0.5.2",
       "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
       "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "optional": true,
       "requires": {
         "atob": "^2.1.1",
         "decode-uri-component": "^0.2.0",
@@ -4913,7 +5685,8 @@
     "source-map-url": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
-      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "optional": true
     },
     "spdx-correct": {
       "version": "3.1.0",
@@ -4947,6 +5720,7 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
       "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "optional": true,
       "requires": {
         "extend-shallow": "^3.0.0"
       }
@@ -4971,6 +5745,7 @@
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
       "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "optional": true,
       "requires": {
         "define-property": "^0.2.5",
         "object-copy": "^0.1.0"
@@ -4980,6 +5755,7 @@
           "version": "0.2.5",
           "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
           "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "optional": true,
           "requires": {
             "is-descriptor": "^0.1.0"
           }
@@ -5074,6 +5850,12 @@
         "get-stdin": "^4.0.1"
       }
     },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
     "supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -5098,6 +5880,12 @@
         "inherits": "2"
       }
     },
+    "term-size": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz",
+      "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==",
+      "dev": true
+    },
     "throttleit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
@@ -5131,6 +5919,7 @@
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
       "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "optional": true,
       "requires": {
         "kind-of": "^3.0.2"
       },
@@ -5139,16 +5928,24 @@
           "version": "3.2.2",
           "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
           "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "optional": true,
           "requires": {
             "is-buffer": "^1.1.5"
           }
         }
       }
     },
+    "to-readable-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+      "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+      "dev": true
+    },
     "to-regex": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
       "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "optional": true,
       "requires": {
         "define-property": "^2.0.2",
         "extend-shallow": "^3.0.2",
@@ -5160,6 +5957,7 @@
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
       "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "optional": true,
       "requires": {
         "is-number": "^3.0.0",
         "repeat-string": "^1.6.1"
@@ -5170,6 +5968,26 @@
       "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
       "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
     },
+    "touch": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+      "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+      "dev": true,
+      "requires": {
+        "nopt": "~1.0.10"
+      },
+      "dependencies": {
+        "nopt": {
+          "version": "1.0.10",
+          "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+          "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+          "dev": true,
+          "requires": {
+            "abbrev": "1"
+          }
+        }
+      }
+    },
     "tough-cookie": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@@ -5211,12 +6029,27 @@
       "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
       "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
     },
+    "type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true
+    },
     "typedarray": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
       "dev": true
     },
+    "typedarray-to-buffer": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+      "dev": true,
+      "requires": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
     "uglify-js": {
       "version": "2.8.29",
       "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
@@ -5261,10 +6094,20 @@
       "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
       "optional": true
     },
+    "undefsafe": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
+      "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==",
+      "dev": true,
+      "requires": {
+        "debug": "^2.2.0"
+      }
+    },
     "union-value": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
       "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+      "optional": true,
       "requires": {
         "arr-union": "^3.1.0",
         "get-value": "^2.0.6",
@@ -5272,6 +6115,15 @@
         "set-value": "^2.0.1"
       }
     },
+    "unique-string": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+      "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+      "dev": true,
+      "requires": {
+        "crypto-random-string": "^2.0.0"
+      }
+    },
     "universalify": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
@@ -5287,6 +6139,7 @@
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
       "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "optional": true,
       "requires": {
         "has-value": "^0.3.1",
         "isobject": "^3.0.0"
@@ -5296,6 +6149,7 @@
           "version": "0.3.1",
           "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
           "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "optional": true,
           "requires": {
             "get-value": "^2.0.3",
             "has-values": "^0.1.4",
@@ -5306,6 +6160,7 @@
               "version": "2.1.0",
               "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
               "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "optional": true,
               "requires": {
                 "isarray": "1.0.0"
               }
@@ -5315,7 +6170,8 @@
         "has-values": {
           "version": "0.1.4",
           "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
-          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "optional": true
         }
       }
     },
@@ -5331,6 +6187,103 @@
       "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
       "optional": true
     },
+    "update-notifier": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz",
+      "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==",
+      "dev": true,
+      "requires": {
+        "boxen": "^4.2.0",
+        "chalk": "^3.0.0",
+        "configstore": "^5.0.1",
+        "has-yarn": "^2.1.0",
+        "import-lazy": "^2.1.0",
+        "is-ci": "^2.0.0",
+        "is-installed-globally": "^0.3.1",
+        "is-npm": "^4.0.0",
+        "is-yarn-global": "^0.3.0",
+        "latest-version": "^5.0.0",
+        "pupa": "^2.0.1",
+        "semver-diff": "^3.1.1",
+        "xdg-basedir": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+          "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "global-dirs": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
+          "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
+          "dev": true,
+          "requires": {
+            "ini": "^1.3.5"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "is-installed-globally": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
+          "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
+          "dev": true,
+          "requires": {
+            "global-dirs": "^2.0.1",
+            "is-path-inside": "^3.0.1"
+          }
+        },
+        "is-path-inside": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+          "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
     "uri-js": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -5342,7 +6295,8 @@
     "urix": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
-      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "optional": true
     },
     "url": {
       "version": "0.11.0",
@@ -5362,10 +6316,20 @@
         }
       }
     },
+    "url-parse-lax": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+      "dev": true,
+      "requires": {
+        "prepend-http": "^2.0.0"
+      }
+    },
     "use": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
-      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "optional": true
     },
     "util-deprecate": {
       "version": "1.0.2",
@@ -5432,6 +6396,55 @@
         "string-width": "^1.0.2 || 2"
       }
     },
+    "widest-line": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+      "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+      "dev": true,
+      "requires": {
+        "string-width": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        }
+      }
+    },
     "window-size": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
@@ -5465,6 +6478,24 @@
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
     },
+    "write-file-atomic": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+      "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4",
+        "is-typedarray": "^1.0.0",
+        "signal-exit": "^3.0.2",
+        "typedarray-to-buffer": "^3.1.5"
+      }
+    },
+    "xdg-basedir": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
+      "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
+      "dev": true
+    },
     "xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
diff --git a/package.json b/package.json
index 239bde9731f0a5e17453a4408453950159dc4466..9aa2ab1169dc700cab230de92defac01269ea358 100644
--- a/package.json
+++ b/package.json
@@ -13,20 +13,34 @@
     "build:jscomponents": "babel \"src/components/*.js\" --out-dir dist/components/",
     "build:pug": "pug src/index.pug -o dist/ --obj config.json",
     "build:manifest": "node --experimental-modules make-webmanifest.mjs",
+    "build:i18n": "copyfiles -u 2 src/locales/*.json dist/locales",
     "copy:font": "copyfiles -f src/fonts/* dist/fonts",
     "copy:image": "copyfiles -f src/images/* dist/images",
     "copy:sw": "copyfiles -f src/sw.js dist",
     "serve": "pushstate-server -d ./dist -p 3000",
-    "watch": "run-p copy:* build:manifest watch:* serve",
-    "watch:css": "npm run build:css && npm run build:css -- -w",
-    "watch:js": "babel --watch \"src/scripts/*.js\" -o dist/scripts/index.js",
-    "watch:jscomponents": "babel --watch \"src/components/*.js\" --out-dir dist/components/",
+    "watch": "run-p build watch:* serve",
+    "watch:css": "npm-watch build:css",
+    "watch:js": "npm-watch build:js",
+    "watch:jscomponents": "npm-watch build:jscomponents",
+    "watch:manifest": "npm-watch build:manifest",
     "watch:pug": "pug --watch src/index.pug -o dist/ --obj config.json",
+    "watch:i18n": "npm-watch build:i18n",
+    "watch:font": "npm-watch copy:font",
+    "watch:image": "npm-watch copy:image",
     "cypress:open": "cypress open",
     "cypress:verify": "cypress verify",
     "cypress:info": "cypress info",
     "test": "cypress run"
   },
+  "watch": {
+    "build:css": "src/styles/*",
+    "build:manifest": "make-webmanifest.mjs",
+    "build:i18n": "src/locales/*",
+    "copy:images": "src/fonts/*.js",
+    "copy:fonts": "src/images/*.js",
+    "build:js": "src/scripts/*.js",
+    "build:jscomponents": "src/components/*.js"
+  },
   "release": {
     "branches": [
       "master"
@@ -71,6 +85,7 @@
   "devDependencies": {
     "cypress": "^4.5.0",
     "cypress-localstorage-commands": "^1.2.1",
-    "cypress-terminal-report": "^1.2.1"
+    "cypress-terminal-report": "^1.2.1",
+    "npm-watch": "^0.7.0"
   }
 }
diff --git a/src/components/hubl-status.js b/src/components/hubl-status.js
index 15b4b1fab6804fd967a20adfb3fb2dd971bf3429..76372c0dc3a6b6a1a3ca604454457b0d25b50e40 100644
--- a/src/components/hubl-status.js
+++ b/src/components/hubl-status.js
@@ -11,10 +11,10 @@ const HublStatus = widgetFactory(
       name="\${name}">
       <option
         value="Public"
-        \${value=="Public" ? 'selected' : ''}>Public</option>
+        \${value=="Public" ? 'selected' : ''} data-trans="hublStatus.public">Public</option>
       <option
         value="Private"
-        \${value=="Private" ? 'selected' : ''}>Privé</option>
+        \${value=="Private" ? 'selected' : ''} data-trans="hublStatus.private">Privé</option>
     </select>
   </label>`,
   '',
diff --git a/src/components/sentry.js b/src/components/sentry.js
index f406310507a76ccdc04f4073a82ba40586e24532..e4349e4d2a57c157ca50e096664746d6181a966e 100644
--- a/src/components/sentry.js
+++ b/src/components/sentry.js
@@ -3,6 +3,6 @@ if(typeof Sentry !== 'undefined') {
         dsn: 'https://b4b29557689049a39168599577adb940@sentry.startinblox.com/4',
         integrations: [new Sentry.Integrations.BrowserTracing()],
         environment: document.location.hostname,
-        tracesSampleRate: 1.0,
+        tracesSampleRate: 0.2,
     });
 }
\ No newline at end of file
diff --git a/src/dependencies.pug b/src/dependencies.pug
index aaadd9275b4733d38f8abd09989dc587c44f8ef0..afd34107d02161cb52b30c4e37b6a24648cfa944 100644
--- a/src/dependencies.pug
+++ b/src/dependencies.pug
@@ -10,7 +10,7 @@ script(type="module" src="https://unpkg.com/@startinblox/core@0.12" defer)
 script(type="module" src="https://unpkg.com/@startinblox/oidc@0.10" defer)
 //- script(type="module" src="/lib/sib-auth/index.js" defer)
 
-script(type="module" src="https://unpkg.com/@startinblox/router@0.9" defer)
+script(type="module" src="https://unpkg.com/@startinblox/router@0.10" defer)
 //- script(type="module" src="/lib/sib-router/src/index.js" defer)
 
 script(type="module" src="https://unpkg.com/@startinblox/component-notifications@0.7" defer)
@@ -25,11 +25,11 @@ if (endpoints.resources || (endpoints.get && endpoints.get.resources)) && (endpo
     //- script(type="module" src="/lib/sib-resource/sib-resource.js" defer)
 
 if endpoints.joboffers || (endpoints.get && endpoints.get.joboffers)
-    script(type="module" src="https://unpkg.com/@startinblox/component-job-board@0.8" defer)
+    script(type="module" src="https://unpkg.com/@startinblox/component-job-board@1.0" defer)
     //- script(type="module" src="/lib/solid-job-board/dist/index.js" defer)
 
 if (endpoints.uploads || (endpoints.get && endpoints.get.uploads)) && (endpoints.skills || (endpoints.get && endpoints.get.skills)) && (endpoints.users || (endpoints.get && endpoints.get.users))
-    script(type="module" src="https://unpkg.com/@startinblox/component-directory@0.10" defer)
+    script(type="module" src="https://unpkg.com/@startinblox/component-directory@1.0" defer)
     //- script(type="module" src="/lib/solid-directory/dist/index.js" defer)
 
 if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
@@ -37,7 +37,7 @@ if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
     //- script(type="module" src="/lib/solid-dashboard/dist/index.js" defer)
 
 if endpoints.users || (endpoints.get && endpoints.get.users)
-    script(type="module" src="https://unpkg.com/@startinblox/component-chat@1.1" defer)
+    script(type="module" src="https://unpkg.com/@startinblox/component-chat@1.2" defer)
     //- script(type="module" src="/lib/solid-xmpp-chat/dist/index.js" defer)
 
 if endpoints.polls || (endpoints.get && endpoints.get.polls)
diff --git a/src/header.pug b/src/header.pug
index 552f26f3c9c0ed832ec7b56d5152e19c9aa62763..49b663df8e90837503f8dbf900edf4fecf770d3a 100644
--- a/src/header.pug
+++ b/src/header.pug
@@ -3,7 +3,7 @@
     solid-link(next='dashboard')
       img(src=`${clientLogo || '/images/logo.png'}` style=`max-height:${clientLogoHeight || '32px'}`)
 
-  span.beta-tag Beta
+  span.beta-tag(data-trans='header.beta')
 
 solid-notifications.notLoggedIn(
   nested-field="inbox"
@@ -30,14 +30,14 @@ details#user-controls.notLoggedIn
       ul
         if (endpoints.uploads || (endpoints.get && endpoints.get.uploads)) && (endpoints.skills || (endpoints.get && endpoints.get.skills)) && (endpoints.users || (endpoints.get && endpoints.get.users))
           li
-            solid-link(next='profile') Mon profil
+            solid-link(next='profile' data-trans='header.myProfile')
         li
-          solid-link(next='admin') Administration
+          solid-link(next='admin' data-trans='header.admin')
         li
-          solid-link(next='about') A propos
-      button(role='log out' onclick="document.querySelector('sib-auth').logout();") Se déconnecter
+          solid-link(next='about' data-trans='header.about')
+      button(role='log out' onclick="document.querySelector('sib-auth').logout();" data-trans='header.logOut')
 
-button.loggedIn(role='log in' onclick="document.querySelector('sib-auth').login();") Se connecter
+button.loggedIn(role='log in' onclick="document.querySelector('sib-auth').login();" data-trans='header.logIn')
 
 button.notLoggedIn.mobile-menu-icon.icon-menu#toggleMainMenu
 
diff --git a/src/index.pug b/src/index.pug
index f9cda2d6dac77d786d20fb378182bf3690a65934..1a5d095e7bfc2b68e38953861bbd4c90dc1e9868 100644
--- a/src/index.pug
+++ b/src/index.pug
@@ -27,15 +27,15 @@ html(lang="en")
       main#viewport.content.notLoggedIn
 
         if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
-          #dashboard(hidden).no-sidebar.with-padding
+          #dashboard(hidden, data-view="dashboard").no-sidebar.with-padding
             include page-dashboard.pug
 
         if publicDirectory && (endpoints.users || (endpoints.get && endpoints.get.users))
-          #members(hidden).no-sidebar.with-padding
+          #members(hidden, data-view="members").no-sidebar.with-padding
             include page-directory.pug
 
         if endpoints.joboffers || (endpoints.get && endpoints.get.joboffers)
-          #job-offers(hidden).no-sidebar.with-padding
+          #job-offers(hidden, data-view="job-offers").no-sidebar.with-padding
             if (endpoints.post && endpoints.post.joboffers) && (endpoints.get && endpoints.get.joboffers)
               hubl-reactivity(data-src=`${endpoints.post.joboffers}current/` target-src=`${endpoints.get.joboffers}`)
               hubl-reactivity(data-src=`${endpoints.post.joboffers}expired/` target-src=`${endpoints.get.joboffers}`)
@@ -49,7 +49,7 @@ html(lang="en")
             include page-job-offers.pug
 
         if endpoints.projects || (endpoints.get && endpoints.get.projects)
-          #project(hidden).with-sidebar
+          #project(hidden, data-view="project").with-sidebar
             if (endpoints.post && endpoints.post.projects) && (endpoints.get && endpoints.get.projects)
               hubl-reactivity(data-src=`${endpoints.post.projects}joinable/` target-src=`${endpoints.get.projects}`)
               hubl-reactivity(data-src=`${endpoints.post.projects}` target-src=`${endpoints.get.projects}`)
@@ -61,7 +61,7 @@ html(lang="en")
             include page-project.pug
 
         if endpoints.circles || (endpoints.get && endpoints.get.circles)
-          #circle(hidden).with-sidebar
+          #circle(hidden, data-view="circle").with-sidebar
             if (endpoints.post && endpoints.post.circles) && (endpoints.get && endpoints.get.circles)
               hubl-reactivity(data-src=`${endpoints.post.circles}joinable/` target-src=`${endpoints.get.circles}`)
               hubl-reactivity(data-src=`${endpoints.post.circles}` target-src=`${endpoints.get.circles}`)
@@ -72,29 +72,29 @@ html(lang="en")
             hubl-reactivity(bind-user nested-field="circles" target-src=`${endpoints.circles || endpoints.get.circles}joinable/`)
             include page-circle.pug
         if endpoints.users || (endpoints.get && endpoints.get.users)
-          #messages(hidden).with-sidebar
+          #messages(hidden, data-view="messages").with-sidebar
             include page-messages.pug
 						
         if endpoints.polls || (endpoints.get && endpoints.get.polls)
-          #polls(hidden).with-sidebar
+          #polls(hidden, data-view="polls").with-sidebar
             include page-polls.pug
 
         if endpoints.events || (endpoints.get && endpoints.get.events)
-          #events(hidden)
+          #events(hidden, data-view="events")
             include page-events.pug
 
         if endpoints.resources || (endpoints.get && endpoints.get.resources)
-          #resources(hidden)
+          #resources(hidden, data-view="resources")
             include page-resources.pug
 
-        #admin(hidden).with-sidebar
+        #admin(hidden, data-view="admin").with-sidebar
           include page-admin.pug
 
-        #about.no-sidebar.with-padding
+        #about(data-view="about").no-sidebar.with-padding
           include page-about.pug
           
         if (endpoints.skills || (endpoints.get && endpoints.get.skills)) && (endpoints.uploads || (endpoints.post && endpoints.post.uploads)) && (endpoints.users || (endpoints.post && endpoints.post.users))
-          #profile(hidden).no-sidebar
+          #profile(hidden, data-view="profile").no-sidebar
             include page-profile.pug
     
     if analytics
diff --git a/src/locales/fr.json b/src/locales/fr.json
new file mode 100644
index 0000000000000000000000000000000000000000..cad2808c7e90d788094d258ffe411bac1a1a1459
--- /dev/null
+++ b/src/locales/fr.json
@@ -0,0 +1,208 @@
+{
+  "header": {
+    "beta": "Beta",
+    "myProfile": "Mon profil",
+    "admin": "Administration",
+    "about": "A propos",
+    "logOut": "Se déconnecter",
+    "logIn": "Se connecter"
+    },
+  "menuLeft": {
+    "emptyCircleProject": {
+      "notPartOf": "Tu ne fais partie d'aucun",
+      "createNew": "Pour en créer un nouveau, tu peux te rendre dans le",
+      "adminPanel": "panneau d'administration",
+      "project": "projet",
+      "circle": "cercle"
+    },
+    "dashboard": "Tableau de bord",
+    "events": "Evènements",
+    "gov": "Gouvernance",
+    "resources": "Ressources",
+    "jobBoard": "Offres de mission",
+    "profileDirectory": "Annuaire des membres",
+    "projects": "Projets",
+    "circles": "Circles",
+    "messages": "Messages",
+    "search": "Rechercher..."
+  },
+  "about": {
+    "title": "A propos",
+    "card1": {
+      "subTitle": "Cette application est développée par Startin'blox",
+      "paragraph1": "Startin’blox est une coopérative qui développe des outils libres pour construire facilement et à moindre coût des applications fédérées et interopérables basées sur les derniers standards du web poussés par le projet SOLID.",
+      "paragraph2": "Sa mission est de redonner le pouvoir aux utilisateurs en leur permettant de reprendre la main sur leur outil numérique et de bénéficier d’un effet de réseau au sein d’un écosystème choisi afin de s’émanciper des grandes plateformes."
+    },
+    "card2": {
+      "title": "Contacte-nous",
+      "paragraph-1": "Tu veux contribuer, nous remonter un bug, nous suggérer une amélioration, travailler avec nous ?",
+      "link": "Contact"
+    }
+  },
+  "admin": {
+    "menuRight": {
+      "fold": "Replier le menu",
+      "community": "Communautés",
+      "circles": "Cercles",
+      "projects": "Projets"
+    }
+  },
+  "dashboard": {
+    "title": "Tableau de bord"
+  },
+  "circle": {
+    "menuRight": {
+      "buttonMobile": "MENU",
+      "fold": "Replier le menu",
+      "chat": "Chat",
+      "information": "Information",
+      "resources": "Resources",
+      "events": "Events",
+      "polls": "Polls"
+    },
+    "create": {
+      "backlink": "Retour",
+      "title": "Créer un cercle",
+      "labelStatus": "Statut du cercle",
+      "labelName": "Nom du cercle *",
+      "labelDescription": "Sous-titre du cercle *",
+      "buttonSubmit": "Enregistrer"
+    },
+    "edit": {
+      "buttonDelete": "Retirer",
+      "backlink": "Retour",
+      "title": "Modifie ton cercle",
+      "labelStatus": "Statut du cercle",
+      "labelName": "Nom du cercle *",
+      "labelOwner": "Administrateur ou administratrice *",
+      "labelDescription": "Sous-titre du cercle *",
+      "subTitle": "Liste des membres :",
+      "tableHeader1": "Nom",
+      "tableHeader2": "Accès",
+      "buttonSubmit": "Enregistrer",
+      "buttonAddMember": "Ajouter un membre"
+    },
+    "list": {
+      "title": "Administration",
+      "buttonMobile": "MENU",
+      "subTitle": "Cercles",
+      "buttonCreate": "Créer un cercle",
+      "tableHeader1": "Nom",
+      "tableHeader2": "Administrateurs",
+      "tableHeader3": "Rejoindre",
+      "buttonQuit": "Quitter",
+      "buttonJoin": "Rejoindre"
+    },
+    "left": {
+      "paragraphQuit": "Tu as quitté ce cercle.",
+      "paragraphJoin": "Pour le rejoindre à nouveau, rends-toi dans le panneau",
+      "paragraphContact": "ou contacte un administrateur.",
+      "admin": "d'administration"
+    },
+    "profile": {
+      "creationDate": "Date de création : ",
+      "buttonModify": "Modifier et ajouter un membre",
+      "buttonAdd": "Ajouter un membre",
+      "buttonDelete": "Supprimer le cercle",
+      "buttonQuit": "Quitter le cercle",
+      "buttonJoin": "Rejoindre le cercle",
+      "subTitle": "Membres :"
+    }
+  },
+  "communities": {
+    "title": "Administration",
+    "menuMobile": "MENU",
+    "linkInvite": "Inviter un nouvel utilisateur",
+    "noPermission": "Membre, aucune permission",
+    "subTitle": "Communautés",
+    "tableHeader1": "Nom",
+    "tableHeader2": "Action"
+  },
+  "project": {
+    "menuRight": {
+      "buttonMobile": "MENU",
+      "fold": "Replier le menu",
+      "chat": "Chat",
+      "information": "Information"
+    },
+    "create": {
+      "backlink": "Retour",
+      "title": "Créer un nouveau projet",
+      "labelName": "Nom du projet *",
+      "labelCustomer": "Nom du client*",
+      "labelCaptain": "Capitaine du projet*",
+      "buttonSubmit": "Enregistrer"
+    },
+    "edit": {
+      "buttonDelete": "Retirer",
+      "backlink": "Retour",
+      "title": "Modifie ton projet",
+      "labelName": "Nom du projet *",
+      "labelCustomer": "Nom du client *",
+      "subTitle": "Liste des membres :",
+      "tableHeader1": "Nom",
+      "tableHeader2": "Accès",
+      "buttonSubmit": "Enregistrer",
+      "buttonAddMember": "Ajouter un membre"
+    },
+    "modifyPicture": {
+      "backlink": "Retour",
+      "title": "Modifier l'image du projet"
+    },
+    "list": {
+      "title": "Administration",
+      "buttonMobile": "MENU",
+      "subTitle": "Projets",
+      "buttonCreate": "Créer un nouveau projet",
+      "tableHeader1": "Nom",
+      "tableHeader2": "Administrateurs",
+      "tableHeader3": "Capitaines",
+      "tableHeader4": "Rejoindre",
+      "buttonQuit": "Quitter",
+      "buttonJoin":"Rejoindre"
+    },
+    "left": {
+      "paragraphQuit": "Tu as quitté ce projet.",
+      "paragraphJoin": "Ceci est un projet privé. Pour le joindre à nouveau, rends-toi dans le panneau",
+      "paragraphContact": "et demande une invitation.",
+      "admin": "d'administration"
+    },
+    "profile": {
+      "creationDate": "Date de création : ",
+      "buttonModify": "Modifier et ajouter un membre",
+      "buttonAdd": "Ajouter un membre",
+      "buttonDelete": "Supprimer le projet",
+      "buttonQuit": "Quitter le projet",
+      "buttonJoin": "Rejoindre le projet",
+      "captain": "Capitaine :",
+      "subTitle": "Equipe :"
+    }
+  },
+  "user": {
+    "create": {
+      "backlink": "Retour",
+      "title": "Inviter un utilisateur à ",
+      "labelUsername": "Nom d'utilisateur*",
+      "labelUsernameTitle": "Caractères alphanumérique uniquement",
+      "labelEmail": "E-mail *",
+      "labelFirstname": "Prénom *",
+      "labelLastname": "Nom *",
+      "buttonSubmit": "Inviter"
+    }
+  },
+  "notification": {
+    "circle": {
+      "in": "dans"
+    },
+    "private": {
+      "private": "en privé"
+    }
+  },
+  "template-captain": {
+    "isLead": "Capitaine"
+  },
+  "hublStatus": {
+    "private": "Privé",
+    "public": "Public"
+  }
+}
\ No newline at end of file
diff --git a/src/menu-left.pug b/src/menu-left.pug
index 7513598d692f7e5cb407aebe5f4d22c0468fa913..b3a751801301932d2d6af110c5fb9d67177305bc 100644
--- a/src/menu-left.pug
+++ b/src/menu-left.pug
@@ -14,10 +14,13 @@ solid-widget(name='hubl-menu-publicprivate')
 
 solid-widget(name='hubl-create')
   template
-    p.create Tu ne fais partie d'aucun ${value}.
+    p.create 
+      span(data-trans="menuLeft.emptyCircleProject.notPartOf")
+      span &nbsp;${value}.
       br
-      | Pour en créer un nouveau, tu peux te rendre dans le 
-      solid-link(next='admin') panneau d'administration
+      span(data-trans="menuLeft.emptyCircleProject.createNew")
+      span &nbsp;
+      solid-link(next="${value == 'projet' ? 'admin-projects' : 'admin-circles'}", data-trans="menuLeft.emptyCircleProject.adminPanel")
 
 solid-widget(name='hubl-menu-fix-url-circle')
   template
@@ -53,32 +56,32 @@ solid-widget(name='hubl-menu-fix-url-project')
 solid-router#navbar-router(default-route='dashboard')
   if endpoints.dashboards || (endpoints.get && endpoints.get.dashboards)
     solid-route.menu(name='dashboard')
-      div.menu-label Tableau de bord
+      div.menu-label(data-trans="menuLeft.dashboard")
       div.menu-icon.icon-home
     div.divider
   if publicDirectory && (endpoints.users || (endpoints.get && endpoints.get.users))
     solid-route.menu(name='members')
-      div.menu-label Annuaire des membres
+      div.menu-label(data-trans="menuLeft.profileDirectory")
       div.menu-icon.icon-people
     div.divider
   if endpoints.joboffers || (endpoints.get && endpoints.get.joboffers)
     solid-route.menu(name='job-offers', rdf-type='hd:joboffer')
-      div.menu-label Offres de mission
+      div.menu-label(data-trans="menuLeft.jobBoard")
       div.menu-icon.icon-briefcase
     div.divider
   if endpoints.resources || (endpoints.get && endpoints.get.resources)
     solid-route.menu(name='resources')
-      div.menu-label Ressources
+      div.menu-label(data-trans="menuLeft.resources")
       div.menu-icon.icon-docs
     div.divider
   if endpoints.polls || (endpoints.get && endpoints.get.polls)
     solid-route.menu(name='polls')
-      div.menu-label Gouvernance
+      div.menu-label(data-trans="menuLeft.gov")
       div.menu-icon.icon-bubbles
     div.divider
   if endpoints.events || (endpoints.get && endpoints.get.events)
     solid-route.menu(name='events')
-      div.menu-label Evènements
+      div.menu-label(data-trans="menuLeft.events")
       div.menu-icon.icon-calendar
     div.divider
   if endpoints.projects || (endpoints.get && endpoints.get.projects)
@@ -89,7 +92,7 @@ solid-router#navbar-router(default-route='dashboard')
           div.menu-chevron
             div.menu-icon.icon-arrow-up
             //- div.menu-icon.icon-arrow-right-circle
-          div.menu-label  Projets
+          div.menu-label(data-trans="menuLeft.projects")
           div.menu-icon.icon-folder-alt
       solid-route(name='project', rdf-type='hd:project', use-id='', hidden)
       div.sub-menu.menu-notification
@@ -104,7 +107,8 @@ solid-router#navbar-router(default-route='dashboard')
           fields='project'
           loader-id='loader-projects'
           empty-widget='hubl-create'
-          empty-value='projet'
+          empty-value=''
+          data-trans="empty-value=menuLeft.emptyCircleProject.project"
           widget-project='hubl-menu-fix-url-project'
           order-by="project.customer.name"
         )
@@ -117,7 +121,7 @@ solid-router#navbar-router(default-route='dashboard')
           div.menu-chevron
             div.menu-icon.icon-arrow-up
             //- div.menu-icon.icon-arrow-right-circle
-          div.menu-label  Cercles
+          div.menu-label(data-trans="menuLeft.circles")
           div.menu-icon.icon-folder-alt
       solid-route(name='circle', rdf-type='hd:circle', use-id='', hidden)
       div.sub-menu.menu-notification
@@ -132,7 +136,8 @@ solid-router#navbar-router(default-route='dashboard')
           fields='circle'
           loader-id='loader-circles'
           empty-widget='hubl-create'
-          empty-value='cercle'
+          empty-value=''
+          data-trans="empty-value=menuLeft.emptyCircleProject.circle"
           widget-circle='hubl-menu-fix-url-circle'
           order-by="circle.name"
         )
@@ -142,7 +147,7 @@ solid-router#navbar-router(default-route='dashboard')
       div.menu
         div.menu-chevron
           div.menu-icon.icon-arrow-up
-        div.menu-label Messages
+        div.menu-label(data-trans="menuLeft.messages")
         div.menu-icon.icon-envelope-letter
       solid-route(name='messages', rdf-type='foaf:user', use-id='', hidden)
       div.sub-menu.menu-notification
@@ -156,7 +161,8 @@ solid-router#navbar-router(default-route='dashboard')
           fields='name, chatProfile.jabberID, badge'
           loader-id='loader-messages'
           search-fields="name"
-          search-label-name="Rechercher..."
+          search-label-name=""
+          data-trans="search-label-name=menuLeft.search"
           search-widget-name="hubl-search-users"
           widget-name='solid-display-div'
           widget-badge='hubl-counter'
diff --git a/src/page-about.pug b/src/page-about.pug
index 0bad6cf188f01ed27263dfe4d062ad97e28bb899..98870a65dc6339c18305bed4647ec2dd4b38fc6b 100644
--- a/src/page-about.pug
+++ b/src/page-about.pug
@@ -1,17 +1,17 @@
 .views-container
-  h2 A propos
+  h2(data-trans='about.title')
   div.flex-content-white
     div
       div
-        h3 Cette application est développée  par Startin'blox
-        p Startin’blox est une coopérative qui développe des outils libres pour construire facilement et à moindre coût des applications fédérées et interopérables basées sur les derniers standards du web poussés par le projet SOLID.
-        p Sa mission est de redonner le pouvoir aux utilisateurs en leur permettant de reprendre la main sur leur outil numérique et de bénéficier d’un effet de réseau au sein d’un écosystème choisi afin de s’émanciper des grandes plateformes.
+        h3(data-trans='about.card1.subTitle')
+        p(data-trans='about.card1.paragraph1')
+        p(data-trans='about.card1.paragraph2')
       div
         a(href="https://startinblox.com/fr/" target="_blank") https://startinblox.com/fr/
 
     div
       div
-        h3 Contacte-nous
-        p Tu veux contribuer, nous remonter un bug, nous suggérer une amélioration, travailler avec nous ? 
+        h3(data-trans='about.card2.subTitle')
+        p(data-trans='about.card2.paragraph1')
       div
-        a(href="https://startinblox.com/fr/#home-contact" target="_blank").main-cta Contact 
\ No newline at end of file
+        a(href="https://startinblox.com/fr/#home-contact" target="_blank" data-trans='about.card2.link').main-cta
\ No newline at end of file
diff --git a/src/page-admin.pug b/src/page-admin.pug
index 979faed4b616e7dce1d500a6947f188f6a6eac26..b58012708b46d3c21bad6867f730aea983eb759d 100644
--- a/src/page-admin.pug
+++ b/src/page-admin.pug
@@ -1,27 +1,27 @@
 .views-container.sidebar-is-closed
   if endpoints.circles || (endpoints.get && endpoints.get.circles)
-    #admin-circles(hidden)
+    #admin-circles(hidden, data-view="admin-circles")
       include views/admin/page-admin-circles.pug
   if endpoints.projects || (endpoints.get && endpoints.get.projects)
-    #admin-projects(hidden)
+    #admin-projects(hidden, data-view="admin-projects")
       include views/admin/page-admin-projects.pug
   if (endpoints.users || (endpoints.get && endpoints.get.users))
-    #admin-communities(hidden)
+    #admin-communities(hidden, data-view="admin-communities")
       include views/admin/page-admin-communities.pug
 nav.jsRightMenu(role='navigation')
   solid-router(default-route='admin-circles')
     ul
       li.jsOffsiteToggle
-        a Replier le menu
+        a(data-trans='admin.menuRight.fold')
       if (endpoints.users || (endpoints.get && endpoints.get.users))
         solid-route(name='admin-communities')
           li
-            a Communautés
+            a(data-trans='admin.menuRight.community')
       if endpoints.circles || (endpoints.get && endpoints.get.circles)
         solid-route(name='admin-circles')
           li
-            a Cercles
+            a(data-trans='admin.menuRight.circles')
       if endpoints.projects || (endpoints.get && endpoints.get.projects)
         solid-route(name='admin-projects')
           li
-            a Projets
+            a(data-trans='admin.menuRight.projects')
diff --git a/src/page-circle.pug b/src/page-circle.pug
index 5ca22718bb5b3c0634198df54e19fe9fc6137fd7..9d86a5480db81193ba1fa7e90bb879883b54505e 100644
--- a/src/page-circle.pug
+++ b/src/page-circle.pug
@@ -9,41 +9,41 @@
           class-name='h1-like'
           class-description='h1-aside description'
         )
-        button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle MENU
+        button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle(data-trans='circle.menuRight.buttonMobile')
     div.content-box__height
       solid-ac-checker(permission='acl:Read', bind-resources)
-        #circle-chat(hidden)
+        #circle-chat(hidden, data-view="circle-chat")
           include views/circle/page-circle-chat.pug
-        #circle-information.content-box__height(hidden)
+        #circle-information.content-box__height(hidden, data-view="circle-information")
           include views/circle/page-circle-profile.pug
-        #circle-events(hidden)
+        #circle-events(hidden, data-view="circle-events")
           include views/circle/page-circle-events.pug
-        #circle-resources(hidden)
+        #circle-resources(hidden, data-view="circle-resources")
           include views/circle/page-circle-resources.pug
-        #circle-polls(hidden)
+        #circle-polls(hidden, data-view="circle-polls")
           include views/circle/page-circle-polls.pug
 
 nav.jsRightMenu(role='navigation')
   solid-router(default-route='circle-chat')
     ul
       li.jsOffsiteToggle
-        a Replier le menu
+        a(data-trans='circle.menuRight.fold')
       solid-route(name='circle-chat')
         li
-          a Chat
+          a(data-trans='circle.menuRight.chat')
       solid-route(name='circle-information')
         li
-          a Information
+          a(data-trans='circle.menuRight.information')
       if (endpoints.resources || (endpoints.get && endpoints.get.resources)) && (endpoints.resourceskeywords || (endpoints.get && endpoints.get.resourceskeywords)) && (endpoints.resourcestypes || (endpoints.get && endpoints.get.resourcestypes))
         solid-route(name='circle-resources' use-id)
           li
-            a Resources
+            a(data-trans='circle.menuRight.resources')
       if (endpoints.events || (endpoints.get && endpoints.get.events)) && (endpoints.typeevents || (endpoints.get && endpoints.get.typeevents))
         solid-route(name='circle-events' use-id)
           li
-            a Events
+            a(data-trans='circle.menuRight.events')
       if endpoints.polls || (endpoints.get && endpoints.get.polls)
         solid-route(name='circle-polls' use-id)
           li
-            a Polls
+            a(data-trans='circle.menuRight.polls')
       
diff --git a/src/page-dashboard.pug b/src/page-dashboard.pug
index 9a22752ee0d61b2bcf4f1b6e97d528a181ed0b3d..3b3cae6c28feed7f5fb6f59adbd10259c3c56af1 100644
--- a/src/page-dashboard.pug
+++ b/src/page-dashboard.pug
@@ -1,5 +1,5 @@
 .views-container
-  h1 Tableau de bord
+  h1(data-trans='dashboard.title')
   solid-dashboard(
     data-src=`${endpoints.dashboards || endpoints.get.dashboards}`
   )
diff --git a/src/page-project.pug b/src/page-project.pug
index 3c102656818c215ad892df83ed991b0b532a6de4..9a9825d52a1f8841945d88ac5397781454be6a04 100644
--- a/src/page-project.pug
+++ b/src/page-project.pug
@@ -13,25 +13,25 @@
     
           value-const-title1='N°'
         )
-        button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle MENU
+        button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle(data-trans='project.menuRight.buttonMobile')
     div.content-box__height
       solid-ac-checker(permission='acl:Read', bind-resources)
-        #project-chat(hidden)
+        #project-chat(hidden, data-view="project-chat")
           include views/project/page-project-chat.pug
-        #project-information.content-box__height(hidden)
+        #project-information.content-box__height(hidden, data-view="project-information")
           include views/project/page-project-profile.pug
-        #project-picture(hidden)
+        #project-picture(hidden, data-view="project-picture")
           include views/project/page-project-picture.pug
 
 nav.jsRightMenu(role='navigation')
   solid-router(default-route='project-chat')
     ul
       li.jsOffsiteToggle
-        a Replier le menu
+        a(data-trans='project.menuRight.fold')
       solid-route(name='project-chat')
         li 
-          a Chat
+          a(data-trans='project.menuRight.chat')
       solid-route(name='project-information')
         li 
-          a Information
+          a(data-trans='project.menuRight.information')
       solid-route(name='project-picture' use-id)
\ No newline at end of file
diff --git a/src/scripts/firefox-scroll.js b/src/scripts/firefox-scroll.js
new file mode 100644
index 0000000000000000000000000000000000000000..5f624687d0f02093eefcd89331c862faa236eaef
--- /dev/null
+++ b/src/scripts/firefox-scroll.js
@@ -0,0 +1,55 @@
+document.addEventListener("DOMContentLoaded", () => {
+  const resizeChat = () => {
+    let chatBox = Array.from(document.querySelectorAll("solid-xmpp-chat"))
+      .map((el) => el.shadowRoot ? el.shadowRoot.getElementById("conversejs") : false)
+      .filter((el) => el)
+      .pop();
+    if (chatBox) {
+      let chatTextArea = chatBox.querySelector(".message-form-container");
+      let ischatTextArea = setInterval(() => {
+        chatTextArea = chatBox.querySelector(".message-form-container");
+        if (chatTextArea) {
+          clearInterval(ischatTextArea);
+          if (
+            chatBox.getBoundingClientRect().height -
+            chatTextArea.getBoundingClientRect().height !=
+            chatTextArea.offsetTop
+          ) {
+            let viewportChat = Array.from(
+              document.querySelectorAll("#viewport .chat-view")
+            );
+            viewportChat.forEach(
+              (c) => (c.style.height = "calc(100vh - 106px - 57px - 4px)")
+            );
+          }
+        }
+      }, 15);
+    }
+  };
+  resizeChat();
+
+  let isbody = setInterval(() => {
+    if (document.body) {
+      clearInterval(isbody);
+      resizeChat();
+    }
+  }, 15);
+
+  window.addEventListener("load", () => {
+    setTimeout(() => {
+      resizeChat();
+    }, 0);
+  });
+
+  window.addEventListener("resize", () => {
+    setTimeout(() => {
+      resizeChat();
+    }, 0);
+  });
+
+  document.addEventListener("navigate", () => {
+    setTimeout(() => {
+      resizeChat();
+    }, 0);
+  });
+});
\ No newline at end of file
diff --git a/src/scripts/intl.js b/src/scripts/intl.js
new file mode 100644
index 0000000000000000000000000000000000000000..9b098e7e00519d1959b3d11e7f361f3afb2316c6
--- /dev/null
+++ b/src/scripts/intl.js
@@ -0,0 +1,198 @@
+/*
+  js intl, inspired by danabr/jsI18n
+*/
+class JsI18n {
+
+  constructor() {
+    this.locale = ""; //Current locale
+    this.locales = new Array(); //Available locales
+  }
+
+  /*
+    Method for automatically detecting the language, does not work in every browser.
+  */
+  detectLanguage() {
+    if (localStorage.getItem('language') || (window.navigator.language !== null && window.navigator.language !== undefined)) {
+      this.setLocale(localStorage.getItem('language') || window.navigator.language.slice(0, 2));
+    } else {
+      console.error('Language not found');
+      this.setLocale('fr');
+    }
+  };
+
+  /*
+    Translates tag contents and
+    attributes depending on the
+    value of key.
+  */
+  translateTag(node, key) {
+    if (key.indexOf("=") == -1) { //Simple key
+      this.translateNodeContent(node, key);
+    } else { //Attribute/key pairs
+      var parts = key.split(";");
+
+      for (var i = 0; i < parts.length; i++) {
+        var pair = parts[i].split("=");
+        var attr = pair[0].toLowerCase().trim();
+        var k = pair[1].trim();
+
+        if (attr == "html") {
+          this.translateNodeContent(node, k);
+        } else {
+          if(node.tagName == "SOLID-DELETE") {
+            let button = node.querySelector('button');
+            if(button != null) {
+              this.translateNodeContent(button, k);
+            }
+          }
+          this.translateNodeContent(node.attributes[attr], k);
+        }
+      }
+    }
+  }
+
+  /**
+    Replace the content of the given node
+    if there is a translation for the given key.
+  **/
+  translateNodeContent(node, key) {
+    var translation = this.t(key);
+    if (node != null && translation != undefined) {
+      if (node.nodeType == 1) { //Element
+        try {
+          node.innerHTML = translation;
+        } catch (e) {
+          node.text = translation;
+        }
+      } else if (node.nodeType == 2) { //Attribute
+        node.value = translation;
+      }
+    }
+  }
+
+  /*
+    Helper for translating a node
+    and all its child nodes.
+  */
+  processNode(node) {
+    if (node != undefined) {
+      if (node.nodeType == 1) { //Element node
+
+        var key = node.attributes["data-trans"];
+        if (key != null) {
+          this.translateTag(node, key.nodeValue);
+        }
+      }
+
+      //Process child nodes
+      var children = node.childNodes;
+      for (var i = 0; i < children.length; i++) {
+        this.processNode(children[i]);
+      }
+    }
+  }
+
+  /*
+    Adds a locale to the list,
+    replacing the translations
+    if the locale is already defined.
+  */
+  addLocale(locale, translations) {
+    this.locales[locale.toString()] = translations;
+  }
+
+  /*
+    Sets the locale to use when translating.
+  */
+  setLocale(locale) {
+    try {
+      fetch(`/locales/${locale}.json`).then((result) => {
+        if (result.ok) {
+          result.json().then(e => {
+            this.addLocale(locale, e);
+            this.processPage();
+          }).catch(() => {
+            if (locale != "fr") {
+              console.warn(`Locale not found: ${locale}, fallback to french`);
+              this.setLocale("fr");
+            } else {
+              console.error("Language not found");
+            }
+          });
+        } else {
+            if (locale != "fr") {
+              console.warn(`Locale not found: ${locale}, fallback to french`);
+              this.setLocale("fr");
+            } else {
+              console.error("Language not found");
+            }
+        }
+      });
+      this.locale = locale;
+    } catch {
+      if (locale != "fr") {
+        console.warn(`Locale not found: ${locale}, fallback to french`);
+        this.setLocale("fr");
+      } else {
+        console.error("Language not found");
+      }
+    }
+  }
+
+  /*
+    Fetches the translation associated with the given key.
+  */
+  t(key) {
+    var translations = this.locales[this.locale];
+    if (translations != undefined) {
+      let translation = key.toString().split('.').reduce((o, i) => (o ? o[i] : undefined), translations);
+      if(typeof translation == "string") {
+        return translation;
+      } else {
+        return translations[key.toString()];
+      }
+    }
+    return undefined;
+  }
+
+  /*
+    Alias for JsI18n.t
+  */
+  translate(key) {
+    this.t(key);
+  }
+
+  /**
+    Replaces the contents of all tags
+    that have the data-trans attribute set.
+  **/
+  processPage() {
+    this.processNode(document.getElementsByTagName("html")[0]);
+  }
+}
+
+//Global
+jsI18n = new JsI18n;
+
+document.addEventListener("DOMContentLoaded", () => {
+
+  // Detect the lang & initialize, based on the browser or "language" item from localstorage
+  jsI18n.detectLanguage();
+  
+  /*
+    recursivePopulate(DOMElement)
+    Will listen for the populate event of any sib element
+    Process the changed node every time it populate
+    Recursively add a populate listener for children elements
+  */
+  function recursivePopulate(element) {
+    Array.from(element.querySelectorAll('*')).forEach((e) => {
+      e.addEventListener("populate", (e) => {
+        recursivePopulate(e.target);
+        jsI18n.processNode(e.target);
+      });
+    });
+  }
+  // Process every children from document
+  recursivePopulate(document);
+});
\ No newline at end of file
diff --git a/src/styles/base/table.scss b/src/styles/base/table.scss
index 9fb19b764c6284ab3bc660961db13f14d17ff256..c6b7e376025ae9f72323edfd3d23ee076d365063 100644
--- a/src/styles/base/table.scss
+++ b/src/styles/base/table.scss
@@ -49,6 +49,9 @@
             text-align: center;
             vertical-align: middle;
           }
+          solid-multiple[name="user.communities"] {
+            text-align: left;
+          }
         }
       }
 
diff --git a/src/templates/hubl-captain.pug b/src/templates/hubl-captain.pug
index 4b2bc9b781c6cf6264eb9aaaf11c38f51b681239..5a5248cd47a50c2e2be36be353496695c49c71e8 100644
--- a/src/templates/hubl-captain.pug
+++ b/src/templates/hubl-captain.pug
@@ -11,5 +11,6 @@ solid-widget(name='hubl-captain')
       class-is_lead='user-thumb__lead'
 
       widget-account.picture='hubl-user-avatar'
-      value-is_lead='Capitaine'
+      value-is_lead=''
+      data-trans='value-is_lead=template-captain.isLead'
     )
diff --git a/src/views/admin/page-admin-circles-create.pug b/src/views/admin/page-admin-circles-create.pug
index fcf1334b703fae07a854d98eb915e6242b02f9df..e01c33538be04aefd78bbd71337de96ec55dbd54 100644
--- a/src/views/admin/page-admin-circles-create.pug
+++ b/src/views/admin/page-admin-circles-create.pug
@@ -1,7 +1,7 @@
 div.content-box__info.flex
-  solid-link(class="backlink right", next='admin-circle-list') Retour
+  solid-link(class="backlink right", next='admin-circle-list' data-trans='circle.create.backlink')
 
-  h1.centered Créer un cercle
+  h1.centered(data-trans='circle.create.title')
 
   div#loader-circles-create.loader.loader-top
     div
@@ -22,13 +22,15 @@ div.content-box__info.flex
     class-name='form-label is-light is-full-width input-text-like'
     class-description='form-label is-light is-full-width input-text-like'
 
-    label-status='Statut du cercle'
-    label-name='Nom du cercle *'
-    label-description='Sous-titre du cercle *'
+    label-status=''
+    label-name=''
+    label-description=''
 
     widget-status='hubl-status'
     
     next='circle'
 
-    submit-button='Enregistrer'
+    submit-button=''
+    
+    data-trans='label-status=circle.create.labelStatus;label-name=circle.create.labelName;label-description=circle.create.labelDescription;submit-button=circle.create.buttonSubmit'
   )
diff --git a/src/views/admin/page-admin-circles.pug b/src/views/admin/page-admin-circles.pug
index a75f432388326cec2bffb044b893534ee8a4137b..c9b596573627b25f161c61c2751af974f4a77f85 100644
--- a/src/views/admin/page-admin-circles.pug
+++ b/src/views/admin/page-admin-circles.pug
@@ -5,12 +5,12 @@
     solid-route(name='circle-left')
 
   div.content-box__header.flex.space-between
-    h1.without-margin Administration
-    button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle MENU
+    h1.without-margin(data-trans='circle.list.title')
+    button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle(data-trans='circle.list.buttonMobile')
 
   include ../circle/page-circle-left.pug
 
-  #admin-circle-list.content-box__height(hidden)
+  #admin-circle-list.content-box__height(hidden, data-view="admin-circle-list")
     include ../../templates/hubl-user-avatar.pug
 
     solid-widget(name='hubl-circle-owner')
@@ -31,27 +31,29 @@
 
       div.admin-header.flex
 
-        h3 Cercles
+        h3(data-trans='circle.list.subTitle')
 
-        solid-link(
-          class='button text-bold text-uppercase reversed button-primary bordered with-icon icon-plus'
-          next='admin-circle-create'
-        ) Créer un cercle
+        solid-ac-checker(data-src=`${endpoints.circles || (endpoints.post && endpoints.post.circles)}`, permission='acl:Append')
+          solid-link(
+            class='button text-bold text-uppercase reversed button-primary bordered with-icon icon-plus'
+            next='admin-circle-create' data-trans='circle.list.buttonCreate'
+          )
 
       .table-wrapper
         .table
 
           div.table-header.grey-color
-            div.w280 Nom
-            div.w280 Administrateurs
-            div.w280 Rejoindre
+            div.w280(data-trans='circle.list.tableHeader1')
+            div.w280(data-trans='circle.list.tableHeader2')
+            div.w280(data-trans='circle.list.tableHeader3')
 
           solid-widget(name='hubl-admin-circle-leave-button')
             template
               solid-delete(
                 class='circle-leave button text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
                 data-src="${src}"
-                data-label='Quitter'
+                data-label=''
+                data-trans='data-label=circle.list.buttonQuit'
               )
               hubl-reactivity(data-src=`${endpoints.circles || endpoints.get.circles}` target-src='${src}')
               hubl-reactivity(data-src=`${endpoints.circles || endpoints.get.circles}joinable/` target-src='${src}')
@@ -89,6 +91,7 @@
                 widget-user.username='solid-form-hidden'
 
                 submit-button='Rejoindre'
+                data-trans='submit-button=circle.list.buttonJoin'
               )
               hubl-reactivity(data-src=`${endpoints.circles || endpoints.get.circles}` target-src='${value}')
               hubl-reactivity(data-src=`${endpoints.circles || endpoints.get.circles}joinable/` target-src='${value}')
@@ -120,5 +123,5 @@
         div
         div
 
-  #admin-circle-create.content-box__height(hidden)
+  #admin-circle-create.content-box__height(hidden, data-view="admin-circle-create")
     include page-admin-circles-create.pug
diff --git a/src/views/admin/page-admin-communities.pug b/src/views/admin/page-admin-communities.pug
index b5dce387ebfcdcff0b74493d36cc73082e13ff99..78835710a8cf9a0da61ad294a3ded7ecf3d3101f 100644
--- a/src/views/admin/page-admin-communities.pug
+++ b/src/views/admin/page-admin-communities.pug
@@ -4,8 +4,8 @@
     solid-route(name='admin-users-create', use-id)
 
   div.content-box__header.flex.space-between
-    h1.without-margin Administration
-    button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle MENU
+    h1.without-margin(data-trans='communities.title')
+    button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle(data-trans='communities.menuMobile')
   
   solid-widget(name='hubl-action-community')
     template
@@ -14,20 +14,21 @@
           class='button text-bold text-uppercase reversed button-primary bordered with-icon icon-plus'
           data-src="${value}"
           next="admin-users-create"
-        ) Inviter un nouvel utilisateur
+          data-trans='communities.linkInvite'
+        )
       solid-ac-checker(data-src="${value}", nested-field="members", no-permission='acl:Append')
-        div.button.text-bold.text-uppercase.button-disabled Membre, aucune permission
+        div.button.text-bold.text-uppercase.button-disabled(data-trans='communities.noPermission')
 
-  #admin-communities-list.content-box__height(hidden)
+  #admin-communities-list.content-box__height(hidden, data-view="admin-communities-list")
     div.content-box__info.flex
       div.admin-header.flex
-        h3 Communautés
+        h3(data-trans='communities.subTitle')
 
       .table-wrapper
         .table
           div.table-header.grey-color
-            div.w450 Nom
-            div.w370 Action
+            div.w450(data-trans='communities.tableHeader1') 
+            div.w370(data-trans='communities.tableHeader2')
         
           solid-display(
             class='table-body'
@@ -49,5 +50,5 @@
         div
         div
 
-  #admin-users-create.content-box__height(hidden)
+  #admin-users-create.content-box__height(hidden, data-view="admin-users-create")
     include page-admin-users-create.pug
diff --git a/src/views/admin/page-admin-projects-create.pug b/src/views/admin/page-admin-projects-create.pug
index 8a42024e61bf11aeee8ad0adb7a1776f00ee5dde..44169cee9773c42bd690dcf3065c17d3c271640f 100644
--- a/src/views/admin/page-admin-projects-create.pug
+++ b/src/views/admin/page-admin-projects-create.pug
@@ -1,7 +1,7 @@
 div.content-box__info.flex
-  solid-link(class="backlink right" next='admin-project-list') Retour
+  solid-link(class="backlink right" next='admin-project-list' data-trans='project.create.backlink')
 
-  h1.centered Créer un nouveau projet
+  h1.centered(data-trans='project.create.title')
 
   div#loader-projects-create.loader.loader-top
     div
@@ -19,18 +19,18 @@ div.content-box__info.flex
     required-captain
     loader-id='loader-projects-create'
 
-    label-status='Statut du cercle*'
+    label-status=''
     widget-status='solid-form-hidden'
     class-status='form-label is-light is-full-width'
     value-status="Private"
 
-		label-customer.name='Nom du client*'
+		label-customer.name=''
     class-customer.name='form-label is-light is-half-width input-text-like'
 
-		label-name='Nom du projet*'
+		label-name=''
     class-name='form-label is-light is-half-width input-text-like'
 
-    label-captain='Capitaine du projet*'
+    label-captain=''
     range-captain=`${endpoints.users || endpoints.get.users}`
     class-captain='form-label is-light is-half-width'
     widget-captain='solid-form-dropdown-autocompletion-label'
@@ -39,5 +39,7 @@ div.content-box__info.flex
 
     next='project'
 
-    submit-button='Enregistrer'
+    submit-button=''
+
+    data-trans='label-status=project.create.labelStatus;label-customer.name=project.create.labelCustomer;label-name=project.create.labelName;label-captain=project.create.labelCaptain;submit-button=project.create.buttonSubmit'
   )
diff --git a/src/views/admin/page-admin-projects.pug b/src/views/admin/page-admin-projects.pug
index d984c2741e983b9164856d23193d434f9e8efc5b..04bef98413aeb0a98d2e6aedfa36ea21a25933ca 100644
--- a/src/views/admin/page-admin-projects.pug
+++ b/src/views/admin/page-admin-projects.pug
@@ -5,37 +5,40 @@
     solid-route(name='project-left')
 
   div.content-box__header.flex.space-between
-    h1.without-margin Administration
-    button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle MENU
+    h1.without-margin(data-trans='project.list.title')
+    button.mobile-sidebar-button.jsMobileSidebarOpenButton.icon-arrow-left-circle(data-trans='project.list.buttonMobile')
 
-  #project-left(hidden)
+  #project-left(hidden, data-view="project-left")
     include ../project/page-project-left.pug
 
-  #admin-project-list.content-box__height(hidden)
+  #admin-project-list.content-box__height(hidden, data-view="admin-project-list")
     include ../../templates/hubl-user-avatar.pug
 
     div.content-box__info.flex
       div.admin-header.flex
-        h3 Projets
-        solid-link(
-          class='button text-bold text-uppercase reversed button-primary bordered with-icon icon-plus'
-          next='admin-project-create'
-        ) Créer un nouveau projet
+        h3(data-trans='project.list.subTitle')
+        solid-ac-checker(data-src=`${endpoints.projects || (endpoints.post && endpoints.post.projects)}`, permission='acl:Append')
+          solid-link(
+            class='button text-bold text-uppercase reversed button-primary bordered with-icon icon-plus'
+            next='admin-project-create'
+            data-trans='project.list.buttonCreate'
+          )
 
       .table-wrapper
         .table
           div.table-header.grey-color
-            div.w280 Nom
-            div.w280 Administrateurs
-            div.w280 Capitaines
-            div.w230 Rejoindre
+            div.w280(data-trans='project.list.tableHeader1')
+            div.w280(data-trans='project.list.tableHeader2')
+            div.w280(data-trans='project.list.tableHeader3')
+            div.w230(data-trans='project.list.tableHeader4')
 
           solid-widget(name="hubl-admin-project-leave-button")
             template
               solid-delete(
                 class='button text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
                 data-src="${src}"
-                data-label='Quitter'
+                data-label=''
+                data-trans='data-label=project.list.buttonQuit'
               )
               hubl-reactivity(data-src=`${endpoints.projects || endpoints.get.projects}` target-src='${src}')
               hubl-reactivity(data-src=`${endpoints.projects || endpoints.get.projects}joinable/` target-src='${src}')
@@ -73,7 +76,8 @@
               solid-delete(
                 class='button text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
                 data-src="${src}"
-                data-label='Quitter'
+                data-label=''
+                data-trans='data-label=project.list.buttonQuit'
               )
 
           solid-display(
@@ -108,7 +112,8 @@
                 value-user.username='hubl-workaround-493'
                 widget-user.username='solid-form-hidden'
 
-                submit-button='Rejoindre'
+                submit-button=''
+                data-trans='submit-button=project.list.buttonJoin'
               )
               hubl-reactivity(data-src=`${endpoints.projects || endpoints.get.projects}` target-src='${src}')
               hubl-reactivity(data-src=`${endpoints.projects || endpoints.get.projects}joinable/` target-src='${src}')
@@ -144,5 +149,5 @@
         div
         div
 
-  #admin-project-create(hidden)
-    include page-admin-projects-create.pug
\ No newline at end of file
+  #admin-project-create(hidden, data-view="admin-project-create")
+    include page-admin-projects-create.pug
diff --git a/src/views/admin/page-admin-users-create.pug b/src/views/admin/page-admin-users-create.pug
index 260efc54d2fc65fff3f74d5283cb3ca9ab395d21..66e7c47535ac61cc7df2139b79b24a6fb4c71689 100644
--- a/src/views/admin/page-admin-users-create.pug
+++ b/src/views/admin/page-admin-users-create.pug
@@ -1,10 +1,11 @@
 div.content-box__info.flex
-  solid-link(class='backlink right', next='admin-communities-list') Retour
+  solid-link(class='backlink right', next='admin-communities-list' data-trans='user.create.backlink')
 
   solid-display.h1-like.centered(
     bind-resources
     fields='text, name'
-    value-text="Inviter un utilisateur à "
+    value-text=''
+    data-trans='value-text=user.create.title'
     loader-id='loader-users-title'
   )
 
@@ -22,13 +23,13 @@ div.content-box__info.flex
 
   solid-widget(name='hubl-username-field')
     template
-      label Nom d'utilisateur*
-      input(type="text" title='Caractères alphanumérique uniquement' pattern="[a-zA-Z0-9]+" label="Nom d'utilisateur *" name="username" required value="\${value}" data-holder)
+      label(data-trans='user.create.labelUsername')
+      input(type="text" title='' pattern="[a-zA-Z0-9]+" label="" data-trans='title=user.create.labelUsernameTitle;label=user.create.labelUsername' name="username" required value="\${value}" data-holder)
 
   solid-widget(name='hubl-email-field')
     template
-      label E-mail *
-      input(type="email" label="E-mail *" name="email" required value="\${value}" data-holder)
+      label(data-trans='user.create.labelEmail')
+      input(type="email" label='' data-trans='label=user.create.labelEmail' name="email" required value="\${value}" data-holder)
 
   solid-form.form.button-register#selected-community(
     bind-resources
@@ -46,10 +47,10 @@ div.content-box__info.flex
     class-user.username='form-label is-light is-half-width input-text-like'
     class-user.email='form-label is-light is-half-width input-text-like'
 
-    label-user.first_name='Prénom *'
-    label-user.last_name='Nom *'
-    label-user.username='Nom d\'utilisateur *'
-    label-user.email='E-mail *'
+    label-user.first_name=''
+    label-user.last_name=''
+    label-user.username=''
+    label-user.email=''
 
     value-user.password=''
     widget-user.password='solid-form-hidden'
@@ -59,5 +60,6 @@ div.content-box__info.flex
 
     next='admin-communities-list'
 
-    submit-button='Inviter'
+    submit-button=''
+    data-trans='label-user.first_name=user.create.labelFirstname;label-user.last_name=user.create.labelLastname;label-user.username=user.create.labelUsername;label-user.email=user.create.labelEmail;submit-button=user.create.buttonSubmit'
   )
diff --git a/src/views/circle/page-circle-edit.pug b/src/views/circle/page-circle-edit.pug
index 9e16a4ff3503c20248cefe5dcea2385d7fb443c3..c56d36aea903fd2e201e48523da4b93b09b649e7 100644
--- a/src/views/circle/page-circle-edit.pug
+++ b/src/views/circle/page-circle-edit.pug
@@ -8,13 +8,14 @@ div.content-box__info
         solid-delete(
           class='button text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
           data-src="${src}"
-          data-label='Retirer'
+          data-label=''
+          data-trans='data-label=circle.edit.buttonDelete'
         )
 
-  solid-link(class="backlink right", bind-resources, next='circle-profile') Retour
+  solid-link(class="backlink right", bind-resources, next='circle-profile' data-trans='circle.edit.backlink')
 
   solid-ac-checker(permission='acl:Write', bind-resources)
-    h1 Modifie ton cercle
+    h1(data-trans='circle.edit.title')
 
     div#loader-circle-edit.loader.loader-top
       div
@@ -32,12 +33,12 @@ div.content-box__info
       required-description
       range-owner=`${endpoints.users || endpoints.get.users}`
 
-      label-status='Statut du cercle'
+      label-status=''
       widget-status='hubl-status'
 
-      label-name='Nom du cercle *'
-      label-owner='Administrateur ou administratrice *'
-      label-description='Sous-titre du cercle *'
+      label-name=''
+      label-owner=''
+      label-description=''
 
       class-name='form-label is-light is-half-width input-text-like'
       class-owner='form-label is-light is-half-width member-select color'
@@ -50,9 +51,11 @@ div.content-box__info
 
       submit-button='Enregistrer'
       next='circle-information'
+
+      data-trans='label-name=circle.edit.labelStatus;label-name=circle.edit.labelName;label-owner=circle.edit.labelOwner;label-description=circle.edit.labelDescription;submit-button=circle.edit.buttonSubmit'
     )
 
-  h2 Liste des membres :
+  h2(data-trans='circle.edit.subTitle')
 
   solid-ac-checker(permission='acl:Append', bind-resources, nested-field='members')
     solid-form.block.select-add(
@@ -64,14 +67,15 @@ div.content-box__info
       class-user='team'
       widget-user='solid-form-dropdown-autocompletion'
 
-      submit-button='Ajouter un membre'
+      submit-button=''
+      data-trans='submit-button=circle.edit.buttonAddMember'
     )
 
   .table-wrapper
     .table
       div.table-header.grey-color
-        div.w280 Nom
-        div.w162 Accès
+        div.w280(data-trans='circle.edit.tableHeader1')
+        div.w162(data-trans='circle.edit.tableHeader2')
 
       solid-display(
         class='table-body'
diff --git a/src/views/circle/page-circle-left.pug b/src/views/circle/page-circle-left.pug
index 5ecf22c6532f6d006cee2309b5c2aad9143942a0..afd075178a8b07efd550a498e91964504f727cb9 100644
--- a/src/views/circle/page-circle-left.pug
+++ b/src/views/circle/page-circle-left.pug
@@ -1,5 +1,10 @@
-#circle-left(hidden)
+#circle-left(hidden, data-view="circle-left")
   div.content-box__info.flex(style="padding: 15px")
 
-    p Tu as quitté ce cercle.
-    p Pour le rejoindre à nouveau, rends-toi dans le panneau <solid-link next="admin-circle-list">administration</solid-link> ou contacte un administrateur.
+    p(data-trans='circle.left.paragraphQuit')
+    p
+      span(data-trans='circle.left.paragraphJoin')
+      span &nbsp;
+      solid-link(next="admin-circle-list" data-trans='circle.left.admin')
+      span &nbsp;
+      span(data-trans='circle.left.paragraphContact')
\ No newline at end of file
diff --git a/src/views/circle/page-circle-profile.pug b/src/views/circle/page-circle-profile.pug
index 4bcfeeb8ff6d7458d10bab16bec94cc4e505f312..35f5f4804c447678d59bcc1f32bdec787f171bf5 100644
--- a/src/views/circle/page-circle-profile.pug
+++ b/src/views/circle/page-circle-profile.pug
@@ -2,7 +2,7 @@ solid-router(default-route='circle-profile', hidden)
   solid-route(name='circle-profile')
   solid-route(name='circle-edit')
 
-#circle-profile(hidden)
+#circle-profile(hidden, data-view="circle-profile")
 
   solid-widget(name='hubl-circle-team-contact')
     template 
@@ -24,15 +24,16 @@ solid-router(default-route='circle-profile', hidden)
 
         class-title='word-spacing-right'
 
-        value-title='Date de création : '
+        value-title=''
+        data-trans='value-title=circle.profile.creationDate'
 
         widget-creationDate='solid-display-value-date'
       )
       solid-ac-checker(permission='acl:Append', bind-resources, nested-field='members')
         solid-ac-checker(permission='acl:Delete', bind-resources)
-          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='circle-edit' bind-resources) Modifier et ajouter un membre
+          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='circle-edit' bind-resources data-trans='circle.profile.buttonModify')
         solid-ac-checker(no-permission='acl:Delete', bind-resources)
-          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='circle-edit' bind-resources) Ajouter un membre
+          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='circle-edit' bind-resources data-trans='circle.profile.buttonAdd')
 
 
     div.flex.desktop-button__end
@@ -40,7 +41,8 @@ solid-router(default-route='circle-profile', hidden)
         solid-delete(
           class='button mobile-full-width text-bold text-uppercase button-primary bordered with-icon icon-trash'
           bind-resources
-          data-label='Supprimer le cercle'
+          data-label=''
+          data-trans='data-label=circle.profile.buttonDelete'
           next='admin-circles'
         )
 
@@ -50,7 +52,8 @@ solid-router(default-route='circle-profile', hidden)
             solid-delete(
               class='button mobile-full-width desktop-btn-margin__left text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
               data-src="${src}"
-              data-label='Quitter le cercle'
+              data-label=''
+              data-trans='data-label=circle.profile.buttonQuit'
               next='circle-left'
             )
 
@@ -65,7 +68,8 @@ solid-router(default-route='circle-profile', hidden)
               value-user.username='hubl-workaround-493'
               widget-user.username='solid-form-hidden'
 
-              submit-button='Rejoindre le cercle'
+              submit-button=''
+              data-trans='submit-button=circle.profile.buttonJoin'
             )
 
       solid-display(
@@ -82,7 +86,7 @@ solid-router(default-route='circle-profile', hidden)
         hubl-inherit-user-id="search-value-user"
       )
 
-    h2 Membres :
+    h2(data-trans='circle.profile.subTitle')
 
     solid-widget(name='hubl-circle-user-admin')
       template ${value ? "Administrateur" : ""}
@@ -109,5 +113,5 @@ solid-router(default-route='circle-profile', hidden)
     )
 
 
-#circle-edit.content-box__height(hidden)
+#circle-edit.content-box__height(hidden, data-view="circle-edit")
   include page-circle-edit.pug
diff --git a/src/views/notifications/message-circle.pug b/src/views/notifications/message-circle.pug
index 239c6745fc71e804417b03430e3529472111f9de..e0136ff885669b5f2413c5b6bf2af2b4bfca7cee 100644
--- a/src/views/notifications/message-circle.pug
+++ b/src/views/notifications/message-circle.pug
@@ -4,7 +4,8 @@ solid-notifications-template(data-rdf-type='hd:circle')
       | ${await author['account.foaf:depiction'] ? `<img src="${await author['account.foaf:depiction']}" style="max-width:100%; max-height: 100%;" />` : `<object type="image/svg+xml" data="/images/alien.svg"></object>`}
     .solid-notification__content
       .solid-notification__title ${await author.name} 
-        span.solid-notification__title__side dans 
+        span.solid-notification__title__side
+          span(data-trans='notification.circle.in')
           span.solid-notification__title__icon ${(await object.status) == 'Public' ? '#' : 'î‚Ž'} 
           | ${await object.name}
       p.solid-notification__summary ${summary}
diff --git a/src/views/notifications/message-private.pug b/src/views/notifications/message-private.pug
index ee785d959006dc65fce4441057e60991da39d41c..9825d7469cdc99b305421d26cf7b40b74a66849c 100644
--- a/src/views/notifications/message-private.pug
+++ b/src/views/notifications/message-private.pug
@@ -4,5 +4,5 @@ solid-notifications-template(data-rdf-type='foaf:user')
       | ${await author['account.foaf:depiction'] ? `<img src="${await author['account.foaf:depiction']}" style="max-width:100%; max-height: 100%;" />` : `<object type="image/svg+xml" data="/images/alien.svg"></object>`}
     .solid-notification__content
       .solid-notification__title ${await author.name} 
-        span.solid-notification__title__side en privé
+        span.solid-notification__title__side(data-trans='notification.private.private')
       p.solid-notification__summary ${summary}
\ No newline at end of file
diff --git a/src/views/project/page-project-edit.pug b/src/views/project/page-project-edit.pug
index ec0593532acf40125c434d51304d5bafd5e0a0ed..f6498bca4e3a4fab8b984f435d4d3a2d60340fcc 100644
--- a/src/views/project/page-project-edit.pug
+++ b/src/views/project/page-project-edit.pug
@@ -8,13 +8,14 @@ div.content-box__info
         solid-delete(
           class='button text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
           data-src="${src}"
-          data-label='Retirer'
+          data-label=''
+          data-trans='data-label=project.edit.buttonDelete'
         )
 			
-  solid-link(class='backlink right', bind-resources, next='project-profile') Retour
+  solid-link(class='backlink right', bind-resources, next='project-profile' data-trans='project.edit.backlink')
 
   solid-ac-checker(permission='acl:Write', bind-resources)
-    h1 Modifie ton projet
+    h1(data-trans='project.edit.title')
 
     div#loader-project-edit.loader.loader-top
       div
@@ -29,20 +30,21 @@ div.content-box__info
       required-customer.name
       required-name
 
-
-      label-name='Nom du projet*'
+      label-name=''
       class-name='form-label is-light is-half-width input-text-like'
 
-      label-customer.name='Nom du client*'
+      label-customer.name=''
       class-customer.name='form-label is-light is-half-width input-text-like'
 
       partial=""
 
       submit-button='Enregistrer'
       next='project-information'
+      
+      data-trans='label-name=project.edit.labelName;label-customer.name=project.edit.labelCustomer;submit-button=project.edit.buttonSubmit'
     )
 
-  h2 Liste des membres :
+  h2(data-trans='project.edit.subTitle')
 
   solid-ac-checker(permission='acl:Append', bind-resources, nested-field='members')
     solid-form.block.select-add(
@@ -55,14 +57,15 @@ div.content-box__info
       label-user=''
       widget-user='solid-form-dropdown-autocompletion'
 
-      submit-button='Ajouter un membre'
+      submit-button=''
+      data-trans='submit-button=project.edit.buttonAddMember'
     )
 
   .table-wrapper
     .table
       div.table-header.grey-color
-        div.w280 Nom
-        div.w162 Accès
+        div.w280(data-trans='project.edit.tableHeader1')
+        div.w162(data-trans='project.edit.tableHeader2')
 
       //-class='table-body'
       solid-display(
diff --git a/src/views/project/page-project-left.pug b/src/views/project/page-project-left.pug
index baac3078dae35aaa1bb6deea5ee9e5f4a1b11278..c2022890b7f3ea82d26f955796a4946728cb2826 100644
--- a/src/views/project/page-project-left.pug
+++ b/src/views/project/page-project-left.pug
@@ -1,5 +1,10 @@
 #project-left
   div.content-box__info.flex(style="padding: 15px")
 
-    p Tu as quitté ce projet.
-    p Ceci est un projet privé. Pour le rejoindre, rends-toi dans le panneau <solid-link next="admin-project-list">administration</solid-link> et demande une invitation.
+    p(data-trans='circle.left.paragraphQuit')
+    p
+      span(data-trans='project.left.paragraphJoin')
+      span &nbsp;
+      solid-link(next="admin-project-list" data-trans='project.left.admin')
+      span &nbsp;
+      span(data-trans='project.left.paragraphContact')
diff --git a/src/views/project/page-project-picture.pug b/src/views/project/page-project-picture.pug
index 7bea1d90fba1073204e9dfbb7de6a55fb54b4fff..0de842c8fd13f8eefd0ecf38c09db416b3195ab6 100644
--- a/src/views/project/page-project-picture.pug
+++ b/src/views/project/page-project-picture.pug
@@ -1,8 +1,8 @@
 div.content-box__info
 			
-  solid-link(class='backlink right', bind-resources, next='project-edit') Retour
+  solid-link(class='backlink right', bind-resources, next='project-edit' data-trans='project.modifyPicture.backlink')
 
-  h1 Modifier l'image du projet
+  h1(data-trans='project.modifyPicture.title')
   
   solid-picture.project-edit-picture(
     bind-resources
diff --git a/src/views/project/page-project-profile.pug b/src/views/project/page-project-profile.pug
index bb1b7a76d3d2e801ccf9ae8f5692466ca7b543d6..fce9844e5a42d164b32d9846cf902319ee558d5c 100644
--- a/src/views/project/page-project-profile.pug
+++ b/src/views/project/page-project-profile.pug
@@ -2,7 +2,7 @@ solid-router(default-route='project-profile', hidden)
   solid-route(name='project-profile')
   solid-route(name='project-edit')
 
-#project-profile(hidden)
+#project-profile(hidden, data-view="project-profile")
   include ../../templates/hubl-captain.pug
 
   solid-widget(name='hubl-project-team-contact')
@@ -25,22 +25,24 @@ solid-router(default-route='project-profile', hidden)
 
         class-title='word-spacing-right'
 
-        value-title='Date de création : '
+        value-title=''
+        data-trans='value-title=project.profile.creationDate'
 
         widget-creationDate='solid-display-value-date'
       )
       solid-ac-checker(permission='acl:Append', bind-resources, nested-field='members')
         solid-ac-checker(permission='acl:Delete', bind-resources)
-          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='project-edit' bind-resources) Modifier et ajouter un membre
+          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='project-edit' bind-resources data-trans='project.profile.buttonModify')
         solid-ac-checker(no-permission='acl:Delete', bind-resources)
-          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='project-edit' bind-resources) Ajouter un membre
+          solid-link(class='button mobile-full-width text-bold text-uppercase reversed button-primary bordered with-icon icon-pencil' next='project-edit' bind-resources data-trans='project.profile.buttonAdd')
       
     div.flex.desktop-button__end
       solid-ac-checker(permission='acl:Delete', bind-resources)
         solid-delete(
           class='button mobile-full-width text-bold text-uppercase button-primary bordered with-icon icon-trash'
           bind-resources
-          data-label='Supprimer le projet'
+          data-label=''
+          data-trans='data-label=project.profile.buttonDelete'
           next='admin-projects'
         )
 
@@ -49,7 +51,8 @@ solid-router(default-route='project-profile', hidden)
           solid-delete(
             class='button mobile-full-width desktop-btn-margin__left text-bold text-uppercase reversed button-secondary bordered with-icon icon-close'
             data-src="${src}"
-            data-label='Quitter le projet'
+            data-label=''
+            data-trans='data-label=project.profile.buttonQuit'
             next='project-left'
           )
 
@@ -74,14 +77,15 @@ solid-router(default-route='project-profile', hidden)
         bind-resources
         fields='label-captain, captain'
 
-        value-label-captain='Capitaine :'
+        value-label-captain=''
+        data-trans='value-label-captain=project.profile.captain',
         class-label-captain='h2-like'
         widget-captain='hubl-captain'
       )
 
     br
 
-    h2 Equipe :
+    h2(data-trans:'project.profile.subTitle')
 
     solid-widget(name='hubl-project-user-admin')
       template ${value ? "Administrateur" : ""}
@@ -107,5 +111,5 @@ solid-router(default-route='project-profile', hidden)
       widget-is_admin='hubl-project-user-admin'
     )
 
-#project-edit.content-box__height(hidden)
+#project-edit.content-box__height(hidden, data-view="project-edit")
   include page-project-edit.pug