WuXinyu il y a 7 ans
Parent
commit
8409d55573

+ 1 - 1
mock/routes.js

@@ -1,7 +1,7 @@
 const express = require("express");
 const router = express.Router();
 
-router.use("/auth", require("./modules/auth"));
+router.use("/login", require("./modules/auth"));
 router.use("/user", require("./modules/user"));
 // router.use("/tag", require("./modules/tag"));
 // router.use("/doc", require("./modules/doc"));

+ 11 - 2
package.json

@@ -6,18 +6,25 @@
     "serve": "vue-cli-service serve",
     "build": "vue-cli-service build",
     "lint": "vue-cli-service lint",
+    "mock": "node mock/index.js",
     "test:e2e": "vue-cli-service test:e2e",
-    "test:unit": "vue-cli-service test:unit",
-    "mock": "node mock/index.js"
+    "test:unit": "vue-cli-service test:unit"
   },
   "dependencies": {
+    "buefy": "^0.7.1",
     "register-service-worker": "^1.5.2",
     "vue": "^2.5.17",
     "vue-router": "^3.0.1",
+    "vuelidate": "^0.7.4",
     "vuex": "^3.0.1",
     "whatwg-fetch": "^3.0.0"
   },
   "devDependencies": {
+    "@pollyjs/adapter-fetch": "^1.4.1",
+    "@pollyjs/adapter-xhr": "^1.4.1",
+    "@pollyjs/core": "^1.4.1",
+    "@pollyjs/persister-fs": "^1.4.1",
+    "@pollyjs/persister-local-storage": "^1.4.1",
     "@vue/cli-plugin-babel": "^3.2.0",
     "@vue/cli-plugin-e2e-nightwatch": "^3.2.0",
     "@vue/cli-plugin-eslint": "^3.2.0",
@@ -37,6 +44,8 @@
     "lint-staged": "^7.2.2",
     "node-sass": "^4.9.0",
     "sass-loader": "^7.0.1",
+    "setup-polly-jest": "^0.5.2",
+    "vue-cli-plugin-buefy": "^0.3.3",
     "vue-template-compiler": "^2.5.17",
     "winston": "^3.1.0"
   },

+ 1 - 0
public/index.html

@@ -5,6 +5,7 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <link rel="stylesheet" href="//cdn.materialdesignicons.com/2.0.46/css/materialdesignicons.min.css">
     <title>seec-frontend</title>
   </head>
   <body>

+ 20 - 19
src/App.vue

@@ -1,29 +1,30 @@
 <template>
   <div id="app">
-    <div id="nav">
-      <router-link to="/">Home</router-link> |
-      <router-link to="/about">About</router-link>
-    </div>
+    <!--<div id="nav">-->
+    <!--<router-link to="/">Home</router-link> |-->
+    <!--<router-link to="/about">About</router-link>-->
+    <!--</div>-->
     <router-view />
   </div>
 </template>
 
 <style lang="scss">
 #app {
-  font-family: "Avenir", Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
-}
-#nav {
-  padding: 30px;
-  a {
-    font-weight: bold;
-    color: #2c3e50;
-    &.router-link-exact-active {
-      color: #42b983;
-    }
-  }
+  /*font-family: "Avenir", Helvetica, Arial, sans-serif;*/
+  /*-webkit-font-smoothing: antialiased;*/
+  /*-moz-osx-font-smoothing: grayscale;*/
+  /*text-align: center;*/
+  /*color: #2c3e50;*/
+  background: #f4f7fb;
 }
+/*#nav {*/
+/*padding: 30px;*/
+/*a {*/
+/*font-weight: bold;*/
+/*color: #2c3e50;*/
+/*&.router-link-exact-active {*/
+/*color: #42b983;*/
+/*}*/
+/*}*/
+/*}*/
 </style>

+ 0 - 3
src/api/auth.js

@@ -1,9 +1,6 @@
 import request from "@/util/request";
 import { AUTH_MODULE } from "./_prefix";
 
-/**
- * @param {{username,password}} 登陆信息
- */
 /**
  * 登陆 login
  * @param {string} username

+ 152 - 0
src/assets/scss/_variables.scss

@@ -0,0 +1,152 @@
+// Included below are all the defined variables from Bulma
+// Modify as needed, removing the !default attribute.
+
+// Colors
+
+$black:        hsl(0, 0%, 4%) !default;
+$black-bis:    hsl(0, 0%, 7%) !default;
+$black-ter:    hsl(0, 0%, 14%) !default;
+
+$grey-darker:  hsl(0, 0%, 21%) !default;
+$grey-dark:    hsl(0, 0%, 29%) !default;
+$grey:         hsl(0, 0%, 48%) !default;
+$grey-light:   hsl(0, 0%, 71%) !default;
+$grey-lighter: hsl(0, 0%, 86%) !default;
+
+$white-ter:    hsl(0, 0%, 96%) !default;
+$white-bis:    hsl(0, 0%, 98%) !default;
+$white:        hsl(0, 0%, 100%) !default;
+
+$orange:       hsl(14,  100%, 53%) !default;
+$yellow:       hsl(48,  100%, 67%) !default;
+$green:        hsl(141, 71%,  48%) !default;
+$turquoise:    hsl(171, 100%, 41%) !default;
+$cyan:         hsl(204, 86%,  53%) !default;
+$blue:         hsl(217, 71%,  53%) !default;
+$purple:       hsl(271, 100%, 71%) !default;
+$red:          hsl(348, 100%, 61%) !default;
+
+// Typography
+
+$family-sans-serif: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !default;
+$family-monospace: monospace !default;
+$render-mode: optimizeLegibility !default;
+
+$size-1: 3rem !default;
+$size-2: 2.5rem !default;
+$size-3: 2rem !default;
+$size-4: 1.5rem !default;
+$size-5: 1.25rem !default;
+$size-6: 1rem !default;
+$size-7: 0.75rem !default;
+
+$weight-light: 300 !default;
+$weight-normal: 400 !default;
+$weight-medium: 500 !default;
+$weight-semibold: 600 !default;
+$weight-bold: 700 !default;
+
+// Responsiveness
+
+// The container horizontal gap, which acts as the offset for breakpoints
+$gap: 32px !default;
+// 960, 1152, and 1344 have been chosen because they are divisible by both 12 and 16
+$tablet: 769px !default;
+// 960px container + 4rem
+$desktop: 960px + (2 * $gap) !default;
+// 1152px container + 4rem
+$widescreen: 1152px + (2 * $gap) !default;
+// 1344px container + 4rem;
+$fullhd: 1344px + (2 * $gap) !default;
+
+// Miscellaneous
+
+$easing: ease-out !default;
+$radius-small: 2px !default;
+$radius: 3px !default;
+$radius-large: 5px !default;
+$radius-rounded: 290486px !default;
+$speed: 86ms !default;
+
+// Flags
+
+$variable-columns: true !default;
+
+
+// The default Bulma derived variables are declared below
+
+$primary: $turquoise !default;
+
+$info: $cyan !default;
+$success: $green !default;
+$warning: $yellow !default;
+$danger: $red !default;
+
+$light: $white-ter !default;
+$dark: $grey-darker !default;
+
+// Invert colors
+
+$orange-invert: findColorInvert($orange) !default;
+$yellow-invert: findColorInvert($yellow) !default;
+$green-invert: findColorInvert($green) !default;
+$turquoise-invert: findColorInvert($turquoise) !default;
+$cyan-invert: findColorInvert($cyan) !default;
+$blue-invert: findColorInvert($blue) !default;
+$purple-invert: findColorInvert($purple) !default;
+$red-invert: findColorInvert($red) !default;
+
+$primary-invert: $turquoise-invert !default;
+$info-invert: $cyan-invert !default;
+$success-invert: $green-invert !default;
+$warning-invert: $yellow-invert !default;
+$danger-invert: $red-invert !default;
+$light-invert: $dark !default;
+$dark-invert: $light !default;
+
+// General colors
+
+$background: $white-ter !default;
+
+$border: $grey-lighter !default;
+$border-hover: $grey-light !default;
+
+// Text colors
+
+$text: $grey-dark !default;
+$text-invert: findColorInvert($text) !default;
+$text-light: $grey !default;
+$text-strong: $grey-darker !default;
+
+// Code colors
+
+$code: $red !default;
+$code-background: $background !default;
+
+$pre: $text !default;
+$pre-background: $background !default;
+
+// Link colors
+
+$link: $blue !default;
+$link-invert: $blue-invert !default;
+$link-visited: $purple !default;
+
+$link-hover: $grey-darker !default;
+$link-hover-border: $grey-light !default;
+
+$link-focus: $grey-darker !default;
+$link-focus-border: $blue !default;
+
+$link-active: $grey-darker !default;
+$link-active-border: $grey-dark !default;
+
+// Typography
+
+$family-primary: $family-sans-serif !default;
+$family-code: $family-monospace !default;
+
+$size-small: $size-7 !default;
+$size-normal: $size-6 !default;
+$size-medium: $size-5 !default;
+$size-large: $size-4 !default;

+ 28 - 0
src/assets/scss/app.scss

@@ -0,0 +1,28 @@
+@import "~bulma/sass/utilities/initial-variables";
+@import "~bulma/sass/utilities/functions";
+// 1. Set your own initial variables and derived 
+//    variables in _variables.scss
+@import "variables";
+
+// 2. Setup your Custom Colors
+$linkedin: #0077b5;
+$linkedin-invert: findColorInvert($linkedin);
+$twitter: #55acee;
+$twitter-invert: findColorInvert($twitter);
+$github: #333;
+$github-invert: findColorInvert($github);
+
+@import "~bulma/sass/utilities/derived-variables";
+
+// 3. Add new color variables to the color map.
+$addColors: (
+  "twitter":($twitter, $twitter-invert),
+  "linkedin": ($linkedin, $linkedin-invert),
+  "github": ($github, $github-invert)
+);
+$colors: map-merge($colors, $addColors);
+
+@import "~bulma";
+@import "~buefy/src/scss/buefy";
+
+// 4. Provide custom buefy overrides and site styles here

+ 48 - 0
src/layouts/LoginLayout.vue

@@ -0,0 +1,48 @@
+<template>
+  <section class="main-body">
+    <section class="main-body-section">
+      <div class="logo">MOOC</div>
+      <div class="login_container">
+        <div class="container__main"><router-view /></div>
+      </div>
+    </section>
+    <footer class="footer is-transparent" style="background: #f4f7fb">
+      <div class="content has-text-centered">@nju software</div>
+    </footer>
+  </section>
+</template>
+
+<style lang="scss" scoped>
+.logo {
+  text-align: center;
+  padding: 20vh 0 0;
+  font-size: 40px;
+  /*<!--color: $logo-color;-->*/
+  /*<!--font-size: $logo-font-size;-->*/
+  /*<!--font-family: $logo-font-family;-->*/
+}
+.outer-container {
+  min-height: 100vh;
+}
+.login_container {
+  width: 100%;
+  .container__main {
+    max-width: 300px;
+    margin: 0 auto;
+    padding-bottom: 20px;
+  }
+}
+.author {
+  /*<!--color: $footer-color;-->*/
+  text-align: center;
+}
+.main-body {
+  min-height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background: #f4f7fb;
+  .main-body-section {
+    flex: 1;
+  }
+}
+</style>

+ 6 - 0
src/main.js

@@ -3,9 +3,15 @@ import App from "./App.vue";
 import router from "./router";
 import store from "./store";
 import "./registerServiceWorker";
+import Buefy from "buefy";
+import "./assets/scss/app.scss";
+import Vuelidate from "vuelidate";
 
 Vue.config.productionTip = false;
 
+Vue.use(Vuelidate);
+Vue.use(Buefy);
+
 new Vue({
   router,
   store,

+ 17 - 17
src/router/index.js

@@ -2,9 +2,9 @@ import Vue from "vue";
 import Router from "vue-router";
 import {
   LOGIN_ROUTER,
-  REGISTER_ROUTER,
-  HOME_ROUTER,
-  MIXER_ROUTER
+  // REGISTER_ROUTER,
+  HOME_ROUTER
+  // MIXER_ROUTER
 } from "@/router/name";
 
 Vue.use(Router);
@@ -15,19 +15,19 @@ const router = new Router({
   routes: [
     {
       path: "/login",
-      component: () => import("@/layout/LoginLayout"),
+      component: () => import("@/layouts/LoginLayout"),
       meta: { requiresAuth: false },
       children: [
-        {
-          name: REGISTER_ROUTER,
-          path: "/register",
-          component: () => import("@/views/Register"),
-          meta: { requiresAuth: false }
-        },
+        // {
+        //   name: REGISTER_ROUTER,
+        //   path: "/register",
+        //   component: () => import("@/views/Register"),
+        //   meta: { requiresAuth: false }
+        // },
         {
           name: LOGIN_ROUTER,
           path: "",
-          component: () => import("@/views/Login"),
+          component: () => import("@/views/login/Login.vue"),
           meta: { requiresAuth: false }
         }
       ]
@@ -37,13 +37,13 @@ const router = new Router({
       path: "/",
       component: () => import("@/views/Home"),
       meta: { requiresAuth: true }
-    },
-    {
-      name: MIXER_ROUTER,
-      path: "/mixer",
-      component: () => import("@/views/Mixer"),
-      meta: { requiresAuth: true }
     }
+    // {
+    //   name: MIXER_ROUTER,
+    //   path: "/mixer",
+    //   component: () => import("@/views/Mixer"),
+    //   meta: { requiresAuth: true }
+    // }
   ]
 });
 

+ 112 - 0
src/views/login/Login.vue

@@ -0,0 +1,112 @@
+<template>
+  <div>
+    <div class="intro">Sign in</div>
+    <b-field
+      label="Username"
+      :type="!$v.username.required ? 'is-danger' : ''"
+      :message="!$v.username.required ? 'username required' : ''"
+    >
+      <b-input v-model="username" placeholder="input username here"></b-input>
+    </b-field>
+
+    <b-field label="Password">
+      <b-input
+        type="password"
+        v-model="password"
+        placeholder="input password here"
+        password-reveal
+      >
+      </b-input>
+    </b-field>
+    <b-field>
+      <p class="control level" style="padding-top: 20px">
+        <button
+          style="width:40%"
+          :class="{ 'is-loading': submitting }"
+          class="button is-link"
+          @click="loginAction"
+        >
+          登 陆
+        </button>
+        <router-link
+          :to="{ name: 'register' }"
+          :class="{ 'is-text': true }"
+          class="button"
+          type="submit"
+          >没有账户,注册
+        </router-link>
+      </p>
+    </b-field>
+  </div>
+</template>
+
+<script>
+import { required } from "vuelidate/lib/validators";
+
+export default {
+  data() {
+    return {
+      username: "",
+      password: "",
+      submitting: false
+    };
+  },
+  validations: {
+    username: {
+      required
+    },
+    password: {
+      required
+    }
+  },
+  computed: {},
+  methods: {
+    loginAction() {
+      this.$router.push("");
+    }
+  }
+
+  // @State((state: RootState) => state.auth.isLoginError)
+  // public isLoginError: boolean;
+  // public mounted() {
+  //   this.$store.dispatch(LOGOUT);
+  //   Validator.extend("truthy", {
+  //     getMessage: (field: string): string => "两次输入的密码不相同",
+  //     validate: (value: string): boolean => value === this.credentials.password
+  //   });
+  // }
+  // public closeError() {
+  //   this.$store.commit(SET_LOGIN_ERROR, false);
+  // }
+  // public submit() {
+  //   this.$validator.validateAll().then(async result => {
+  //     if (result) {
+  //       this.submitting = true;
+  //       await this.$store.dispatch(LOGIN, this.credentials);
+  //       if (!this.isLoginError) {
+  //         this.$router.push({ name: "home" });
+  //       } else {
+  //         this.submitting = false;
+  //       }
+  //     }
+  //   });
+  // }
+};
+</script>
+
+<style lang="scss" scoped>
+.intro {
+  /*<!--color: $oc-gray-7;-->*/
+  text-align: center;
+  font-size: 25px;
+  padding: 10px 0 30px;
+}
+.link {
+  /*<!--color: $oc-blue-5;-->*/
+  text-decoration: none;
+}
+.action-section {
+  display: flex;
+  justify-content: space-between;
+}
+</style>

+ 15 - 0
tests/unit/api/polly.config.js

@@ -0,0 +1,15 @@
+import { Polly } from "@pollyjs/core";
+import FetchAdapter from "@pollyjs/adapter-fetch";
+import XHRAdapter from "@pollyjs/adapter-xhr";
+import LocalStoragePersister from "@pollyjs/persister-local-storage";
+
+Polly.register(FetchAdapter);
+Polly.register(XHRAdapter);
+Polly.register(LocalStoragePersister);
+
+export default Polly;
+
+export const pollyConfig = {
+  adapters: ["fetch", "xhr"],
+  persister: "local-storage"
+};

+ 22 - 0
tests/unit/api/user.spec.js

@@ -0,0 +1,22 @@
+import { setupPolly } from "setup-polly-jest";
+import "whatwg-fetch";
+const getPost = async id => {
+  const response = await fetch(`/posts/${id}`);
+
+  const json = await response.json();
+
+  return Object.assign(json, { ok: response.ok, status: response.status });
+};
+describe("user api test", () => {
+  let context = setupPolly({
+    /* default configuration options */
+  });
+
+  test("should have polly running with `test`", async () => {
+    const { server } = context.polly;
+    server.get("/posts/*path").intercept((req, res) => {
+      res.send(1);
+    });
+    expect(await getPost(1)).toHaveProperty("id", 1);
+  });
+});

+ 283 - 5
yarn.lock

@@ -671,6 +671,94 @@
   resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
   integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
 
+"@pollyjs/adapter-fetch@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/adapter-fetch/-/adapter-fetch-1.4.1.tgz#d1eecbe2fbb966ad92981ee3d2f40a3058def68d"
+  integrity sha512-1Jak8KityZjy7fSO+MzOng7AE0nAxK/xOs30cDWz7mQ+B/U5yLqgvpjfrj1NrxstgY8Ag/5H6etqimE8cHjskA==
+  dependencies:
+    "@pollyjs/adapter" "^1.4.1"
+    "@pollyjs/utils" "^1.4.1"
+    detect-node "^2.0.4"
+
+"@pollyjs/adapter-xhr@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/adapter-xhr/-/adapter-xhr-1.4.1.tgz#3a5e446960484ebd07bc863cdd4f23984c65fdd3"
+  integrity sha512-1pPf9jhoTmtebtNmSfNK4UwHEJGbncLc1pXsP7U5bSkry5KNc40thhusjSpy3rCwqUIMeEaMl93P0qYqrXS+jw==
+  dependencies:
+    "@pollyjs/adapter" "^1.4.1"
+    "@pollyjs/utils" "^1.4.1"
+    nise "^1.4.6"
+
+"@pollyjs/adapter@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/adapter/-/adapter-1.4.1.tgz#4bf58f5127620f004edfcb7f27b572ba0699aaee"
+  integrity sha512-1CFoFkoFhP/DLhCIbTLpyIKr1jlzHWBTzL2WerE1loWLrCvnI+rw7YYfz2wJxEH9fuF25QRg5P3L2Yrvw5l3ig==
+  dependencies:
+    "@pollyjs/utils" "^1.4.1"
+
+"@pollyjs/core@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/core/-/core-1.4.1.tgz#5037eba04fb7152648ddfb2e26d79ada752fc25d"
+  integrity sha512-uUp+e9FK8CAlXjgiXAFutvTAciWY9k2wddyCk73+TJybjZzzchL4QBrOQ1TYbs8DKVQoGfoRnBNypqDT2vOt+w==
+  dependencies:
+    "@pollyjs/utils" "^1.4.1"
+    "@sindresorhus/fnv1a" "^1.0.0"
+    blueimp-md5 "^2.10.0"
+    fast-json-stable-stringify "^2.0.0"
+    is-absolute-url "^2.1.0"
+    lodash-es "^4.17.11"
+    route-recognizer "^0.3.4"
+    slugify "^1.3.3"
+
+"@pollyjs/node-server@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/node-server/-/node-server-1.4.1.tgz#75c79bda3d37ff510d2e447dd2ef0f9fa25ffcd0"
+  integrity sha512-AeSjVzJshE6tQlH9DMfV3m4YQOs8whTTjLIQXlLUktSiZLqPdhYDK6I3nerMyOc1jkk80U8f61DhyqrGAG4fvQ==
+  dependencies:
+    "@pollyjs/utils" "^1.4.1"
+    body-parser "^1.18.3"
+    cors "^2.8.5"
+    express "^4.16.4"
+    fs-extra "^5.0.0"
+    http-graceful-shutdown "^2.1.3"
+    morgan "^1.9.1"
+    nocache "^2.0.0"
+
+"@pollyjs/persister-fs@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/persister-fs/-/persister-fs-1.4.1.tgz#ac927932bb4aab159c1eed76358931d95eda8e09"
+  integrity sha512-nFOFxXHiwNHpybQfEY72e6dhM5YMWIFsL9edtV1wp6kQfbv2NfAyvejyBPJ18pbMm+KEvfWRmEdn/qoJnVTJdQ==
+  dependencies:
+    "@pollyjs/node-server" "^1.4.1"
+    "@pollyjs/persister" "^1.4.1"
+
+"@pollyjs/persister-local-storage@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/persister-local-storage/-/persister-local-storage-1.4.1.tgz#7d60c07cb10a761c9491914e131e7f11096a75ec"
+  integrity sha512-LJzFR4iKhEj7Vd2Q4hgHsy74axYeFUs7vU2HCJKumfPjoeBBS5NJBUs3lJzPYdudAAenR3D1uT3XXAuAGfY4Hg==
+  dependencies:
+    "@pollyjs/persister" "^1.4.1"
+
+"@pollyjs/persister@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/persister/-/persister-1.4.1.tgz#12de9b582d0ba2154b0b293a0155ac50213a5fe3"
+  integrity sha512-jAeC9D6lrCaq3iKzQTg4gW/1XK9LeZJdzcltCK8jNcqtGEhjGddm5M+DDnTwuKWREXZvtUWBTEcpNvn7WbHbag==
+  dependencies:
+    "@pollyjs/utils" "^1.4.1"
+    bowser "^1.9.3"
+    fast-json-stable-stringify "^2.0.0"
+    lodash-es "^4.17.11"
+    set-cookie-parser "^2.2.1"
+    utf8-byte-length "^1.0.4"
+
+"@pollyjs/utils@^1.4.1":
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/@pollyjs/utils/-/utils-1.4.1.tgz#2cee4980ca9f27427cd62833e916ae28660e6652"
+  integrity sha512-UVIgsj50LBdWZfcUY+Yh0NU9sciLtUW75kqqgnPCagUYnYpsENiih1+C83zs4IcPR7kbuBht8z2EMxeD1tf+qg==
+  dependencies:
+    qs "^6.6.0"
+    url-parse "^1.4.4"
+
 "@samverschueren/stream-to-observable@^0.3.0":
   version "0.3.0"
   resolved "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
@@ -678,6 +766,34 @@
   dependencies:
     any-observable "^0.3.0"
 
+"@sindresorhus/fnv1a@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.npmjs.org/@sindresorhus/fnv1a/-/fnv1a-1.0.0.tgz#d419dd111b4d7fc3b87f97d86849bc23316149de"
+  integrity sha512-n+7NAD9vCDb2PaCRFIGrT2UF8WPIfMgGvCiVsYKY1/eBTrZU80N9erKhX9UTdxyvWhNuxQxwZGzdOIOlt8WqsA==
+
+"@sinonjs/commons@^1.0.2":
+  version "1.3.0"
+  resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz#50a2754016b6f30a994ceda6d9a0a8c36adda849"
+  integrity sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==
+  dependencies:
+    type-detect "4.0.8"
+
+"@sinonjs/formatio@^3.1.0":
+  version "3.1.0"
+  resolved "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz#6ac9d1eb1821984d84c4996726e45d1646d8cce5"
+  integrity sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==
+  dependencies:
+    "@sinonjs/samsam" "^2 || ^3"
+
+"@sinonjs/samsam@^2 || ^3":
+  version "3.0.2"
+  resolved "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.0.2.tgz#304fb33bd5585a0b2df8a4c801fcb47fa84d8e43"
+  integrity sha512-m08g4CS3J6lwRQk1pj1EO+KEVWbrbXsmi9Pw0ySmrIbcVxVaedoFgLvFsV8wHLwh01EpROVz3KvVcD1Jmks9FQ==
+  dependencies:
+    "@sinonjs/commons" "^1.0.2"
+    array-from "^2.1.1"
+    lodash.get "^4.4.2"
+
 "@types/node@^10.11.7":
   version "10.12.15"
   resolved "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz#20e85651b62fd86656e57c9c9bc771ab1570bc59"
@@ -1305,6 +1421,11 @@ array-flatten@^2.1.0:
   resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
   integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
 
+array-from@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195"
+  integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=
+
 array-map@~0.0.0:
   version "0.0.0"
   resolved "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
@@ -1712,6 +1833,13 @@ base@^0.11.1:
     mixin-deep "^1.2.0"
     pascalcase "^0.1.1"
 
+basic-auth@~2.0.0:
+  version "2.0.1"
+  resolved "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a"
+  integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==
+  dependencies:
+    safe-buffer "5.1.2"
+
 batch@0.6.1:
   version "0.6.1"
   resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
@@ -1756,6 +1884,11 @@ bluebird@^3.1.1, bluebird@^3.5.1:
   resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
   integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==
 
+blueimp-md5@^2.10.0:
+  version "2.10.0"
+  resolved "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.10.0.tgz#02f0843921f90dca14f5b8920a38593201d6964d"
+  integrity sha512-EkNUOi7tpV68TqjpiUz9D9NcT8um2+qtgntmMbi5UKssVX2m/2PLqotcric0RE63pB3HPN/fjf3cKHN2ufGSUQ==
+
 bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
   version "4.11.8"
   resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
@@ -1794,6 +1927,11 @@ boolbase@^1.0.0, boolbase@~1.0.0:
   resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
   integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
 
+bowser@^1.9.3:
+  version "1.9.4"
+  resolved "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a"
+  integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==
+
 brace-expansion@^1.0.0, brace-expansion@^1.1.7:
   version "1.1.11"
   resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1932,6 +2070,13 @@ bser@^2.0.0:
   dependencies:
     node-int64 "^0.4.0"
 
+buefy@^0.7.1:
+  version "0.7.1"
+  resolved "https://registry.npmjs.org/buefy/-/buefy-0.7.1.tgz#84ad090c4300b1e808db5e35d3e48fad76027d8c"
+  integrity sha512-Pq7T5ASuSjpBMFPQfnkDLCKtQxz8ciftTwYkzix7DMWvZHjtcZh1dF34ve8StjXqknEKYxFruCyioE3LdPmqqQ==
+  dependencies:
+    bulma "0.7.2"
+
 buffer-from@^1.0.0:
   version "1.1.1"
   resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -1966,6 +2111,11 @@ builtin-status-codes@^3.0.0:
   resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
   integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
 
+bulma@0.7.2:
+  version "0.7.2"
+  resolved "https://registry.npmjs.org/bulma/-/bulma-0.7.2.tgz#8e944377b74c7926558830d38d8e19eaf49f5fb6"
+  integrity sha512-6JHEu8U/1xsyOst/El5ImLcZIiE2JFXgvrz8GGWbnDLwTNRPJzdAM0aoUM1Ns0avALcVb6KZz9NhzmU53dGDcQ==
+
 bytes@3.0.0:
   version "3.0.0"
   resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -2610,6 +2760,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
   resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
   integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
 
+cors@^2.8.5:
+  version "2.8.5"
+  resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
+  integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
+  dependencies:
+    object-assign "^4"
+    vary "^1"
+
 cosmiconfig@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc"
@@ -3163,7 +3321,7 @@ detect-newline@^2.1.0:
   resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
   integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
 
-detect-node@^2.0.3:
+detect-node@^2.0.3, detect-node@^2.0.4:
   version "2.0.4"
   resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
   integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
@@ -4336,6 +4494,15 @@ fs-extra@^4.0.2:
     jsonfile "^4.0.0"
     universalify "^0.1.0"
 
+fs-extra@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd"
+  integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==
+  dependencies:
+    graceful-fs "^4.1.2"
+    jsonfile "^4.0.0"
+    universalify "^0.1.0"
+
 fs-extra@^7.0.1:
   version "7.0.1"
   resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
@@ -4870,6 +5037,13 @@ http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3:
     setprototypeof "1.1.0"
     statuses ">= 1.4.0 < 2"
 
+http-graceful-shutdown@^2.1.3:
+  version "2.2.1"
+  resolved "https://registry.npmjs.org/http-graceful-shutdown/-/http-graceful-shutdown-2.2.1.tgz#11b6d94ea9ed551f83b23ae77c27a3c12cad30f2"
+  integrity sha512-kQr5RsblW3UcYmLjPcDFt7bdon1qwvAtAInykesL+ALeURxHblGfBlFqK6XWnhzfsLonb3Gy6KeX2YGdm6dUfg==
+  dependencies:
+    debug "^4.1.0"
+
 http-parser-js@>=0.4.0:
   version "0.5.0"
   resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz#d65edbede84349d0dc30320815a15d39cc3cbbd8"
@@ -5161,7 +5335,7 @@ ipaddr.js@^1.5.2:
   resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.1.tgz#fa4b79fa47fd3def5e3b159825161c0a519c9427"
   integrity sha1-+kt5+kf9Pe9eOxWYJRYcClGclCc=
 
-is-absolute-url@^2.0.0:
+is-absolute-url@^2.0.0, is-absolute-url@^2.1.0:
   version "2.1.0"
   resolved "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
   integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=
@@ -6141,6 +6315,11 @@ jsprim@^1.2.2:
     json-schema "0.2.3"
     verror "1.10.0"
 
+just-extend@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc"
+  integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==
+
 killable@^1.0.0:
   version "1.0.1"
   resolved "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892"
@@ -6360,6 +6539,11 @@ locate-path@^3.0.0:
     p-locate "^3.0.0"
     path-exists "^3.0.0"
 
+lodash-es@^4.17.11:
+  version "4.17.11"
+  resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz#145ab4a7ac5c5e52a3531fb4f310255a152b4be0"
+  integrity sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q==
+
 lodash._arraycopy@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz#76e7b7c1f1fb92547374878a562ed06a3e50f6e1"
@@ -6485,6 +6669,11 @@ lodash.defaultsdeep@^4.6.0:
   resolved "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz#bec1024f85b1bd96cbea405b23c14ad6443a6f81"
   integrity sha1-vsECT4WxvZbL6kBbI8FK1kQ6b4E=
 
+lodash.get@^4.4.2:
+  version "4.4.2"
+  resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+  integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
+
 lodash.isarguments@^3.0.0:
   version "3.1.0"
   resolved "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
@@ -6613,6 +6802,11 @@ loglevel@^1.4.1:
   resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
   integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
 
+lolex@^2.3.2:
+  version "2.7.5"
+  resolved "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733"
+  integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==
+
 loose-envify@^1.0.0:
   version "1.4.0"
   resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -6995,6 +7189,17 @@ mocha-nightwatch@3.2.2:
     mkdirp "0.5.1"
     supports-color "3.1.2"
 
+morgan@^1.9.1:
+  version "1.9.1"
+  resolved "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59"
+  integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==
+  dependencies:
+    basic-auth "~2.0.0"
+    debug "2.6.9"
+    depd "~1.1.2"
+    on-finished "~2.3.0"
+    on-headers "~1.0.1"
+
 move-concurrently@^1.0.1:
   version "1.0.1"
   resolved "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -7112,6 +7317,17 @@ nightwatch@^0.9.21:
     proxy-agent "2.0.0"
     q "1.4.1"
 
+nise@^1.4.6:
+  version "1.4.8"
+  resolved "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz#ce91c31e86cf9b2c4cac49d7fcd7f56779bfd6b0"
+  integrity sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==
+  dependencies:
+    "@sinonjs/formatio" "^3.1.0"
+    just-extend "^4.0.2"
+    lolex "^2.3.2"
+    path-to-regexp "^1.7.0"
+    text-encoding "^0.6.4"
+
 no-case@^2.2.0:
   version "2.3.2"
   resolved "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
@@ -7119,6 +7335,11 @@ no-case@^2.2.0:
   dependencies:
     lower-case "^1.1.1"
 
+nocache@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz#202b48021a0c4cbde2df80de15a17443c8b43980"
+  integrity sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA=
+
 node-cache@^4.1.1:
   version "4.2.0"
   resolved "https://registry.npmjs.org/node-cache/-/node-cache-4.2.0.tgz#48ac796a874e762582692004a376d26dfa875811"
@@ -7371,7 +7592,7 @@ oauth-sign@~0.9.0:
   resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
   integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
 
-object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
+object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
   integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@@ -7800,6 +8021,13 @@ path-to-regexp@0.1.7:
   resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
   integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
 
+path-to-regexp@^1.7.0:
+  version "1.7.0"
+  resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
+  integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=
+  dependencies:
+    isarray "0.0.1"
+
 path-type@^1.0.0:
   version "1.1.0"
   resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
@@ -8448,6 +8676,11 @@ qs@6.5.2, qs@~6.5.2:
   resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
   integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
 
+qs@^6.6.0:
+  version "6.6.0"
+  resolved "https://registry.npmjs.org/qs/-/qs-6.6.0.tgz#a99c0f69a8d26bf7ef012f871cdabb0aee4424c2"
+  integrity sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA==
+
 querystring-es3@^0.2.0:
   version "0.2.1"
   resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@@ -8879,6 +9112,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
     hash-base "^3.0.0"
     inherits "^2.0.1"
 
+route-recognizer@^0.3.4:
+  version "0.3.4"
+  resolved "https://registry.npmjs.org/route-recognizer/-/route-recognizer-0.3.4.tgz#39ab1ffbce1c59e6d2bdca416f0932611e4f3ca3"
+  integrity sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g==
+
 rsvp@^3.3.3:
   version "3.6.2"
   resolved "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
@@ -9091,6 +9329,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0:
   resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
   integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
 
+set-cookie-parser@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.2.1.tgz#eae9e36c48667c9b385246ab6f450aade889aaf4"
+  integrity sha1-6unjbEhmfJs4Ukarb0UKreiJqvQ=
+
 set-value@^0.4.3:
   version "0.4.3"
   resolved "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1"
@@ -9121,6 +9364,11 @@ setprototypeof@1.1.0:
   resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
   integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
 
+setup-polly-jest@^0.5.2:
+  version "0.5.2"
+  resolved "https://registry.npmjs.org/setup-polly-jest/-/setup-polly-jest-0.5.2.tgz#f99aa7c5fde539a37187c651fb63de5c10f4814e"
+  integrity sha512-GmnzYGb21k01zY7IXmiz87spnpo1zN/zroexedAB3UIBE4lLKvDG4Y37wHn4PBiaO/MYjSuaihP5afoyaAdSeg==
+
 sha.js@^2.4.0, sha.js@^2.4.8:
   version "2.4.11"
   resolved "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
@@ -9218,6 +9466,11 @@ slice-ansi@2.0.0:
     astral-regex "^1.0.0"
     is-fullwidth-code-point "^2.0.0"
 
+slugify@^1.3.3:
+  version "1.3.4"
+  resolved "https://registry.npmjs.org/slugify/-/slugify-1.3.4.tgz#78d2792d7222b55cd9fc81fa018df99af779efeb"
+  integrity sha512-KP0ZYk5hJNBS8/eIjGkFDCzGQIoZ1mnfQRYS5WM3273z+fxGWXeN0fkwf2ebEweydv9tioZIHGZKoF21U07/nw==
+
 smart-buffer@^1.0.13:
   version "1.1.15"
   resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16"
@@ -9817,6 +10070,11 @@ test-exclude@^4.2.1:
     read-pkg-up "^1.0.1"
     require-main-filename "^1.0.1"
 
+text-encoding@^0.6.4:
+  version "0.6.4"
+  resolved "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
+  integrity sha1-45mpgiV6J22uQou5KEXLcb3CbRk=
+
 text-hex@1.0.x:
   version "1.0.0"
   resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
@@ -10041,6 +10299,11 @@ type-detect@0.1.1:
   resolved "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822"
   integrity sha1-C6XsKohWQORw6k6FBZcZANrFiCI=
 
+type-detect@4.0.8:
+  version "4.0.8"
+  resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
+  integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
+
 type-is@~1.6.16:
   version "1.6.16"
   resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
@@ -10173,7 +10436,7 @@ url-loader@^1.1.2:
     mime "^2.0.3"
     schema-utils "^1.0.0"
 
-url-parse@^1.4.3:
+url-parse@^1.4.3, url-parse@^1.4.4:
   version "1.4.4"
   resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8"
   integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==
@@ -10194,6 +10457,11 @@ use@^3.1.0:
   resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
   integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
 
+utf8-byte-length@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
+  integrity sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=
+
 util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@@ -10244,7 +10512,7 @@ validate-npm-package-license@^3.0.1:
     spdx-correct "^3.0.0"
     spdx-expression-parse "^3.0.0"
 
-vary@~1.1.2:
+vary@^1, vary@~1.1.2:
   version "1.1.2"
   resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
   integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
@@ -10270,6 +10538,11 @@ vm-browserify@0.0.4:
   dependencies:
     indexof "0.0.1"
 
+vue-cli-plugin-buefy@^0.3.3:
+  version "0.3.3"
+  resolved "https://registry.npmjs.org/vue-cli-plugin-buefy/-/vue-cli-plugin-buefy-0.3.3.tgz#497942f854d1a578d8f8021f57323865b4c53d38"
+  integrity sha512-ZYwNuMcT9a1MvD0/YwJOLoM+mWd8+sLIw9eJgrDLZ8dcwW51nOxPPkJRZIul7FUibjsZX0JGJ+1f8MSGUdbxaA==
+
 vue-eslint-parser@^2.0.3:
   version "2.0.3"
   resolved "http://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz#c268c96c6d94cfe3d938a5f7593959b0ca3360d1"
@@ -10357,6 +10630,11 @@ vue@^2.5.17:
   resolved "https://registry.npmjs.org/vue/-/vue-2.5.21.tgz#3d33dcd03bb813912ce894a8303ab553699c4a85"
   integrity sha512-Aejvyyfhn0zjVeLvXd70h4hrE4zZDx1wfZqia6ekkobLmUZ+vNFQer53B4fu0EjWBSiqApxPejzkO1Znt3joxQ==
 
+vuelidate@^0.7.4:
+  version "0.7.4"
+  resolved "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.4.tgz#5a0e54be09ac0192f1aa3387d74b92e0945bf8aa"
+  integrity sha512-QHZWYOL325Zo+2K7VBNEJTZ496Kd8Z31p85aQJFldKudUUGBmgw4zu4ghl4CyqPwjRCmqZ9lDdx4FSdMnu4fGg==
+
 vuex@^3.0.1:
   version "3.0.1"
   resolved "https://registry.npmjs.org/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2"