diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 02140c9273e757719d5e80e2a8830b1e1f6d82cf..582915984cf785abc6a165fe8acfc06348175af4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -30,7 +30,7 @@ frontend-build:
         - python3 ./generate_base_model.py 
         - npm run build
     artifacts:
-        expire_in: 1 days
+        expire_in: 7 days
         paths:
             - frontend/dist/
             - frontend/src/api-services.gen/
diff --git a/frontend/generate_base_model.py b/frontend/generate_base_model.py
index 77717f5dab6f8f9f0c0ec6d82f5c40ad2968d534..72340724429100e1643751910553bb3f79dc3574 100644
--- a/frontend/generate_base_model.py
+++ b/frontend/generate_base_model.py
@@ -1,14 +1,44 @@
+import json
+
 import requests
 import os
 
 AUTH = os.getenv('NETDB_AUTH')
-API_BASE_URL = "https://www-net-devel.scc.kit.edu/api/3.0"
+API_SCHEME = 'https'
+API_HOST = 'www-net-devel.scc.kit.edu'
+API_VERSION = '3.0'
+API_BASE_URL = f'/api/{API_VERSION}'
 BASE_DIR = 'src/api-services.gen/'
 
+SWAGGER_TARGET_FILE = 'public/api.json'
+
+swagger = {'swagger': '2.0',
+           'info': {
+               'description': """
+Die Schnittstelle WebAPI bietet IT-Betreuern am KIT die Möglichkeit, eigene, speziell zugeschnittene Anwendungsprogramme für die Pflege ihrer netzwerk-spezifischen Anwendungsdaten (wie z.B. DNS) aufzubauen.
+Die Schnittstelle setzt auf der Netzdatenbank des SCC (NetDB) auf und ist für eine vollautomatisierte Nutzung auf Basis des heutzutage üblichen textbasierten Datenaustauschformates JSON (JavaScript Object Notation) vorgesehen (s.a. http://de.wikipedia.org/wiki/JavaScript_Object_Notation).
+Sie ist über HTTPS erreichbar und kann dadurch mit jeder beliebigen HTTP-Programmbibliothek benutzt werden. Im Rahmen der implementierten Systeme (Anwendungsbereiche), Objekttypen und Funktionen lassen sich sämtliche Daten durch entsprechende Dienstanforderungen (Requests) sowohl ausgeben bzw. abfragen als auch manipulieren (im Standardfall Eintragen, Ändern, Löschen). Die konkreten, jeweils versionsspezifischen Informationen und Parameter zu diesen Systemen, Objekttypen und Funktionen sind nicht Bestandteil dieser Dokumentation, sondern über selbstdokumentierende Indexabfragen der WebAPI erreichbar.""",
+               'version': API_VERSION,
+               'title': 'SCC NETDB-API'},
+
+           'externalDocs': {
+               'description': 'Weitere Dokumentation',
+               'url': f'https://www-net-devel-doku.scc.kit.edu/webapi/{API_VERSION}/intro'
+           },
+           'host': '',
+           'basePath': API_BASE_URL,
+           # 'schemes': [API_SCHEME],
+           'tags': [],
+           'paths': []
+           }
+
 keyword_replacements = {'class': 'cls'}
 
 files = {}
-request = requests.get("{base}/wapi/function/list".format(base=API_BASE_URL), headers={'Authorization': AUTH})
+sess = requests.Session()
+sess.headers.update({'Authorization': AUTH})
+request = sess.get("{scheme}://{base_host}{base_url}/wapi/function/list".format(scheme=API_SCHEME, base_host=API_HOST,
+                                                                                base_url=API_BASE_URL))
 if not request.status_code == 200:
     print("Fail! Unexpected status_code", request.status_code)
     print("Is the NETDB_AUTH environment variable correct?")
@@ -38,7 +68,7 @@ export default {
         old_default = None
         new_default = None
         p_esc = p
-        for (unesc,esc) in keyword_replacements.items():
+        for (unesc, esc) in keyword_replacements.items():
             p_esc = p_esc.replace(unesc, esc)
         if 'old' in v:
             old_default = v['old']['dataDefault']
@@ -56,7 +86,7 @@ export default {
                 params_dict_old += '\'{p}\': {p_esc}_old, '.format(p=p, p_esc=p_esc)
             params_str += '{p_esc}_old={d}, '.format(p_esc=p_esc, p=p, d=old_default)
         if 'new' in v:
-            params_str += '{p}_new={d}, '.format(p=p,d=new_default)
+            params_str += '{p}_new={d}, '.format(p=p, d=new_default)
             params_dict_new += '\'{p}\': {p}_new, '.format(p=p)
 
     params_dict_new += '}'
@@ -94,10 +124,134 @@ export default {
         return Axios.get(`${{NETVSConfig.NETDB_API_BASE_URL}}/{fq_name_slash}`, cnf)
     }},
 """
-    f_handle.write(func_str.format(params_dict_old=params_dict_old, params_dict=params_dict, name=f['name'], params=params_str, fq_name_slash=f['fq_name'].replace('.', '/')))
+    f_handle.write(
+        func_str.format(params_dict_old=params_dict_old, params_dict=params_dict, name=f['name'], params=params_str,
+                        fq_name_slash=f['fq_name'].replace('.', '/')))
 
 for f in files.values():
     f.write("""}
 """)
     f.close()
 
+
+def generateParamters(f):
+    if not f['is_data_manipulating']:
+        return [
+            {
+                'name': p, 'description': d['description'],
+                'required': d['old']['isRequired'] if 'old' in d else d['new']['isRequired'],
+                'schema': {
+                    'type': d['dataType']['jsonName'],
+                    'default': d['old']['dataDefault'],
+                    'nullable': d['old']['isNullable'],
+                },
+                'in': 'query'
+            }
+            for p, d in f['parameters'].items()]
+    new_params = {
+        p: {
+            'type': d['dataType']['jsonName'],
+            'description': d['description'],
+            'required': d['new']['isRequired'],
+            'nullable': d['new']['isNullable'],
+            'default': d['new']['dataDefault']
+        }
+        for p, d in f['parameters'].items() if 'new' in d
+    }
+    old_params = {
+        p: {
+            'type': d['dataType']['jsonName'],
+            'description': d['description'],
+            'required': d['old']['isRequired'],
+            'nullable': d['old']['isNullable'],
+            'default': d['old']['dataDefault']
+        }
+        for p, d in f['parameters'].items() if 'old' in d
+    }
+    props = {}
+    if len(old_params) > 0:
+        props['old'] = {
+            'description': 'Alte Attribute zur einduetigen Identifizierung des Objekts',
+            'type': 'object',
+            'properties': old_params,
+        }
+    if len(new_params) > 0:
+        props['new'] = {
+            'description': 'Neue Angaben',
+            'type': 'object',
+            'properties': new_params,
+        }
+    return [{
+        'name': 'body',
+        'in': 'body',
+        'required': True,
+        'schema': {
+            'type': 'object',
+            'properties': props
+        }
+    }]
+
+
+systems = sess.get(
+    "{scheme}://{base_host}{base_url}/".format(scheme=API_SCHEME, base_host=API_HOST, base_url=API_BASE_URL))
+objects = sess.get(
+    "{scheme}://{base_host}{base_url}/wapi/object_type/list".format(scheme=API_SCHEME, base_host=API_HOST,
+                                                                    base_url=API_BASE_URL)).json()[0]
+
+swagger['tags'] = systems.json()[0]
+swagger['securityDefinitions'] = {'api_key': {'type': 'apiKey', 'name': 'Authorization', 'in': 'header'}}
+swagger['paths'] = {f"/{f['system']}/{f['object_type']}/{f['name']}":
+    {
+        'post' if f['is_data_manipulating'] else 'get': {
+            'parameters': generateParamters(f),
+            'produces': ['application/json'] if f['is_returning'] else [],
+            'tags': [f['system']],
+            'security': [{'api_key': []}],
+            'responses': {
+                200: {
+                    'description': 'Request erfolgreich',
+                    'schema': {
+                        'type': 'array',
+                        'items': {
+                            '$ref': '#/definitions/' + f['object_type']
+                        }
+                    } if f['is_returning'] else None
+                },
+                400: {
+                    'description': 'Eingabefehler',
+                },
+                401: {
+                    'description': 'Unautorisiert',
+                },
+                500: {
+                    'description': 'Interner Serverfehler',
+                },
+            }}}
+    for f in func_index
+}
+
+
+def renderDataType(d):
+    dat = {'type': d['dataType']['jsonName'],
+           'description': d['description']
+           }
+    if d['dataType']['apiName'] == 'text_array':
+        dat['items'] = {
+            'type': 'string'
+        }
+    return dat
+
+
+swagger['definitions'] = {o['name']:
+    {
+        'type': 'object',
+        'description': o['description'],
+        'properties': {
+            a: renderDataType(d)
+            for a, d in o['attributes'].items()
+        }
+    }
+    for o in objects
+}
+with open(SWAGGER_TARGET_FILE, 'w') as f:
+    f.write(json.dumps(swagger))
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 6ef5ea5bdfb12b3ade8c1ae82974af9e364b93f8..19e588539d75cdabb9c084b698def2fdb7e11bb3 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -760,7 +760,6 @@
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.2.0.tgz",
       "integrity": "sha512-kPfmKoRI8Hpo5ZJGACWyrc9Eq1j3ZIUpUAQT2yH045OuYpccFJ9kYA/eErwzOM2jeBG1sC8XX1nl1EArtuM8tg==",
-      "dev": true,
       "requires": {
         "core-js": "^2.5.7",
         "regenerator-runtime": "^0.12.0"
@@ -805,6 +804,11 @@
         "to-fast-properties": "^2.0.0"
       }
     },
+    "@braintree/sanitize-url": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-3.1.0.tgz",
+      "integrity": "sha512-GcIY79elgB+azP74j8vqkiXz8xLFfIzbQJdlwOPisgbKT00tviJQuEghOXSMVxJ00HoYJbGswr4kcllUc4xCcg=="
+    },
     "@fortawesome/fontawesome-common-types": {
       "version": "0.2.14",
       "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.14.tgz",
@@ -850,6 +854,19 @@
         "postcss": "^7.0.0"
       }
     },
+    "@kyleshockey/object-assign-deep": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/@kyleshockey/object-assign-deep/-/object-assign-deep-0.4.2.tgz",
+      "integrity": "sha1-hJAPDu/DcnmPR1G1JigwuCCJIuw="
+    },
+    "@kyleshockey/xml": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@kyleshockey/xml/-/xml-1.0.2.tgz",
+      "integrity": "sha512-iMo32MPLcI9cPxs3YL5kmKxKgDmkSZDCFEqIT5eRk7d/Ll8r4X3SwGYSigzALd6+RHWlFEmjL1QyaQ15xDZFlw==",
+      "requires": {
+        "stream": "^0.0.2"
+      }
+    },
     "@mrmlnc/readdir-enhanced": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@@ -867,25 +884,13 @@
       "dev": true
     },
     "@nuxt/opencollective": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.3.0.tgz",
-      "integrity": "sha512-Vf09BxCdj1iT2IRqVwX5snaY2WCTkvM0O4cWWSO1ThCFuc4if0Q/nNwAgCxRU0FeYHJ7DdyMUNSdswCLKlVqeg==",
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.2.1.tgz",
+      "integrity": "sha512-NP2VSUKRFGutbhWeKgIU0MnY4fmpH8UWxxwTJNPurCQ5BeWhOxp+Gp5ltO39P/Et/J2GYGb3+ALNqZJ+5cGBBw==",
       "requires": {
-        "chalk": "^2.4.2",
-        "consola": "^2.10.1",
-        "node-fetch": "^2.6.0"
-      },
-      "dependencies": {
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        }
+        "chalk": "^2.4.1",
+        "consola": "^2.3.0",
+        "node-fetch": "^2.3.0"
       }
     },
     "@soda/friendly-errors-webpack-plugin": {
@@ -982,6 +987,15 @@
       "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
       "dev": true
     },
+    "@types/react": {
+      "version": "16.4.6",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-16.4.6.tgz",
+      "integrity": "sha512-9LDZdhsuKSc+DjY65SjBkA958oBWcTWSVWAd2cD9XqKBjhGw1KzAkRhWRw2eIsXvaIE/TOTjjKMFVC+JA1iU4g==",
+      "optional": true,
+      "requires": {
+        "csstype": "^2.2.0"
+      }
+    },
     "@vue/babel-preset-app": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-3.2.2.tgz",
@@ -2163,7 +2177,6 @@
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
       "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "dev": true,
       "requires": {
         "sprintf-js": "~1.0.2"
       }
@@ -2238,6 +2251,11 @@
       "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
       "dev": true
     },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+    },
     "asn1": {
       "version": "0.2.4",
       "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
@@ -2333,6 +2351,14 @@
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
       "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
     },
+    "autolinker": {
+      "version": "0.28.1",
+      "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-0.28.1.tgz",
+      "integrity": "sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=",
+      "requires": {
+        "gulp-header": "^1.7.1"
+      }
+    },
     "autoprefixer": {
       "version": "9.5.1",
       "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.5.1.tgz",
@@ -2585,6 +2611,22 @@
         "esutils": "^2.0.2"
       }
     },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.11.1",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+          "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+        }
+      }
+    },
     "balanced-match": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -2643,8 +2685,7 @@
     "base64-js": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
-      "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
-      "dev": true
+      "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
     },
     "batch": {
       "version": "0.6.1",
@@ -2778,21 +2819,20 @@
       "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
     },
     "bootstrap-vue": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.1.0.tgz",
-      "integrity": "sha512-dftb5fc42x7QLv814nN+3Cx8MMuCB+xrGQjOmSXH81ET0+yo7KYb4lUN3/pOnf+8Tkv8oaawZ1OOth5/AZfktg==",
-      "requires": {
-        "@nuxt/opencollective": "^0.3.0",
-        "bootstrap": ">=4.3.1 <5.0.0",
-        "popper.js": "^1.16.0",
-        "portal-vue": "^2.1.6",
-        "vue-functional-data-merge": "^3.1.0"
+      "version": "2.0.0-rc.13",
+      "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.0.0-rc.13.tgz",
+      "integrity": "sha512-XKCHeb3vzdbw3tD7jMOBOA0YuK+1PZo2s5+Vl0uglZKKPIN0V9DljnUv+10xJve6yr88WX0sFWInYObRGFiC/Q==",
+      "requires": {
+        "@nuxt/opencollective": "^0.2.1",
+        "bootstrap": "^4.3.1",
+        "popper.js": "^1.14.7",
+        "vue-functional-data-merge": "^2.0.7"
       },
       "dependencies": {
-        "popper.js": {
-          "version": "1.16.0",
-          "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.0.tgz",
-          "integrity": "sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw=="
+        "bootstrap": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
+          "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
         }
       }
     },
@@ -2920,6 +2960,11 @@
         "node-releases": "^1.1.3"
       }
     },
+    "btoa": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.1.2.tgz",
+      "integrity": "sha1-PkC4FmP4HS3WWWpMtxSo3BbPq+A="
+    },
     "buffer": {
       "version": "4.9.1",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
@@ -3146,7 +3191,6 @@
       "version": "2.4.1",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
       "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
-      "dev": true,
       "requires": {
         "ansi-styles": "^3.2.1",
         "escape-string-regexp": "^1.0.5",
@@ -3243,6 +3287,11 @@
         }
       }
     },
+    "classnames": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
+      "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
+    },
     "clean-css": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
@@ -3493,6 +3542,21 @@
         "typedarray": "^0.0.6"
       }
     },
+    "concat-with-sourcemaps": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz",
+      "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==",
+      "requires": {
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        }
+      }
+    },
     "connect-history-api-fallback": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
@@ -3500,9 +3564,9 @@
       "dev": true
     },
     "consola": {
-      "version": "2.11.0",
-      "resolved": "https://registry.npmjs.org/consola/-/consola-2.11.0.tgz",
-      "integrity": "sha512-2bcAqHastlPSCvZ+ur8bgHInGAWvUnysWz3h3xRX+/XZoCY7avolJJnVXOPGoVoyCcg1b231XixonoArmgxaoA=="
+      "version": "2.5.6",
+      "resolved": "https://registry.npmjs.org/consola/-/consola-2.5.6.tgz",
+      "integrity": "sha512-DN0j6ewiNWkT09G3ZoyyzN3pSYrjxWcx49+mHu+oDI5dvW5vzmyuzYsqGS79+yQserH9ymJQbGzeqUejfssr8w=="
     },
     "console-browserify": {
       "version": "1.1.0",
@@ -3623,8 +3687,7 @@
     "core-js": {
       "version": "2.6.1",
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz",
-      "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==",
-      "dev": true
+      "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg=="
     },
     "core-util-is": {
       "version": "1.0.2",
@@ -3680,6 +3743,41 @@
         "sha.js": "^2.4.8"
       }
     },
+    "create-react-class": {
+      "version": "15.6.3",
+      "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
+      "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
+      "requires": {
+        "fbjs": "^0.8.9",
+        "loose-envify": "^1.3.1",
+        "object-assign": "^4.1.1"
+      }
+    },
+    "cross-fetch": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-0.0.8.tgz",
+      "integrity": "sha1-Ae2U3EB98sAPGAf95wCnz6SKIFw=",
+      "requires": {
+        "node-fetch": "1.7.3",
+        "whatwg-fetch": "2.0.3"
+      },
+      "dependencies": {
+        "node-fetch": {
+          "version": "1.7.3",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+          "requires": {
+            "encoding": "^0.1.11",
+            "is-stream": "^1.0.1"
+          }
+        },
+        "whatwg-fetch": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
+          "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
+        }
+      }
+    },
     "cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -3862,6 +3960,11 @@
       "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
       "dev": true
     },
+    "css.escape": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
+      "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s="
+    },
     "cssesc": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
@@ -3966,6 +4069,12 @@
         }
       }
     },
+    "csstype": {
+      "version": "2.6.7",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz",
+      "integrity": "sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ==",
+      "optional": true
+    },
     "current-script-polyfill": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/current-script-polyfill/-/current-script-polyfill-1.0.0.tgz",
@@ -4038,8 +4147,12 @@
     "deep-equal": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
-      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
-      "dev": true
+      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
+    },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
     },
     "deep-is": {
       "version": "0.1.3",
@@ -4301,6 +4414,11 @@
         "domelementtype": "1"
       }
     },
+    "dompurify": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.7.tgz",
+      "integrity": "sha512-S3O0lk6rFJtO01ZTzMollCOGg+WAtCwS3U5E2WSDY/x/sy7q70RjEC4Dmrih5/UqzLLB9XoKJ8KqwBxaNvBu4A=="
+    },
     "domutils": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
@@ -4398,6 +4516,11 @@
         "minimalistic-crypto-utils": "^1.0.0"
       }
     },
+    "emitter-component": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz",
+      "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY="
+    },
     "emoji-regex": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@@ -4409,12 +4532,25 @@
       "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
       "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k="
     },
+    "encode-3986": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/encode-3986/-/encode-3986-1.0.0.tgz",
+      "integrity": "sha1-lA1RSY+HQa3hhLda0UObMXwMemA="
+    },
     "encodeurl": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
       "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
       "dev": true
     },
+    "encoding": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+      "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+      "requires": {
+        "iconv-lite": "~0.4.13"
+      }
+    },
     "end-of-stream": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
@@ -4520,6 +4656,17 @@
         "ext": "^1.1.2"
       }
     },
+    "es6-weak-map": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+      "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.46",
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.1"
+      }
+    },
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -4834,8 +4981,7 @@
     "esprima": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
-      "dev": true
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
     },
     "esquery": {
       "version": "1.0.1",
@@ -4873,6 +5019,15 @@
       "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
       "dev": true
     },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+      "requires": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
     "event-pubsub": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz",
@@ -5172,6 +5327,14 @@
         "micromatch": "^3.1.10"
       }
     },
+    "fast-json-patch": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.1.0.tgz",
+      "integrity": "sha512-PipOsAKamRw7+CXtKiieehyjUeDVPJ5J7b2kdJYerEf6TSUQoD2ijpVyZ88KQm5YXziff4h762bz3+vzf56khg==",
+      "requires": {
+        "deep-equal": "^1.0.1"
+      }
+    },
     "fast-json-stable-stringify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@@ -5198,6 +5361,27 @@
         "websocket-driver": ">=0.5.1"
       }
     },
+    "fbjs": {
+      "version": "0.8.17",
+      "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
+      "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
+      "requires": {
+        "core-js": "^1.0.0",
+        "isomorphic-fetch": "^2.1.1",
+        "loose-envify": "^1.0.0",
+        "object-assign": "^4.1.0",
+        "promise": "^7.1.1",
+        "setimmediate": "^1.0.5",
+        "ua-parser-js": "^0.7.18"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "1.2.7",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
+        }
+      }
+    },
     "figgy-pudding": {
       "version": "3.5.1",
       "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
@@ -5486,7 +5670,8 @@
         "ansi-regex": {
           "version": "2.1.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -5507,12 +5692,14 @@
         "balanced-match": {
           "version": "1.0.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -5527,17 +5714,20 @@
         "code-point-at": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "console-control-strings": {
           "version": "1.1.0",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -5654,7 +5844,8 @@
         "inherits": {
           "version": "2.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
@@ -5666,6 +5857,7 @@
           "version": "1.0.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -5680,6 +5872,7 @@
           "version": "3.0.4",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
@@ -5687,12 +5880,14 @@
         "minimist": {
           "version": "0.0.8",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.3.5",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -5711,6 +5906,7 @@
           "version": "0.5.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -5791,7 +5987,8 @@
         "number-is-nan": {
           "version": "1.0.1",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -5803,6 +6000,7 @@
           "version": "1.4.0",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -5888,7 +6086,8 @@
         "safe-buffer": {
           "version": "5.1.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -5924,6 +6123,7 @@
           "version": "1.0.2",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -5943,6 +6143,7 @@
           "version": "3.0.1",
           "bundled": true,
           "dev": true,
+          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -5986,12 +6187,14 @@
         "wrappy": {
           "version": "1.0.2",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         },
         "yallist": {
           "version": "3.0.3",
           "bundled": true,
-          "dev": true
+          "dev": true,
+          "optional": true
         }
       }
     },
@@ -6206,6 +6409,16 @@
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
       "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
     },
+    "gulp-header": {
+      "version": "1.8.12",
+      "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz",
+      "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==",
+      "requires": {
+        "concat-with-sourcemaps": "*",
+        "lodash.template": "^4.4.0",
+        "through2": "^2.0.0"
+      }
+    },
     "gzip-size": {
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.0.tgz",
@@ -6397,6 +6610,14 @@
       "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==",
       "dev": true
     },
+    "hoist-non-react-statics": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+      "integrity": "sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw==",
+      "requires": {
+        "react-is": "^16.7.0"
+      }
+    },
     "homedir-polyfill": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
@@ -6607,7 +6828,6 @@
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
       "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "dev": true,
       "requires": {
         "safer-buffer": ">= 2.1.2 < 3"
       }
@@ -6630,8 +6850,7 @@
     "ieee754": {
       "version": "1.1.13",
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
-      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
-      "dev": true
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
     },
     "iferr": {
       "version": "0.1.5",
@@ -6645,6 +6864,11 @@
       "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
       "dev": true
     },
+    "immutable": {
+      "version": "3.8.2",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
+      "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM="
+    },
     "import-cwd": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
@@ -6855,7 +7079,6 @@
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
       "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
-      "dev": true,
       "requires": {
         "loose-envify": "^1.0.0"
       }
@@ -7011,6 +7234,15 @@
       "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
       "dev": true
     },
+    "is-dom": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-dom/-/is-dom-1.1.0.tgz",
+      "integrity": "sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==",
+      "requires": {
+        "is-object": "^1.0.1",
+        "is-window": "^1.0.2"
+      }
+    },
     "is-extendable": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -7066,6 +7298,11 @@
       "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
       "dev": true
     },
+    "is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA="
+    },
     "is-path-cwd": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.1.0.tgz",
@@ -7107,8 +7344,7 @@
     "is-promise": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
-      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
-      "dev": true
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
     },
     "is-regex": {
       "version": "1.0.4",
@@ -7128,8 +7364,7 @@
     "is-stream": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
     },
     "is-svg": {
       "version": "3.0.0",
@@ -7159,6 +7394,11 @@
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
       "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
     },
+    "is-window": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-window/-/is-window-1.0.2.tgz",
+      "integrity": "sha1-LIlspT25feRdPDMTOmXYyfVjSA0="
+    },
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -7194,6 +7434,54 @@
       "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
       "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
     },
+    "isomorphic-fetch": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+      "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+      "requires": {
+        "node-fetch": "^1.0.1",
+        "whatwg-fetch": ">=0.10.0"
+      },
+      "dependencies": {
+        "node-fetch": {
+          "version": "1.7.3",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+          "requires": {
+            "encoding": "^0.1.11",
+            "is-stream": "^1.0.1"
+          }
+        }
+      }
+    },
+    "isomorphic-form-data": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isomorphic-form-data/-/isomorphic-form-data-0.0.1.tgz",
+      "integrity": "sha1-Am9ifgMrDNhBPsyHVZKLlKRosGI=",
+      "requires": {
+        "form-data": "^1.0.0-rc3"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.3",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+          "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+          "requires": {
+            "lodash": "^4.17.14"
+          }
+        },
+        "form-data": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz",
+          "integrity": "sha1-rjFduaSQf6BlUCMEpm13M0de43w=",
+          "requires": {
+            "async": "^2.0.1",
+            "combined-stream": "^1.0.5",
+            "mime-types": "^2.1.11"
+          }
+        }
+      }
+    },
     "isstream": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@@ -7221,6 +7509,11 @@
       "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
       "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw=="
     },
+    "js-file-download": {
+      "version": "0.4.8",
+      "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.8.tgz",
+      "integrity": "sha512-8xygX/IkjQbr/2nWqJnyc0IWOMvA1R/78HQVyexB22YZDBAEz2MG59s+ieLFKOkDFzyDDk3bezKXEjyGW5HPCw=="
+    },
     "js-levenshtein": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.4.tgz",
@@ -7245,14 +7538,12 @@
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
     },
     "js-yaml": {
       "version": "3.13.1",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
       "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
-      "dev": true,
       "requires": {
         "argparse": "^1.0.7",
         "esprima": "^4.0.0"
@@ -7505,6 +7796,16 @@
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
       "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
     },
+    "lodash-es": {
+      "version": "4.17.15",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
+      "integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
+    },
+    "lodash._reinterpolate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
+      "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0="
+    },
     "lodash.assign": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
@@ -7515,6 +7816,11 @@
       "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
       "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
     },
+    "lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
+    },
     "lodash.defaultsdeep": {
       "version": "4.6.1",
       "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
@@ -7543,6 +7849,23 @@
       "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
       "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ="
     },
+    "lodash.template": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
+      "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
+      "requires": {
+        "lodash._reinterpolate": "^3.0.0",
+        "lodash.templatesettings": "^4.0.0"
+      }
+    },
+    "lodash.templatesettings": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
+      "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
+      "requires": {
+        "lodash._reinterpolate": "^3.0.0"
+      }
+    },
     "lodash.transform": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz",
@@ -7574,7 +7897,6 @@
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
       "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
-      "dev": true,
       "requires": {
         "js-tokens": "^3.0.0 || ^4.0.0"
       }
@@ -7603,6 +7925,14 @@
         "yallist": "^3.0.2"
       }
     },
+    "lru-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+      "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
+      "requires": {
+        "es5-ext": "~0.10.2"
+      }
+    },
     "make-dir": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
@@ -7673,6 +8003,21 @@
         "p-is-promise": "^1.1.0"
       }
     },
+    "memoizee": {
+      "version": "0.4.14",
+      "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz",
+      "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==",
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.45",
+        "es6-weak-map": "^2.0.2",
+        "event-emitter": "^0.3.5",
+        "is-promise": "^2.1",
+        "lru-queue": "0.1",
+        "next-tick": "1",
+        "timers-ext": "^0.1.5"
+      }
+    },
     "memory-fs": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@@ -7927,19 +8272,6 @@
         }
       }
     },
-    "moment": {
-      "version": "2.24.0",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
-      "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
-    },
-    "moment-range": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/moment-range/-/moment-range-4.0.2.tgz",
-      "integrity": "sha512-n8sceWwSTjmz++nFHzeNEUsYtDqjgXgcOBzsHi+BoXQU2FW+eU92LUaK8gqOiSu5PG57Q9sYj1Fz4LRDj4FtKA==",
-      "requires": {
-        "es6-symbol": "^3.1.0"
-      }
-    },
     "move-concurrently": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -8054,9 +8386,9 @@
       }
     },
     "node-fetch": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
-      "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz",
+      "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA=="
     },
     "node-forge": {
       "version": "0.7.5",
@@ -8273,9 +8605,9 @@
       "dev": true
     },
     "npm": {
-      "version": "6.12.0",
-      "resolved": "https://registry.npmjs.org/npm/-/npm-6.12.0.tgz",
-      "integrity": "sha512-juj5VkB3/k+PWbJUnXD7A/8oc8zLusDnK/sV9PybSalsbOVOTIp5vSE0rz5rQ7BsmUgQS47f/L2GYQnWXaKgnQ==",
+      "version": "6.13.2",
+      "resolved": "https://registry.npmjs.org/npm/-/npm-6.13.2.tgz",
+      "integrity": "sha512-TG7AFkKpjBNJh8OVJYcGaAbW0PZxEkjew51Lc6TRdhQpNjSSEnAOEpidApqEuciB7cs09C8mxbo8NbuPs4QDzg==",
       "requires": {
         "JSONStream": "^1.3.5",
         "abbrev": "~1.1.1",
@@ -8288,7 +8620,7 @@
         "byte-size": "^5.0.1",
         "cacache": "^12.0.3",
         "call-limit": "^1.1.1",
-        "chownr": "^1.1.2",
+        "chownr": "^1.1.3",
         "ci-info": "^2.0.0",
         "cli-columns": "^3.1.2",
         "cli-table3": "^0.5.1",
@@ -8306,7 +8638,7 @@
         "fs-write-stream-atomic": "~1.0.10",
         "gentle-fs": "^2.2.1",
         "glob": "^7.1.4",
-        "graceful-fs": "^4.2.2",
+        "graceful-fs": "^4.2.3",
         "has-unicode": "~2.0.1",
         "hosted-git-info": "^2.8.5",
         "iferr": "^1.0.2",
@@ -8319,7 +8651,7 @@
         "is-cidr": "^3.0.0",
         "json-parse-better-errors": "^1.0.2",
         "lazy-property": "~1.0.0",
-        "libcipm": "^4.0.4",
+        "libcipm": "^4.0.7",
         "libnpm": "^3.0.1",
         "libnpmaccess": "^3.0.2",
         "libnpmhook": "^5.0.3",
@@ -8353,23 +8685,23 @@
         "npm-install-checks": "^3.0.2",
         "npm-lifecycle": "^3.1.4",
         "npm-package-arg": "^6.1.1",
-        "npm-packlist": "^1.4.4",
+        "npm-packlist": "^1.4.6",
         "npm-pick-manifest": "^3.0.2",
         "npm-profile": "^4.0.2",
-        "npm-registry-fetch": "^4.0.0",
+        "npm-registry-fetch": "^4.0.2",
         "npm-user-validate": "~1.0.0",
         "npmlog": "~4.1.2",
         "once": "~1.4.0",
         "opener": "^1.5.1",
         "osenv": "^0.1.5",
-        "pacote": "^9.5.8",
+        "pacote": "^9.5.9",
         "path-is-inside": "~1.0.2",
         "promise-inflight": "~1.0.1",
         "qrcode-terminal": "^0.12.0",
         "query-string": "^6.8.2",
         "qw": "~1.0.1",
         "read": "~1.0.7",
-        "read-cmd-shim": "^1.0.4",
+        "read-cmd-shim": "^1.0.5",
         "read-installed": "~4.0.3",
         "read-package-json": "^2.1.0",
         "read-package-tree": "^5.3.1",
@@ -8386,7 +8718,7 @@
         "sorted-union-stream": "~2.1.3",
         "ssri": "^6.0.1",
         "stringify-package": "^1.0.1",
-        "tar": "^4.4.12",
+        "tar": "^4.4.13",
         "text-table": "~0.2.0",
         "tiny-relative-date": "^1.3.0",
         "uid-number": "0.0.6",
@@ -8394,7 +8726,7 @@
         "unique-filename": "^1.1.1",
         "unpipe": "~1.0.0",
         "update-notifier": "^2.5.0",
-        "uuid": "^3.3.2",
+        "uuid": "^3.3.3",
         "validate-npm-package-license": "^3.0.4",
         "validate-npm-package-name": "~3.0.0",
         "which": "^1.3.1",
@@ -8640,7 +8972,7 @@
           }
         },
         "chownr": {
-          "version": "1.1.2",
+          "version": "1.1.3",
           "bundled": true
         },
         "ci-info": {
@@ -9201,7 +9533,7 @@
           },
           "dependencies": {
             "minipass": {
-              "version": "2.8.6",
+              "version": "2.9.0",
               "bundled": true,
               "requires": {
                 "safe-buffer": "^5.1.2",
@@ -9383,7 +9715,7 @@
           }
         },
         "graceful-fs": {
-          "version": "4.2.2",
+          "version": "4.2.3",
           "bundled": true
         },
         "har-schema": {
@@ -9443,7 +9775,7 @@
           }
         },
         "https-proxy-agent": {
-          "version": "2.2.2",
+          "version": "2.2.4",
           "bundled": true,
           "requires": {
             "agent-base": "^4.3.0",
@@ -9469,7 +9801,7 @@
           "bundled": true
         },
         "ignore-walk": {
-          "version": "3.0.1",
+          "version": "3.0.3",
           "bundled": true,
           "requires": {
             "minimatch": "^3.0.4"
@@ -9683,7 +10015,7 @@
           }
         },
         "libcipm": {
-          "version": "4.0.4",
+          "version": "4.0.7",
           "bundled": true,
           "requires": {
             "bin-links": "^1.1.2",
@@ -9952,14 +10284,14 @@
           }
         },
         "make-fetch-happen": {
-          "version": "5.0.0",
+          "version": "5.0.2",
           "bundled": true,
           "requires": {
             "agentkeepalive": "^3.4.1",
             "cacache": "^12.0.0",
             "http-cache-semantics": "^3.8.1",
             "http-proxy-agent": "^2.1.0",
-            "https-proxy-agent": "^2.2.1",
+            "https-proxy-agent": "^2.2.3",
             "lru-cache": "^5.1.1",
             "mississippi": "^3.0.0",
             "node-fetch-npm": "^2.0.2",
@@ -10005,27 +10337,23 @@
           "version": "0.0.8",
           "bundled": true
         },
-        "minipass": {
-          "version": "2.3.3",
+        "minizlib": {
+          "version": "1.3.3",
           "bundled": true,
           "requires": {
-            "safe-buffer": "^5.1.2",
-            "yallist": "^3.0.0"
+            "minipass": "^2.9.0"
           },
           "dependencies": {
-            "yallist": {
-              "version": "3.0.2",
-              "bundled": true
+            "minipass": {
+              "version": "2.9.0",
+              "bundled": true,
+              "requires": {
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.0"
+              }
             }
           }
         },
-        "minizlib": {
-          "version": "1.2.2",
-          "bundled": true,
-          "requires": {
-            "minipass": "^2.2.1"
-          }
-        },
         "mississippi": {
           "version": "3.0.0",
           "bundled": true,
@@ -10193,7 +10521,7 @@
           }
         },
         "npm-packlist": {
-          "version": "1.4.4",
+          "version": "1.4.6",
           "bundled": true,
           "requires": {
             "ignore-walk": "^3.0.1",
@@ -10219,7 +10547,7 @@
           }
         },
         "npm-registry-fetch": {
-          "version": "4.0.0",
+          "version": "4.0.2",
           "bundled": true,
           "requires": {
             "JSONStream": "^1.3.4",
@@ -10227,7 +10555,14 @@
             "figgy-pudding": "^3.4.1",
             "lru-cache": "^5.1.1",
             "make-fetch-happen": "^5.0.0",
-            "npm-package-arg": "^6.1.0"
+            "npm-package-arg": "^6.1.0",
+            "safe-buffer": "^5.2.0"
+          },
+          "dependencies": {
+            "safe-buffer": {
+              "version": "5.2.0",
+              "bundled": true
+            }
           }
         },
         "npm-run-path": {
@@ -10344,7 +10679,7 @@
           }
         },
         "pacote": {
-          "version": "9.5.8",
+          "version": "9.5.9",
           "bundled": true,
           "requires": {
             "bluebird": "^3.5.3",
@@ -10379,7 +10714,7 @@
           },
           "dependencies": {
             "minipass": {
-              "version": "2.3.5",
+              "version": "2.9.0",
               "bundled": true,
               "requires": {
                 "safe-buffer": "^5.1.2",
@@ -10579,7 +10914,7 @@
           }
         },
         "read-cmd-shim": {
-          "version": "1.0.4",
+          "version": "1.0.5",
           "bundled": true,
           "requires": {
             "graceful-fs": "^4.1.2"
@@ -10768,15 +11103,15 @@
           "bundled": true
         },
         "smart-buffer": {
-          "version": "4.0.2",
+          "version": "4.1.0",
           "bundled": true
         },
         "socks": {
-          "version": "2.3.2",
+          "version": "2.3.3",
           "bundled": true,
           "requires": {
-            "ip": "^1.1.5",
-            "smart-buffer": "4.0.2"
+            "ip": "1.1.5",
+            "smart-buffer": "^4.1.0"
           }
         },
         "socks-proxy-agent": {
@@ -10991,7 +11326,7 @@
           }
         },
         "tar": {
-          "version": "4.4.12",
+          "version": "4.4.13",
           "bundled": true,
           "requires": {
             "chownr": "^1.1.1",
@@ -11004,7 +11339,7 @@
           },
           "dependencies": {
             "minipass": {
-              "version": "2.8.6",
+              "version": "2.9.0",
               "bundled": true,
               "requires": {
                 "safe-buffer": "^5.1.2",
@@ -11166,7 +11501,7 @@
           }
         },
         "uuid": {
-          "version": "3.3.2",
+          "version": "3.3.3",
           "bundled": true
         },
         "validate-npm-package-license": {
@@ -11823,11 +12158,6 @@
       "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz",
       "integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ=="
     },
-    "portal-vue": {
-      "version": "2.1.6",
-      "resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.6.tgz",
-      "integrity": "sha512-lvCF85D4e8whd0nN32D8FqKwwkk7nYUI3Ku8UAEx4Z1reomu75dv5evRUTZNaj1EalxxWNXiNl0EHRq36fG8WA=="
-    },
     "portfinder": {
       "version": "1.0.20",
       "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz",
@@ -12352,12 +12682,30 @@
       "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
       "dev": true
     },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "requires": {
+        "asap": "~2.0.3"
+      }
+    },
     "promise-inflight": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
       "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
       "dev": true
     },
+    "prop-types": {
+      "version": "15.7.2",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+      "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+      "requires": {
+        "loose-envify": "^1.4.0",
+        "object-assign": "^4.1.1",
+        "react-is": "^16.8.1"
+      }
+    },
     "proxy-addr": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
@@ -12461,8 +12809,12 @@
     "querystring": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
-      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
-      "dev": true
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+    },
+    "querystring-browser": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/querystring-browser/-/querystring-browser-1.0.4.tgz",
+      "integrity": "sha1-8uNYgYQKgZvHsb9Zf68JeeZiLcY="
     },
     "querystring-es3": {
       "version": "0.2.1",
@@ -12473,14 +12825,20 @@
     "querystringify": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
-      "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
-      "dev": true
+      "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
+    },
+    "raf": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
+      "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
+      "requires": {
+        "performance-now": "^2.1.0"
+      }
     },
     "randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
       "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
-      "dev": true,
       "requires": {
         "safe-buffer": "^5.1.0"
       }
@@ -12513,6 +12871,96 @@
         "unpipe": "1.0.0"
       }
     },
+    "react": {
+      "version": "15.6.2",
+      "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz",
+      "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=",
+      "requires": {
+        "create-react-class": "^15.6.0",
+        "fbjs": "^0.8.9",
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.0",
+        "prop-types": "^15.5.10"
+      }
+    },
+    "react-debounce-input": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.2.2.tgz",
+      "integrity": "sha512-RIBu68Cq/gImKz/2h1cE042REDqyqj3D+7SJ3lnnIpJX0ht9D9PfH7KAnL+SgDz6hvKa9pZS2CnAxlkrLmnQlg==",
+      "requires": {
+        "lodash.debounce": "^4",
+        "prop-types": "^15.7.2"
+      }
+    },
+    "react-dom": {
+      "version": "15.6.2",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz",
+      "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=",
+      "requires": {
+        "fbjs": "^0.8.9",
+        "loose-envify": "^1.1.0",
+        "object-assign": "^4.1.0",
+        "prop-types": "^15.5.10"
+      }
+    },
+    "react-immutable-proptypes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz",
+      "integrity": "sha1-Aj1vObsVyXwHHp5g0A0TbqxfoLQ="
+    },
+    "react-immutable-pure-component": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-1.2.3.tgz",
+      "integrity": "sha512-kNy2A/fDrSuR8TKwB+4ynmItmp1vgF87tWxxfmadwDYo2J3ANipHqTjDIBvJvJ7libvuh76jIbvmK0krjtKH1g==",
+      "requires": {
+        "@types/react": "16.4.6"
+      }
+    },
+    "react-inspector": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-2.3.1.tgz",
+      "integrity": "sha512-tUUK7t3KWgZEIUktOYko5Ic/oYwvjEvQUFAGC1UeMeDaQ5za2yZFtItJa2RTwBJB//NxPr000WQK6sEbqC6y0Q==",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "is-dom": "^1.0.9",
+        "prop-types": "^15.6.1"
+      }
+    },
+    "react-is": {
+      "version": "16.12.0",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
+      "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q=="
+    },
+    "react-motion": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.5.2.tgz",
+      "integrity": "sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==",
+      "requires": {
+        "performance-now": "^0.2.0",
+        "prop-types": "^15.5.8",
+        "raf": "^3.1.0"
+      },
+      "dependencies": {
+        "performance-now": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+          "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU="
+        }
+      }
+    },
+    "react-redux": {
+      "version": "4.4.10",
+      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-4.4.10.tgz",
+      "integrity": "sha512-tjL0Bmpkj75Td0k+lXlF8Fc8a9GuXFv/3ahUOCXExWs/jhsKiQeTffdH0j5byejCGCRL4tvGFYlrwBF1X/Aujg==",
+      "requires": {
+        "create-react-class": "^15.5.1",
+        "hoist-non-react-statics": "^3.3.0",
+        "invariant": "^2.0.0",
+        "lodash": "^4.17.11",
+        "loose-envify": "^1.4.0",
+        "prop-types": "^15.7.2"
+      }
+    },
     "read-pkg": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.1.1.tgz",
@@ -12645,6 +13093,25 @@
         }
       }
     },
+    "redux": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz",
+      "integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==",
+      "requires": {
+        "lodash": "^4.2.1",
+        "lodash-es": "^4.2.1",
+        "loose-envify": "^1.1.0",
+        "symbol-observable": "^1.0.3"
+      }
+    },
+    "redux-immutable": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-3.1.0.tgz",
+      "integrity": "sha1-yvvWhuBxEmERm5wolgk13EeknQo=",
+      "requires": {
+        "immutable": "^3.8.1"
+      }
+    },
     "regenerate": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
@@ -12663,8 +13130,7 @@
     "regenerator-runtime": {
       "version": "0.12.1",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
-      "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==",
-      "dev": true
+      "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg=="
     },
     "regenerator-transform": {
       "version": "0.13.3",
@@ -12733,6 +13199,15 @@
       "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
       "dev": true
     },
+    "remarkable": {
+      "version": "1.7.4",
+      "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz",
+      "integrity": "sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==",
+      "requires": {
+        "argparse": "^1.0.10",
+        "autolinker": "~0.28.0"
+      }
+    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -12887,6 +13362,11 @@
       "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
       "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
     },
+    "reselect": {
+      "version": "2.5.4",
+      "resolved": "https://registry.npmjs.org/reselect/-/reselect-2.5.4.tgz",
+      "integrity": "sha1-t9I/3wC4P6etAnlUb427vXZccEc="
+    },
     "resolve": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz",
@@ -13290,6 +13770,11 @@
         }
       }
     },
+    "serialize-error": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
+      "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go="
+    },
     "serialize-javascript": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz",
@@ -13387,8 +13872,7 @@
     "setimmediate": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
-      "dev": true
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
     },
     "setprototypeof": {
       "version": "1.1.1",
@@ -13400,7 +13884,6 @@
       "version": "2.4.11",
       "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
       "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.1",
         "safe-buffer": "^5.0.1"
@@ -13775,8 +14258,7 @@
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-      "dev": true
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
     },
     "sshpk": {
       "version": "1.16.0",
@@ -13854,6 +14336,14 @@
       "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
       "dev": true
     },
+    "stream": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz",
+      "integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=",
+      "requires": {
+        "emitter-component": "^1.1.1"
+      }
+    },
     "stream-browserify": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
@@ -14055,6 +14545,123 @@
         "util.promisify": "~1.0.0"
       }
     },
+    "swagger-client": {
+      "version": "3.9.6",
+      "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.9.6.tgz",
+      "integrity": "sha512-aS01VInNv6I+/DVQ++7TCwunYGWM/uiQNNPO0L+1+MfA3r0UEHYc9XJ8aXmrhXCvQ1jdY626ePch3plwhTunUQ==",
+      "requires": {
+        "@babel/runtime-corejs2": "^7.0.0",
+        "@kyleshockey/object-assign-deep": "^0.4.0",
+        "btoa": "1.1.2",
+        "buffer": "^5.1.0",
+        "cookie": "^0.3.1",
+        "cross-fetch": "0.0.8",
+        "deep-extend": "^0.5.1",
+        "encode-3986": "^1.0.0",
+        "fast-json-patch": "~2.1.0",
+        "isomorphic-form-data": "0.0.1",
+        "js-yaml": "^3.13.1",
+        "lodash": "^4.17.14",
+        "qs": "^6.3.0",
+        "querystring-browser": "^1.0.4",
+        "traverse": "^0.6.6",
+        "url": "^0.11.0",
+        "utf8-bytes": "0.0.1",
+        "utfstring": "^2.0.0"
+      },
+      "dependencies": {
+        "buffer": {
+          "version": "5.4.3",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
+          "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
+          "requires": {
+            "base64-js": "^1.0.2",
+            "ieee754": "^1.1.4"
+          }
+        },
+        "cookie": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+          "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+        },
+        "deep-extend": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
+          "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w=="
+        }
+      }
+    },
+    "swagger-ui": {
+      "version": "3.24.3",
+      "resolved": "https://registry.npmjs.org/swagger-ui/-/swagger-ui-3.24.3.tgz",
+      "integrity": "sha512-mTVRuiu9oLdi3WOvPQ2L7tHGoJ5cI3+d/4Y58OvTJSyIkoFo0ffr6/BNF68JFB8HsaaJc8stU5REepS0dxxq6Q==",
+      "requires": {
+        "@babel/runtime-corejs2": "^7.5.5",
+        "@braintree/sanitize-url": "^3.0.0",
+        "@kyleshockey/object-assign-deep": "^0.4.2",
+        "@kyleshockey/xml": "^1.0.2",
+        "base64-js": "^1.2.0",
+        "classnames": "^2.2.6",
+        "core-js": "^2.5.1",
+        "css.escape": "1.5.1",
+        "deep-extend": "0.6.0",
+        "dompurify": "^2.0.7",
+        "ieee754": "^1.1.13",
+        "immutable": "^3.x.x",
+        "js-file-download": "^0.4.1",
+        "js-yaml": "^3.13.1",
+        "lodash": "^4.17.15",
+        "memoizee": "^0.4.12",
+        "prop-types": "^15.7.2",
+        "randombytes": "^2.1.0",
+        "react": "^15.6.2",
+        "react-debounce-input": "^3.2.0",
+        "react-dom": "^15.6.2",
+        "react-immutable-proptypes": "2.1.0",
+        "react-immutable-pure-component": "^1.1.1",
+        "react-inspector": "^2.3.0",
+        "react-motion": "^0.5.2",
+        "react-redux": "^4.x.x",
+        "redux": "^3.x.x",
+        "redux-immutable": "3.1.0",
+        "remarkable": "^1.7.4",
+        "reselect": "^2.5.4",
+        "serialize-error": "^2.1.0",
+        "sha.js": "^2.4.11",
+        "swagger-client": "^3.9.6",
+        "url-parse": "^1.4.7",
+        "xml-but-prettier": "^1.0.1",
+        "zenscroll": "^4.0.2"
+      },
+      "dependencies": {
+        "@babel/runtime-corejs2": {
+          "version": "7.7.4",
+          "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.7.4.tgz",
+          "integrity": "sha512-hKNcmHQbBSJFnZ82ewYtWDZ3fXkP/l1XcfRtm7c8gHPM/DMecJtFFBEp7KMLZTuHwwb7RfemHdsEnd7L916Z6A==",
+          "requires": {
+            "core-js": "^2.6.5",
+            "regenerator-runtime": "^0.13.2"
+          },
+          "dependencies": {
+            "core-js": {
+              "version": "2.6.10",
+              "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
+              "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA=="
+            }
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.13.3",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
+          "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
+        }
+      }
+    },
+    "symbol-observable": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+      "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+    },
     "table": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
@@ -14325,7 +14932,6 @@
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
       "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
-      "dev": true,
       "requires": {
         "readable-stream": "~2.3.6",
         "xtend": "~4.0.1"
@@ -14346,6 +14952,15 @@
         "setimmediate": "^1.0.4"
       }
     },
+    "timers-ext": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
+      "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
+      "requires": {
+        "es5-ext": "~0.10.46",
+        "next-tick": "1"
+      }
+    },
     "timsort": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
@@ -14448,6 +15063,11 @@
         }
       }
     },
+    "traverse": {
+      "version": "0.6.6",
+      "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
+      "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc="
+    },
     "trim-newlines": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
@@ -14551,6 +15171,11 @@
       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
       "dev": true
     },
+    "ua-parser-js": {
+      "version": "0.7.20",
+      "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz",
+      "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw=="
+    },
     "uglify-js": {
       "version": "3.4.10",
       "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
@@ -14727,7 +15352,6 @@
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
       "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
-      "dev": true,
       "requires": {
         "punycode": "1.3.2",
         "querystring": "0.2.0"
@@ -14736,8 +15360,7 @@
         "punycode": {
           "version": "1.3.2",
           "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
-          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
-          "dev": true
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
         }
       }
     },
@@ -14756,7 +15379,6 @@
       "version": "1.4.7",
       "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
       "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
-      "dev": true,
       "requires": {
         "querystringify": "^2.1.1",
         "requires-port": "^1.0.0"
@@ -14767,6 +15389,16 @@
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
       "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
     },
+    "utf8-bytes": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/utf8-bytes/-/utf8-bytes-0.0.1.tgz",
+      "integrity": "sha1-EWsCVEjJtQAIHN+/H01sbDfYg30="
+    },
+    "utfstring": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/utfstring/-/utfstring-2.0.0.tgz",
+      "integrity": "sha512-/ugBfyvIoLe9xqkFHio3CxXnpUKQ1p2LfTxPr6QTRj6GiwpHo73YGdh03UmAzDQNOWpNIE0J5nLss00L4xlWgg=="
+    },
     "util": {
       "version": "0.11.1",
       "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
@@ -14808,11 +15440,6 @@
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
       "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
     },
-    "v-click-outside": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/v-click-outside/-/v-click-outside-2.1.5.tgz",
-      "integrity": "sha512-VPNCOTZK6WZy73lcWc+R7IW1uaBFEO3/Csrs5CzWVOdvE30V8Y1+BE/BtTlcEmeDGx0eqdE7bSCg55Jj37PMJg=="
-    },
     "v-debounce": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/v-debounce/-/v-debounce-0.1.2.tgz",
@@ -14879,24 +15506,6 @@
       "resolved": "https://registry.npmjs.org/vue-axios/-/vue-axios-2.1.4.tgz",
       "integrity": "sha512-DS8Q+WFT3i7nS0aZ/NMmTPf2yhbtlXhj4QEZmY69au/BshsGzGjC6dXaniZaPQlErP3J3Sv1HtQ4RVrXaUTkxA=="
     },
-    "vue-ctk-date-time-picker": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/vue-ctk-date-time-picker/-/vue-ctk-date-time-picker-2.4.0.tgz",
-      "integrity": "sha512-E4s0kacbL+oqURB+b6o1RNUEdsX8B5WSt6YoQKVZ019ytCv351Bs4FfZajEzo8oc9TVoI3BfcR0hLOYtaGyhEw==",
-      "requires": {
-        "moment": "^2.24.0",
-        "moment-range": "^4.0.1",
-        "v-click-outside": "^2.0.2",
-        "vue": "^2.6.9"
-      },
-      "dependencies": {
-        "vue": {
-          "version": "2.6.10",
-          "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz",
-          "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ=="
-        }
-      }
-    },
     "vue-eslint-parser": {
       "version": "2.0.3",
       "resolved": "http://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz",
@@ -14923,9 +15532,9 @@
       }
     },
     "vue-functional-data-merge": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-3.1.0.tgz",
-      "integrity": "sha512-leT4kdJVQyeZNY1kmnS1xiUlQ9z1B/kdBFCILIjYYQDqZgLqCLa0UhjSSeRX6c3mUe6U5qYeM8LrEqkHJ1B4LA=="
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-2.0.7.tgz",
+      "integrity": "sha512-pvLc+H+x2prwBj/uSEIITyxjz/7ZUVVK8uYbrYMmhDvMXnzh9OvQvVEwcOSBQjsubd4Eq41/CSJaWzy4hemMNQ=="
     },
     "vue-hot-reload-api": {
       "version": "2.3.2",
@@ -15459,6 +16068,11 @@
       "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
       "dev": true
     },
+    "whatwg-fetch": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
+      "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -15561,11 +16175,18 @@
         "async-limiter": "~1.0.0"
       }
     },
+    "xml-but-prettier": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz",
+      "integrity": "sha1-9aMyZ+1CzNTjVcYlV6XjmwH7QPM=",
+      "requires": {
+        "repeat-string": "^1.5.2"
+      }
+    },
     "xtend": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
-      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
-      "dev": true
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
     },
     "y18n": {
       "version": "4.0.0",
@@ -15780,6 +16401,11 @@
           "dev": true
         }
       }
+    },
+    "zenscroll": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz",
+      "integrity": "sha1-6NV3TRwHOKR7z6hynzcS4t7d6yU="
     }
   }
 }
diff --git a/frontend/package.json b/frontend/package.json
index 92a05af2aa45eb6beaeb67c2c6b4d52d07b6bdc3..3cbf94fc9a5839505b394502219da2f4a029eda4 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -19,9 +19,10 @@
     "http-proxy-middleware": "^0.19.1",
     "i": "^0.3.6",
     "node-sass": "^4.11.0",
-    "npm": "^6.12.0",
+    "npm": "^6.13.2",
     "popper.js": "^1.14.7",
     "sass-loader": "^7.1.0",
+    "swagger-ui": "^3.24.3",
     "v-debounce": "^0.1.2",
     "vue": "^2.6.0",
     "vue-awesome": "^3.4.0",
diff --git a/frontend/public/.gitignore b/frontend/public/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4017a088e617a99781942d30fbde2116db0d67d8
--- /dev/null
+++ b/frontend/public/.gitignore
@@ -0,0 +1 @@
+api.json
\ No newline at end of file
diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 850edf73aacd2a7fa78d7368a4ebec60bd64191f..8e8247d2c421b9aae92bba482eba38e8478f11b3 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -62,7 +62,7 @@
                         <hr>
                         <p class="pull-right d-print-none">
                             <a target="_blank" href="https://www-net-doku.scc.kit.edu/webapi/release/dnscfg-perms/"><font-awesome-icon :icon="['far', 'life-ring']"></font-awesome-icon> Hilfe/Dokumentation</a> |
-                            <a target="_blank" href="https://www-net-devel-doku.scc.kit.edu/webapi/release/intro/"><font-awesome-icon icon="code"></font-awesome-icon> API</a> |
+                            <b-link to="/swagger"><font-awesome-icon icon="code"></font-awesome-icon> API</b-link> |
                             <a target="_blank" href="https://git.scc.kit.edu/scc-net/net-suite/net-suite/issues"><font-awesome-icon icon="bug"></font-awesome-icon> Fehler melden</a> |
                             Kontakt: <a href="mailto:dns-betrieb@scc.kit.edu">dns-betrieb∂scc.kit.edu</a>
                         </p>
diff --git a/frontend/src/router.js b/frontend/src/router.js
index f1de6be5f62e12e9eb3ae3b8670e2c1d615b15f3..8f6d53437087c588d26fb207953035d2328f2aa4 100644
--- a/frontend/src/router.js
+++ b/frontend/src/router.js
@@ -10,6 +10,16 @@ export default new Router({
         {
             path: '/', beforeEnter: (to, from, next) => next('/dnsvs')
         },
+        {
+            path: '/swagger',
+            name: 'wagger-ui',
+            component: () => import('./views/swagger/ui.vue'),
+            meta: {
+                resolveName: function () {
+                    return "API-Browser"
+                }
+            }
+        },
         {
             path: '/login',
             name: 'login',
diff --git a/frontend/src/views/netdb/tokens.vue b/frontend/src/views/netdb/tokens.vue
index 1ff167b81c3815746d15a639a5bc228f67dd4986..207524a7a3203c6e0078f04cb3e522914e9414b0 100644
--- a/frontend/src/views/netdb/tokens.vue
+++ b/frontend/src/views/netdb/tokens.vue
@@ -1,7 +1,7 @@
 <template>
     <div class="main">
         <h1>Accounts</h1>
-        <b-modal id="modal-create-account" title="Subaccount erstellen" @ok="createAccount">
+        <b-modal id="modal-create-account" size="lg" title="Subaccount erstellen" @ok="createAccount">
             <b-form @submit="createAccount">
                 <b-form-group label="Login Name:" label-for="input-account-create-login-name">
                     <b-form-input
@@ -25,7 +25,7 @@
                 <b-button variant="outline-secondary" @click="cancel()">
                     Abbrechen
                 </b-button>
-                <b-button variant="success" @click="ok()">
+                <b-button type="submit" variant="success" @click="ok()">
                     Erstellen
                 </b-button>
             </template>
@@ -48,7 +48,7 @@
                 </b-button>
             </b-col>
         </b-row>
-        <b-modal id="modal-edit-account" title="Account bearbeiten">
+        <b-modal id="modal-edit-account" size="lg" title="Account bearbeiten">
             <b-form>
                 <b-form-group label="Login Name:" label-for="input-account-edit-login-name">
                     <b-form-input
@@ -73,7 +73,7 @@
                     Abbrechen
                 </b-button>
                 <!-- TODO: don't show for main account -->
-                <b-button variant="danger">
+                <b-button v-if="new_account.parent_login_name !== null" variant="danger">
                     Löschen
                 </b-button>
                 <b-button variant="primary" @click="ok()">
@@ -81,7 +81,7 @@
                 </b-button>
             </template>
         </b-modal>
-        <b-modal id="modal-create-token" title="Token erstellen">
+        <b-modal id="modal-create-token" size=lg title="Token erstellen">
             <b-form>
                 <b-form-group label="Beschreibung:" label-for="input-token-create-description">
                     <b-form-textarea
@@ -92,18 +92,33 @@
                             invalid-feedback="TODO: Beschreibung bad!"
                     />
                 </b-form-group>
+                <b-form-group label="Ablaufdatum:" label-for="input-token-create-delete_date">
+                    <!-- TODO: use theme color -->
+                    <VueCtkDateTimePicker
+                            :inline="!isMobile()"
+                            :min-date="getMinDate()"
+                            format="DD-MM-YYYY HH:mm"
+                            locale="de"
+                            noButtonNow
+                            minute-interval="5"
+                            noLabel
+                            noClearButton
+                            id="input-token-create-delete_date"
+                            color="#007BFF"
+                            button-color="#007BFF"
+                            v-model="test_date"/>
+                </b-form-group>
             </b-form>
-            <p>TODO: Date picker / Ablaufdatum</p>
             <template v-slot:modal-footer="{cancel, ok}">
                 <b-button variant="outline-secondary" @click="cancel()">
                     Abbrechen
                 </b-button>
-                <b-button variant="success" @click="ok()">
+                <b-button type="submit" variant="success" @click="ok()">
                     Erstellen
                 </b-button>
             </template>
         </b-modal>
-        <b-modal id="modal-edit-token" title="Token bearbeiten">
+        <b-modal id="modal-edit-token" size=lg title="Token bearbeiten">
             <b-form>
                 <b-form-group label="Beschreibung:" label-for="input-token-edit-description">
                     <b-form-textarea
@@ -115,7 +130,8 @@
                     />
                 </b-form-group>
             </b-form>
-            <p>TODO: Date picker / Ablaufdatum</p>
+            <!-- TODO: use theme color -->
+            <VueCtkDateTimePicker color="#007BFF" v-model="test_date"/>
             <template v-slot:modal-footer="{cancel, ok}">
                 <b-button variant="outline-secondary" @click="cancel()">
                     Abbrechen
@@ -123,7 +139,7 @@
                 <b-button variant="danger">
                     Löschen
                 </b-button>
-                <b-button variant="primary" @click="ok()">
+                <b-button type="submit" variant="primary" @click="ok()">
                     Änderungen übernehmen
                 </b-button>
             </template>
@@ -136,15 +152,18 @@
                             <h4>
                                 {{account.login_name}}
                                 <b-badge variant="success">
-                                    <div v-if="tokens_by_account[account.login_name].length === 1">{{tokens_by_account[account.login_name].length}} Token</div>
+                                    <div v-if="tokens_by_account[account.login_name].length === 1">
+                                        {{tokens_by_account[account.login_name].length}} Token
+                                    </div>
                                     <div v-else>{{tokens_by_account[account.login_name].length}} Tokens</div>
                                 </b-badge>
                             </h4>
                             <p class="text-muted">Login Name</p>
                         </b-col>
                         <b-col>
-                            TODO: "Hauptaccount, kann nicht gelöcht werden." / "Keine Beschreibung vorhanden."
-                            {{account.description}}
+                            <div v-if="account.parent_login_name == null">Hauptaccount; enthält nur Session-Tokens; kann nicht gelöscht werden.</div>
+                            <div v-else-if="account.description == null">Keine Beschreibung vorhanden.</div>
+                            <div v-else>{{account.description}}</div>
                             <p class="text-muted">Beschreibung</p>
                         </b-col>
                         <b-col>
@@ -211,9 +230,11 @@
         name: 'tokens',
         data() {
             return {
+                test_date: null,
                 tokens_by_account: null,
                 accounts: null,
                 new_account: {
+                    parent_login_name: null,
                     description: '',
                     login_name: '',
                     delete_date: null
@@ -285,6 +306,26 @@
             })
         },
         methods: {
+            openModalEditAccount(account) {
+                this.new_account.description = account.description
+                this.new_account.login_name = account.login_name
+                this.new_account.delete_date = account.delete_date
+            },
+            openModalEditToken(token) {
+                this.new_token.description = token.description
+                this.new_token.login_name = token.login_name
+                this.new_token.delete_date = token.delete_date
+            },
+            resetNewAccount() {
+                this.new_account.description = ''
+                this.new_account.login_name = ''
+                this.new_account.delete_date = null
+            },
+            resetNewToken() {
+                this.new_token.description = ''
+                this.new_token.login_name = ''
+                this.new_token.delete_date = null
+            },
             createAccount() {
                 AccountService.create(this.$store.state.netdb_axios_config, {
                     description_new: this.new_account.description
@@ -292,6 +333,11 @@
             },
             formatDate(value) {
                 return new Date(Date.parse(value)).toLocaleString('de-DE');
+            },
+            getMinDate() {
+                let d = new Date()
+                d.setDate(d.getDate() - 1)
+                return d
             }
         }
     }
diff --git a/frontend/src/views/swagger/ui.vue b/frontend/src/views/swagger/ui.vue
new file mode 100644
index 0000000000000000000000000000000000000000..9532e216c35975bb28847a74f43416798a78fd79
--- /dev/null
+++ b/frontend/src/views/swagger/ui.vue
@@ -0,0 +1,40 @@
+<template>
+    <div id="swagger-ui">
+    </div>
+</template>
+
+<script>
+    import SwaggerUI from 'swagger-ui'
+    import 'swagger-ui/dist/swagger-ui.css'
+
+    export default {
+        name: "ui.vue",
+        mounted() {
+            var self = this
+            SwaggerUI({
+                url: '/api.json',
+                docExpansion: 'none',
+                dom_id: '#swagger-ui',
+                deepLinking: false,
+                presets: [
+                    SwaggerUI.presets.apis
+                ],
+                plugins: [
+                    SwaggerUI.plugins.DownloadUrl
+                ],
+                requestInterceptor: function (req) {
+                    if (self.$store.state.logged_in) {
+                        req.headers.Authorization = self.$store.state.token.token
+                        window.console.log('Authorized from Session');
+                    }
+                },
+            })
+        },
+        created() {
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>
diff --git a/middleware/net_suite/model.py b/middleware/net_suite/model.py
index 696885f5579eb1b9dfed1717654e47bef5beb202..32092c45b492be1b1874ecff0e93a6bfb318f159 100644
--- a/middleware/net_suite/model.py
+++ b/middleware/net_suite/model.py
@@ -853,6 +853,54 @@ class NDPPort(DBObject):
         self.name = name
         self.module = module
 
+
+    @staticmethod
+    def get_nd_p_port_by_vlan(db, connection, vlan_id, ni_name):
+        res = db.execute(connection,
+                         """
+                         select nd_mdl_typ_class.name as root_nd_mdl_typ_class_name, root_typ.name as root_nd_mdl_typ_name, dst.name as nd_p_port_name, root.name as root_nd_mdl_name, mod.name as base_nd_mdl_name,
+nd_room.name as nd_room_name, nd_room.nr as nd_room_nr, nd_floor.nr as nd_floor_nr, nd_floor.descr as nd_floor_descr,
+nd_bldg.nr as nd_bldg_nr, nd_bldg.name as nd_bldg_name from nd_dev
+  INNER JOIN dns_ntree on nd_dev.dns_ntree_key_nr=dns_ntree.key_nr
+  inner join nd_l_port on nd_dev.key_nr=nd_l_port.nd_dev_key_nr
+  inner join nd_vlan on nd_l_port.nd_vlan_key_nr=nd_vlan.key_nr
+  inner join nd_net_instnc on nd_vlan.nd_net_instnc_key_nr=nd_net_instnc.key_nr
+  inner join nd_l2p_port on nd_l_port.key_nr=nd_l2p_port.nd_l_port_key_nr
+  inner join nd_p_port src on nd_l2p_port.nd_p_port_key_nr = src.key_nr
+  inner join nd_p_port dst on src.nd_dest_p_port_key_nr=dst.key_nr
+  inner join nd_mdl mod on dst.nd_mdl_key_nr=mod.key_nr
+  inner join nd_mdl root on mod.nd_root_mdl_key_nr=root.key_nr
+  inner join nd_room on root.nd_room_key_nr=nd_room.key_nr
+  inner join nd_floor on nd_room.nd_floor_key_nr=nd_floor.key_nr
+  inner join nd_bldg on nd_room.nd_bldg_key_nr=nd_bldg.key_nr
+  inner join nd_mdl_typ root_typ on root.nd_mdl_typ_key_nr = root_typ.key_nr
+  inner join nd_mdl_typ_class on root_typ.nd_mdl_typ_class_key_nr=nd_mdl_typ_class.key_nr
+  where nd_net_instnc.name = {ni_name} and nd_vlan.id = {vlan_id}
+                         """,
+                         {'ni_name': ni_name, 'vlan_id': vlan_id})
+        if len(res) == 0:
+            return None
+        return [NDPPort(
+            **_marshal_dict(r, NDPPort),
+            module=NDModule(**_marshal_dict(_marshal_dict_str(r, 'base'), NDModule),
+                            root_module=NDModule(**_marshal_dict(_marshal_dict_str(r, 'root'), NDModule),
+                                                 room=NDRoom(
+                                                     **_marshal_dict(r, NDRoom)),
+                                                 floor=NDFloor(
+                                                     **_marshal_dict(r, NDFloor)),
+                                                 building=NDBuilding(
+                                                     **_marshal_dict(r, NDBuilding)),
+                                                 module_type=NDModuleType(
+                                                     **_marshal_dict(_marshal_dict_str(r, 'root'), NDModuleType),
+                                                     type_class=NDModuleTypeClass(
+                                                         **_marshal_dict(_marshal_dict_str(r, 'root'),
+                                                                         NDModuleTypeClass)
+                                                     )
+                                                 )
+                                                 ),
+                            )
+        ) for r in res]
+
     @staticmethod
     def get_nd_p_port_by_dev_fqdn_and_port_name(db, connection, fqdn, port):
         res = db.execute(connection,
diff --git a/middleware/net_suite/modules/user_nd/__init__.py b/middleware/net_suite/modules/user_nd/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc1d1d10380176e0b7baa1e94ea32fac755a5850
--- /dev/null
+++ b/middleware/net_suite/modules/user_nd/__init__.py
@@ -0,0 +1,14 @@
+from flask import Blueprint
+from net_suite import app, get_git_version, ModMetaData
+import requests
+
+
+# we are assuming, that at the time of loading the app is initializes and the config is loaded
+bb_name = 'user_nd'
+user_nd = Blueprint(bb_name, __name__)
+
+METADATA = ModMetaData(name=bb_name, mod_path=__name__, gitlab_url='https://git.scc.kit.edu/scc-net/net-suite/net-suite',
+                       printable_name='User-Netdoc', version=get_git_version(__file__),
+                       contact_email='dns-betrieb@scc.kit.edu', is_tool=False)
+MENU = []
+from . import views
diff --git a/middleware/net_suite/modules/user_nd/views.py b/middleware/net_suite/modules/user_nd/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..b8d94a1b8229c6859a1a5015d7d448530c546873
--- /dev/null
+++ b/middleware/net_suite/modules/user_nd/views.py
@@ -0,0 +1,22 @@
+from . import user_nd, METADATA
+from net_suite.model import *
+from net_suite import app
+from net_suite.views import login_required, get_db_conn, db
+import requests
+from flask import render_template, request, flash, jsonify, redirect, url_for, abort
+
+
+@user_nd.route('/vlans/<ni_name>/<vlan>/ports')
+@login_required
+def get_dev_ports(ni_name, vlan):
+    vlan = int(vlan)
+    s = request.environ['beaker.session']
+    areas = s['login'].get_areas(db=db, connection=get_db_conn())
+    vlan_valid = False
+    for a in areas:
+        if a.vlan is not None and a.vlan.id == vlan and a.vlan.ni_name == ni_name:
+            vlan_valid = True
+            break
+    if not vlan_valid:
+        return abort(404)
+    return jsonify(NDPPort.get_nd_p_port_by_vlan(db, get_db_conn(), ni_name=ni_name, vlan_id=vlan))